Bug 1718587 - Copy formerly shared common files from mail to suite. r=frg DONTBUILD
--HG-- rename : mail/base/content/customizeToolbar.css => suite/components/customizeToolbar.css rename : mail/base/content/customizeToolbar.js => suite/components/customizeToolbar.js rename : mail/base/content/customizeToolbar.xhtml => suite/components/customizeToolbar.xhtml
This commit is contained in:
Родитель
af7507134a
Коммит
41bcbca172
|
@ -3,9 +3,9 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
comm.jar:
|
||||
content/communicator/customizeToolbar.css (../../../common/src/customizeToolbar.css)
|
||||
content/communicator/customizeToolbar.js (../../../common/src/customizeToolbar.js)
|
||||
* content/communicator/customizeToolbar.xhtml (../../../common/src/customizeToolbar.xhtml)
|
||||
content/communicator/customizeToolbar.css (../customizeToolbar.css)
|
||||
content/communicator/customizeToolbar.js (../customizeToolbar.js)
|
||||
* content/communicator/customizeToolbar.xhtml (../customizeToolbar.xhtml)
|
||||
content/communicator/bindings/datetimepicker.xml (datetimepicker.xml)
|
||||
content/communicator/bindings/findbar.xml (findbar.xml)
|
||||
content/communicator/bindings/general.xml (general.xml)
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
@namespace html url("http://www.w3.org/1999/xhtml");
|
||||
|
||||
#CustomizeToolbarWindow:-moz-lwtheme[lwtheme-image] {
|
||||
background-image: none !important;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
#main-box {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#instructions {
|
||||
font-weight: 600;
|
||||
font-size: 1.2em;
|
||||
margin-block: 5px 10px;
|
||||
}
|
||||
|
||||
#palette-box {
|
||||
overflow: auto;
|
||||
display: block;
|
||||
min-height: 3em;
|
||||
background-color: hsla(0, 0%, 100%, .3);
|
||||
border: 1px solid hsla(0, 0%, 50%, .4);
|
||||
}
|
||||
|
||||
:root[lwt-tree] #palette-box {
|
||||
scrollbar-color: rgba(204, 204, 204, .5) rgba(230, 230, 235, .5);
|
||||
}
|
||||
|
||||
:root[lwt-tree-brighttext] #palette-box {
|
||||
scrollbar-color: rgba(249, 249, 250, .4) rgba(20, 20, 25, .3);
|
||||
}
|
||||
|
||||
#palette-box > toolbarpaletteitem {
|
||||
padding: 8px 2px;
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
toolbarpaletteitem {
|
||||
-moz-window-dragging: no-drag;
|
||||
-moz-box-pack: start;
|
||||
}
|
||||
|
||||
toolbarpaletteitem[place="palette"] {
|
||||
-moz-box-orient: vertical;
|
||||
width: 10em;
|
||||
max-width: 10em;
|
||||
/* icon (16) + margin (9 + 12) + 4 lines of text: */
|
||||
height: calc(39px + 4em);
|
||||
margin-bottom: 5px;
|
||||
margin-inline-end: 24px;
|
||||
overflow: visible;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
toolbarpaletteitem[place=palette]::after {
|
||||
content: attr(title);
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
toolbarpaletteitem > toolbarbutton,
|
||||
toolbarpaletteitem > toolbarseparator,
|
||||
toolbarpaletteitem > toolbaritem {
|
||||
/* Prevent children from getting events */
|
||||
pointer-events: none;
|
||||
-moz-box-pack: center;
|
||||
-moz-box-flex: 1;
|
||||
}
|
||||
|
||||
toolbarpaletteitem[type="separator"][place="palette"] {
|
||||
-moz-box-align: center;
|
||||
}
|
||||
|
||||
toolbarpaletteitem[type="separator"][place="palette"] toolbarseparator {
|
||||
background-color: currentColor;
|
||||
}
|
||||
|
||||
#main-box > box {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Hide the toolbarbutton label because we replicate it on the wrapper */
|
||||
.toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
toolbarbutton > .toolbarbutton-menubutton-dropmarker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#buttonBox {
|
||||
margin-block: 5px;
|
||||
}
|
||||
|
||||
#titlebarSettings > checkbox {
|
||||
margin-inline: 0 15px;
|
||||
}
|
||||
|
||||
#modelistLabel {
|
||||
margin-top: 2px;
|
||||
}
|
|
@ -0,0 +1,855 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var gToolboxDocument = null;
|
||||
var gToolbox = null;
|
||||
var gCurrentDragOverItem = null;
|
||||
var gToolboxChanged = false;
|
||||
var gToolboxSheet = false;
|
||||
var gPaletteBox = null;
|
||||
|
||||
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
var { AppConstants } = ChromeUtils.import(
|
||||
"resource://gre/modules/AppConstants.jsm"
|
||||
);
|
||||
|
||||
function onLoad() {
|
||||
if ("arguments" in window && window.arguments[0]) {
|
||||
InitWithToolbox(window.arguments[0]);
|
||||
repositionDialog(window);
|
||||
} else if (window.frameElement && "toolbox" in window.frameElement) {
|
||||
gToolboxSheet = true;
|
||||
InitWithToolbox(window.frameElement.toolbox);
|
||||
repositionDialog(window.frameElement.panel);
|
||||
}
|
||||
}
|
||||
|
||||
function InitWithToolbox(aToolbox) {
|
||||
gToolbox = aToolbox;
|
||||
dispatchCustomizationEvent("beforecustomization");
|
||||
gToolboxDocument = gToolbox.ownerDocument;
|
||||
gToolbox.customizing = true;
|
||||
forEachCustomizableToolbar(function(toolbar) {
|
||||
toolbar.setAttribute("customizing", "true");
|
||||
});
|
||||
gPaletteBox = document.getElementById("palette-box");
|
||||
|
||||
var elts = getRootElements();
|
||||
for (let i = 0; i < elts.length; i++) {
|
||||
elts[i].addEventListener("dragstart", onToolbarDragStart, true);
|
||||
elts[i].addEventListener("dragover", onToolbarDragOver, true);
|
||||
elts[i].addEventListener("dragexit", onToolbarDragExit, true);
|
||||
elts[i].addEventListener("drop", onToolbarDrop, true);
|
||||
}
|
||||
|
||||
initDialog();
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
if (!gToolboxSheet) {
|
||||
window.close();
|
||||
} else {
|
||||
finishToolbarCustomization();
|
||||
}
|
||||
}
|
||||
|
||||
function onUnload() {
|
||||
if (!gToolboxSheet) {
|
||||
finishToolbarCustomization();
|
||||
}
|
||||
}
|
||||
|
||||
function finishToolbarCustomization() {
|
||||
removeToolboxListeners();
|
||||
unwrapToolbarItems();
|
||||
persistCurrentSets();
|
||||
gToolbox.customizing = false;
|
||||
forEachCustomizableToolbar(function(toolbar) {
|
||||
toolbar.removeAttribute("customizing");
|
||||
});
|
||||
|
||||
notifyParentComplete();
|
||||
}
|
||||
|
||||
function initDialog() {
|
||||
var mode = gToolbox.getAttribute("mode");
|
||||
document.getElementById("modelist").value = mode;
|
||||
var smallIconsCheckbox = document.getElementById("smallicons");
|
||||
smallIconsCheckbox.checked = gToolbox.getAttribute("iconsize") == "small";
|
||||
if (mode == "text") {
|
||||
smallIconsCheckbox.disabled = true;
|
||||
}
|
||||
|
||||
if (AppConstants.MOZ_APP_NAME == "thunderbird") {
|
||||
document.getElementById(
|
||||
"showTitlebar"
|
||||
).checked = !Services.prefs.getBoolPref("mail.tabs.drawInTitlebar");
|
||||
document.getElementById(
|
||||
"showDragSpace"
|
||||
).checked = Services.prefs.getBoolPref("mail.tabs.extraDragSpace");
|
||||
if (
|
||||
window.opener &&
|
||||
window.opener.document.documentElement.getAttribute("windowtype") ==
|
||||
"mail:3pane"
|
||||
) {
|
||||
document.getElementById("titlebarSettings").hidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Build up the palette of other items.
|
||||
buildPalette();
|
||||
|
||||
// Wrap all the items on the toolbar in toolbarpaletteitems.
|
||||
wrapToolbarItems();
|
||||
}
|
||||
|
||||
function repositionDialog(aWindow) {
|
||||
// Position the dialog touching the bottom of the toolbox and centered with
|
||||
// it.
|
||||
if (!aWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
var width;
|
||||
if (aWindow != window) {
|
||||
width = aWindow.getBoundingClientRect().width;
|
||||
} else if (document.documentElement.hasAttribute("width")) {
|
||||
width = document.documentElement.getAttribute("width");
|
||||
} else {
|
||||
width = parseInt(document.documentElement.style.width);
|
||||
}
|
||||
var boundingRect = gToolbox.getBoundingClientRect();
|
||||
var screenX = gToolbox.screenX + (boundingRect.width - width) / 2;
|
||||
var screenY = gToolbox.screenY + boundingRect.height;
|
||||
|
||||
aWindow.moveTo(screenX, screenY);
|
||||
}
|
||||
|
||||
function removeToolboxListeners() {
|
||||
var elts = getRootElements();
|
||||
for (let i = 0; i < elts.length; i++) {
|
||||
elts[i].removeEventListener("dragstart", onToolbarDragStart, true);
|
||||
elts[i].removeEventListener("dragover", onToolbarDragOver, true);
|
||||
elts[i].removeEventListener("dragexit", onToolbarDragExit, true);
|
||||
elts[i].removeEventListener("drop", onToolbarDrop, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
dispatchCustomizationEvent("aftercustomization");
|
||||
}
|
||||
|
||||
function toolboxChanged(aType) {
|
||||
gToolboxChanged = true;
|
||||
if ("customizeChange" in gToolbox) {
|
||||
gToolbox.customizeChange(aType);
|
||||
}
|
||||
dispatchCustomizationEvent("customizationchange");
|
||||
}
|
||||
|
||||
function dispatchCustomizationEvent(aEventName) {
|
||||
var evt = document.createEvent("Events");
|
||||
evt.initEvent(aEventName, true, true);
|
||||
gToolbox.dispatchEvent(evt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist the current set of buttons in all customizable toolbars to
|
||||
* localstore.
|
||||
*/
|
||||
function persistCurrentSets() {
|
||||
if (!gToolboxChanged || gToolboxDocument.defaultView.closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
forEachCustomizableToolbar(function(toolbar) {
|
||||
// Calculate currentset and store it in the attribute.
|
||||
var currentSet = toolbar.currentSet;
|
||||
toolbar.setAttribute("currentset", currentSet);
|
||||
Services.xulStore.persist(toolbar, "currentset");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps all items in all customizable toolbars in a toolbox.
|
||||
*/
|
||||
function wrapToolbarItems() {
|
||||
forEachCustomizableToolbar(function(toolbar) {
|
||||
for (let item of toolbar.children) {
|
||||
if (AppConstants.platform == "macosx") {
|
||||
if (
|
||||
item.firstElementChild &&
|
||||
item.firstElementChild.localName == "menubar"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (isToolbarItem(item)) {
|
||||
let wrapper = wrapToolbarItem(item);
|
||||
cleanupItemForToolbar(item, wrapper);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getRootElements() {
|
||||
if (window.frameElement && "externalToolbars" in window.frameElement) {
|
||||
return [gToolbox].concat(window.frameElement.externalToolbars);
|
||||
}
|
||||
if ("arguments" in window && window.arguments[1].length > 0) {
|
||||
return [gToolbox].concat(window.arguments[1]);
|
||||
}
|
||||
return [gToolbox];
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwraps all items in all customizable toolbars in a toolbox.
|
||||
*/
|
||||
function unwrapToolbarItems() {
|
||||
let elts = getRootElements();
|
||||
for (let i = 0; i < elts.length; i++) {
|
||||
let paletteItems = elts[i].getElementsByTagName("toolbarpaletteitem");
|
||||
let paletteItem;
|
||||
while ((paletteItem = paletteItems.item(0)) != null) {
|
||||
let toolbarItem = paletteItem.firstElementChild;
|
||||
restoreItemForToolbar(toolbarItem, paletteItem);
|
||||
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) {
|
||||
let wrapper = aDocument.createXULElement("toolbarpaletteitem");
|
||||
|
||||
wrapper.id = "wrapper-" + aId;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an item that has been cloned from a template and adds
|
||||
* it to the end of the palette.
|
||||
*/
|
||||
function wrapPaletteItem(aPaletteItem) {
|
||||
var wrapper = createWrapper(aPaletteItem.id, document);
|
||||
|
||||
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);
|
||||
|
||||
gPaletteBox.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 = {};
|
||||
forEachCustomizableToolbar(function(toolbar) {
|
||||
var child = toolbar.firstElementChild;
|
||||
while (child) {
|
||||
if (isToolbarItem(child)) {
|
||||
currentItems[child.id] = 1;
|
||||
}
|
||||
child = child.nextElementSibling;
|
||||
}
|
||||
});
|
||||
return currentItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the palette of draggable items that are not yet in a toolbar.
|
||||
*/
|
||||
function buildPalette() {
|
||||
// Empty the palette first.
|
||||
while (gPaletteBox.lastElementChild) {
|
||||
gPaletteBox.lastChild.remove();
|
||||
}
|
||||
|
||||
// Add the toolbar separator item.
|
||||
var templateNode = document.createXULElement("toolbarseparator");
|
||||
templateNode.id = "separator";
|
||||
wrapPaletteItem(templateNode);
|
||||
|
||||
// Add the toolbar spring item.
|
||||
templateNode = document.createXULElement("toolbarspring");
|
||||
templateNode.id = "spring";
|
||||
templateNode.flex = 1;
|
||||
wrapPaletteItem(templateNode);
|
||||
|
||||
// Add the toolbar spacer item.
|
||||
templateNode = document.createXULElement("toolbarspacer");
|
||||
templateNode.id = "spacer";
|
||||
templateNode.flex = 1;
|
||||
wrapPaletteItem(templateNode);
|
||||
|
||||
var currentItems = getCurrentItemIds();
|
||||
templateNode = gToolbox.palette.firstElementChild;
|
||||
while (templateNode) {
|
||||
// Check if the item is already in a toolbar before adding it to the
|
||||
// palette, but do not add back separators, springs and spacers - we do
|
||||
// not want them duplicated.
|
||||
if (!isSpecialItem(templateNode) && !(templateNode.id in currentItems)) {
|
||||
var paletteItem = document.importNode(templateNode, true);
|
||||
wrapPaletteItem(paletteItem);
|
||||
}
|
||||
|
||||
templateNode = templateNode.nextElementSibling;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure that an item that has been cloned from a template
|
||||
* is stripped of any attributes 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 (aItem.hasAttribute("label")) {
|
||||
aWrapper.setAttribute("title", aItem.getAttribute("label"));
|
||||
} 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);
|
||||
}
|
||||
aWrapper.setAttribute("tooltiptext", aWrapper.getAttribute("title"));
|
||||
|
||||
// Remove attributes that screw up our appearance.
|
||||
aItem.removeAttribute("command");
|
||||
aItem.removeAttribute("observes");
|
||||
aItem.removeAttribute("type");
|
||||
aItem.removeAttribute("width");
|
||||
aItem.removeAttribute("checked");
|
||||
aItem.removeAttribute("collapsed");
|
||||
|
||||
aWrapper.querySelectorAll("[disabled]").forEach(function(aNode) {
|
||||
aNode.removeAttribute("disabled");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.hasAttribute("collapsed")) {
|
||||
aWrapper.setAttribute("itemcollapsed", aItem.getAttribute("collapsed"));
|
||||
aItem.removeAttribute("collapsed");
|
||||
}
|
||||
|
||||
if (aItem.checked) {
|
||||
aWrapper.setAttribute("itemchecked", "true");
|
||||
aItem.checked = false;
|
||||
}
|
||||
|
||||
if (aItem.disabled) {
|
||||
aWrapper.setAttribute("itemdisabled", "true");
|
||||
aItem.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore all the properties that we stripped off above.
|
||||
*/
|
||||
function restoreItemForToolbar(aItem, aWrapper) {
|
||||
if (aWrapper.hasAttribute("itemdisabled")) {
|
||||
aItem.disabled = true;
|
||||
}
|
||||
|
||||
if (aWrapper.hasAttribute("itemchecked")) {
|
||||
aItem.checked = true;
|
||||
}
|
||||
|
||||
if (aWrapper.hasAttribute("itemcollapsed")) {
|
||||
let collapsed = aWrapper.getAttribute("itemcollapsed");
|
||||
aItem.setAttribute("collapsed", collapsed);
|
||||
}
|
||||
|
||||
if (aWrapper.hasAttribute("itemcommand")) {
|
||||
let commandID = aWrapper.getAttribute("itemcommand");
|
||||
aItem.setAttribute("command", commandID);
|
||||
|
||||
// XXX Bug 309953 - toolbarbuttons aren't in sync with their commands after customizing
|
||||
let command = gToolboxDocument.getElementById(commandID);
|
||||
if (command && command.hasAttribute("disabled")) {
|
||||
aItem.setAttribute("disabled", command.getAttribute("disabled"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.firstElementChild) {
|
||||
aWrapper.setAttribute("type", aItem.firstElementChild.localName);
|
||||
}
|
||||
}
|
||||
|
||||
function setDragActive(aItem, aValue) {
|
||||
var node = aItem;
|
||||
var direction = window.getComputedStyle(aItem).direction;
|
||||
var value = direction == "ltr" ? "left" : "right";
|
||||
if (aItem.localName == "toolbar") {
|
||||
node = aItem.lastElementChild;
|
||||
value = direction == "ltr" ? "right" : "left";
|
||||
}
|
||||
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aValue) {
|
||||
if (!node.hasAttribute("dragover")) {
|
||||
node.setAttribute("dragover", value);
|
||||
}
|
||||
} else {
|
||||
node.removeAttribute("dragover");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.lastElementChild;
|
||||
while (child) {
|
||||
if (child.hasAttribute("customindex")) {
|
||||
var thisChild = child;
|
||||
child = child.previousElementSibling;
|
||||
thisChild.currentSet = "__empty";
|
||||
gToolbox.removeChild(thisChild);
|
||||
} else {
|
||||
child = child.previousElementSibling;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the defaultset for fixed toolbars.
|
||||
forEachCustomizableToolbar(function(toolbar) {
|
||||
var defaultSet = toolbar.getAttribute("defaultset");
|
||||
if (defaultSet) {
|
||||
toolbar.currentSet = defaultSet;
|
||||
}
|
||||
});
|
||||
|
||||
// Restore the default icon size and mode.
|
||||
document.getElementById("smallicons").checked = updateIconSize() == "small";
|
||||
document.getElementById("modelist").value = updateToolbarMode();
|
||||
|
||||
// Now rebuild the palette.
|
||||
buildPalette();
|
||||
|
||||
// Now re-wrap the items on the toolbar.
|
||||
wrapToolbarItems();
|
||||
|
||||
toolboxChanged("reset");
|
||||
}
|
||||
|
||||
function updateIconSize(aSize) {
|
||||
return updateToolboxProperty("iconsize", aSize, "large");
|
||||
}
|
||||
|
||||
function updateTitlebar() {
|
||||
let titlebarCheckbox = document.getElementById("showTitlebar");
|
||||
Services.prefs.setBoolPref(
|
||||
"mail.tabs.drawInTitlebar",
|
||||
!titlebarCheckbox.checked
|
||||
);
|
||||
|
||||
// Bring the customizeToolbar window to front (on linux it's behind the main
|
||||
// window). Otherwise the customization window gets left in the background.
|
||||
setTimeout(() => window.focus(), 100);
|
||||
}
|
||||
|
||||
function updateDragSpace() {
|
||||
let dragSpaceCheckbox = document.getElementById("showDragSpace");
|
||||
Services.prefs.setBoolPref(
|
||||
"mail.tabs.extraDragSpace",
|
||||
dragSpaceCheckbox.checked
|
||||
);
|
||||
|
||||
// Bring the customizeToolbar window to front (on linux it's behind the main
|
||||
// window). Otherwise the customization window gets left in the background.
|
||||
setTimeout(() => window.focus(), 100);
|
||||
}
|
||||
|
||||
function updateToolbarMode(aModeValue) {
|
||||
var mode = updateToolboxProperty("mode", aModeValue, "icons");
|
||||
|
||||
var iconSizeCheckbox = document.getElementById("smallicons");
|
||||
iconSizeCheckbox.disabled = mode == "text";
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
function updateToolboxProperty(aProp, aValue, aToolkitDefault) {
|
||||
var toolboxDefault =
|
||||
gToolbox.getAttribute("default" + aProp) || aToolkitDefault;
|
||||
|
||||
gToolbox.setAttribute(aProp, aValue || toolboxDefault);
|
||||
Services.xulStore.persist(gToolbox, aProp);
|
||||
|
||||
forEachCustomizableToolbar(function(toolbar) {
|
||||
var toolbarDefault =
|
||||
toolbar.getAttribute("default" + aProp) || toolboxDefault;
|
||||
if (
|
||||
toolbar.getAttribute("lock" + aProp) == "true" &&
|
||||
toolbar.getAttribute(aProp) == toolbarDefault
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
toolbar.setAttribute(aProp, aValue || toolbarDefault);
|
||||
Services.xulStore.persist(toolbar, aProp);
|
||||
});
|
||||
|
||||
toolboxChanged(aProp);
|
||||
|
||||
return aValue || toolboxDefault;
|
||||
}
|
||||
|
||||
function forEachCustomizableToolbar(callback) {
|
||||
if (window.frameElement && "externalToolbars" in window.frameElement) {
|
||||
Array.from(window.frameElement.externalToolbars)
|
||||
.filter(isCustomizableToolbar)
|
||||
.forEach(callback);
|
||||
} else if ("arguments" in window && window.arguments[1].length > 0) {
|
||||
Array.from(window.arguments[1])
|
||||
.filter(isCustomizableToolbar)
|
||||
.forEach(callback);
|
||||
}
|
||||
Array.from(gToolbox.children)
|
||||
.filter(isCustomizableToolbar)
|
||||
.forEach(callback);
|
||||
}
|
||||
|
||||
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 onToolbarDragExit(aEvent) {
|
||||
if (isUnwantedDragEvent(aEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gCurrentDragOverItem) {
|
||||
setDragActive(gCurrentDragOverItem, false);
|
||||
}
|
||||
}
|
||||
|
||||
function onToolbarDragStart(aEvent) {
|
||||
var item = aEvent.target;
|
||||
while (item && item.localName != "toolbarpaletteitem") {
|
||||
if (item.localName == "toolbar") {
|
||||
return;
|
||||
}
|
||||
item = item.parentNode;
|
||||
}
|
||||
|
||||
item.setAttribute("dragactive", "true");
|
||||
|
||||
var dt = aEvent.dataTransfer;
|
||||
var documentId = gToolboxDocument.documentElement.id;
|
||||
dt.setData("text/toolbarwrapper-id/" + documentId, item.firstElementChild.id);
|
||||
dt.effectAllowed = "move";
|
||||
}
|
||||
|
||||
function onToolbarDragOver(aEvent) {
|
||||
if (isUnwantedDragEvent(aEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var documentId = gToolboxDocument.documentElement.id;
|
||||
if (
|
||||
!aEvent.dataTransfer.types.includes(
|
||||
"text/toolbarwrapper-id/" + documentId.toLowerCase()
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
var toolbar = aEvent.target;
|
||||
var dropTarget = aEvent.target;
|
||||
while (toolbar && toolbar.localName != "toolbar") {
|
||||
dropTarget = toolbar;
|
||||
toolbar = toolbar.parentNode;
|
||||
}
|
||||
|
||||
// Make sure we are dragging over a customizable toolbar.
|
||||
if (!toolbar || !isCustomizableToolbar(toolbar)) {
|
||||
gCurrentDragOverItem = null;
|
||||
return;
|
||||
}
|
||||
|
||||
var previousDragItem = gCurrentDragOverItem;
|
||||
|
||||
if (dropTarget.localName == "toolbar") {
|
||||
gCurrentDragOverItem = dropTarget;
|
||||
} else {
|
||||
gCurrentDragOverItem = null;
|
||||
|
||||
var direction = window.getComputedStyle(dropTarget.parentNode).direction;
|
||||
var boundingRect = dropTarget.getBoundingClientRect();
|
||||
var dropTargetCenter = boundingRect.x + boundingRect.width / 2;
|
||||
var dragAfter;
|
||||
if (direction == "ltr") {
|
||||
dragAfter = aEvent.clientX > dropTargetCenter;
|
||||
} else {
|
||||
dragAfter = aEvent.clientX < dropTargetCenter;
|
||||
}
|
||||
|
||||
if (dragAfter) {
|
||||
gCurrentDragOverItem = dropTarget.nextElementSibling;
|
||||
if (!gCurrentDragOverItem) {
|
||||
gCurrentDragOverItem = toolbar;
|
||||
}
|
||||
} else {
|
||||
gCurrentDragOverItem = dropTarget;
|
||||
}
|
||||
}
|
||||
|
||||
if (previousDragItem && gCurrentDragOverItem != previousDragItem) {
|
||||
setDragActive(previousDragItem, false);
|
||||
}
|
||||
|
||||
setDragActive(gCurrentDragOverItem, true);
|
||||
|
||||
aEvent.preventDefault();
|
||||
aEvent.stopPropagation();
|
||||
}
|
||||
|
||||
function onToolbarDrop(aEvent) {
|
||||
if (isUnwantedDragEvent(aEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gCurrentDragOverItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
setDragActive(gCurrentDragOverItem, false);
|
||||
|
||||
var documentId = gToolboxDocument.documentElement.id;
|
||||
var draggedItemId = aEvent.dataTransfer.getData(
|
||||
"text/toolbarwrapper-id/" + documentId
|
||||
);
|
||||
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.
|
||||
let wrapper = gToolboxDocument.getElementById("wrapper-" + draggedItemId);
|
||||
if (wrapper == gCurrentDragOverItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't allow non-removable kids (e.g., the menubar) to move.
|
||||
if (wrapper.firstElementChild.getAttribute("removable") != "true") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the item from its place in the toolbar.
|
||||
wrapper.remove();
|
||||
|
||||
// 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.
|
||||
let 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.
|
||||
if (
|
||||
draggedItemId != "separator" &&
|
||||
draggedItemId != "spring" &&
|
||||
draggedItemId != "spacer"
|
||||
) {
|
||||
gPaletteBox.removeChild(draggedPaletteWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentDragOverItem = null;
|
||||
|
||||
toolboxChanged();
|
||||
}
|
||||
|
||||
function onPaletteDragOver(aEvent) {
|
||||
if (isUnwantedDragEvent(aEvent)) {
|
||||
return;
|
||||
}
|
||||
var documentId = gToolboxDocument.documentElement.id;
|
||||
if (
|
||||
aEvent.dataTransfer.types.includes(
|
||||
"text/toolbarwrapper-id/" + documentId.toLowerCase()
|
||||
)
|
||||
) {
|
||||
aEvent.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
function onPaletteDrop(aEvent) {
|
||||
if (isUnwantedDragEvent(aEvent)) {
|
||||
return;
|
||||
}
|
||||
var documentId = gToolboxDocument.documentElement.id;
|
||||
var itemId = aEvent.dataTransfer.getData(
|
||||
"text/toolbarwrapper-id/" + documentId
|
||||
);
|
||||
|
||||
var wrapper = gToolboxDocument.getElementById("wrapper-" + itemId);
|
||||
if (wrapper) {
|
||||
// Don't allow non-removable kids (e.g., the menubar) to move.
|
||||
if (wrapper.firstElementChild.getAttribute("removable") != "true") {
|
||||
return;
|
||||
}
|
||||
|
||||
var wrapperType = wrapper.getAttribute("type");
|
||||
if (
|
||||
wrapperType != "separator" &&
|
||||
wrapperType != "spacer" &&
|
||||
wrapperType != "spring"
|
||||
) {
|
||||
restoreItemForToolbar(wrapper.firstElementChild, wrapper);
|
||||
wrapPaletteItem(document.importNode(wrapper.firstElementChild, true));
|
||||
gToolbox.palette.appendChild(wrapper.firstElementChild);
|
||||
}
|
||||
|
||||
// The item was dragged out of the toolbar.
|
||||
wrapper.remove();
|
||||
}
|
||||
|
||||
toolboxChanged();
|
||||
}
|
||||
|
||||
function isUnwantedDragEvent(aEvent) {
|
||||
try {
|
||||
if (
|
||||
Services.prefs.getBoolPref("toolkit.customization.unsafe_drag_events")
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
} catch (ex) {}
|
||||
|
||||
/* Discard drag events that originated from a separate window to
|
||||
prevent content->chrome privilege escalations. */
|
||||
let mozSourceNode = aEvent.dataTransfer.mozSourceNode;
|
||||
// mozSourceNode is null in the dragStart event handler or if
|
||||
// the drag event originated in an external application.
|
||||
if (!mozSourceNode) {
|
||||
return true;
|
||||
}
|
||||
let sourceWindow = mozSourceNode.ownerGlobal;
|
||||
return sourceWindow != window && sourceWindow != gToolboxDocument.defaultView;
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<!DOCTYPE dialog [
|
||||
<!ENTITY % customizeToolbarDTD SYSTEM
|
||||
#ifdef MOZ_SUITE
|
||||
"chrome://communicator/locale/customizeToolbar.dtd">
|
||||
#else
|
||||
"chrome://messenger/locale/customizeToolbar.dtd">
|
||||
#endif
|
||||
%customizeToolbarDTD;
|
||||
]>
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
|
||||
#ifdef MOZ_SUITE
|
||||
<?xml-stylesheet href="chrome://communicator/content/customizeToolbar.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://communicator/skin/customizeToolbar.css" type="text/css"?>
|
||||
#else
|
||||
<?xml-stylesheet href="chrome://messenger/content/customizeToolbar.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://messenger/skin/customizeToolbar.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://messenger/content/messenger.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://messenger/skin/messenger.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://messenger/skin/messageHeader.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://messenger/skin/primaryToolbar.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://messenger/skin/chat.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://messenger/skin/addressbook/addressbook.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://messenger/skin/messengercompose/messengercompose.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://messenger/skin/themeableDialog.css" type="text/css"?>
|
||||
#endif
|
||||
<?xml-stylesheet href="chrome://calendar/skin/calendar-task-view.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://calendar/skin/shared/dialogs/calendar-event-dialog.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://calendar/skin/calendar-toolbar.css" type="text/css"?>
|
||||
|
||||
<window id="CustomizeToolbarWindow"
|
||||
title="&dialog.title;"
|
||||
#ifdef MOZ_SUITE
|
||||
onload="onLoad();"
|
||||
#else
|
||||
lightweightthemes="true"
|
||||
windowtype="mailnews:customizeToolbar"
|
||||
onload="overlayOnLoad();"
|
||||
#endif
|
||||
onunload="onUnload();"
|
||||
style="&dialog.dimensions;"
|
||||
persist="width height"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
|
||||
#ifdef MOZ_SUITE
|
||||
<script src="chrome://communicator/content/customizeToolbar.js"/>
|
||||
<stringbundle id="stringBundle" src="chrome://communicator/locale/customizeToolbar.properties"/>
|
||||
#else
|
||||
<script src="chrome://messenger/content/customizeToolbar.js"/>
|
||||
<script src="chrome://messenger/content/mailCore.js"/>
|
||||
<stringbundle id="stringBundle" src="chrome://messenger/locale/customizeToolbar.properties"/>
|
||||
#endif
|
||||
|
||||
<keyset id="CustomizeToolbarKeyset">
|
||||
<key id="cmd_close1" keycode="VK_ESCAPE" oncommand="onClose();"/>
|
||||
<key id="cmd_close2" keycode="VK_RETURN" oncommand="onClose();"/>
|
||||
</keyset>
|
||||
|
||||
<vbox id="main-box" flex="1">
|
||||
<description id="instructions">
|
||||
&instructions.description;
|
||||
</description>
|
||||
|
||||
<vbox flex="1" id="palette-box"
|
||||
ondragstart="onToolbarDragStart(event)"
|
||||
ondragover="onPaletteDragOver(event)"
|
||||
ondrop="onPaletteDrop(event)"/>
|
||||
|
||||
<hbox id="buttonBox" align="center">
|
||||
#ifndef MOZ_SUITE
|
||||
<hbox id="titlebarSettings" hidden="true">
|
||||
<checkbox id="showTitlebar" oncommand="updateTitlebar();" label="&showTitlebar2.label;"/>
|
||||
<checkbox id="showDragSpace" oncommand="updateDragSpace();" label="&extraDragSpace2.label;"/>
|
||||
</hbox>
|
||||
#endif
|
||||
<label id="modelistLabel" value="&show.label;" control="modelist"/>
|
||||
<menulist id="modelist"
|
||||
value="icons"
|
||||
#ifdef MOZ_SUITE
|
||||
oncommand="updateToolbarMode(this.value);">
|
||||
#else
|
||||
oncommand="overlayUpdateToolbarMode(this.value, 'mail-toolbox');">
|
||||
#endif
|
||||
<menupopup id="modelistpopup">
|
||||
<menuitem id="modefull" value="full" label="&iconsAndText.label;"/>
|
||||
<menuitem id="modeicons" value="icons" label="&icons.label;"/>
|
||||
<menuitem id="modetext" value="text" label="&text.label;"/>
|
||||
#ifndef MOZ_SUITE
|
||||
<menuitem id="textbesideiconItem" value="textbesideicon" label="&iconsBesideText.label;"/>
|
||||
#endif
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<checkbox id="smallicons" oncommand="updateIconSize(this.checked ? 'small' : 'large');" label="&useSmallIcons.label;"/>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
<button id="restoreDefault" label="&restoreDefaultSet.label;" oncommand="restoreDefaultSet();"/>
|
||||
<spacer flex="1"/>
|
||||
<button id="donebutton" label="&saveChanges.label;" oncommand="onClose();"
|
||||
default="true"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
||||
</window>
|
|
@ -16,7 +16,6 @@ DIRS += [
|
|||
"modules",
|
||||
"themes/classic",
|
||||
"themes/modern",
|
||||
"../common",
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_IRC']:
|
||||
|
|
Загрузка…
Ссылка в новой задаче