зеркало из https://github.com/mozilla/pjs.git
Bug 458233 - Use the new D&D API in Places Toolbar. r=Marco Bonardo.
This commit is contained in:
Родитель
fde27110d2
Коммит
476cd861ae
|
@ -87,7 +87,7 @@
|
|||
</xul:hbox>
|
||||
</content>
|
||||
|
||||
<implementation>
|
||||
<implementation implements="nsIAccessibleProvider, nsITimerCallback">
|
||||
<constructor><![CDATA[
|
||||
this._init();
|
||||
]]></constructor>
|
||||
|
@ -144,8 +144,8 @@
|
|||
<method name="_rebuild">
|
||||
<body><![CDATA[
|
||||
// Clear out references to existing nodes, since we'll be deleting and re-adding.
|
||||
if (this._DNDObserver._overFolder.node)
|
||||
this._DNDObserver._clearOverFolder();
|
||||
if (this._overFolder.node)
|
||||
this._clearOverFolder();
|
||||
this._openedMenuButton = null;
|
||||
|
||||
while (this.hasChildNodes())
|
||||
|
@ -701,323 +701,6 @@
|
|||
}
|
||||
})]]></field>
|
||||
|
||||
<field name="_DNDObserver"><![CDATA[({
|
||||
// Inside the _DNDObserver object's functions, this points to
|
||||
// the _DNDObserver object. _self points to the toolbar xbl object.
|
||||
_self: this,
|
||||
|
||||
// Menu buttons 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.
|
||||
_overFolder: {node: null,
|
||||
openTimer: null,
|
||||
hoverTime: 350,
|
||||
closeTimer: null},
|
||||
|
||||
// timer for turning of indicator bar, to get rid of flicker
|
||||
_ibTimer: null,
|
||||
|
||||
_setTimer: function TBV_DO_setTimer(time) {
|
||||
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
timer.initWithCallback(this, time, timer.TYPE_ONE_SHOT);
|
||||
return timer;
|
||||
},
|
||||
|
||||
// Function to process all timer notifications.
|
||||
notify: function TBV_DO_notify(timer) {
|
||||
// Timer to turn off indicator bar.
|
||||
if (timer == this._ibTimer) {
|
||||
ib = this._self._dropIndicatorBar.removeAttribute('dragging');
|
||||
this._ibTimer = null;
|
||||
}
|
||||
|
||||
// Timer to open a menubutton that's being dragged over.
|
||||
if (timer == this._overFolder.openTimer) {
|
||||
// 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.
|
||||
if (timer == this._overFolder.closeTimer) {
|
||||
// Only close the menubutton if the drag session isn't currently 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.)
|
||||
var currentNode = PlacesControllerDragHelper.currentDropTarget;
|
||||
var inHierarchy = false;
|
||||
while (currentNode) {
|
||||
if (currentNode == this._self) {
|
||||
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();
|
||||
}
|
||||
},
|
||||
|
||||
// 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.
|
||||
_clearOverFolder: function TBV_DO_clearOverFolder() {
|
||||
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;
|
||||
}
|
||||
},
|
||||
|
||||
// This function returns information about where to drop when
|
||||
// dragging over this menu--insertion point, child index to drop
|
||||
// before, and folder to drop into.
|
||||
_getDropPoint: function TBV_DO_getDropPoint(event) {
|
||||
// Can't drop if the toolbar isn't a folder.
|
||||
var result = this._self.getResult();
|
||||
if (!PlacesUtils.nodeIsFolder(result.root))
|
||||
return null;
|
||||
|
||||
var isRTL = document.defaultView
|
||||
.getComputedStyle(this._self.parentNode, "")
|
||||
.direction == "rtl";
|
||||
|
||||
var dropPoint = { ip: null, beforeIndex: null, folderNode: null };
|
||||
// Loop through all the nodes to see which one this should
|
||||
// get dropped in/next to
|
||||
for (var i = 0; i < this._self.childNodes.length; i++) {
|
||||
var xulNode = this._self.childNodes[i];
|
||||
if (PlacesUtils.nodeIsFolder(xulNode.node) &&
|
||||
!PlacesUtils.nodeIsReadOnly(xulNode.node)) {
|
||||
// This is a folder. If the mouse is in the left 25% of the
|
||||
// node (or 25% of the right, in RTL UI), drop before the folder.
|
||||
// If it's in the middle 50%, drop into the folder. If it's past
|
||||
// that, drop after.
|
||||
if ((isRTL && event.clientX > xulNode.boxObject.x +
|
||||
(xulNode.boxObject.width * 0.75)) ||
|
||||
(!isRTL && event.clientX < xulNode.boxObject.x +
|
||||
(xulNode.boxObject.width * 0.25))) {
|
||||
// Drop to the left of this folder.
|
||||
dropPoint.ip =
|
||||
new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
|
||||
i, -1);
|
||||
dropPoint.beforeIndex = i;
|
||||
return dropPoint;
|
||||
}
|
||||
else if ((isRTL && event.clientX > xulNode.boxObject.x +
|
||||
(xulNode.boxObject.width * 0.25)) ||
|
||||
(!isRTL && event.clientX < xulNode.boxObject.x +
|
||||
(xulNode.boxObject.width * 0.75))) {
|
||||
// Drop inside this folder.
|
||||
dropPoint.ip =
|
||||
new InsertionPoint(PlacesUtils.getConcreteItemId(xulNode.node),
|
||||
-1, 1,
|
||||
PlacesUtils.nodeIsTagQuery(xulNode.node));
|
||||
dropPoint.beforeIndex = i;
|
||||
dropPoint.folderNode = xulNode;
|
||||
return dropPoint;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is a non-folder node. If the mouse is left (or right, in
|
||||
// RTL UI) of the middle, drop before the folder. Otehrwise,
|
||||
// we'll drop after
|
||||
if ((isRTL && event.clientX > xulNode.boxObject.x + (xulNode.boxObject.width / 2)) ||
|
||||
(!isRTL && event.clientX < xulNode.boxObject.x + (xulNode.boxObject.width / 2))) {
|
||||
// Drop before this bookmark.
|
||||
dropPoint.ip =
|
||||
new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
|
||||
i, -1);
|
||||
dropPoint.beforeIndex = i;
|
||||
return dropPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Should drop after the last node.
|
||||
dropPoint.ip =
|
||||
new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
|
||||
-1, 1);
|
||||
dropPoint.beforeIndex = -1;
|
||||
return dropPoint;
|
||||
},
|
||||
|
||||
onDragStart: function TBV_DO_onDragStart(aEvent, aXferData, aDragAction) {
|
||||
var draggedXulNode = aEvent.target;
|
||||
// sub menus have their own d&d handlers
|
||||
if (draggedXulNode.parentNode != this._self)
|
||||
return false;
|
||||
|
||||
if (draggedXulNode.localName == "toolbarbutton" &&
|
||||
draggedXulNode.getAttribute("type") == "menu") {
|
||||
#ifdef XP_WIN
|
||||
// Support folder dragging on the personal toolbar when the user
|
||||
// holds the "alt" or "shift" key while dragging.
|
||||
// Ctrl+drag is Copy
|
||||
if (!aEvent.shiftKey && !aEvent.altKey && !aEvent.ctrlKey)
|
||||
return false;
|
||||
#else
|
||||
// Support folder dragging on the personal toolbar when the user
|
||||
// holds the "shift" key while dragging
|
||||
// Ctrl+drag is Copy
|
||||
if (!aEvent.shiftKey && !aEvent.ctrlKey)
|
||||
return false;
|
||||
#endif
|
||||
draggedXulNode.firstChild.hidePopup();
|
||||
}
|
||||
|
||||
// activate the view and cache the dragged node
|
||||
this._self._draggedNode = draggedXulNode.node;
|
||||
this._self.focus();
|
||||
|
||||
this._self._controller.setDataTransfer(aEvent);
|
||||
return true;
|
||||
},
|
||||
|
||||
canDrop: function TBV_DO_canDrop(aEvent, aDragSession) {
|
||||
// Cache the dataTransfer
|
||||
PlacesControllerDragHelper.currentDataTransfer = aEvent.dataTransfer;
|
||||
|
||||
var ip = this._self.insertionPoint;
|
||||
return ip && PlacesControllerDragHelper.canDrop(ip);
|
||||
},
|
||||
|
||||
onDragOver: function TBV_DO_onDragOver(event, flavor, session) {
|
||||
PlacesControllerDragHelper.currentDropTarget = event.target;
|
||||
var dropPoint = this._getDropPoint(event);
|
||||
|
||||
var ib = this._self._dropIndicatorBar;
|
||||
if (this._ibTimer) {
|
||||
this._ibTimer.cancel();
|
||||
this._ibTimer = null;
|
||||
}
|
||||
|
||||
if (dropPoint.folderNode ||
|
||||
event.originalTarget == this._self._chevron) {
|
||||
// Dropping over a menubutton or chevron button
|
||||
// set styles and timer to open relative menupopup
|
||||
var overNode = dropPoint.folderNode || this._self._chevron;
|
||||
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");
|
||||
|
||||
ib.removeAttribute("dragging");
|
||||
}
|
||||
else {
|
||||
// Dragging over a normal toolbarbutton,
|
||||
// show indicator bar and move it to the appropriate drop point.
|
||||
if (!ib.hasAttribute("dragging"))
|
||||
ib.setAttribute("dragging", "true");
|
||||
var ind = ib.firstChild;
|
||||
var halfInd = ind.boxObject.width / 2;
|
||||
var direction = document.defaultView.getComputedStyle(this._self.parentNode, "").direction;
|
||||
if (direction == "ltr") {
|
||||
halfInd = Math.ceil(halfInd);
|
||||
if (!this._self.childNodes.length)
|
||||
ind.style.marginLeft = 0 - this._self.boxObject.x - halfInd + 'px'
|
||||
else if (dropPoint.beforeIndex == -1)
|
||||
ind.style.marginLeft = this._self.lastChild.boxObject.x +
|
||||
this._self.lastChild.boxObject.width - this._self.boxObject.x - halfInd + 'px';
|
||||
else
|
||||
ind.style.marginLeft = this._self.childNodes[dropPoint.beforeIndex].boxObject.x -
|
||||
this._self.boxObject.x - halfInd + 'px';
|
||||
}
|
||||
else {
|
||||
halfInd = Math.floor(halfInd);
|
||||
if (this._self.childNodes.length == 0)
|
||||
ind.style.marginRight = this._self.boxObject.width + 'px';
|
||||
else if (dropPoint.beforeIndex == -1) {
|
||||
ind.style.marginRight = this._self.boxObject.width -
|
||||
(this._self.childNodes[this._self.childNodes.length - 1].boxObject.x +
|
||||
halfInd) +'px';
|
||||
}
|
||||
else {
|
||||
ind.style.marginRight = this._self.boxObject.width -
|
||||
(this._self.childNodes[dropPoint.beforeIndex].boxObject.x +
|
||||
this._self.childNodes[dropPoint.beforeIndex].boxObject.width -
|
||||
this._self.boxObject.x + halfInd) + 'px';
|
||||
}
|
||||
}
|
||||
// Clear out old folder information
|
||||
this._clearOverFolder();
|
||||
}
|
||||
},
|
||||
|
||||
onDrop: function TBV_DO_onDrop(event, dropData, session) {
|
||||
// Cache the dataTransfer
|
||||
PlacesControllerDragHelper.currentDataTransfer = event.dataTransfer;
|
||||
|
||||
var dropPoint = this._getDropPoint(event);
|
||||
if (!dropPoint)
|
||||
return;
|
||||
PlacesControllerDragHelper.onDrop(dropPoint.ip);
|
||||
},
|
||||
|
||||
onDragExit: function TBV_DO_onDragExit(event, session) {
|
||||
PlacesControllerDragHelper.currentDropTarget = null;
|
||||
PlacesControllerDragHelper.currentDataTransfer = null;
|
||||
|
||||
// Set timer to turn off indicator bar (if we turn it off
|
||||
// here, dragenter might be called immediately after, creating
|
||||
// flicker.)
|
||||
if (this._ibTimer)
|
||||
this._ibTimer.cancel();
|
||||
this._ibTimer = this._setTimer(10);
|
||||
// Close any folder being hovered over
|
||||
if (this._overFolder.node)
|
||||
this._overFolder.closeTimer = this._setTimer(this._overFolder.hoverTime);
|
||||
|
||||
this._self._draggedNode = null;
|
||||
},
|
||||
|
||||
getSupportedFlavours: function TBV_DO_getSupportedFlavours() {
|
||||
return PlacesControllerDragHelper.flavourSet;
|
||||
}
|
||||
})]]></field>
|
||||
|
||||
<method name="checkForMenuEvent">
|
||||
<parameter name="event"/>
|
||||
<parameter name="action"/>
|
||||
<body><![CDATA[
|
||||
// It seems that even if the menu drag/drop event
|
||||
// handlers set their phase to capturing, toolbarbutton
|
||||
// menu events come to the toolbar first, and don't bubble.
|
||||
// So if this is a menu/menuitem, try to send the event to its
|
||||
// xbl handler.
|
||||
if (event.target.localName.indexOf("menu") == 0) {
|
||||
var parent = event.target.parentNode;
|
||||
// XULDocument has no getAttribute() function, so check for it before calling.
|
||||
while (parent && parent.getAttribute) {
|
||||
if (parent.getAttribute("type") == "places") {
|
||||
nsDragAndDrop[action](event, parent._DNDObserver);
|
||||
return true;
|
||||
}
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<property name="selType" onget="return 'single';"/>
|
||||
|
||||
<method name="buildContextMenu">
|
||||
|
@ -1133,6 +816,168 @@
|
|||
aPopup._built = true;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<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
|
||||
// dragging over this menu--insertion point, child index to drop
|
||||
// before, and folder to drop into.
|
||||
// Can't drop if the toolbar isn't a folder.
|
||||
var result = this.getResult();
|
||||
if (!PlacesUtils.nodeIsFolder(result.root))
|
||||
return null;
|
||||
|
||||
var isRTL = document.defaultView
|
||||
.getComputedStyle(this.parentNode, "")
|
||||
.direction == "rtl";
|
||||
|
||||
var dropPoint = { ip: null, beforeIndex: null, folderNode: null };
|
||||
// Loop through all the nodes to see which one this should
|
||||
// get dropped in/next to
|
||||
for (var i = 0; i < this.childNodes.length; i++) {
|
||||
var xulNode = this.childNodes[i];
|
||||
if (PlacesUtils.nodeIsFolder(xulNode.node) &&
|
||||
!PlacesUtils.nodeIsReadOnly(xulNode.node)) {
|
||||
// This is a folder. If the mouse is in the left 25% of the
|
||||
// node (or 25% of the right, in RTL UI), drop before the folder.
|
||||
// If it's in the middle 50%, drop into the folder. If it's past
|
||||
// that, drop after.
|
||||
if ((isRTL && aEvent.clientX > xulNode.boxObject.x +
|
||||
(xulNode.boxObject.width * 0.75)) ||
|
||||
(!isRTL && aEvent.clientX < xulNode.boxObject.x +
|
||||
(xulNode.boxObject.width * 0.25))) {
|
||||
// Drop to the left of this folder.
|
||||
dropPoint.ip =
|
||||
new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
|
||||
i, -1);
|
||||
dropPoint.beforeIndex = i;
|
||||
return dropPoint;
|
||||
}
|
||||
else if ((isRTL && aEvent.clientX > xulNode.boxObject.x +
|
||||
(xulNode.boxObject.width * 0.25)) ||
|
||||
(!isRTL && aEvent.clientX < xulNode.boxObject.x +
|
||||
(xulNode.boxObject.width * 0.75))) {
|
||||
// Drop inside this folder.
|
||||
dropPoint.ip =
|
||||
new InsertionPoint(PlacesUtils.getConcreteItemId(xulNode.node),
|
||||
-1, 1,
|
||||
PlacesUtils.nodeIsTagQuery(xulNode.node));
|
||||
dropPoint.beforeIndex = i;
|
||||
dropPoint.folderNode = xulNode;
|
||||
return dropPoint;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is a non-folder node. If the mouse is left (or right, in
|
||||
// RTL UI) of the middle, drop before the folder. Otehrwise,
|
||||
// we'll drop after
|
||||
if ((isRTL && aEvent.clientX > xulNode.boxObject.x + (xulNode.boxObject.width / 2)) ||
|
||||
(!isRTL && aEvent.clientX < xulNode.boxObject.x + (xulNode.boxObject.width / 2))) {
|
||||
// Drop before this bookmark.
|
||||
dropPoint.ip =
|
||||
new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
|
||||
i, -1);
|
||||
dropPoint.beforeIndex = i;
|
||||
return dropPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Should drop after the last node.
|
||||
dropPoint.ip =
|
||||
new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
|
||||
-1, 1);
|
||||
dropPoint.beforeIndex = -1;
|
||||
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.
|
||||
|
||||
// * Timer to turn off indicator bar.
|
||||
if (aTimer == this._ibTimer) {
|
||||
ib = this._dropIndicatorBar.removeAttribute('dragging');
|
||||
this._ibTimer = null;
|
||||
}
|
||||
|
||||
// * Timer to open a menubutton that's being dragged over.
|
||||
if (aTimer == this._overFolder.openTimer) {
|
||||
// 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.
|
||||
if (aTimer == this._overFolder.closeTimer) {
|
||||
// Only close the menubutton if the drag session isn't currently 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.)
|
||||
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>
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
|
@ -1142,26 +987,148 @@
|
|||
PlacesUtils.nodeIsURI(button.node))
|
||||
window.XULBrowserWindow.setOverLink(event.target.node.uri, null);
|
||||
]]></handler>
|
||||
|
||||
<handler event="mouseout"><![CDATA[
|
||||
window.XULBrowserWindow.setOverLink("", null);
|
||||
]]></handler>
|
||||
<handler event="draggesture"><![CDATA[
|
||||
if (event.target.localName == "toolbarbutton" ||
|
||||
event.target.localName == "toolbarseparator")
|
||||
nsDragAndDrop.startDrag(event, this._DNDObserver);
|
||||
|
||||
<handler event="dragstart"><![CDATA[
|
||||
// sub menus have their own d&d handlers
|
||||
var draggedDOMNode = event.target;
|
||||
if (draggedDOMNode.parentNode != this || !draggedDOMNode.node)
|
||||
return;
|
||||
|
||||
if (draggedDOMNode.localName == "toolbarbutton" &&
|
||||
draggedDOMNode.getAttribute("type") == "menu") {
|
||||
#ifdef XP_WIN
|
||||
// Support folder dragging on the personal toolbar when the user
|
||||
// holds the "alt" or "shift" key while dragging.
|
||||
// Ctrl+drag is Copy
|
||||
if (!event.shiftKey && !event.altKey && !event.ctrlKey)
|
||||
return;
|
||||
#else
|
||||
// Support folder dragging on the personal toolbar when the user
|
||||
// holds the "shift" key while dragging
|
||||
// Ctrl+drag is Copy
|
||||
if (!event.shiftKey && !event.ctrlKey)
|
||||
return;
|
||||
#endif
|
||||
draggedDOMNode.firstChild.hidePopup();
|
||||
}
|
||||
|
||||
// activate the view and cache the dragged node
|
||||
this._draggedNode = draggedDOMNode.node;
|
||||
this.focus();
|
||||
|
||||
this._controller.setDataTransfer(event);
|
||||
]]></handler>
|
||||
|
||||
<handler event="dragover"><![CDATA[
|
||||
if (!this.checkForMenuEvent(event, "dragOver"))
|
||||
nsDragAndDrop.dragOver(event, this._DNDObserver);
|
||||
// Cache the dataTransfer
|
||||
var dt = PlacesControllerDragHelper.currentDataTransfer =
|
||||
event.dataTransfer;
|
||||
|
||||
var ip = this.insertionPoint;
|
||||
if (!ip || !PlacesControllerDragHelper.canDrop(ip)) {
|
||||
ib.removeAttribute("dragging");
|
||||
return;
|
||||
}
|
||||
|
||||
PlacesControllerDragHelper.currentDropTarget = event.target;
|
||||
var dropPoint = this._getDropPoint(event);
|
||||
|
||||
if (this._ibTimer) {
|
||||
this._ibTimer.cancel();
|
||||
this._ibTimer = null;
|
||||
}
|
||||
|
||||
var ib = this._dropIndicatorBar;
|
||||
if (dropPoint.folderNode ||
|
||||
event.originalTarget == this._chevron) {
|
||||
// Dropping over a menubutton or chevron button
|
||||
// set styles and timer to open relative menupopup
|
||||
var overNode = dropPoint.folderNode || this._chevron;
|
||||
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");
|
||||
|
||||
ib.removeAttribute("dragging");
|
||||
}
|
||||
else {
|
||||
// Dragging over a normal toolbarbutton,
|
||||
// show indicator bar and move it to the appropriate drop point.
|
||||
if (!ib.hasAttribute("dragging"))
|
||||
ib.setAttribute("dragging", "true");
|
||||
var ind = ib.firstChild;
|
||||
var halfInd = ind.boxObject.width / 2;
|
||||
var direction = document.defaultView.getComputedStyle(this.parentNode, "").direction;
|
||||
if (direction == "ltr") {
|
||||
halfInd = Math.ceil(halfInd);
|
||||
if (!this.childNodes.length)
|
||||
ind.style.marginLeft = 0 - this.boxObject.x - halfInd + 'px'
|
||||
else if (dropPoint.beforeIndex == -1)
|
||||
ind.style.marginLeft = this.lastChild.boxObject.x +
|
||||
this.lastChild.boxObject.width - this.boxObject.x - halfInd + 'px';
|
||||
else
|
||||
ind.style.marginLeft = this.childNodes[dropPoint.beforeIndex].boxObject.x -
|
||||
this.boxObject.x - halfInd + 'px';
|
||||
}
|
||||
else {
|
||||
halfInd = Math.floor(halfInd);
|
||||
if (this.childNodes.length == 0)
|
||||
ind.style.marginRight = this.boxObject.width + 'px';
|
||||
else if (dropPoint.beforeIndex == -1) {
|
||||
ind.style.marginRight = this.boxObject.width -
|
||||
(this.childNodes[this.childNodes.length - 1].boxObject.x +
|
||||
halfInd) +'px';
|
||||
}
|
||||
else {
|
||||
ind.style.marginRight = this.boxObject.width -
|
||||
(this.childNodes[dropPoint.beforeIndex].boxObject.x +
|
||||
this.childNodes[dropPoint.beforeIndex].boxObject.width -
|
||||
this.boxObject.x + halfInd) + 'px';
|
||||
}
|
||||
}
|
||||
// Clear out old folder information
|
||||
this._clearOverFolder();
|
||||
}
|
||||
|
||||
dt.effectAllowed = "all";
|
||||
event.preventDefault();
|
||||
]]></handler>
|
||||
<handler event="dragdrop"><![CDATA[
|
||||
if (!this.checkForMenuEvent(event, "drop"))
|
||||
nsDragAndDrop.drop(event, this._DNDObserver);
|
||||
|
||||
<handler event="drop"><![CDATA[
|
||||
// Cache the dataTransfer
|
||||
PlacesControllerDragHelper.currentDataTransfer = event.dataTransfer;
|
||||
|
||||
var dropPoint = this._getDropPoint(event);
|
||||
if (!dropPoint)
|
||||
return;
|
||||
PlacesControllerDragHelper.onDrop(dropPoint.ip);
|
||||
]]></handler>
|
||||
<handler event="dragexit"><![CDATA[
|
||||
if (!this.checkForMenuEvent(event, "dragExit"))
|
||||
nsDragAndDrop.dragExit(event, this._DNDObserver);
|
||||
|
||||
<handler event="dragleave"><![CDATA[
|
||||
PlacesControllerDragHelper.currentDropTarget = null;
|
||||
PlacesControllerDragHelper.currentDataTransfer = null;
|
||||
|
||||
// Set timer to turn off indicator bar (if we turn it off
|
||||
// here, dragenter might be called immediately after, creating
|
||||
// flicker.)
|
||||
if (this._ibTimer)
|
||||
this._ibTimer.cancel();
|
||||
this._ibTimer = this._setTimer(10);
|
||||
|
||||
// Close any folder being hovered over
|
||||
if (this._overFolder.node)
|
||||
this._overFolder.closeTimer = this._setTimer(this._overFolder.hoverTime);
|
||||
|
||||
this._draggedNode = null;
|
||||
]]></handler>
|
||||
|
||||
<handler event="popupshowing" phase="capturing"><![CDATA[
|
||||
// Don't show the popup if we are dragging a container.
|
||||
if (this._draggingContainer) {
|
||||
|
@ -1185,6 +1152,7 @@
|
|||
!PlacesControllerDragHelper.getSession())
|
||||
this._openedMenuButton = parent;
|
||||
]]></handler>
|
||||
|
||||
<handler event="popuphidden"><![CDATA[
|
||||
var popup = event.originalTarget;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче