!import
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1 //@line 40 "/home/visbrero/mnt/roisin/rev_control/hg/mozilla/mail/base/content/customizeToolbar.js"
2
3 const kRowMax = 4;
4 const kWindowWidth = 600;
5 const kWindowHeight = 400;
6 const kAnimateIncrement = 50;
7 const kAnimateSteps = kWindowHeight / kAnimateIncrement - 1;
8 const kVSizeSlop = 5;
9
10 var gToolboxDocument = null;
11 var gToolbox = null;
12 var gCurrentDragOverItem = null;
13 var gToolboxChanged = false;
14 var gPreviousMode = null;
15 var gPreviousIconSize = null;
16
onLoad
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
17 function onLoad()
18 {
19 InitWithToolbox(window.arguments[0]);
20 repositionDialog();
21 }
22
InitWithToolbox
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
23 function InitWithToolbox(aToolbox)
24 {
25 gToolbox = aToolbox;
26 gToolboxDocument = gToolbox.ownerDocument;
27
28 gToolbox.addEventListener("draggesture", onToolbarDragGesture, false);
29 gToolbox.addEventListener("dragover", onToolbarDragOver, false);
30 gToolbox.addEventListener("dragexit", onToolbarDragExit, false);
31 gToolbox.addEventListener("dragdrop", onToolbarDragDrop, false);
32
33 initDialog();
34 }
35
finishToolbarCustomization
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
36 function finishToolbarCustomization()
37 {
38 removeToolboxListeners();
39 unwrapToolbarItems(true);
40 persistCurrentSets();
41
42 notifyParentComplete();
43 }
44
onCancel
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
45 function onCancel()
46 {
47 // restore the saved toolbarset for each customizeable toolbar
48 unwrapToolbarItems(false);
49 var toolbar = gToolbox.firstChild;
50 while (toolbar) {
51 if (isCustomizableToolbar(toolbar)) {
52 if (!toolbar.hasAttribute("customindex")) {
53 var previousset = toolbar.getAttribute("previousset");
54 if (previousset)
55 {
56 toolbar.currentSet = previousset;
57 }
58 }
59 }
60 toolbar = toolbar.nextSibling;
61 }
62
63 // restore the previous mode and iconsize
64 updateIconSize(gPreviousIconSize == "small");
65 updateToolbarMode(gPreviousMode);
66
67 repositionDialog();
68 gToolboxChanged = true;
69
70 return onAccept(); // we restored the default toolbar, act like a normal accept event now
71 }
72
onAccept
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
73 function onAccept(aEvent)
74 {
75 document.getElementById("main-box").collapsed = true;
76 window.close();
77 }
78
initDialog
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
79 function initDialog()
80 {
81 document.getElementById("main-box").collapsed = false;
82
83 gPreviousMode = gToolbox.getAttribute("mode");
84 document.getElementById("modelist").value = gPreviousMode;
85 gPreviousIconSize = gToolbox.getAttribute("iconsize");
86 var smallIconsCheckbox = document.getElementById("smallicons");
87 if (gPreviousMode == "text")
88 smallIconsCheckbox.disabled = true;
89 else
90 smallIconsCheckbox.checked = gPreviousIconSize == "small";
91
92 // Build up the palette of other items.
93 buildPalette();
94
95 // Wrap all the items on the toolbar in toolbarpaletteitems.
96 wrapToolbarItems(true);
97 }
98
repositionDialog
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
99 function repositionDialog()
100 {
101 // Position the dialog touching the bottom of the toolbox and centered with
102 // it. We must resize the window smaller first so that it is positioned
103 // properly.
104 var screenX = gToolbox.boxObject.screenX + ((gToolbox.boxObject.width - kWindowWidth) / 2);
105 var screenY = gToolbox.boxObject.screenY + gToolbox.boxObject.height;
106
107 var newHeight = kWindowHeight;
108 if (newHeight >= screen.availHeight - screenY - kVSizeSlop) {
109 newHeight = screen.availHeight - screenY - kVSizeSlop;
110 }
111
112 window.resizeTo(kWindowWidth, newHeight);
113 window.moveTo(screenX, screenY);
114 }
115
removeToolboxListeners
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
116 function removeToolboxListeners()
117 {
118 gToolbox.removeEventListener("draggesture", onToolbarDragGesture, false);
119 gToolbox.removeEventListener("dragover", onToolbarDragOver, false);
120 gToolbox.removeEventListener("dragexit", onToolbarDragExit, false);
121 gToolbox.removeEventListener("dragdrop", onToolbarDragDrop, false);
122 }
123
124 /**
125 * Invoke a callback on the toolbox to notify it that the dialog is done
126 * and going away.
127 */
notifyParentComplete
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
128 function notifyParentComplete()
129 {
130 if ("customizeDone" in gToolbox)
131 gToolbox.customizeDone(gToolboxChanged);
132 }
133
getToolbarAt
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
134 function getToolbarAt(i)
135 {
136 return gToolbox.childNodes[i];
137 }
138
139 /**
140 * Persist the current set of buttons in all customizable toolbars to
141 * localstore.
142 */
persistCurrentSets
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
143 function persistCurrentSets()
144 {
145 if (!gToolboxChanged || gToolboxDocument.defaultView.closed)
146 return;
147
148 var customCount = 0;
149 for (var i = 0; i < gToolbox.childNodes.length; ++i) {
150 // Look for customizable toolbars that need to be persisted.
151 var toolbar = getToolbarAt(i);
152 if (isCustomizableToolbar(toolbar)) {
153 // Calculate currentset and store it in the attribute.
154 var currentSet = toolbar.currentSet;
155 toolbar.setAttribute("currentset", currentSet);
156
157 var customIndex = toolbar.hasAttribute("customindex");
158 if (customIndex) {
159 if (!toolbar.firstChild) {
160 // Remove custom toolbars whose contents have been removed.
161 gToolbox.removeChild(toolbar);
162 --i;
163 } else {
164 // Persist custom toolbar info on the <toolbarset/>
165 gToolbox.toolbarset.setAttribute("toolbar"+(++customCount),
166 toolbar.toolbarName + ":" + currentSet);
167 gToolboxDocument.persist(gToolbox.toolbarset.id, "toolbar"+customCount);
168 }
169 }
170
171 if (!customIndex) {
172 // Persist the currentset attribute directly on hardcoded toolbars.
173 gToolboxDocument.persist(toolbar.id, "currentset");
174 }
175 }
176 }
177
178 // Remove toolbarX attributes for removed toolbars.
179 while (gToolbox.toolbarset.hasAttribute("toolbar"+(++customCount))) {
180 gToolbox.toolbarset.removeAttribute("toolbar"+customCount);
181 gToolboxDocument.persist(gToolbox.toolbarset.id, "toolbar"+customCount);
182 }
183 }
184
185 /**
186 * Wraps all items in all customizable toolbars in a toolbox.
187 */
wrapToolbarItems
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
188 function wrapToolbarItems(aStorePreviousSet)
189 {
190 for (var i = 0; i < gToolbox.childNodes.length; ++i) {
191 var toolbar = getToolbarAt(i);
192 if (isCustomizableToolbar(toolbar)) {
193 if (aStorePreviousSet)
194 toolbar.setAttribute('previousset', toolbar.currentSet);
195
196 for (var k = 0; k < toolbar.childNodes.length; ++k) {
197 var item = toolbar.childNodes[k];
198 if (isToolbarItem(item)) {
199 var nextSibling = item.nextSibling;
200
201 var wrapper = wrapToolbarItem(item);
202 if (nextSibling)
203 toolbar.insertBefore(wrapper, nextSibling);
204 else
205 toolbar.appendChild(wrapper);
206 }
207 }
208 }
209 }
210 }
211
212 /**
213 * Unwraps all items in all customizable toolbars in a toolbox.
214 */
unwrapToolbarItems
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
215 function unwrapToolbarItems(aRemovePreviousSet)
216 {
217 for (var i = 0; i < gToolbox.childNodes.length; ++i) {
218 var toolbar = getToolbarAt(i);
219 if (isCustomizableToolbar(toolbar)) {
220 if (aRemovePreviousSet)
221 toolbar.removeAttribute('previousset');
222
223 for (var k = 0; k < toolbar.childNodes.length; ++k) {
224 var paletteItem = toolbar.childNodes[k];
225 var toolbarItem = paletteItem.firstChild;
226
227 if (toolbarItem && isToolbarItem(toolbarItem)) {
228 var nextSibling = paletteItem.nextSibling;
229
230 if (paletteItem.hasAttribute("itemcommand"))
231 toolbarItem.setAttribute("command", paletteItem.getAttribute("itemcommand"));
232 if (paletteItem.hasAttribute("itemobserves"))
233 toolbarItem.setAttribute("observes", paletteItem.getAttribute("itemobserves"));
234
235 paletteItem.removeChild(toolbarItem);
236 paletteItem.parentNode.removeChild(paletteItem);
237
238 if (nextSibling)
239 toolbar.insertBefore(toolbarItem, nextSibling);
240 else
241 toolbar.appendChild(toolbarItem);
242 }
243 }
244 }
245 }
246 }
247
248
249 /**
250 * Creates a wrapper that can be used to contain a toolbaritem and prevent
251 * it from receiving UI events.
252 */
createWrapper
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
253 function createWrapper(aId)
254 {
255 var wrapper = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
256 "toolbarpaletteitem");
257
258 wrapper.id = "wrapper-"+aId;
259 return wrapper;
260 }
261
262 /**
263 * Wraps an item that has been cloned from a template and adds
264 * it to the end of a row in the palette.
265 */
wrapPaletteItem
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
266 function wrapPaletteItem(aPaletteItem, aCurrentRow, aSpacer)
267 {
268 var wrapper = createWrapper(aPaletteItem.id);
269
270 wrapper.setAttribute("flex", 1);
271 wrapper.setAttribute("align", "center");
272 wrapper.setAttribute("pack", "center");
273 wrapper.setAttribute("minheight", "0");
274 wrapper.setAttribute("minwidth", "0");
275
276 document.adoptNode(aPaletteItem);
277 wrapper.appendChild(aPaletteItem);
278
279 // XXX We need to call this AFTER the palette item has been appended
280 // to the wrapper or else we crash dropping certain buttons on the
281 // palette due to removal of the command and disabled attributes - JRH
282 cleanUpItemForPalette(aPaletteItem, wrapper);
283
284 if (aSpacer)
285 aCurrentRow.insertBefore(wrapper, aSpacer);
286 else
287 aCurrentRow.appendChild(wrapper);
288
289 }
290
291 /**
292 * Wraps an item that is currently on a toolbar and replaces the item
293 * with the wrapper. This is not used when dropping items from the palette,
294 * only when first starting the dialog and wrapping everything on the toolbars.
295 */
wrapToolbarItem
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
296 function wrapToolbarItem(aToolbarItem)
297 {
298 var wrapper = createWrapper(aToolbarItem.id);
299 gToolboxDocument.adoptNode(wrapper);
300
301 cleanupItemForToolbar(aToolbarItem, wrapper);
302 wrapper.flex = aToolbarItem.flex;
303
304 if (aToolbarItem.parentNode)
305 aToolbarItem.parentNode.removeChild(aToolbarItem);
306
307 wrapper.appendChild(aToolbarItem);
308
309 return wrapper;
310 }
311
312 /**
313 * Get the list of ids for the current set of items on each toolbar.
314 */
getCurrentItemIds
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
315 function getCurrentItemIds()
316 {
317 var currentItems = {};
318 for (var i = 0; i < gToolbox.childNodes.length; ++i) {
319 var toolbar = getToolbarAt(i);
320 if (isCustomizableToolbar(toolbar)) {
321 var child = toolbar.firstChild;
322 while (child) {
323 if (isToolbarItem(child))
324 currentItems[child.id] = 1;
325 child = child.nextSibling;
326 }
327 }
328 }
329 return currentItems;
330 }
331
332 /**
333 * Builds the palette of draggable items that are not yet in a toolbar.
334 */
buildPalette
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
335 function buildPalette()
336 {
337 // Empty the palette first.
338 var paletteBox = document.getElementById("palette-box");
339 while (paletteBox.lastChild)
340 paletteBox.removeChild(paletteBox.lastChild);
341
342 var currentRow = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
343 "hbox");
344 currentRow.setAttribute("class", "paletteRow");
345
346 // Add the toolbar separator item.
347 var templateNode = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
348 "toolbarseparator");
349 templateNode.id = "separator";
350 wrapPaletteItem(templateNode, currentRow, null);
351
352 // Add the toolbar spring item.
353 templateNode = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
354 "toolbarspring");
355 templateNode.id = "spring";
356 templateNode.flex = 1;
357 wrapPaletteItem(templateNode, currentRow, null);
358
359 // Add the toolbar spacer item.
360 templateNode = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
361 "toolbarspacer");
362 templateNode.id = "spacer";
363 templateNode.flex = 1;
364 wrapPaletteItem(templateNode, currentRow, null);
365
366 var rowSlot = 3;
367
368 var currentItems = getCurrentItemIds();
369 templateNode = gToolbox.palette.firstChild;
370 while (templateNode) {
371 // Check if the item is already in a toolbar before adding it to the palette.
372 if (!(templateNode.id in currentItems)) {
373 var paletteItem = templateNode.cloneNode(true);
374
375 if (rowSlot == kRowMax) {
376 // Append the old row.
377 paletteBox.appendChild(currentRow);
378
379 // Make a new row.
380 currentRow = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
381 "hbox");
382 currentRow.setAttribute("class", "paletteRow");
383 rowSlot = 0;
384 }
385
386 ++rowSlot;
387 wrapPaletteItem(paletteItem, currentRow, null);
388 }
389
390 templateNode = templateNode.nextSibling;
391 }
392
393 if (currentRow) {
394 fillRowWithFlex(currentRow);
395 paletteBox.appendChild(currentRow);
396 }
397 }
398
399 /**
400 * Creates a new palette item for a cloned template node and
401 * adds it to the last slot in the palette.
402 */
appendPaletteItem
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
403 function appendPaletteItem(aItem)
404 {
405 var paletteBox = document.getElementById("palette-box");
406 var lastRow = paletteBox.lastChild;
407 var lastSpacer = lastRow.lastChild;
408
409 if (lastSpacer.localName != "spacer") {
410 // The current row is full, so we have to create a new row.
411 lastRow = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
412 "hbox");
413 lastRow.setAttribute("class", "paletteRow");
414 paletteBox.appendChild(lastRow);
415
416 wrapPaletteItem(aItem, lastRow, null);
417
418 fillRowWithFlex(lastRow);
419 } else {
420 // Decrement the flex of the last spacer or remove it entirely.
421 var flex = lastSpacer.getAttribute("flex");
422 if (flex == 1) {
423 lastRow.removeChild(lastSpacer);
424 lastSpacer = null;
425 } else
426 lastSpacer.setAttribute("flex", --flex);
427
428 // Insert the wrapper where the last spacer was.
429 wrapPaletteItem(aItem, lastRow, lastSpacer);
430 }
431 }
432
fillRowWithFlex
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
433 function fillRowWithFlex(aRow)
434 {
435 var remainingFlex = kRowMax - aRow.childNodes.length;
436 if (remainingFlex > 0) {
437 var spacer = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
438 "spacer");
439 spacer.setAttribute("flex", remainingFlex);
440 aRow.appendChild(spacer);
441 }
442 }
443
444 /**
445 * Makes sure that an item that has been cloned from a template
446 * is stripped of all properties that may adversely affect it's
447 * appearance in the palette.
448 */
cleanUpItemForPalette
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
449 function cleanUpItemForPalette(aItem, aWrapper)
450 {
451 aWrapper.setAttribute("place", "palette");
452 setWrapperType(aItem, aWrapper);
453
454 if (aItem.hasAttribute("title"))
455 aWrapper.setAttribute("title", aItem.getAttribute("title"));
456 else if (isSpecialItem(aItem)) {
457 var stringBundle = document.getElementById("stringBundle");
458 var title = stringBundle.getString(aItem.id + "Title");
459 aWrapper.setAttribute("title", title);
460 }
461
462 // Remove attributes that screw up our appearance.
463 aItem.removeAttribute("command");
464 aItem.removeAttribute("observes");
465 aItem.removeAttribute("disabled");
466 aItem.removeAttribute("type");
467
468 if (aItem.localName == "toolbaritem" && aItem.firstChild) {
469 aItem.firstChild.removeAttribute("observes");
470
471 // So the throbber doesn't throb in the dialog,
472 // cute as that may be...
473 aItem.firstChild.removeAttribute("busy");
474 }
475 }
476
477 /**
478 * Makes sure that an item that has been cloned from a template
479 * is stripped of all properties that may adversely affect it's
480 * appearance in the toolbar. Store critical properties on the
481 * wrapper so they can be put back on the item when we're done.
482 */
cleanupItemForToolbar
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
483 function cleanupItemForToolbar(aItem, aWrapper)
484 {
485 setWrapperType(aItem, aWrapper);
486 aWrapper.setAttribute("place", "toolbar");
487
488 if (aItem.hasAttribute("command")) {
489 aWrapper.setAttribute("itemcommand", aItem.getAttribute("command"));
490 aItem.removeAttribute("command");
491 }
492
493 if (aItem.hasAttribute("observes"))
494 {
495 aWrapper.setAttribute("itemobserves", aItem.getAttribute("observes"));
496 aItem.removeAttribute("observes");
497 }
498
499 if (aItem.disabled) {
500 aWrapper.setAttribute("itemdisabled", "true");
501 aItem.disabled = false;
502 }
503 }
504
setWrapperType
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
505 function setWrapperType(aItem, aWrapper)
506 {
507 if (aItem.localName == "toolbarseparator") {
508 aWrapper.setAttribute("type", "separator");
509 } else if (aItem.localName == "toolbarspring") {
510 aWrapper.setAttribute("type", "spring");
511 } else if (aItem.localName == "toolbarspacer") {
512 aWrapper.setAttribute("type", "spacer");
513 } else if (aItem.localName == "toolbaritem" && aItem.firstChild) {
514 aWrapper.setAttribute("type", aItem.firstChild.localName);
515 }
516 }
517
setDragActive
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
518 function setDragActive(aItem, aValue)
519 {
520 var node = aItem;
521 var direction = window.getComputedStyle(aItem, null).direction;
522 var value = direction == "ltr"? "left" : "right";
523 if (aItem.localName == "toolbar") {
524 node = aItem.lastChild;
525 value = direction == "ltr"? "right" : "left";
526 }
527
528 if (!node)
529 return;
530
531 if (aValue) {
532 if (!node.hasAttribute("dragover"))
533 node.setAttribute("dragover", value);
534 } else {
535 node.removeAttribute("dragover");
536 }
537 }
538
539
540 /**
541 * Restore the default set of buttons to fixed toolbars,
542 * remove all custom toolbars, and rebuild the palette.
543 */
restoreDefaultSet
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
544 function restoreDefaultSet()
545 {
546 // Restore the defaultset for fixed toolbars.
547 unwrapToolbarItems(false);
548 var toolbar = gToolbox.firstChild;
549 while (toolbar) {
550 if (isCustomizableToolbar(toolbar)) {
551 if (!toolbar.hasAttribute("customindex")) {
552 var defaultSet = toolbar.getAttribute("defaultset");
553 if (defaultSet)
554 {
555 toolbar.currentSet = defaultSet;
556 }
557 }
558 }
559 toolbar = toolbar.nextSibling;
560 }
561
562 // Restore the default icon size (large) and mode (icons and text).
563 updateIconSize(false);
564 document.getElementById("smallicons").checked = false;
565 updateToolbarMode("full");
566 document.getElementById("modelist").value = "full";
567
568 // Remove all of the customized toolbars.
569 var child = gToolbox.lastChild;
570 while (child) {
571 if (child.hasAttribute("customindex")) {
572 var thisChild = child;
573 child = child.previousSibling;
574 gToolbox.removeChild(thisChild);
575 } else {
576 child = child.previousSibling;
577 }
578 }
579
580 // Now rebuild the palette.
581 buildPalette();
582
583 // Now re-wrap the items on the toolbar, but don't clobber previousset.
584 wrapToolbarItems(false);
585
586 repositionDialog();
587 gToolboxChanged = true;
588 }
589
updateIconSize
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
590 function updateIconSize(aUseSmallIcons)
591 {
592 var val = aUseSmallIcons ? "small" : null;
593
594 setAttribute(gToolbox, "iconsize", val);
595 gToolboxDocument.persist(gToolbox.id, "iconsize");
596
597 for (var i = 0; i < gToolbox.childNodes.length; ++i) {
598 var toolbar = getToolbarAt(i);
599 if (isCustomizableToolbar(toolbar)) {
600 setAttribute(toolbar, "iconsize", val);
601 gToolboxDocument.persist(toolbar.id, "iconsize");
602 }
603 }
604
605 repositionDialog();
606 }
607
updateToolbarMode
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
608 function updateToolbarMode(aModeValue)
609 {
610 setAttribute(gToolbox, "mode", aModeValue);
611 gToolboxDocument.persist(gToolbox.id, "mode");
612
613 for (var i = 0; i < gToolbox.childNodes.length; ++i) {
614 var toolbar = getToolbarAt(i);
615 if (isCustomizableToolbar(toolbar)) {
616 setAttribute(toolbar, "mode", aModeValue);
617 gToolboxDocument.persist(toolbar.id, "mode");
618 }
619 }
620
621 var iconSizeCheckbox = document.getElementById("smallicons");
622 iconSizeCheckbox.disabled = aModeValue == "text";
623
624 repositionDialog();
625 }
626
627
setAttribute
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
628 function setAttribute(aElt, aAttr, aVal)
629 {
630 if (aVal)
631 aElt.setAttribute(aAttr, aVal);
632 else
633 aElt.removeAttribute(aAttr);
634 }
635
isCustomizableToolbar
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
636 function isCustomizableToolbar(aElt)
637 {
638 return aElt.localName == "toolbar" &&
639 aElt.getAttribute("customizable") == "true";
640 }
641
isSpecialItem
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
642 function isSpecialItem(aElt)
643 {
644 return aElt.localName == "toolbarseparator" ||
645 aElt.localName == "toolbarspring" ||
646 aElt.localName == "toolbarspacer";
647 }
648
isToolbarItem
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
649 function isToolbarItem(aElt)
650 {
651 return aElt.localName == "toolbarbutton" ||
652 aElt.localName == "toolbaritem" ||
653 aElt.localName == "toolbarseparator" ||
654 aElt.localName == "toolbarspring" ||
655 aElt.localName == "toolbarspacer";
656 }
657
658 ///////////////////////////////////////////////////////////////////////////
659 //// Drag and Drop observers
660
onToolbarDragGesture
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
661 function onToolbarDragGesture(aEvent)
662 {
663 nsDragAndDrop.startDrag(aEvent, dragStartObserver);
664 }
665
onToolbarDragOver
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
666 function onToolbarDragOver(aEvent)
667 {
668 nsDragAndDrop.dragOver(aEvent, toolbarDNDObserver);
669 }
670
onToolbarDragDrop
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
671 function onToolbarDragDrop(aEvent)
672 {
673 nsDragAndDrop.drop(aEvent, toolbarDNDObserver);
674 }
675
onToolbarDragExit
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
676 function onToolbarDragExit(aEvent)
677 {
678 if (gCurrentDragOverItem)
679 setDragActive(gCurrentDragOverItem, false);
680 }
681
682 var dragStartObserver =
683 {
onDragStart
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
684 onDragStart: function (aEvent, aXferData, aDragAction) {
685 var documentId = gToolboxDocument.documentElement.id;
686
687 var item = aEvent.target;
688 while (item && item.localName != "toolbarpaletteitem")
689 item = item.parentNode;
690
691 item.setAttribute("dragactive", "true");
692
693 aXferData.data = new TransferDataSet();
694 var data = new TransferData();
695 data.addDataForFlavour("text/toolbarwrapper-id/"+documentId, item.firstChild.id);
696 aXferData.data.push(data);
697 }
698 }
699
700 var toolbarDNDObserver =
701 {
onDragOver
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
702 onDragOver: function (aEvent, aFlavour, aDragSession)
703 {
704 var toolbar = aEvent.target;
705 var dropTarget = aEvent.target;
706 while (toolbar && toolbar.localName != "toolbar") {
707 dropTarget = toolbar;
708 toolbar = toolbar.parentNode;
709 }
710
711 var previousDragItem = gCurrentDragOverItem;
712
713 // Make sure we are dragging over a customizable toolbar.
714 if (!isCustomizableToolbar(toolbar)) {
715 gCurrentDragOverItem = null;
716 return;
717 }
718
719 if (dropTarget.localName == "toolbar") {
720 gCurrentDragOverItem = dropTarget;
721 } else {
722 gCurrentDragOverItem = null;
723
724 var direction = window.getComputedStyle(dropTarget.parentNode, null).direction;
725 var dropTargetCenter = dropTarget.boxObject.x + (dropTarget.boxObject.width / 2);
726 if (direction == "ltr")
727 dragAfter = aEvent.clientX > dropTargetCenter;
728 else
729 dragAfter = aEvent.clientX < dropTargetCenter;
730
731 if (dragAfter) {
732 gCurrentDragOverItem = dropTarget.nextSibling;
733 if (!gCurrentDragOverItem)
734 gCurrentDragOverItem = toolbar;
735 } else
736 gCurrentDragOverItem = dropTarget;
737 }
738
739 if (previousDragItem && gCurrentDragOverItem != previousDragItem) {
740 setDragActive(previousDragItem, false);
741 }
742
743 setDragActive(gCurrentDragOverItem, true);
744
745 aDragSession.canDrop = true;
746 },
747
onDrop
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
748 onDrop: function (aEvent, aXferData, aDragSession)
749 {
750 if (!gCurrentDragOverItem)
751 return;
752
753 setDragActive(gCurrentDragOverItem, false);
754
755 var draggedItemId = aXferData.data;
756 if (gCurrentDragOverItem.id == draggedItemId)
757 return;
758
759 var toolbar = aEvent.target;
760 while (toolbar.localName != "toolbar")
761 toolbar = toolbar.parentNode;
762
763 var draggedPaletteWrapper = document.getElementById("wrapper-"+draggedItemId);
764 if (!draggedPaletteWrapper) {
765 // The wrapper has been dragged from the toolbar.
766
767 // Get the wrapper from the toolbar document and make sure that
768 // it isn't being dropped on itself.
769 var wrapper = gToolboxDocument.getElementById("wrapper-"+draggedItemId);
770 if (wrapper == gCurrentDragOverItem)
771 return;
772
773 // Don't allow static kids (e.g., the menubar) to move.
774 if (wrapper.parentNode.firstPermanentChild && wrapper.parentNode.firstPermanentChild.id == wrapper.firstChild.id)
775 return;
776 if (wrapper.parentNode.lastPermanentChild && wrapper.parentNode.lastPermanentChild.id == wrapper.firstChild.id)
777 return;
778
779 // Remove the item from it's place in the toolbar.
780 wrapper.parentNode.removeChild(wrapper);
781
782 // Determine which toolbar we are dropping on.
783 var dropToolbar = null;
784 if (gCurrentDragOverItem.localName == "toolbar")
785 dropToolbar = gCurrentDragOverItem;
786 else
787 dropToolbar = gCurrentDragOverItem.parentNode;
788
789 // Insert the item into the toolbar.
790 if (gCurrentDragOverItem != dropToolbar)
791 dropToolbar.insertBefore(wrapper, gCurrentDragOverItem);
792 else
793 dropToolbar.appendChild(wrapper);
794 } else {
795 // The item has been dragged from the palette
796
797 // Create a new wrapper for the item. We don't know the id yet.
798 var wrapper = createWrapper("");
799 gToolboxDocument.adoptNode(wrapper);
800
801 // Ask the toolbar to clone the item's template, place it inside the wrapper, and insert it in the toolbar.
802 var newItem = toolbar.insertItem(draggedItemId, gCurrentDragOverItem == toolbar ? null : gCurrentDragOverItem, wrapper);
803
804 // Prepare the item and wrapper to look good on the toolbar.
805 cleanupItemForToolbar(newItem, wrapper);
806 wrapper.id = "wrapper-"+newItem.id;
807 wrapper.flex = newItem.flex;
808
809 // Remove the wrapper from the palette.
810 var currentRow = draggedPaletteWrapper.parentNode;
811 if (draggedItemId != "separator" &&
812 draggedItemId != "spring" &&
813 draggedItemId != "spacer")
814 {
815 currentRow.removeChild(draggedPaletteWrapper);
816
817 while (currentRow) {
818 // Pull the first child of the next row up
819 // into this row.
820 var nextRow = currentRow.nextSibling;
821
822 if (!nextRow) {
823 var last = currentRow.lastChild;
824 var first = currentRow.firstChild;
825 if (first == last) {
826 // Kill the row.
827 currentRow.parentNode.removeChild(currentRow);
828 break;
829 }
830
831 if (last.localName == "spacer") {
832 var flex = last.getAttribute("flex");
833 last.setAttribute("flex", ++flex);
834 // Reflow doesn't happen for some reason. Trigger it with a hide/show. ICK! -dwh
835 last.hidden = true;
836 last.hidden = false;
837 break;
838 } else {
839 // Make a spacer and give it a flex of 1.
840 var spacer = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
841 "spacer");
842 spacer.setAttribute("flex", "1");
843 currentRow.appendChild(spacer);
844 }
845 break;
846 }
847
848 currentRow.appendChild(nextRow.firstChild);
849 currentRow = currentRow.nextSibling;
850 }
851 }
852 }
853
854 gCurrentDragOverItem = null;
855
856 repositionDialog();
857 gToolboxChanged = true;
858 },
859
860 _flavourSet: null,
861
getSupportedFlavours
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
862 getSupportedFlavours: function ()
863 {
864 if (!this._flavourSet) {
865 this._flavourSet = new FlavourSet();
866 var documentId = gToolboxDocument.documentElement.id;
867 this._flavourSet.appendFlavour("text/toolbarwrapper-id/"+documentId);
868 }
869 return this._flavourSet;
870 }
871 }
872
873 var paletteDNDObserver =
874 {
onDragOver
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
875 onDragOver: function (aEvent, aFlavour, aDragSession)
876 {
877 aDragSession.canDrop = true;
878 },
879
onDrop
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
880 onDrop: function(aEvent, aXferData, aDragSession)
881 {
882 var itemId = aXferData.data;
883
884 var wrapper = gToolboxDocument.getElementById("wrapper-"+itemId);
885 if (wrapper) {
886 // Don't allow static kids (e.g., the menubar) to move.
887 if (wrapper.parentNode.firstPermanentChild && wrapper.parentNode.firstPermanentChild.id == wrapper.firstChild.id)
888 return;
889 if (wrapper.parentNode.lastPermanentChild && wrapper.parentNode.lastPermanentChild.id == wrapper.firstChild.id)
890 return;
891
892 // The item was dragged out of the toolbar.
893 wrapper.parentNode.removeChild(wrapper);
894
895 var wrapperType = wrapper.getAttribute("type");
896 if (wrapperType != "separator" && wrapperType != "spacer" && wrapperType != "spring") {
897 // Find the template node in the toolbox palette
898 var templateNode = gToolbox.palette.firstChild;
899 while (templateNode) {
900 if (templateNode.id == itemId)
901 break;
902 templateNode = templateNode.nextSibling;
903 }
904 if (!templateNode)
905 return;
906
907 // Clone the template and add it to our palette.
908 var paletteItem = templateNode.cloneNode(true);
909 appendPaletteItem(paletteItem);
910 }
911 }
912
913 repositionDialog();
914 gToolboxChanged = true;
915 },
916
917 _flavourSet: null,
918
getSupportedFlavours
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
919 getSupportedFlavours: function ()
920 {
921 if (!this._flavourSet) {
922 this._flavourSet = new FlavourSet();
923 var documentId = gToolboxDocument.documentElement.id;
924 this._flavourSet.appendFlavour("text/toolbarwrapper-id/"+documentId);
925 }
926 return this._flavourSet;
927 }
928 }