]> git.gir.st - VimFx.git/blob - extension/lib/button.coffee
Configure coffeelint and fix lint errors
[VimFx.git] / extension / lib / button.coffee
1 ###
2 # Copyright Anton Khodakivskiy 2012, 2013, 2014.
3 # Copyright Simon Lydell 2013, 2014.
4 #
5 # This file is part of VimFx.
6 #
7 # VimFx is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # VimFx is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with VimFx. If not, see <http://www.gnu.org/licenses/>.
19 ###
20
21 { getPref
22 , setPref } = require('./prefs')
23 { injectHelp } = require('./help')
24 { commands } = require('./commands')
25 utils = require('./utils')
26 _ = require('./l10n')
27
28 KEYSET_ID = 'vimfx-keyset'
29 BUTTON_ID = 'vimfx-toolbar-button'
30 KEY_ID = 'vimfx-key'
31 MENUPOPUP_ID = 'vimfx-menupopup'
32 MENU_ITEM_PREF = 'vimfx-menu-item-preferences'
33 MENU_ITEM_HELP = 'vimfx-menu-item-help'
34 TEXTBOX_BLACKLIST_ID = 'vimfx-textbox-blacklist-id'
35 BUTTON_BLACKLIST_ID = 'vimfx-button-blacklist-id'
36
37 $ = (document, selector) -> document.getElementById(selector)
38 $$ = (document, selector) -> document.querySelectorAll(selector)
39
40 positions = {}
41
42 setButtonInstallPosition = (toolbarId, beforeId) ->
43 positions[BUTTON_ID] = {toolbarId, beforeId}
44
45 addToolbarButton = (vimBucket, window) ->
46 document = window.document
47 win = document.querySelector('window')
48
49 [ button, keyset ] = createButton(vimBucket, window)
50
51 # Namespace to put the VimFx state on, for example.
52 button.VimFx = {}
53
54 restorePosition(document, button)
55
56 if tabWindow = utils.getCurrentTabWindow(window)
57 blacklisted = utils.isBlacklisted(tabWindow.location.href)
58 disabled = getPref('disabled')
59 updateToolbarButton(window, {disabled, blacklisted})
60
61 win.appendChild(keyset)
62
63 module.onShutdown(->
64 button.remove()
65 keyset.remove()
66 $(document, 'navigator-toolbox').palette.removeChild(button)
67 )
68
69 createButton = (vimBucket, window) ->
70 document = window.document
71
72 button = utils.createElement(document, 'toolbarbutton', {
73 id: BUTTON_ID
74 type: 'menu-button'
75 label: 'VimFx'
76 class: 'toolbarbutton-1'
77 })
78
79 menupopup = createMenupopup(window, button)
80
81 onButtonCommand = (event) ->
82 switch
83 when button.VimFx.blacklisted
84 menupopup.openPopup(button, 'after_start')
85 when button.VimFx.insertMode
86 return unless currentTabWindow = utils.getEventCurrentTabWindow(event)
87 return unless vim = vimBucket.get(currentTabWindow)
88 updateToolbarButton(window, {insertMode: false})
89 vim.enterMode('normal')
90 else
91 disabled = not getPref('disabled')
92 setPref('disabled', disabled)
93 updateToolbarButton(window, {disabled})
94
95 event.stopPropagation()
96
97 button.addEventListener('command', onButtonCommand, false)
98
99 vimkey = utils.createElement(document, 'key', {
100 id: KEY_ID
101 key: 'V'
102 modifiers: 'shift,alt'
103 oncommand: 'void(0);'
104 })
105 vimkey.addEventListener('command', onButtonCommand, false)
106
107 keyset = utils.createElement(document, 'keyset', {id: KEYSET_ID})
108 keyset.appendChild(vimkey)
109
110 return [button, keyset]
111
112 createMenupopup = (window, button) ->
113 document = window.document
114
115 blacklistTextbox = utils.createElement(document, 'textbox', {
116 id: TEXTBOX_BLACKLIST_ID
117 })
118 blacklistButton = utils.createElement(document, 'toolbarbutton', {
119 id: BUTTON_BLACKLIST_ID
120 class: 'toolbarbutton-1'
121 })
122 blacklistControls = utils.createElement(document, 'hbox')
123 blacklistControls.appendChild(blacklistTextbox)
124 blacklistControls.appendChild(blacklistButton)
125
126 itemPreferences = utils.createElement(document, 'menuitem', {
127 id: MENU_ITEM_PREF
128 label: _('item_preferences')
129 })
130
131 itemHelp = utils.createElement(document, 'menuitem', {
132 id: MENU_ITEM_HELP
133 label: _('help_title')
134 })
135
136 menupopup = utils.createElement(document, 'menupopup', {
137 id: MENUPOPUP_ID
138 ignorekeys: true
139 })
140 menupopup.appendChild(blacklistControls)
141 menupopup.appendChild(itemPreferences)
142 menupopup.appendChild(itemHelp)
143
144 onPopupShowing = (event) ->
145 return unless tabWindow = utils.getCurrentTabWindow(window)
146
147 if button.VimFx.blacklisted
148 matchingRules = utils.getMatchingBlacklistRules(tabWindow.location.href)
149 blacklistTextbox.value = matchingRules.join(', ')
150 blacklistTextbox.setAttribute('readonly', true)
151 blacklistButton.setAttribute('tooltiptext',
152 _('item_blacklist_button_inverse_tooltip'))
153 blacklistButton.style.listStyleImage = iconUrl('blacklist_inverse')
154 else
155 blacklistTextbox.value =
156 # In `about:` pages, the `host` property is an empty string. Fall back
157 # to the whole URL.
158 if tabWindow.location.host != ''
159 "*#{ tabWindow.location.host }*"
160 else
161 tabWindow.location.href
162 blacklistTextbox.removeAttribute('readonly')
163 blacklistButton.setAttribute('tooltiptext',
164 _('item_blacklist_button_tooltip'))
165 blacklistButton.style.listStyleImage = iconUrl('blacklist')
166
167 onBlacklistButtonCommand = (event) ->
168 return unless tabWindow = utils.getCurrentTabWindow(window)
169
170 if button.VimFx.blacklisted
171 utils.updateBlacklist({remove: blacklistTextbox.value})
172 else
173 utils.updateBlacklist({add: blacklistTextbox.value})
174
175 menupopup.hidePopup()
176
177 tabWindow.location.reload(false)
178
179 event.stopPropagation()
180
181 onPreferencesCommand = (event) ->
182 id = encodeURIComponent(utils.ADDON_ID)
183 window.BrowserOpenAddonsMgr("addons://detail/#{ id }/preferences")
184
185 event.stopPropagation()
186
187 onHelpCommand = (event) ->
188 if tabWindow = utils.getCurrentTabWindow(window)
189 injectHelp(tabWindow.document, commands)
190
191 event.stopPropagation()
192
193 menupopup.addEventListener('popupshowing', onPopupShowing, false)
194 blacklistButton.addEventListener('command', onBlacklistButtonCommand, false)
195 itemPreferences.addEventListener('command', onPreferencesCommand, false)
196 itemHelp.addEventListener('command', onHelpCommand, false)
197
198 button.appendChild(menupopup)
199 return menupopup
200
201 restorePosition = (document, button) ->
202 $(document, 'navigator-toolbox').palette.appendChild(button)
203
204 for tb in $$(document, 'toolbar')
205 currentset = tb.getAttribute('currentset').split(',')
206 idx = currentset.indexOf(button.id)
207 if idx != -1
208 toolbar = tb
209 break
210
211 # Saved position not found, using the default one, after persisting it.
212 if not toolbar and button.id of positions
213 { toolbarId, beforeId } = positions[button.id]
214 if toolbar = $(document, toolbarId)
215 [ currentset, idx ] = persist(document, toolbar, button.id, beforeId)
216
217 if toolbar and idx != -1
218 # Inserting the button before the first item in `currentset`
219 # after `idx` that is present in the document.
220 for id in currentset[idx + 1..]
221 if before = $(document, id)
222 toolbar.insertItem(button.id, before)
223 return
224
225 toolbar.insertItem(button.id)
226
227 persist = (document, toolbar, buttonId, beforeId) ->
228 currentset = toolbar.currentSet.split(',')
229 idx = if beforeId then currentset.indexOf(beforeId) else -1
230 if idx != -1
231 currentset.splice(idx, 0, buttonId)
232 else
233 currentset.push(buttonId)
234
235 toolbar.setAttribute('currentset', currentset.join(','))
236 document.persist(toolbar.id, 'currentset')
237 return [currentset, idx]
238
239 updateToolbarButton = (window, { disabled, blacklisted, insertMode }) ->
240 return unless button = $(window.document, BUTTON_ID)
241
242 button.VimFx.disabled = disabled if disabled?
243 button.VimFx.blacklisted = blacklisted if blacklisted?
244 button.VimFx.insertMode = insertMode if insertMode?
245
246 [ icon, tooltip ] = switch
247 when button.VimFx.disabled
248 ['grey', 'disabled']
249 when button.VimFx.blacklisted
250 ['red', 'blacklisted']
251 when button.VimFx.insertMode
252 ['grey', 'insertMode']
253 else
254 ['normal', 'enabled']
255
256 button.style.listStyleImage = iconUrl(icon)
257 button.setAttribute('tooltiptext', _("button_tooltip_#{ tooltip }"))
258
259 iconUrl = (kind) ->
260 url = utils.getResourceURI("resources/icon16-#{ kind }.png").spec
261 return "url(#{ url })"
262
263 exports.setButtonInstallPosition = setButtonInstallPosition
264 exports.addToolbarButton = addToolbarButton
265 exports.updateToolbarButton = updateToolbarButton
Imprint / Impressum