bug 406780 - In OSX The customizeToolbars window should be in a <panel> popup, r=stefanh r+sr=Neil

This commit is contained in:
Philip Chee 2009-02-03 22:54:11 +08:00
Родитель fa584ba29c
Коммит bc4b22fddd
10 изменённых файлов: 1217 добавлений и 4 удалений

Просмотреть файл

@ -440,6 +440,8 @@ pref("xpinstall.blacklist.add", "");
// Customizable toolbar stuff
pref("custtoolbar.personal_toolbar_folder", "");
// Use a popup window for the customize toolbar UI
pref("toolbar.customization.usesheet", false);
pref("sidebar.customize.all_panels.url", "http://sidebar-rdf.netscape.com/%LOCALE%/sidebar-rdf/%SIDEBAR_VERSION%/all-panels.rdf");
pref("sidebar.customize.directory.url", "http://dmoz.org/Netscape/Sidebar/");
@ -513,6 +515,9 @@ pref("browser.downloadmanager.behavior", 1);
// Turn on click-and-hold contextual menus
pref("ui.click_hold_context_menus", true);
// Use a sheet instead of a popup window for the customize toolbar UI
pref("toolbar.customization.usesheet", true);
#endif
#ifndef XP_MACOSX

Просмотреть файл

@ -425,6 +425,8 @@
</vbox>
</hbox>
<panel id="customizeToolbarSheetPopup"/>
<statusbar id="status-bar" class="chromeclass-status"
ondragdrop="nsDragAndDrop.drop(event, contentAreaDNDObserver);">
<statusbarpanel id="component-bar"/>

Просмотреть файл

