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