2 # Copyright Anton Khodakivskiy 2012, 2013, 2014.
3 # Copyright Simon Lydell 2013, 2014.
5 # This file is part of VimFx.
7 # VimFx is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # VimFx is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with VimFx. If not, see <http://www.gnu.org/licenses/>.
22 , setPref } = require('./prefs')
23 { injectHelp } = require('./help')
24 utils = require('./utils')
27 BUTTON_ID = 'vimfx-toolbar-button'
28 MENUPOPUP_ID = 'vimfx-menupopup'
29 MENU_ITEM_PREF = 'vimfx-menu-item-preferences'
30 MENU_ITEM_HELP = 'vimfx-menu-item-help'
31 TEXTBOX_BLACKLIST_ID = 'vimfx-textbox-blacklist-id'
32 BUTTON_BLACKLIST_ID = 'vimfx-button-blacklist-id'
34 $ = (document, selector) -> document.getElementById(selector)
35 $$ = (document, selector) -> document.querySelectorAll(selector)
39 setButtonInstallPosition = (toolbarId, beforeId) ->
40 positions[BUTTON_ID] = {toolbarId, beforeId}
42 addToolbarButton = (vimfx, window) ->
43 document = window.document
44 win = document.querySelector('window')
46 button = createButton(vimfx, window)
48 # Namespace to put the VimFx state on, for example.
51 restorePosition(document, button)
53 if tabWindow = utils.getCurrentTabWindow(window)
54 blacklisted = utils.isBlacklisted(tabWindow.location.href)
55 updateToolbarButton({rootWindow: window, state: {blacklisted}})
57 vimfx.on('modechange', updateToolbarButton)
58 vimfx.on('bucket.get', updateToolbarButton)
62 $(document, 'navigator-toolbox').palette.removeChild(button)
65 createButton = (vimfx, window) ->
66 document = window.document
68 button = utils.createElement(document, 'toolbarbutton', {
72 class: 'toolbarbutton-1'
75 menupopup = createMenupopup(vimfx, window, button)
77 onButtonCommand = (event) ->
79 when button.VimFx.blacklisted
80 menupopup.openPopup(button, 'after_start')
81 when button.VimFx.insertMode
82 return unless currentTabWindow = utils.getEventCurrentTabWindow(event)
83 return unless vim = vimfx.vimBucket.get(currentTabWindow)
84 vim.enterMode('normal')
86 return unless currentTabWindow = utils.getEventCurrentTabWindow(event)
87 return unless vim = vimfx.vimBucket.get(currentTabWindow)
88 setPref('disabled', not getPref('disabled'))
89 updateToolbarButton(vim)
91 event.stopPropagation()
93 button.addEventListener('command', onButtonCommand, false)
97 createMenupopup = (vimfx, window, button) ->
98 document = window.document
100 blacklistTextbox = utils.createElement(document, 'textbox', {
101 id: TEXTBOX_BLACKLIST_ID
103 blacklistButton = utils.createElement(document, 'toolbarbutton', {
104 id: BUTTON_BLACKLIST_ID
105 class: 'toolbarbutton-1'
107 blacklistControls = utils.createElement(document, 'hbox')
108 blacklistControls.appendChild(blacklistTextbox)
109 blacklistControls.appendChild(blacklistButton)
111 itemPreferences = utils.createElement(document, 'menuitem', {
113 label: _('item_preferences')
116 itemHelp = utils.createElement(document, 'menuitem', {
118 label: _('help_title')
121 menupopup = utils.createElement(document, 'menupopup', {
125 menupopup.appendChild(blacklistControls)
126 menupopup.appendChild(itemPreferences)
127 menupopup.appendChild(itemHelp)
129 onPopupShowing = (event) ->
130 return unless tabWindow = utils.getCurrentTabWindow(window)
132 if button.VimFx.blacklisted
133 matchingRules = utils.getMatchingBlacklistRules(tabWindow.location.href)
134 blacklistTextbox.value = matchingRules.join(', ')
135 blacklistTextbox.setAttribute('readonly', true)
136 blacklistButton.setAttribute('tooltiptext',
137 _('item_blacklist_button_inverse_tooltip'))
138 blacklistButton.style.listStyleImage = iconUrl('blacklist_inverse')
140 blacklistTextbox.value =
141 # In `about:` pages, the `host` property is an empty string. Fall back
143 if tabWindow.location.host != ''
144 "*#{ tabWindow.location.host }*"
146 tabWindow.location.href
147 blacklistTextbox.removeAttribute('readonly')
148 blacklistButton.setAttribute('tooltiptext',
149 _('item_blacklist_button_tooltip'))
150 blacklistButton.style.listStyleImage = iconUrl('blacklist')
152 onBlacklistButtonCommand = (event) ->
153 return unless tabWindow = utils.getCurrentTabWindow(window)
155 if button.VimFx.blacklisted
156 utils.updateBlacklist({remove: blacklistTextbox.value})
158 utils.updateBlacklist({add: blacklistTextbox.value})
160 menupopup.hidePopup()
162 tabWindow.location.reload(false)
164 event.stopPropagation()
166 onPreferencesCommand = (event) ->
167 id = encodeURIComponent(vimfx.ID)
168 window.BrowserOpenAddonsMgr("addons://detail/#{ id }/preferences")
170 event.stopPropagation()
172 onHelpCommand = (event) ->
173 if tabWindow = utils.getCurrentTabWindow(window)
174 injectHelp(tabWindow.document, vimfx)
176 event.stopPropagation()
178 menupopup.addEventListener('popupshowing', onPopupShowing, false)
179 blacklistButton.addEventListener('command', onBlacklistButtonCommand, false)
180 itemPreferences.addEventListener('command', onPreferencesCommand, false)
181 itemHelp.addEventListener('command', onHelpCommand, false)
183 button.appendChild(menupopup)
186 restorePosition = (document, button) ->
187 $(document, 'navigator-toolbox').palette.appendChild(button)
189 for tb in $$(document, 'toolbar')
190 currentset = tb.getAttribute('currentset').split(',')
191 idx = currentset.indexOf(button.id)
196 # Saved position not found, using the default one, after persisting it.
197 if not toolbar and button.id of positions
198 { toolbarId, beforeId } = positions[button.id]
199 if toolbar = $(document, toolbarId)
200 [ currentset, idx ] = persist(document, toolbar, button.id, beforeId)
202 if toolbar and idx != -1
203 # Inserting the button before the first item in `currentset`
204 # after `idx` that is present in the document.
205 for id in currentset[idx + 1..]
206 if before = $(document, id)
207 toolbar.insertItem(button.id, before)
210 toolbar.insertItem(button.id)
212 persist = (document, toolbar, buttonId, beforeId) ->
213 currentset = toolbar.currentSet.split(',')
214 idx = if beforeId then currentset.indexOf(beforeId) else -1
216 currentset.splice(idx, 0, buttonId)
218 currentset.push(buttonId)
220 toolbar.setAttribute('currentset', currentset.join(','))
221 document.persist(toolbar.id, 'currentset')
222 return [currentset, idx]
224 updateToolbarButton = (vim) ->
225 window = vim.rootWindow
226 return unless button = $(window.document, BUTTON_ID)
228 button.VimFx.disabled = getPref('disabled')
229 button.VimFx.blacklisted = vim.state.blacklisted
230 button.VimFx.insertMode = (vim.mode == 'insert')
232 [ icon, tooltip ] = switch
233 when button.VimFx.disabled
234 ['grey', _('button_tooltip_disabled')]
235 when button.VimFx.blacklisted
236 ['red', _('button_tooltip_blacklisted')]
237 when button.VimFx.insertMode
238 keys = require('./modes')['insert'].commands['exit'].keys().join(', ')
239 ['grey', _('button_tooltip_insertMode', keys)]
241 ['normal', _('button_tooltip_enabled')]
243 button.style.listStyleImage = iconUrl(icon)
244 button.setAttribute('tooltiptext', tooltip)
247 url = utils.getResourceURI("resources/icon16-#{ kind }.png").spec
248 return "url(#{ url })"
250 exports.setButtonInstallPosition = setButtonInstallPosition
251 exports.addToolbarButton = addToolbarButton