@ -0,0 +1,992 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* David Hyatt.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* David Hyatt (hyatt@apple.com)
* Blake Ross (blaker@netscape.com)
* Joe Hewitt (hewitt@netscape.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
const kRowMax = 4;
var gToolboxDocument = null;
var gToolbox = null;
var gCurrentDragOverItem = null;
var gToolboxChanged = false;
var gToolboxIconSize = false;
var gToolboxSheet = false;
function onLoad()
{
if ("arguments" in window && window.arguments[0]) {
InitWithToolbox(window.arguments[0]);
repositionDialog();
}
else if (window.frameElement &&
"toolbox" in window.frameElement) {
gToolboxSheet = true;
InitWithToolbox(window.frameElement.toolbox);
}
}
function InitWithToolbox(aToolbox)
{
gToolbox = aToolbox;
gToolboxDocument = gToolbox.ownerDocument;
gToolbox.customizing = true;
gToolbox.addEventListener("dragstart", onToolbarDragStart, false);
gToolbox.addEventListener("dragover", onToolbarDragOver, false);
gToolbox.addEventListener("dragleave", onToolbarDragLeave, false);
gToolbox.addEventListener("drop", onToolbarDrop, false);
initDialog();
notifyParentInitialized();
}
function onClose()
{
if (!gToolboxSheet)
window.close();
else
finishToolbarCustomization();
}
function onUnload()
{
if (!gToolboxSheet)
finishToolbarCustomization();
}
function finishToolbarCustomization()
{
gToolbox.customizing = false;
removeToolboxListeners();
unwrapToolbarItems();
persistCurrentSets();
notifyParentComplete();
}
function initDialog()
{
var mode = gToolbox.getAttribute("mode");
document.getElementById("modelist").value = mode;
gToolboxIconSize = gToolbox.getAttribute("iconsize");
var smallIconsCheckbox = document.getElementById("smallicons");
smallIconsCheckbox.checked = gToolboxIconSize == "small";
if (mode == "text")
smallIconsCheckbox.disabled = true;
// Build up the palette of other items.
buildPalette();
// Wrap all the items on the toolbar in toolbarpaletteitems.
wrapToolbarItems();
}
function repositionDialog()
{
// Position the dialog touching the bottom of the toolbox and centered with
// it.
var width;
if (document.documentElement.hasAttribute("width"))
width = document.documentElement.getAttribute("width");
else
width = parseInt(document.documentElement.style.width);
var screenX = gToolbox.boxObject.screenX
+ ((gToolbox.boxObject.width - width) / 2);
var screenY = gToolbox.boxObject.screenY + gToolbox.boxObject.height;
window.moveTo(screenX, screenY);
}
function removeToolboxListeners()
{
gToolbox.removeEventListener("dragstart", onToolbarDragStart, false);
gToolbox.removeEventListener("dragover", onToolbarDragOver, false);
gToolbox.removeEventListener("dragleave", onToolbarDragLeave, false);
gToolbox.removeEventListener("drop", onToolbarDrop, false);
}
/**
* Invoke a callback on the toolbox to notify it that the dialog is done
* and going away.
*/
function notifyParentComplete()
{
if ("customizeDone" in gToolbox)
gToolbox.customizeDone(gToolboxChanged);
}
/**
* Invoke a callback on the toolbox to notify it that the dialog is fully
* initialized.
*/
function notifyParentInitialized()
{
if ("customizeInitialized" in gToolbox)
gToolbox.customizeInitialized();
}
function toolboxChanged()
{
gToolboxChanged = true;
if ("customizeChange" in gToolbox)
gToolbox.customizeChange();
}
function getToolbarAt(i)
{
return gToolbox.childNodes[i];
}
/**
* Persist the current set of buttons in all customizable toolbars to
* localstore.
*/
function persistCurrentSets()
{
if (!gToolboxChanged || gToolboxDocument.defaultView.closed)
return;
var customCount = 0;
for (var i = 0; i < gToolbox.childNodes.length; ++i) {
// Look for customizable toolbars that need to be persisted.
var toolbar = getToolbarAt(i);
if (isCustomizableToolbar(toolbar)) {
// Calculate currentset and store it in the attribute.
var currentSet = toolbar.currentSet;
toolbar.setAttribute("currentset", currentSet);
var customIndex = toolbar.hasAttribute("customindex");
if (customIndex) {
if (!toolbar.firstChild) {
// Remove custom toolbars whose contents have been removed.
gToolbox.removeChild(toolbar);
--i;
} else {
// Persist custom toolbar info on the <toolbarset/>
gToolbox.toolbarset.setAttribute("toolbar"+(++customCount),
toolbar.toolbarName + ":" + currentSet);
gToolboxDocument.persist(gToolbox.toolbarset.id, "toolbar"+customCount);
}
}
if (!customIndex) {
// Persist the currentset attribute directly on hardcoded toolbars.
gToolboxDocument.persist(toolbar.id, "currentset");
}
}
}
// Remove toolbarX attributes for removed toolbars.
while (gToolbox.toolbarset.hasAttribute("toolbar"+(++customCount))) {
gToolbox.toolbarset.removeAttribute("toolbar"+customCount);
gToolboxDocument.persist(gToolbox.toolbarset.id, "toolbar"+customCount);
}
}
/**
* Wraps all items in all customizable toolbars in a toolbox.
*/
function wrapToolbarItems()
{
for (var i = 0; i < gToolbox.childNodes.length; ++i) {
var toolbar = getToolbarAt(i);
if (isCustomizableToolbar(toolbar)) {
for (var k = 0; k < toolbar.childNodes.length; ++k) {
var item = toolbar.childNodes[k];
if (/Mac/.test(navigator.platform)) {
if (item.firstChild && item.firstChild.localName == "menubar")
continue;
}
if (isToolbarItem(item)) {
var wrapper = wrapToolbarItem(item);
cleanupItemForToolbar(item, wrapper);
}
}
}
}
}
/**
* Unwraps all items in all customizable toolbars in a toolbox.
*/
function unwrapToolbarItems()
{
var paletteItems = gToolbox.getElementsByTagName("toolbarpaletteitem");
var paletteItem;
while ((paletteItem = paletteItems.item(0)) != null) {
var toolbarItem = paletteItem.firstChild;
if (paletteItem.hasAttribute("itemdisabled"))
toolbarItem.disabled = true;
if (paletteItem.hasAttribute("itemcommand")) {
let commandID = paletteItem.getAttribute("itemcommand");
toolbarItem.setAttribute("command", commandID);
//XXX Bug 309953 - toolbarbuttons aren't in sync with their commands after customizing
toolbarItem.disabled = gToolboxDocument.getElementById(commandID).disabled;
}
paletteItem.parentNode.replaceChild(toolbarItem, paletteItem);
}
}
/**
* Creates a wrapper that can be used to contain a toolbaritem and prevent
* it from receiving UI events.
*/
function createWrapper(aId, aDocument)
{
var wrapper = aDocument.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"toolbarpaletteitem");
wrapper.id = "wrapper-"+aId;
return wrapper;
}
/**
* Wraps an item that has been cloned from a template and adds
* it to the end of a row in the palette.
*/
function wrapPaletteItem(aPaletteItem, aCurrentRow, aSpacer)
{
var wrapper = createWrapper(aPaletteItem.id, document);
wrapper.setAttribute("flex", 1);
wrapper.setAttribute("align", "center");
wrapper.setAttribute("pack", "center");
wrapper.setAttribute("minheight", "0");
wrapper.setAttribute("minwidth", "0");
wrapper.appendChild(aPaletteItem);
// XXX We need to call this AFTER the palette item has been appended
// to the wrapper or else we crash dropping certain buttons on the
// palette due to removal of the command and disabled attributes - JRH
cleanUpItemForPalette(aPaletteItem, wrapper);
if (aSpacer)
aCurrentRow.insertBefore(wrapper, aSpacer);
else
aCurrentRow.appendChild(wrapper);
}
/**
* Wraps an item that is currently on a toolbar and replaces the item
* with the wrapper. This is not used when dropping items from the palette,
* only when first starting the dialog and wrapping everything on the toolbars.
*/
function wrapToolbarItem(aToolbarItem)
{
var wrapper = createWrapper(aToolbarItem.id, gToolboxDocument);
wrapper.flex = aToolbarItem.flex;
aToolbarItem.parentNode.replaceChild(wrapper, aToolbarItem);
wrapper.appendChild(aToolbarItem);
return wrapper;
}
/**
* Get the list of ids for the current set of items on each toolbar.
*/
function getCurrentItemIds()
{
var currentItems = {};
for (var i = 0; i < gToolbox.childNodes.length; ++i) {
var toolbar = getToolbarAt(i);
if (isCustomizableToolbar(toolbar)) {
var child = toolbar.firstChild;
while (child) {
if (isToolbarItem(child))
currentItems[child.id] = 1;
child = child.nextSibling;
}
}
}
return currentItems;
}
/**
* Builds the palette of draggable items that are not yet in a toolbar.
*/
function buildPalette()
{
// Empty the palette first.
var paletteBox = document.getElementById("palette-box");
while (paletteBox.lastChild)
paletteBox.removeChild(paletteBox.lastChild);
var currentRow = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"hbox");
currentRow.setAttribute("class", "paletteRow");
// Add the toolbar separator item.
var templateNode = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"toolbarseparator");
templateNode.id = "separator";
wrapPaletteItem(templateNode, currentRow, null);
// Add the toolbar spring item.
templateNode = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"toolbarspring");
templateNode.id = "spring";
templateNode.flex = 1;
wrapPaletteItem(templateNode, currentRow, null);
// Add the toolbar spacer item.
templateNode = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"toolbarspacer");
templateNode.id = "spacer";
templateNode.flex = 1;
wrapPaletteItem(templateNode, currentRow, null);
var rowSlot = 3;
var currentItems = getCurrentItemIds();
templateNode = gToolbox.palette.firstChild;
while (templateNode) {
// Check if the item is already in a toolbar before adding it to the palette.
if (!(templateNode.id in currentItems)) {
var paletteItem = document.importNode(templateNode, true);
if (rowSlot == kRowMax) {
// Append the old row.
paletteBox.appendChild(currentRow);
// Make a new row.
currentRow = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"hbox");
currentRow.setAttribute("class", "paletteRow");
rowSlot = 0;
}
++rowSlot;
wrapPaletteItem(paletteItem, currentRow, null);
}
templateNode = templateNode.nextSibling;
}
if (currentRow) {
fillRowWithFlex(currentRow);
paletteBox.appendChild(currentRow);
}
}
/**
* Creates a new palette item for a cloned template node and
* adds it to the last slot in the palette.
*/
function appendPaletteItem(aItem)
{
var paletteBox = document.getElementById("palette-box");
var lastRow = paletteBox.lastChild;
var lastSpacer = lastRow.lastChild;
if (lastSpacer.localName != "spacer") {
// The current row is full, so we have to create a new row.
lastRow = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"hbox");
lastRow.setAttribute("class", "paletteRow");
paletteBox.appendChild(lastRow);
wrapPaletteItem(aItem, lastRow, null);
fillRowWithFlex(lastRow);
} else {
// Decrement the flex of the last spacer or remove it entirely.
var flex = lastSpacer.getAttribute("flex");
if (flex == 1) {
lastRow.removeChild(lastSpacer);
lastSpacer = null;
} else
lastSpacer.setAttribute("flex", --flex);
// Insert the wrapper where the last spacer was.
wrapPaletteItem(aItem, lastRow, lastSpacer);
}
}
function fillRowWithFlex(aRow)
{
var remainingFlex = kRowMax - aRow.childNodes.length;
if (remainingFlex > 0) {
var spacer = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"spacer");
spacer.setAttribute("flex", remainingFlex);
aRow.appendChild(spacer);
}
}
/**
* Makes sure that an item that has been cloned from a template
* is stripped of all properties that may adversely affect its
* appearance in the palette.
*/
function cleanUpItemForPalette(aItem, aWrapper)
{
aWrapper.setAttribute("place", "palette");
setWrapperType(aItem, aWrapper);
if (aItem.hasAttribute("title"))
aWrapper.setAttribute("title", aItem.getAttribute("title"));
else if (isSpecialItem(aItem)) {
var stringBundle = document.getElementById("stringBundle");
// Remove the common "toolbar" prefix to generate the string name.
var title = stringBundle.getString(aItem.localName.slice(7) + "Title");
aWrapper.setAttribute("title", title);
}
// Remove attributes that screw up our appearance.
aItem.removeAttribute("command");
aItem.removeAttribute("observes");
aItem.removeAttribute("disabled");
aItem.removeAttribute("type");
aItem.removeAttribute("width");
if (aItem.localName == "toolbaritem" && aItem.firstChild) {
aItem.firstChild.removeAttribute("observes");
// So the throbber doesn't throb in the dialog,
// cute as that may be...
aItem.firstChild.removeAttribute("busy");
}
}
/**
* Makes sure that an item that has been cloned from a template
* is stripped of all properties that may adversely affect its
* appearance in the toolbar. Store critical properties on the
* wrapper so they can be put back on the item when we're done.
*/
function cleanupItemForToolbar(aItem, aWrapper)
{
setWrapperType(aItem, aWrapper);
aWrapper.setAttribute("place", "toolbar");
if (aItem.hasAttribute("command")) {
aWrapper.setAttribute("itemcommand", aItem.getAttribute("command"));
aItem.removeAttribute("command");
}
if (aItem.disabled) {
aWrapper.setAttribute("itemdisabled", "true");
aItem.disabled = false;
}
}
function setWrapperType(aItem, aWrapper)
{
if (aItem.localName == "toolbarseparator") {
aWrapper.setAttribute("type", "separator");
} else if (aItem.localName == "toolbarspring") {
aWrapper.setAttribute("type", "spring");
} else if (aItem.localName == "toolbarspacer") {
aWrapper.setAttribute("type", "spacer");
} else if (aItem.localName == "toolbaritem" && aItem.firstChild) {
aWrapper.setAttribute("type", aItem.firstChild.localName);
}
}
function setDragActive(aItem, aValue)
{
var node = aItem;
var direction = window.getComputedStyle(aItem, null).direction;
var value = direction == "ltr"? "left" : "right";
if (aItem.localName == "toolbar") {
node = aItem.lastChild;
value = direction == "ltr"? "right" : "left";
}
if (!node)
return;
if (aValue) {
if (!node.hasAttribute("dragover"))
node.setAttribute("dragover", value);
} else {
node.removeAttribute("dragover");
}
}
function addNewToolbar()
{
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);
var stringBundle = document.getElementById("stringBundle");
var message = stringBundle.getString("enterToolbarName");
var title = stringBundle.getString("enterToolbarTitle");
var name = {};
// Quitting from the toolbar dialog while the new toolbar prompt is up
// can cause things to become unresponsive on the Mac. Until dialog modality
// is fixed (395465), disable the "Done" button explicitly.
var doneButton = document.getElementById("donebutton");
doneButton.disabled = true;
while (true) {
if (!promptService.prompt(window, title, message, name, null, {})) {
doneButton.disabled = false;
return;
}
if (!name.value) {
message = stringBundle.getFormattedString("enterToolbarBlank", [name.value]);
continue;
}
var dupeFound = false;
// Check for an existing toolbar with the same display name
for (i = 0; i < gToolbox.childNodes.length; ++i) {
var toolbar = gToolbox.childNodes[i];
var toolbarName = toolbar.getAttribute("toolbarname");
if (toolbarName == name.value &&
toolbar.getAttribute("type") != "menubar" &&
toolbar.nodeName == 'toolbar') {
dupeFound = true;
break;
}
}
if (!dupeFound)
break;
message = stringBundle.getFormattedString("enterToolbarDup", [name.value]);
}
gToolbox.appendCustomToolbar(name.value, "");
toolboxChanged();
doneButton.disabled = false;
}
/**
* Restore the default set of buttons to fixed toolbars,
* remove all custom toolbars, and rebuild the palette.
*/
function restoreDefaultSet()
{
// Unwrap the items on the toolbar.
unwrapToolbarItems();
// Remove all of the customized toolbars.
var child = gToolbox.lastChild;
while (child) {
if (child.hasAttribute("customindex")) {
var thisChild = child;
child = child.previousSibling;
thisChild.currentSet = "__empty";
gToolbox.removeChild(thisChild);
} else {
child = child.previousSibling;
}
}
// Restore the defaultset for fixed toolbars.
var toolbar = gToolbox.firstChild;
while (toolbar) {
if (isCustomizableToolbar(toolbar)) {
var defaultSet = toolbar.getAttribute("defaultset");
if (defaultSet)
toolbar.currentSet = defaultSet;
}
toolbar = toolbar.nextSibling;
}
// Restore the default icon size and mode.
var defaultMode = gToolbox.getAttribute("defaultmode");
var defaultIconsSmall = gToolbox.getAttribute("defaulticonsize") == "small";
updateIconSize(defaultIconsSmall, true);
document.getElementById("smallicons").checked = defaultIconsSmall;
updateToolbarMode(defaultMode, true);
document.getElementById("modelist").value = defaultMode;
// Now rebuild the palette.
buildPalette();
// Now re-wrap the items on the toolbar.
wrapToolbarItems();
toolboxChanged();
}
function updateIconSize(aUseSmallIcons, localDefault)
{
gToolboxIconSize = aUseSmallIcons ? "small" : "large";
setAttribute(gToolbox, "iconsize", gToolboxIconSize);
gToolboxDocument.persist(gToolbox.id, "iconsize");
for (var i = 0; i < gToolbox.childNodes.length; ++i) {
var toolbar = getToolbarAt(i);
if (isCustomizableToolbar(toolbar)) {
var toolbarIconSize = (localDefault && toolbar.hasAttribute("defaulticonsize")) ?
toolbar.getAttribute("defaulticonsize") :
gToolboxIconSize;
setAttribute(toolbar, "iconsize", toolbarIconSize);
gToolboxDocument.persist(toolbar.id, "iconsize");
}
}
}
function updateToolbarMode(aModeValue, localDefault)
{
setAttribute(gToolbox, "mode", aModeValue);
gToolboxDocument.persist(gToolbox.id, "mode");
for (var i = 0; i < gToolbox.childNodes.length; ++i) {
var toolbar = getToolbarAt(i);
if (isCustomizableToolbar(toolbar)) {
var toolbarMode = (localDefault && toolbar.hasAttribute("defaultmode")) ?
toolbar.getAttribute("defaultmode") :
aModeValue;
setAttribute(toolbar, "mode", toolbarMode);
gToolboxDocument.persist(toolbar.id, "mode");
}
}
var iconSizeCheckbox = document.getElementById("smallicons");
iconSizeCheckbox.disabled = aModeValue == "text";
}
function setAttribute(aElt, aAttr, aVal)
{
if (aVal)
aElt.setAttribute(aAttr, aVal);
else
aElt.removeAttribute(aAttr);
}
function isCustomizableToolbar(aElt)
{
return aElt.localName == "toolbar" &&
aElt.getAttribute("customizable") == "true";
}
function isSpecialItem(aElt)
{
return aElt.localName == "toolbarseparator" ||
aElt.localName == "toolbarspring" ||
aElt.localName == "toolbarspacer";
}
function isToolbarItem(aElt)
{
return aElt.localName == "toolbarbutton" ||
aElt.localName == "toolbaritem" ||
aElt.localName == "toolbarseparator" ||
aElt.localName == "toolbarspring" ||
aElt.localName == "toolbarspacer";
}
///////////////////////////////////////////////////////////////////////////
//// Drag and Drop observers
function onToolbarDragStart(aEvent)
{
nsDragAndDrop.startDrag(aEvent, dragStartObserver);
}
function onToolbarDragOver(aEvent)
{
nsDragAndDrop.dragOver(aEvent, toolbarDNDObserver);
}
function onToolbarDrop(aEvent)
{
nsDragAndDrop.drop(aEvent, toolbarDNDObserver);
}
function onToolbarDragLeave(aEvent)
{
if (gCurrentDragOverItem)
setDragActive(gCurrentDragOverItem, false);
}
var dragStartObserver =
{
onDragStart: function (aEvent, aXferData, aDragAction) {
var documentId = gToolboxDocument.documentElement.id;
var item = aEvent.target;
while (item && item.localName != "toolbarpaletteitem")
item = item.parentNode;
item.setAttribute("dragactive", "true");
aXferData.data = new TransferDataSet();
var data = new TransferData();
data.addDataForFlavour("text/toolbarwrapper-id/"+documentId, item.firstChild.id);
aXferData.data.push(data);
aDragAction.action = Components.interfaces.nsIDragService.DRAGDROP_ACTION_MOVE;
}
}
var toolbarDNDObserver =
{
onDragOver: function (aEvent, aFlavour, aDragSession)
{
var toolbar = aEvent.target;
var dropTarget = aEvent.target;
while (toolbar && toolbar.localName != "toolbar") {
dropTarget = toolbar;
toolbar = toolbar.parentNode;
}
var previousDragItem = gCurrentDragOverItem;
// Make sure we are dragging over a customizable toolbar.
if (!isCustomizableToolbar(toolbar)) {
gCurrentDragOverItem = null;
return;
}
if (dropTarget.localName == "toolbar") {
gCurrentDragOverItem = dropTarget;
} else {
gCurrentDragOverItem = null;
var direction = window.getComputedStyle(dropTarget.parentNode, null).direction;
var dropTargetCenter = dropTarget.boxObject.x + (dropTarget.boxObject.width / 2);
if (direction == "ltr")
dragAfter = aEvent.clientX > dropTargetCenter;
else
dragAfter = aEvent.clientX < dropTargetCenter;
if (dragAfter) {
gCurrentDragOverItem = dropTarget.nextSibling;
if (!gCurrentDragOverItem)
gCurrentDragOverItem = toolbar;
} else
gCurrentDragOverItem = dropTarget;
}
if (previousDragItem && gCurrentDragOverItem != previousDragItem) {
setDragActive(previousDragItem, false);
}
setDragActive(gCurrentDragOverItem, true);
aDragSession.canDrop = true;
},
onDrop: function (aEvent, aXferData, aDragSession)
{
if (!gCurrentDragOverItem)
return;
setDragActive(gCurrentDragOverItem, false);
var draggedItemId = aXferData.data;
if (gCurrentDragOverItem.id == draggedItemId)
return;
var toolbar = aEvent.target;
while (toolbar.localName != "toolbar")
toolbar = toolbar.parentNode;
var draggedPaletteWrapper = document.getElementById("wrapper-"+draggedItemId);
if (!draggedPaletteWrapper) {
// The wrapper has been dragged from the toolbar.
// Get the wrapper from the toolbar document and make sure that
// it isn't being dropped on itself.
var wrapper = gToolboxDocument.getElementById("wrapper-"+draggedItemId);
if (wrapper == gCurrentDragOverItem)
return;
// Don't allow static kids (e.g., the menubar) to move.
if (wrapper.parentNode.firstPermanentChild && wrapper.parentNode.firstPermanentChild.id == wrapper.firstChild.id)
return;
if (wrapper.parentNode.lastPermanentChild && wrapper.parentNode.lastPermanentChild.id == wrapper.firstChild.id)
return;
// Remove the item from its place in the toolbar.
wrapper.parentNode.removeChild(wrapper);
// Determine which toolbar we are dropping on.
var dropToolbar = null;
if (gCurrentDragOverItem.localName == "toolbar")
dropToolbar = gCurrentDragOverItem;
else
dropToolbar = gCurrentDragOverItem.parentNode;
// Insert the item into the toolbar.
if (gCurrentDragOverItem != dropToolbar)
dropToolbar.insertBefore(wrapper, gCurrentDragOverItem);
else
dropToolbar.appendChild(wrapper);
} else {
// 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);
// 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);
// Prepare the item and wrapper to look good on the toolbar.
cleanupItemForToolbar(newItem, wrapper);
wrapper.id = "wrapper-"+newItem.id;
wrapper.flex = newItem.flex;
// Remove the wrapper from the palette.
var currentRow = draggedPaletteWrapper.parentNode;
if (draggedItemId != "separator" &&
draggedItemId != "spring" &&
draggedItemId != "spacer")
{
currentRow.removeChild(draggedPaletteWrapper);
while (currentRow) {
// Pull the first child of the next row up
// into this row.
var nextRow = currentRow.nextSibling;
if (!nextRow) {
var last = currentRow.lastChild;
var first = currentRow.firstChild;
if (first == last) {
// Kill the row.
currentRow.parentNode.removeChild(currentRow);
break;
}
if (last.localName == "spacer") {
var flex = last.getAttribute("flex");
last.setAttribute("flex", ++flex);
// Reflow doesn't happen for some reason. Trigger it with a hide/show. ICK! -dwh
last.hidden = true;
last.hidden = false;
break;
} else {
// Make a spacer and give it a flex of 1.
var spacer = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"spacer");
spacer.setAttribute("flex", "1");
currentRow.appendChild(spacer);
}
break;
}
currentRow.appendChild(nextRow.firstChild);
currentRow = currentRow.nextSibling;
}
}
}
gCurrentDragOverItem = null;
toolboxChanged();
},
_flavourSet: null,
getSupportedFlavours: function ()
{
if (!this._flavourSet) {
this._flavourSet = new FlavourSet();
var documentId = gToolboxDocument.documentElement.id;
this._flavourSet.appendFlavour("text/toolbarwrapper-id/"+documentId);
}
return this._flavourSet;
}
}
var paletteDNDObserver =
{
onDragOver: function (aEvent, aFlavour, aDragSession)
{
aDragSession.canDrop = true;
},
onDrop: function(aEvent, aXferData, aDragSession)
{
var itemId = aXferData.data;
var wrapper = gToolboxDocument.getElementById("wrapper-"+itemId);
if (wrapper) {
// Don't allow static kids (e.g., the menubar) to move.
if (wrapper.parentNode.firstPermanentChild && wrapper.parentNode.firstPermanentChild.id == wrapper.firstChild.id)
return;
if (wrapper.parentNode.lastPermanentChild && wrapper.parentNode.lastPermanentChild.id == wrapper.firstChild.id)
return;
var wrapperType = wrapper.getAttribute("type");
if (wrapperType != "separator" &&
wrapperType != "spacer" &&
wrapperType != "spring") {
appendPaletteItem(document.importNode(wrapper.firstChild, true));
gToolbox.palette.appendChild(wrapper.firstChild);
}
// The item was dragged out of the toolbar.
wrapper.parentNode.removeChild(wrapper);
}
toolboxChanged();
},
_flavourSet: null,
getSupportedFlavours: function ()
{
if (!this._flavourSet) {
this._flavourSet = new FlavourSet();
var documentId = gToolboxDocument.documentElement.id;
this._flavourSet.appendFlavour("text/toolbarwrapper-id/"+documentId);
}
return this._flavourSet;
}
}

