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