]> git.gir.st - VimFx.git/blob - extension/packages/button.coffee
Reorganized code, removed memory leaks
[VimFx.git] / extension / packages / button.coffee
1 { getPref
2 , setPref } = require 'prefs'
3 { injectHelp } = require 'help'
4 { commandsHelp } = 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 $ = (doc, sel) -> doc.getElementById(sel)
19 $$ = (doc, sel) -> doc.querySelectorAll(sel)
20
21 positions = {}
22
23 setButtonInstallPosition = (toolbarId, beforeId) ->
24 positions[BUTTON_ID] = [toolbarId, beforeId]
25
26 persist = (document, toolbar, buttonId, beforeId) ->
27 currentset = toolbar.currentSet.split(',')
28 idx = if beforeId then currentset.indexOf(beforeId) else -1
29 if idx != -1
30 currentset.splice(idx, 0, buttonId)
31 else
32 currentset.push(buttonId)
33
34 toolbar.setAttribute('currentset', currentset.join(','))
35 document.persist(toolbar.id, 'currentset')
36 return [currentset, idx]
37
38 restorePosition = (doc, button) ->
39 $(doc, 'navigator-toolbox').palette.appendChild(button)
40
41 for tb in $$(doc, 'toolbar')
42 currentset = tb.getAttribute('currentset').split(',')
43 idx = currentset.indexOf(button.id)
44 if idx != -1
45 toolbar = tb
46 break
47
48 # Saved position not found, using the default one, after persisting it
49 if !toolbar and pos = positions[button.id]
50 [tbID, beforeId] = pos
51 if toolbar = $(doc, tbID)
52 [currentset, idx] = persist(doc, toolbar, button.id, beforeId)
53
54 if toolbar and idx != -1
55 # Inserting the button before the first item in `currentset`
56 # after `idx` that is present in the document
57 for i in [idx + 1 ... currentset.length]
58 if before = $(doc, currentset[i])
59 toolbar.insertItem(button.id, before)
60 return
61
62 toolbar.insertItem(button.id)
63
64 iconUrl = do ->
65 kinds =
66 normal: utils.getResourceURI('resources/icon16.png').spec
67 grey: utils.getResourceURI('resources/icon16-grey.png').spec
68 red: utils.getResourceURI('resources/icon16-red.png').spec
69 blacklist: utils.getResourceURI('resources/icon16-blacklist.png').spec
70
71 return (kind) -> "url(#{ kinds[kind] })"
72
73
74 createMenupopup = (window) ->
75 doc = window.document
76
77 blacklistTextbox = doc.createElement('textbox')
78 blacklistTextbox.id = TEXTBOX_BLACKLIST_ID
79 blacklistButton = doc.createElement('toolbarbutton')
80 blacklistButton.id = BUTTON_BLACKLIST_ID
81 blacklistButton.setAttribute('tooltiptext', _('item_blacklist_button_tooltip'))
82 blacklistButton.setAttribute('class', 'toolbarbutton-1')
83 blacklistButton.style.listStyleImage = iconUrl('blacklist')
84 hbox = doc.createElement('hbox')
85 hbox.appendChild(blacklistTextbox)
86 hbox.appendChild(blacklistButton)
87
88 itemPreferences = doc.createElement('menuitem')
89 itemPreferences.id = MENU_ITEM_PREF
90 itemPreferences.setAttribute('label', _('item_preferences'))
91
92 itemHelp = doc.createElement('menuitem')
93 itemHelp.id = MENU_ITEM_HELP
94 itemHelp.setAttribute('label', _('item_help'))
95
96 menupopup = doc.createElement('menupopup')
97 menupopup.id = MENUPOPUP_ID
98 menupopup.setAttribute('ignorekeys', true)
99 menupopup.appendChild(hbox)
100 menupopup.appendChild(itemPreferences)
101 menupopup.appendChild(itemHelp)
102
103 onPopupShowing = (event) ->
104 if tabWindow = window.gBrowser.selectedTab.linkedBrowser.contentWindow
105 blacklistTextbox.value = "*#{ tabWindow.location.host }*"
106
107 onBlacklistButtonCommand = (event) ->
108 blackList = getPref('black_list')
109 blackList += ', ' if blackList.length > 0
110 blackList += blacklistTextbox.value
111
112 setPref('black_list', blackList)
113 menupopup.hidePopup()
114
115 if tabWindow = window.gBrowser.selectedTab.linkedBrowser.contentWindow
116 tabWindow.location.reload(false)
117
118 event.stopPropagation()
119
120 onPreferencesCommand = (event) ->
121 id = encodeURIComponent(getPref('addon_id'))
122 window.BrowserOpenAddonsMgr("addons://detail/#{ id }/preferences")
123
124 event.stopPropagation()
125
126 onHelpCommand = (event) ->
127 if tabWindow = window.gBrowser.selectedTab.linkedBrowser.contentWindow
128 injectHelp(tabWindow.document, commandsHelp)
129
130 event.stopPropagation()
131
132 menupopup.addEventListener 'popupshowing', onPopupShowing, false
133 blacklistButton.addEventListener 'command', onBlacklistButtonCommand, false
134 itemPreferences.addEventListener 'command', onPreferencesCommand, false
135 itemHelp.addEventListener 'command', onHelpCommand, false
136
137 return menupopup
138
139 createButton = (window) ->
140 doc = window.document
141
142 button = doc.createElement('toolbarbutton')
143 button.setAttribute('id', BUTTON_ID)
144 button.setAttribute('type', 'menu-button')
145 button.setAttribute('label', 'VimFx')
146 button.setAttribute('class', 'toolbarbutton-1')
147
148 # Create and install event listeners
149 onButtonCommand = (event) ->
150 # Change disabled state value which is stored in Prefs
151 setPref('disabled', not getPref 'disabled')
152 updateToolbarButton(button)
153
154 event.stopPropagation()
155
156 button.addEventListener('command', onButtonCommand, false)
157
158 menupopup = createMenupopup(window)
159 button.appendChild(menupopup)
160
161 vimkey = doc.createElement('key')
162 vimkey.setAttribute('id', KEY_ID)
163 vimkey.setAttribute('key', 'V')
164 vimkey.setAttribute('modifiers', 'shift,alt')
165 vimkey.setAttribute('oncommand', 'void(0);')
166 vimkey.addEventListener('command', onButtonCommand, false)
167
168 keyset = doc.createElement('keyset')
169 keyset.setAttribute('id', KEYSET_ID)
170 keyset.appendChild(vimkey)
171
172 return [button, keyset]
173
174 addToolbarButton = (window) ->
175 doc = window.document
176 win = doc.querySelector('window')
177
178 [button, keyset] = createButton(window)
179 updateToolbarButton(button)
180
181 restorePosition(doc, button)
182 win.appendChild(keyset)
183
184 unload ->
185 if buttonParent = button.parentNode
186 buttonParent.removeChild(button)
187 if keysetParent = keyset.parentNode
188 keysetParent.removeChild(keyset)
189 $(doc, 'navigator-toolbox').palette.removeChild(button)
190
191 updateToolbarButton = (button) ->
192 if getPref('disabled')
193 button.style.listStyleImage = iconUrl('grey')
194 button.setAttribute('tooltiptext', _('button_tooltip_disabled'))
195 else if button['VimFx_blacklisted']
196 button.style.listStyleImage = iconUrl('red')
197 button.setAttribute('tooltiptext', _('button_tooltip_blacklisted'))
198 else
199 button.style.listStyleImage = iconUrl('normal')
200 button.setAttribute('tooltiptext', _('button_tooltip_enabled'))
201
202 setWindowBlacklisted = (window, blacklisted) ->
203 if button = $(window.document, BUTTON_ID)
204 button['VimFx_blacklisted'] = blacklisted
205 updateToolbarButton(button)
206
207 exports.addToolbarButton = addToolbarButton
208 exports.setWindowBlacklisted = setWindowBlacklisted
209 exports.setButtonInstallPosition = setButtonInstallPosition
Imprint / Impressum