2 , setPref } = require 'prefs'
3 { injectHelp } = require 'help'
4 { commands } = require 'commands'
5 utils = require 'utils'
6 { unload } = require 'unload'
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 $ = (doc, sel) -> doc.getElementById(sel)
19 $$ = (doc, sel) -> doc.querySelectorAll(sel)
23 setButtonInstallPosition = (toolbarId, beforeId) ->
24 positions[BUTTON_ID] = [toolbarId, beforeId]
26 persist = (document, toolbar, buttonId, beforeId) ->
27 currentset = toolbar.currentSet.split(',')
28 idx = if beforeId then currentset.indexOf(beforeId) else -1
30 currentset.splice(idx, 0, buttonId)
32 currentset.push(buttonId)
34 toolbar.setAttribute('currentset', currentset.join(','))
35 document.persist(toolbar.id, 'currentset')
36 return [currentset, idx]
38 restorePosition = (doc, button) ->
39 $(doc, 'navigator-toolbox').palette.appendChild(button)
41 for tb in $$(doc, 'toolbar')
42 currentset = tb.getAttribute('currentset').split(',')
43 idx = currentset.indexOf(button.id)
48 # Saved position not found, using the default one, after persisting it
49 if !toolbar and pos = positions[button.id]
50 [tbID, beforeId] = pos
51 if toolbar = $(doc, tbID)
52 [currentset, idx] = persist(doc, toolbar, button.id, beforeId)
54 if toolbar and idx != -1
55 # Inserting the button before the first item in `currentset`
56 # after `idx` that is present in the document
57 for i in [idx + 1 ... currentset.length]
58 if before = $(doc, currentset[i])
59 toolbar.insertItem(button.id, before)
62 toolbar.insertItem(button.id)
65 url = utils.getResourceURI("resources/icon16-#{kind}.png").spec
66 return "url(#{ url })"
69 createMenupopup = (window, button) ->
72 blacklistTextbox = doc.createElement('textbox')
73 blacklistTextbox.id = TEXTBOX_BLACKLIST_ID
74 blacklistButton = doc.createElement('toolbarbutton')
75 blacklistButton.id = BUTTON_BLACKLIST_ID
76 blacklistButton.setAttribute('class', 'toolbarbutton-1')
77 hbox = doc.createElement('hbox')
78 hbox.appendChild(blacklistTextbox)
79 hbox.appendChild(blacklistButton)
81 itemPreferences = doc.createElement('menuitem')
82 itemPreferences.id = MENU_ITEM_PREF
83 itemPreferences.setAttribute('label', _('item_preferences'))
85 itemHelp = doc.createElement('menuitem')
86 itemHelp.id = MENU_ITEM_HELP
87 itemHelp.setAttribute('label', _('help_title'))
89 menupopup = doc.createElement('menupopup')
90 menupopup.id = MENUPOPUP_ID
91 menupopup.setAttribute('ignorekeys', true)
92 menupopup.appendChild(hbox)
93 menupopup.appendChild(itemPreferences)
94 menupopup.appendChild(itemHelp)
96 onPopupShowing = (event) ->
97 return unless tabWindow = window.gBrowser.selectedTab.linkedBrowser.contentWindow
99 { blacklisted, matchedRule } = button['VimFx_blacklisted'] or {}
101 blacklistTextbox.value = matchedRule
102 blacklistButton.setAttribute('tooltiptext', _('item_blacklist_button_inverse_tooltip'))
103 blacklistButton.style.listStyleImage = iconUrl('blacklist_inverse')
105 # In `about:` pages, the `host` property is an empty string. Fall back to the whole URL
106 blacklistTextbox.value = "*#{ tabWindow.location.host or tabWindow.location }*"
107 blacklistButton.setAttribute('tooltiptext', _('item_blacklist_button_tooltip'))
108 blacklistButton.style.listStyleImage = iconUrl('blacklist')
110 onBlacklistButtonCommand = (event) ->
111 { blacklisted, matchedRule } = button['VimFx_blacklisted'] or {}
113 utils.updateBlacklist({remove: matchedRule})
115 utils.updateBlacklist({add: blacklistTextbox.value})
117 menupopup.hidePopup()
119 if tabWindow = window.gBrowser.selectedTab.linkedBrowser.contentWindow
120 tabWindow.location.reload(false)
122 event.stopPropagation()
124 onPreferencesCommand = (event) ->
125 id = encodeURIComponent(getPref('addon_id'))
126 window.BrowserOpenAddonsMgr("addons://detail/#{ id }/preferences")
128 event.stopPropagation()
130 onHelpCommand = (event) ->
131 if tabWindow = window.gBrowser.selectedTab.linkedBrowser.contentWindow
132 injectHelp(tabWindow.document, commands)
134 event.stopPropagation()
136 menupopup.addEventListener 'popupshowing', onPopupShowing, false
137 blacklistButton.addEventListener 'command', onBlacklistButtonCommand, false
138 itemPreferences.addEventListener 'command', onPreferencesCommand, false
139 itemHelp.addEventListener 'command', onHelpCommand, false
141 button.appendChild(menupopup)
144 createButton = (window) ->
145 doc = window.document
147 button = doc.createElement('toolbarbutton')
148 button.setAttribute('id', BUTTON_ID)
149 button.setAttribute('type', 'menu-button')
150 button.setAttribute('label', 'VimFx')
151 button.setAttribute('class', 'toolbarbutton-1')
153 # Create and install event listeners
154 onButtonCommand = (event) ->
155 # Change disabled state value which is stored in Prefs
156 setPref('disabled', not getPref 'disabled')
157 updateToolbarButton(button)
159 event.stopPropagation()
161 button.addEventListener('command', onButtonCommand, false)
163 createMenupopup(window, button)
165 vimkey = doc.createElement('key')
166 vimkey.setAttribute('id', KEY_ID)
167 vimkey.setAttribute('key', 'V')
168 vimkey.setAttribute('modifiers', 'shift,alt')
169 vimkey.setAttribute('oncommand', 'void(0);')
170 vimkey.addEventListener('command', onButtonCommand, false)
172 keyset = doc.createElement('keyset')
173 keyset.setAttribute('id', KEYSET_ID)
174 keyset.appendChild(vimkey)
176 return [button, keyset]
178 addToolbarButton = (window) ->
179 doc = window.document
180 win = doc.querySelector('window')
182 [button, keyset] = createButton(window)
183 updateToolbarButton(button)
185 restorePosition(doc, button)
186 win.appendChild(keyset)
189 if buttonParent = button.parentNode
190 buttonParent.removeChild(button)
191 if keysetParent = keyset.parentNode
192 keysetParent.removeChild(keyset)
193 $(doc, 'navigator-toolbox').palette.removeChild(button)
195 updateToolbarButton = (button) ->
196 if getPref('disabled')
197 button.style.listStyleImage = iconUrl('grey')
198 button.setAttribute('tooltiptext', _('button_tooltip_disabled'))
199 else if button['VimFx_blacklisted']
200 button.style.listStyleImage = iconUrl('red')
201 button.setAttribute('tooltiptext', _('button_tooltip_blacklisted'))
203 button.style.listStyleImage = iconUrl('normal')
204 button.setAttribute('tooltiptext', _('button_tooltip_enabled'))
206 setWindowBlacklisted = (window, blacklisted) ->
207 if button = $(window.document, BUTTON_ID)
208 button['VimFx_blacklisted'] = blacklisted
209 updateToolbarButton(button)
211 exports.addToolbarButton = addToolbarButton
212 exports.setWindowBlacklisted = setWindowBlacklisted
213 exports.setButtonInstallPosition = setButtonInstallPosition