Allow items to be moved (not copied) between collections w/modifier key

Cmd on OS X, Shift on Windows/Linux

How do I not get to close a ticket for this?

Unfortunately on Windows it doesn't seem possible to set the cursor
effect to arbitrary states (see note in libraryTreeView.js::
_setDropEffect() for the gory details), so this just uses the default
cursor there. On OS X and Linux the cursor reflects the requested
action.
This commit is contained in:
Dan Stillman 2013-09-05 13:37:09 -04:00
parent ea97c3d956
commit d318bca7a4
6 changed files with 379 additions and 208 deletions

View file

@ -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;
}
////////////////////////////////////////////////////////////////////////////////
///

View file

@ -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;
}
////////////////////////////////////////////////////////////////////////////////
///

View file

@ -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 <http://www.gnu.org/licenses/>.
***** 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;
}
};

View file

@ -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;
}
}

View file

@ -301,10 +301,6 @@
<tree id="zotero-collections-tree" hidecolumnpicker="true" context="zotero-collectionmenu"
onmouseover="ZoteroPane_Local.collectionsView.setHighlightedRows();"
onselect="ZoteroPane_Local.onCollectionSelected();"
ondragstart="if (event.target.localName == 'treechildren') { ZoteroPane_Local.collectionsView.onDragStart(event); }"
ondragenter="return ZoteroPane_Local.collectionsView.onDragEnter(event)"
ondragover="return ZoteroPane_Local.collectionsView.onDragOver(event)"
ondrop="return ZoteroPane_Local.collectionsView.onDrop(event)"
seltype="cell" flex="1">
<treecols>
<treecol
@ -313,7 +309,10 @@
primary="true"
hideheader="true"/>
</treecols>
<treechildren/>
<treechildren ondragstart="ZoteroPane_Local.collectionsView.onDragStart(event)"
ondragenter="return ZoteroPane_Local.collectionsView.onDragEnter(event)"
ondragover="return ZoteroPane_Local.collectionsView.onDragOver(event)"
ondrop="return ZoteroPane_Local.collectionsView.onDrop(event)"/>
</tree>
<splitter id="zotero-tags-splitter" onmouseup="ZoteroPane_Local.updateTagSelectorSize()" collapse="after">
<grippy oncommand="ZoteroPane_Local.toggleTagSelector()"/>
@ -338,10 +337,6 @@
onfocus="if (ZoteroPane_Local.itemsView.rowCount &amp;&amp; !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">
<treecols id="zotero-items-columns-header">
@ -519,7 +514,10 @@
src="chrome://zotero/skin/treeitem-note-small.png"
zotero-persist="width ordinal hidden sortActive sortDirection"/>
</treecols>
<treechildren/>
<treechildren ondragstart="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)"/>
</tree>
<!-- Label for displaying messages when items pane is hidden

View file

@ -53,6 +53,7 @@ const xpcomFilesAll = [
/** XPCOM files to be loaded only for local translation and DB access **/
const xpcomFilesLocal = [
'libraryTreeView',
'collectionTreeView',
'annotate',
'attachments',