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 Menupopup 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>
|
|
|
|
# Asaf Romano <mano@mozilla.com>
|
2008-02-20 18:17:52 -08:00
|
|
|
# Simon Bünzli <zeniko@gmail.com>
|
|
|
|
# Marco Bonardo <mak77@supereva.it>
|
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.
|
|
|
|
#
|
2007-09-16 18:45:16 -07:00
|
|
|
# ***** END LICENSE BLOCK *****
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
<bindings id="placesMenuBindings"
|
|
|
|
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">
|
|
|
|
|
2008-02-20 18:17:52 -08:00
|
|
|
<binding id="places-popup-base"
|
2007-03-22 10:30:00 -07:00
|
|
|
extends="chrome://global/content/bindings/popup.xml#popup">
|
2008-02-20 18:17:52 -08:00
|
|
|
<content>
|
|
|
|
<xul:hbox flex="1">
|
|
|
|
<xul:vbox class="menupopup-drop-indicator-bar" hidden="true">
|
|
|
|
<xul:image class="menupopup-drop-indicator" mousethrough="always"/>
|
|
|
|
</xul:vbox>
|
|
|
|
<xul:arrowscrollbox class="popup-internal-box" flex="1" orient="vertical">
|
|
|
|
<children/>
|
|
|
|
</xul:arrowscrollbox>
|
|
|
|
</xul:hbox>
|
|
|
|
</content>
|
|
|
|
|
|
|
|
<implementation>
|
|
|
|
|
|
|
|
<field name="_indicatorBar">
|
|
|
|
document.getAnonymousElementByAttribute(this, "class",
|
|
|
|
"menupopup-drop-indicator-bar");
|
|
|
|
</field>
|
|
|
|
|
|
|
|
<field name="_scrollBox">
|
|
|
|
document.getAnonymousElementByAttribute(this, "class",
|
|
|
|
"popup-internal-box");
|
|
|
|
</field>
|
|
|
|
|
|
|
|
<!-- markers for start and end of valid places items -->
|
|
|
|
<field name="_startMarker">-1</field>
|
|
|
|
<field name="_endMarker">-1</field>
|
|
|
|
|
|
|
|
<!-- This is the view that manage the popup -->
|
2008-03-13 12:25:49 -07:00
|
|
|
<field name="_rootView">PlacesUIUtils.getViewForNode(this);</field>
|
2008-02-20 18:17:52 -08:00
|
|
|
|
2008-03-12 04:08:08 -07:00
|
|
|
<field name="_built">false</field>
|
|
|
|
|
2008-02-20 18:17:52 -08:00
|
|
|
<method name="onDragOver">
|
|
|
|
<parameter name="aEvent"/>
|
|
|
|
<parameter name="aFlavour"/>
|
|
|
|
<parameter name="aDragSession"/>
|
|
|
|
<body><![CDATA[
|
|
|
|
PlacesControllerDragHelper.currentDropTarget = aEvent.target;
|
|
|
|
// check if we have a valid dropPoint
|
|
|
|
var dropPoint = this._getDropPoint(aEvent);
|
|
|
|
if (!dropPoint)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// add a dragover attribute to this popup
|
|
|
|
this.setAttribute("dragover", "true");
|
|
|
|
|
|
|
|
if (dropPoint.folderNode) {
|
|
|
|
// We are dragging over a folder
|
|
|
|
// _overFolder should take the care of opening it on a timer
|
|
|
|
if (this._overFolder.node &&
|
|
|
|
this._overFolder.node != dropPoint.folderNode) {
|
|
|
|
// we are dragging over a new folder, let's clear old values
|
|
|
|
this._overFolder.clear();
|
|
|
|
}
|
|
|
|
if (!this._overFolder.node) {
|
|
|
|
this._overFolder.node = dropPoint.folderNode;
|
|
|
|
// create the timer to open this folder
|
|
|
|
this._overFolder.openTimer = this._overFolder
|
|
|
|
.setTimer(this._overFolder.hoverTime);
|
|
|
|
}
|
|
|
|
// since we are dropping into a folder set the corresponding style
|
|
|
|
dropPoint.folderNode.setAttribute("dragover-into", "true");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// We are not dragging over a folder
|
|
|
|
// Clear out old _overFolder information
|
|
|
|
this._overFolder.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if we should hide the drop indicator for this target
|
|
|
|
if (!aDragSession.canDrop ||
|
|
|
|
!dropPoint || dropPoint.folderNode ||
|
|
|
|
this._hideDropIndicator(aEvent, dropPoint)) {
|
|
|
|
this._indicatorBar.hidden = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var scrollBoxObject = this._scrollBox.scrollBoxObject;
|
|
|
|
// Autoscroll the popup strip if we drag over the scroll buttons
|
|
|
|
var anonid = aEvent.originalTarget.getAttribute("anonid");
|
|
|
|
var scrollDir = anonid == "scrollbutton-up" ? -1 :
|
|
|
|
anonid == "scrollbutton-down" ? 1 : 0;
|
|
|
|
if (scrollDir != 0)
|
|
|
|
this._scrollBox.scrollByIndex(scrollDir);
|
|
|
|
|
|
|
|
// We should display the drop indicator relative to the arrowscrollbox
|
|
|
|
var newMarginTop = 0;
|
|
|
|
if (scrollDir == 0) {
|
|
|
|
var node = this.firstChild;
|
|
|
|
while (node && aEvent.screenY > node.boxObject.screenY +
|
|
|
|
node.boxObject.height / 2)
|
|
|
|
node = node.nextSibling;
|
|
|
|
newMarginTop = node ? node.boxObject.screenY - scrollBoxObject.screenY :
|
|
|
|
scrollBoxObject.height;
|
|
|
|
}
|
|
|
|
else if (scrollDir == 1)
|
|
|
|
newMarginTop = scrollBoxObject.height;
|
|
|
|
|
|
|
|
// set the new marginTop based on arrowscrollbox
|
2008-04-17 19:21:30 -07:00
|
|
|
newMarginTop += scrollBoxObject.y - this._scrollBox.boxObject.y;
|
2008-02-20 18:17:52 -08:00
|
|
|
this._indicatorBar.firstChild.style.marginTop = newMarginTop + "px";
|
|
|
|
this._indicatorBar.hidden = false;
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="onDragExit">
|
|
|
|
<parameter name="aEvent"/>
|
|
|
|
<parameter name="aDragSession"/>
|
|
|
|
<body><![CDATA[
|
|
|
|
PlacesControllerDragHelper.currentDropTarget = null;
|
|
|
|
this.removeAttribute("dragover");
|
|
|
|
// remove dragover-into style from previous target
|
|
|
|
aEvent.target.removeAttribute("dragover-into");
|
|
|
|
|
|
|
|
// if we have not moved to a valid new target clear the drop indicator
|
|
|
|
// this happens when moving out of the popup
|
|
|
|
var target = aEvent.relatedTarget;
|
|
|
|
if (!target)
|
|
|
|
this._indicatorBar.hidden = true;
|
|
|
|
|
|
|
|
// Close any folder being hovered over
|
|
|
|
if (this._overFolder.node) {
|
|
|
|
this._overFolder.closeTimer = this._overFolder
|
|
|
|
.setTimer(this._overFolder.hoverTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
// The autoopened attribute is set when this folder was automatically
|
|
|
|
// opened after the user dragged over it. If this attribute is set,
|
|
|
|
// auto-close the folder on drag exit.
|
|
|
|
if (this.hasAttribute("autoopened")) {
|
|
|
|
this._overFolder.closeMenuTimer = this._overFolder
|
|
|
|
.setTimer(this._overFolder.hoverTime);
|
|
|
|
}
|
2008-04-28 02:33:40 -07:00
|
|
|
|
|
|
|
this._rootView._draggedNode = null;
|
2008-02-20 18:17:52 -08:00
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="onDragStart">
|
|
|
|
<parameter name="aEvent"/>
|
|
|
|
<parameter name="aXferData"/>
|
|
|
|
<parameter name="aDragAction"/>
|
|
|
|
<body><![CDATA[
|
2008-04-25 14:36:40 -07:00
|
|
|
// Force a copy action if parent node is a query or not-removable
|
2008-04-11 09:22:01 -07:00
|
|
|
if (aEvent.ctrlKey ||
|
2008-04-25 14:36:40 -07:00
|
|
|
PlacesUtils.nodeIsQuery(aEvent.target.node.parent) ||
|
|
|
|
PlacesControllerDragHelper.canMoveContainerNode(aEvent.target.node))
|
2008-02-20 18:17:52 -08:00
|
|
|
aDragAction.action = Ci.nsIDragService.DRAGDROP_ACTION_COPY;
|
2008-02-25 13:45:22 -08:00
|
|
|
|
|
|
|
// activate the view and cache the dragged node
|
|
|
|
this._rootView._draggedNode = aEvent.target.node;
|
|
|
|
this._rootView.focus();
|
2008-04-11 09:22:01 -07:00
|
|
|
|
2008-02-20 18:17:52 -08:00
|
|
|
aXferData.data = this._rootView.controller
|
|
|
|
.getTransferData(aDragAction.action);
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="onDrop">
|
|
|
|
<parameter name="aEvent"/>
|
|
|
|
<parameter name="aDropData"/>
|
|
|
|
<parameter name="aSession"/>
|
|
|
|
<body><![CDATA[
|
|
|
|
var dropPoint = this._getDropPoint(aEvent);
|
|
|
|
if (!dropPoint)
|
|
|
|
return;
|
|
|
|
|
|
|
|
PlacesControllerDragHelper.onDrop(dropPoint.ip);
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<!-- This returns the FavourSet accepted by this popup -->
|
|
|
|
<method name="getSupportedFlavours">
|
|
|
|
<body><![CDATA[
|
|
|
|
var flavourSet = new FlavourSet();
|
2008-03-13 12:25:49 -07:00
|
|
|
var acceptedDropFlavours = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES;
|
2008-02-20 18:17:52 -08:00
|
|
|
acceptedDropFlavours.forEach(flavourSet.appendFlavour, flavourSet);
|
|
|
|
return flavourSet;
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<!-- Check if we should hide the drop indicator for the target -->
|
|
|
|
<method name="_hideDropIndicator">
|
|
|
|
<parameter name="aEvent"/>
|
|
|
|
<body><![CDATA[
|
|
|
|
var target = aEvent.target;
|
|
|
|
|
|
|
|
// in some view we have _startMarker and _endMarker, we should not
|
|
|
|
// draw the drop indicator outside of them
|
|
|
|
var betweenMarkers = true;
|
|
|
|
if (this._startMarker != -1 &&
|
2008-03-12 04:08:08 -07:00
|
|
|
target.boxObject.y <= this.childNodes[this._startMarker].boxObject.y)
|
2008-02-20 18:17:52 -08:00
|
|
|
betweenMarkers = false;
|
|
|
|
if (this._endMarker != -1 &&
|
2008-03-12 04:08:08 -07:00
|
|
|
target.boxObject.y >= this.childNodes[this._endMarker].boxObject.y)
|
2008-02-20 18:17:52 -08:00
|
|
|
betweenMarkers = false;
|
|
|
|
|
|
|
|
// hide the dropmarker if current node is not a places bookmark item
|
2008-03-12 04:08:08 -07:00
|
|
|
return !(target && target.node && betweenMarkers && this.canDrop());
|
2008-02-20 18:17:52 -08:00
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<!-- This function returns information about where to drop when
|
|
|
|
dragging over this popup insertion point -->
|
|
|
|
<method name="_getDropPoint">
|
|
|
|
<parameter name="aEvent"/>
|
|
|
|
<body><![CDATA[
|
|
|
|
// Can't drop if the menu isn't a folder
|
|
|
|
var resultNode = this._resultNode;
|
|
|
|
if (!PlacesUtils.nodeIsFolder(resultNode))
|
|
|
|
return null;
|
|
|
|
|
|
|
|
var dropPoint = { ip: null, beforeIndex: null, folderNode: null };
|
2008-02-23 02:21:07 -08:00
|
|
|
|
|
|
|
// set the limits for valid items
|
2008-02-20 18:17:52 -08:00
|
|
|
var start = 0;
|
|
|
|
var popup = this;
|
|
|
|
var end = popup.childNodes.length;
|
2008-02-23 02:21:07 -08:00
|
|
|
if (this._startMarker != -1)
|
|
|
|
start = this._startMarker + 1;
|
|
|
|
if (this._endMarker != -1)
|
|
|
|
end = this._endMarker;
|
|
|
|
|
|
|
|
// Loop through all the nodes to find the correct dropPoint
|
|
|
|
var popupY = popup.boxObject.y;
|
|
|
|
// we should add the scrollBox button height if visible
|
|
|
|
popupY += this._scrollBox.scrollBoxObject.y - popup.boxObject.y;
|
2008-02-20 18:17:52 -08:00
|
|
|
for (var i = start; i < end; i++) {
|
|
|
|
var xulNode = popup.childNodes[i];
|
2008-02-23 02:21:07 -08:00
|
|
|
var nodeY = xulNode.boxObject.y - popupY;
|
2008-02-20 18:17:52 -08:00
|
|
|
var nodeHeight = xulNode.boxObject.height;
|
|
|
|
if (xulNode.node &&
|
2008-04-11 09:22:01 -07:00
|
|
|
(PlacesUtils.nodeIsFolder(xulNode.node) ||
|
|
|
|
PlacesUtils.nodeIsTagQuery(xulNode.node)) &&
|
2008-02-20 18:17:52 -08:00
|
|
|
!PlacesUtils.nodeIsReadOnly(xulNode.node)) {
|
|
|
|
// This is a folder. If the mouse is in the top 25% of the
|
|
|
|
// node, drop above the folder. If it's in the middle
|
|
|
|
// 50%, drop into the folder. If it's past that, drop below.
|
|
|
|
if (aEvent.layerY < nodeY + (nodeHeight * 0.25)) {
|
|
|
|
// Drop above this folder.
|
|
|
|
dropPoint.ip = new InsertionPoint(resultNode.itemId,
|
|
|
|
i - start, -1);
|
|
|
|
dropPoint.beforeIndex = i;
|
|
|
|
return dropPoint;
|
|
|
|
}
|
|
|
|
else if (aEvent.layerY < nodeY + (nodeHeight * 0.75)) {
|
|
|
|
// Drop inside this folder.
|
|
|
|
dropPoint.ip = new InsertionPoint(xulNode.node.itemId, -1, 1);
|
|
|
|
dropPoint.beforeIndex = i;
|
|
|
|
dropPoint.folderNode = xulNode;
|
|
|
|
return dropPoint;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// This is a non-folder node. If the mouse is above the middle,
|
|
|
|
// drop above the folder. Otherwise, drop below.
|
2008-02-23 02:21:07 -08:00
|
|
|
if (aEvent.layerY <= nodeY + (nodeHeight / 2)) {
|
2008-02-20 18:17:52 -08:00
|
|
|
// Drop above this bookmark.
|
|
|
|
dropPoint.ip = new InsertionPoint(resultNode.itemId,
|
|
|
|
i - start, -1);
|
|
|
|
dropPoint.beforeIndex = i;
|
|
|
|
return dropPoint;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Should drop below the last node.
|
|
|
|
dropPoint.ip = new InsertionPoint(resultNode.itemId, -1, 1);
|
|
|
|
dropPoint.beforeIndex = -1;
|
|
|
|
return dropPoint;
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="canDrop">
|
|
|
|
<body><![CDATA[
|
2008-03-16 23:34:57 -07:00
|
|
|
var ip = this._rootView.insertionPoint;
|
2008-03-14 12:37:37 -07:00
|
|
|
return ip && PlacesControllerDragHelper.canDrop(ip);
|
2008-02-20 18:17:52 -08:00
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<!-- Sub-menus should be opened when the mouse drags over them, and closed
|
|
|
|
when the mouse drags off. The overFolder object manages opening and
|
|
|
|
closing of folders when the mouse hovers. -->
|
|
|
|
<field name="_overFolder"><![CDATA[({
|
|
|
|
_self: this,
|
|
|
|
_folder: {node: null, openTimer: null, hoverTime: 350, closeTimer: null},
|
|
|
|
_closeMenuTimer: null,
|
|
|
|
|
|
|
|
get node() {
|
|
|
|
return this._folder.node;
|
|
|
|
},
|
|
|
|
set node(val) {
|
|
|
|
return this._folder.node = val;
|
|
|
|
},
|
|
|
|
|
|
|
|
get openTimer() {
|
|
|
|
return this._folder.openTimer;
|
|
|
|
},
|
|
|
|
set openTimer(val) {
|
|
|
|
return this._folder.openTimer = val;
|
|
|
|
},
|
|
|
|
|
|
|
|
get hoverTime() {
|
|
|
|
return this._folder.hoverTime;
|
|
|
|
},
|
|
|
|
set hoverTime(val) {
|
|
|
|
return this._folder.hoverTime = val;
|
|
|
|
},
|
|
|
|
|
|
|
|
get closeTimer() {
|
|
|
|
return this._folder.closeTimer;
|
|
|
|
},
|
|
|
|
set closeTimer(val) {
|
|
|
|
return this._folder.closeTimer = val;
|
|
|
|
},
|
|
|
|
|
|
|
|
get closeMenuTimer() {
|
|
|
|
return this._closeMenuTimer;
|
|
|
|
},
|
|
|
|
set closeMenuTimer(val) {
|
|
|
|
return this._closeMenuTimer = val;
|
|
|
|
},
|
|
|
|
|
|
|
|
setTimer: function OF__setTimer(aTime) {
|
|
|
|
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
|
|
|
timer.initWithCallback(this, aTime, timer.TYPE_ONE_SHOT);
|
|
|
|
return timer;
|
|
|
|
},
|
|
|
|
|
|
|
|
notify: function OF__notify(aTimer) {
|
|
|
|
// Function to process all timer notifications.
|
|
|
|
|
|
|
|
if (aTimer == this._folder.openTimer) {
|
|
|
|
// Timer to open a submenu that's being dragged over.
|
|
|
|
this._folder.node.lastChild.setAttribute("autoopened", "true");
|
|
|
|
this._folder.node.lastChild.showPopup(this._folder.node);
|
|
|
|
this._folder.openTimer = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (aTimer == this._folder.closeTimer) {
|
|
|
|
// Timer to close a submenu that's been dragged off of.
|
|
|
|
// Only close the submenu if the mouse isn't being dragged over any
|
|
|
|
// of its child menus.
|
|
|
|
var draggingOverChild = PlacesControllerDragHelper
|
|
|
|
.draggingOverChildNode(this._folder.node);
|
|
|
|
if (draggingOverChild)
|
|
|
|
this._folder.node = null;
|
|
|
|
this.clear();
|
|
|
|
|
|
|
|
// Close any parent folders which aren't being dragged over.
|
|
|
|
// (This is necessary because of the above code that keeps a folder
|
|
|
|
// open while its children are being dragged over.)
|
|
|
|
if (!draggingOverChild)
|
|
|
|
this.closeParentMenus();
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (aTimer == this.closeMenuTimer) {
|
|
|
|
// Timer to close this menu after the drag exit.
|
|
|
|
var popup = this._self;
|
|
|
|
if (!PlacesControllerDragHelper.draggingOverChildNode(popup.parentNode)) {
|
|
|
|
popup.hidePopup();
|
|
|
|
// Close any parent menus that aren't being dragged over;
|
|
|
|
// otherwise they'll stay open because they couldn't close
|
|
|
|
// while this menu was being dragged over.
|
|
|
|
this.closeParentMenus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
// Helper function to close all parent menus of this menu,
|
|
|
|
// as long as none of the parent's children are currently being
|
|
|
|
// dragged over.
|
|
|
|
closeParentMenus: function OF__closeParentMenus() {
|
|
|
|
var popup = this._self;
|
|
|
|
var parent = popup.parentNode;
|
|
|
|
while (parent) {
|
|
|
|
if (parent.nodeName == "menupopup" && parent._resultNode) {
|
|
|
|
if (PlacesControllerDragHelper.draggingOverChildNode(parent.parentNode))
|
|
|
|
break;
|
|
|
|
parent.hidePopup();
|
|
|
|
}
|
|
|
|
parent = parent.parentNode;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
clear: function OF__clear() {
|
|
|
|
if (this._folder.node && this._folder.node.lastChild) {
|
|
|
|
if (!this._folder.node.lastChild.hasAttribute("dragover"))
|
|
|
|
this._folder.node.lastChild.hidePopup();
|
|
|
|
// remove dragover-into style
|
|
|
|
this._folder.node.removeAttribute("dragover-into");
|
|
|
|
this._folder.node = null;
|
|
|
|
}
|
|
|
|
if (this._folder.openTimer) {
|
|
|
|
this._folder.openTimer.cancel();
|
|
|
|
this._folder.openTimer = null;
|
|
|
|
}
|
|
|
|
if (this._folder.closeTimer) {
|
|
|
|
this._folder.closeTimer.cancel();
|
|
|
|
this._folder.closeTimer = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})]]></field>
|
|
|
|
|
|
|
|
</implementation>
|
|
|
|
|
|
|
|
<handlers>
|
2008-03-12 04:42:32 -07:00
|
|
|
<handler event="DOMMenuItemActive"><![CDATA[
|
|
|
|
var node = event.target;
|
|
|
|
if (node.parentNode != this)
|
|
|
|
return;
|
|
|
|
|
|
|
|
#ifdef XP_MACOSX
|
|
|
|
// XXXschonfeld: The following check is a temporary hack
|
|
|
|
// until bug 420033 is resolved.
|
|
|
|
while (node) {
|
|
|
|
if (node.id == "bookmarksMenuPopup" || node.id == "goPopup")
|
|
|
|
return;
|
|
|
|
|
|
|
|
node = node.parentNode;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (window.XULBrowserWindow) {
|
|
|
|
var nodeItem = event.target.node;
|
|
|
|
if (nodeItem && PlacesUtils.nodeIsURI(nodeItem))
|
|
|
|
window.XULBrowserWindow.setOverLink(nodeItem.uri, null);
|
|
|
|
}
|
|
|
|
]]></handler>
|
|
|
|
<handler event="DOMMenuItemInactive"><![CDATA[
|
|
|
|
var node = event.target;
|
|
|
|
if (node.parentNode != this)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (window.XULBrowserWindow)
|
|
|
|
window.XULBrowserWindow.setOverLink("", null);
|
|
|
|
]]></handler>
|
2008-02-20 18:17:52 -08:00
|
|
|
<handler event="draggesture" action="if (event.target.node) nsDragAndDrop.startDrag(event, this);"/>
|
|
|
|
<handler event="dragdrop" action="nsDragAndDrop.drop(event, this);"/>
|
|
|
|
<handler event="dragover" action="nsDragAndDrop.dragOver(event, this);"/>
|
|
|
|
<handler event="dragexit" action="nsDragAndDrop.dragExit(event, this);"/>
|
|
|
|
</handlers>
|
|
|
|
</binding>
|
|
|
|
|
|
|
|
|
|
|
|
<binding id="places-menupopup"
|
|
|
|
extends="chrome://browser/content/places/menu.xml#places-popup-base">
|
2007-03-22 10:30:00 -07:00
|
|
|
<implementation>
|
|
|
|
<destructor><![CDATA[
|
2007-05-19 13:29:48 -07:00
|
|
|
this._resultNode = null;
|
2007-06-15 18:53:06 -07:00
|
|
|
if (this._result) {
|
|
|
|
this._result.viewer = null;
|
|
|
|
this._result = null;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></destructor>
|
|
|
|
|
2007-10-12 17:27:31 -07:00
|
|
|
<field name="_initialized">false</field>
|
|
|
|
<method name="_ensureInitialized">
|
2007-03-22 10:30:00 -07:00
|
|
|
<body><![CDATA[
|
2007-10-12 17:27:31 -07:00
|
|
|
if (this._initialized)
|
|
|
|
return;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
this._controller = new PlacesController(this);
|
|
|
|
this.controllers.appendController(this._controller);
|
|
|
|
|
|
|
|
// This function should only be called for top-level menus like the bookmarks menu.
|
|
|
|
// Submenus get their _result and _resultNode from their parents.
|
|
|
|
if (this.hasAttribute("place")) {
|
2007-09-16 18:45:16 -07:00
|
|
|
// Do the initial build.
|
2007-03-22 10:30:00 -07:00
|
|
|
this.place = this.place;
|
|
|
|
}
|
2007-10-12 17:27:31 -07:00
|
|
|
this._initialized = true;
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<property name="controller"
|
|
|
|
readonly="true"
|
|
|
|
onget="return this._controller;"/>
|
|
|
|
|
|
|
|
<method name="onPopupShowing">
|
2007-10-24 19:02:28 -07:00
|
|
|
<parameter name="aEvent"/>
|
2007-03-22 10:30:00 -07:00
|
|
|
<body><![CDATA[
|
2007-10-24 19:02:28 -07:00
|
|
|
var popup = aEvent.target;
|
|
|
|
var resultNode = popup._resultNode;
|
2008-03-12 04:08:08 -07:00
|
|
|
if (!resultNode.containerOpen)
|
|
|
|
resultNode.containerOpen = true;
|
2007-10-24 19:02:28 -07:00
|
|
|
if (!popup._built)
|
|
|
|
this._rebuild(popup);
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
2007-09-16 18:45:16 -07:00
|
|
|
|
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[
|
2007-10-24 19:02:28 -07:00
|
|
|
this._ensureInitialized();
|
2007-03-22 10:30:00 -07:00
|
|
|
return this._resultNode;
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
2007-06-15 18:53:06 -07:00
|
|
|
<method name="removeItem">
|
|
|
|
<parameter name="child"/>
|
|
|
|
<body><![CDATA[
|
|
|
|
if (PlacesUtils.nodeIsContainer(child.node)) {
|
|
|
|
for (var i=0; i < this._containerNodesMap.length; i++) {
|
2007-10-24 19:02:28 -07:00
|
|
|
if (this._containerNodesMap[i].resultNode == child.node) {
|
2007-06-15 18:53:06 -07:00
|
|
|
this._containerNodesMap.splice(i, 1);
|
2007-10-24 19:02:28 -07:00
|
|
|
break;
|
|
|
|
}
|
2007-06-15 18:53:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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;
|
2007-10-24 19:02:28 -07:00
|
|
|
child.parentNode.removeChild(child);
|
2007-06-15 18:53:06 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="insertNewItem">
|
2007-10-24 19:02:28 -07:00
|
|
|
<parameter name="aChild"/>
|
|
|
|
<parameter name="aParentPopup"/>
|
|
|
|
<parameter name="aBefore"/>
|
2007-06-15 18:53:06 -07:00
|
|
|
<body><![CDATA[
|
2007-10-24 19:02:28 -07:00
|
|
|
var element =
|
2008-03-13 12:25:49 -07:00
|
|
|
PlacesUIUtils.createMenuItemForNode(aChild, this._containerNodesMap);
|
2007-10-24 19:02:28 -07:00
|
|
|
|
|
|
|
if (aBefore)
|
|
|
|
aParentPopup.insertBefore(element, aBefore);
|
|
|
|
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)
|
|
|
|
aParentPopup.insertBefore(element,
|
2008-03-13 05:31:59 -07:00
|
|
|
aParentPopup.childNodes[aParentPopup._endMarker++]);
|
2007-10-24 19:02:28 -07:00
|
|
|
else
|
|
|
|
aParentPopup.appendChild(element);
|
2007-06-15 18:53:06 -07:00
|
|
|
}
|
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
2007-09-16 18:45:16 -07:00
|
|
|
<method name="_showEmptyMenuItem">
|
2007-10-24 19:02:28 -07:00
|
|
|
<parameter name="aPopup"/>
|
2007-09-16 18:45:16 -07:00
|
|
|
<body><![CDATA[
|
2007-10-24 19:02:28 -07:00
|
|
|
if (aPopup._emptyMenuItem) {
|
|
|
|
aPopup._emptyMenuItem.hidden = false;
|
2007-09-16 18:45:16 -07:00
|
|
|
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);
|
2007-09-16 18:45:16 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<method name="_rebuild">
|
2007-10-24 19:02:28 -07:00
|
|
|
<parameter name="aPopup"/>
|
2007-03-22 10:30:00 -07:00
|
|
|
<body><![CDATA[
|
2008-03-13 12:25:49 -07:00
|
|
|
PlacesUIUtils.cleanPlacesPopup(aPopup);
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
var cc = aPopup._resultNode.childCount;
|
2007-03-22 10:30:00 -07:00
|
|
|
if (cc > 0) {
|
2007-10-24 19:02:28 -07:00
|
|
|
if (aPopup._emptyMenuItem)
|
|
|
|
aPopup._emptyMenuItem.hidden = true;
|
2007-09-16 18:45:16 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
for (var i = 0; i < cc; ++i) {
|
2007-10-24 19:02:28 -07:00
|
|
|
var child = aPopup._resultNode.getChild(i);
|
|
|
|
this.insertNewItem(child, aPopup, null);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2007-06-15 18:53:06 -07:00
|
|
|
}
|
|
|
|
else {
|
2007-03-22 10:30:00 -07:00
|
|
|
// This menu is empty. If there is no static content, add
|
|
|
|
// an element to show it is empty.
|
2007-10-24 19:02:28 -07:00
|
|
|
if (aPopup._startMarker == -1 && aPopup._endMarker == -1)
|
|
|
|
this._showEmptyMenuItem(aPopup);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2007-10-24 19:02:28 -07:00
|
|
|
aPopup._built = true;
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
2007-06-15 18:53:06 -07:00
|
|
|
|
|
|
|
<!-- nsINavHistoryResultViewer -->
|
|
|
|
<field name="_viewer"><![CDATA[({
|
|
|
|
_self: this,
|
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
_getPopupForContainer:
|
|
|
|
function PMV__getPopupForContainer(aNode) {
|
|
|
|
if (this._self._resultNode == aNode)
|
|
|
|
return this._self;
|
|
|
|
|
2007-06-15 18:53:06 -07:00
|
|
|
for (var i=0; i < this._self._containerNodesMap.length; i++) {
|
2007-10-24 19:02:28 -07:00
|
|
|
if (this._self._containerNodesMap[i].resultNode == aNode)
|
|
|
|
return this._self._containerNodesMap[i].domNode;
|
2007-06-15 18:53:06 -07:00
|
|
|
}
|
2007-06-20 00:27:41 -07:00
|
|
|
throw("Container view not found");
|
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) {
|
2008-02-19 18:08:25 -08:00
|
|
|
// some methods (e.g. getURLsFromContainer) temporarily null out the
|
|
|
|
// viewer when they do temporary changes to the view, this does _not_
|
|
|
|
// call setResult(null), but then, we're called again with the result
|
|
|
|
// object which is already set for this viewer. At that point,
|
|
|
|
// we should do nothing.
|
|
|
|
if (this._self._result != val) {
|
|
|
|
this._built = false;
|
|
|
|
this._self._containerNodesMap = [];
|
|
|
|
this._self._resultNode = val.root;
|
|
|
|
this._self._result = val;
|
|
|
|
}
|
|
|
|
return val;
|
2008-01-29 12:04:43 -08:00
|
|
|
},
|
|
|
|
|
2007-06-15 18:53:06 -07:00
|
|
|
itemInserted: function PMV_itemInserted(aParentNode, aNode, aIndex) {
|
2007-10-24 19:02:28 -07:00
|
|
|
var popup = this._getPopupForContainer(aParentNode);
|
|
|
|
if (!popup._built)
|
2007-06-28 13:33:21 -07:00
|
|
|
return;
|
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
var index = popup._startMarker + 1 + aIndex;
|
|
|
|
var before = popup.childNodes[index] || null;
|
|
|
|
this._self.insertNewItem(aNode, popup, before);
|
|
|
|
if (popup._emptyMenuItem)
|
|
|
|
popup._emptyMenuItem.hidden = true;
|
2007-06-15 18:53:06 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
itemRemoved: function PMV_itemRemoved(aParentNode, aNode, aIndex) {
|
2007-10-24 19:02:28 -07:00
|
|
|
var popup = this._getPopupForContainer(aParentNode);
|
|
|
|
if (!popup._built)
|
2007-06-28 13:33:21 -07:00
|
|
|
return;
|
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
var children = popup.childNodes;
|
|
|
|
for (var i = 0; i < children.length; i++) {
|
|
|
|
if (children[i].node == aNode) {
|
|
|
|
this._self.removeItem(children[i]);
|
|
|
|
if (!popup.hasChildNodes() ||
|
|
|
|
(popup.childNodes.length == 1 &&
|
|
|
|
popup.firstChild == popup._emptyMenuItem)) {
|
|
|
|
this._self._showEmptyMenuItem(popup);
|
2007-06-15 18:53:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2007-12-28 18:59:22 -08:00
|
|
|
itemMoved:
|
|
|
|
function PMV_itemMoved(aItem, aOldParent, aOldIndex, aNewParent,
|
|
|
|
aNewIndex) {
|
|
|
|
// This cannot actually happen yet (see IDL)
|
2008-01-08 22:21:09 -08:00
|
|
|
if (aNewParent != aOldParent)
|
2007-12-28 18:59:22 -08:00
|
|
|
return;
|
|
|
|
|
|
|
|
var popup = this._getPopupForContainer(aNewParent);
|
|
|
|
var index = popup._startMarker + 1 + aNewIndex;
|
|
|
|
var children = popup.childNodes;
|
|
|
|
for (var i = 0; i < children.length; i++) {
|
|
|
|
var menuItem = children[i];
|
|
|
|
if (menuItem.node == aItem) {
|
|
|
|
popup.removeChild(menuItem);
|
|
|
|
popup.insertBefore(menuItem, children[index]);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2007-06-15 18:53:06 -07:00
|
|
|
itemChanged: function PMV_itemChanged(aNode) {
|
|
|
|
// this check can be removed once we fix bug #382397
|
|
|
|
var parentNode = aNode.parent;
|
|
|
|
if (!parentNode)
|
|
|
|
return;
|
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
var popup = this._getPopupForContainer(parentNode);
|
|
|
|
if (!popup._built)
|
2007-06-15 18:53:06 -07:00
|
|
|
return;
|
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
var children = popup.childNodes;
|
2007-06-15 18:53:06 -07:00
|
|
|
var menuitem;
|
|
|
|
for (var i = 0; i < children.length; i++) {
|
|
|
|
if (children[i].node == aNode) {
|
|
|
|
menuitem = children[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PlacesUtils.nodeIsSeparator(aNode)) {
|
|
|
|
// nothing to do when a separator changes
|
|
|
|
return;
|
2007-09-16 18:45:16 -07:00
|
|
|
}
|
2007-06-15 18:53:06 -07:00
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
var iconURI = aNode.icon;
|
2007-10-30 17:15:55 -07:00
|
|
|
if (iconURI) {
|
|
|
|
var spec = iconURI.spec;
|
|
|
|
if (menuitem.getAttribute("image") != spec)
|
|
|
|
menuitem.setAttribute("image", spec);
|
|
|
|
}
|
2007-06-15 18:53:06 -07:00
|
|
|
else
|
|
|
|
menuitem.removeAttribute("image");
|
|
|
|
|
2008-03-13 12:25:49 -07:00
|
|
|
var title = PlacesUIUtils.getBestTitle(aNode);
|
2007-06-15 18:53:06 -07:00
|
|
|
if (menuitem.getAttribute("label") != title)
|
|
|
|
menuitem.setAttribute("label", title);
|
2007-11-19 18:01:53 -08:00
|
|
|
|
|
|
|
if (!menuitem.hasAttribute("livemark") &&
|
|
|
|
PlacesUtils.nodeIsLivemarkContainer(aNode))
|
2007-12-02 17:52:32 -08:00
|
|
|
menuitem.setAttribute("livemark", "true");
|
2007-06-15 18:53:06 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
itemReplaced:
|
|
|
|
function PMV_itemReplaced(aParentNode, aOldNode, aNewNode, aIndex) {
|
2007-10-24 19:02:28 -07:00
|
|
|
var popup = this._getPopupForContainer(aParentNode);
|
|
|
|
if (!popup._built)
|
2007-06-28 13:33:21 -07:00
|
|
|
return;
|
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
var children = popup.childNodes;
|
|
|
|
for (var i = 0; i < children.length; i++) {
|
|
|
|
if (children[i].node == aOldNode) {
|
|
|
|
var next = children[i].nextSibling;
|
|
|
|
this._self.removeItem(children[i]);
|
|
|
|
this._self.insertNewItem(aNewNode, popup, next);
|
|
|
|
return;
|
2007-06-15 18:53:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
containerOpened: function PMV_containerOpened(aNode) {
|
2007-06-27 23:50:46 -07:00
|
|
|
this.invalidateContainer(aNode);
|
2007-06-15 18:53:06 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
containerClosed: function PMV_containerClosed(aNode) {
|
2007-06-27 23:50:46 -07:00
|
|
|
this.invalidateContainer(aNode);
|
2007-06-15 18:53:06 -07:00
|
|
|
},
|
2007-10-10 23:42:38 -07:00
|
|
|
|
2007-06-27 23:50:46 -07:00
|
|
|
invalidateContainer: function PMV_invalidateContainer(aContainer) {
|
2007-06-28 13:33:21 -07:00
|
|
|
if (!this._self._built)
|
|
|
|
return;
|
|
|
|
|
2007-06-27 23:50:46 -07:00
|
|
|
function isChildOf(node, container) {
|
|
|
|
var parent = node.parent;
|
|
|
|
while (parent) {
|
|
|
|
if (parent == container)
|
|
|
|
return true;
|
|
|
|
parent = parent.parent;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
var popupToRebuild = null;
|
2007-06-27 23:50:46 -07:00
|
|
|
for (var i=0; i < this._self._containerNodesMap.length; i++) {
|
|
|
|
var node = this._self._containerNodesMap[i].resultNode;
|
2007-09-16 18:45:16 -07:00
|
|
|
|
2007-06-27 23:50:46 -07:00
|
|
|
if (node == aContainer)
|
2007-10-24 19:02:28 -07:00
|
|
|
popupToRebuild = this._self._containerNodesMap[i].domNode;
|
|
|
|
if (isChildOf(node, aContainer)) {
|
2007-06-27 23:50:46 -07:00
|
|
|
this._self._containerNodesMap.splice(i,1);
|
2007-10-24 19:02:28 -07:00
|
|
|
i--;
|
|
|
|
}
|
2007-06-27 23:50:46 -07:00
|
|
|
}
|
2007-09-16 18:45:16 -07:00
|
|
|
|
2007-10-24 19:02:28 -07:00
|
|
|
if (popupToRebuild)
|
|
|
|
popupToRebuild._built = false;
|
|
|
|
else
|
|
|
|
this._self._built = false;
|
2007-06-15 18:53:06 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
invalidateAll: function PMV_invalidateAll() {
|
2007-06-27 23:50:46 -07:00
|
|
|
this._self._containerNodesMap.splice(0);
|
2007-06-28 13:33:21 -07:00
|
|
|
this._self._built = false;
|
2007-06-15 18:53:06 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
sortingChanged: function PMV_sortingChanged(aSortingMode) {
|
|
|
|
}
|
|
|
|
})]]></field>
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<!-- nsIPlacesView -->
|
|
|
|
<property name="place">
|
|
|
|
<getter><![CDATA[
|
|
|
|
return this.getAttribute("place");
|
|
|
|
]]></getter>
|
2007-06-16 20:14:08 -07:00
|
|
|
<setter><![CDATA[
|
2007-03-22 10:30:00 -07:00
|
|
|
this.setAttribute("place", val);
|
|
|
|
var queries = { }, options = { };
|
|
|
|
PlacesUtils.history.queryStringToQueries(val, queries, { }, options);
|
2007-09-16 18:45:16 -07:00
|
|
|
if (!queries.value.length)
|
2007-03-22 10:30:00 -07:00
|
|
|
queries.value = [PlacesUtils.history.getNewQuery()];
|
2008-01-29 12:04:43 -08:00
|
|
|
var result =
|
2007-03-22 10:30:00 -07:00
|
|
|
PlacesUtils.history.executeQueries(queries.value,
|
|
|
|
queries.value.length,
|
|
|
|
options.value);
|
2008-01-29 12:04:43 -08:00
|
|
|
result.viewer = this._viewer;
|
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">
|
2007-09-16 18:45:16 -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">
|
2007-09-16 18:45:16 -07:00
|
|
|
<body><![CDATA[
|
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 -->
|
|
|
|
<method name="getDragableSelection">
|
|
|
|
<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">
|
2007-09-16 18:45:16 -07:00
|
|
|
<getter><![CDATA[
|
2008-02-25 13:45:22 -08:00
|
|
|
if (this._contextMenuShown) {
|
|
|
|
var popupNode = document.popupNode;
|
|
|
|
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">
|
2007-09-16 18:45:16 -07:00
|
|
|
<getter><![CDATA[
|
|
|
|
// 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;
|
2007-03-22 10:30:00 -07:00
|
|
|
var folderId = 0;
|
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;
|
|
|
|
|
|
|
|
if (PlacesUtils.nodeIsFolder(this._resultNode)) {
|
2008-01-25 11:01:18 -08:00
|
|
|
folderId = PlacesUtils.getConcreteItemId(this._resultNode);
|
2008-04-11 09:22:01 -07:00
|
|
|
isTag = PlacesUtils.nodeIsTagQuery(this._resultNode);
|
|
|
|
}
|
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;
|
|
|
|
if (popupNode == popupNode.parentNode._emptyMenuItem) {
|
|
|
|
// If (empty) menuitem is selected the insertion point
|
|
|
|
// is inside the folder, at the end.
|
2008-02-25 13:45:22 -08:00
|
|
|
folderId = PlacesUtils.getConcreteItemId(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-02-25 13:45:22 -08:00
|
|
|
folderId = PlacesUtils.getConcreteItemId(selectedNode.parent);
|
2008-04-11 09:22:01 -07:00
|
|
|
index = PlacesUtils.getIndexOfNode(selectedNode);
|
|
|
|
isTag = PlacesUtils.nodeIsTagQuery(selectedNode.parent);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
2008-04-28 02:33:40 -07:00
|
|
|
return new InsertionPoint(folderId, 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">
|
2008-02-25 13:45:22 -08:00
|
|
|
<body/>
|
2007-03-22 10:30:00 -07:00
|
|
|
</method>
|
2007-03-22 16:43:56 -07:00
|
|
|
|
2008-02-21 11:50:22 -08:00
|
|
|
<method name="selectItems">
|
2008-02-25 13:45:22 -08:00
|
|
|
<body/>
|
2008-02-21 11:50:22 -08:00
|
|
|
</method>
|
|
|
|
|
2007-06-15 18:53:06 -07:00
|
|
|
<property name="selType" readonly="true" onget="return 'single';"/>
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
<method name="buildContextMenu">
|
|
|
|
<parameter name="aPopup"/>
|
|
|
|
<body><![CDATA[
|
2007-10-12 17:27:31 -07:00
|
|
|
this._ensureInitialized();
|
2008-02-25 13:45:22 -08:00
|
|
|
this._contextMenuShown = true;
|
2007-03-22 10:30:00 -07:00
|
|
|
this.focus();
|
2008-04-04 11:01:15 -07:00
|
|
|
var show = this.controller.buildContextMenu(aPopup);
|
|
|
|
if (show) {
|
|
|
|
// disable the Delete command if the selection isn't explicit
|
|
|
|
if (document.popupNode && document.popupNode.localName == "menupopup")
|
|
|
|
document.getElementById("cmd_delete").setAttribute("disabled", "true");
|
2008-04-06 12:41:08 -07:00
|
|
|
return true;
|
2008-04-04 11:01:15 -07:00
|
|
|
}
|
|
|
|
return false;
|
2007-03-22 10:30:00 -07:00
|
|
|
]]></body>
|
|
|
|
</method>
|
|
|
|
|
|
|
|
<method name="destroyContextMenu">
|
|
|
|
<parameter name="aPopup"/>
|
|
|
|
<body>
|
|
|
|
<![CDATA[
|
2008-02-25 13:45:22 -08:00
|
|
|
this._contextMenuShown = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
if (window.content)
|
|
|
|
window.content.focus();
|
|
|
|
]]>
|
|
|
|
</body>
|
|
|
|
</method>
|
|
|
|
</implementation>
|
|
|
|
<handlers>
|
2008-02-20 18:17:52 -08:00
|
|
|
<handler event="popupshowing" phase="capturing"><![CDATA[
|
2007-10-24 19:02:28 -07:00
|
|
|
this._ensureInitialized();
|
2008-03-17 04:33:16 -07:00
|
|
|
var popup = event.target;
|
2008-03-17 04:38:17 -07:00
|
|
|
// Avoid handling popupshowing of inner views
|
2008-03-17 04:33:16 -07:00
|
|
|
if (!popup._resultNode || PlacesUIUtils.getViewForNode(popup) != this)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this.onPopupShowing(event);
|
2008-02-20 18:17:52 -08:00
|
|
|
]]></handler>
|
2007-06-18 17:16:09 -07:00
|
|
|
|
2008-02-20 18:17:52 -08:00
|
|
|
<handler event="popuphidden"><![CDATA[
|
2007-10-24 19:02:28 -07:00
|
|
|
var popup = event.target;
|
2008-03-17 04:33:16 -07:00
|
|
|
// We should avoid to handle events of inner views
|
|
|
|
if (!popup._resultNode || PlacesUIUtils.getViewForNode(popup) != this)
|
2007-06-15 18:53:06 -07:00
|
|
|
return;
|
|
|
|
|
2007-06-28 13:33:21 -07:00
|
|
|
// UI performance: folder queries are cheap, keep the resultnode open
|
|
|
|
// so we don't rebuild its contents whenever the popup is reopened.
|
2007-10-24 19:02:28 -07:00
|
|
|
if (!PlacesUtils.nodeIsFolder(popup._resultNode))
|
|
|
|
popup._resultNode.containerOpen = false;
|
2007-06-15 18:53:06 -07:00
|
|
|
|
|
|
|
// The autoopened attribute is set for folders which have been
|
|
|
|
// automatically opened when dragged over. Turn off this attribute
|
|
|
|
// when the folder closes because it is no longer applicable.
|
2007-10-24 19:02:28 -07:00
|
|
|
popup.removeAttribute("autoopened");
|
2008-02-20 18:17:52 -08:00
|
|
|
]]></handler>
|
2007-03-22 10:30:00 -07:00
|
|
|
</handlers>
|
|
|
|
</binding>
|
|
|
|
|
|
|
|
</bindings>
|