]> git.gir.st - VimFx.git/blob - extension/packages/button.coffee
Add count support to follow link commands
[VimFx.git] / extension / packages / button.coffee
1 { getPref
2 , setPref } = require 'prefs'
3 { injectHelp } = require 'help'
4 { commands } = require 'commands'
5 utils = require 'utils'
6 { unloader } = require 'unloader'
7 { _ } = require 'l10n'
8
9 KEYSET_ID = 'vimfx-keyset'
10 BUTTON_ID = 'vimfx-toolbar-button'
11 KEY_ID = 'vimfx-key'
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'
17
18 $ = (document, selector) -> document.getElementById(selector)
19 $$ = (document, selector) -> document.querySelectorAll(selector)
20
21 positions = {}
22
23 setButtonInstallPosition = (toolbarId, beforeId) ->
24 positions[BUTTON_ID] = {toolbarId, beforeId}
25
26 addToolbarButton = (vimBucket, window) ->
27 document = window.document
28 win = document.querySelector('window')
29
30 [ button, keyset ] = createButton(vimBucket, window)
31
32 # Namespace to put the VimFx state on, for example.
33 button.VimFx = {}
34
35 restorePosition(document, button)
36
37 if tabWindow = utils.getCurrentTabWindow(window)
38 blacklisted = utils.isBlacklisted(tabWindow.location.href)
39 disabled = getPref('disabled')
40 updateToolbarButton(window, {disabled, blacklisted})
41
42 win.appendChild(keyset)
43
44 unloader.add(->
45 button.remove()
46 keyset.remove()
47 $(document, 'navigator-toolbox').palette.removeChild(button)
48 )
49
50 createButton = (vimBucket, window) ->
51 document = window.document
52
53 button = utils.createElement(document, 'toolbarbutton', {
54 id: BUTTON_ID
55 type: 'menu-button'
56 label: 'VimFx'
57 class: 'toolbarbutton-1'
58 })
59
60 menupopup = createMenupopup(window, button)
61
62 onButtonCommand = (event) ->
63 switch
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')
71 else
72 disabled = not getPref('disabled')
73 setPref('disabled', disabled)
74 updateToolbarButton(window, {disabled})
75
76 event.stopPropagation()
77
78 button.addEventListener('command', onButtonCommand, false)
79
80 vimkey = utils.createElement(document, 'key', {
81 id: KEY_ID
82 key: 'V'
83 modifiers: 'shift,alt'
84 oncommand: 'void(0);'
85 })
86 vimkey.addEventListener('command', onButtonCommand, false)
87
88 keyset = utils.createElement(document, 'keyset', {id: KEYSET_ID})
89 keyset.appendChild(vimkey)
90
91 return [button, keyset]
92
93 createMenupopup = (window, button) ->
94 document = window.document
95
96 blacklistTextbox = utils.createElement(document, 'textbox', {
97 id: TEXTBOX_BLACKLIST_ID
98 })
99 blacklistButton = utils.createElement(document, 'toolbarbutton', {
100 id: BUTTON_BLACKLIST_ID
101 class: 'toolbarbutton-1'
102 })
103 blacklistControls = utils.createElement(document, 'hbox')
104 blacklistControls.appendChild(blacklistTextbox)
105 blacklistControls.appendChild(blacklistButton)
106
107 itemPreferences = utils.createElement(document, 'menuitem', {
108 id: MENU_ITEM_PREF
109 label: _('item_preferences')
110 })
111
112 itemHelp = utils.createElement(document, 'menuitem', {
113 id: MENU_ITEM_HELP
114 label: _('help_title')
115 })
116
117 menupopup = utils.createElement(document, 'menupopup', {
118 id: MENUPOPUP_ID
119 ignorekeys: true
120 })
121 menupopup.appendChild(blacklistControls)
122 menupopup.appendChild(itemPreferences)
123 menupopup.appendChild(itemHelp)
124
125 onPopupShowing = (event) ->
126 return unless tabWindow = utils.getCurrentTabWindow(window)
127
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')
135 else
136 blacklistTextbox.value =
137 # In `about:` pages, the `host` property is an empty string. Fall back
138 # to the whole URL.
139 if tabWindow.location.host != ''
140 "*#{ tabWindow.location.host }*"
141 else
142 tabWindow.location.href
143 blacklistTextbox.removeAttribute('readonly')
144 blacklistButton.setAttribute('tooltiptext',
145 _('item_blacklist_button_tooltip'))
146 blacklistButton.style.listStyleImage = iconUrl('blacklist')
147
148 onBlacklistButtonCommand = (event) ->
149 return unless tabWindow = utils.getCurrentTabWindow(window)
150
151 if button.VimFx.blacklisted
152 utils.updateBlacklist({remove: blacklistTextbox.value})
153 else
154 utils.updateBlacklist({add: blacklistTextbox.value})
155
156 menupopup.hidePopup()
157
158 tabWindow.location.reload(false)
159
160 event.stopPropagation()
161
162 onPreferencesCommand = (event) ->
163 id = encodeURIComponent(utils.ADDON_ID)
164 window.BrowserOpenAddonsMgr("addons://detail/#{ id }/preferences")
165
166 event.stopPropagation()
167
168 onHelpCommand = (event) ->
169 if tabWindow = utils.getCurrentTabWindow(window)
170 injectHelp(tabWindow.document, commands)
171
172 event.stopPropagation()
173
174 menupopup.addEventListener('popupshowing', onPopupShowing, false)
175 blacklistButton.addEventListener('command', onBlacklistButtonCommand, false)
176 itemPreferences.addEventListener('command', onPreferencesCommand, false)
177 itemHelp.addEventListener('command', onHelpCommand, false)
178
179 button.appendChild(menupopup)
180 return menupopup
181
182 restorePosition = (document, button) ->
183 $(document, 'navigator-toolbox').palette.appendChild(button)
184
185 for tb in $$(document, 'toolbar')
186 currentset = tb.getAttribute('currentset').split(',')
187 idx = currentset.indexOf(button.id)
188 if idx != -1
189 toolbar = tb
190 break
191
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)
197
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)
204 return
205
206 toolbar.insertItem(button.id)
207
208 persist = (document, toolbar, buttonId, beforeId) ->
209 currentset = toolbar.currentSet.split(',')
210 idx = if beforeId then currentset.indexOf(beforeId) else -1
211 if idx != -1
212 currentset.splice(idx, 0, buttonId)
213 else
214 currentset.push(buttonId)
215
216 toolbar.setAttribute('currentset', currentset.join(','))
217 document.persist(toolbar.id, 'currentset')
218 return [currentset, idx]
219
220 updateToolbarButton = (window, { disabled, blacklisted, insertMode }) ->
221 return unless button = $(window.document, BUTTON_ID)
222
223 button.VimFx.disabled = disabled if disabled?
224 button.VimFx.blacklisted = blacklisted if blacklisted?
225 button.VimFx.insertMode = insertMode if insertMode?
226
227 [ icon, tooltip ] = switch
228 when button.VimFx.disabled
229 ['grey', 'disabled']
230 when button.VimFx.blacklisted
231 ['red', 'blacklisted']
232 when button.VimFx.insertMode
233 ['grey', 'insertMode']
234 else
235 ['normal', 'enabled']
236
237 button.style.listStyleImage = iconUrl(icon)
238 button.setAttribute('tooltiptext', _("button_tooltip_#{ tooltip }"))
239
240 iconUrl = (kind) ->
241 url = utils.getResourceURI("resources/icon16-#{ kind }.png").spec
242 return "url(#{ url })"
243
244 exports.setButtonInstallPosition = setButtonInstallPosition
245 exports.addToolbarButton = addToolbarButton
246 exports.updateToolbarButton = updateToolbarButton
Imprint / Impressum