browser/components/customizableui/content/toolbar.xml

Wed, 31 Dec 2014 07:53:36 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:53:36 +0100
branch
TOR_BUG_3246
changeset 5
4ab42b5ab56c
permissions
-rw-r--r--

Correct small whitespace inconsistency, lost while renaming variables.

michael@0 1 <?xml version="1.0"?>
michael@0 2 <!-- This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 - License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
michael@0 5
michael@0 6 <bindings id="browserToolbarBindings"
michael@0 7 xmlns="http://www.mozilla.org/xbl"
michael@0 8 xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
michael@0 9 xmlns:xbl="http://www.mozilla.org/xbl">
michael@0 10
michael@0 11 <binding id="toolbar" role="xul:toolbar">
michael@0 12 <resources>
michael@0 13 <stylesheet src="chrome://global/skin/toolbar.css"/>
michael@0 14 </resources>
michael@0 15 <implementation>
michael@0 16 <field name="overflowedDuringConstruction">null</field>
michael@0 17
michael@0 18 <constructor><![CDATA[
michael@0 19 let scope = {};
michael@0 20 Cu.import("resource:///modules/CustomizableUI.jsm", scope);
michael@0 21 // Add an early overflow event listener that will mark if the
michael@0 22 // toolbar overflowed during construction.
michael@0 23 if (scope.CustomizableUI.isAreaOverflowable(this.id)) {
michael@0 24 this.addEventListener("overflow", this);
michael@0 25 this.addEventListener("underflow", this);
michael@0 26 }
michael@0 27
michael@0 28 if (document.readyState == "complete") {
michael@0 29 this._init();
michael@0 30 } else {
michael@0 31 // Need to wait until XUL overlays are loaded. See bug 554279.
michael@0 32 let self = this;
michael@0 33 document.addEventListener("readystatechange", function onReadyStateChange() {
michael@0 34 if (document.readyState != "complete")
michael@0 35 return;
michael@0 36 document.removeEventListener("readystatechange", onReadyStateChange, false);
michael@0 37 self._init();
michael@0 38 }, false);
michael@0 39 }
michael@0 40 ]]></constructor>
michael@0 41
michael@0 42 <method name="_init">
michael@0 43 <body><![CDATA[
michael@0 44 let scope = {};
michael@0 45 Cu.import("resource:///modules/CustomizableUI.jsm", scope);
michael@0 46 let CustomizableUI = scope.CustomizableUI;
michael@0 47
michael@0 48 // Bug 989289: Forcibly set the now unsupported "mode" and "iconsize"
michael@0 49 // attributes, just in case they accidentally get restored from
michael@0 50 // persistence from a user that's been upgrading and downgrading.
michael@0 51 if (CustomizableUI.isBuiltinToolbar(this.id)) {
michael@0 52 const kAttributes = new Map([["mode", "icons"], ["iconsize", "small"]]);
michael@0 53 for (let [attribute, value] of kAttributes) {
michael@0 54 if (this.getAttribute(attribute) != value) {
michael@0 55 this.setAttribute(attribute, value);
michael@0 56 document.persist(this.id, attribute);
michael@0 57 }
michael@0 58 if (this.toolbox) {
michael@0 59 if (this.toolbox.getAttribute(attribute) != value) {
michael@0 60 this.toolbox.setAttribute(attribute, value);
michael@0 61 document.persist(this.toolbox.id, attribute);
michael@0 62 }
michael@0 63 }
michael@0 64 }
michael@0 65 }
michael@0 66
michael@0 67 // Searching for the toolbox palette in the toolbar binding because
michael@0 68 // toolbars are constructed first.
michael@0 69 let toolbox = this.toolbox;
michael@0 70 if (toolbox && !toolbox.palette) {
michael@0 71 for (let node of toolbox.children) {
michael@0 72 if (node.localName == "toolbarpalette") {
michael@0 73 // Hold on to the palette but remove it from the document.
michael@0 74 toolbox.palette = node;
michael@0 75 toolbox.removeChild(node);
michael@0 76 break;
michael@0 77 }
michael@0 78 }
michael@0 79 }
michael@0 80
michael@0 81 // pass the current set of children for comparison with placements:
michael@0 82 let children = [node.id for (node of this.childNodes)
michael@0 83 if (node.getAttribute("skipintoolbarset") != "true" && node.id)];
michael@0 84 CustomizableUI.registerToolbarNode(this, children);
michael@0 85 ]]></body>
michael@0 86 </method>
michael@0 87
michael@0 88 <method name="handleEvent">
michael@0 89 <parameter name="aEvent"/>
michael@0 90 <body><![CDATA[
michael@0 91 if (aEvent.type == "overflow" && aEvent.detail > 0) {
michael@0 92 if (this.overflowable && this.overflowable.initialized) {
michael@0 93 this.overflowable.onOverflow(aEvent);
michael@0 94 } else {
michael@0 95 this.overflowedDuringConstruction = aEvent;
michael@0 96 }
michael@0 97 } else if (aEvent.type == "underflow" && aEvent.detail > 0) {
michael@0 98 this.overflowedDuringConstruction = null;
michael@0 99 }
michael@0 100 ]]></body>
michael@0 101 </method>
michael@0 102
michael@0 103 <method name="insertItem">
michael@0 104 <parameter name="aId"/>
michael@0 105 <parameter name="aBeforeElt"/>
michael@0 106 <parameter name="aWrapper"/>
michael@0 107 <body><![CDATA[
michael@0 108 if (aWrapper) {
michael@0 109 Cu.reportError("Can't insert " + aId + ": using insertItem " +
michael@0 110 "no longer supports wrapper elements.");
michael@0 111 return null;
michael@0 112 }
michael@0 113
michael@0 114 // Hack, the customizable UI code makes this be the last position
michael@0 115 let pos = null;
michael@0 116 if (aBeforeElt) {
michael@0 117 let beforeInfo = CustomizableUI.getPlacementOfWidget(aBeforeElt.id);
michael@0 118 if (beforeInfo.area != this.id) {
michael@0 119 Cu.reportError("Can't insert " + aId + " before " +
michael@0 120 aBeforeElt.id + " which isn't in this area (" +
michael@0 121 this.id + ").");
michael@0 122 return null;
michael@0 123 }
michael@0 124 pos = beforeInfo.position;
michael@0 125 }
michael@0 126
michael@0 127 CustomizableUI.addWidgetToArea(aId, this.id, pos);
michael@0 128 return this.ownerDocument.getElementById(aId);
michael@0 129 ]]></body>
michael@0 130 </method>
michael@0 131
michael@0 132 <property name="toolbarName"
michael@0 133 onget="return this.getAttribute('toolbarname');"
michael@0 134 onset="this.setAttribute('toolbarname', val); return val;"/>
michael@0 135
michael@0 136 <property name="customizationTarget" readonly="true">
michael@0 137 <getter><![CDATA[
michael@0 138 if (this._customizationTarget)
michael@0 139 return this._customizationTarget;
michael@0 140
michael@0 141 let id = this.getAttribute("customizationtarget");
michael@0 142 if (id)
michael@0 143 this._customizationTarget = document.getElementById(id);
michael@0 144
michael@0 145 if (this._customizationTarget)
michael@0 146 this._customizationTarget.insertItem = this.insertItem.bind(this);
michael@0 147 else
michael@0 148 this._customizationTarget = this;
michael@0 149
michael@0 150 return this._customizationTarget;
michael@0 151 ]]></getter>
michael@0 152 </property>
michael@0 153
michael@0 154 <property name="toolbox" readonly="true">
michael@0 155 <getter><![CDATA[
michael@0 156 if (this._toolbox)
michael@0 157 return this._toolbox;
michael@0 158
michael@0 159 let toolboxId = this.getAttribute("toolboxid");
michael@0 160 if (toolboxId) {
michael@0 161 let toolbox = document.getElementById(toolboxId);
michael@0 162 if (toolbox) {
michael@0 163 if (toolbox.externalToolbars.indexOf(this) == -1)
michael@0 164 toolbox.externalToolbars.push(this);
michael@0 165
michael@0 166 this._toolbox = toolbox;
michael@0 167 }
michael@0 168 }
michael@0 169
michael@0 170 if (!this._toolbox && this.parentNode &&
michael@0 171 this.parentNode.localName == "toolbox") {
michael@0 172 this._toolbox = this.parentNode;
michael@0 173 }
michael@0 174
michael@0 175 return this._toolbox;
michael@0 176 ]]></getter>
michael@0 177 </property>
michael@0 178
michael@0 179 <property name="currentSet">
michael@0 180 <getter><![CDATA[
michael@0 181 let currentWidgets = new Set();
michael@0 182 for (let node of this.customizationTarget.children) {
michael@0 183 let realNode = node.localName == "toolbarpaletteitem" ? node.firstChild : node;
michael@0 184 if (realNode.getAttribute("skipintoolbarset") != "true") {
michael@0 185 currentWidgets.add(realNode.id);
michael@0 186 }
michael@0 187 }
michael@0 188 if (this.getAttribute("overflowing") == "true") {
michael@0 189 let overflowTarget = this.getAttribute("overflowtarget");
michael@0 190 let overflowList = this.ownerDocument.getElementById(overflowTarget);
michael@0 191 for (let node of overflowList.children) {
michael@0 192 let realNode = node.localName == "toolbarpaletteitem" ? node.firstChild : node;
michael@0 193 if (realNode.getAttribute("skipintoolbarset") != "true") {
michael@0 194 currentWidgets.add(realNode.id);
michael@0 195 }
michael@0 196 }
michael@0 197 }
michael@0 198 let orderedPlacements = CustomizableUI.getWidgetIdsInArea(this.id);
michael@0 199 return orderedPlacements.filter((x) => currentWidgets.has(x)).join(',');
michael@0 200 ]]></getter>
michael@0 201 <setter><![CDATA[
michael@0 202 // Get list of new and old ids:
michael@0 203 let newVal = (val || '').split(',').filter(x => x);
michael@0 204 let oldIds = CustomizableUI.getWidgetIdsInArea(this.id);
michael@0 205
michael@0 206 // Get a list of items only in the new list
michael@0 207 let newIds = [id for (id of newVal) if (oldIds.indexOf(id) == -1)];
michael@0 208 CustomizableUI.beginBatchUpdate();
michael@0 209 try {
michael@0 210 for (let newId of newIds) {
michael@0 211 oldIds = CustomizableUI.getWidgetIdsInArea(this.id);
michael@0 212 let nextId = newId;
michael@0 213 let pos;
michael@0 214 do {
michael@0 215 // Get the next item
michael@0 216 nextId = newVal[newVal.indexOf(nextId) + 1];
michael@0 217 // Figure out where it is in the old list
michael@0 218 pos = oldIds.indexOf(nextId);
michael@0 219 // If it's not in the old list, repeat:
michael@0 220 } while (pos == -1 && nextId);
michael@0 221 if (pos == -1) {
michael@0 222 pos = null; // We didn't find anything, insert at the end
michael@0 223 }
michael@0 224 CustomizableUI.addWidgetToArea(newId, this.id, pos);
michael@0 225 }
michael@0 226
michael@0 227 let currentIds = this.currentSet.split(',');
michael@0 228 let removedIds = [id for (id of currentIds) if (newIds.indexOf(id) == -1 && newVal.indexOf(id) == -1)];
michael@0 229 for (let removedId of removedIds) {
michael@0 230 CustomizableUI.removeWidgetFromArea(removedId);
michael@0 231 }
michael@0 232 } finally {
michael@0 233 CustomizableUI.endBatchUpdate();
michael@0 234 }
michael@0 235 ]]></setter>
michael@0 236 </property>
michael@0 237
michael@0 238
michael@0 239 </implementation>
michael@0 240 </binding>
michael@0 241
michael@0 242 <binding id="toolbar-menubar-stub">
michael@0 243 <implementation>
michael@0 244 <property name="toolbox" readonly="true">
michael@0 245 <getter><![CDATA[
michael@0 246 if (this._toolbox)
michael@0 247 return this._toolbox;
michael@0 248
michael@0 249 if (this.parentNode && this.parentNode.localName == "toolbox") {
michael@0 250 this._toolbox = this.parentNode;
michael@0 251 }
michael@0 252
michael@0 253 return this._toolbox;
michael@0 254 ]]></getter>
michael@0 255 </property>
michael@0 256 <property name="currentSet" readonly="true">
michael@0 257 <getter><![CDATA[
michael@0 258 return this.getAttribute("defaultset");
michael@0 259 ]]></getter>
michael@0 260 </property>
michael@0 261 <method name="insertItem">
michael@0 262 <body><![CDATA[
michael@0 263 return null;
michael@0 264 ]]></body>
michael@0 265 </method>
michael@0 266 </implementation>
michael@0 267 </binding>
michael@0 268
michael@0 269 <!-- The toolbar-menubar-autohide and toolbar-drag bindings are almost
michael@0 270 verbatim copies of their toolkit counterparts - they just inherit from
michael@0 271 the customizableui's toolbar binding instead of toolkit's. We're currently
michael@0 272 OK with the maintainance burden of having two copies of a binding, since
michael@0 273 the long term goal is to move the customization framework into toolkit. -->
michael@0 274
michael@0 275 <binding id="toolbar-menubar-autohide"
michael@0 276 extends="chrome://browser/content/customizableui/toolbar.xml#toolbar">
michael@0 277 <implementation>
michael@0 278 <constructor>
michael@0 279 this._setInactive();
michael@0 280 </constructor>
michael@0 281 <destructor>
michael@0 282 this._setActive();
michael@0 283 </destructor>
michael@0 284
michael@0 285 <field name="_inactiveTimeout">null</field>
michael@0 286
michael@0 287 <field name="_contextMenuListener"><![CDATA[({
michael@0 288 toolbar: this,
michael@0 289 contextMenu: null,
michael@0 290
michael@0 291 get active () !!this.contextMenu,
michael@0 292
michael@0 293 init: function (event) {
michael@0 294 let node = event.target;
michael@0 295 while (node != this.toolbar) {
michael@0 296 if (node.localName == "menupopup")
michael@0 297 return;
michael@0 298 node = node.parentNode;
michael@0 299 }
michael@0 300
michael@0 301 let contextMenuId = this.toolbar.getAttribute("context");
michael@0 302 if (!contextMenuId)
michael@0 303 return;
michael@0 304
michael@0 305 this.contextMenu = document.getElementById(contextMenuId);
michael@0 306 if (!this.contextMenu)
michael@0 307 return;
michael@0 308
michael@0 309 this.contextMenu.addEventListener("popupshown", this, false);
michael@0 310 this.contextMenu.addEventListener("popuphiding", this, false);
michael@0 311 this.toolbar.addEventListener("mousemove", this, false);
michael@0 312 },
michael@0 313 handleEvent: function (event) {
michael@0 314 switch (event.type) {
michael@0 315 case "popupshown":
michael@0 316 this.toolbar.removeEventListener("mousemove", this, false);
michael@0 317 break;
michael@0 318 case "popuphiding":
michael@0 319 case "mousemove":
michael@0 320 this.toolbar._setInactiveAsync();
michael@0 321 this.toolbar.removeEventListener("mousemove", this, false);
michael@0 322 this.contextMenu.removeEventListener("popuphiding", this, false);
michael@0 323 this.contextMenu.removeEventListener("popupshown", this, false);
michael@0 324 this.contextMenu = null;
michael@0 325 break;
michael@0 326 }
michael@0 327 }
michael@0 328 })]]></field>
michael@0 329
michael@0 330 <method name="_setInactive">
michael@0 331 <body><![CDATA[
michael@0 332 this.setAttribute("inactive", "true");
michael@0 333 ]]></body>
michael@0 334 </method>
michael@0 335
michael@0 336 <method name="_setInactiveAsync">
michael@0 337 <body><![CDATA[
michael@0 338 this._inactiveTimeout = setTimeout(function (self) {
michael@0 339 if (self.getAttribute("autohide") == "true") {
michael@0 340 self._inactiveTimeout = null;
michael@0 341 self._setInactive();
michael@0 342 }
michael@0 343 }, 0, this);
michael@0 344 ]]></body>
michael@0 345 </method>
michael@0 346
michael@0 347 <method name="_setActive">
michael@0 348 <body><![CDATA[
michael@0 349 if (this._inactiveTimeout) {
michael@0 350 clearTimeout(this._inactiveTimeout);
michael@0 351 this._inactiveTimeout = null;
michael@0 352 }
michael@0 353 this.removeAttribute("inactive");
michael@0 354 ]]></body>
michael@0 355 </method>
michael@0 356 </implementation>
michael@0 357
michael@0 358 <handlers>
michael@0 359 <handler event="DOMMenuBarActive" action="this._setActive();"/>
michael@0 360 <handler event="popupshowing" action="this._setActive();"/>
michael@0 361 <handler event="mousedown" button="2" action="this._contextMenuListener.init(event);"/>
michael@0 362 <handler event="DOMMenuBarInactive"><![CDATA[
michael@0 363 if (!this._contextMenuListener.active)
michael@0 364 this._setInactiveAsync();
michael@0 365 ]]></handler>
michael@0 366 </handlers>
michael@0 367 </binding>
michael@0 368
michael@0 369 <binding id="toolbar-drag"
michael@0 370 extends="chrome://browser/content/customizableui/toolbar.xml#toolbar">
michael@0 371 <implementation>
michael@0 372 <field name="_dragBindingAlive">true</field>
michael@0 373 <constructor><![CDATA[
michael@0 374 if (!this._draggableStarted) {
michael@0 375 this._draggableStarted = true;
michael@0 376 try {
michael@0 377 let tmp = {};
michael@0 378 Components.utils.import("resource://gre/modules/WindowDraggingUtils.jsm", tmp);
michael@0 379 let draggableThis = new tmp.WindowDraggingElement(this);
michael@0 380 draggableThis.mouseDownCheck = function(e) {
michael@0 381 return this._dragBindingAlive;
michael@0 382 };
michael@0 383 } catch (e) {}
michael@0 384 }
michael@0 385 ]]></constructor>
michael@0 386 </implementation>
michael@0 387 </binding>
michael@0 388
michael@0 389
michael@0 390 <!-- This is a peculiar binding. It is here to deal with overlayed/inserted add-on content,
michael@0 391 and immediately direct such content elsewhere. -->
michael@0 392 <binding id="addonbar-delegating">
michael@0 393 <implementation>
michael@0 394 <constructor><![CDATA[
michael@0 395 // Reading these immediately so nobody messes with them anymore:
michael@0 396 this._delegatingToolbar = this.getAttribute("toolbar-delegate");
michael@0 397 this._wasCollapsed = this.getAttribute("collapsed") == "true";
michael@0 398 // Leaving those in here to unbreak some code:
michael@0 399 if (document.readyState == "complete") {
michael@0 400 this._init();
michael@0 401 } else {
michael@0 402 // Need to wait until XUL overlays are loaded. See bug 554279.
michael@0 403 let self = this;
michael@0 404 document.addEventListener("readystatechange", function onReadyStateChange() {
michael@0 405 if (document.readyState != "complete")
michael@0 406 return;
michael@0 407 document.removeEventListener("readystatechange", onReadyStateChange, false);
michael@0 408 self._init();
michael@0 409 }, false);
michael@0 410 }
michael@0 411 ]]></constructor>
michael@0 412
michael@0 413 <method name="_init">
michael@0 414 <body><![CDATA[
michael@0 415 // Searching for the toolbox palette in the toolbar binding because
michael@0 416 // toolbars are constructed first.
michael@0 417 let toolbox = this.toolbox;
michael@0 418 if (toolbox && !toolbox.palette) {
michael@0 419 for (let node of toolbox.children) {
michael@0 420 if (node.localName == "toolbarpalette") {
michael@0 421 // Hold on to the palette but remove it from the document.
michael@0 422 toolbox.palette = node;
michael@0 423 toolbox.removeChild(node);
michael@0 424 }
michael@0 425 }
michael@0 426 }
michael@0 427
michael@0 428 // pass the current set of children for comparison with placements:
michael@0 429 let children = [];
michael@0 430 for (let node of this.childNodes) {
michael@0 431 if (node.getAttribute("skipintoolbarset") != "true" && node.id) {
michael@0 432 // Force everything to be removable so that buildArea can chuck stuff
michael@0 433 // out if the user has customized things / we've been here before:
michael@0 434 if (!this._whiteListed.has(node.id)) {
michael@0 435 node.setAttribute("removable", "true");
michael@0 436 }
michael@0 437 children.push(node);
michael@0 438 }
michael@0 439 }
michael@0 440 CustomizableUI.registerToolbarNode(this, children);
michael@0 441 let existingMigratedItems = (this.getAttribute("migratedset") || "").split(',');
michael@0 442 for (let migratedItem of existingMigratedItems.filter((x) => !!x)) {
michael@0 443 this._currentSetMigrated.add(migratedItem);
michael@0 444 }
michael@0 445 this.evictNodes();
michael@0 446 // We can't easily use |this| or strong bindings for the observer fn here
michael@0 447 // because that creates leaky circular references when the node goes away,
michael@0 448 // and XBL destructors are unreliable.
michael@0 449 let mutationObserver = new MutationObserver(function(mutations) {
michael@0 450 if (!mutations.length) {
michael@0 451 return;
michael@0 452 }
michael@0 453 let toolbar = mutations[0].target;
michael@0 454 // Can't use our own attribute because we might not have one if we're set to
michael@0 455 // collapsed
michael@0 456 let areCustomizing = toolbar.ownerDocument.documentElement.getAttribute("customizing");
michael@0 457 if (!toolbar._isModifying && !areCustomizing) {
michael@0 458 toolbar.evictNodes();
michael@0 459 }
michael@0 460 });
michael@0 461 mutationObserver.observe(this, {childList: true});
michael@0 462 ]]></body>
michael@0 463 </method>
michael@0 464 <method name="evictNodes">
michael@0 465 <body><![CDATA[
michael@0 466 this._isModifying = true;
michael@0 467 let i = this.childNodes.length;
michael@0 468 while (i--) {
michael@0 469 let node = this.childNodes[i];
michael@0 470 if (this.childNodes[i].id) {
michael@0 471 this.evictNode(this.childNodes[i]);
michael@0 472 } else {
michael@0 473 node.remove();
michael@0 474 }
michael@0 475 }
michael@0 476 this._isModifying = false;
michael@0 477 this._updateMigratedSet();
michael@0 478 ]]></body>
michael@0 479 </method>
michael@0 480 <method name="evictNode">
michael@0 481 <parameter name="aNode"/>
michael@0 482 <body>
michael@0 483 <![CDATA[
michael@0 484 if (this._whiteListed.has(aNode.id) || CustomizableUI.isSpecialWidget(aNode.id)) {
michael@0 485 return;
michael@0 486 }
michael@0 487 const kItemMaxWidth = 100;
michael@0 488 let oldParent = aNode.parentNode;
michael@0 489 aNode.setAttribute("removable", "true");
michael@0 490 this._currentSetMigrated.add(aNode.id);
michael@0 491
michael@0 492 let movedOut = false;
michael@0 493 if (!this._wasCollapsed) {
michael@0 494 try {
michael@0 495 let nodeWidth = aNode.getBoundingClientRect().width;
michael@0 496 if (nodeWidth == 0 || nodeWidth > kItemMaxWidth) {
michael@0 497 throw new Error(aNode.id + " is too big (" + nodeWidth +
michael@0 498 "px wide), moving to the palette");
michael@0 499 }
michael@0 500 CustomizableUI.addWidgetToArea(aNode.id, this._delegatingToolbar);
michael@0 501 movedOut = true;
michael@0 502 } catch (ex) {
michael@0 503 // This will throw if the node is too big, or can't be moved there for
michael@0 504 // some reason. Report this:
michael@0 505 Cu.reportError(ex);
michael@0 506 }
michael@0 507 }
michael@0 508
michael@0 509 /* We won't have moved the widget if either the add-on bar was collapsed,
michael@0 510 * or if it was too wide to be inserted into the navbar. */
michael@0 511 if (!movedOut) {
michael@0 512 try {
michael@0 513 CustomizableUI.removeWidgetFromArea(aNode.id);
michael@0 514 } catch (ex) {
michael@0 515 Cu.reportError(ex);
michael@0 516 aNode.remove();
michael@0 517 }
michael@0 518 }
michael@0 519
michael@0 520 // Surprise: addWidgetToArea(palette) will get you nothing if the palette
michael@0 521 // is not constructed yet. Fix:
michael@0 522 if (aNode.parentNode == oldParent) {
michael@0 523 let palette = this.toolbox.palette;
michael@0 524 if (palette && oldParent != palette) {
michael@0 525 palette.appendChild(aNode);
michael@0 526 }
michael@0 527 }
michael@0 528 ]]></body>
michael@0 529 </method>
michael@0 530 <method name="insertItem">
michael@0 531 <parameter name="aId"/>
michael@0 532 <parameter name="aBeforeElt"/>
michael@0 533 <parameter name="aWrapper"/>
michael@0 534 <body><![CDATA[
michael@0 535 if (aWrapper) {
michael@0 536 Cu.reportError("Can't insert " + aId + ": using insertItem " +
michael@0 537 "no longer supports wrapper elements.");
michael@0 538 return null;
michael@0 539 }
michael@0 540
michael@0 541 let widget = CustomizableUI.getWidget(aId);
michael@0 542 widget = widget && widget.forWindow(window);
michael@0 543 let node = widget && widget.node;
michael@0 544 if (!node) {
michael@0 545 return null;
michael@0 546 }
michael@0 547
michael@0 548 this._isModifying = true;
michael@0 549 // Temporarily add it here so it can have a width, then ditch it:
michael@0 550 this.appendChild(node);
michael@0 551 this.evictNode(node);
michael@0 552 this._isModifying = false;
michael@0 553 this._updateMigratedSet();
michael@0 554 // We will now have moved stuff around; kick off some events
michael@0 555 // so add-ons know we've just moved their stuff:
michael@0 556 // XXXgijs: only in this window. It's hard to know for sure what's the right
michael@0 557 // thing to do here - typically insertItem is used on each window, so
michael@0 558 // this seems to make the most sense, even if some of the effects of
michael@0 559 // evictNode might affect multiple windows.
michael@0 560 CustomizableUI.dispatchToolboxEvent("customizationchange", {}, window);
michael@0 561 CustomizableUI.dispatchToolboxEvent("aftercustomization", {}, window);
michael@0 562 return node;
michael@0 563 ]]></body>
michael@0 564 </method>
michael@0 565 <method name="getMigratedItems">
michael@0 566 <body><![CDATA[
michael@0 567 return [... this._currentSetMigrated];
michael@0 568 ]]></body>
michael@0 569 </method>
michael@0 570 <method name="_updateMigratedSet">
michael@0 571 <body><![CDATA[
michael@0 572 let newMigratedItems = this.getMigratedItems().join(',');
michael@0 573 if (this.getAttribute("migratedset") != newMigratedItems) {
michael@0 574 this.setAttribute("migratedset", newMigratedItems);
michael@0 575 this.ownerDocument.persist(this.id, "migratedset");
michael@0 576 }
michael@0 577 ]]></body>
michael@0 578 </method>
michael@0 579 <property name="customizationTarget" readonly="true">
michael@0 580 <getter><![CDATA[
michael@0 581 return this;
michael@0 582 ]]></getter>
michael@0 583 </property>
michael@0 584 <property name="currentSet">
michael@0 585 <getter><![CDATA[
michael@0 586 return [node.id for (node of this.children)].join(',');
michael@0 587 ]]></getter>
michael@0 588 <setter><![CDATA[
michael@0 589 let v = val.split(',');
michael@0 590 let newButtons = v.filter(x => x && (!this._whiteListed.has(x) &&
michael@0 591 !CustomizableUI.isSpecialWidget(x) &&
michael@0 592 !this._currentSetMigrated.has(x)));
michael@0 593 for (let newButton of newButtons) {
michael@0 594 this._currentSetMigrated.add(newButton);
michael@0 595 this.insertItem(newButton);
michael@0 596 }
michael@0 597 this._updateMigratedSet();
michael@0 598 ]]></setter>
michael@0 599 </property>
michael@0 600 <property name="toolbox" readonly="true">
michael@0 601 <getter><![CDATA[
michael@0 602 if (!this._toolbox && this.parentNode &&
michael@0 603 this.parentNode.localName == "toolbox") {
michael@0 604 this._toolbox = this.parentNode;
michael@0 605 }
michael@0 606
michael@0 607 return this._toolbox;
michael@0 608 ]]></getter>
michael@0 609 </property>
michael@0 610 <field name="_whiteListed" readonly="true">new Set(["addonbar-closebutton", "status-bar"])</field>
michael@0 611 <field name="_isModifying">false</field>
michael@0 612 <field name="_currentSetMigrated">new Set()</field>
michael@0 613 </implementation>
michael@0 614 </binding>
michael@0 615 </bindings>

mercurial