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: Created Nov. 22, 2013, 5:06 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");
23 25
26 // UI module has to be referenced lazily to avoid circular references
27 XPCOMUtils.defineLazyGetter(this, "UI", function() require("ui").UI);
28
24 let widgets = Map(); 29 let widgets = Map();
25
26 function findElement(/**Window*/ window, /**String|String[]*/ id) /**Element*/
27 {
28 if (id instanceof Array)
29 {
30 for (let candidate of id)
31 {
32 let result = window.document.getElementById(candidate);
33 if (result)
34 return result;
35 }
36 return null;
37 }
38 else
39 return window.document.getElementById(id);
40 }
41 30
42 function getToolbox(/**Window*/ window, /**Widget*/ widget) /**Element*/ 31 function getToolbox(/**Window*/ window, /**Widget*/ widget) /**Element*/
43 { 32 {
44 if (!("defaultArea" in widget) || !widget.defaultArea) 33 if (!("defaultArea" in widget) || !widget.defaultArea)
45 return null; 34 return null;
46 35
47 let toolbar = findElement(window, widget.defaultArea); 36 let toolbar = UI.findElement(window, widget.defaultArea);
48 if (!toolbar) 37 if (!toolbar)
49 return null; 38 return null;
50 39
51 let toolbox = toolbar.toolbox; 40 let toolbox = toolbar.toolbox;
52 if (toolbox && ("palette" in toolbox) && toolbox.palette) 41 if (toolbox && ("palette" in toolbox) && toolbox.palette)
53 return toolbox; 42 return toolbox;
54 else 43 else
55 return null; 44 return null;
56 } 45 }
57 46
(...skipping 10 matching lines...) Expand all
68 for (let child of toolbox.palette.children) 57 for (let child of toolbox.palette.children)
69 if (child.id == id) 58 if (child.id == id)
70 return child; 59 return child;
71 60
72 return null; 61 return null;
73 } 62 }
74 63
75 function restoreWidget(/**Element*/ toolbox, /**Widget*/ widget) 64 function restoreWidget(/**Element*/ toolbox, /**Widget*/ widget)
76 { 65 {
77 // Create node 66 // Create node
78 let node = toolbox.ownerDocument.createElement("toolbarbutton"); 67 let node = widget.onBuild(toolbox.ownerDocument);
79 node.setAttribute("id", widget.id);
80 if (typeof widget.onClick == "function") 68 if (typeof widget.onClick == "function")
81 node.addEventListener("click", widget.onClick, false); 69 node.addEventListener("click", widget.onClick, false);
82 if (typeof widget.onCommand == "function") 70 if (typeof widget.onCommand == "function")
83 node.addEventListener("command", widget.onCommand, false); 71 node.addEventListener("command", widget.onCommand, false);
84 if (typeof widget.onCreated == "function")
85 widget.onCreated(node);
86 72
87 // Insert into the palette first 73 // Insert into the palette first
88 toolbox.palette.insertBefore(node, toolbox.palette.firstChild); 74 toolbox.palette.insertBefore(node, toolbox.palette.firstChild);
89 75
90 // Now find out where we should put it 76 // Now find out where we should put it
91 let position = toolbox.getAttribute(widget.positionAttribute); 77 let position = toolbox.getAttribute(widget.positionAttribute);
92 if (!/^\S*,\S*,\S*$/.test(position)) 78 if (!/^\S*,\S*,\S*$/.test(position))
93 position = null; 79 position = null;
94 80
95 if (position == null) 81 if (position == null)
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 if (visible == "visible" && !parent) 126 if (visible == "visible" && !parent)
141 { 127 {
142 let insertionPoint = { 128 let insertionPoint = {
143 parent: widget.defaultArea 129 parent: widget.defaultArea
144 }; 130 };
145 if (typeof widget.defaultBefore != "undefined") 131 if (typeof widget.defaultBefore != "undefined")
146 insertionPoint.before = widget.defaultBefore; 132 insertionPoint.before = widget.defaultBefore;
147 if (typeof widget.defaultAfter != "undefined") 133 if (typeof widget.defaultAfter != "undefined")
148 insertionPoint.after = widget.defaultAfter; 134 insertionPoint.after = widget.defaultAfter;
149 135
150 let {UI} = require("ui");
151 [parent, before] = UI.resolveInsertionPoint(toolbox.ownerDocument.defaultVie w, insertionPoint); 136 [parent, before] = UI.resolveInsertionPoint(toolbox.ownerDocument.defaultVie w, insertionPoint);
152 } 137 }
153 138
154 if (parent && parent.localName != "toolbar") 139 if (parent && parent.localName != "toolbar")
155 parent = null; 140 parent = null;
156 141
157 if (visible != "visible") 142 if (visible != "visible")
158 { 143 {
159 // Move to palette if the item is currently visible 144 // Move to palette if the item is currently visible
160 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
196 saveState(toolbox, widget); 181 saveState(toolbox, widget);
197 } 182 }
198 183
199 function saveState(/**Element*/ toolbox, /**Widget*/ widget) 184 function saveState(/**Element*/ toolbox, /**Widget*/ widget)
200 { 185 {
201 let node = toolbox.ownerDocument.getElementById(widget.id); 186 let node = toolbox.ownerDocument.getElementById(widget.id);
202 187
203 let position = toolbox.getAttribute(widget.positionAttribute) || "hidden,,"; 188 let position = toolbox.getAttribute(widget.positionAttribute) || "hidden,,";
204 if (node) 189 if (node)
205 { 190 {
206 if (typeof widget.onCreated == "function") 191 if (typeof widget.onAdded == "function")
207 widget.onCreated(node); 192 widget.onAdded(node)
208 193
209 let toolbar = getToolbar(node); 194 let toolbar = getToolbar(node);
210 position = "visible," + toolbar.id + "," + (node.nextSibling ? node.nextSibl ing.id : ""); 195 position = "visible," + toolbar.id + "," + (node.nextSibling ? node.nextSibl ing.id : "");
211 } 196 }
212 else 197 else
213 position = position.replace(/^visible,/, "hidden,") 198 position = position.replace(/^visible,/, "hidden,")
214 199
215 toolbox.setAttribute(widget.positionAttribute, position); 200 toolbox.setAttribute(widget.positionAttribute, position);
216 toolbox.ownerDocument.persist(toolbox.id, widget.positionAttribute); 201 toolbox.ownerDocument.persist(toolbox.id, widget.positionAttribute);
217 } 202 }
218 203
219 let CustomizableUI = exports.CustomizableUI = 204 let CustomizableUI = exports.CustomizableUI =
220 { 205 {
221 createWidget: function(widget) 206 createWidget: function(widget)
222 { 207 {
223 if (typeof widget.id == "undefined" || 208 if (typeof widget.id == "undefined" ||
224 typeof widget.defaultArea == "undefined" || 209 typeof widget.defaultArea == "undefined" ||
225 typeof widget.positionAttribute == "undefined") 210 typeof widget.positionAttribute == "undefined")
226 { 211 {
227 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");
228 } 213 }
229 widgets.set(widget.id, widget); 214 widgets.set(widget.id, widget);
230 215
231 // Show widget in any existing windows 216 // Show widget in any existing windows
232 let {UI} = require("ui");
233 for (let window of UI.applicationWindows) 217 for (let window of UI.applicationWindows)
234 { 218 {
235 let toolbox = getToolbox(window, widget); 219 let toolbox = getToolbox(window, widget);
236 if (toolbox) 220 if (toolbox)
237 { 221 {
238 toolbox.addEventListener("aftercustomization", onToolbarCustomization, f alse); 222 toolbox.addEventListener("aftercustomization", onToolbarCustomization, f alse);
239 restoreWidget(toolbox, widget); 223 restoreWidget(toolbox, widget);
240 } 224 }
241 } 225 }
242 }, 226 },
243 227
244 destroyWidget: function(id) 228 destroyWidget: function(id)
245 { 229 {
246 // Don't do anything here. This function is called on shutdown, 230 // Don't do anything here. This function is called on shutdown,
247 // removeFromWindow will take care of cleaning up already. 231 // removeFromWindow will take care of cleaning up already.
248 }, 232 },
249 233
250 getPlacementOfWidget: function(id) 234 getPlacementOfWidget: function(id)
251 { 235 {
252 let {UI} = require("ui");
253 let window = UI.currentWindow; 236 let window = UI.currentWindow;
254 if (!window) 237 if (!window)
255 return null; 238 return null;
256 239
257 let widget = window.document.getElementById(id); 240 let widget = window.document.getElementById(id);
258 if (!widget) 241 if (!widget)
259 return null; 242 return null;
260 243
261 let toolbar = getToolbar(widget); 244 let toolbar = getToolbar(widget);
262 if (!toolbar) 245 if (!toolbar)
263 return null; 246 return null;
264 247
265 let items = toolbar.currentSet.split(","); 248 return {area: toolbar.id};
266 let index = items.indexOf(id); 249 },
267 if (index < 0) 250
268 return null; 251 addWidgetToArea: function(id)
269 else 252 {
270 return {area: toolbar.id, placement: index}; 253 // Note: the official API function also has area and position parameters.
271 }, 254 // We ignore those here and simply restore the previous position instead.
272
273 addWidgetToArea: function(id, area, position)
274 {
275 let {UI} = require("ui");
276 let widget = widgets.get(id); 255 let widget = widgets.get(id);
277 for (let window of UI.applicationWindows) 256 for (let window of UI.applicationWindows)
278 { 257 {
279 let toolbox = getToolbox(window, widget); 258 let toolbox = getToolbox(window, widget);
280 if (!toolbox) 259 if (!toolbox)
281 continue; 260 continue;
282 261
283 let position = toolbox.getAttribute(widget.positionAttribute); 262 let position = toolbox.getAttribute(widget.positionAttribute);
284 if (position) 263 if (position)
285 position = position.replace(/^hidden,/, "visible,"); 264 position = position.replace(/^hidden,/, "visible,");
286 showWidget(toolbox, widget, position); 265 showWidget(toolbox, widget, position);
287 } 266 }
288 }, 267 },
289 268
290 removeWidgetFromArea: function(id) 269 removeWidgetFromArea: function(id)
291 { 270 {
292 let {UI} = require("ui");
293 let widget = widgets.get(id); 271 let widget = widgets.get(id);
294 for (let window of UI.applicationWindows) 272 for (let window of UI.applicationWindows)
295 { 273 {
296 let toolbox = getToolbox(window, widget); 274 let toolbox = getToolbox(window, widget);
297 if (!toolbox) 275 if (!toolbox)
298 continue; 276 continue;
299 277
300 let position = toolbox.getAttribute(widget.positionAttribute); 278 let position = toolbox.getAttribute(widget.positionAttribute);
301 if (position) 279 if (position)
302 position = position.replace(/^visible,/, "hidden,"); 280 position = position.replace(/^visible,/, "hidden,");
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 for (let [id, widget] of widgets) 315 for (let [id, widget] of widgets)
338 { 316 {
339 let toolbox = getToolbox(window, widget); 317 let toolbox = getToolbox(window, widget);
340 if (toolbox) 318 if (toolbox)
341 toolbox.removeEventListener("aftercustomization", onToolbarCustomization , false); 319 toolbox.removeEventListener("aftercustomization", onToolbarCustomization , false);
342 320
343 removeWidget(window, widget); 321 removeWidget(window, widget);
344 } 322 }
345 } 323 }
346 }); 324 });
LEFTRIGHT

Powered by Google App Engine
This is Rietveld