Bug 407725 Toolbar customisation pointlessly removes, clones and adopts nodes r=gavin

This commit is contained in:
Neil Rashbrook 2008-12-03 12:35:34 +00:00
parent f613bef10c
commit c9f8c5fbb8
2 changed files with 30 additions and 112 deletions

View File

@ -202,15 +202,7 @@ function wrapToolbarItems()
#endif
if (isToolbarItem(item)) {
var nextSibling = item.nextSibling;
var wrapper = wrapToolbarItem(item);
if (nextSibling)
toolbar.insertBefore(wrapper, nextSibling);
else
toolbar.appendChild(wrapper);
cleanupItemForToolbar(item, wrapper);
}
}
@ -242,9 +234,9 @@ function unwrapToolbarItems()
* Creates a wrapper that can be used to contain a toolbaritem and prevent
* it from receiving UI events.
*/
function createWrapper(aId)
function createWrapper(aId, aDocument)
{
var wrapper = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
var wrapper = aDocument.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"toolbarpaletteitem");
wrapper.id = "wrapper-"+aId;
@ -257,7 +249,7 @@ function createWrapper(aId)
*/
function wrapPaletteItem(aPaletteItem, aCurrentRow, aSpacer)
{
var wrapper = createWrapper(aPaletteItem.id);
var wrapper = createWrapper(aPaletteItem.id, document);
wrapper.setAttribute("flex", 1);
wrapper.setAttribute("align", "center");
@ -265,7 +257,6 @@ function wrapPaletteItem(aPaletteItem, aCurrentRow, aSpacer)
wrapper.setAttribute("minheight", "0");
wrapper.setAttribute("minwidth", "0");
document.adoptNode(aPaletteItem);
wrapper.appendChild(aPaletteItem);
// XXX We need to call this AFTER the palette item has been appended
@ -287,13 +278,11 @@ function wrapPaletteItem(aPaletteItem, aCurrentRow, aSpacer)
*/
function wrapToolbarItem(aToolbarItem)
{
var wrapper = createWrapper(aToolbarItem.id);
gToolboxDocument.adoptNode(wrapper);
var wrapper = createWrapper(aToolbarItem.id, gToolboxDocument);
wrapper.flex = aToolbarItem.flex;
if (aToolbarItem.parentNode)
aToolbarItem.parentNode.removeChild(aToolbarItem);
aToolbarItem.parentNode.replaceChild(wrapper, aToolbarItem);
wrapper.appendChild(aToolbarItem);
@ -361,7 +350,7 @@ function buildPalette()
while (templateNode) {
// Check if the item is already in a toolbar before adding it to the palette.
if (!(templateNode.id in currentItems)) {
var paletteItem = templateNode.cloneNode(true);
var paletteItem = document.importNode(templateNode, true);
if (rowSlot == kRowMax) {
// Append the old row.
@ -446,7 +435,8 @@ function cleanUpItemForPalette(aItem, aWrapper)
aWrapper.setAttribute("title", aItem.getAttribute("title"));
else if (isSpecialItem(aItem)) {
var stringBundle = document.getElementById("stringBundle");
var title = stringBundle.getString(aItem.id + "Title");
// Remove the common "toolbar" prefix to generate the string name.
var title = stringBundle.getString(aItem.localName.slice(7) + "Title");
aWrapper.setAttribute("title", title);
}
@ -585,9 +575,8 @@ function addNewToolbar()
*/
function restoreDefaultSet()
{
// Save disabled/command states, because we're
// going to recreate the wrappers and lose this
var savedAttributes = saveItemAttributes(["itemdisabled", "itemcommand"]);
// Unwrap the items on the toolbar.
unwrapToolbarItems();
// Remove all of the customized toolbars.
var child = gToolbox.lastChild;
@ -595,6 +584,7 @@ function restoreDefaultSet()
if (child.hasAttribute("customindex")) {
var thisChild = child;
child = child.previousSibling;
thisChild.currentSet = "__empty";
gToolbox.removeChild(thisChild);
} else {
child = child.previousSibling;
@ -627,49 +617,9 @@ function restoreDefaultSet()
// Now re-wrap the items on the toolbar.
wrapToolbarItems();
// Restore the disabled and command states
restoreItemAttributes(["itemdisabled", "itemcommand"], savedAttributes);
toolboxChanged();
}
function saveItemAttributes(aAttributeList)
{
var items = [];
var paletteItems = gToolbox.getElementsByTagName("toolbarpaletteitem");
for (var i = 0; i < paletteItems.length; i++) {
var paletteItem = paletteItems.item(i);
for (var j = 0; j < aAttributeList.length; j++) {
var attr = aAttributeList[j];
if (paletteItem.hasAttribute(attr)) {
items.push([paletteItem.id, attr, paletteItem.getAttribute(attr)]);
}
}
}
return items;
}
function restoreItemAttributes(aAttributeList, aSavedAttrList)
{
var paletteItems = gToolbox.getElementsByTagName("toolbarpaletteitem");
for (var i = 0; i < paletteItems.length; i++) {
var paletteItem = paletteItems.item(i);
// if the item is supposed to have this, it'll get
// restored from the saved list
for (var j = 0; j < aAttributeList.length; j++)
paletteItem.removeAttribute(aAttributeList[j]);
for (var j = 0; j < aSavedAttrList.length; j++) {
var savedAttr = aSavedAttrList[j];
if (paletteItem.id == savedAttr[0]) {
paletteItem.setAttribute(savedAttr[1], savedAttr[2]);
}
}
}
}
function updateIconSize(aUseSmallIcons, localDefault)
{
gToolboxIconSize = aUseSmallIcons ? "small" : "large";
@ -881,8 +831,7 @@ var toolbarDNDObserver =
// The item has been dragged from the palette
// Create a new wrapper for the item. We don't know the id yet.
var wrapper = createWrapper("");
gToolboxDocument.adoptNode(wrapper);
var wrapper = createWrapper("", gToolboxDocument);
// Ask the toolbar to clone the item's template, place it inside the wrapper, and insert it in the toolbar.
var newItem = toolbar.insertItem(draggedItemId, gCurrentDragOverItem == toolbar ? null : gCurrentDragOverItem, wrapper);
@ -974,27 +923,16 @@ var paletteDNDObserver =
if (wrapper.parentNode.lastPermanentChild && wrapper.parentNode.lastPermanentChild.id == wrapper.firstChild.id)
return;
// The item was dragged out of the toolbar.
wrapper.parentNode.removeChild(wrapper);
var wrapperType = wrapper.getAttribute("type");
if (wrapperType != "separator" &&
wrapperType != "spacer" &&
wrapperType != "spring") {
// Find the template node in the toolbox palette
var templateNode = gToolbox.palette.firstChild;
while (templateNode) {
if (templateNode.id == itemId)
break;
templateNode = templateNode.nextSibling;
}
if (!templateNode)
return;
// Clone the template and add it to our palette.
var paletteItem = templateNode.cloneNode(true);
appendPaletteItem(paletteItem);
appendPaletteItem(document.importNode(wrapper.firstChild, true));
gToolbox.palette.appendChild(wrapper.firstChild);
}
// The item was dragged out of the toolbar.
wrapper.parentNode.removeChild(wrapper);
}
toolboxChanged();

View File

@ -161,22 +161,13 @@
<setter>
<![CDATA[
var palette = this.parentNode.palette;
// Remove all items before the first permanent child and after the last permanent child.
while (this.lastChild) {
if (this.lastChild == this.lastPermanentChild ||
(this.lastChild.localName == "toolbarpaletteitem" &&
this.lastChild.firstChild == this.lastPermanentChild))
break;
this.removeChild(this.lastChild);
}
while (this.lastChild != this.lastPermanentChild)
palette.appendChild(this.lastChild);
while (this.firstChild) {
if (this.firstChild == this.firstPermanentChild ||
(this.firstChild.localName == "toolbarpaletteitem" &&
this.firstChild.firstChild == this.firstPermanentChild))
break;
this.removeChild(this.firstChild);
}
while (this.firstChild != this.firstPermanentChild)
palette.appendChild(this.firstChild);
var firstChildID = this.firstPermanentChild ? this.firstPermanentChild.id : "";
var lastChildID = this.lastPermanentChild ? this.lastPermanentChild.id : "";
@ -184,14 +175,12 @@
if (val && val != "__empty") {
var itemIds = val.split(",");
var before = true;
this._trackInserted = {};
for (var i = 0; i < itemIds.length; i++) {
if (itemIds[i] == firstChildID || itemIds[i] == lastChildID)
before = false;
else
this.insertItem(itemIds[i], null, null, before);
}
delete this._trackInserted;
}
return val;
@ -230,26 +219,17 @@
newItem.id = "spacer" + uniqueId;
newItem.className = "chromeclass-toolbar-additional";
} else if (this.parentNode.localName == "toolbox") {
if (this._trackInserted) {
// Protect against creating an item with the given id more than once.
if (aId in this._trackInserted)
// Attempt to locate an item with a matching id within document.
newItem = document.getElementById(aId);
if (!newItem || newItem.parentNode.parentNode != this.parentNode) {
// Attempt to locate an item with a matching id within palette.
// The palette does not live in the document by default.
newItem = this.parentNode.palette
.getElementsByAttribute("id", aId).item(0);
if (!newItem || newItem.parentNode != this.parentNode.palette)
return false;
this._trackInserted[aId] = null;
}
// Attempt to locate an item with a matching id within palette.
var paletteItem = this.parentNode.palette.firstChild;
while (paletteItem) {
var paletteId = paletteItem.id;
if (paletteId == aId) {
newItem = paletteItem.cloneNode(true);
break;
}
paletteItem = paletteItem.nextSibling;
}
}
if (!newItem)
return false;
var insertItem = newItem;