duplicatesMerge.js (4894B)
1 /* 2 ***** BEGIN LICENSE BLOCK ***** 3 4 Copyright © 2009 Center for History and New Media 5 George Mason University, Fairfax, Virginia, USA 6 http://zotero.org 7 8 This file is part of Zotero. 9 10 Zotero is free software: you can redistribute it and/or modify 11 it under the terms of the GNU Affero General Public License as published by 12 the Free Software Foundation, either version 3 of the License, or 13 (at your option) any later version. 14 15 Zotero is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU Affero General Public License for more details. 19 20 You should have received a copy of the GNU Affero General Public License 21 along with Zotero. If not, see <http://www.gnu.org/licenses/>. 22 23 ***** END LICENSE BLOCK ***** 24 */ 25 26 "use strict"; 27 28 var Zotero_Duplicates_Pane = new function () { 29 var _masterItem; 30 var _items = []; 31 var _otherItems = []; 32 var _ignoreFields = ['dateAdded', 'dateModified', 'accessDate']; 33 34 this.setItems = function (items, displayNumItemsOnTypeError) { 35 var itemTypeID, oldestItem, otherItems = []; 36 for (let item of items) { 37 // Find the oldest item 38 if (!oldestItem) { 39 oldestItem = item; 40 } 41 else if (item.dateAdded < oldestItem.dateAdded) { 42 otherItems.push(oldestItem); 43 oldestItem = item; 44 } 45 else { 46 otherItems.push(item); 47 } 48 49 if (!item.isRegularItem() || [1,14].indexOf(item.itemTypeID) != -1) { 50 var msg = Zotero.getString('pane.item.duplicates.onlyTopLevel'); 51 ZoteroPane_Local.setItemPaneMessage(msg); 52 return false; 53 } 54 55 // Make sure all items are of the same type 56 if (itemTypeID) { 57 if (itemTypeID != item.itemTypeID) { 58 if (displayNumItemsOnTypeError) { 59 var msg = Zotero.getString('pane.item.selected.multiple', items.length); 60 } 61 else { 62 var msg = Zotero.getString('pane.item.duplicates.onlySameItemType'); 63 } 64 ZoteroPane_Local.setItemPaneMessage(msg); 65 return false; 66 } 67 } 68 else { 69 itemTypeID = item.itemTypeID; 70 } 71 } 72 73 _items = items; 74 75 _items.sort(function (a, b) { 76 return a.dateAdded > b.dateAdded ? 1 : a.dateAdded == b.dateAdded ? 0 : -1; 77 }); 78 79 // 80 // Update the UI 81 // 82 83 var button = document.getElementById('zotero-duplicates-merge-button'); 84 var versionSelect = document.getElementById('zotero-duplicates-merge-version-select'); 85 var itembox = document.getElementById('zotero-duplicates-merge-item-box'); 86 var fieldSelect = document.getElementById('zotero-duplicates-merge-field-select'); 87 88 var alternatives = oldestItem.multiDiff(otherItems, _ignoreFields); 89 if (alternatives) { 90 // Populate menulist with Date Added values from all items 91 var dateList = document.getElementById('zotero-duplicates-merge-original-date'); 92 93 while (dateList.itemCount) { 94 dateList.removeItemAt(0); 95 } 96 97 var numRows = 0; 98 for (let item of items) { 99 var date = Zotero.Date.sqlToDate(item.dateAdded, true); 100 dateList.appendItem(date.toLocaleString()); 101 numRows++; 102 } 103 104 dateList.setAttribute('rows', numRows); 105 106 // If we set this inline, the selection doesn't take on the first 107 // selection after unhiding versionSelect (when clicking 108 // from a set with no differences) -- tested in Fx5.0.1 109 setTimeout(function () { 110 dateList.selectedIndex = 0; 111 }, 0); 112 } 113 114 button.label = Zotero.getString('pane.item.duplicates.mergeItems', (otherItems.length + 1)); 115 versionSelect.hidden = fieldSelect.hidden = !alternatives; 116 itembox.hiddenFields = alternatives ? [] : ['dateAdded', 'dateModified']; 117 118 this.setMaster(0); 119 120 return true; 121 } 122 123 124 this.setMaster = function (pos) { 125 var itembox = document.getElementById('zotero-duplicates-merge-item-box'); 126 itembox.mode = 'fieldmerge'; 127 128 _otherItems = _items.concat(); 129 var item = _otherItems.splice(pos, 1)[0]; 130 131 // Add master item's values to the beginning of each set of 132 // alternative values so that they're still available if the item box 133 // modifies the item 134 var alternatives = item.multiDiff(_otherItems, _ignoreFields); 135 if (alternatives) { 136 let itemValues = item.toJSON(); 137 for (let i in alternatives) { 138 alternatives[i].unshift(itemValues[i] !== undefined ? itemValues[i] : ''); 139 } 140 itembox.fieldAlternatives = alternatives; 141 } 142 143 _masterItem = item; 144 itembox.item = item.clone(null, { includeCollections: true }); 145 } 146 147 148 this.merge = Zotero.Promise.coroutine(function* () { 149 var itembox = document.getElementById('zotero-duplicates-merge-item-box'); 150 Zotero.CollectionTreeCache.clear(); 151 // Update master item with any field alternatives from the item box 152 _masterItem.fromJSON(itembox.item.toJSON()); 153 Zotero.Items.merge(_masterItem, _otherItems); 154 }); 155 }