2007-03-22 10:30:00 -07:00
|
|
|
<?xml version="1.0"?>
|
|
|
|
|
|
|
|
# ***** BEGIN LICENSE BLOCK *****
|
|
|
|
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
|
|
#
|
|
|
|
# The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
# 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
# the License. You may obtain a copy of the License at
|
|
|
|
# http://www.mozilla.org/MPL/
|
|
|
|
#
|
|
|
|
# Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
# for the specific language governing rights and limitations under the
|
|
|
|
# License.
|
|
|
|
#
|
|
|
|
# The Original Code is the Places Toolbar View.
|
|
|
|
#
|
|
|
|
# The Initial Developer of the Original Code is Google Inc.
|
|
|
|
# Portions created by the Initial Developer are Copyright (C) 2005-2006
|
|
|
|
# the Initial Developer. All Rights Reserved.
|
|
|
|
#
|
|
|
|
# Contributor(s):
|
|
|
|
# Annie Sullivan <annie.sullivan@gmail.com>
|
|
|
|
# Ben Goodger <beng@google.com>
|
|
|
|
# Myk Melez <myk@mozilla.org>
|
2008-09-19 08:47:45 -07:00
|
|
|
# Marco Bonardo <mak77@bonardo.net>
|
2009-10-01 09:53:26 -07:00
|
|
|
# Asaf Romano <mano@mozilla.com>
|
2007-03-22 10:30:00 -07:00
|
|
|
#
|
|
|
|
# Alternatively, the contents of this file may be used under the terms of
|
|
|
|
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
|
|
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
|
|
# in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
# of those above. If you wish to allow use of your version of this file only
|
|
|
|
# under the terms of either the GPL or the LGPL, and not to allow others to
|
|
|
|
# use your version of this file under the terms of the MPL, indicate your
|
|
|
|
# decision by deleting the provisions above and replace them with the notice
|
|
|
|
# and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
# the provisions above, a recipient may use your version of this file under
|
|
|
|
# the terms of any one of the MPL, the GPL or the LGPL.
|
|
|
|
#
|
2009-10-01 09:53:26 -07:00
|
|
|
# ***** END LICENSE BLOCK *****
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
|
|
|
|
<!DOCTYPE bindings [
|
|
|
|
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
|
|
|
|
%browserDTD;
|
|
|
|
]>
|
|
|
|
|
|
|
|
<bindings id="placesToolbarBindings"
|
|
|
|
xmlns="http://www.mozilla.org/xbl"
|
|
|
|
xmlns:xbl="http://www.mozilla.org/xbl"
|
|
|
|
xmlns:html="http://www.w3.org/1999/xhtml"
|
|
|
|
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
|
|
|
|
|
|
|
<binding id="places-bar">
|
|
|
|
<resources>
|
|
|
|
<stylesheet src="chrome://browser/skin/places/places.css"/>
|
|
|
|
</resources>
|
2007-10-24 19:02:28 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<content>
|
2009-08-14 01:03:34 -07:00
|
|
|
<xul:toolbarbutton class="bookmark-item bookmarks-toolbar-customize"
|
|
|
|
mousethrough="never"
|
|
|
|
label="&bookmarksToolbarItem.label;"/>
|
2007-03-22 10:30:00 -07:00
|
|
|
<xul:hbox flex="1">
|
2009-08-14 01:03:34 -07:00
|
|
|
<xul:hbox align="center">
|
|
|
|
<xul:image class="toolbar-drop-indicator"
|
|
|
|
mousethrough="always"
|
|
|
|
collapsed="true"/>
|
2007-03-22 10:30:00 -07:00
|
|
|
</xul:hbox>
|
2009-08-14 01:03:34 -07:00
|
|
|
<xul:scrollbox orient="horizontal"
|
|
|
|
class="bookmarks-toolbar-items"
|
|
|
|
flex="1">
|
|
|
|
<children/>
|
|
|
|
</xul:scrollbox>
|
2009-08-18 01:23:34 -07:00
|
|
|
<xul:toolbarbutton type="menu"
|
|
|
|
class="chevron"
|
|
|
|
mousethrough="never"
|
|
|
|
collapsed="true"
|
|
|
|
tooltiptext="&bookmarksToolbarChevron.tooltip;"
|
|
|
|
onpopupshowing="_onChevronPopupShowing(event);">
|
|
|
|
<xul:menupopup anonid="chevronPopup"
|
2009-09-14 04:06:33 -07:00
|
|
|
popupsinherittooltip="true"
|
2009-08-18 01:23:34 -07:00
|
|
|
xbl:inherits="tooltip"
|
2007-07-11 12:59:14 -07:00
|
|
|
#ifndef XP_MACOSX
|
2009-08-18 01:23:34 -07:00
|
|
|
context="placesContext"
|
2007-07-11 12:59:14 -07:00
|
|
|
#endif
|
2009-08-18 01:23:34 -07:00
|
|
|
/>
|
|
|
|
</xul:toolbarbutton>
|
2009-08-14 01:03:34 -07:00
|
|
|
</xul:hbox>
|
2007-03-22 10:30:00 -07:00
|
|
|
</content>
|
2007-10-24 19:02:28 -07:00
|
|
|
|
2009-08-14 01:03:34 -07:00
|
|
|
<implementation implements="nsIAccessibleProvider, nsITimerCallback, nsIDOMEventListener">
|
2007-03-22 10:30:00 -07:00
|
|
|
<constructor><![CDATA[
|
2007-10-24 19:02:28 -07:00
|
|
|
this._init();
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></constructor>
|
2007-10-24 19:02:28 -07:00
|
|
|
|
|
|
|
<destructor><![CDATA[
|
2009-08-14 01:03:34 -07:00
|
|
|
this._scrollbox.removeEventListener("overflow", this, false);
|
|
|
|
this._scrollbox.removeEventListener("underflow", this, false);
|
|
|
|
window.removeEventListener("resize", this, false);
|
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
if (this._result) {
|
2010-03-12 03:14:47 -08:00
|
|
|
this._result.removeObserver(this._resultObserver);
|
2009-10-01 09:53:26 -07:00
|
|
|
this._resultNode.containerOpen = false;
|
|
|
|
this._resultNode = null;
|
2007-10-24 19:02:28 -07:00
|
|
|
this._result = null;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></destructor>
|
|
|
|
|
|
|
|
<property name="controller"
|
|
|
|
readonly="true"
|
|
|
|
onget="return this._controller;"/>
|
|
|
|
|
|
|
|
<method name="_init">
|
|
|
|
<body><![CDATA[
|
2009-10-01 09:53:26 -07:00
|
|
|
// XBL bug is in the middle...
|
|
|
|
// When toolbar customization is opened, this binding is attached
|
|
|
|
// again, as a result of adding the item under the wrapper. However,
|
|
|
|
// the binding isn't detached from the "original" hbox element due
|
|
|
|
// to bug 83635.
|
|
|
|
//
|
|
|
|
// Then, when the customization dialog is closed, the binding is
|
|
|
|
// attached the third time, as a result of adding our element back to
|
|
|
|
// the toolbar.
|
|
|
|
//
|
|
|
|
// So, We'll just continue using the original binding, which was
|
|
|
|
// never removed, and avoid using the new bindings. This means that
|
|
|
|
// this workaround will work just until bug 83635 is fixed.
|
|
|
|
//
|
|
|
|
// However, when the binding is "reconstructed", we do need to add
|
|
|
|
// back the event listeners and the places controller.
|
|
|
|
//
|
|
|
|
// Note: we could avoid part of this mess by moving the "Bookmark
|
|
|
|
// Toolbar Items" placeholder out of this binding.
|
|
|
|
|
|
|
|
// We also need to avoid initializing _result and _resultNode and
|
|
|
|
// _controller as XBL fields. Otherwise, they'll be unset when the
|
|
|
|
// "extra" bindings are applied.
|
|
|
|
|
|
|
|
this._scrollbox.addEventListener("overflow", this, false);
|
|
|
|
this._scrollbox.addEventListener("underflow", this, false);
|
|
|
|
window.addEventListener("resize", this, false);
|
|
|
|
|
|
|
|
if (this._result === undefined) {
|
|
|
|
this._result = null;
|
|
|
|
this._resultNode = null;
|
|
|
|
if (this.hasAttribute("place")) {
|
|
|
|
// Do the initial build.
|
|
|
|
this.place = this.place;
|
|
|
|
}
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
// Attach the places controller.
|
|
|
|
if (!this._controller)
|
|
|
|
this._controller = new PlacesController(this);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
this.controllers.appendController(this._controller);
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
2009-08-14 01:03:34 -07:00
|
|
|
<field name="_scrollbox">
|
|
|
|
document.getAnonymousElementByAttribute(this, "class",
|
|
|
|
"bookmarks-toolbar-items")
|
|
|
|
</field>
|
|
|
|
<field name="_dropIndicator">
|
|
|
|
document.getAnonymousElementByAttribute(this, "class",
|
|
|
|
"toolbar-drop-indicator")
|
|
|
|
</field>
|
|
|
|
<field name="_chevron">
|
|
|
|
document.getAnonymousElementByAttribute(this, "class", "chevron")
|
|
|
|
</field>
|
2009-08-18 01:23:34 -07:00
|
|
|
<field name="_chevronPopup">
|
|
|
|
document.getAnonymousElementByAttribute(this, "anonid", "chevronPopup")
|
|
|
|
</field>
|
2007-10-24 19:02:28 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<field name="_openedMenuButton">null</field>
|
2009-06-24 15:15:25 -07:00
|
|
|
<field name="_allowPopupShowing">true</field>
|
2007-10-10 23:42:38 -07:00
|
|
|
|
2009-08-14 01:03:34 -07:00
|
|
|
<field name="_isRTL">
|
|
|
|
document.defaultView.getComputedStyle(this.parentNode, "")
|
|
|
|
.direction == "rtl"
|
|
|
|
</field>
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<!-- nsIPlacesView -->
|
|
|
|
<method name="getResult">
|
|
|
|
<body><![CDATA[
|
|
|
|
return this._result;
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<!-- nsIPlacesView -->
|
|
|
|
<method name="getResultNode">
|
|
|
|
<body><![CDATA[
|
2009-10-01 09:53:26 -07:00
|
|
|
return this._resultNode;
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="_rebuild">
|
|
|
|
<body><![CDATA[
|
2009-08-14 01:03:34 -07:00
|
|
|
// Clear out references to existing nodes, since they will be removed
|
|
|
|
// and re-added.
|
2008-10-14 05:35:03 -07:00
|
|
|
if (this._overFolder.node)
|
|
|
|
this._clearOverFolder();
|
2007-03-22 10:30:00 -07:00
|
|
|
this._openedMenuButton = null;
|
2007-05-03 05:26:27 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
while (this.hasChildNodes())
|
|
|
|
this.removeChild(this.firstChild);
|
2007-10-24 19:02:28 -07:00
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
let cc = this._resultNode.childCount;
|
2009-08-14 01:03:34 -07:00
|
|
|
for (let i = 0; i < cc; ++i)
|
2009-10-01 09:53:26 -07:00
|
|
|
this.insertNewItem(this._resultNode.getChild(i), null);
|
2007-05-03 05:26:27 -07:00
|
|
|
|
2009-08-14 01:03:34 -07:00
|
|
|
if (this._chevronPopup.hasAttribute("type")) {
|
|
|
|
// Chevron has already been initialized, but since we are forcing
|
|
|
|
// a rebuild of the toolbar, it has to be rebuilt.
|
|
|
|
// Otherwise, it will be initialized when the toolbar overflows.
|
|
|
|
this._chevronPopup.place = this.place;
|
2007-10-24 19:02:28 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
2007-05-03 05:26:27 -07:00
|
|
|
|
|
|
|
<method name="insertNewItem">
|
2007-10-24 19:02:28 -07:00
|
|
|
<parameter name="aChild"/>
|
|
|
|
<parameter name="aBefore"/>
|
2007-05-03 05:26:27 -07:00
|
|
|
<body><![CDATA[
|
2007-10-24 19:02:28 -07:00
|
|
|
var type = aChild.type;
|
|
|
|
var button;
|
|
|
|
if (type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR)
|
|
|
|
button = document.createElement("toolbarseparator");
|
|
|
|
else {
|
|
|
|
button = document.createElement("toolbarbutton");
|
|
|
|
button.className = "bookmark-item";
|
|
|
|
button.setAttribute("label", aChild.title);
|
2009-10-01 09:53:26 -07:00
|
|
|
var icon = aChild.icon;
|
|
|
|
if (icon)
|
|
|
|
button.setAttribute("image", icon);
|
2007-10-24 19:02:28 -07:00
|
|
|
|
|
|
|
if (PlacesUtils.containerTypes.indexOf(type) != -1) {
|
|
|
|
button.setAttribute("type", "menu");
|
|
|
|
button.setAttribute("container", "true");
|
2008-04-15 10:09:00 -07:00
|
|
|
|
|
|
|
if (PlacesUtils.nodeIsQuery(aChild)) {
|
|
|
|
button.setAttribute("query", "true");
|
|
|
|
if (PlacesUtils.nodeIsTagQuery(aChild))
|
|
|
|
button.setAttribute("tagContainer", "true");
|
|
|
|
}
|
|
|
|
else if (PlacesUtils.nodeIsLivemarkContainer(aChild))
|
2007-10-24 19:02:28 -07:00
|
|
|
button.setAttribute("livemark", "true");
|
|
|
|
|
|
|
|
var popup = document.createElement("menupopup");
|
2008-02-20 18:17:52 -08:00
|
|
|
popup.setAttribute("placespopup", "true");
|
2007-10-24 19:02:28 -07:00
|
|
|
button.appendChild(popup);
|
|
|
|
popup._resultNode = asContainer(aChild);
|
2007-05-03 05:26:27 -07:00
|
|
|
#ifndef XP_MACOSX
|
2007-10-24 19:02:28 -07:00
|
|
|
popup.setAttribute("context", "placesContext");
|
2007-05-03 05:26:27 -07:00
|
|
|
#endif
|
2007-10-24 19:02:28 -07:00
|
|
|
}
|
2009-10-01 09:53:26 -07:00
|
|
|
else if (PlacesUtils.nodeIsURI(aChild))
|
2009-03-12 06:14:12 -07:00
|
|
|
button.setAttribute("scheme", PlacesUIUtils.guessUrlSchemeForUI(aChild.uri));
|
2007-05-03 05:26:27 -07:00
|
|
|
}
|
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
button.node = aChild;
|
2009-10-01 09:53:26 -07:00
|
|
|
aChild._DOMElement = button;
|
2007-10-24 19:02:28 -07:00
|
|
|
if (aBefore)
|
|
|
|
this.insertBefore(button, aBefore);
|
2007-05-03 05:26:27 -07:00
|
|
|
else
|
|
|
|
this.appendChild(button);
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="removeItem">
|
|
|
|
<parameter name="child"/>
|
|
|
|
<body><![CDATA[
|
2008-02-25 13:45:22 -08:00
|
|
|
// if document.popupNode pointed to this child, null it out,
|
|
|
|
// otherwise controller's command-updating may rely on the removed
|
|
|
|
// item still being "selected".
|
|
|
|
if (document.popupNode == child)
|
|
|
|
document.popupNode = null;
|
2009-10-01 09:53:26 -07:00
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
child.parentNode.removeChild(child);
|
2007-05-03 05:26:27 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
2009-08-14 01:03:34 -07:00
|
|
|
<method name="_updateChevronPopupNodesVisibility">
|
|
|
|
<body><![CDATA[
|
|
|
|
for (let i = 0; i < this._chevronPopup.childNodes.length; i++) {
|
|
|
|
this._chevronPopup.childNodes[i].hidden =
|
|
|
|
this.childNodes[i].style.visibility != "hidden";
|
|
|
|
}
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="_onChevronPopupShowing">
|
2007-10-24 19:02:28 -07:00
|
|
|
<parameter name="aEvent"/>
|
2007-03-22 10:30:00 -07:00
|
|
|
<body><![CDATA[
|
2009-08-14 01:03:34 -07:00
|
|
|
// Handle popupshowing only for the chevron popup, not for
|
|
|
|
// nested ones.
|
|
|
|
if (aEvent.target != this._chevronPopup)
|
2007-10-24 19:02:28 -07:00
|
|
|
return;
|
|
|
|
|
2009-08-14 01:03:34 -07:00
|
|
|
this._updateChevronPopupNodesVisibility();
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
2007-05-03 05:26:27 -07:00
|
|
|
|
2009-08-14 01:03:34 -07:00
|
|
|
<method name="handleEvent">
|
|
|
|
<parameter name="aEvent"/>
|
2007-03-22 10:30:00 -07:00
|
|
|
<body><![CDATA[
|
2009-08-14 01:03:34 -07:00
|
|
|
// Both overflow/underflow and resize events should not be handled
|
|
|
|
// for descendant nodes.
|
|
|
|
if (aEvent.target != aEvent.currentTarget)
|
|
|
|
return;
|
|
|
|
|
|
|
|
switch (aEvent.type) {
|
|
|
|
case "resize":
|
|
|
|
// This handler updates nodes visibility in both the toolbar
|
|
|
|
// and the chevron popup when a window resize does not change
|
|
|
|
// the overflow status of the toolbar.
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "overflow":
|
2009-09-11 06:25:18 -07:00
|
|
|
// Ignore purely vertical overflows.
|
|
|
|
if (aEvent.detail == 0)
|
|
|
|
return;
|
|
|
|
|
2009-08-14 01:03:34 -07:00
|
|
|
// Attach the popup binding to the chevron popup if it has not yet
|
|
|
|
// been initialized.
|
|
|
|
if (!this._chevronPopup.hasAttribute("type")) {
|
|
|
|
this._chevronPopup.setAttribute("place", this.place);
|
|
|
|
this._chevronPopup.setAttribute("type", "places");
|
|
|
|
}
|
|
|
|
this._chevron.collapsed = false;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "underflow":
|
2009-09-11 06:25:18 -07:00
|
|
|
// Ignore purely vertical underflows.
|
|
|
|
if (aEvent.detail == 0)
|
|
|
|
return;
|
|
|
|
|
2009-08-14 01:03:34 -07:00
|
|
|
this._chevron.collapsed = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.updateChevron();
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
2007-10-24 19:02:28 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<method name="updateChevron">
|
|
|
|
<body><![CDATA[
|
2009-08-14 01:03:34 -07:00
|
|
|
// If the chevron is collapsed there's nothing to update.
|
|
|
|
if (this._chevron.collapsed)
|
2007-03-22 10:30:00 -07:00
|
|
|
return;
|
|
|
|
|
2009-08-14 01:03:34 -07:00
|
|
|
// XXX (bug 508816) Scrollbox does not handle correctly RTL mode.
|
|
|
|
// This workarounds the issue scrolling the box to the right.
|
|
|
|
if (this._isRTL)
|
|
|
|
this._scrollbox.scrollLeft = this._scrollbox.scrollWidth;
|
2007-06-26 18:13:28 -07:00
|
|
|
|
2009-08-14 01:03:34 -07:00
|
|
|
// Update the chevron on a timer. This will avoid repeated work when
|
|
|
|
// lot of changes happen in a small timeframe.
|
|
|
|
if (this._updateChevronTimer)
|
|
|
|
this._updateChevronTimer.cancel();
|
|
|
|
this._updateChevronTimer = this._setTimer(100);
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="_updateChevronTimerCallback">
|
|
|
|
<body><![CDATA[
|
|
|
|
var scrollRect = this._scrollbox.getBoundingClientRect();
|
|
|
|
var childOverflowed = false;
|
|
|
|
for (let i = 0; i < this.childNodes.length; i++) {
|
|
|
|
let child = this.childNodes[i];
|
|
|
|
// Once a child overflows, all the next ones will.
|
|
|
|
if (!childOverflowed) {
|
|
|
|
let childRect = child.getBoundingClientRect();
|
|
|
|
childOverflowed = this._isRTL ? (childRect.left < scrollRect.left)
|
|
|
|
: (childRect.right > scrollRect.right);
|
2007-10-24 19:02:28 -07:00
|
|
|
}
|
2009-08-14 01:03:34 -07:00
|
|
|
child.style.visibility = childOverflowed ? "hidden" : "visible";
|
2007-10-24 19:02:28 -07:00
|
|
|
}
|
2008-09-19 08:47:45 -07:00
|
|
|
|
|
|
|
// We rebuild the chevron on popupShowing, so if it is open
|
2009-08-14 01:03:34 -07:00
|
|
|
// we must update it.
|
|
|
|
if (this._chevron.open)
|
|
|
|
this._updateChevronPopupNodesVisibility();
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
2007-10-24 19:02:28 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<!-- nsIPlacesView -->
|
|
|
|
<property name="place">
|
|
|
|
<getter><![CDATA[
|
|
|
|
return this.getAttribute("place");
|
|
|
|
]]></getter>
|
2009-10-01 09:53:26 -07:00
|
|
|
<setter><![CDATA[
|
2007-03-22 10:30:00 -07:00
|
|
|
this.setAttribute("place", val);
|
|
|
|
|
|
|
|
var history = PlacesUtils.history;
|
|
|
|
var queries = { }, options = { };
|
|
|
|
history.queryStringToQueries(val, queries, { }, options);
|
2009-10-01 09:53:26 -07:00
|
|
|
if (!queries.value.length)
|
2007-03-22 10:30:00 -07:00
|
|
|
queries.value = [history.getNewQuery()];
|
|
|
|
try {
|
2008-01-29 12:04:43 -08:00
|
|
|
var result =
|
2007-03-22 10:30:00 -07:00
|
|
|
history.executeQueries(queries.value, queries.value.length,
|
|
|
|
options.value);
|
2010-03-12 03:14:47 -08:00
|
|
|
result.addObserver(this._resultObserver, false);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
catch(ex) {
|
|
|
|
// Invalid query, or had no results.
|
2009-10-01 09:53:26 -07:00
|
|
|
// This is valid, eg: user deletes his bookmarks toolbar folder.
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
return val;
|
|
|
|
]]></setter>
|
|
|
|
</property>
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<!-- nsIPlacesView -->
|
|
|
|
<property name="hasSelection">
|
2009-10-01 09:53:26 -07:00
|
|
|
<getter><![CDATA[
|
2008-02-25 13:45:22 -08:00
|
|
|
return this.selectedNode != null;
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></getter>
|
|
|
|
</property>
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<!-- nsIPlacesView -->
|
|
|
|
<method name="getSelectionNodes">
|
|
|
|
<body><![CDATA[
|
2008-02-25 13:45:22 -08:00
|
|
|
var selectedNode = this.selectedNode;
|
|
|
|
return selectedNode ? [selectedNode] : [];
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<!-- nsIPlacesView -->
|
|
|
|
<method name="getRemovableSelectionRanges">
|
2008-02-25 13:45:22 -08:00
|
|
|
<body><![CDATA[
|
2008-12-13 01:57:30 -08:00
|
|
|
// On static content the current selectedNode would be the selection's
|
|
|
|
// parent node. We don't want to allow removing a node when the
|
|
|
|
// selection is not explicit.
|
|
|
|
if (document.popupNode &&
|
|
|
|
(document.popupNode == "menupopup" || !document.popupNode.node))
|
|
|
|
return [];
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return [this.getSelectionNodes()];
|
|
|
|
]]></body>
|
|
|
|
</method>
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<!-- nsIPlacesView -->
|
2009-02-28 04:00:05 -08:00
|
|
|
<method name="getDraggableSelection">
|
2007-03-22 10:30:00 -07:00
|
|
|
<body><![CDATA[
|
2008-02-25 13:45:22 -08:00
|
|
|
return [this._draggedNode];
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<!-- nsIPlacesView -->
|
|
|
|
<property name="selectedNode">
|
|
|
|
<getter><![CDATA[
|
2008-02-25 13:45:22 -08:00
|
|
|
if (this._contextMenuShown) {
|
|
|
|
var popupNode = document.popupNode;
|
2008-04-06 12:41:08 -07:00
|
|
|
if (popupNode == this)
|
|
|
|
return this.getResultNode();
|
|
|
|
|
2008-02-25 13:45:22 -08:00
|
|
|
return popupNode.node || popupNode.parentNode._resultNode || null;
|
|
|
|
}
|
|
|
|
return null;
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></getter>
|
|
|
|
</property>
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<!-- nsIPlacesView -->
|
|
|
|
<property name="insertionPoint">
|
|
|
|
<getter><![CDATA[
|
2009-10-01 09:53:26 -07:00
|
|
|
// By default, the insertion point is at the top level, at the end.
|
2008-04-28 02:33:40 -07:00
|
|
|
var index = PlacesUtils.bookmarks.DEFAULT_INDEX;
|
2009-10-01 09:53:26 -07:00
|
|
|
var container = this._resultNode;
|
2008-04-28 02:33:40 -07:00
|
|
|
var orientation = Ci.nsITreeView.DROP_BEFORE;
|
2008-04-11 09:22:01 -07:00
|
|
|
var isTag = false;
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2008-02-25 13:45:22 -08:00
|
|
|
var selectedNode = this.selectedNode;
|
|
|
|
if (selectedNode) {
|
2008-04-28 02:33:40 -07:00
|
|
|
var popupNode = document.popupNode;
|
2008-05-05 13:03:37 -07:00
|
|
|
if (!popupNode.node) {
|
|
|
|
// If a static menuitem is selected the insertion point
|
2008-04-28 02:33:40 -07:00
|
|
|
// is inside the folder, at the end.
|
2008-08-06 09:46:43 -07:00
|
|
|
container = selectedNode;
|
2008-04-28 02:33:40 -07:00
|
|
|
orientation = Ci.nsITreeView.DROP_ON;
|
2008-02-25 13:45:22 -08:00
|
|
|
}
|
|
|
|
else {
|
2008-04-28 02:33:40 -07:00
|
|
|
// In all other cases the insertion point is before that node.
|
2008-08-06 09:46:43 -07:00
|
|
|
container = selectedNode.parent;
|
2010-02-25 10:30:09 -08:00
|
|
|
index = container.getChildIndex(selectedNode);
|
|
|
|
isTag = PlacesUtils.nodeIsTagQuery(container);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
2008-08-06 09:46:43 -07:00
|
|
|
|
2008-09-19 08:47:45 -07:00
|
|
|
if (PlacesControllerDragHelper.disallowInsertion(container))
|
2008-08-06 09:46:43 -07:00
|
|
|
return null;
|
|
|
|
|
|
|
|
return new InsertionPoint(PlacesUtils.getConcreteItemId(container),
|
|
|
|
index, orientation, isTag);
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></getter>
|
|
|
|
</property>
|
2007-03-22 16:43:56 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<!-- nsIPlacesView -->
|
|
|
|
<method name="selectAll">
|
2009-10-01 09:53:26 -07:00
|
|
|
<body><![CDATA[
|
2007-03-22 10:30:00 -07:00
|
|
|
// Nothing
|
|
|
|
]]></body>
|
2008-02-21 11:50:22 -08:00
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="selectItems">
|
|
|
|
<body><![CDATA[
|
|
|
|
// Nothing
|
|
|
|
]]></body>
|
2007-03-22 10:30:00 -07:00
|
|
|
</method>
|
2007-05-30 09:17:34 -07:00
|
|
|
|
2010-03-12 03:14:47 -08:00
|
|
|
<!-- nsINavHistoryResultObserver -->
|
|
|
|
<field name="_resultObserver"><![CDATA[({
|
2007-03-22 10:30:00 -07:00
|
|
|
_self: this,
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2008-01-29 12:04:43 -08:00
|
|
|
get result() {
|
|
|
|
return this._self._result;
|
|
|
|
},
|
|
|
|
|
|
|
|
set result(val) {
|
2010-03-12 03:14:47 -08:00
|
|
|
if (this._self._result) {
|
|
|
|
this._self._result.removeObserver(this);
|
|
|
|
this._self._resultNode.containerOpen = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._self._result = val;
|
|
|
|
if (val) {
|
|
|
|
this._self._resultNode = val.root;
|
|
|
|
this._self._resultNode._DOMElement = this._self;
|
|
|
|
// This calls _rebuild through invalidateContainer.
|
|
|
|
this._self._resultNode.containerOpen = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this._self._resultNode = null;
|
2008-02-19 18:08:25 -08:00
|
|
|
}
|
2010-03-12 03:14:47 -08:00
|
|
|
|
2008-01-29 12:04:43 -08:00
|
|
|
return val;
|
|
|
|
},
|
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
nodeInserted: function TV_V_nodeInserted(aParentNode, aNode, aIndex) {
|
|
|
|
let parentElt = aParentNode._DOMElement;
|
|
|
|
NS_ASSERT(parentElt, "parent node must have _DOMElement set");
|
|
|
|
|
|
|
|
if (parentElt == this._self) {
|
|
|
|
// Node is on the toolbar.
|
|
|
|
let children = this._self.childNodes;
|
2007-05-27 12:28:40 -07:00
|
|
|
this._self.insertNewItem(aNode,
|
|
|
|
aIndex < children.length ? children[aIndex] : null);
|
|
|
|
this._self.updateChevron();
|
|
|
|
}
|
2009-10-01 09:53:26 -07:00
|
|
|
else if (parentElt._built) {
|
|
|
|
// Node is within a built menu.
|
|
|
|
let popup = parentElt.firstChild;
|
|
|
|
let before = popup.childNodes[aIndex] || null;
|
2007-10-24 19:02:28 -07:00
|
|
|
this._self.insertNewItemToPopup(aNode, popup, before);
|
|
|
|
if (popup._emptyMenuItem)
|
|
|
|
popup._emptyMenuItem.hidden = true;
|
2007-06-15 18:53:06 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
nodeRemoved: function TV_V_nodeRemoved(aParentNode, aNode, aIndex) {
|
|
|
|
let parentElt = aParentNode._DOMElement;
|
|
|
|
let nodeElt = aNode._DOMElement;
|
|
|
|
|
|
|
|
NS_ASSERT(parentElt, "parent node must have _DOMElement set");
|
|
|
|
NS_ASSERT(nodeElt, "node must have _DOMElement set");
|
|
|
|
|
|
|
|
if (parentElt == this._self) {
|
|
|
|
// Node is on the toolbar.
|
|
|
|
this._self.removeChild(nodeElt);
|
|
|
|
this._self.updateChevron();
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2009-10-01 09:53:26 -07:00
|
|
|
else if (parentElt._built) {
|
|
|
|
// Node is within a built menu.
|
|
|
|
var popup = parentElt.firstChild;
|
|
|
|
popup.removeChild(nodeElt);
|
|
|
|
if (!popup.hasChildNodes() ||
|
|
|
|
(popup.childNodes.length == 1 &&
|
|
|
|
popup.firstChild == popup._emptyMenuItem))
|
|
|
|
this._self._showEmptyMenuItem(popup);
|
|
|
|
|
|
|
|
if (popup._endMarker != -1)
|
|
|
|
popup._endMarker--;
|
2007-10-24 19:02:28 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
nodeMoved:
|
|
|
|
function TV_V_nodeMoved(aNode,
|
|
|
|
aOldParent, aOldIndex,
|
|
|
|
aNewParent, aNewIndex) {
|
|
|
|
// Note: the current implementation of moveItem does not actually
|
|
|
|
// use this notification when the item in question is moved from one
|
|
|
|
// folder to another. Instead, it calls nodeRemoved and nodeInserted
|
|
|
|
// for the two folders. Thus, we can assume aOldParent == aNewParent.
|
|
|
|
|
|
|
|
let nodeElt = aNode._DOMElement;
|
|
|
|
NS_ASSERT(nodeElt, "node must have _DOMElement set");
|
|
|
|
|
|
|
|
// If our root node is a folder, it might be moved. There's nothing
|
|
|
|
// we need to do in that case.
|
|
|
|
if (nodeElt == this._self)
|
2007-12-28 18:59:22 -08:00
|
|
|
return;
|
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
let parentElt = aNewParent._DOMElement;
|
|
|
|
NS_ASSERT(parentElt, "parent node must have _DOMElement set");
|
|
|
|
|
|
|
|
if (parentElt == this._self) {
|
|
|
|
// Container is on the toolbar.
|
|
|
|
|
|
|
|
// Move the node.
|
|
|
|
this._self.removeChild(nodeElt);
|
|
|
|
this._self.insertBefore(nodeElt, this._self.childNodes[aNewIndex]);
|
|
|
|
|
|
|
|
// If the chevron popup is open, keep it in sync.
|
|
|
|
if (this._self._chevron.open) {
|
|
|
|
let chevronPopup = this._self._chevronPopup;
|
|
|
|
let menuitem = chevronPopup.childNodes[aOldIndex];
|
|
|
|
chevronPopup.removeChild(menuitem);
|
|
|
|
chevronPopup.insertBefore(menuitem,
|
|
|
|
chevronPopup.childNodes[aNewIndex]);
|
2007-12-28 18:59:22 -08:00
|
|
|
}
|
2009-10-01 09:53:26 -07:00
|
|
|
this._self.updateChevron();
|
2007-12-28 18:59:22 -08:00
|
|
|
}
|
2009-10-01 09:53:26 -07:00
|
|
|
else if (parentElt._built) {
|
|
|
|
// Container is within a built menu.
|
|
|
|
|
|
|
|
// parentElt is the <menu> element for the container,
|
|
|
|
// we need the <menupopup>.
|
|
|
|
var popup = parentElt.firstChild;
|
|
|
|
|
|
|
|
// Move the node.
|
|
|
|
popup.removeChild(nodeElt);
|
|
|
|
popup.insertBefore(nodeElt, popup.childNodes[aNewIndex]);
|
2007-12-28 18:59:22 -08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
nodeTitleChanged: function TV_V_nodeTitleChanged(aNode, aNewTitle) {
|
|
|
|
let nodeElt = aNode._DOMElement;
|
|
|
|
NS_ASSERT(nodeElt, "node must have _DOMElement set");
|
2007-05-30 09:17:34 -07:00
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
// There's no UI representation for the root node, thus there's
|
|
|
|
// nothing to be done when the title changes.
|
|
|
|
if (nodeElt == this._self)
|
2009-06-24 09:29:26 -07:00
|
|
|
return;
|
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
if (nodeElt.parentNode == this._self) {
|
|
|
|
// Node is on the toolbar
|
|
|
|
nodeElt.label = aNewTitle;
|
|
|
|
this._self.updateChevron();
|
2007-05-30 09:17:34 -07:00
|
|
|
}
|
2007-10-24 19:02:28 -07:00
|
|
|
else {
|
2009-10-01 09:53:26 -07:00
|
|
|
// Node is within a built menu.
|
|
|
|
nodeElt.label = aNewTitle || PlacesUIUtils.getBestTitle(aNode);
|
2007-10-24 19:02:28 -07:00
|
|
|
}
|
2009-10-01 09:53:26 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
nodeURIChanged: function TV_V_nodeURIChanged(aNode, aURIString) {
|
|
|
|
let nodeElt = aNode._DOMElement;
|
|
|
|
NS_ASSERT(nodeElt, "node must have _DOMElement set");
|
|
|
|
|
|
|
|
nodeElt.setAttribute("scheme",
|
|
|
|
PlacesUIUtils.guessUrlSchemeForUI(aURIString));
|
|
|
|
},
|
|
|
|
|
|
|
|
nodeIconChanged: function TV_V_nodeIconChanged(aNode) {
|
|
|
|
let nodeElt = aNode._DOMElement;
|
|
|
|
NS_ASSERT(nodeElt, "node must have _DOMElement set");
|
|
|
|
|
|
|
|
// There's no UI representation for the root node, thus there's
|
|
|
|
// nothing to be done when the icon changes.
|
|
|
|
if (nodeElt == this._self)
|
|
|
|
return;
|
2007-05-30 09:17:34 -07:00
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
let icon = aNode.icon;
|
|
|
|
if (icon) {
|
|
|
|
if (nodeElt.getAttribute("image") != icon)
|
|
|
|
nodeElt.setAttribute("image", icon);
|
2007-10-30 17:15:55 -07:00
|
|
|
}
|
2007-05-30 09:17:34 -07:00
|
|
|
else
|
2009-10-01 09:53:26 -07:00
|
|
|
nodeElt.removeAttribute("image");
|
|
|
|
},
|
2007-11-19 18:01:53 -08:00
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
nodeAnnotationChanged:
|
|
|
|
function TV_V_nodeAnnotationChanged(aNode, aAnno) {
|
|
|
|
// Ensure the changed annotation is a livemark one.
|
|
|
|
if (/^livemark\//.test(aAnno) &&
|
|
|
|
PlacesUtils.nodeIsLivemarkContainer(aNode)) {
|
|
|
|
let nodeElt = aNode._DOMElement;
|
|
|
|
NS_ASSERT(nodeElt, "node must have _DOMElement set");
|
2009-09-26 01:23:17 -07:00
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
if (!nodeElt.hasAttribute("livemark"))
|
|
|
|
nodeElt.setAttribute("livemark", "true");
|
|
|
|
|
|
|
|
// Add or remove the livemark status menuitem.
|
|
|
|
PlacesUIUtils.ensureLivemarkStatusMenuItem(nodeElt.firstChild);
|
2009-03-09 06:15:46 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
nodeHistoryDetailsChanged: function() { },
|
|
|
|
nodeTagsChanged: function() { },
|
|
|
|
nodeDateAddedChanged: function() { },
|
|
|
|
nodeLastModifiedChanged: function() { },
|
|
|
|
nodeKeywordChanged: function() { },
|
|
|
|
|
|
|
|
nodeReplaced:
|
|
|
|
function TV_V_nodeReplaced(aParentNode, aOldNode, aNewNode, aIndex) {
|
|
|
|
let nodeElt = aOldNode._DOMElement;
|
|
|
|
NS_ASSERT(nodeElt, "node must have _DOMElement set");
|
|
|
|
|
|
|
|
// No worries: If nodeElt is the last item (i.e. no nextSibling),
|
|
|
|
// insertNewItem/insertNewItemToPopup will insert the new element as
|
|
|
|
// the last item.
|
|
|
|
let next = nodeElt.nextSibling;
|
|
|
|
|
|
|
|
let parentElt = aParentNode._DOMElement;
|
|
|
|
NS_ASSERT(parentElt, "parent node must have _DOMElement set");
|
|
|
|
if (parentElt == this._self) {
|
|
|
|
// Node is on the toolbar.
|
|
|
|
this._self.removeItem(nodeElt);
|
|
|
|
this._self.insertNewItem(aNewNode, next);
|
|
|
|
this._self.updateChevron();
|
|
|
|
}
|
|
|
|
else if (parentElt._built) {
|
|
|
|
// Node is within a built menu.
|
|
|
|
let popup = parentElt.firstChild;
|
|
|
|
popup.removeItem(nodeElt);
|
|
|
|
this._self.insertNewItemToPopup(aNewNode, popup, next);
|
2007-05-03 05:26:27 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
containerOpened: function TV_V_containerOpened(aContainer) {
|
|
|
|
this.invalidateContainer(aContainer);
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
containerClosed: function TV_V_containerClosed(aContainer) {
|
|
|
|
this.invalidateContainer(aContainer);
|
2007-03-22 10:30:00 -07:00
|
|
|
},
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2010-04-09 11:30:35 -07:00
|
|
|
containerStateChanged:
|
|
|
|
function TV_V_containerStateChanged(aNode, aOldState, aNewState) {},
|
|
|
|
|
2007-06-27 23:50:46 -07:00
|
|
|
invalidateContainer: function TV_V_invalidateContainer(aContainer) {
|
2009-10-01 09:53:26 -07:00
|
|
|
let containerNodeElt = aContainer._DOMElement;
|
|
|
|
NS_ASSERT(containerNodeElt, "node must have _DOMElement set");
|
2009-09-30 17:21:39 -07:00
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
if (containerNodeElt == this._self) {
|
|
|
|
// Container is the toolbar itself.
|
|
|
|
this._self._rebuild();
|
2008-05-06 12:21:10 -07:00
|
|
|
}
|
2009-10-01 09:53:26 -07:00
|
|
|
else if (containerNodeElt._built) {
|
|
|
|
// Container is a built menu.
|
|
|
|
containerNodeElt._built = false;
|
|
|
|
// If the menupopup is open we should live-update it.
|
|
|
|
if (containerNodeElt.open)
|
|
|
|
this._self._rebuildPopup(containerNodeElt.firstChild);
|
2009-09-30 17:21:39 -07:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2007-06-15 18:53:06 -07:00
|
|
|
sortingChanged: function TV_V_sortingChanged(aSortingMode) {
|
2010-03-12 03:14:47 -08:00
|
|
|
},
|
|
|
|
|
|
|
|
QueryInterface: function PTV_QueryInterface(aIID) {
|
|
|
|
if (aIID.equals(Ci.nsINavHistoryResultObserver) ||
|
|
|
|
aIID.equals(Ci.nsISupportsWeakReference) ||
|
|
|
|
aIID.equals(Ci.nsISupports))
|
|
|
|
return this;
|
|
|
|
throw Cr.NS_ERROR_NO_INTERFACE;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
})]]></field>
|
2007-05-03 05:26:27 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<property name="selType" onget="return 'single';"/>
|
|
|
|
|
|
|
|
<method name="buildContextMenu">
|
|
|
|
<parameter name="aPopup"/>
|
|
|
|
<body><![CDATA[
|
2008-02-25 13:45:22 -08:00
|
|
|
this._contextMenuShown = true;
|
2009-06-10 11:00:30 -07:00
|
|
|
window.updateCommands("places");
|
2008-12-13 01:57:30 -08:00
|
|
|
return this.controller.buildContextMenu(aPopup);
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="destroyContextMenu">
|
|
|
|
<parameter name="aPopup"/>
|
2007-10-24 19:02:28 -07:00
|
|
|
<body><![CDATA[
|
2008-02-25 13:45:22 -08:00
|
|
|
this._contextMenuShown = false;
|
2007-10-24 19:02:28 -07:00
|
|
|
if (window.content)
|
|
|
|
window.content.focus();
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="_showEmptyMenuItem">
|
|
|
|
<parameter name="aPopup"/>
|
|
|
|
<body><![CDATA[
|
|
|
|
if (aPopup._emptyMenuItem) {
|
|
|
|
aPopup._emptyMenuItem.hidden = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-03-13 12:25:49 -07:00
|
|
|
var label = PlacesUIUtils.getString("bookmarksMenuEmptyFolder");
|
2007-10-24 19:02:28 -07:00
|
|
|
aPopup._emptyMenuItem = document.createElement("menuitem");
|
|
|
|
aPopup._emptyMenuItem.setAttribute("label", label);
|
|
|
|
aPopup._emptyMenuItem.setAttribute("disabled", true);
|
|
|
|
aPopup.appendChild(aPopup._emptyMenuItem);
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="insertNewItemToPopup">
|
|
|
|
<parameter name="aChild"/>
|
|
|
|
<parameter name="aParentPopup"/>
|
|
|
|
<parameter name="aBefore"/>
|
|
|
|
<body><![CDATA[
|
2009-10-01 09:53:26 -07:00
|
|
|
var element = PlacesUIUtils.createMenuItemForNode(aChild);
|
2008-03-12 04:08:08 -07:00
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
if (aBefore)
|
|
|
|
aParentPopup.insertBefore(element, aBefore);
|
2008-03-12 04:08:08 -07:00
|
|
|
else {
|
|
|
|
// Add the new element to the menu. If there is static content at
|
|
|
|
// the end of the menu, add the element before that. Otherwise,
|
|
|
|
// just add to the end.
|
|
|
|
if (aParentPopup._endMarker != -1) {
|
2009-08-14 01:03:34 -07:00
|
|
|
let lastNode = aParentPopup.childNodes[aParentPopup._endMarker];
|
|
|
|
aParentPopup.insertBefore(element, lastNode);
|
2008-03-12 04:08:08 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
aParentPopup.appendChild(element);
|
|
|
|
}
|
2008-09-19 08:47:45 -07:00
|
|
|
|
|
|
|
if (aParentPopup._endMarker != -1)
|
|
|
|
aParentPopup._endMarker++;
|
2007-10-24 19:02:28 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="_containerPopupShowing">
|
|
|
|
<parameter name="aPopup"/>
|
|
|
|
<body><![CDATA[
|
2009-10-01 09:53:26 -07:00
|
|
|
if (!aPopup.parentNode._built)
|
2008-05-06 12:21:10 -07:00
|
|
|
this._rebuildPopup(aPopup);
|
|
|
|
]]></body>
|
|
|
|
</method>
|
2007-10-24 19:02:28 -07:00
|
|
|
|
2008-05-06 12:21:10 -07:00
|
|
|
<method name="_rebuildPopup">
|
|
|
|
<parameter name="aPopup"/>
|
|
|
|
<body><![CDATA[
|
2008-03-13 15:14:07 -07:00
|
|
|
PlacesUIUtils.cleanPlacesPopup(aPopup);
|
2007-10-24 19:02:28 -07:00
|
|
|
|
2008-09-25 03:30:33 -07:00
|
|
|
// If this is a livemark container check if the status menuitem has
|
|
|
|
// to be added or removed.
|
|
|
|
if (PlacesUtils.nodeIsLivemarkContainer(aPopup._resultNode))
|
|
|
|
PlacesUIUtils.ensureLivemarkStatusMenuItem(aPopup);
|
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
var resultNode = aPopup._resultNode;
|
|
|
|
if (!resultNode.containerOpen)
|
|
|
|
resultNode.containerOpen = true;
|
|
|
|
|
|
|
|
var cc = resultNode.childCount;
|
|
|
|
if (cc > 0) {
|
|
|
|
if (aPopup._emptyMenuItem)
|
|
|
|
aPopup._emptyMenuItem.hidden = true;
|
|
|
|
|
2009-08-14 01:03:34 -07:00
|
|
|
for (let i = 0; i < cc; ++i) {
|
2007-10-24 19:02:28 -07:00
|
|
|
var child = resultNode.getChild(i);
|
|
|
|
this.insertNewItemToPopup(child, aPopup, null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2008-03-12 04:08:08 -07:00
|
|
|
// This menu is empty. If there is no static content, add
|
|
|
|
// an element to show it is empty.
|
|
|
|
if (aPopup._startMarker == -1 && aPopup._endMarker == -1)
|
|
|
|
this._showEmptyMenuItem(aPopup);
|
2007-10-24 19:02:28 -07:00
|
|
|
}
|
2009-10-01 09:53:26 -07:00
|
|
|
aPopup.parentNode._built = true;
|
2007-10-24 19:02:28 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
2008-10-14 05:35:03 -07:00
|
|
|
|
|
|
|
<field name="_overFolder"><![CDATA[
|
|
|
|
(
|
|
|
|
// Menu buttons should be opened when the mouse drags over them, and
|
|
|
|
// closed when the mouse drags off. This object manages opening and
|
|
|
|
// closing of folders when the mouse hovers.
|
|
|
|
{ node: null, openTimer: null, hoverTime: 350, closeTimer: null }
|
|
|
|
);
|
|
|
|
]]></field>
|
|
|
|
|
|
|
|
<method name="_clearOverFolder">
|
|
|
|
<body><![CDATA[
|
|
|
|
// The mouse is no longer dragging over the stored menubutton.
|
|
|
|
// Close the menubutton, clear out drag styles, and clear all
|
|
|
|
// timers for opening/closing it.
|
|
|
|
if (this._overFolder.node && this._overFolder.node.lastChild) {
|
|
|
|
if (!this._overFolder.node.lastChild.hasAttribute("dragover")) {
|
|
|
|
this._overFolder.node.lastChild.hidePopup();
|
|
|
|
}
|
|
|
|
this._overFolder.node.removeAttribute("dragover");
|
|
|
|
this._overFolder.node = null;
|
|
|
|
}
|
|
|
|
if (this._overFolder.openTimer) {
|
|
|
|
this._overFolder.openTimer.cancel();
|
|
|
|
this._overFolder.openTimer = null;
|
|
|
|
}
|
|
|
|
if (this._overFolder.closeTimer) {
|
|
|
|
this._overFolder.closeTimer.cancel();
|
|
|
|
this._overFolder.closeTimer = null;
|
|
|
|
}
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="_getDropPoint">
|
|
|
|
<parameter name="aEvent"/>
|
|
|
|
<body><![CDATA[
|
|
|
|
// This function returns information about where to drop when
|
2009-08-14 01:03:34 -07:00
|
|
|
// dragging over the toolbar.
|
|
|
|
// The returned object has 3 properties:
|
|
|
|
// - ip: the insertion point for the bookmarks service.
|
|
|
|
// - beforeIndex: child index to drop before, for the drop indicator.
|
|
|
|
// - folderNode: the folder to drop into, if applicable.
|
2008-10-14 05:35:03 -07:00
|
|
|
var result = this.getResult();
|
2009-10-01 09:53:26 -07:00
|
|
|
if (!PlacesUtils.nodeIsFolder(this._resultNode))
|
2008-10-14 05:35:03 -07:00
|
|
|
return null;
|
|
|
|
|
|
|
|
var dropPoint = { ip: null, beforeIndex: null, folderNode: null };
|
2009-08-14 01:03:34 -07:00
|
|
|
var xulNode = aEvent.target;
|
|
|
|
if (xulNode.node) {
|
|
|
|
let nodeRect = xulNode.getBoundingClientRect();
|
|
|
|
let nodeIndex = Array.indexOf(this.childNodes, xulNode);
|
2008-10-14 05:35:03 -07:00
|
|
|
if (PlacesUtils.nodeIsFolder(xulNode.node) &&
|
|
|
|
!PlacesUtils.nodeIsReadOnly(xulNode.node)) {
|
2009-08-14 01:03:34 -07:00
|
|
|
// This is a folder.
|
|
|
|
// If we are in the middle of it, drop inside it.
|
|
|
|
// Otherwise, drop before it, with regards to RTL mode.
|
|
|
|
let threshold = nodeRect.width * 0.25;
|
|
|
|
if (this._isRTL ? (aEvent.clientX > nodeRect.right - threshold)
|
|
|
|
: (aEvent.clientX < nodeRect.left + threshold)) {
|
|
|
|
// Drop before this folder.
|
2008-10-14 05:35:03 -07:00
|
|
|
dropPoint.ip =
|
2009-10-01 09:53:26 -07:00
|
|
|
new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
|
2009-08-14 01:03:34 -07:00
|
|
|
nodeIndex, Ci.nsITreeView.DROP_BEFORE);
|
|
|
|
dropPoint.beforeIndex = nodeIndex;
|
2008-10-14 05:35:03 -07:00
|
|
|
}
|
2009-08-14 01:03:34 -07:00
|
|
|
else if (this._isRTL ? (aEvent.clientX > nodeRect.left + threshold)
|
|
|
|
: (aEvent.clientX < nodeRect.right - threshold)) {
|
2008-10-14 05:35:03 -07:00
|
|
|
// Drop inside this folder.
|
|
|
|
dropPoint.ip =
|
|
|
|
new InsertionPoint(PlacesUtils.getConcreteItemId(xulNode.node),
|
2009-08-14 01:03:34 -07:00
|
|
|
-1, Ci.nsITreeView.DROP_ON,
|
2008-10-14 05:35:03 -07:00
|
|
|
PlacesUtils.nodeIsTagQuery(xulNode.node));
|
2009-08-14 01:03:34 -07:00
|
|
|
dropPoint.beforeIndex = nodeIndex;
|
2008-10-14 05:35:03 -07:00
|
|
|
dropPoint.folderNode = xulNode;
|
2009-08-14 01:03:34 -07:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Drop after this folder.
|
|
|
|
let beforeIndex =
|
|
|
|
(nodeIndex == this.childNodes.length - 1) ? -1 : nodeIndex + 1;
|
|
|
|
dropPoint.ip =
|
2009-10-01 09:53:26 -07:00
|
|
|
new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
|
2009-08-14 01:03:34 -07:00
|
|
|
beforeIndex, Ci.nsITreeView.DROP_BEFORE);
|
|
|
|
dropPoint.beforeIndex = beforeIndex;
|
2008-10-14 05:35:03 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2009-08-14 01:03:34 -07:00
|
|
|
// This is a non-folder node or a read-only folder.
|
|
|
|
// Drop before it with regards to RTL mode.
|
|
|
|
let threshold = nodeRect.width * 0.5;
|
|
|
|
if (this._isRTL ? (aEvent.clientX > nodeRect.left + threshold)
|
|
|
|
: (aEvent.clientX < nodeRect.left + threshold)) {
|
2008-10-14 05:35:03 -07:00
|
|
|
// Drop before this bookmark.
|
|
|
|
dropPoint.ip =
|
2009-10-01 09:53:26 -07:00
|
|
|
new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
|
2009-08-14 01:03:34 -07:00
|
|
|
nodeIndex, Ci.nsITreeView.DROP_BEFORE);
|
|
|
|
dropPoint.beforeIndex = nodeIndex;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Drop after this bookmark.
|
|
|
|
let beforeIndex =
|
|
|
|
nodeIndex == this.childNodes.length - 1 ? -1 : nodeIndex + 1;
|
|
|
|
dropPoint.ip =
|
2009-10-01 09:53:26 -07:00
|
|
|
new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
|
2009-08-14 01:03:34 -07:00
|
|
|
beforeIndex, Ci.nsITreeView.DROP_BEFORE);
|
|
|
|
dropPoint.beforeIndex = beforeIndex;
|
2008-10-14 05:35:03 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-08-14 01:03:34 -07:00
|
|
|
else {
|
|
|
|
// We are most likely dragging on the empty area of the
|
|
|
|
// toolbar, we should drop after the last node.
|
|
|
|
dropPoint.ip =
|
2009-10-01 09:53:26 -07:00
|
|
|
new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
|
2009-08-14 01:03:34 -07:00
|
|
|
-1, Ci.nsITreeView.DROP_BEFORE);
|
|
|
|
dropPoint.beforeIndex = -1;
|
|
|
|
}
|
|
|
|
|
2008-10-14 05:35:03 -07:00
|
|
|
return dropPoint;
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="_setTimer">
|
|
|
|
<parameter name="aTime"/>
|
|
|
|
<body><![CDATA[
|
|
|
|
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
|
|
|
timer.initWithCallback(this, aTime, timer.TYPE_ONE_SHOT);
|
|
|
|
return timer;
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<!-- nsITimerCallback -->
|
|
|
|
<method name="notify">
|
|
|
|
<parameter name="aTimer"/>
|
|
|
|
<body><![CDATA[
|
|
|
|
// Function to process all timer notifications.
|
|
|
|
|
2009-08-14 01:03:34 -07:00
|
|
|
if (aTimer == this._updateChevronTimer) {
|
|
|
|
this._updateChevronTimer = null;
|
|
|
|
this._updateChevronTimerCallback();
|
|
|
|
}
|
|
|
|
|
2008-10-14 05:35:03 -07:00
|
|
|
// * Timer to turn off indicator bar.
|
2009-08-14 01:03:34 -07:00
|
|
|
else if (aTimer == this._ibTimer) {
|
|
|
|
this._dropIndicator.collapsed = true;
|
2008-10-14 05:35:03 -07:00
|
|
|
this._ibTimer = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// * Timer to open a menubutton that's being dragged over.
|
2009-08-14 01:03:34 -07:00
|
|
|
else if (aTimer == this._overFolder.openTimer) {
|
2008-10-14 05:35:03 -07:00
|
|
|
// Set the autoopen attribute on the folder's menupopup so that
|
|
|
|
// the menu will automatically close when the mouse drags off of it.
|
|
|
|
this._overFolder.node.lastChild.setAttribute("autoopened", "true");
|
|
|
|
this._overFolder.node.open = true;
|
|
|
|
this._overFolder.openTimer = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// * Timer to close a menubutton that's been dragged off of.
|
2009-08-14 01:03:34 -07:00
|
|
|
else if (aTimer == this._overFolder.closeTimer) {
|
|
|
|
// Close the menubutton if we are not dragging over it or one of
|
|
|
|
// its children. The autoopened attribute will let the menu know to
|
|
|
|
// close later if the menu is still being dragged over.
|
2008-10-14 05:35:03 -07:00
|
|
|
var currentNode = PlacesControllerDragHelper.currentDropTarget;
|
|
|
|
var inHierarchy = false;
|
|
|
|
while (currentNode) {
|
|
|
|
if (currentNode == this) {
|
|
|
|
inHierarchy = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
currentNode = currentNode.parentNode;
|
|
|
|
}
|
|
|
|
// The _clearOverFolder() function will close the menu for _overFolder.node.
|
|
|
|
// So null it out if we don't want to close it.
|
|
|
|
if (inHierarchy)
|
|
|
|
this._overFolder.node = null;
|
|
|
|
|
|
|
|
// Clear out the folder and all associated timers.
|
|
|
|
this._clearOverFolder();
|
|
|
|
}
|
|
|
|
]]></body>
|
|
|
|
</method>
|
2010-02-23 07:20:36 -08:00
|
|
|
|
|
|
|
<method name="_cleanupDragDetails">
|
|
|
|
<body><![CDATA[
|
|
|
|
// Called on dragend and drop.
|
|
|
|
PlacesControllerDragHelper.currentDropTarget = null;
|
|
|
|
this._draggedNode = null;
|
|
|
|
if (this._ibTimer)
|
|
|
|
this._ibTimer.cancel();
|
|
|
|
this._dropIndicator.collapsed = true;
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
</implementation>
|
2007-10-24 19:02:28 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<handlers>
|
2008-02-06 13:20:23 -08:00
|
|
|
<handler event="mouseover"><![CDATA[
|
|
|
|
var button = event.target;
|
|
|
|
if (button.parentNode == this && button.node &&
|
|
|
|
PlacesUtils.nodeIsURI(button.node))
|
|
|
|
window.XULBrowserWindow.setOverLink(event.target.node.uri, null);
|
|
|
|
]]></handler>
|
2008-10-14 05:35:03 -07:00
|
|
|
|
2008-02-06 13:20:23 -08:00
|
|
|
<handler event="mouseout"><![CDATA[
|
|
|
|
window.XULBrowserWindow.setOverLink("", null);
|
|
|
|
]]></handler>
|
2008-10-14 05:35:03 -07:00
|
|
|
|
|
|
|
<handler event="dragstart"><![CDATA[
|
2010-02-23 07:20:36 -08:00
|
|
|
// Sub menus have their own d&d handlers.
|
|
|
|
let draggedDOMNode = event.target;
|
2008-10-14 05:35:03 -07:00
|
|
|
if (draggedDOMNode.parentNode != this || !draggedDOMNode.node)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (draggedDOMNode.localName == "toolbarbutton" &&
|
|
|
|
draggedDOMNode.getAttribute("type") == "menu") {
|
2009-01-23 03:52:14 -08:00
|
|
|
// If the drag gesture on a container is toward down we open instead
|
|
|
|
// of dragging.
|
|
|
|
if (this._mouseDownTimer) {
|
|
|
|
this._mouseDownTimer.cancel();
|
|
|
|
this._mouseDownTimer = null;
|
|
|
|
}
|
2010-02-23 07:20:36 -08:00
|
|
|
let translateY = this._cachedMouseMoveEvent.clientY - event.clientY;
|
|
|
|
let translateX = this._cachedMouseMoveEvent.clientX - event.clientX;
|
2009-01-23 03:52:14 -08:00
|
|
|
if ((translateY) >= Math.abs(translateX/2)) {
|
2010-02-23 07:20:36 -08:00
|
|
|
// Don't start the drag.
|
2009-01-23 03:52:14 -08:00
|
|
|
event.preventDefault();
|
|
|
|
// Open the menu
|
|
|
|
draggedDOMNode.open = true;
|
2008-10-14 05:35:03 -07:00
|
|
|
return;
|
2009-01-23 03:52:14 -08:00
|
|
|
}
|
2010-02-23 07:20:36 -08:00
|
|
|
// If the menu is open, close it.
|
2009-01-23 03:52:14 -08:00
|
|
|
if (draggedDOMNode.open) {
|
|
|
|
draggedDOMNode.firstChild.hidePopup();
|
|
|
|
draggedDOMNode.open = false;
|
|
|
|
}
|
2008-10-14 05:35:03 -07:00
|
|
|
}
|
|
|
|
|
2010-02-23 07:20:36 -08:00
|
|
|
// Activate the view and cache the dragged node.
|
2008-10-14 05:35:03 -07:00
|
|
|
this._draggedNode = draggedDOMNode.node;
|
|
|
|
this.focus();
|
|
|
|
|
|
|
|
this._controller.setDataTransfer(event);
|
2008-11-18 12:09:50 -08:00
|
|
|
event.stopPropagation();
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></handler>
|
2008-10-14 05:35:03 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<handler event="dragover"><![CDATA[
|
2010-02-23 07:20:36 -08:00
|
|
|
PlacesControllerDragHelper.currentDropTarget = event.target;
|
|
|
|
let dt = event.dataTransfer;
|
2008-10-14 05:35:03 -07:00
|
|
|
|
2010-02-23 07:20:36 -08:00
|
|
|
let dropPoint = this._getDropPoint(event);
|
|
|
|
if (!dropPoint || !dropPoint.ip ||
|
|
|
|
!PlacesControllerDragHelper.canDrop(dropPoint.ip, dt)) {
|
2009-08-14 01:03:34 -07:00
|
|
|
this._dropIndicator.collapsed = true;
|
2010-02-23 07:20:36 -08:00
|
|
|
event.stopPropagation();
|
2008-10-14 05:35:03 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this._ibTimer) {
|
|
|
|
this._ibTimer.cancel();
|
|
|
|
this._ibTimer = null;
|
|
|
|
}
|
|
|
|
|
2010-02-23 07:20:36 -08:00
|
|
|
if (dropPoint.folderNode || event.originalTarget == this._chevron) {
|
|
|
|
// Dropping over a menubutton or chevron button.
|
|
|
|
// Set styles and timer to open relative menupopup.
|
|
|
|
let overNode = dropPoint.folderNode || this._chevron;
|
2008-10-14 05:35:03 -07:00
|
|
|
if (this._overFolder.node != overNode) {
|
|
|
|
this._clearOverFolder();
|
|
|
|
this._overFolder.node = overNode;
|
|
|
|
this._overFolder.openTimer = this._setTimer(this._overFolder.hoverTime);
|
|
|
|
}
|
|
|
|
if (!this._overFolder.node.hasAttribute("dragover"))
|
|
|
|
this._overFolder.node.setAttribute("dragover", "true");
|
|
|
|
|
2009-08-14 01:03:34 -07:00
|
|
|
this._dropIndicator.collapsed = true;
|
2008-10-14 05:35:03 -07:00
|
|
|
}
|
|
|
|
else {
|
2010-02-23 07:20:36 -08:00
|
|
|
// Dragging over a normal toolbarbutton.
|
|
|
|
// Show indicator bar and move it to the appropriate drop point.
|
2009-08-14 01:03:34 -07:00
|
|
|
let ind = this._dropIndicator;
|
|
|
|
let halfInd = ind.clientWidth / 2;
|
|
|
|
let translateX;
|
|
|
|
if (this._isRTL) {
|
2008-10-14 05:35:03 -07:00
|
|
|
halfInd = Math.ceil(halfInd);
|
2009-08-14 01:03:34 -07:00
|
|
|
translateX = 0 - this._scrollbox.getBoundingClientRect().right -
|
|
|
|
halfInd;
|
2009-10-14 10:45:33 -07:00
|
|
|
if (this.firstChild) {
|
|
|
|
if (dropPoint.beforeIndex == -1)
|
|
|
|
translateX += this.lastChild.getBoundingClientRect().left;
|
|
|
|
else {
|
|
|
|
translateX += this.childNodes[dropPoint.beforeIndex]
|
2009-08-14 01:03:34 -07:00
|
|
|
.getBoundingClientRect().right;
|
2009-10-14 10:45:33 -07:00
|
|
|
}
|
2009-08-14 01:03:34 -07:00
|
|
|
}
|
2008-10-14 05:35:03 -07:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
halfInd = Math.floor(halfInd);
|
2009-08-14 01:03:34 -07:00
|
|
|
translateX = 0 - this._scrollbox.getBoundingClientRect().left +
|
|
|
|
halfInd;
|
2009-10-14 10:45:33 -07:00
|
|
|
if (this.firstChild) {
|
|
|
|
if (dropPoint.beforeIndex == -1)
|
|
|
|
translateX += this.lastChild.getBoundingClientRect().right;
|
|
|
|
else {
|
|
|
|
translateX += this.childNodes[dropPoint.beforeIndex]
|
|
|
|
.getBoundingClientRect().left;
|
|
|
|
}
|
2008-10-14 05:35:03 -07:00
|
|
|
}
|
|
|
|
}
|
2009-08-14 01:03:34 -07:00
|
|
|
|
|
|
|
ind.style.MozTransform = "translate(" + Math.round(translateX) + "px)";
|
|
|
|
ind.style.MozMarginStart = (-ind.clientWidth) + "px";
|
|
|
|
ind.collapsed = false;
|
|
|
|
|
2010-02-23 07:20:36 -08:00
|
|
|
// Clear out old folder information.
|
2008-10-14 05:35:03 -07:00
|
|
|
this._clearOverFolder();
|
|
|
|
}
|
|
|
|
|
|
|
|
event.preventDefault();
|
2008-11-18 12:09:50 -08:00
|
|
|
event.stopPropagation();
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></handler>
|
2008-10-14 05:35:03 -07:00
|
|
|
|
|
|
|
<handler event="drop"><![CDATA[
|
2008-11-18 12:09:50 -08:00
|
|
|
PlacesControllerDragHelper.currentDropTarget = event.target;
|
|
|
|
|
2010-02-23 07:20:36 -08:00
|
|
|
let dropPoint = this._getDropPoint(event);
|
|
|
|
if (dropPoint && dropPoint.ip) {
|
|
|
|
PlacesControllerDragHelper.onDrop(dropPoint.ip, event.dataTransfer);
|
|
|
|
event.preventDefault();
|
|
|
|
}
|
2008-11-18 12:09:50 -08:00
|
|
|
|
2010-02-23 07:20:36 -08:00
|
|
|
this._cleanupDragDetails();
|
2008-11-18 12:09:50 -08:00
|
|
|
event.stopPropagation();
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></handler>
|
2008-10-14 05:35:03 -07:00
|
|
|
|
|
|
|
<handler event="dragleave"><![CDATA[
|
|
|
|
PlacesControllerDragHelper.currentDropTarget = null;
|
|
|
|
|
|
|
|
// Set timer to turn off indicator bar (if we turn it off
|
|
|
|
// here, dragenter might be called immediately after, creating
|
2010-02-23 07:20:36 -08:00
|
|
|
// flicker).
|
2008-10-14 05:35:03 -07:00
|
|
|
if (this._ibTimer)
|
|
|
|
this._ibTimer.cancel();
|
|
|
|
this._ibTimer = this._setTimer(10);
|
|
|
|
|
2010-02-23 07:20:36 -08:00
|
|
|
// If we hovered over a folder, close it now.
|
2008-10-14 05:35:03 -07:00
|
|
|
if (this._overFolder.node)
|
|
|
|
this._overFolder.closeTimer = this._setTimer(this._overFolder.hoverTime);
|
2008-11-20 16:56:21 -08:00
|
|
|
]]></handler>
|
2008-10-14 05:35:03 -07:00
|
|
|
|
2008-11-20 16:56:21 -08:00
|
|
|
<handler event="dragend"><![CDATA[
|
2010-02-23 07:20:36 -08:00
|
|
|
this._cleanupDragDetails();
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></handler>
|
2008-10-14 05:35:03 -07:00
|
|
|
|
2009-10-01 09:53:26 -07:00
|
|
|
<handler event="popupshowing" phase="capturing"><![CDATA[
|
2009-01-23 03:52:14 -08:00
|
|
|
if (!this._allowPopupShowing) {
|
|
|
|
this._allowPopupShowing = true;
|
2008-09-19 08:47:45 -07:00
|
|
|
event.preventDefault();
|
2009-01-23 03:52:14 -08:00
|
|
|
return;
|
2008-09-19 08:47:45 -07:00
|
|
|
}
|
|
|
|
|
2008-03-18 12:40:05 -07:00
|
|
|
var popup = event.originalTarget;
|
2007-10-24 19:02:28 -07:00
|
|
|
|
2008-03-18 12:40:05 -07:00
|
|
|
// Avoid handling popupshowing of inner views
|
|
|
|
if (popup._resultNode && PlacesUIUtils.getViewForNode(popup) == this)
|
|
|
|
this._containerPopupShowing(popup);
|
2007-10-24 19:02:28 -07:00
|
|
|
|
2008-03-18 12:40:05 -07:00
|
|
|
var parent = popup.parentNode;
|
2009-02-28 03:56:40 -08:00
|
|
|
if (parent.localName == "toolbarbutton")
|
2008-03-18 12:40:05 -07:00
|
|
|
this._openedMenuButton = parent;
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></handler>
|
2008-10-14 05:35:03 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<handler event="popuphidden"><![CDATA[
|
2008-03-18 12:40:05 -07:00
|
|
|
var popup = event.originalTarget;
|
|
|
|
|
2008-12-30 13:42:23 -08:00
|
|
|
// Avoid handling popuphidden of inner views
|
2008-03-18 12:40:05 -07:00
|
|
|
if (popup._resultNode && PlacesUIUtils.getViewForNode(popup) == this) {
|
|
|
|
// UI performance: folder queries are cheap, keep the resultnode open
|
|
|
|
// so we don't rebuild its contents whenever the popup is reopened.
|
|
|
|
if (!PlacesUtils.nodeIsFolder(popup._resultNode))
|
|
|
|
popup._resultNode.containerOpen = false;
|
|
|
|
}
|
2007-10-24 19:02:28 -07:00
|
|
|
|
2008-03-18 12:40:05 -07:00
|
|
|
var parent = popup.parentNode;
|
2008-12-30 13:42:23 -08:00
|
|
|
if (parent.localName == "toolbarbutton") {
|
2009-02-28 03:56:40 -08:00
|
|
|
this._openedMenuButton = null;
|
2008-12-30 13:42:23 -08:00
|
|
|
// Clear the dragover attribute if present, if we are dragging into a
|
|
|
|
// folder in the hierachy of current opened popup we don't clear
|
|
|
|
// this attribute on clearOverFolder. See Notify for closeTimer.
|
|
|
|
if (parent.hasAttribute("dragover"))
|
|
|
|
parent.removeAttribute("dragover");
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></handler>
|
2007-10-24 19:02:28 -07:00
|
|
|
|
2009-06-24 15:15:25 -07:00
|
|
|
#ifdef XP_UNIX
|
|
|
|
#ifndef XP_MACOSX
|
2008-09-19 08:47:45 -07:00
|
|
|
<handler event="mousedown"><![CDATA[
|
2009-01-23 03:52:14 -08:00
|
|
|
var target = event.target;
|
|
|
|
if (event.button == 0 &&
|
|
|
|
target.localName == "toolbarbutton" &&
|
|
|
|
target.getAttribute("type") == "menu") {
|
|
|
|
this._allowPopupShowing = false;
|
2009-06-24 15:15:25 -07:00
|
|
|
// On Linux we can open the popup only after a delay.
|
|
|
|
// Indeed as soon as the menupopup opens we are unable to start a
|
|
|
|
// drag event. See bug 500081 for details.
|
2009-01-23 03:52:14 -08:00
|
|
|
this._mouseDownTimer = Cc["@mozilla.org/timer;1"]
|
|
|
|
.createInstance(Ci.nsITimer);
|
|
|
|
var callback = {
|
|
|
|
_self: this,
|
|
|
|
_target: target,
|
|
|
|
notify: function(timer) {
|
|
|
|
this._target.open = true;
|
|
|
|
this._self._mouseDownTimer = null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-06-24 15:15:25 -07:00
|
|
|
this._mouseDownTimer.initWithCallback(callback, 300,
|
2009-01-23 03:52:14 -08:00
|
|
|
Ci.nsITimer.TYPE_ONE_SHOT);
|
|
|
|
}
|
|
|
|
]]></handler>
|
2009-06-24 15:15:25 -07:00
|
|
|
#endif
|
|
|
|
#endif
|
2009-01-23 03:52:14 -08:00
|
|
|
<handler event="mouseup"><![CDATA[
|
|
|
|
if (event.button != 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (this._mouseDownTimer) {
|
|
|
|
// On a click (down/up) we should open the menu popup
|
|
|
|
this._mouseDownTimer.cancel();
|
|
|
|
this._mouseDownTimer = null;
|
|
|
|
event.target.open = true;
|
|
|
|
}
|
2008-09-19 08:47:45 -07:00
|
|
|
]]></handler>
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<handler event="mousemove"><![CDATA[
|
2009-01-23 03:52:14 -08:00
|
|
|
// Used in dragStart to prevent dragging folders when dragging down
|
|
|
|
this._cachedMouseMoveEvent = event;
|
|
|
|
|
2008-09-19 08:47:45 -07:00
|
|
|
if (this._openedMenuButton == null ||
|
|
|
|
PlacesControllerDragHelper.getSession())
|
2007-03-22 10:30:00 -07:00
|
|
|
return;
|
2007-10-24 19:02:28 -07:00
|
|
|
|
2007-06-11 22:28:20 -07:00
|
|
|
var target = event.originalTarget;
|
2007-03-22 10:30:00 -07:00
|
|
|
if (this._openedMenuButton != target &&
|
2007-06-11 22:28:20 -07:00
|
|
|
target.localName == "toolbarbutton" &&
|
2007-03-22 10:30:00 -07:00
|
|
|
target.type == "menu") {
|
|
|
|
this._openedMenuButton.open = false;
|
|
|
|
target.open = true;
|
|
|
|
}
|
|
|
|
]]></handler>
|
|
|
|
</handlers>
|
|
|
|
</binding>
|
|
|
|
|
|
|
|
</bindings>
|