Просмотреть файл

@ -0,0 +1,103 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Mozilla Communicator client code, released
- March 31, 1998.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1998-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- David Hyatt (hyatt@apple.com)
- Blake Ross (blaker@netscape.com)
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the LGPL or the GPL. If you do not delete
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE dialog [
<!ENTITY % customizeToolbarDTD SYSTEM "chrome://global/locale/customizeToolbar.dtd">
%customizeToolbarDTD;
]>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://global/content/customizeToolbar.css" type="text/css"?>
<?xml-stylesheet href="chrome://global/skin/customizeToolbar.css" type="text/css"?>
<window id="CustomizeToolbarWindow"
title="&dialog.title;"
onload="onLoad();"
onunload="onUnload();"
style="&dialog.style;"
persist="width height"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://communicator/content/customizeToolbar.js"/>
<script type="application/javascript" src="chrome://global/content/nsDragAndDrop.js"/>
<stringbundle id="stringBundle" src="chrome://global/locale/customizeToolbar.properties"/>
<keyset id="CustomizeToolbarKeyset">
<key id="cmd_close1" keycode="VK_ESCAPE" oncommand="onClose();"/>
<key id="cmd_close2" keycode="VK_RETURN" oncommand="onClose();"/>
<key id="cmd_close3" keycode="VK_ENTER" oncommand="onClose();"/>
</keyset>
<vbox id="main-box" flex="1">
<description id="instructions">
&instructions.description;
</description>
<vbox flex="1" id="palette-box"
ondraggesture="nsDragAndDrop.startDrag(event, dragStartObserver);"
ondragover="nsDragAndDrop.dragOver(event, paletteDNDObserver);"
ondragdrop="nsDragAndDrop.drop(event, paletteDNDObserver);"/>
<box align="center">
<label value="&show.label;"/>
<menulist id="modelist" value="icons" oncommand="updateToolbarMode(this.value);">
<menupopup>
<menuitem value="full" label="&iconsAndText.label;"/>
<menuitem value="icons" label="&icons.label;"/>
<menuitem value="text" label="&text.label;"/>
</menupopup>
</menulist>
<checkbox id="smallicons" oncommand="updateIconSize(this.checked);" label="&useSmallIcons.label;"/>
<button label="&addNewToolbar.label;" oncommand="addNewToolbar();" icon="add"/>
<button label="&restoreDefaultSet.label;" oncommand="restoreDefaultSet();" icon="revert"/>
</box>
<separator class="groove"/>
<hbox align="center" pack="end">
<button id="donebutton" label="&saveChanges.label;" oncommand="onClose();"
default="true" icon="close"/>
</hbox>
</vbox>
</window>

