diff --git a/chrome/content/zotero/xpcom/collectionTreeView.js b/chrome/content/zotero/xpcom/collectionTreeView.js index 9f506b9fc..4c0356fe2 100644 --- a/chrome/content/zotero/xpcom/collectionTreeView.js +++ b/chrome/content/zotero/xpcom/collectionTreeView.js @@ -48,6 +48,16 @@ Zotero.CollectionTreeView = function() this._trashNotEmpty = {}; } +Zotero.CollectionTreeView.prototype = Object.create(Zotero.LibraryTreeView.prototype); +Zotero.CollectionTreeView.prototype.type = 'collection'; + +Object.defineProperty(Zotero.CollectionTreeView.prototype, "itemGroup", { + get: function () { + return this.getItemGroupAtRow(this.selection.currentIndex); + } +}) + + /* * Called by the tree itself */ @@ -980,8 +990,10 @@ Zotero.CollectionTreeView.prototype._hideItem = function(row) } -/* +/** * Returns Zotero.ItemGroup at row + * + * @deprecated Use getItemGroupAtRow() */ Zotero.CollectionTreeView.prototype._getItemAtRow = function(row) { @@ -989,6 +1001,12 @@ Zotero.CollectionTreeView.prototype._getItemAtRow = function(row) } +Zotero.CollectionTreeView.prototype.getItemGroupAtRow = function(row) +{ + return this._dataItems[row][0]; +} + + /* * Saves the ids of the currently selected item for later */ @@ -1155,7 +1173,7 @@ Zotero.CollectionTreeCommandController.prototype.onEvent = function(evt) * Start a drag using HTML 5 Drag and Drop */ Zotero.CollectionTreeView.prototype.onDragStart = function(event) { - var itemGroup = this._getItemAtRow(this.selection.currentIndex); + var itemGroup = this.itemGroup; if (!itemGroup.isCollection()) { return; } @@ -1163,18 +1181,16 @@ Zotero.CollectionTreeView.prototype.onDragStart = function(event) { } -/* - * Called while a drag is over the tree. +/** + * Called by treechildren.onDragOver() before setting the dropEffect, + * which is checked in libraryTreeView.canDrop() */ -Zotero.CollectionTreeView.prototype.canDrop = function(row, orient, dragData) -{ +Zotero.CollectionTreeView.prototype.canDropCheck = function (row, orient, dataTransfer) { //Zotero.debug("Row is " + row + "; orient is " + orient); - if (!dragData || !dragData.data) { - var dragData = Zotero.DragDrop.getDragData(this); - } - + var dragData = Zotero.DragDrop.getDataFromDataTransfer(dataTransfer); if (!dragData) { + Zotero.debug("No drag data"); return false; } var dataType = dragData.dataType; @@ -1184,8 +1200,8 @@ Zotero.CollectionTreeView.prototype.canDrop = function(row, orient, dragData) if (orient == 1 && row == 0 && dataType == 'zotero/collection') { return true; } - else if(orient == 0) //directly on a row... - { + // Directly on a row + else if (orient == 0) { var itemGroup = this._getItemAtRow(row); //the collection we are dragging over if (dataType == 'zotero/item' && itemGroup.isBucket()) { @@ -1331,17 +1347,21 @@ Zotero.CollectionTreeView.prototype.canDrop = function(row, orient, dragData) /* * Called when something's been dropped on or next to a row */ -Zotero.CollectionTreeView.prototype.drop = function(row, orient) +Zotero.CollectionTreeView.prototype.drop = function(row, orient, dataTransfer) { - var dragData = Zotero.DragDrop.getDragData(this); - - if (!this.canDrop(row, orient, dragData)) { + if (!this.canDropCheck(row, orient, dataTransfer)) { return false; } + var dragData = Zotero.DragDrop.getDataFromDataTransfer(dataTransfer); + if (!dragData) { + Zotero.debug("No drag data"); + return false; + } + var dropEffect = dragData.dropEffect; var dataType = dragData.dataType; var data = dragData.data; - var itemGroup = this._getItemAtRow(row); + var itemGroup = this.getItemGroupAtRow(row); function copyItem (item, targetLibraryID) { // Check if there's already a copy of this item in the library @@ -1589,6 +1609,7 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) var newItems = []; var newIDs = []; + var toMove = []; // TODO: support items coming from different sources? if (items[0].libraryID == targetLibraryID) { var sameLibrary = true; @@ -1604,6 +1625,7 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) if (sameLibrary) { newIDs.push(item.id); + toMove.push(item.id); } else { newItems.push(item); @@ -1667,6 +1689,18 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) collection.addItems(newIDs); } + // If moving, remove items from source collection + if (dropEffect == 'move' && toMove.length) { + if (!sameLibrary) { + throw new Error("Cannot move items between libraries"); + } + let itemGroup = Zotero.DragDrop.getDragSource(); + if (!itemGroup || !itemGroup.isCollection()) { + throw new Error("Drag source must be a collection for move action"); + } + itemGroup.ref.removeItems(toMove); + } + Zotero.DB.commitTransaction(); } else if (dataType == 'text/x-moz-url' || dataType == 'application/x-moz-file') { @@ -1725,7 +1759,7 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) try { Zotero.DB.beginTransaction(); - if (dragData.dropEffect == 'link') { + if (dropEffect == 'link') { var itemID = Zotero.Attachments.linkFromFile(file); } else { @@ -1740,7 +1774,6 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) } } } - if (parentCollectionID) { var col = Zotero.Collections.get(parentCollectionID); if (col) { @@ -1762,85 +1795,6 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) } -/* - * Called by HTML 5 Drag and Drop when dragging over the tree - */ -Zotero.CollectionTreeView.prototype.onDragEnter = function (event) { - Zotero.DragDrop.currentDataTransfer = event.dataTransfer; - return false; -} - - -/* - * Called by HTML 5 Drag and Drop when dragging over the tree - */ -Zotero.CollectionTreeView.prototype.onDragOver = function (event) { - Zotero.DragDrop.currentDataTransfer = event.dataTransfer; - if (event.dataTransfer.types.contains("application/x-moz-file")) { - // As of Aug. 2013 nightlies: - // - // - Setting the dropEffect only works on Linux and OS X. - // - // - Modifier keys don't show up in the drag event on OS X until the - // drop (https://bugzilla.mozilla.org/show_bug.cgi?id=911918), - // so since we can't show a correct effect, we leave it at - // the default 'move', the least misleading option, and set it - // below in onDrop(). - // - // - The cursor effect gets set by the system on Windows 7 and can't - // be overridden. - if (!Zotero.isMac) { - if (event.shiftKey) { - if (event.ctrlKey) { - event.dataTransfer.dropEffect = "link"; - } - else { - event.dataTransfer.dropEffect = "move"; - } - } - else { - event.dataTransfer.dropEffect = "copy"; - } - } - } - // Show copy symbol when dragging an item over a collection - else if (event.dataTransfer.getData("zotero/item")) { - event.dataTransfer.dropEffect = "copy"; - } - return false; -} - - -/* - * Called by HTML 5 Drag and Drop when dropping onto the tree - */ -Zotero.CollectionTreeView.prototype.onDrop = function (event) { - if (event.dataTransfer.types.contains("application/x-moz-file")) { - if (Zotero.isMac) { - Zotero.DragDrop.currentDataTransfer = event.dataTransfer; - if (event.metaKey) { - if (event.altKey) { - event.dataTransfer.dropEffect = 'link'; - } - else { - event.dataTransfer.dropEffect = 'move'; - } - } - else { - event.dataTransfer.dropEffect = 'copy'; - } - } - } - return false; -} - -Zotero.CollectionTreeView.prototype.onDragExit = function (event) { - //Zotero.debug("Clearing drag data"); - Zotero.DragDrop.currentDataTransfer = null; -} - - - //////////////////////////////////////////////////////////////////////////////// /// diff --git a/chrome/content/zotero/xpcom/itemTreeView.js b/chrome/content/zotero/xpcom/itemTreeView.js index ef35b0383..6924df5ee 100644 --- a/chrome/content/zotero/xpcom/itemTreeView.js +++ b/chrome/content/zotero/xpcom/itemTreeView.js @@ -38,11 +38,14 @@ Zotero.ItemTreeView = function(itemGroup, sourcesOnly) { this.wrappedJSObject = this; this.rowCount = 0; + this.itemGroup = itemGroup; + // Deprecated + // TODO: remove + this._itemGroup = itemGroup; this._initialized = false; this._skipKeypress = false; - this._itemGroup = itemGroup; this._sourcesOnly = sourcesOnly; this._callbacks = []; @@ -59,6 +62,8 @@ Zotero.ItemTreeView = function(itemGroup, sourcesOnly) ); } +Zotero.ItemTreeView.prototype = Object.create(Zotero.LibraryTreeView.prototype); +Zotero.ItemTreeView.prototype.type = 'item'; Zotero.ItemTreeView.prototype.addCallback = function(callback) { this._callbacks.push(callback); @@ -2427,6 +2432,11 @@ Zotero.ItemTreeCommandController.prototype.onEvent = function(evt) * Start a drag using HTML 5 Drag and Drop */ Zotero.ItemTreeView.prototype.onDragStart = function (event) { + // See note in LibraryTreeView::_setDropEffect() + if (Zotero.isWin) { + event.dataTransfer.effectAllowed = 'move'; + } + var itemIDs = this.saveSelection(); var items = Zotero.Items.get(itemIDs); @@ -2741,17 +2751,14 @@ Zotero.ItemTreeView.fileDragDataProvider.prototype = { } -Zotero.ItemTreeView.prototype.canDrop = function(row, orient, dragData) -{ - Zotero.debug("Row is " + row + "; orient is " + orient); +/** + * Called by treechildren.onDragOver() before setting the dropEffect, + * which is checked in libraryTreeView.canDrop() + */ +Zotero.ItemTreeView.prototype.canDropCheck = function (row, orient, dataTransfer) { + //Zotero.debug("Row is " + row + "; orient is " + orient); - if (row == -1 && orient == -1) { - //return true; - } - - if (!dragData || !dragData.data) { - var dragData = Zotero.DragDrop.getDragData(this); - } + var dragData = Zotero.DragDrop.getDataFromDataTransfer(dataTransfer); if (!dragData) { Zotero.debug("No drag data"); return false; @@ -2869,18 +2876,21 @@ Zotero.ItemTreeView.prototype.canDrop = function(row, orient, dragData) /* * Called when something's been dropped on or next to a row */ -Zotero.ItemTreeView.prototype.drop = function(row, orient) -{ - var dragData = Zotero.DragDrop.getDragData(this); - - if (!this.canDrop(row, orient, dragData)) { +Zotero.ItemTreeView.prototype.drop = function(row, orient, dataTransfer) { + if (!this.canDropCheck(row, orient, dataTransfer)) { return false; } + var dragData = Zotero.DragDrop.getDataFromDataTransfer(dataTransfer); + if (!dragData) { + Zotero.debug("No drag data"); + return false; + } + var dropEffect = dragData.dropEffect; var dataType = dragData.dataType; var data = dragData.data; - - var itemGroup = this._itemGroup; + var itemGroup = this.itemGroup; + var targetLibraryID = itemGroup.isWithinGroup() ? itemGroup.ref.libraryID : null; if (dataType == 'zotero/item') { var ids = data; @@ -2889,6 +2899,19 @@ Zotero.ItemTreeView.prototype.drop = function(row, orient) return; } + // TEMP: This is always false for now, since cross-library drag + // is disallowed in canDropCheck() + // + // TODO: support items coming from different sources? + if (items[0].libraryID == targetLibraryID) { + var sameLibrary = true; + } + else { + var sameLibrary = false; + } + + var toMove = []; + // Dropped directly on a row if (orient == 0) { // Set drop target as the parent item for dragged items @@ -2926,9 +2949,24 @@ Zotero.ItemTreeView.prototype.drop = function(row, orient) item.save() } itemGroup.ref.addItem(item.id); + toMove.push(item.id); } } } + + // If moving, remove items from source collection + if (dropEffect == 'move' && toMove.length) { + if (!sameLibrary) { + throw new Error("Cannot move items between libraries"); + } + let targetItemGroup = Zotero.DragDrop.getDragSource(); + if (!targetItemGroup || !targetItemGroup.isCollection()) { + throw new Error("Drag source must be a collection"); + } + if (itemGroup.id != targetItemGroup.id) { + itemGroup.ref.removeItems(toMove); + } + } } else if (dataType == 'text/x-moz-url' || dataType == 'application/x-moz-file') { // Disallow drop into read-only libraries @@ -3011,7 +3049,7 @@ Zotero.ItemTreeView.prototype.drop = function(row, orient) try { Zotero.DB.beginTransaction(); - if (dragData.dropEffect == 'link') { + if (dropEffect == 'link') { var itemID = Zotero.Attachments.linkFromFile(file, sourceItemID); } else { @@ -3046,79 +3084,6 @@ Zotero.ItemTreeView.prototype.drop = function(row, orient) } } -Zotero.ItemTreeView.prototype.onDragEnter = function (event) { - Zotero.DragDrop.currentDataTransfer = event.dataTransfer; - return false; -} - -/* - * Called by HTML 5 Drag and Drop when dragging over the tree - */ -Zotero.ItemTreeView.prototype.onDragOver = function (event) { - Zotero.DragDrop.currentDataTransfer = event.dataTransfer; - if (event.dataTransfer.types.contains("application/x-moz-file")) { - // As of Aug. 2013 nightlies: - // - // - Setting the dropEffect only works on Linux and OS X. - // - // - Modifier keys don't show up in the drag event on OS X until the - // drop (https://bugzilla.mozilla.org/show_bug.cgi?id=911918), - // so since we can't show a correct effect, we leave it at - // the default 'move', the least misleading option, and set it - // below in onDrop(). - // - // - The cursor effect gets set by the system on Windows 7 and can't - // be overridden. - if (!Zotero.isMac) { - if (event.shiftKey) { - if (event.ctrlKey) { - event.dataTransfer.dropEffect = "link"; - } - else { - event.dataTransfer.dropEffect = "move"; - } - } - else { - event.dataTransfer.dropEffect = "copy"; - } - } - } - // Show copy symbol when dragging an item over a collection - else if (event.dataTransfer.getData("zotero/item")) { - event.dataTransfer.dropEffect = "copy"; - } - return false; -} - - -/* - * Called by HTML 5 Drag and Drop when dropping onto the tree - */ -Zotero.ItemTreeView.prototype.onDrop = function (event) { - if (event.dataTransfer.types.contains("application/x-moz-file")) { - if (Zotero.isMac) { - Zotero.DragDrop.currentDataTransfer = event.dataTransfer; - if (event.metaKey) { - if (event.altKey) { - event.dataTransfer.dropEffect = 'link'; - } - else { - event.dataTransfer.dropEffect = 'move'; - } - } - else { - event.dataTransfer.dropEffect = 'copy'; - } - } - } - return false; -} - -Zotero.ItemTreeView.prototype.onDragExit = function (event) { - //Zotero.debug("Clearing drag data"); - Zotero.DragDrop.currentDataTransfer = null; -} - //////////////////////////////////////////////////////////////////////////////// /// diff --git a/chrome/content/zotero/xpcom/libraryTreeView.js b/chrome/content/zotero/xpcom/libraryTreeView.js new file mode 100644 index 000000000..a6cd76b35 --- /dev/null +++ b/chrome/content/zotero/xpcom/libraryTreeView.js @@ -0,0 +1,216 @@ +/* + ***** BEGIN LICENSE BLOCK ***** + + Copyright © 2013 Center for History and New Media + George Mason University, Fairfax, Virginia, USA + http://zotero.org + + This file is part of Zotero. + + Zotero is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Zotero is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with Zotero. If not, see . + + ***** END LICENSE BLOCK ***** +*/ + +Zotero.LibraryTreeView = function () {}; +Zotero.LibraryTreeView.prototype = { + /** + * Called while a drag is over the tree + */ + canDrop: function(row, orient, dataTransfer) { + // onDragOver() calls the view's canDropCheck() and sets the + // dropEffect, which we check here. Setting the dropEffect on the + // dataTransfer here seems to have no effect. + + // ondragover doesn't have access to the orientation on its own, + // so we stuff it in Zotero.DragDrop + Zotero.DragDrop.currentOrientation = orient; + + return dataTransfer.dropEffect && dataTransfer.dropEffect != "none"; + }, + + + /* + * Called by HTML 5 Drag and Drop when dragging over the tree + */ + onDragEnter: function (event) { + Zotero.DragDrop.currentDragEvent = event; + return false; + }, + + + /** + * Called by HTML 5 Drag and Drop when dragging over the tree + * + * We use this to set the drag action, which is used by view.canDrop(), + * based on the view's canDropCheck() and modifier keys. + */ + onDragOver: function (event) { + // Prevent modifier keys from doing their normal things + event.preventDefault(); + + Zotero.DragDrop.currentDragEvent = event; + + var target = event.target; + if (target.tagName != 'treechildren') { + return false; + } + var tree = target.parentNode; + let row = {}, col = {}, obj = {}; + tree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, obj); + if (tree.id == 'zotero-collections-tree') { + var view = tree.ownerDocument.defaultView.ZoteroPane.collectionsView; + } + else if (tree.id == 'zotero-items-tree') { + var view = tree.ownerDocument.defaultView.ZoteroPane.itemsView; + } + else { + throw new Error("Invalid tree id '" + tree.id + "'"); + } + if (!view.canDropCheck(row.value, Zotero.DragDrop.currentOrientation, event.dataTransfer)) { + this._setDropEffect(event, "none"); + return; + } + + if (event.dataTransfer.getData("zotero/item")) { + var sourceItemGroup = Zotero.DragDrop.getDragSource(); + if (sourceItemGroup) { + if (this.type == 'collection') { + var targetItemGroup = Zotero.DragDrop.getDragTarget(); + } + else if (this.type == 'item') { + var targetItemGroup = this.itemGroup; + } + else { + throw new Error("Invalid type '" + this.type + "'"); + } + + if (!targetItemGroup) { + this._setDropEffect(event, "none"); + return false; + } + + if (sourceItemGroup.id == targetItemGroup.id) { + // Ignore drag into the same collection + if (this.type == 'collection') { + this._setDropEffect(event, "none"); + } + // If dragging from the same source, do a move + else { + this._setDropEffect(event, "move"); + } + return false; + } + // If the source isn't a collection, the action has to be a copy + if (!sourceItemGroup.isCollection()) { + this._setDropEffect(event, "copy"); + return false; + } + // For now, all cross-library drags are copies + if (sourceItemGroup.ref.libraryID != targetItemGroup.ref.libraryID) { + this._setDropEffect(event, "copy"); + return false; + } + } + + if ((Zotero.isMac && event.metaKey) || (!Zotero.isMac && event.shiftKey)) { + this._setDropEffect(event, "move"); + } + else { + this._setDropEffect(event, "copy"); + } + } + else if (event.dataTransfer.types.contains("application/x-moz-file")) { + // As of Aug. 2013 nightlies: + // + // - Setting the dropEffect only works on Linux and OS X. + // + // - Modifier keys don't show up in the drag event on OS X until the + // drop (https://bugzilla.mozilla.org/show_bug.cgi?id=911918), + // so since we can't show a correct effect, we leave it at + // the default 'move', the least misleading option, and set it + // below in onDrop(). + // + // - The cursor effect gets set by the system on Windows 7 and can't + // be overridden. + if (!Zotero.isMac) { + if (event.shiftKey) { + if (event.ctrlKey) { + event.dataTransfer.dropEffect = "link"; + } + else { + event.dataTransfer.dropEffect = "move"; + } + } + else { + event.dataTransfer.dropEffect = "copy"; + } + } + } + return false; + }, + + + /* + * Called by HTML 5 Drag and Drop when dropping onto the tree + */ + onDrop: function (event) { + // See note above + if (event.dataTransfer.types.contains("application/x-moz-file")) { + if (Zotero.isMac) { + Zotero.DragDrop.currentDragEvent = event; + if (event.metaKey) { + if (event.altKey) { + event.dataTransfer.dropEffect = 'link'; + } + else { + event.dataTransfer.dropEffect = 'move'; + } + } + else { + event.dataTransfer.dropEffect = 'copy'; + } + } + } + return false; + }, + + + onDragExit: function (event) { + //Zotero.debug("Clearing drag data"); + Zotero.DragDrop.currentDragEvent = null; + }, + + + _setDropEffect: function (event, effect) { + // On Windows (in Fx26), Firefox uses 'move' for unmodified drags, + // and 'copy'/'link' for drags with system-default modifier keys, + // as long as the actions are allowed by the initial effectAllowed set + // in onDragStart, regardless of the effectAllowed or dropEffect set + // in onDragOver. To prevent inaccurate 'copy'/'link' cursors, we set + // effectAllowed to 'move' in onDragStart, which locks the cursor at + // 'move'. ('none' still changes the cursor, but 'copy'/'link' do not.) + // + // However, since effectAllowed is enforced, leaving it at 'move' + // would prevent our default 'copy' from working, so we also have to + // set effectAllowed here (called from onDragOver) to the same action + // as the dropEffect. This allows the dropEffect setting (which we use + // in the tree's canDrop() and drop() to determine the desired action) + // to be changed, even if the cursor doesn't reflect the new setting. + if (Zotero.isWin) { + event.dataTransfer.effectAllowed = effect; + } + event.dataTransfer.dropEffect = effect; + } +}; diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index 5c760502e..c9df66950 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -2386,14 +2386,12 @@ Zotero.VersionHeader = { } Zotero.DragDrop = { - currentDataTransfer: null, + currentDragEvent: null, + currentTarget: null, + currentOrientation: 0, - getDragData: function (element, firstOnly) { - var dt = this.currentDataTransfer; - if (!dt) { - Zotero.debug("Drag data not available"); - return false; - } + getDataFromDataTransfer: function (dataTransfer, firstOnly) { + var dt = dataTransfer; var dragData = { dataType: '', @@ -2401,7 +2399,6 @@ Zotero.DragDrop = { dropEffect: dt.dropEffect }; - var len = firstOnly ? 1 : dt.mozItemCount; if (dt.types.contains('zotero/collection')) { @@ -2439,6 +2436,46 @@ Zotero.DragDrop = { } return dragData; + }, + + + getDragSource: function () { + var dt = this.currentDragEvent.dataTransfer; + if (!dt) { + Zotero.debug("Drag data not available", 2); + return false; + } + + // For items, the drag source is the ItemGroup of the parent window + // of the source tree + if (dt.types.contains("zotero/item")) { + var sourceNode = dt.mozSourceNode; + if (!sourceNode || sourceNode.tagName != 'treechildren' + || sourceNode.parentElement.id != 'zotero-items-tree') { + return false; + } + var win = sourceNode.ownerDocument.defaultView; + return win.ZoteroPane.collectionsView.itemGroup; + } + else { + return false; + } + }, + + + getDragTarget: function () { + var event = this.currentDragEvent; + var target = event.target; + if (target.tagName == 'treechildren') { + var tree = target.parentNode; + if (tree.id == 'zotero-collections-tree') { + let row = {}, col = {}, obj = {}; + tree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, obj); + let win = tree.ownerDocument.defaultView; + return win.ZoteroPane.collectionsView.getItemGroupAtRow(row.value); + } + } + return false; } } diff --git a/chrome/content/zotero/zoteroPane.xul b/chrome/content/zotero/zoteroPane.xul index 9952a8dc3..30d58580a 100644 --- a/chrome/content/zotero/zoteroPane.xul +++ b/chrome/content/zotero/zoteroPane.xul @@ -301,10 +301,6 @@ - + @@ -338,10 +337,6 @@ onfocus="if (ZoteroPane_Local.itemsView.rowCount && !ZoteroPane_Local.itemsView.selection.count) { ZoteroPane_Local.itemsView.selection.select(0); }" onkeydown="ZoteroPane_Local.handleKeyDown(event, this.id)" onselect="ZoteroPane_Local.itemSelected(event)" - ondragstart="if (event.target.localName == 'treechildren') { ZoteroPane_Local.itemsView.onDragStart(event); }" - ondragenter="return ZoteroPane_Local.itemsView.onDragEnter(event)" - ondragover="return ZoteroPane_Local.itemsView.onDragOver(event)" - ondrop="return ZoteroPane_Local.itemsView.onDrop(event)" oncommand="ZoteroPane_Local.serializePersist()" flex="1"> @@ -519,7 +514,10 @@ src="chrome://zotero/skin/treeitem-note-small.png" zotero-persist="width ordinal hidden sortActive sortDirection"/> - +