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