OSDN Git Service

import source-tree based svn r84.
[bluegriffon/BlueGriffon.git] / base / content / bluegriffon / bindings / sidebar.xml
1 <?xml version="1.0"?>
2
3 <!-- ***** BEGIN LICENSE BLOCK *****
4    - Version: MPL 1.1/GPL 2.0/LGPL 2.1
5    -
6    - The contents of this file are subject to the Mozilla Public License Version
7    - 1.1 (the "License"); you may not use this file except in compliance with
8    - the License. You may obtain a copy of the License at
9    - http://www.mozilla.org/MPL/
10    -
11    - Software distributed under the License is distributed on an "AS IS" basis,
12    - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13    - for the specific language governing rights and limitations under the
14    - License.
15    -
16    - The Original Code is BlueGriffon.
17    -
18    - The Initial Developer of the Original Code is
19    - Disruptive Innovations SARL.
20    - Portions created by the Initial Developer are Copyright (C) 2006
21    - the Initial Developer. All Rights Reserved.
22    -
23    - Contributor(s):
24    -   Daniel Glazman (daniel.glazman@disruptive-innovations.com), Original Author
25    -
26    - Alternatively, the contents of this file may be used under the terms of
27    - either the GNU General Public License Version 2 or later (the "GPL"), or
28    - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29    - in which case the provisions of the GPL or the LGPL are applicable instead
30    - of those above. If you wish to allow use of your version of this file only
31    - under the terms of either the GPL or the LGPL, and not to allow others to
32    - use your version of this file under the terms of the MPL, indicate your
33    - decision by deleting the provisions above and replace them with the notice
34    - and other provisions required by the LGPL or the GPL. If you do not delete
35    - the provisions above, a recipient may use your version of this file under
36    - the terms of any one of the MPL, the GPL or the LGPL.
37    -
38    - ***** END LICENSE BLOCK ***** -->
39
40 <!DOCTYPE bindings [
41   <!ENTITY % sidebarDTD SYSTEM "chrome://bluegriffon/locale/sidebar.dtd" >
42   %sidebarDTD;
43 ]>
44
45 <bindings id="sidebarBindings"
46           xmlns="http://www.mozilla.org/xbl"
47           xmlns:html="http://www.w3.org/1999/xhtml"
48           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
49           xmlns:xbl="http://www.mozilla.org/xbl">
50
51   <binding id="sidebaritems">
52
53     <resources>
54       <stylesheet src="chrome://bluegriffon/skin/sidebar.css"/>
55     </resources>
56
57     <implementation>
58       <method name="init">
59         <body>
60         <![CDATA[
61           // let's find all sidebaritems living in their own window
62           var items = this.getElementsByAttribute("standalone", "true");
63           for (var i = 0; i < items.length; i++)
64           {
65             var item = items[i];
66             // retrieve all the data it carries
67             var name       = item.getAttribute("name");
68             var properties = item.getAttribute("properties");
69             var src        = item.getAttribute("src");
70             // let's see if we have a localized string for that
71             // item name
72             var label      = item.getAttribute("title");
73
74             // show it
75             window.openDialog("chrome://bluegriffon/content/dialogs/standaloneSidebar.xul","_blank",
76                               "all,dialog=no", name,
77                               label ? label : name, src, item);
78           }
79         ]]>
80         </body>
81       </method>
82
83       <property name="mItems"
84                 readonly="true"
85                 onget="return this.getElementsByTagName('sidebaritem');" />
86
87       <method name="_getItemsFromName">
88         <parameter name="aName"/>
89         <body>
90         <![CDATA[
91           return this.getElementsByAttribute("name", aName);
92         ]]>
93         </body>
94       </method>
95
96     </implementation>
97
98   </binding>
99
100   <binding id="sidebar">
101
102     <resources>
103       <stylesheet src="chrome://bluegriffon/skin/sidebar.css"/>
104     </resources>
105
106     <content>
107       <xul:hbox align="center" class="titlebox"
108                 ondragover="this.parentNode.onDragOver(event, this)"
109                 ondragleave="this.parentNode.onDragLeave(this)"
110                 ondrop="this.parentNode.onDrop(event)">
111         <xul:toolbarbutton label="&addSidebarContent.label;" class="sidebar-morebutton" type="menu"
112                            tooltiptext="&addSidebarContent.tooltip;">
113           <xul:menupopup onpopupshowing="this.parentNode.parentNode.parentNode._updateMissingSidebarItems(this)"/>
114         </xul:toolbarbutton>
115         <xul:spacer flex="1"/>
116         <xul:toolbarbutton class="sidebar-closebutton"
117                            tooltiptext="&closeSidebar.tooltip;"
118                            oncommand="this.parentNode.parentNode._close()"/>
119       </xul:hbox>
120       <xul:vbox flex="1" anonid="content">
121         <children/>
122       </xul:vbox>
123     </content>
124
125     <implementation>
126
127       <field name="mXUL_NS">"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"</field>
128
129       <field name="mSidebarItems">null</field>
130       <field name="mOtherSidebar">null</field>
131       <field name="mSplitter">null</field>
132
133       <property name="mContents"
134                 readonly="true"
135                 onget="return this.getElementsByTagName('sidebarcontent');" />
136       <property name="mSplitters"
137                 readonly="true"
138                 onget="return this.getElementsByTagName('splitter');" />
139
140       <method name="init">
141         <parameter name="aSidebarItems"/>
142         <parameter name="aOtherSidebar"/>
143         <parameter name="aSplitter"/>
144         <body>
145         <![CDATA[
146
147           if (!aSidebarItems)
148             return;
149
150           this.mSidebarItems = aSidebarItems;
151           this.mOtherSidebar = aOtherSidebar;
152           this.mSplitter     = aSplitter;
153
154           // get the list of sidebaritems shown in this sidebar
155           var itemsAttr  = this.getAttribute("sidebaritems");
156           var itemsArray = itemsAttr.split(",");
157           var ordinalIndex = 1;
158           for (var i = 0; i < itemsArray.length; i++)
159           {
160             // sanity case
161             if (itemsArray[i])
162             {
163               // now, find the corresponding sidebaritem
164               var item = aSidebarItems._getItemsFromName(itemsArray[i]).item(0);
165               if (item)
166               {
167                 // retrieve all the data it carries
168                 var properties = item.getAttribute("properties");
169                 var src        = item.getAttribute("src");
170                 // the height on the sidebaritem is persistent, and is updated
171                 // each time a splitter between sidebarcontent elements is moved
172                 var height     = item.getAttribute("height");
173
174                 // let's see if we have a localized string for that
175                 // item name
176                 var label      = item.getAttribute("title");
177
178                 // create a sidebarcontent
179                 var sidebarcontent = document.createElementNS(this.mXUL_NS, "sidebarcontent");
180                 // set the name and the height
181                 sidebarcontent.setAttribute("name",  itemsArray[i]);
182                 sidebarcontent.setAttribute("height",  height);
183                 // append it to the sidebar
184                 this.appendChild(sidebarcontent);
185                 // and init it
186                 sidebarcontent._setLabel(label ? label : itemsArray[i]);
187                 // now create the iframe
188                 var iframe = document.createElementNS(this.mXUL_NS, "iframe");
189                 iframe.setAttribute("flex", "1");
190                 iframe.setAttribute("src", src);
191                 sidebarcontent.appendChild(iframe);
192                 
193                 sidebarcontent.setAttribute("ordinal", ordinalIndex++);
194
195                 // and this is not the last sidebaritem for this sidebar,
196                 // let's add a splitter
197                 if (i < itemsArray.length - 1)
198                 {
199                   var splitter = document.createElementNS(this.mXUL_NS, "splitter");
200                   // we need to know when the splitter is moved.
201                   splitter.setAttribute("oncommand",
202                                         "this.parentNode._setPersistentHeights()");
203                   // append the splitter to the sidebar
204                   splitter.setAttribute("ordinal", ordinalIndex++);
205                   this.appendChild(splitter);
206                 }
207               }
208             }
209           }
210
211         ]]>
212         </body>
213       </method>
214
215       <method name="_setPersistentHeights">
216         <body>
217         <![CDATA[
218
219           // early way out if no sidebaritems
220           if (!this.mSidebarItems)
221             return;
222
223           // browse all sidebarcontent elements in this sidebar
224           var contents = this.mContents;
225           for (var i = 0; i < contents.length; i++)
226           {
227             var child = contents[i];
228             // find their unique identifier
229             var name = child.getAttribute("name");
230             if (name.length)
231             {
232               // find the corresponding sidebaritem
233               var items = this.mSidebarItems._getItemsFromName(name);
234               if (items && items.length)
235               {
236                 var item = items[0];
237                 // get the sidebarcontent's height and store it in the
238                 // sidebaritem
239                 item.setAttribute("height", child.getAttribute("height"));
240                 // make it persist so we get it back next session
241                 document.persist(item.getAttribute("id"), "height");
242               }
243             }
244           }
245
246         ]]>
247         </body>
248       </method>
249
250       <method name="_updatePersistentItemsList">
251         <body>
252         <![CDATA[
253
254           function compare(a, b) {
255             return a.ordinal - b.ordinal;
256           }
257
258           // early way out if no sidebaritems
259           if (!this.mSidebarItems)
260             return;
261
262           // find all sidebarcontents in the current sidebar
263           var contents = this.mContents;
264           if (!contents || !contents.length)
265           {
266             // none, zilch, nada... Make that persist and leave
267             this.setAttribute("sidebaritems", "");
268             document.persist(this, "sidebaritems");
269             return;
270           }
271
272           // make an array storing all sidebarcontents
273           var itemsArray = [];
274           for (var i = 0; i < contents.length; i++)
275             itemsArray.push( contents[i] );
276
277           // sort it by ordinal
278           itemsArray.sort(compare);
279
280           // now rebuild the sidebaritems attribute on the sidebar
281           var newList = "";
282           for (var i = 0; i < itemsArray.length; i++)
283           {
284             var item = itemsArray[i];
285             item.setAttribute("ordinal", i * 2 + 1);
286             if (i)
287               newList += ",";
288             newList += item.getAttribute("name");
289           }
290
291           // store and persist
292           this.setAttribute("sidebaritems", newList);
293           document.persist(this, "sidebaritems");
294
295           // don't forget to update splitters' ordinal !
296           var splitters = this.mSplitters;
297           for (var i = 0; i < splitters.length; i++)
298           {
299             splitters[i].setAttribute("ordinal", i * 2 + 2);
300           }
301
302         ]]>
303         </body>
304       </method>
305
306       <method name="_addToOtherSidebar">
307         <parameter name="aName"/>
308         <parameter name="aTitle"/>
309         <parameter name="aURL"/>
310         <body>
311         <![CDATA[
312           this.mOtherSidebar.addContent(aName, aTitle, aURL);
313         ]]>
314         </body>
315       </method>
316
317       <method name="addContent">
318         <parameter name="aName"/>
319         <parameter name="aTitle"/>
320         <parameter name="aURL"/>
321         <body>
322         <![CDATA[
323           // what should be the default original for this new content ?
324           var ordinalIndex = this.childNodes.length;
325           if (ordinalIndex)
326           {
327             var splitter = document.createElementNS(this.mXUL_NS, "splitter");
328             // we need to know when the splitter is moved.
329             splitter.setAttribute("oncommand",
330                                   "this.parentNode._setPersistentHeights()");
331             // append the splitter to the sidebar
332             splitter.setAttribute("ordinal", ++ordinalIndex);
333             this.appendChild(splitter);
334           }
335
336           // create a sidebarcontent
337           var sidebarcontent = document.createElementNS(this.mXUL_NS, "sidebarcontent");
338           // set the name and the height
339           sidebarcontent.setAttribute("name",  aName);
340           // append it to the sidebar
341           this.appendChild(sidebarcontent);
342           // and init it
343           sidebarcontent._setLabel(aTitle);
344           // now create the iframe
345           var iframe = document.createElementNS(this.mXUL_NS, "iframe");
346           iframe.setAttribute("flex", "1");
347           iframe.setAttribute("src", aURL);
348           sidebarcontent.appendChild(iframe);
349           
350           sidebarcontent.setAttribute("ordinal", ordinalIndex++);
351
352           this._updatePersistentItemsList();
353         ]]>
354         </body>
355       </method>
356
357       <method name="_addSidebarItem">
358         <parameter name="aMenuitem"/>
359         <body>
360         <![CDATA[
361           this.addContent( aMenuitem.getAttribute("name"),
362                             aMenuitem.getAttribute("label"),
363                             aMenuitem.getAttribute("src") );
364         ]]>
365         </body>
366       </method>
367
368       <method name="_updateMissingSidebarItems">
369         <parameter name="aPopup"/>
370         <body>
371         <![CDATA[
372           // early way out if no sidebaritems
373           if (!this.mSidebarItems)
374             return;
375
376           // find all sidebaritems
377           var items = this.mSidebarItems.mItems;
378           var missingItems = {};
379           for (var i = 0; i < items.length; i++)
380           {
381             var item = items[i];
382             var name  = item.getAttribute("name");
383             var title = item.getAttribute("title");
384             var src   = item.getAttribute("src");
385
386             // don't offer to them to a sidebar if they are
387             // already shown in standalone windows
388             if (item.getAttribute("standalone") != "true")
389               missingItems[name] = [ title, src ]
390           }
391
392           // remove from list the ones already in the current sidebar
393           var contents = this.mContents;
394           for (var i = 0; i < contents.length; i++)
395           {
396             var content = contents[i];
397             name = content.getAttribute("name");
398             delete missingItems[name];
399           }
400           // and remove from list the ones already in the other sidebar
401           // if there is one
402           if (this.mOtherSidebar)
403           {
404             contents = this.mOtherSidebar.mContents;
405             for (var i = 0; i < contents.length; i++)
406             {
407               content = contents[i];
408               name = content.getAttribute("name");
409               delete missingItems[name];
410             }
411           }
412
413           // popup cleanup
414           while (aPopup.hasChildNodes())
415             aPopup.removeChild(aPopup.lastChild);
416
417           var empty = true;
418           for (i in missingItems)
419           {
420             empty = false;
421             var menuitem = document.createElementNS(this.mXUL_NS, "menuitem");
422             var label    = missingItems[i][0];
423             menuitem.setAttribute("label", label ? label : i);
424             menuitem.setAttribute("tooltiptext", label ? label : i);
425             menuitem.setAttribute("name",  i);
426             menuitem.setAttribute("src",   missingItems[i][1]);
427             menuitem.setAttribute("oncommand", "this.parentNode.parentNode.parentNode.parentNode._addSidebarItem(this)");
428             aPopup.appendChild(menuitem);
429           }
430           if (empty)
431           {
432             var menuitem = document.createElementNS(this.mXUL_NS, "menuitem");
433             menuitem.setAttribute("label", " -- ");
434             menuitem.setAttribute("disabled", "true");
435             aPopup.appendChild(menuitem);
436           }
437         ]]>
438         </body>
439       </method>
440
441       <method name="_close">
442         <body>
443         <![CDATA[
444           if (this.mSplitter)
445           {
446             this.mSplitter.setAttribute("state", "collapsed");
447             document.persist(this.mSplitter.getAttribute("id"), "state");
448           }
449           else
450             this.setAttribute("collapsed", "true");
451         ]]>
452         </body>
453       </method>
454
455       <method name="onDragOver">
456         <parameter name="aEvent"/>
457         <parameter name="aDropTarget"/>
458         <body>
459         <![CDATA[
460           var sidebar = aDropTarget.parentNode;
461
462           var dt = aEvent.dataTransfer;
463           var hasNode = dt.types.contains("application/x-moz-node");
464           if (hasNode)
465           {
466             var node = dt.mozGetDataAt("application/x-moz-node", 0);
467             if (node.nodeName.toLowerCase() != "sidebarcontent")
468               return;
469
470
471             if (node.parentNode != sidebar)
472             {
473               aDropTarget.setAttribute("style", "background-color: orange");
474               aEvent.preventDefault();
475             }
476           }
477           
478         ]]>
479         </body>
480       </method>
481
482       <method name="onDragLeave">
483         <parameter name="aDropTarget"/>
484         <body>
485         <![CDATA[
486           aDropTarget.removeAttribute("style");
487         ]]>
488         </body>
489       </method>
490
491        <method name="onDrop">
492         <parameter name="aEvent"/>
493         <body>
494         <![CDATA[
495
496           var dt = aEvent.dataTransfer;
497           var e = aEvent.target;
498           while (e && (e.localName.toLowerCase() != "hbox" ||
499                        e.className != "titlebox"))
500             e = e.parentNode;
501           if (!e)
502             return; 
503           var dragSource = dt.mozGetDataAt("application/x-moz-node", 0);
504
505           dragSource._moveToOtherSidebar();
506         ]]>
507         </body>
508       </method>
509     </implementation>
510
511   </binding>
512
513   <binding id="sidebarcontent">
514
515     <resources>
516       <stylesheet src="chrome://bluegriffon/skin/sidebarcontent.css"/>
517     </resources>
518
519     <content>
520       <xul:hbox align="center" class="titlebox" anonid="titlebox"
521                 ondragover="this.parentNode.onDragOver(event, this)"
522                 ondragleave="this.parentNode.onDragLeave(this)"
523                 ondrop="this.parentNode.onDrop(event)">
524         <xul:label ondragstart="this.parentNode.parentNode.onDragStart(event, this.parentNode.parentNode)"
525                    ondragend="this.parentNode.parentNode.onDragEnd(event, this.parentNode.parentNode)"
526                    anonid="name" class="sidebarcontent-name"/>
527         <xul:spacer flex="1"/>
528         <xul:toolbarbutton label="&actions.label;" class="sidebar-arrowbutton" type="menu">
529           <xul:menupopup onpopupshowing="this.parentNode.parentNode.parentNode._updateActionsPopup(this)">
530             <xul:menuitem anonid="detachmenu"
531                           label="&detachMenu.label;"
532                           accesskey="&detachMenu.accesskey;"
533                           oncommand="this.parentNode.parentNode.parentNode.parentNode._detach()" />
534             <xul:menuseparator/>
535             <xul:menuitem anonid="closemenu"
536                           label="&closeMenu.label;"
537                           accesskey="&closeMenu.accesskey;"
538                           oncommand="this.parentNode.parentNode.parentNode.parentNode._close()"/>
539           </xul:menupopup>
540         </xul:toolbarbutton>
541       </xul:hbox>
542       <children/>
543     </content>
544
545     <implementation>
546       <property name="mTitleBox">
547         <getter>
548         <![CDATA[
549           return document.getAnonymousElementByAttribute(this, "anonid", "titlebox");
550         ]]>
551         </getter>
552       </property>
553
554       <property name="mLabel">
555         <getter>
556         <![CDATA[
557           return this.mTitleBox.firstChild;
558         ]]>
559         </getter>
560       </property>
561
562       <property name="mTitle">
563         <getter>
564         <![CDATA[
565           return this.mLabel.value;
566         ]]>
567         </getter>
568       </property>
569
570       <property name="mContent">
571         <getter>
572         <![CDATA[
573           return this.getElementsByTagName("iframe").item(0);
574         ]]>
575         </getter>
576       </property>
577
578       <method name="_updateActionsPopup">
579         <parameter name="aPopup"/>
580         <body>
581         <![CDATA[
582           var isFirst = (this.getAttribute("ordinal") == "1");
583           var isLast  = (this.getAttribute("ordinal") == this.parentNode.childNodes.length);
584           var moveupmenu   = aPopup.getElementsByAttribute("anonid", "moveupmenu")[0];
585           var movedownmenu = aPopup.getElementsByAttribute("anonid", "movedownmenu")[0];
586           moveupmenu.setAttribute("disabled", isFirst);
587           movedownmenu.setAttribute("disabled", isLast);
588           var moveothermenu = aPopup.getElementsByAttribute("anonid", "moveothermenu")[0];
589           if (this.parentNode.mOtherSidebar)
590             moveothermenu.removeAttribute("disabled");
591           else
592             moveothermenu.setAttribute("disabled", "true");
593         ]]>
594         </body>
595       </method>
596
597       <method name="_setLabel">
598         <parameter name="aLabel"/>
599         <body>
600         <![CDATA[
601           this.mLabel.value = aLabel;
602         ]]>
603         </body>
604       </method>
605
606       <method name="_close">
607         <body>
608         <![CDATA[
609           var currentOrdinal  = parseInt(this.getAttribute("ordinal"));
610           var sidebar = this.parentNode;
611           if (currentOrdinal == 1)
612           {
613             // we have a splitter after the current item and we have
614             // to remove it
615             var splitterOrdinal = currentOrdinal + 1;
616             var splitters = this.parentNode.getElementsByAttribute("ordinal", splitterOrdinal);
617             if (splitters && splitters.length)
618               sidebar.removeChild(splitters[0]);
619           }
620           else
621           {
622             // we have a splitter before the current item and we have
623             // to remove it
624             var splitterOrdinal = currentOrdinal - 1;
625             var splitters = this.parentNode.getElementsByAttribute("ordinal", splitterOrdinal);
626             if (splitters && splitters.length)
627               sidebar.removeChild(splitters[0]);
628           }
629           sidebar.removeChild(this);
630
631           sidebar._updatePersistentItemsList();
632         ]]>
633         </body>
634       </method>
635
636       <method name="_move">
637         <parameter name="aOffset"/>
638         <body>
639         <![CDATA[
640           // we always have a splitter before the current element
641           // as we always have another sidebarcontent before the splitter
642           var currentOrdinal  = this.getAttribute("ordinal");
643           var otherOrdinal = parseInt(currentOrdinal) + aOffset;
644           var otherContent = this.parentNode.getElementsByAttribute("ordinal", otherOrdinal).item(0);
645           otherContent.setAttribute("ordinal", currentOrdinal);
646           this.setAttribute("ordinal", otherOrdinal);
647
648           this.parentNode._updatePersistentItemsList();
649         ]]>
650         </body>
651       </method>
652
653       <method name="_moveToOtherSidebar">
654         <body>
655         <![CDATA[
656           var sidebar = this.parentNode;
657           var title = this.mTitle;
658           var src   = this.mContent.getAttribute("src");
659           var name  = this.getAttribute("name");
660
661           // we cannot really move a sidebarcontent from one
662           // sidebar to the other because the iframe's context is
663           // lost anyway
664           //sidebar._addToOtherSidebar(name, title, src);
665
666           // close this one
667           //this._close();
668
669           var ordinalIndex = sidebar.mOtherSidebar.childNodes.length;
670
671           if (ordinalIndex)
672           {
673             var splitter = document.createElementNS(sidebar.mXUL_NS, "splitter");
674             // we need to know when the splitter is moved.
675             splitter.setAttribute("oncommand",
676                                   "this.parentNode._setPersistentHeights()");
677             // append the splitter to the sidebar
678             splitter.setAttribute("ordinal", ++ordinalIndex);
679             sidebar.mOtherSidebar.appendChild(splitter);
680           }
681           this.setAttribute("ordinal", ++ordinalIndex);
682
683           if (this.previousSibling &&
684               this.previousSibling.nodeName.toLowerCase() == "splitter")
685             sidebar.removeChild(this.previousSibling);
686
687           sidebar.mOtherSidebar.appendChild(this);
688           this.setAttribute("name", name);
689           this.mLabel.value = title;
690
691           sidebar._updatePersistentItemsList()
692           sidebar.mOtherSidebar._updatePersistentItemsList();
693         ]]>
694         </body>
695       </method>
696
697       <method name="_detach">
698         <body>
699         <![CDATA[
700           var label = this.mTitle;
701           var name  = this.getAttribute("name");
702           // find the corresponding sidebaritem
703           var sidebar = this.parentNode;
704           var items = sidebar.mSidebarItems._getItemsFromName(name);
705           if (items && items.length)
706           {
707             var item = items[0];
708             // remember that we want this sidebaritem to be floating alone
709             item.setAttribute("standalone", "true");
710             document.persist(item.getAttribute("id"), "standalone");
711
712             var src  = item.getAttribute("src");
713             // make it float, make it float
714             window.openDialog("chrome://bluegriffon/content/dialogs/standaloneSidebar.xul","_blank",
715                               "chrome,modal=no,titlebar,scrollbars=yes,resizable", name, label, src, item);
716
717             // close this one
718             this._close();
719           }
720         ]]>
721         </body>
722       </method>
723
724       <method name="onDragOver">
725         <parameter name="aEvent"/>
726         <parameter name="aDropTarget"/>
727         <body>
728         <![CDATA[
729           var sidebarContent = aDropTarget.parentNode;
730           var dt = aEvent.dataTransfer;
731           var hasNode = dt.types.contains("application/x-moz-node");
732           if (hasNode)
733           {
734             var node = dt.mozGetDataAt("application/x-moz-node", 0);
735             if (node.nodeName.toLowerCase() != "sidebarcontent")
736               return;
737             if (node.getAttribute("name") != aDropTarget.parentNode.getAttribute("name"))
738             {
739               aDropTarget.setAttribute("style", "background-color: orange");
740               aEvent.preventDefault();
741             }
742           }
743         ]]>
744         </body>
745       </method>
746
747       <method name="onDragLeave">
748         <parameter name="aDropTarget"/>
749         <body>
750         <![CDATA[
751           aDropTarget.removeAttribute("style");
752         ]]>
753         </body>
754       </method>
755
756       <method name="onDragStart">
757         <parameter name="aEvent"/>
758         <parameter name="aDragSource"/>
759         <body>
760         <![CDATA[
761
762           var dt = aEvent.dataTransfer;
763           dt.setData("text/plain", aDragSource.mTitle);
764           dt.mozSetDataAt("application/x-moz-node", aDragSource, 0);
765           dt.effectAllowed = "all";
766         ]]>
767         </body>
768       </method>
769
770       <method name="onDragEnd">
771         <parameter name="aEvent"/>
772         <parameter name="aDragSource"/>
773         <body>
774         <![CDATA[
775
776           var dt = aEvent.dataTransfer;
777         ]]>
778         </body>
779       </method>
780
781        <method name="onDrop">
782         <parameter name="aEvent"/>
783         <body>
784         <![CDATA[
785
786           var dt = aEvent.dataTransfer;
787           var e = aEvent.target;
788           while (e && e.nodeName.toLowerCase() != "sidebarcontent")
789             e = e.parentNode;
790           if (!e)
791             return; 
792           var dragSource = dt.mozGetDataAt("application/x-moz-node", 0);
793
794           var sameSidebar = (e.parentNode == dragSource.parentNode);
795           if (!sameSidebar)
796             dragSource._moveToOtherSidebar();
797
798           var offset = ( parseInt(dragSource.getAttribute("ordinal")) <
799                          parseInt(e.getAttribute("ordinal")) ) ?
800                          2 : -2;
801
802           while (parseInt(e.getAttribute("ordinal")) -
803                  parseInt(dragSource.getAttribute("ordinal")) +
804                  offset != 0)
805             dragSource._move(offset);
806
807         ]]>
808         </body>
809       </method>
810
811     </implementation>
812
813   </binding>
814
815 </bindings>