Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: lib/customizableUI.js

Issue 5741004535627776: Fix toolbar icon customization in Australis (Closed)
Left Patch Set: Fixed unintentional code duplication Created Nov. 22, 2013, 5:11 p.m.
Right Patch Set: Added 32x32 icon and fixed my own review comments Created Dec. 2, 2013, 10:55 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « lib/appSupport.js ('k') | lib/ui.js » ('j') | lib/ui.js » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 * This file is part of Adblock Plus <http://adblockplus.org/>, 2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2013 Eyeo GmbH 3 * Copyright (C) 2006-2013 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 /** 18 /**
19 * @fileOverview This emulates a subset of the CustomizableUI API from Firefox 2 8. 19 * @fileOverview This emulates a subset of the CustomizableUI API from Firefox 2 8.
20 */ 20 */
21 21
22 let {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", null);
23
22 let {Utils} = require("utils"); 24 let {Utils} = require("utils");
25
26 // UI module has to be referenced lazily to avoid circular references
27 XPCOMUtils.defineLazyGetter(this, "UI", function() require("ui").UI);
23 28
24 let widgets = Map(); 29 let widgets = Map();
25 30
26 function getToolbox(/**Window*/ window, /**Widget*/ widget) /**Element*/ 31 function getToolbox(/**Window*/ window, /**Widget*/ widget) /**Element*/
27 { 32 {
28 if (!("defaultArea" in widget) || !widget.defaultArea) 33 if (!("defaultArea" in widget) || !widget.defaultArea)
29 return null; 34 return null;
30 35
31 let {UI} = require("ui");
32 let toolbar = UI.findElement(window, widget.defaultArea); 36 let toolbar = UI.findElement(window, widget.defaultArea);
33 if (!toolbar) 37 if (!toolbar)
34 return null; 38 return null;
35 39
36 let toolbox = toolbar.toolbox; 40 let toolbox = toolbar.toolbox;
37 if (toolbox && ("palette" in toolbox) && toolbox.palette) 41 if (toolbox && ("palette" in toolbox) && toolbox.palette)
38 return toolbox; 42 return toolbox;
39 else 43 else
40 return null; 44 return null;
41 } 45 }
(...skipping 11 matching lines...) Expand all
53 for (let child of toolbox.palette.children) 57 for (let child of toolbox.palette.children)
54 if (child.id == id) 58 if (child.id == id)
55 return child; 59 return child;
56 60
57 return null; 61 return null;
58 } 62 }
59 63
60 function restoreWidget(/**Element*/ toolbox, /**Widget*/ widget) 64 function restoreWidget(/**Element*/ toolbox, /**Widget*/ widget)
61 { 65 {
62 // Create node 66 // Create node
63 let node = toolbox.ownerDocument.createElement("toolbarbutton"); 67 let node = widget.onBuild(toolbox.ownerDocument);
64 node.setAttribute("id", widget.id);
65 if (typeof widget.onClick == "function") 68 if (typeof widget.onClick == "function")
66 node.addEventListener("click", widget.onClick, false); 69 node.addEventListener("click", widget.onClick, false);
67 if (typeof widget.onCommand == "function") 70 if (typeof widget.onCommand == "function")
68 node.addEventListener("command", widget.onCommand, false); 71 node.addEventListener("command", widget.onCommand, false);
69 if (typeof widget.onCreated == "function")
70 widget.onCreated(node);
71 72
72 // Insert into the palette first 73 // Insert into the palette first
73 toolbox.palette.insertBefore(node, toolbox.palette.firstChild); 74 toolbox.palette.insertBefore(node, toolbox.palette.firstChild);
74 75
75 // Now find out where we should put it 76 // Now find out where we should put it
76 let position = toolbox.getAttribute(widget.positionAttribute); 77 let position = toolbox.getAttribute(widget.positionAttribute);
77 if (!/^\S*,\S*,\S*$/.test(position)) 78 if (!/^\S*,\S*,\S*$/.test(position))
78 position = null; 79 position = null;
79 80
80 if (position == null) 81 if (position == null)
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 if (visible == "visible" && !parent) 126 if (visible == "visible" && !parent)
126 { 127 {
127 let insertionPoint = { 128 let insertionPoint = {
128 parent: widget.defaultArea 129 parent: widget.defaultArea
129 }; 130 };
130 if (typeof widget.defaultBefore != "undefined") 131 if (typeof widget.defaultBefore != "undefined")
131 insertionPoint.before = widget.defaultBefore; 132 insertionPoint.before = widget.defaultBefore;
132 if (typeof widget.defaultAfter != "undefined") 133 if (typeof widget.defaultAfter != "undefined")
133 insertionPoint.after = widget.defaultAfter; 134 insertionPoint.after = widget.defaultAfter;
134 135
135 let {UI} = require("ui");
136 [parent, before] = UI.resolveInsertionPoint(toolbox.ownerDocument.defaultVie w, insertionPoint); 136 [parent, before] = UI.resolveInsertionPoint(toolbox.ownerDocument.defaultVie w, insertionPoint);
137 } 137 }
138 138
139 if (parent && parent.localName != "toolbar") 139 if (parent && parent.localName != "toolbar")
140 parent = null; 140 parent = null;
141 141
142 if (visible != "visible") 142 if (visible != "visible")
143 { 143 {
144 // Move to palette if the item is currently visible 144 // Move to palette if the item is currently visible
145 let node = toolbox.ownerDocument.getElementById(widget.id); 145 let node = toolbox.ownerDocument.getElementById(widget.id);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 saveState(toolbox, widget); 181 saveState(toolbox, widget);
182 } 182 }
183 183
184 function saveState(/**Element*/ toolbox, /**Widget*/ widget) 184 function saveState(/**Element*/ toolbox, /**Widget*/ widget)
185 { 185 {
186 let node = toolbox.ownerDocument.getElementById(widget.id); 186 let node = toolbox.ownerDocument.getElementById(widget.id);
187 187
188 let position = toolbox.getAttribute(widget.positionAttribute) || "hidden,,"; 188 let position = toolbox.getAttribute(widget.positionAttribute) || "hidden,,";
189 if (node) 189 if (node)
190 { 190 {
191 if (typeof widget.onCreated == "function") 191 if (typeof widget.onAdded == "function")
192 widget.onCreated(node); 192 widget.onAdded(node)
193 193
194 let toolbar = getToolbar(node); 194 let toolbar = getToolbar(node);
195 position = "visible," + toolbar.id + "," + (node.nextSibling ? node.nextSibl ing.id : ""); 195 position = "visible," + toolbar.id + "," + (node.nextSibling ? node.nextSibl ing.id : "");
196 } 196 }
197 else 197 else
198 position = position.replace(/^visible,/, "hidden,") 198 position = position.replace(/^visible,/, "hidden,")
199 199
200 toolbox.setAttribute(widget.positionAttribute, position); 200 toolbox.setAttribute(widget.positionAttribute, position);
201 toolbox.ownerDocument.persist(toolbox.id, widget.positionAttribute); 201 toolbox.ownerDocument.persist(toolbox.id, widget.positionAttribute);
202 } 202 }
203 203
204 let CustomizableUI = exports.CustomizableUI = 204 let CustomizableUI = exports.CustomizableUI =
205 { 205 {
206 createWidget: function(widget) 206 createWidget: function(widget)
207 { 207 {
208 if (typeof widget.id == "undefined" || 208 if (typeof widget.id == "undefined" ||
209 typeof widget.defaultArea == "undefined" || 209 typeof widget.defaultArea == "undefined" ||
210 typeof widget.positionAttribute == "undefined") 210 typeof widget.positionAttribute == "undefined")
211 { 211 {
212 throw new Error("Unexpected: required property missing from the widget dat a"); 212 throw new Error("Unexpected: required property missing from the widget dat a");
213 } 213 }
214 widgets.set(widget.id, widget); 214 widgets.set(widget.id, widget);
215 215
216 // Show widget in any existing windows 216 // Show widget in any existing windows
217 let {UI} = require("ui");
218 for (let window of UI.applicationWindows) 217 for (let window of UI.applicationWindows)
219 { 218 {
220 let toolbox = getToolbox(window, widget); 219 let toolbox = getToolbox(window, widget);
221 if (toolbox) 220 if (toolbox)
222 { 221 {
223 toolbox.addEventListener("aftercustomization", onToolbarCustomization, f alse); 222 toolbox.addEventListener("aftercustomization", onToolbarCustomization, f alse);
224 restoreWidget(toolbox, widget); 223 restoreWidget(toolbox, widget);
225 } 224 }
226 } 225 }
227 }, 226 },
228 227
229 destroyWidget: function(id) 228 destroyWidget: function(id)
230 { 229 {
231 // Don't do anything here. This function is called on shutdown, 230 // Don't do anything here. This function is called on shutdown,
232 // removeFromWindow will take care of cleaning up already. 231 // removeFromWindow will take care of cleaning up already.
233 }, 232 },
234 233
235 getPlacementOfWidget: function(id) 234 getPlacementOfWidget: function(id)
236 { 235 {
237 let {UI} = require("ui");
238 let window = UI.currentWindow; 236 let window = UI.currentWindow;
239 if (!window) 237 if (!window)
240 return null; 238 return null;
241 239
242 let widget = window.document.getElementById(id); 240 let widget = window.document.getElementById(id);
243 if (!widget) 241 if (!widget)
244 return null; 242 return null;
245 243
246 let toolbar = getToolbar(widget); 244 let toolbar = getToolbar(widget);
247 if (!toolbar) 245 if (!toolbar)
248 return null; 246 return null;
249 247
250 let items = toolbar.currentSet.split(","); 248 return {area: toolbar.id};
251 let index = items.indexOf(id); 249 },
252 if (index < 0) 250
253 return null; 251 addWidgetToArea: function(id)
254 else 252 {
255 return {area: toolbar.id, placement: index}; 253 // Note: the official API function also has area and position parameters.
256 }, 254 // We ignore those here and simply restore the previous position instead.
257
258 addWidgetToArea: function(id, area, position)
259 {
260 let {UI} = require("ui");
261 let widget = widgets.get(id); 255 let widget = widgets.get(id);
262 for (let window of UI.applicationWindows) 256 for (let window of UI.applicationWindows)
263 { 257 {
264 let toolbox = getToolbox(window, widget); 258 let toolbox = getToolbox(window, widget);
265 if (!toolbox) 259 if (!toolbox)
266 continue; 260 continue;
267 261
268 let position = toolbox.getAttribute(widget.positionAttribute); 262 let position = toolbox.getAttribute(widget.positionAttribute);
269 if (position) 263 if (position)
270 position = position.replace(/^hidden,/, "visible,"); 264 position = position.replace(/^hidden,/, "visible,");
271 showWidget(toolbox, widget, position); 265 showWidget(toolbox, widget, position);
272 } 266 }
273 }, 267 },
274 268
275 removeWidgetFromArea: function(id) 269 removeWidgetFromArea: function(id)
276 { 270 {
277 let {UI} = require("ui");
278 let widget = widgets.get(id); 271 let widget = widgets.get(id);
279 for (let window of UI.applicationWindows) 272 for (let window of UI.applicationWindows)
280 { 273 {
281 let toolbox = getToolbox(window, widget); 274 let toolbox = getToolbox(window, widget);
282 if (!toolbox) 275 if (!toolbox)
283 continue; 276 continue;
284 277
285 let position = toolbox.getAttribute(widget.positionAttribute); 278 let position = toolbox.getAttribute(widget.positionAttribute);
286 if (position) 279 if (position)
287 position = position.replace(/^visible,/, "hidden,"); 280 position = position.replace(/^visible,/, "hidden,");
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 for (let [id, widget] of widgets) 315 for (let [id, widget] of widgets)
323 { 316 {
324 let toolbox = getToolbox(window, widget); 317 let toolbox = getToolbox(window, widget);
325 if (toolbox) 318 if (toolbox)
326 toolbox.removeEventListener("aftercustomization", onToolbarCustomization , false); 319 toolbox.removeEventListener("aftercustomization", onToolbarCustomization , false);
327 320
328 removeWidget(window, widget); 321 removeWidget(window, widget);
329 } 322 }
330 } 323 }
331 }); 324 });
LEFTRIGHT

Powered by Google App Engine
This is Rietveld