Просмотреть файл

@ -2,6 +2,7 @@ comm.jar:
% content communicator %content/communicator/ xpcnativewrappers=yes contentaccessible=yes
% override chrome://global/content/license.html chrome://communicator/content/license.html
% override chrome://mozapps/content/profile/profileSelection.xul chrome://communicator/content/profile/profileSelection.xul
% override chrome://global/content/customizeToolbar.xul chrome://communicator/content/customizeToolbar.xul
% overlay chrome://communicator/content/contentAreaContextOverlay.xul chrome://communicator/content/permissions/imageContextOverlay.xul
% overlay chrome://navigator/content/navigatorOverlay.xul chrome://communicator/content/permissions/permissionsNavigatorOverlay.xul
% overlay chrome://global/content/console.xul chrome://communicator/content/consoleOverlay.xul
@ -55,6 +56,8 @@ comm.jar:
content/communicator/contentAreaDD.js
content/communicator/contentAreaClick.js
content/communicator/contentAreaContextOverlay.xul
content/communicator/customizeToolbar.js
content/communicator/customizeToolbar.xul
content/communicator/defaultClientDialog.js
content/communicator/defaultClientDialog.xul
content/communicator/editorBindings.xul

Просмотреть файл

@ -280,6 +280,8 @@ function goToggleToolbar( id, elementID )
}
}
var gCustomizeSheet = false;
function goCustomizeToolbar(toolbox)
{
/* If the toolbox has a method "customizeInit" then call it first.
@ -289,10 +291,38 @@ function goCustomizeToolbar(toolbox)
toolbox.customizeInit();
var customizeURL = "chrome://global/content/customizeToolbar.xul";
window.openDialog(customizeURL,
"",
"chrome,all,dependent",
toolbox);
gCustomizeSheet = getBoolPref("toolbar.customization.usesheet", false);
if (gCustomizeSheet) {
var sheetFrame = document.getElementById("customizeToolbarSheetIFrame");
sheetFrame.hidden = false;
sheetFrame.toolbox = toolbox;
// The document might not have been loaded yet, if this is the first time.
// If it is already loaded, reload it so that the onload initialization
// code re-runs.
if (sheetFrame.getAttribute("src") == customizeURL)
sheetFrame.contentWindow.location.reload();
else
sheetFrame.setAttribute("src", customizeURL);
// XXXmano: there's apparently no better way to get this when the iframe
// is hidden
var sheetWidth = sheetFrame.style.width.match(/([0-9]+)px/)[1];
document.getElementById("customizeToolbarSheetPopup")
.openPopup(toolbox,
"after_start",
(window.innerWidth - sheetWidth) / 2, 0);
return sheetFrame.contentWindow;
}
else {
return window.openDialog(customizeURL,
"",
"chrome,all,dependent",
toolbox);
}
}
function onViewToolbarsPopupShowing(aEvent)
@ -453,6 +483,16 @@ function toolboxCustomizeInit(menubarID)
function toolboxCustomizeDone(menubarID, toolbox, aToolboxChanged)
{
if (gCustomizeSheet) {
var sheetFrame = document.getElementById("customizeToolbarSheetIFrame");
sheetFrame.hidden = true;
document.getElementById("customizeToolbarSheetPopup").hidePopup();
if (content)
content.focus();
else
window.focus();
}
// Re-enable parts of the UI we disabled during the dialog
var menubar = document.getElementById(menubarID);
for (let i = 0; i < menubar.childNodes.length; ++i) {

Просмотреть файл

@ -10,6 +10,8 @@
%platformCommunicatorDTD;
<!ENTITY % utilityDTD SYSTEM "chrome://communicator/locale/utilityOverlay.dtd">
%utilityDTD;
<!ENTITY % customizeToolbarDTD SYSTEM "chrome://global/locale/customizeToolbar.dtd">
%customizeToolbarDTD;
]>
@ -114,6 +116,12 @@
</popup>
<panel id="customizeToolbarSheetPopup" noautohide="true">
<iframe id="customizeToolbarSheetIFrame"
style="&dialog.style;"
hidden="true"/>
</panel>
<statusbarpanel id="offline-status" context="networkProperties"
observes="Communicator:WorkMode"/>

Просмотреть файл

@ -0,0 +1,58 @@
/* ***** BEGIN LICENSE BLOCK *****
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is
Blake Ross.
Portions created by the Initial Developer are Copyright (C) 2002
the Initial Developer. All Rights Reserved.
Contributor(s):
Blake Ross (blaker@netscape.com)
Joe Hewitt (hewitt@netscape.com)
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
***** END LICENSE BLOCK ***** */
window,
dialog {
padding: 7px 5px 5px 5px;
}
#instructions {
font-weight: bold;
font-size: larger;
}
#CustomizeToolbarWindow > #main-box {
border-top: none;
border-left: 2px solid;
border-right: 2px solid;
border-bottom: 3px solid;
-moz-border-right-colors: #F8FAFE #5D616E;
-moz-border-bottom-colors: #5D616E #5D616E #BEC3D3;
-moz-border-left-colors: #5D616E #F8FAFE;
}

Просмотреть файл

@ -43,6 +43,7 @@
/* ::::: popup/menupopup ::::: */
panel,
menupopup,
popup {
cursor: default;

Просмотреть файл

@ -144,6 +144,7 @@ modern.jar:
skin/modern/global/checkbox.css (global/checkbox.css)
skin/modern/global/colorpicker.css (global/colorpicker.css)
skin/modern/global/config.css (global/config.css)
skin/modern/global/customizeToolbar.css (global/customizeToolbar.css)
skin/modern/global/datetimepicker.css (global/datetimepicker.css)
skin/modern/global/dialog.css (global/dialog.css)
skin/modern/global/dropmarker.css (global/dropmarker.css)