Merge branch '4.0'
This commit is contained in:
commit
6915b7aa56
13 changed files with 554 additions and 367 deletions
|
@ -118,7 +118,7 @@
|
|||
this.mode = this.getAttribute('mode');
|
||||
}
|
||||
|
||||
this._notifierID = Zotero.Notifier.registerObserver(this, ['setting']);
|
||||
this._notifierID = Zotero.Notifier.registerObserver(this, ['item-tag', 'setting']);
|
||||
]]>
|
||||
</constructor>
|
||||
|
||||
|
@ -142,6 +142,55 @@
|
|||
}
|
||||
return;
|
||||
}
|
||||
else if (type == 'item-tag') {
|
||||
let itemID, tagID;
|
||||
|
||||
for (var i=0; i<ids.length; i++) {
|
||||
[itemID, tagID] = ids[i].split('-');
|
||||
if (!this.item || itemID != this.item.id) {
|
||||
continue;
|
||||
}
|
||||
if (event == 'add') {
|
||||
var newTabIndex = this.add(tagID);
|
||||
if (newTabIndex == -1) {
|
||||
return;
|
||||
}
|
||||
if (this._tabDirection == -1) {
|
||||
if (this._lastTabIndex > newTabIndex) {
|
||||
this._lastTabIndex++;
|
||||
}
|
||||
}
|
||||
else if (this._tabDirection == 1) {
|
||||
if (this._lastTabIndex > newTabIndex) {
|
||||
this._lastTabIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event == 'remove') {
|
||||
var oldTabIndex = this.remove(tagID);
|
||||
if (oldTabIndex == -1) {
|
||||
return;
|
||||
}
|
||||
if (this._tabDirection == -1) {
|
||||
if (this._lastTabIndex > oldTabIndex) {
|
||||
this._lastTabIndex--;
|
||||
}
|
||||
}
|
||||
else if (this._tabDirection == 1) {
|
||||
if (this._lastTabIndex >= oldTabIndex) {
|
||||
this._lastTabIndex--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.updateCount();
|
||||
}
|
||||
else if (type == 'tag') {
|
||||
if (event == 'modify') {
|
||||
this.reload();
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -166,14 +215,11 @@
|
|||
while(rows.hasChildNodes()) {
|
||||
rows.removeChild(rows.firstChild);
|
||||
}
|
||||
var tags = self.item.getTags();
|
||||
if (tags) {
|
||||
var tags = self.item.getTags() || [];
|
||||
for (var i=0; i<tags.length; i++) {
|
||||
self.addDynamicRow(tags[i], i+1);
|
||||
}
|
||||
}
|
||||
|
||||
self.updateCount(0);
|
||||
self.updateCount(tags.length);
|
||||
|
||||
self._reloading = false;
|
||||
self._focusField();
|
||||
|
@ -187,6 +233,7 @@
|
|||
<method name="addDynamicRow">
|
||||
<parameter name="tagObj"/>
|
||||
<parameter name="tabindex"/>
|
||||
<parameter name="skipAppend"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (tagObj) {
|
||||
|
@ -224,9 +271,11 @@
|
|||
row.appendChild(remove);
|
||||
}
|
||||
|
||||
this.updateRow(row, tagObj, tabindex);
|
||||
this.updateRow(row, tagObj);
|
||||
|
||||
if (!skipAppend) {
|
||||
this.id('tagRows').appendChild(row);
|
||||
}
|
||||
|
||||
return row;
|
||||
]]>
|
||||
|
@ -234,10 +283,13 @@
|
|||
</method>
|
||||
|
||||
|
||||
<!--
|
||||
Update various attributes of a row to match the given tag
|
||||
and current editability
|
||||
-->
|
||||
<method name="updateRow">
|
||||
<parameter name="row"/>
|
||||
<parameter name="tagObj"/>
|
||||
<parameter name="tabindex"/>
|
||||
<body><![CDATA[
|
||||
if (tagObj) {
|
||||
var tagID = tagObj.id;
|
||||
|
@ -274,7 +326,7 @@
|
|||
var self = this;
|
||||
remove.addEventListener('click', function () {
|
||||
self._lastTabIndex = false;
|
||||
document.getBindingParent(this).remove(tagID);
|
||||
document.getBindingParent(this).item.removeTag(tagID);
|
||||
|
||||
// Return focus to items pane
|
||||
var tree = document.getElementById('zotero-items-tree');
|
||||
|
@ -302,7 +354,9 @@
|
|||
valueElement.className = 'zotero-box-label';
|
||||
|
||||
if (this.clickable) {
|
||||
if (tabindex) {
|
||||
valueElement.setAttribute('ztabindex', tabindex);
|
||||
}
|
||||
valueElement.addEventListener('click', function (event) {
|
||||
/* Skip right-click on Windows */
|
||||
if (event.button) {
|
||||
|
@ -476,12 +530,7 @@
|
|||
|
||||
case event.DOM_VK_ESCAPE:
|
||||
// Reset field to original value
|
||||
if (target.getAttribute('multiline')) {
|
||||
target.value = "";
|
||||
}
|
||||
else {
|
||||
target.value = target.getAttribute('value');
|
||||
}
|
||||
|
||||
var tagsbox = Zotero.getAncestorByTagName(focused, 'tagsbox');
|
||||
|
||||
|
@ -571,7 +620,8 @@
|
|||
if (!rows) {
|
||||
rows = value.match(/\n/g).length + 1;
|
||||
}
|
||||
textbox = this.showEditor(textbox, rows, value);
|
||||
textbox = this.showEditor(textbox, rows, textbox.getAttribute('value'));
|
||||
textbox.value = value;
|
||||
// Move cursor to end
|
||||
textbox.selectionStart = value.length;
|
||||
]]></body>
|
||||
|
@ -583,21 +633,12 @@
|
|||
<body>
|
||||
<![CDATA[
|
||||
Zotero.debug('Hiding editor');
|
||||
/*
|
||||
var textbox = Zotero.getAncestorByTagName(t, 'textbox');
|
||||
if (!textbox){
|
||||
Zotero.debug('Textbox not found in hideEditor');
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO: get rid of this?
|
||||
//var saveChanges = this.saveOnEdit;
|
||||
var saveChanges = true;
|
||||
|
||||
var fieldName = 'tag';
|
||||
var tabindex = textbox.getAttribute('ztabindex');
|
||||
|
||||
var oldValue = textbox.getAttribute('value');
|
||||
textbox.value = textbox.value.trim();
|
||||
var value = textbox.value;
|
||||
|
||||
var tagsbox = Zotero.getAncestorByTagName(textbox, 'tagsbox');
|
||||
|
@ -611,47 +652,50 @@
|
|||
var rows = row.parentNode;
|
||||
|
||||
// Tag id encoded as 'tag-1234'
|
||||
var id = row.getAttribute('id').split('-')[1];
|
||||
var oldTagID = row.getAttribute('id').split('-')[1];
|
||||
|
||||
// Remove empty row at end
|
||||
if (!oldTagID && !value) {
|
||||
row.parentNode.removeChild(row);
|
||||
return;
|
||||
}
|
||||
|
||||
// If row hasn't changed, change back to label
|
||||
if (oldValue == value) {
|
||||
this.textboxToLabel(textbox);
|
||||
return;
|
||||
}
|
||||
|
||||
var tagArray = value.split(/\r\n?|\n/);
|
||||
|
||||
if (saveChanges) {
|
||||
// Modifying existing tag
|
||||
if (id && tagArray.length < 2) {
|
||||
// Modifying existing tag with a single new one
|
||||
if (oldTagID && tagArray.length < 2) {
|
||||
if (value) {
|
||||
var newTagID = tagsbox.replace(id, value);
|
||||
if (newTagID) {
|
||||
id = newTagID;
|
||||
}
|
||||
// Changed tag to existing
|
||||
else if (value != Zotero.Tags.getName(id)) {
|
||||
if (this._tabDirection == 1) {
|
||||
this._lastTabIndex -= 1;
|
||||
}
|
||||
this.reload();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
var unchanged = true;
|
||||
}
|
||||
tagsbox.replace(oldTagID, value);
|
||||
}
|
||||
// Existing tag cleared
|
||||
else {
|
||||
tagsbox.remove(id);
|
||||
return;
|
||||
this.item.removeTag(oldTagID);
|
||||
}
|
||||
}
|
||||
// // Multiple tags
|
||||
// Multiple tags
|
||||
else if (tagArray.length > 1) {
|
||||
var lastTag = row == row.parentNode.lastChild;
|
||||
|
||||
Zotero.DB.beginTransaction();
|
||||
|
||||
if (oldTagID) {
|
||||
var oldValue = Zotero.Tags.getName(oldTagID);
|
||||
// If old tag isn't in array, remove it
|
||||
if (id) {
|
||||
var oldValue = Zotero.Tags.getName(id);
|
||||
if (tagArray.indexOf(oldValue) == -1) {
|
||||
this.item.removeTag(id);
|
||||
this.item.removeTag(oldTagID);
|
||||
}
|
||||
// If old tag is staying, restore the textbox
|
||||
// immediately. This isn't strictly necessary, but it
|
||||
// makes the transition nicer.
|
||||
else {
|
||||
textbox.value = textbox.getAttribute('value');
|
||||
this.textboxToLabel(textbox);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -659,99 +703,16 @@
|
|||
|
||||
Zotero.DB.commitTransaction();
|
||||
|
||||
// TODO: get tab index right
|
||||
|
||||
if (lastTag) {
|
||||
this._lastTabIndex = this.item.getTags().length;
|
||||
}
|
||||
|
||||
this.reload();
|
||||
return;
|
||||
}
|
||||
// Single tag at end
|
||||
else {
|
||||
id = tagsbox.add(value);
|
||||
// New tag
|
||||
if (id) {
|
||||
// Stay put, since a tag was added above
|
||||
if (this._tabDirection == -1) {
|
||||
this._tabDirection = false;
|
||||
}
|
||||
}
|
||||
// Already exists
|
||||
else {
|
||||
// Go back one, since we'll remove this below
|
||||
if (this._tabDirection == 1) {
|
||||
this._lastTabIndex--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (id) {
|
||||
var elem = this.createValueElement(
|
||||
value,
|
||||
tabindex
|
||||
);
|
||||
|
||||
var row = textbox.parentNode;
|
||||
row.replaceChild(elem, textbox);
|
||||
|
||||
this.updateRow(row, Zotero.Tags.get(id), tabindex);
|
||||
|
||||
if (!unchanged) {
|
||||
// Move row to appropriate place, alphabetically
|
||||
var collation = Zotero.getLocaleCollation();
|
||||
var rows = row.parentNode;
|
||||
var labels = rows.getElementsByAttribute('fieldname', 'tag');
|
||||
|
||||
rows.removeChild(row);
|
||||
var currentTabIndex = elem.getAttribute('ztabindex');
|
||||
|
||||
var before = null;
|
||||
var inserted = false;
|
||||
for (var i=0; i<labels.length; i++) {
|
||||
let newTabIndex = i + 1;
|
||||
if (inserted) {
|
||||
labels[i].setAttribute('ztabindex', newTabIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (collation.compareString(1, value, labels[i].textContent) > 0) {
|
||||
labels[i].setAttribute('ztabindex', newTabIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
elem.setAttribute('ztabindex', newTabIndex);
|
||||
rows.insertBefore(row, labels[i].parentNode);
|
||||
inserted = true;
|
||||
|
||||
// Adjust last tab index
|
||||
if (this._tabDirection == -1) {
|
||||
if (this._lastTabIndex > newTabIndex) {
|
||||
this._lastTabIndex++;
|
||||
}
|
||||
}
|
||||
else if (this._tabDirection == 1) {
|
||||
if (this._lastTabIndex < newTabIndex) {
|
||||
this._lastTabIndex--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!inserted) {
|
||||
elem.setAttribute('ztabindex', i + 1);
|
||||
rows.appendChild(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Just remove the row
|
||||
//
|
||||
// If there's an open popup, this throws NODE CANNOT BE FOUND
|
||||
try {
|
||||
var row = rows.removeChild(row);
|
||||
}
|
||||
catch (e) {}
|
||||
row.parentNode.removeChild(row);
|
||||
this.item.addTag(value);
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
|
@ -769,16 +730,84 @@
|
|||
</method>
|
||||
|
||||
|
||||
<method name="textboxToLabel">
|
||||
<parameter name="textbox"/>
|
||||
<body><![CDATA[
|
||||
var elem = this.createValueElement(
|
||||
textbox.value, textbox.getAttribute('ztabindex')
|
||||
);
|
||||
var row = textbox.parentNode;
|
||||
row.replaceChild(elem, textbox);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
||||
<method name="add">
|
||||
<parameter name="value"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (value) {
|
||||
return this.item.addTag(value);
|
||||
<parameter name="tagID"/>
|
||||
<body><![CDATA[
|
||||
var rowsElement = this.id('tagRows');
|
||||
var rows = rowsElement.childNodes;
|
||||
|
||||
// Get this tag's existing row, if there is one
|
||||
var row = rowsElement.getElementsByAttribute('id', 'tag-' + tagID);
|
||||
row = row.length ? row[0] : false;
|
||||
|
||||
var tagObj = Zotero.Tags.get(tagID);
|
||||
var name = tagObj.name;
|
||||
|
||||
if (row) {
|
||||
// Update row and label
|
||||
this.updateRow(row, tagObj);
|
||||
var elem = this.createValueElement(name);
|
||||
|
||||
// Remove the old row, which we'll reinsert at the correct place
|
||||
rowsElement.removeChild(row);
|
||||
|
||||
// Find the current label or textbox within the row
|
||||
// and replace it with the new element -- this is used
|
||||
// both when creating new rows and when hiding the
|
||||
// entry textbox
|
||||
var oldElem = row.getElementsByAttribute('fieldname', 'tag')[0];
|
||||
row.replaceChild(elem, oldElem);
|
||||
}
|
||||
return false;
|
||||
]]>
|
||||
</body>
|
||||
else {
|
||||
// Create new row, but don't insert it
|
||||
row = this.addDynamicRow(tagObj, false, true);
|
||||
var elem = row.getElementsByAttribute('fieldname', 'tag')[0];
|
||||
}
|
||||
|
||||
// Move row to appropriate place, alphabetically
|
||||
var collation = Zotero.getLocaleCollation();
|
||||
var labels = rowsElement.getElementsByAttribute('fieldname', 'tag');
|
||||
|
||||
var before = null;
|
||||
var inserted = false;
|
||||
var newTabIndex = false;
|
||||
for (var i=0; i<labels.length; i++) {
|
||||
let index = i + 1;
|
||||
if (inserted) {
|
||||
labels[i].setAttribute('ztabindex', index);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (collation.compareString(1, name, labels[i].textContent) > 0) {
|
||||
labels[i].setAttribute('ztabindex', index);
|
||||
continue;
|
||||
}
|
||||
|
||||
elem.setAttribute('ztabindex', index);
|
||||
rowsElement.insertBefore(row, labels[i].parentNode);
|
||||
newTabIndex = index;
|
||||
inserted = true;
|
||||
}
|
||||
if (!inserted) {
|
||||
newTabIndex = i + 1;
|
||||
elem.setAttribute('ztabindex', newTabIndex);
|
||||
rowsElement.appendChild(row);
|
||||
}
|
||||
|
||||
return newTabIndex;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
||||
|
@ -803,12 +832,35 @@
|
|||
|
||||
<method name="remove">
|
||||
<parameter name="id"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
this.item.removeTag(id);
|
||||
this.reload();
|
||||
]]>
|
||||
</body>
|
||||
<body><![CDATA[
|
||||
var rowsElement = this.id('tagRows');
|
||||
|
||||
var row = rowsElement.getElementsByAttribute('id', 'tag-' + id);
|
||||
row = row.length ? row[0] : false;
|
||||
if (!row) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var rows = rowsElement.childNodes;
|
||||
var removed = false;
|
||||
var oldTabIndex = -1;
|
||||
for (var i=0; i<rows.length; i++) {
|
||||
let tagID = rows[i].getAttribute('id').split('-')[1];
|
||||
if (tagID == id) {
|
||||
oldTabIndex = i + 1;
|
||||
removed = true;
|
||||
rowsElement.removeChild(rows[i]);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
// After the removal, update tab indexes
|
||||
if (removed && tagID) {
|
||||
var elem = rows[i].getElementsByAttribute('fieldname', 'tag')[0];
|
||||
elem.setAttribute('ztabindex', i + 1);
|
||||
}
|
||||
}
|
||||
return oldTabIndex;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
||||
|
@ -816,7 +868,11 @@
|
|||
<parameter name="count"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if(count === null) {
|
||||
if (!this.item) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof count == 'undefined') {
|
||||
var tags = this.item.getTags();
|
||||
if(tags)
|
||||
count = tags.length;
|
||||
|
|
|
@ -100,21 +100,13 @@
|
|||
</getter>
|
||||
</property>
|
||||
|
||||
<field name="_hasFilter">false</field>
|
||||
<field name="_filter">null</field>
|
||||
<method name="setFilterTags">
|
||||
<field name="_search">null</field>
|
||||
<method name="setSearch">
|
||||
<parameter name="val"/>
|
||||
<parameter name="skipRefresh"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (!Zotero.Utilities.isEmpty(val)) {
|
||||
this._hasFilter = true;
|
||||
this._filter = val;
|
||||
}
|
||||
else {
|
||||
this._hasFilter = !!val;
|
||||
this._filter = {};
|
||||
}
|
||||
this._search = val ? val.toLowerCase() : false;
|
||||
|
||||
if (!skipRefresh) {
|
||||
this.refresh();
|
||||
|
@ -128,12 +120,12 @@
|
|||
<property name="scope" onget="return this._scope">
|
||||
<setter>
|
||||
<![CDATA[
|
||||
if (!Zotero.Utilities.isEmpty(val)) {
|
||||
if (val && !Zotero.Utilities.isEmpty(val)) {
|
||||
this._hasScope = true;
|
||||
this._scope = val;
|
||||
}
|
||||
else {
|
||||
this._hasScope = !!val;
|
||||
this._hasScope = false;
|
||||
this._scope = {};
|
||||
}
|
||||
|
||||
|
@ -159,8 +151,8 @@
|
|||
|
||||
<constructor>
|
||||
<![CDATA[
|
||||
this.id('display-all-tags').setAttribute('checked', !this.filterToScope);
|
||||
this.id('show-automatic').setAttribute('checked', this.showAutomatic);
|
||||
this.id('display-all-tags').setAttribute('checked', !this.filterToScope);
|
||||
this.dragObserver = new this._dragObserverConstructor;
|
||||
]]>
|
||||
</constructor>
|
||||
|
@ -226,9 +218,45 @@
|
|||
// Remove children
|
||||
tagsToggleBox.textContent = "";
|
||||
|
||||
var lastTag;
|
||||
// Sort by name
|
||||
var orderedTags = [];
|
||||
var collation = Zotero.getLocaleCollation();
|
||||
for (let tagID in self._tags) {
|
||||
let tagButton = self._makeClickableTag(tagID, lastTag, self.editable);
|
||||
orderedTags.push(self._tags[tagID])
|
||||
}
|
||||
orderedTags.sort(function(a, b) {
|
||||
return collation.compareString(1, a.name, b.name);
|
||||
});
|
||||
|
||||
var tagColorsLowerCase = {};
|
||||
var colorTags = [];
|
||||
for (let name in tagColors) {
|
||||
colorTags[tagColors[name].position] = name;
|
||||
tagColorsLowerCase[name.toLowerCase()] = true;
|
||||
}
|
||||
var positions = Object.keys(colorTags);
|
||||
for (let i=positions.length-1; i>=0; i--) {
|
||||
let name = colorTags[positions[i]];
|
||||
let ids = Zotero.Tags.getIDs(name, self.libraryID);
|
||||
orderedTags.unshift({
|
||||
id: ids ? ids.join('-') : null,
|
||||
name: name,
|
||||
type: 0,
|
||||
hasColor: true
|
||||
});
|
||||
}
|
||||
|
||||
var lastTag;
|
||||
for (let i=0; i<orderedTags.length; i++) {
|
||||
let tagObj = orderedTags[i];
|
||||
|
||||
// Skip colored tags in the regular section,
|
||||
// since we add them to the beginning above
|
||||
if (!tagObj.hasColor && tagColorsLowerCase[tagObj.name.toLowerCase()]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let tagButton = self._makeClickableTag(orderedTags[i], lastTag, self.editable);
|
||||
if (tagButton) {
|
||||
tagButton.addEventListener('click', function(event) {
|
||||
self.handleTagClick(event, this);
|
||||
|
@ -245,53 +273,77 @@
|
|||
self._dirty = false;
|
||||
}
|
||||
|
||||
var searchTags = self._search ? Zotero.Tags.search(self._search) : {};
|
||||
|
||||
// Set attributes
|
||||
var colorTags = {};
|
||||
var labels = tagsToggleBox.getElementsByTagName('label');
|
||||
for (let i=0; i<labels.length; i++) {
|
||||
var tagIDs = labels[i].getAttribute('tagID').split('-');
|
||||
var tagIDs = labels[i].getAttribute('tagID');
|
||||
tagIDs = tagIDs ? tagIDs.split('-') : [];
|
||||
|
||||
let name = labels[i].value;
|
||||
let lcname = name.toLowerCase();
|
||||
|
||||
let colorData = tagColors[name];
|
||||
if (colorData) {
|
||||
labels[i].setAttribute(
|
||||
'style', 'color:' + colorData.color + '; ' + 'font-weight: bold'
|
||||
);
|
||||
}
|
||||
else {
|
||||
labels[i].removeAttribute('style');
|
||||
}
|
||||
|
||||
// Restore selection
|
||||
if (self.selection[labels[i].value]){
|
||||
if (self.selection[name]){
|
||||
labels[i].setAttribute('selected', 'true');
|
||||
}
|
||||
else {
|
||||
labels[i].setAttribute('selected', 'false');
|
||||
}
|
||||
|
||||
// Check tags against filter
|
||||
if (self._hasFilter) {
|
||||
var inFilter = false;
|
||||
for each(var tagID in tagIDs) {
|
||||
if (self._filter[tagID]) {
|
||||
inFilter = true;
|
||||
// Check tags against search
|
||||
if (self._search) {
|
||||
var inSearch = false;
|
||||
if (tagIDs.length) {
|
||||
for (let i=0; i<tagIDs.length; i++) {
|
||||
if (searchTags[tagIDs[i]]) {
|
||||
inSearch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// For colored tags, compare by name
|
||||
else if (lcname.indexOf(self._search) != -1) {
|
||||
inSearch = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check tags against scope
|
||||
if (self._hasScope) {
|
||||
var inScope = false;
|
||||
for each(var tagID in tagIDs) {
|
||||
if (self._scope[tagID]) {
|
||||
for (let i=0; i<tagIDs.length; i++) {
|
||||
if (self._scope[tagIDs[i]]) {
|
||||
inScope = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If not in filter, hide
|
||||
if (self._hasFilter && !inFilter) {
|
||||
// If not in search, hide
|
||||
if (self._search && !inSearch) {
|
||||
labels[i].setAttribute('hidden', true);
|
||||
}
|
||||
else if (self.filterToScope) {
|
||||
if (self._hasScope && inScope) {
|
||||
labels[i].className = 'zotero-clicky';
|
||||
labels[i].setAttribute('inScope', true);
|
||||
labels[i].setAttribute('hidden', false);
|
||||
empty = false;
|
||||
}
|
||||
else {
|
||||
labels[i].className = '';
|
||||
labels[i].setAttribute('hidden', true);
|
||||
labels[i].setAttribute('inScope', false);
|
||||
}
|
||||
|
@ -299,46 +351,34 @@
|
|||
// Display all
|
||||
else {
|
||||
if (self._hasScope && inScope) {
|
||||
labels[i].className = 'zotero-clicky';
|
||||
labels[i].setAttribute('inScope', true);
|
||||
}
|
||||
else {
|
||||
labels[i].className = '';
|
||||
labels[i].setAttribute('inScope', false);
|
||||
|
||||
// If out of scope, make sure it's not selected (otherwise a tag
|
||||
// stays selected after removing an item with that tag from the
|
||||
// current collection)
|
||||
if (self.selection[labels[i].value]) {
|
||||
labels[i].setAttribute('selected', false);
|
||||
delete self.selection[labels[i].value];
|
||||
var doCommand = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
labels[i].setAttribute('hidden', false);
|
||||
empty = false;
|
||||
}
|
||||
|
||||
let colorData = tagColors[labels[i].value];
|
||||
if (colorData) {
|
||||
labels[i].setAttribute(
|
||||
'style', 'color:' + colorData.color + '; ' + 'font-weight: bold'
|
||||
);
|
||||
colorTags[colorData.position] = tagsToggleBox.removeChild(labels[i]);
|
||||
// The HTMLCollection returned by getElementsByTagName() is live,
|
||||
// so since we removed something we need to decrement the counter
|
||||
i--;
|
||||
}
|
||||
else {
|
||||
labels[i].removeAttribute('style');
|
||||
}
|
||||
// If tag isn't in scope and is still selected, deselect it
|
||||
if (labels[i].getAttribute('hidden') == 'true' && self.selection[name]) {
|
||||
labels[i].setAttribute('selected', false);
|
||||
delete self.selection[name];
|
||||
var doCommand = true;
|
||||
}
|
||||
|
||||
// Add color tags to beginning in order
|
||||
var positions = Object.keys(colorTags);
|
||||
positions.sort();
|
||||
for (var i=positions.length-1; i>=0; i--) {
|
||||
tagsToggleBox.insertBefore(colorTags[positions[i]], tagsToggleBox.firstChild);
|
||||
|
||||
// Always show colored tags at top
|
||||
if (colorData) {
|
||||
labels[i].setAttribute('hidden', false);
|
||||
labels[i].setAttribute('hasColor', true);
|
||||
}
|
||||
else {
|
||||
labels[i].removeAttribute('hasColor');
|
||||
}
|
||||
}
|
||||
|
||||
//start tag cloud code
|
||||
|
@ -516,7 +556,12 @@
|
|||
// This could be more optimized to insert new/changed tags at the appropriate
|
||||
// spot if we cared, but we probably don't
|
||||
var t = me.id('tags-search').inputField;
|
||||
me.setFilterTags(Zotero.Tags.search(t.value), true);
|
||||
if (t.value) {
|
||||
me.setSearch(t.value, true);
|
||||
}
|
||||
else {
|
||||
me.setSearch(false, true);
|
||||
}
|
||||
me._dirty = true;
|
||||
me.doCommand();
|
||||
|
||||
|
@ -590,7 +635,7 @@
|
|||
if (typeof clear != 'undefined') {
|
||||
if (clear){
|
||||
t.value = '';
|
||||
this.setFilterTags(false);
|
||||
this.setSearch();
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
|
@ -598,7 +643,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
this.setFilterTags(Zotero.Tags.search(t.value));
|
||||
if (t.value) {
|
||||
this.setSearch(t.value);
|
||||
}
|
||||
else {
|
||||
this.setSearch();
|
||||
}
|
||||
return true;
|
||||
]]>
|
||||
</body>
|
||||
|
@ -639,16 +689,9 @@
|
|||
|
||||
|
||||
<method name="rename">
|
||||
<parameter name="tagIDs"/>
|
||||
<parameter name="oldName"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
tagIDs = tagIDs.split('-');
|
||||
// Convert to ints
|
||||
for (var i=0; i<tagIDs.length; i++) {
|
||||
tagIDs[i] = parseInt(tagIDs[i]);
|
||||
}
|
||||
var oldName = Zotero.Tags.getName(tagIDs[0]);
|
||||
|
||||
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
||||
.getService(Components.interfaces.nsIPromptService);
|
||||
|
||||
|
@ -658,16 +701,13 @@
|
|||
Zotero.getString('pane.tagSelector.rename.message'),
|
||||
newName, '', {});
|
||||
|
||||
if (result && newName.value) {
|
||||
// Add other ids with same tag
|
||||
var ids = Zotero.Tags.getIDs(oldName, this.libraryID);
|
||||
|
||||
for (var i=0; i<ids.length; i++) {
|
||||
if (tagIDs.indexOf(ids[i]) == -1) {
|
||||
tagIDs.push(ids[i]);
|
||||
}
|
||||
if (!result || !newName.value || oldName == newName.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get current tagIDs with the old name
|
||||
var tagIDs = Zotero.Tags.getIDs(oldName, this.libraryID) || [];
|
||||
if (tagIDs.length) {
|
||||
if (this.selection[oldName]) {
|
||||
var wasSelected = true;
|
||||
delete this.selection[oldName];
|
||||
|
@ -688,18 +728,47 @@
|
|||
Q.all(promises)
|
||||
.done();
|
||||
}
|
||||
// Colored tags don't need to exist, so in that case
|
||||
// just rename the color setting
|
||||
else {
|
||||
var self = this;
|
||||
Zotero.Tags.getColor(this.libraryID, oldName)
|
||||
.then(function (color) {
|
||||
if (color) {
|
||||
if (self.selection[oldName]) {
|
||||
var wasSelected = true;
|
||||
delete self.selection[oldName];
|
||||
}
|
||||
|
||||
return Zotero.Tags.setColor(
|
||||
self.libraryID, oldName, false
|
||||
)
|
||||
.then(function () {
|
||||
return Zotero.Tags.setColor(
|
||||
self.libraryID, newName, color
|
||||
)
|
||||
.then(function () {
|
||||
if (wasSelected) {
|
||||
self.selection[newName.value] = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
throw new Error("Can't rename missing tag");
|
||||
}
|
||||
})
|
||||
.done();
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
|
||||
<method name="delete">
|
||||
<parameter name="tagIDs"/>
|
||||
<parameter name="name"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
tagIDs = tagIDs.split('-');
|
||||
var oldName = Zotero.Tags.getName(tagIDs[0]);
|
||||
|
||||
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
||||
.getService(Components.interfaces.nsIPromptService);
|
||||
|
||||
|
@ -711,17 +780,26 @@
|
|||
Zotero.DB.beginTransaction();
|
||||
|
||||
// Add other ids with same tag
|
||||
var ids = Zotero.Tags.getIDs(oldName, this.libraryID);
|
||||
var ids = Zotero.Tags.getIDs(name, this.libraryID);
|
||||
var tagIDs = [];
|
||||
for each(var id in ids) {
|
||||
if (tagIDs.indexOf(id) == -1) {
|
||||
tagIDs.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (tagIDs.length) {
|
||||
Zotero.Tags.erase(tagIDs);
|
||||
Zotero.Tags.purge(tagIDs);
|
||||
}
|
||||
|
||||
Zotero.DB.commitTransaction()
|
||||
|
||||
// If only a tag color setting, remove that
|
||||
if (!tagIDs.length) {
|
||||
Zotero.Tags.setColor(this.libraryID, name, false);
|
||||
}
|
||||
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
|
@ -743,25 +821,27 @@
|
|||
|
||||
|
||||
<method name="_makeClickableTag">
|
||||
<parameter name="tagID"/>
|
||||
<parameter name="tagObj"/>
|
||||
<parameter name="lastTag"/>
|
||||
<parameter name="editable"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var tagInfo = this._tags[tagID], tagName = tagInfo.name;
|
||||
var tagID = tagObj.id, tagName = tagObj.name, tagType = tagObj.type;
|
||||
// If the last tag was the same, add this tagID and tagType to it
|
||||
if(lastTag && lastTag.value === tagName) {
|
||||
lastTag.setAttribute('tagID', lastTag.getAttribute('tagID') + '-' + tagID);
|
||||
lastTag.setAttribute('tagType', lastTag.getAttribute('tagType') + '-' + tagInfo.type);
|
||||
lastTag.setAttribute('tagType', lastTag.getAttribute('tagType') + '-' + tagType);
|
||||
return false;
|
||||
}
|
||||
|
||||
var label = document.createElement('label');
|
||||
label.className = 'zotero-clicky';
|
||||
|
||||
label.setAttribute('value', tagName);
|
||||
// Not used for color tags
|
||||
if (tagID) {
|
||||
label.setAttribute('tagID', tagID);
|
||||
label.setAttribute('tagType', tagInfo.type);
|
||||
}
|
||||
label.setAttribute('tagType', tagType);
|
||||
if (editable) {
|
||||
label.setAttribute('context', 'tag-menu');
|
||||
}
|
||||
|
@ -772,14 +852,12 @@
|
|||
|
||||
|
||||
<method name="_openColorPickerWindow">
|
||||
<parameter name="tagIDs"/>
|
||||
<parameter name="name"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
tagIDs = tagIDs.split('-');
|
||||
|
||||
var io = {
|
||||
libraryID: this.libraryID,
|
||||
name: Zotero.Tags.getName(tagIDs[0])
|
||||
name: name
|
||||
};
|
||||
|
||||
var self = this;
|
||||
|
@ -868,7 +946,8 @@
|
|||
|
||||
// Find a manual tag if there is one
|
||||
var tagID = null;
|
||||
var tagIDs = node.getAttribute('tagID').split(/\-/);
|
||||
var tagIDs = node.getAttribute('tagID');
|
||||
tagIDs = tagIDs ? node.getAttribute('tagID').split(/\-/) : [];
|
||||
var tagTypes = node.getAttribute('tagType').split(/\-/);
|
||||
for (var i=0; i<tagIDs.length; i++) {
|
||||
if (tagTypes[i] == 0) {
|
||||
|
@ -911,9 +990,12 @@
|
|||
<content>
|
||||
<groupbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1">
|
||||
<menupopup id="tag-menu">
|
||||
<menuitem label="&zotero.tagSelector.assignColor;" oncommand="_openColorPickerWindow(document.popupNode.getAttribute('tagID')); event.stopPropagation()"/>
|
||||
<menuitem label="&zotero.tagSelector.renameTag;" oncommand="document.getBindingParent(this).rename(document.popupNode.getAttribute('tagID')); event.stopPropagation()"/>
|
||||
<menuitem label="&zotero.tagSelector.deleteTag;" oncommand="document.getBindingParent(this).delete(document.popupNode.getAttribute('tagID')); event.stopPropagation()"/>
|
||||
<menuitem label="&zotero.tagSelector.assignColor;"
|
||||
oncommand="_openColorPickerWindow(document.popupNode.getAttribute('value')); event.stopPropagation()"/>
|
||||
<menuitem label="&zotero.tagSelector.renameTag;"
|
||||
oncommand="document.getBindingParent(this).rename(document.popupNode.getAttribute('value')); event.stopPropagation()"/>
|
||||
<menuitem label="&zotero.tagSelector.deleteTag;"
|
||||
oncommand="document.getBindingParent(this).delete(document.popupNode.getAttribute('value')); event.stopPropagation()"/>
|
||||
</menupopup>
|
||||
|
||||
<vbox id="no-tags-box" align="center" pack="center" flex="1">
|
||||
|
@ -930,15 +1012,28 @@
|
|||
onkeypress="if (event.keyCode == event.DOM_VK_ESCAPE) { document.getBindingParent(this).handleKeyPress(true); }"/>
|
||||
<toolbarbutton id="view-settings-menu" tooltiptext="&zotero.toolbar.actions.label;"
|
||||
image="chrome://zotero/skin/tag-selector-menu.png" type="menu">
|
||||
<menupopup id="view-settings-popup">
|
||||
<menupopup id="view-settings-popup"
|
||||
onpopupshown="/*
|
||||
This is necessary to fix a bug with Display All Tags not
|
||||
being checked if enabled before menuu is shown (OS X only?)
|
||||
*/
|
||||
document.getElementById('show-automatic').setAttribute('checked', document.getBindingParent(this).showAutomatic);
|
||||
document.getElementById('display-all-tags').setAttribute('checked', !document.getBindingParent(this).filterToScope);">
|
||||
<menuitem id="num-selected" disabled="true"/>
|
||||
<menuitem id="deselect-all" label="&zotero.tagSelector.clearAll;"
|
||||
oncommand="document.getBindingParent(this).clearAll(); event.stopPropagation();"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="show-automatic" label="&zotero.tagSelector.showAutomatic;" autocheck="true" type="checkbox"
|
||||
oncommand="var ts = document.getBindingParent(this); ts._dirty = true; ts.setAttribute('showAutomatic', this.getAttribute('checked') == 'true')"/>
|
||||
<menuitem id="display-all-tags" label="&zotero.tagSelector.displayAllInLibrary;" autocheck="true" type="checkbox"
|
||||
oncommand="document.getBindingParent(this).filterToScope = !(this.getAttribute('checked') == 'true'); event.stopPropagation();"/>
|
||||
<menuitem id="show-automatic" label="&zotero.tagSelector.showAutomatic;" type="checkbox"
|
||||
oncommand="var ts = document.getBindingParent(this);
|
||||
ts._dirty = true;
|
||||
var showAutomatic = this.getAttribute('checked') == 'true';
|
||||
ts.setAttribute('showAutomatic', showAutomatic);
|
||||
this.setAttribute('checked', showAutomatic);"/>
|
||||
<menuitem id="display-all-tags" label="&zotero.tagSelector.displayAllInLibrary;" type="checkbox"
|
||||
oncommand="var displayAll = this.getAttribute('checked') == 'true';
|
||||
this.setAttribute('checked', !displayAll);
|
||||
document.getBindingParent(this).filterToScope = !displayAll;
|
||||
event.stopPropagation();"/>
|
||||
</menupopup>
|
||||
</toolbarbutton>
|
||||
</hbox>
|
||||
|
|
|
@ -814,7 +814,7 @@ Zotero.CollectionTreeView.prototype.getLastViewedRow = function () {
|
|||
/*
|
||||
* Delete the selection
|
||||
*/
|
||||
Zotero.CollectionTreeView.prototype.deleteSelection = function()
|
||||
Zotero.CollectionTreeView.prototype.deleteSelection = function(deleteItems)
|
||||
{
|
||||
if(this.selection.count == 0)
|
||||
return;
|
||||
|
@ -842,14 +842,12 @@ Zotero.CollectionTreeView.prototype.deleteSelection = function()
|
|||
for (var i=0; i<rows.length; i++)
|
||||
{
|
||||
//erase collection from DB:
|
||||
var group = this._getItemAtRow(rows[i]-i);
|
||||
if(group.isCollection())
|
||||
{
|
||||
group.ref.erase();
|
||||
var itemGroup = this._getItemAtRow(rows[i]-i);
|
||||
if (itemGroup.isCollection()) {
|
||||
itemGroup.ref.erase(deleteItems);
|
||||
}
|
||||
else if(group.isSearch())
|
||||
{
|
||||
Zotero.Searches.erase(group.ref['id']);
|
||||
else if (itemGroup.isSearch()) {
|
||||
Zotero.Searches.erase(itemGroup.ref.id);
|
||||
}
|
||||
}
|
||||
this._treebox.endUpdateBatch();
|
||||
|
|
|
@ -961,7 +961,7 @@ Zotero.Collection.prototype.erase = function(deleteItems) {
|
|||
}
|
||||
}
|
||||
if (del.length) {
|
||||
Zotero.Items.erase(del);
|
||||
Zotero.Items.trash(del);
|
||||
}
|
||||
|
||||
// Remove relations
|
||||
|
|
|
@ -3869,7 +3869,9 @@ Zotero.Item.prototype.replaceTag = function(oldTagID, newTag) {
|
|||
Zotero.DB.commitTransaction();
|
||||
Zotero.Notifier.trigger('modify', 'item', this.id);
|
||||
Zotero.Notifier.trigger('remove', 'item-tag', this.id + '-' + oldTagID);
|
||||
if (id) {
|
||||
Zotero.Notifier.trigger('add', 'item-tag', this.id + '-' + id);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
|
@ -186,11 +186,6 @@ Zotero.Tags = new function() {
|
|||
return {};
|
||||
}
|
||||
|
||||
var collation = Zotero.getLocaleCollation();
|
||||
tags.sort(function(a, b) {
|
||||
return collation.compareString(1, a.name, b.name);
|
||||
});
|
||||
|
||||
var indexed = {};
|
||||
for (var i=0; i<tags.length; i++) {
|
||||
var tag = this.get(tags[i].tagID, true);
|
||||
|
@ -475,13 +470,6 @@ Zotero.Tags = new function() {
|
|||
|
||||
tagColors = tagColors || [];
|
||||
|
||||
// Remove colors for tags that don't exist
|
||||
tagColors = tagColors.filter(function (val) {
|
||||
var tagIDs = self.getIDs(val.name, libraryID);
|
||||
// TEMP: handle future getIDs return format change
|
||||
return tagIDs && tagIDs.length;
|
||||
});
|
||||
|
||||
_libraryColors[libraryID] = tagColors;
|
||||
_libraryColorsByName[libraryID] = {};
|
||||
|
||||
|
@ -515,12 +503,6 @@ Zotero.Tags = new function() {
|
|||
var tagColors = _libraryColors[libraryID];
|
||||
var tagIDs = self.getIDs(name, libraryID);
|
||||
|
||||
// Just to be safe, remove colors for tags that don't exist
|
||||
tagColors = tagColors.filter(function (val) {
|
||||
// TEMP: handle future getIDs return format change
|
||||
return tagIDs && tagIDs.length;
|
||||
});
|
||||
|
||||
// Unset
|
||||
if (!color) {
|
||||
// Trying to clear color on tag that doesn't have one
|
||||
|
@ -634,7 +616,12 @@ Zotero.Tags = new function() {
|
|||
this.toggleItemsListTags = function (libraryID, items, name) {
|
||||
var self = this;
|
||||
return Q.fcall(function () {
|
||||
var tagIDs = self.getIDs(name, libraryID);
|
||||
var tagIDs = self.getIDs(name, libraryID) || [];
|
||||
// If there's a color setting but no matching tag, don't throw
|
||||
// an error (though ideally this wouldn't be possible).
|
||||
if (!tagIDs.length) {
|
||||
return;
|
||||
}
|
||||
var tags = tagIDs.map(function (tagID) {
|
||||
return Zotero.Tags.get(tagID, true);
|
||||
});
|
||||
|
@ -834,14 +821,29 @@ Zotero.Tags = new function() {
|
|||
function erase(ids) {
|
||||
ids = Zotero.flattenArguments(ids);
|
||||
|
||||
var deleted = [];
|
||||
|
||||
Zotero.DB.beginTransaction();
|
||||
for each(var id in ids) {
|
||||
var tag = this.get(id);
|
||||
if (tag) {
|
||||
deleted.push({
|
||||
libraryID: tag.libraryID ? parseInt(tag.libraryID) : 0,
|
||||
name: tag.name
|
||||
});
|
||||
tag.erase();
|
||||
}
|
||||
}
|
||||
Zotero.DB.commitTransaction();
|
||||
|
||||
// Also delete tag color setting
|
||||
//
|
||||
// Note that this isn't done in purge(), so the setting will not
|
||||
// be removed if the tag is just removed from all items without
|
||||
// without being explicitly deleted.
|
||||
for (var i in deleted) {
|
||||
this.setColor(deleted[i].libraryID, deleted[i].name, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -188,10 +188,13 @@ Zotero.ItemTreeView.prototype._setTreeGenerator = function(treebox)
|
|||
let position = parseInt(key) - 1;
|
||||
return Zotero.Tags.getColorByPosition(libraryID, position)
|
||||
.then(function (colorData) {
|
||||
// If a color isn't assigned to this number, allow key navigation,
|
||||
// though I'm not sure this is a good idea.
|
||||
// If a color isn't assigned to this number or any
|
||||
// other numbers, allow key navigation
|
||||
if (!colorData) {
|
||||
return true;
|
||||
return Zotero.Tags.getColors(libraryID)
|
||||
.then(function (colors) {
|
||||
return !Object.keys(colors).length;
|
||||
});
|
||||
}
|
||||
|
||||
var items = self.getSelectedItems();
|
||||
|
@ -316,7 +319,6 @@ Zotero.ItemTreeView.prototype._refreshGenerator = function()
|
|||
}
|
||||
var savedSelection = this.saveSelection();
|
||||
var savedOpenState = this.saveOpenState();
|
||||
var savedFirstRow = this.saveFirstRow();
|
||||
|
||||
var oldRows = this.rowCount;
|
||||
this._dataItems = [];
|
||||
|
@ -405,7 +407,6 @@ Zotero.ItemTreeView.prototype._refreshGenerator = function()
|
|||
}
|
||||
|
||||
this.rememberOpenState(savedOpenState);
|
||||
this.rememberFirstRow(savedFirstRow);
|
||||
this.rememberSelection(savedSelection);
|
||||
this.expandMatchParents();
|
||||
if (unsuppress) {
|
||||
|
|
|
@ -408,29 +408,15 @@ Zotero.Utilities = {
|
|||
// Create a node and use the textContent property to do unescaping where
|
||||
// possible, because this approach preserves <br/>
|
||||
if(node === undefined) {
|
||||
var platformVersion = Components.classes["@mozilla.org/xre/app-info;1"]
|
||||
.getService(Components.interfaces.nsIXULAppInfo).platformVersion;
|
||||
if(Components.classes["@mozilla.org/xpcom/version-comparator;1"]
|
||||
.getService(Components.interfaces.nsIVersionComparator)
|
||||
.compare(platformVersion, "12.0") >= 0) {
|
||||
var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
|
||||
.createInstance(Components.interfaces.nsIDOMParser);
|
||||
var domDocument = parser.parseFromString("<!DOCTYPE html><html></html>",
|
||||
"text/html");
|
||||
node = domDocument.createElement("div");
|
||||
} else {
|
||||
node = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(node) {
|
||||
node.innerHTML = str;
|
||||
return node.textContent.replace(/ {2,}/g, " ");
|
||||
} else if(!nsIScriptableUnescapeHTML) {
|
||||
nsIScriptableUnescapeHTML = Components.classes["@mozilla.org/feed-unescapehtml;1"]
|
||||
.getService(Components.interfaces.nsIScriptableUnescapeHTML);
|
||||
}
|
||||
return nsIScriptableUnescapeHTML.unescape(str);
|
||||
} else if(Zotero.isNode) {
|
||||
/*var doc = require('jsdom').jsdom(str, null, {
|
||||
"features":{
|
||||
|
|
|
@ -663,7 +663,8 @@ var ZoteroPane = new function()
|
|||
if (from == 'zotero-collections-tree') {
|
||||
if ((event.keyCode == event.DOM_VK_BACK_SPACE && Zotero.isMac) ||
|
||||
event.keyCode == event.DOM_VK_DELETE) {
|
||||
ZoteroPane_Local.deleteSelectedCollection();
|
||||
var deleteItems = event.metaKey || (!Zotero.isMac && event.shiftKey);
|
||||
ZoteroPane_Local.deleteSelectedCollection(deleteItems);
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
@ -673,7 +674,7 @@ var ZoteroPane = new function()
|
|||
event.keyCode == event.DOM_VK_DELETE) {
|
||||
// If Cmd/Ctrl delete, use forced mode, which does different
|
||||
// things depending on the context
|
||||
var force = event.metaKey || (!Zotero.isMac && event.ctrlKey);
|
||||
var force = event.metaKey || (!Zotero.isMac && event.shiftKey);
|
||||
ZoteroPane_Local.deleteSelectedItems(force);
|
||||
event.preventDefault();
|
||||
return;
|
||||
|
@ -1587,7 +1588,7 @@ var ZoteroPane = new function()
|
|||
}
|
||||
|
||||
|
||||
this.deleteSelectedCollection = function () {
|
||||
this.deleteSelectedCollection = function (deleteItems) {
|
||||
var itemGroup = this.getItemGroup();
|
||||
|
||||
// Remove virtual duplicates collection
|
||||
|
@ -1606,18 +1607,52 @@ var ZoteroPane = new function()
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
||||
.getService(Components.interfaces.nsIPromptService);
|
||||
buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING
|
||||
+ ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL;
|
||||
if (this.collectionsView.selection.count == 1) {
|
||||
if (itemGroup.isCollection())
|
||||
{
|
||||
if (confirm(Zotero.getString('pane.collections.delete')))
|
||||
{
|
||||
this.collectionsView.deleteSelection();
|
||||
if (deleteItems) {
|
||||
var index = ps.confirmEx(
|
||||
null,
|
||||
Zotero.getString('pane.collections.deleteWithItems.title'),
|
||||
Zotero.getString('pane.collections.deleteWithItems'),
|
||||
buttonFlags,
|
||||
Zotero.getString('pane.collections.deleteWithItems.title'),
|
||||
"", "", "", {}
|
||||
);
|
||||
}
|
||||
else {
|
||||
var index = ps.confirmEx(
|
||||
null,
|
||||
Zotero.getString('pane.collections.delete.title'),
|
||||
Zotero.getString('pane.collections.delete')
|
||||
+ "\n\n"
|
||||
+ Zotero.getString('pane.collections.delete.keepItems'),
|
||||
buttonFlags,
|
||||
Zotero.getString('pane.collections.delete.title'),
|
||||
"", "", "", {}
|
||||
);
|
||||
}
|
||||
if (index == 0) {
|
||||
this.collectionsView.deleteSelection(deleteItems);
|
||||
}
|
||||
}
|
||||
else if (itemGroup.isSearch())
|
||||
{
|
||||
if (confirm(Zotero.getString('pane.collections.deleteSearch')))
|
||||
{
|
||||
|
||||
var index = ps.confirmEx(
|
||||
null,
|
||||
Zotero.getString('pane.collections.deleteSearch.title'),
|
||||
Zotero.getString('pane.collections.deleteSearch'),
|
||||
buttonFlags,
|
||||
Zotero.getString('pane.collections.deleteSearch.title'),
|
||||
"", "", "", {}
|
||||
);
|
||||
if (index == 0) {
|
||||
this.collectionsView.deleteSelection();
|
||||
}
|
||||
}
|
||||
|
@ -1962,7 +1997,8 @@ var ZoteroPane = new function()
|
|||
"showDuplicates",
|
||||
"showUnfiled",
|
||||
"editSelectedCollection",
|
||||
"removeCollection",
|
||||
"deleteCollection",
|
||||
"deleteCollectionAndItems",
|
||||
"sep2",
|
||||
"exportCollection",
|
||||
"createBibCollection",
|
||||
|
@ -1992,7 +2028,8 @@ var ZoteroPane = new function()
|
|||
m.newSubcollection,
|
||||
m.sep1,
|
||||
m.editSelectedCollection,
|
||||
m.removeCollection,
|
||||
m.deleteCollection,
|
||||
m.deleteCollectionAndItems,
|
||||
m.sep2,
|
||||
m.exportCollection,
|
||||
m.createBibCollection,
|
||||
|
@ -2010,7 +2047,8 @@ var ZoteroPane = new function()
|
|||
|
||||
// Adjust labels
|
||||
menu.childNodes[m.editSelectedCollection].setAttribute('label', Zotero.getString('pane.collections.menu.rename.collection'));
|
||||
menu.childNodes[m.removeCollection].setAttribute('label', Zotero.getString('pane.collections.menu.remove.collection'));
|
||||
menu.childNodes[m.deleteCollection].setAttribute('label', Zotero.getString('pane.collections.menu.delete.collection'));
|
||||
menu.childNodes[m.deleteCollectionAndItems].setAttribute('label', Zotero.getString('pane.collections.menu.delete.collectionAndItems'));
|
||||
menu.childNodes[m.exportCollection].setAttribute('label', Zotero.getString('pane.collections.menu.export.collection'));
|
||||
menu.childNodes[m.createBibCollection].setAttribute('label', Zotero.getString('pane.collections.menu.createBib.collection'));
|
||||
menu.childNodes[m.loadReport].setAttribute('label', Zotero.getString('pane.collections.menu.generateReport.collection'));
|
||||
|
@ -2018,14 +2056,14 @@ var ZoteroPane = new function()
|
|||
else if (itemGroup.isSearch()) {
|
||||
show = [
|
||||
m.editSelectedCollection,
|
||||
m.removeCollection,
|
||||
m.deleteCollection,
|
||||
m.sep2,
|
||||
m.exportCollection,
|
||||
m.createBibCollection,
|
||||
m.loadReport
|
||||
];
|
||||
|
||||
menu.childNodes[m.removeCollection].setAttribute('label', Zotero.getString('pane.collections.menu.remove.savedSearch'));
|
||||
menu.childNodes[m.deleteCollection].setAttribute('label', Zotero.getString('pane.collections.menu.delete.savedSearch'));
|
||||
|
||||
var s = [m.exportCollection, m.createBibCollection, m.loadReport];
|
||||
if (!this.itemsView.rowCount) {
|
||||
|
@ -2046,10 +2084,10 @@ var ZoteroPane = new function()
|
|||
}
|
||||
else if (itemGroup.isDuplicates() || itemGroup.isUnfiled()) {
|
||||
show = [
|
||||
m.removeCollection
|
||||
m.deleteCollection
|
||||
];
|
||||
|
||||
menu.childNodes[m.removeCollection].setAttribute('label', Zotero.getString('general.remove'));
|
||||
menu.childNodes[m.deleteCollection].setAttribute('label', Zotero.getString('general.hide'));
|
||||
}
|
||||
else if (itemGroup.isHeader()) {
|
||||
if (itemGroup.ref.id == 'commons-header') {
|
||||
|
@ -2068,7 +2106,7 @@ var ZoteroPane = new function()
|
|||
// Disable some actions if user doesn't have write access
|
||||
//
|
||||
// Some actions are disabled via their commands in onCollectionSelected()
|
||||
var s = [m.newSubcollection, m.editSelectedCollection, m.removeCollection];
|
||||
var s = [m.newSubcollection, m.editSelectedCollection, m.deleteCollection, m.deleteCollectionAndItems];
|
||||
if (itemGroup.isWithinGroup() && !itemGroup.editable && !itemGroup.isDuplicates() && !itemGroup.isUnfiled()) {
|
||||
disable = disable.concat(s);
|
||||
}
|
||||
|
@ -2337,7 +2375,7 @@ var ZoteroPane = new function()
|
|||
}
|
||||
|
||||
// Plural if necessary
|
||||
menu.childNodes[m.deleteFromLibrary].setAttribute('label', Zotero.getString('pane.items.menu.erase' + multiple));
|
||||
menu.childNodes[m.deleteFromLibrary].setAttribute('label', Zotero.getString('pane.items.menu.moveToTrash' + multiple));
|
||||
menu.childNodes[m.exportItems].setAttribute('label', Zotero.getString('pane.items.menu.export' + multiple));
|
||||
menu.childNodes[m.createBib].setAttribute('label', Zotero.getString('pane.items.menu.createBib' + multiple));
|
||||
menu.childNodes[m.loadReport].setAttribute('label', Zotero.getString('pane.items.menu.generateReport' + multiple));
|
||||
|
|
|
@ -245,6 +245,7 @@
|
|||
<menuitem label="&zotero.collections.showUnfiledItems;" oncommand="ZoteroPane_Local.setVirtual(ZoteroPane_Local.getSelectedLibraryID(), 'unfiled', true)"/>
|
||||
<menuitem oncommand="ZoteroPane_Local.editSelectedCollection();"/>
|
||||
<menuitem oncommand="ZoteroPane_Local.deleteSelectedCollection();"/>
|
||||
<menuitem oncommand="ZoteroPane_Local.deleteSelectedCollection(true);"/>
|
||||
<menuseparator/>
|
||||
<menuitem oncommand="Zotero_File_Interface.exportCollection();"/>
|
||||
<menuitem oncommand="Zotero_File_Interface.bibliographyFromCollection();"/>
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
<!ENTITY zotero.items.menu.attach.fileLink "Attach Link to File…">
|
||||
|
||||
<!ENTITY zotero.items.menu.restoreToLibrary "Restore to Library">
|
||||
<!ENTITY zotero.items.menu.duplicateItem "Duplicate Selected Item">
|
||||
<!ENTITY zotero.items.menu.duplicateItem "Duplicate Item">
|
||||
<!ENTITY zotero.items.menu.mergeItems "Merge Items…">
|
||||
|
||||
<!ENTITY zotero.duplicatesMerge.versionSelect "Choose the version of the item to use as the master item:">
|
||||
|
|
|
@ -34,11 +34,13 @@ general.permissionDenied = Permission Denied
|
|||
general.character.singular = character
|
||||
general.character.plural = characters
|
||||
general.create = Create
|
||||
general.delete = Delete
|
||||
general.seeForMoreInformation = See %S for more information.
|
||||
general.enable = Enable
|
||||
general.disable = Disable
|
||||
general.remove = Remove
|
||||
general.reset = Reset
|
||||
general.hide = Hide
|
||||
general.quit = Quit
|
||||
general.useDefault = Use Default
|
||||
general.openDocumentation = Open Documentation
|
||||
|
@ -132,7 +134,13 @@ date.relative.daysAgo.multiple = %S days ago
|
|||
date.relative.yearsAgo.one = 1 year ago
|
||||
date.relative.yearsAgo.multiple = %S years ago
|
||||
|
||||
pane.collections.delete.title = Delete Collection
|
||||
pane.collections.delete = Are you sure you want to delete the selected collection?
|
||||
pane.collections.delete.keepItems = Items within this collection will not be deleted.
|
||||
pane.collections.deleteWithItems.title = Delete Collection and Items
|
||||
pane.collections.deleteWithItems = Are you sure you want to delete the selected collection and move all items within it to the Trash?
|
||||
|
||||
pane.collections.deleteSearch.title = Delete Search
|
||||
pane.collections.deleteSearch = Are you sure you want to delete the selected search?
|
||||
pane.collections.emptyTrash = Are you sure you want to permanently remove items in the Trash?
|
||||
pane.collections.newCollection = New Collection
|
||||
|
@ -149,8 +157,9 @@ pane.collections.duplicate = Duplicate Items
|
|||
|
||||
pane.collections.menu.rename.collection = Rename Collection…
|
||||
pane.collections.menu.edit.savedSearch = Edit Saved Search
|
||||
pane.collections.menu.remove.collection = Remove Collection…
|
||||
pane.collections.menu.remove.savedSearch = Remove Saved Search…
|
||||
pane.collections.menu.delete.collection = Delete Collection…
|
||||
pane.collections.menu.delete.collectionAndItems = Delete Collection and Items…
|
||||
pane.collections.menu.delete.savedSearch = Delete Saved Search…
|
||||
pane.collections.menu.export.collection = Export Collection…
|
||||
pane.collections.menu.export.savedSearch = Export Saved Search…
|
||||
pane.collections.menu.createBib.collection = Create Bibliography From Collection…
|
||||
|
@ -180,22 +189,22 @@ pane.items.trash.multiple = Are you sure you want to move the selected items to
|
|||
pane.items.delete.title = Delete
|
||||
pane.items.delete = Are you sure you want to delete the selected item?
|
||||
pane.items.delete.multiple = Are you sure you want to delete the selected items?
|
||||
pane.items.menu.remove = Remove Selected Item
|
||||
pane.items.menu.remove.multiple = Remove Selected Items
|
||||
pane.items.menu.erase = Delete Selected Item from Library…
|
||||
pane.items.menu.erase.multiple = Delete Selected Items from Library…
|
||||
pane.items.menu.export = Export Selected Item…
|
||||
pane.items.menu.export.multiple = Export Selected Items…
|
||||
pane.items.menu.createBib = Create Bibliography from Selected Item…
|
||||
pane.items.menu.createBib.multiple = Create Bibliography from Selected Items…
|
||||
pane.items.menu.generateReport = Generate Report from Selected Item…
|
||||
pane.items.menu.generateReport.multiple = Generate Report from Selected Items…
|
||||
pane.items.menu.remove = Remove Item from Collection
|
||||
pane.items.menu.remove.multiple = Remove Items from Collection
|
||||
pane.items.menu.moveToTrash = Move Item to Trash…
|
||||
pane.items.menu.moveToTrash.multiple = Move Items to Trash…
|
||||
pane.items.menu.export = Export Item…
|
||||
pane.items.menu.export.multiple = Export Items…
|
||||
pane.items.menu.createBib = Create Bibliography from Item…
|
||||
pane.items.menu.createBib.multiple = Create Bibliography from Items…
|
||||
pane.items.menu.generateReport = Generate Report from Item…
|
||||
pane.items.menu.generateReport.multiple = Generate Report from Items…
|
||||
pane.items.menu.reindexItem = Reindex Item
|
||||
pane.items.menu.reindexItem.multiple = Reindex Items
|
||||
pane.items.menu.recognizePDF = Retrieve Metadata for PDF
|
||||
pane.items.menu.recognizePDF.multiple = Retrieve Metadata for PDFs
|
||||
pane.items.menu.createParent = Create Parent Item from Selected Item
|
||||
pane.items.menu.createParent.multiple = Create Parent Items from Selected Items
|
||||
pane.items.menu.createParent = Create Parent Item
|
||||
pane.items.menu.createParent.multiple = Create Parent Items
|
||||
pane.items.menu.renameAttachments = Rename File from Parent Metadata
|
||||
pane.items.menu.renameAttachments.multiple = Rename Files from Parent Metadata
|
||||
|
||||
|
|
|
@ -25,19 +25,18 @@ checkbox
|
|||
padding: 0 .25em 0 .25em !important;
|
||||
-moz-user-focus: ignore;
|
||||
max-width: 250px;
|
||||
border: 1px solid transparent; /* always include border so height is same as zotero-clicky */
|
||||
}
|
||||
|
||||
/* Visible out-of-scope tags should be grey */
|
||||
#tags-toggle label[inScope="false"]
|
||||
#tags-toggle label[inScope=false]:not([hasColor=true])
|
||||
{
|
||||
color: #666 !important;
|
||||
}
|
||||
|
||||
/* Don't display clicky effect to out-of-scope icons */
|
||||
label.zotero-clicky[inScope="false"]:hover,
|
||||
label.zotero-clicky[inScope="false"]:active
|
||||
#tags-toggle label[inScope=false][hasColor=true]
|
||||
{
|
||||
background: inherit !important;
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
#tags-toggle label[draggedOver="true"]
|
||||
|
|
Loading…
Reference in a new issue