2 # Copyright Anton Khodakivskiy 2012, 2013, 2014.
3 # Copyright Simon Lydell 2013, 2014.
5 # This file is part of VimFx.
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.
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.
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/>.
22 , setPref } = require('./prefs')
23 { injectHelp } = require('./help')
24 { commands } = require('./commands')
25 utils = require('./utils')
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'
35 $ = (document, selector) -> document.getElementById(selector)
36 $$ = (document, selector) -> document.querySelectorAll(selector)
40 setButtonInstallPosition = (toolbarId, beforeId) ->
41 positions[BUTTON_ID] = {toolbarId, beforeId}
43 addToolbarButton = (vimBucket, window) ->
44 document = window.document
45 win = document.querySelector('window')
47 button = createButton(vimBucket, window)
49 # Namespace to put the VimFx state on, for example.
52 restorePosition(document, button)
54 if tabWindow = utils.getCurrentTabWindow(window)
55 blacklisted = utils.isBlacklisted(tabWindow.location.href)
56 disabled = getPref('disabled')
57 updateToolbarButton(window, {disabled, blacklisted})
61 $(document, 'navigator-toolbox').palette.removeChild(button)
64 createButton = (vimBucket, window) ->
65 document = window.document
67 button = utils.createElement(document, 'toolbarbutton', {
71 class: 'toolbarbutton-1'
74 menupopup = createMenupopup(window, button)
76 onButtonCommand = (event) ->
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')
86 disabled = not getPref('disabled')
87 setPref('disabled', disabled)
88 updateToolbarButton(window, {disabled})
90 event.stopPropagation()
92 button.addEventListener('command', onButtonCommand, false)
96 createMenupopup = (window, button) ->
97 document = window.document
99 blacklistTextbox = utils.createElement(document, 'textbox', {
100 id: TEXTBOX_BLACKLIST_ID
102 blacklistButton = utils.createElement(document, 'toolbarbutton', {
103 id: BUTTON_BLACKLIST_ID
104 class: 'toolbarbutton-1'
106 blacklistControls = utils.createElement(document, 'hbox')
107 blacklistControls.appendChild(blacklistTextbox)
108 blacklistControls.appendChild(blacklistButton)
110 itemPreferences = utils.createElement(document, 'menuitem', {
112 label: _('item_preferences')
115 itemHelp = utils.createElement(document, 'menuitem', {
117 label: _('help_title')
120 menupopup = utils.createElement(document, 'menupopup', {
124 menupopup.appendChild(blacklistControls)
125 menupopup.appendChild(itemPreferences)
126 menupopup.appendChild(itemHelp)
128 onPopupShowing = (event) ->
129 return unless tabWindow = utils.getCurrentTabWindow(window)
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')
139 blacklistTextbox.value =
140 # In `about:` pages, the `host` property is an empty string. Fall back
142 if tabWindow.location.host != ''
143 "*#{ tabWindow.location.host }*"
145 tabWindow.location.href
146 blacklistTextbox.removeAttribute('readonly')
147 blacklistButton.setAttribute('tooltiptext',
148 _('item_blacklist_button_tooltip'))
149 blacklistButton.style.listStyleImage = iconUrl('blacklist')
151 onBlacklistButtonCommand = (event) ->
152 return unless tabWindow = utils.getCurrentTabWindow(window)
154 if button.VimFx.blacklisted
155 utils.updateBlacklist({remove: blacklistTextbox.value})
157 utils.updateBlacklist({add: blacklistTextbox.value})
159 menupopup.hidePopup()
161 tabWindow.location.reload(false)
163 event.stopPropagation()
165 onPreferencesCommand = (event) ->
166 id = encodeURIComponent(utils.ADDON_ID)
167 window.BrowserOpenAddonsMgr("addons://detail/#{ id }/preferences")
169 event.stopPropagation()
171 onHelpCommand = (event) ->
172 if tabWindow = utils.getCurrentTabWindow(window)
173 injectHelp(tabWindow.document, commands)
175 event.stopPropagation()
177 menupopup.addEventListener('popupshowing', onPopupShowing, false)
178 blacklistButton.addEventListener('command', onBlacklistButtonCommand, false)
179 itemPreferences.addEventListener('command', onPreferencesCommand, false)
180 itemHelp.addEventListener('command', onHelpCommand, false)
182 button.appendChild(menupopup)
185 restorePosition = (document, button) ->
186 $(document, 'navigator-toolbox').palette.appendChild(button)
188 for tb in $$(document, 'toolbar')
189 currentset = tb.getAttribute('currentset').split(',')
190 idx = currentset.indexOf(button.id)
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)
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)
209 toolbar.insertItem(button.id)
211 persist = (document, toolbar, buttonId, beforeId) ->
212 currentset = toolbar.currentSet.split(',')
213 idx = if beforeId then currentset.indexOf(beforeId) else -1
215 currentset.splice(idx, 0, buttonId)
217 currentset.push(buttonId)
219 toolbar.setAttribute('currentset', currentset.join(','))
220 document.persist(toolbar.id, 'currentset')
221 return [currentset, idx]
223 updateToolbarButton = (window, { disabled, blacklisted, insertMode }) ->
224 return unless button = $(window.document, BUTTON_ID)
226 button.VimFx.disabled = disabled if disabled?
227 button.VimFx.blacklisted = blacklisted if blacklisted?
228 button.VimFx.insertMode = insertMode if insertMode?
230 [ icon, tooltip ] = switch
231 when button.VimFx.disabled
233 when button.VimFx.blacklisted
234 ['red', 'blacklisted']
235 when button.VimFx.insertMode
236 ['grey', 'insertMode']
238 ['normal', 'enabled']
240 button.style.listStyleImage = iconUrl(icon)
241 button.setAttribute('tooltiptext', _("button_tooltip_#{ tooltip }"))
244 url = utils.getResourceURI("resources/icon16-#{ kind }.png").spec
245 return "url(#{ url })"
247 exports.setButtonInstallPosition = setButtonInstallPosition
248 exports.addToolbarButton = addToolbarButton
249 exports.updateToolbarButton = updateToolbarButton