]> git.gir.st - VimFx.git/blob - extension/packages/button.coffee
Merge branch 'develop' into simpler-dom
[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 { unload } = require 'unload'
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, sel) -> document.getElementById(sel)
19 $$ = (document, sel) -> document.querySelectorAll(sel)
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 unload ->
45 button.remove()
46 keyset.remove()
47 $(document, 'navigator-toolbox').palette.removeChild(button)
48
49 createButton = (vimBucket, window) ->
50 document = window.document
51
52 button = utils.createElement(document, 'toolbarbutton', {
53 id: BUTTON_ID
54 type: 'menu-button'
55 label: 'VimFx'
56 class: 'toolbarbutton-1'
57 })
58
59 menupopup = createMenupopup(window, button)
60
61 onButtonCommand = (event) ->
62 switch
63 when button.VimFx.blacklisted
64 menupopup.openPopup(button, 'after_start')
65 when button.VimFx.insertMode
66 return unless currentTabWindow = utils.getEventCurrentTabWindow(event)
67 return unless vim = vimBucket.get(currentTabWindow)
68 updateToolbarButton(window, {insertMode: false})
69 vim.enterMode('normal')
70 else
71 disabled = not getPref('disabled')
72 setPref('disabled', disabled)
73 updateToolbarButton(window, {disabled})
74
75 event.stopPropagation()
76
77 button.addEventListener('command', onButtonCommand, false)
78
79 vimkey = utils.createElement(document, 'key', {
80 id: KEY_ID
81 key: 'V'
82 modifiers: 'shift,alt'
83 oncommand: 'void(0);'
84 })
85 vimkey.addEventListener('command', onButtonCommand, false)
86
87 keyset = utils.createElement(document, 'keyset', {id: KEYSET_ID})
88 keyset.appendChild(vimkey)
89
90 return [button, keyset]
91
92 createMenupopup = (window, button) ->
93 document = window.document
94
95 blacklistTextbox = utils.createElement(document, 'textbox', {
96 id: TEXTBOX_BLACKLIST_ID
97 })
98 blacklistButton = utils.createElement(document, 'toolbarbutton', {
99 id: BUTTON_BLACKLIST_ID
100 class: 'toolbarbutton-1'
101 })
102 blacklistControls = utils.createElement(document, 'hbox')
103 blacklistControls.appendChild(blacklistTextbox)
104 blacklistControls.appendChild(blacklistButton)
105
106 itemPreferences = utils.createElement(document, 'menuitem', {
107 id: MENU_ITEM_PREF
108 label: _('item_preferences')
109 })
110
111 itemHelp = utils.createElement(document, 'menuitem', {
112 id: MENU_ITEM_HELP
113 label: _('help_title')
114 })
115
116 menupopup = utils.createElement(document, 'menupopup', {
117 id: MENUPOPUP_ID
118 ignorekeys: true
119 })
120 menupopup.appendChild(blacklistControls)
121 menupopup.appendChild(itemPreferences)
122 menupopup.appendChild(itemHelp)
123
124 onPopupShowing = (event) ->
125 return unless tabWindow = utils.getCurrentTabWindow(window)
126
127 if button.VimFx.blacklisted
128 matchingRules = utils.getMatchingBlacklistRules(tabWindow.location.href)
129 blacklistTextbox.value = matchingRules.join(', ')
130 blacklistTextbox.setAttribute('readonly', true)
131 blacklistButton.setAttribute('tooltiptext', _('item_blacklist_button_inverse_tooltip'))
132 blacklistButton.style.listStyleImage = iconUrl('blacklist_inverse')
133 else
134 # In `about:` pages, the `host` property is an empty string. Fall back to the whole URL
135 blacklistTextbox.value = "*#{ tabWindow.location.host or tabWindow.location.href }*"
136 blacklistTextbox.removeAttribute('readonly')
137 blacklistButton.setAttribute('tooltiptext', _('item_blacklist_button_tooltip'))
138 blacklistButton.style.listStyleImage = iconUrl('blacklist')
139
140 onBlacklistButtonCommand = (event) ->
141 return unless tabWindow = utils.getCurrentTabWindow(window)
142
143 if button.VimFx.blacklisted
144 utils.updateBlacklist({remove: blacklistTextbox.value})
145 else
146 utils.updateBlacklist({add: blacklistTextbox.value})
147
148 menupopup.hidePopup()
149
150 tabWindow.location.reload(false)
151
152 event.stopPropagation()
153
154 onPreferencesCommand = (event) ->
155 id = encodeURIComponent(getPref('addon_id'))
156 window.BrowserOpenAddonsMgr("addons://detail/#{ id }/preferences")
157
158 event.stopPropagation()
159
160 onHelpCommand = (event) ->
161 if tabWindow = utils.getCurrentTabWindow(window)
162 injectHelp(tabWindow.document, commands)
163
164 event.stopPropagation()
165
166 menupopup.addEventListener('popupshowing', onPopupShowing, false)
167 blacklistButton.addEventListener('command', onBlacklistButtonCommand, false)
168 itemPreferences.addEventListener('command', onPreferencesCommand, false)
169 itemHelp.addEventListener('command', onHelpCommand, false)
170
171 button.appendChild(menupopup)
172 return menupopup
173
174 restorePosition = (document, button) ->
175 $(document, 'navigator-toolbox').palette.appendChild(button)
176
177 for tb in $$(document, 'toolbar')
178 currentset = tb.getAttribute('currentset').split(',')
179 idx = currentset.indexOf(button.id)
180 if idx != -1
181 toolbar = tb
182 break
183
184 # Saved position not found, using the default one, after persisting it
185 if !toolbar and button.id of positions
186 { toolbarId, beforeId } = positions[button.id]
187 if toolbar = $(document, toolbarId)
188 [ currentset, idx ] = persist(document, toolbar, button.id, beforeId)
189
190 if toolbar and idx != -1
191 # Inserting the button before the first item in `currentset`
192 # after `idx` that is present in the document
193 for id in currentset[idx+1..]
194 if before = $(document, id)
195 toolbar.insertItem(button.id, before)
196 return
197
198 toolbar.insertItem(button.id)
199
200 persist = (document, toolbar, buttonId, beforeId) ->
201 currentset = toolbar.currentSet.split(',')
202 idx = if beforeId then currentset.indexOf(beforeId) else -1
203 if idx != -1
204 currentset.splice(idx, 0, buttonId)
205 else
206 currentset.push(buttonId)
207
208 toolbar.setAttribute('currentset', currentset.join(','))
209 document.persist(toolbar.id, 'currentset')
210 return [currentset, idx]
211
212 updateToolbarButton = (window, { disabled, blacklisted, insertMode }) ->
213 return unless button = $(window.document, BUTTON_ID)
214
215 button.VimFx.disabled = disabled if disabled?
216 button.VimFx.blacklisted = blacklisted if blacklisted?
217 button.VimFx.insertMode = insertMode if insertMode?
218
219 [ icon, tooltip ] = switch
220 when button.VimFx.disabled
221 ['grey', 'disabled']
222 when button.VimFx.blacklisted
223 ['red', 'blacklisted']
224 when button.VimFx.insertMode
225 ['grey', 'insertMode']
226 else
227 ['normal', 'enabled']
228
229 button.style.listStyleImage = iconUrl(icon)
230 button.setAttribute('tooltiptext', _("button_tooltip_#{ tooltip }"))
231
232 iconUrl = (kind) ->
233 url = utils.getResourceURI("resources/icon16-#{ kind }.png").spec
234 return "url(#{ url })"
235
236 exports.setButtonInstallPosition = setButtonInstallPosition
237 exports.addToolbarButton = addToolbarButton
238 exports.updateToolbarButton = updateToolbarButton
Imprint / Impressum