2 , setPref } = require 'prefs'
3 { injectHelp } = require 'help'
4 { commands } = require 'commands'
5 utils = require 'utils'
6 { unloader } = require 'unloader'
9 KEYSET_ID = 'vimfx-keyset'
10 BUTTON_ID = 'vimfx-toolbar-button'
12 MENUPOPUP_ID = 'vimfx-menupopup'
13 MENU_ITEM_PREF = 'vimfx-menu-item-preferences'
14 MENU_ITEM_HELP = 'vimfx-menu-item-help'
15 TEXTBOX_BLACKLIST_ID = 'vimfx-textbox-blacklist-id'
16 BUTTON_BLACKLIST_ID = 'vimfx-button-blacklist-id'
18 $ = (document, selector) -> document.getElementById(selector)
19 $$ = (document, selector) -> document.querySelectorAll(selector)
23 setButtonInstallPosition = (toolbarId, beforeId) ->
24 positions[BUTTON_ID] = {toolbarId, beforeId}
26 addToolbarButton = (vimBucket, window) ->
27 document = window.document
28 win = document.querySelector('window')
30 [ button, keyset ] = createButton(vimBucket, window)
32 # Namespace to put the VimFx state on, for example.
35 restorePosition(document, button)
37 if tabWindow = utils.getCurrentTabWindow(window)
38 blacklisted = utils.isBlacklisted(tabWindow.location.href)
39 disabled = getPref('disabled')
40 updateToolbarButton(window, {disabled, blacklisted})
42 win.appendChild(keyset)
47 $(document, 'navigator-toolbox').palette.removeChild(button)
50 createButton = (vimBucket, window) ->
51 document = window.document
53 button = utils.createElement(document, 'toolbarbutton', {
57 class: 'toolbarbutton-1'
60 menupopup = createMenupopup(window, button)
62 onButtonCommand = (event) ->
64 when button.VimFx.blacklisted
65 menupopup.openPopup(button, 'after_start')
66 when button.VimFx.insertMode
67 return unless currentTabWindow = utils.getEventCurrentTabWindow(event)
68 return unless vim = vimBucket.get(currentTabWindow)
69 updateToolbarButton(window, {insertMode: false})
70 vim.enterMode('normal')
72 disabled = not getPref('disabled')
73 setPref('disabled', disabled)
74 updateToolbarButton(window, {disabled})
76 event.stopPropagation()
78 button.addEventListener('command', onButtonCommand, false)
80 vimkey = utils.createElement(document, 'key', {
83 modifiers: 'shift,alt'
86 vimkey.addEventListener('command', onButtonCommand, false)
88 keyset = utils.createElement(document, 'keyset', {id: KEYSET_ID})
89 keyset.appendChild(vimkey)
91 return [button, keyset]
93 createMenupopup = (window, button) ->
94 document = window.document
96 blacklistTextbox = utils.createElement(document, 'textbox', {
97 id: TEXTBOX_BLACKLIST_ID
99 blacklistButton = utils.createElement(document, 'toolbarbutton', {
100 id: BUTTON_BLACKLIST_ID
101 class: 'toolbarbutton-1'
103 blacklistControls = utils.createElement(document, 'hbox')
104 blacklistControls.appendChild(blacklistTextbox)
105 blacklistControls.appendChild(blacklistButton)
107 itemPreferences = utils.createElement(document, 'menuitem', {
109 label: _('item_preferences')
112 itemHelp = utils.createElement(document, 'menuitem', {
114 label: _('help_title')
117 menupopup = utils.createElement(document, 'menupopup', {
121 menupopup.appendChild(blacklistControls)
122 menupopup.appendChild(itemPreferences)
123 menupopup.appendChild(itemHelp)
125 onPopupShowing = (event) ->
126 return unless tabWindow = utils.getCurrentTabWindow(window)
128 if button.VimFx.blacklisted
129 matchingRules = utils.getMatchingBlacklistRules(tabWindow.location.href)
130 blacklistTextbox.value = matchingRules.join(', ')
131 blacklistTextbox.setAttribute('readonly', true)
132 blacklistButton.setAttribute('tooltiptext',
133 _('item_blacklist_button_inverse_tooltip'))
134 blacklistButton.style.listStyleImage = iconUrl('blacklist_inverse')
136 blacklistTextbox.value =
137 # In `about:` pages, the `host` property is an empty string. Fall back
139 if tabWindow.location.host != ''
140 "*#{ tabWindow.location.host }*"
142 tabWindow.location.href
143 blacklistTextbox.removeAttribute('readonly')
144 blacklistButton.setAttribute('tooltiptext',
145 _('item_blacklist_button_tooltip'))
146 blacklistButton.style.listStyleImage = iconUrl('blacklist')
148 onBlacklistButtonCommand = (event) ->
149 return unless tabWindow = utils.getCurrentTabWindow(window)
151 if button.VimFx.blacklisted
152 utils.updateBlacklist({remove: blacklistTextbox.value})
154 utils.updateBlacklist({add: blacklistTextbox.value})
156 menupopup.hidePopup()
158 tabWindow.location.reload(false)
160 event.stopPropagation()
162 onPreferencesCommand = (event) ->
163 id = encodeURIComponent(utils.ADDON_ID)
164 window.BrowserOpenAddonsMgr("addons://detail/#{ id }/preferences")
166 event.stopPropagation()
168 onHelpCommand = (event) ->
169 if tabWindow = utils.getCurrentTabWindow(window)
170 injectHelp(tabWindow.document, commands)
172 event.stopPropagation()
174 menupopup.addEventListener('popupshowing', onPopupShowing, false)
175 blacklistButton.addEventListener('command', onBlacklistButtonCommand, false)
176 itemPreferences.addEventListener('command', onPreferencesCommand, false)
177 itemHelp.addEventListener('command', onHelpCommand, false)
179 button.appendChild(menupopup)
182 restorePosition = (document, button) ->
183 $(document, 'navigator-toolbox').palette.appendChild(button)
185 for tb in $$(document, 'toolbar')
186 currentset = tb.getAttribute('currentset').split(',')
187 idx = currentset.indexOf(button.id)
192 # Saved position not found, using the default one, after persisting it.
193 if not toolbar and button.id of positions
194 { toolbarId, beforeId } = positions[button.id]
195 if toolbar = $(document, toolbarId)
196 [ currentset, idx ] = persist(document, toolbar, button.id, beforeId)
198 if toolbar and idx != -1
199 # Inserting the button before the first item in `currentset`
200 # after `idx` that is present in the document.
201 for id in currentset[idx+1..]
202 if before = $(document, id)
203 toolbar.insertItem(button.id, before)
206 toolbar.insertItem(button.id)
208 persist = (document, toolbar, buttonId, beforeId) ->
209 currentset = toolbar.currentSet.split(',')
210 idx = if beforeId then currentset.indexOf(beforeId) else -1
212 currentset.splice(idx, 0, buttonId)
214 currentset.push(buttonId)
216 toolbar.setAttribute('currentset', currentset.join(','))
217 document.persist(toolbar.id, 'currentset')
218 return [currentset, idx]
220 updateToolbarButton = (window, { disabled, blacklisted, insertMode }) ->
221 return unless button = $(window.document, BUTTON_ID)
223 button.VimFx.disabled = disabled if disabled?
224 button.VimFx.blacklisted = blacklisted if blacklisted?
225 button.VimFx.insertMode = insertMode if insertMode?
227 [ icon, tooltip ] = switch
228 when button.VimFx.disabled
230 when button.VimFx.blacklisted
231 ['red', 'blacklisted']
232 when button.VimFx.insertMode
233 ['grey', 'insertMode']
235 ['normal', 'enabled']
237 button.style.listStyleImage = iconUrl(icon)
238 button.setAttribute('tooltiptext', _("button_tooltip_#{ tooltip }"))
241 url = utils.getResourceURI("resources/icon16-#{ kind }.png").spec
242 return "url(#{ url })"
244 exports.setButtonInstallPosition = setButtonInstallPosition
245 exports.addToolbarButton = addToolbarButton
246 exports.updateToolbarButton = updateToolbarButton