fx-compat: long tag fixer (#2649)

* Manual tag splitting from tag selector
* Only apply split to the tag in current library
* Preserve tag type
This commit is contained in:
Tom Najdek 2023-03-17 02:20:11 +01:00 committed by GitHub
parent b1595cdd1d
commit 13cc393840
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 406 additions and 251 deletions

View file

@ -642,6 +642,46 @@ Zotero.TagSelector = class TagSelectorContainer extends React.PureComponent {
await Zotero.Tags.setColor(this.libraryID, io.name, io.color, io.position); await Zotero.Tags.setColor(this.libraryID, io.name, io.color, io.position);
} }
async openTagSplitterWindow() {
const oldTagName = this.contextTag.name; // contextTag contains { name, width, color }
const dataIn = {
oldTag: this.contextTag.name,
isLongTag: false
};
const dataOut = { result: null };
window.openDialog(
'chrome://zotero/content/longTagFixer.xhtml',
'',
'chrome,modal,centerscreen',
dataIn, dataOut
);
if (!dataOut.result) {
return;
}
const oldTagID = Zotero.Tags.getID(oldTagName);
if (dataOut.result.op === 'split') {
const itemIDs = await Zotero.Tags.getTagItems(this.libraryID, oldTagID);
await Zotero.DB.executeTransaction(async () => {
for (const itemID of itemIDs) {
const item = await Zotero.Items.getAsync(itemID);
const tagType = item.getTagType(oldTagName);
for (const newTagName of dataOut.result.tags) {
item.addTag(newTagName, tagType);
}
item.removeTag(oldTagName);
await item.save();
}
await Zotero.Tags.purge(oldTagID);
});
} else {
throw new Error('Unsupported op: ' + dataOut.result.op);
}
}
async openRenamePrompt() { async openRenamePrompt() {
var promptService = Cc['@mozilla.org/embedcomp/prompt-service;1'] var promptService = Cc['@mozilla.org/embedcomp/prompt-service;1']
.getService(Ci.nsIPromptService); .getService(Ci.nsIPromptService);

View file

@ -1,9 +1,9 @@
/* /*
***** BEGIN LICENSE BLOCK ***** ***** BEGIN LICENSE BLOCK *****
Copyright © 2009 Center for History and New Media Copyright © 2022 Corporation for Digital Scholarship
George Mason University, Fairfax, Virginia, USA Vienna, Virginia, USA
http://zotero.org https://www.zotero.org
This file is part of Zotero. This file is part of Zotero.
@ -23,155 +23,178 @@
***** END LICENSE BLOCK ***** ***** END LICENSE BLOCK *****
*/ */
const HTML_NS = 'http://www.w3.org/1999/xhtml';
var Zotero_Long_Tag_Fixer = new function () { var Zotero_Long_Tag_Fixer = new function () { // eslint-disable-line camelcase, no-unused-vars
var _oldTag = window.arguments[0]; const { oldTag, isLongTag } = window.arguments?.[0] ?? { isLongTag: true, oldTag: '' };
var _dataOut = window.arguments[1]; const dataOut = window.arguments?.[1] || {};
this.init = function () { this.init = function () {
document.getElementById('zotero-old-tag').value = _oldTag; const lastMode = Zotero.Prefs.get('lastLongTagMode') || 0;
document.getElementById('zotero-old-tag-delimiter').nextSibling.value = Zotero.getString('general.character.singular'); const delimiter = Zotero.Prefs.get('lastLongTagDelimiter');
var delimiter = Zotero.Prefs.get('lastLongTagDelimiter'); this.dialog = document.getElementById('zotero-long-tag-fixer');
document.getElementById('zotero-old-tag-delimiter').value = delimiter; this.intro = document.getElementById('intro');
this.tabs = document.getElementById('zotero-new-tag-actions');
this.oldTagInput = document.getElementById('zotero-old-tag');
this.oldTag = document.getElementById('zotero-old-tag');
this.delimiterLabel = document.getElementById('delimiter-label');
this.oldTagDelimiter = document.getElementById('zotero-old-tag-delimiter');
this.listbox = document.getElementById('zotero-new-tag-list');
this.newTagInput = document.getElementById('zotero-new-tag-editor');
this.newTagCharacterCount = document.getElementById('zotero-new-tag-character-count');
this.zoteroNewTagInfo = document.getElementById('zotero-new-tag-characters');
var lastMode = Zotero.Prefs.get('lastLongTagMode'); document.addEventListener('dialogaccept', () => this.accept());
if (!lastMode) { document.addEventListener('dialogcancel', () => this.cancel());
lastMode = 0; this.tabs.addEventListener('select', (ev) => {
} if (ev.target === this.tabs.querySelector('tabpanels')) {
this.switchMode(lastMode); this.switchMode(ev.currentTarget.selectedIndex);
} }
});
this.dialog.classList.toggle('is-long-tag', isLongTag);
this.oldTagDelimiter.addEventListener('input', () => this.onUpdateDelimiter());
this.newTagInput.addEventListener('input', ev => this.updateEditLength(ev.currentTarget.value.length));
this.oldTagInput.value = oldTag;
this.oldTagDelimiter.value = delimiter;
this.updateLabel();
this.switchMode(isLongTag ? lastMode : 0);
};
this.switchMode = function (index) { this.switchMode = function (index) {
var dialog = document.getElementById('zotero-long-tag-fixer'); this.tabs.selectedIndex = index;
let buttonLabel = "";
document.getElementById('zotero-new-tag-actions').selectedIndex = index;
switch (index) { switch (index) {
default:
case 0: case 0:
var buttonLabel = "saveTags"; buttonLabel = 'saveTags';
this.updateTagList(); this.updateTagList();
document.getElementById('zotero-old-tag-delimiter').select(); this.oldTagDelimiter.select();
break; break;
case 1: case 1:
var buttonLabel = "saveTag"; buttonLabel = 'saveTag';
document.getElementById('zotero-new-tag-editor').value = _oldTag; this.newTagInput.value = oldTag;
this.updateEditLength(_oldTag.length) this.updateEditLength(oldTag.length);
break; break;
case 2: case 2:
var buttonLabel = "deleteTag"; buttonLabel = 'deleteTag';
dialog.getButton('accept').disabled = false; this.dialog.getButton('accept').disabled = false;
break; break;
} }
document.getElementById('zotero-long-tag-fixer').getButton('accept').label = Zotero.getString('sync.longTagFixer.' + buttonLabel); this.dialog.getButton('accept').label = Zotero.getString('sync.longTagFixer.' + buttonLabel);
window.sizeToContent(); window.sizeToContent();
if (isLongTag) {
Zotero.Prefs.set('lastLongTagMode', index); Zotero.Prefs.set('lastLongTagMode', index);
} }
};
/** /**
* Split tags and populate list * Split tags and populate list
*/ */
this.updateTagList = function () { this.updateTagList = function () {
var listbox = document.getElementById('zotero-new-tag-list'); let tags = [];
while (listbox.childNodes.length) {
listbox.removeChild(listbox.lastChild);
}
var delimiter = document.getElementById('zotero-old-tag-delimiter').value; const delimiter = document.getElementById('zotero-old-tag-delimiter').value;
if (delimiter) { if (delimiter) {
Zotero.Prefs.set('lastLongTagDelimiter', delimiter); Zotero.Prefs.set('lastLongTagDelimiter', delimiter);
var re = new RegExp("\\s*" + delimiter.replace(/([\.\-\[\]\(\)\?\*\+])/g, "\\$1") + "\\s*"); const re = new RegExp("\\s*" + delimiter.replace(/([\.\-\[\]\(\)\?\*\+])/g, "\\$1") + "\\s*");
var tags = _oldTag.split(re); tags = [...new Set(oldTag.split(re).filter(t => t.length > 0))];
} }
var acceptButton = document.getElementById('zotero-long-tag-fixer').getButton('accept'); const acceptButton = document.getElementById('zotero-long-tag-fixer').getButton('accept');
if (!delimiter || tags.length < 2) { if (!delimiter || tags.length < 2) {
acceptButton.disabled = true; acceptButton.disabled = true;
return; // return;
} }
else { else {
acceptButton.disabled = false; acceptButton.disabled = false;
} }
tags.sort(); tags.sort();
for (var i=0; i<tags.length; i++) {
if (i != 0 && tags[i] == tags[i-1]) { while (this.listbox.childNodes.length) {
continue; this.listbox.removeChild(this.listbox.lastChild);
}
if (!tags[i]) {
continue;
}
var li = listbox.appendItem(tags[i]);
li.setAttribute('type', 'checkbox');
li.setAttribute('checked', 'true');
} }
tags.forEach((tag) => {
const li = document.createElement('richlistitem');
const div = document.createElement('div');
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.checked = true;
checkbox.id = 'tag-' + tag;
const label = document.createElement('label');
label.setAttribute('for', 'tag-' + tag);
label.textContent = tag;
// Don't toggle checkbox for single-click on label
div.appendChild(checkbox);
div.appendChild(label);
li.appendChild(div);
this.listbox.append(li);
});
window.sizeToContent(); window.sizeToContent();
} };
this.updateLabel = function () {
this.delimiterLabel.innerHTML = this.oldTagDelimiter.value.length > 1
? Zotero.getString('general.character.plural')
: Zotero.getString('general.character.singular');
};
this.onUpdateDelimiter = function () {
this.updateLabel();
this.updateTagList();
};
this.deselectAll = function () { this.deselectAll = function () {
var lis = document.getElementById('zotero-new-tag-list').getElementsByTagName('listitem'); this.listbox.querySelectorAll('[type=checkbox]').forEach(checkbox => checkbox.checked = false);
for (var i=0; i<lis.length; i++) { };
lis[i].checked = false;
}
}
this.selectAll = function () { this.selectAll = function () {
var lis = document.getElementById('zotero-new-tag-list').getElementsByTagName('listitem'); this.listbox.querySelectorAll('[type=checkbox]').forEach(checkbox => checkbox.checked = true);
for (var i=0; i<lis.length; i++) { };
lis[i].checked = true;
}
}
this.updateEditLength = function (len) { this.updateEditLength = function (len) {
document.getElementById('zotero-new-tag-character-count').value = len; this.newTagCharacterCount.innerText = len;
var invalid = len == 0 || len > Zotero.Tags.MAX_SYNC_LENGTH; const invalid = len == 0 || len > Zotero.Tags.MAX_SYNC_LENGTH;
document.getElementById('zotero-new-tag-characters').setAttribute('invalid', invalid); this.zoteroNewTagInfo.classList.toggle('invalid', invalid);
document.getElementById('zotero-long-tag-fixer').getButton('accept').disabled = invalid; this.dialog.getButton('accept').disabled = invalid;
} };
this.cancel = function () { this.cancel = function () {
_dataOut.result = false; dataOut.result = false;
} };
this.save = function () { this.accept = function () {
try { try {
const result = {};
var result = {}; switch (this.tabs.selectedIndex) {
var index = document.getElementById('zotero-new-tag-actions').selectedIndex;
switch (index) {
// Split // Split
case 0: case 0:
// Get checked tags
var listbox = document.getElementById('zotero-new-tag-list');
var len = listbox.childElementCount;
var newTags = [];
for (var i=0; i<len; i++) {
var li = listbox.childNodes[i];
if (li.getAttribute('checked') == 'true') {
newTags.push(li.getAttribute('label'));
}
}
result.op = 'split'; result.op = 'split';
result.tags = newTags; result.tags = Array.from(this.listbox.querySelectorAll('[type=checkbox]'))
.filter(c => c.checked)
.map(n => n.nextSibling.textContent);
break; break;
// Edit // Edit
case 1: case 1:
result.op = 'edit'; result.op = 'edit';
result.tag = document.getElementById('zotero-new-tag-editor').value; result.tag = this.newTagInput.value;
break; break;
// Delete // Delete
@ -179,13 +202,11 @@ var Zotero_Long_Tag_Fixer = new function () {
result.op = 'delete'; result.op = 'delete';
break; break;
} }
dataOut.result = result;
_dataOut.result = result;
} }
catch (e) { catch (e) {
Zotero.debug(e); Zotero.debug(e);
throw (e); throw (e);
} }
} };
} };

View file

@ -0,0 +1,65 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://zotero-platform/content/zotero-react-client.css"?>
<!DOCTYPE window SYSTEM "chrome://zotero/locale/zotero.dtd">
<window
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
title="&zotero.sync.error;"
onload="Zotero_Long_Tag_Fixer.init()">
<dialog
id="zotero-long-tag-fixer"
buttons="cancel,accept"
>
<html:div id="intro">
<label value="&zotero.sync.longTagFixer.followingTagTooLong;"/>
<html:textarea id="zotero-old-tag" readonly="readonly" />
<label>&zotero.sync.longTagFixer.syncedTagSizeLimit;</label>
<label value="&zotero.sync.longTagFixer.splitEditDelete;"/>
</html:div>
<tabbox id="zotero-new-tag-actions">
<tabs>
<tab label="&zotero.sync.longTagFixer.split;"/>
<tab label="&zotero.general.edit;"/>
<tab label="&zotero.general.delete;"/>
</tabs>
<tabpanels>
<!-- Split -->
<vbox class="split-tab">
<hbox class="delimiter-input-wrap">
<label>&zotero.sync.longTagFixer.splitAtThe;</label>
<html:input
type="text"
class="delimiter-input"
id="zotero-old-tag-delimiter" />
<label id="delimiter-label"></label>
</hbox>
<richlistbox id="zotero-new-tag-list" class="tag-list" flex="1" tabindex="0" />
<label value="&zotero.sync.longTagFixer.uncheckedTagsNotSaved;"/>
<hbox>
<button label="&zotero.general.deselectAll;" oncommand="Zotero_Long_Tag_Fixer.deselectAll()"/>
<button label="&zotero.general.selectAll;" oncommand="Zotero_Long_Tag_Fixer.selectAll()"/>
</hbox>
</vbox>
<!-- Edit -->
<vbox class="edit-tab">
<html:textarea id="zotero-new-tag-editor"/>
<html:div id="zotero-new-tag-characters">
<html:span id="zotero-new-tag-character-count" />
<html:span>&zotero.sync.longTagFixer.characters;</html:span>
</html:div>
</vbox>
<!-- Delete -->
<vbox align="center" pack="center">
<label value="&zotero.sync.longTagFixer.tagWillBeDeleted;"/>
</vbox>
</tabpanels>
</tabbox>
<script src="include.js"/>
<script src="longTagFixer.js"/>
</dialog>
</window>

View file

@ -1,76 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://zotero/skin/longTagFixer.css" type="text/css"?>
<?xml-stylesheet href="chrome://zotero-platform-version/content/style.css"?>
<!DOCTYPE window SYSTEM "chrome://zotero/locale/zotero.dtd">
<dialog id="zotero-long-tag-fixer" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
buttons="accept,cancel"
onload="Zotero_Long_Tag_Fixer.init()"
ondialogcancel="Zotero_Long_Tag_Fixer.cancel()"
ondialogaccept="Zotero_Long_Tag_Fixer.save()"
title="&zotero.sync.error;">
<script src="include.js"/>
<script src="longTagFixer.js"/>
<label value="&zotero.sync.longTagFixer.followingTagTooLong;"/>
<groupbox>
<textbox id="zotero-old-tag" multiline="true" rows="4" readonly="true" class="plain"/>
</groupbox>
<label>&zotero.sync.longTagFixer.syncedTagSizeLimit;</label>
<separator class="thin"/>
<label value="&zotero.sync.longTagFixer.splitEditDelete;"/>
<separator/>
<tabbox id="zotero-new-tag-actions">
<tabs oncommand="Zotero_Long_Tag_Fixer.switchMode(this.selectedIndex)">
<tab label="&zotero.sync.longTagFixer.split;"/>
<tab label="&zotero.general.edit;"/>
<tab label="&zotero.general.delete;"/>
</tabs>
<tabpanels>
<!-- Split -->
<vbox>
<hbox align="center">
<label>&zotero.sync.longTagFixer.splitAtThe;</label>
<textbox id="zotero-old-tag-delimiter" size="1"
oninput="this.nextSibling.value = Zotero.getString('general.character.' + (this.value.length > 1 ? 'plural' : 'singular')); Zotero_Long_Tag_Fixer.updateTagList();"/>
<label/>
</hbox>
<separator class="thin"/>
<listbox id="zotero-new-tag-list" rows="8"/>
<separator class="thin"/>
<label value="&zotero.sync.longTagFixer.uncheckedTagsNotSaved;"/>
<hbox>
<button label="&zotero.general.deselectAll;" oncommand="Zotero_Long_Tag_Fixer.deselectAll()"/>
<button label="&zotero.general.selectAll;" oncommand="Zotero_Long_Tag_Fixer.selectAll()"/>
</hbox>
</vbox>
<!-- Edit -->
<vbox>
<textbox id="zotero-new-tag-editor" multiline="true" flex="1"
oninput="Zotero_Long_Tag_Fixer.updateEditLength(this.value.length)"/>
<hbox id="zotero-new-tag-characters">
<label id="zotero-new-tag-character-count"/>
<label value="&zotero.sync.longTagFixer.characters;"/>
</hbox>
</vbox>
<!-- Delete -->
<vbox align="center" pack="center">
<label value="&zotero.sync.longTagFixer.tagWillBeDeleted;"/>
</vbox>
</tabpanels>
</tabbox>
</dialog>

View file

@ -1214,46 +1214,42 @@ Zotero.Sync.Runner_Module = function (options = {}) {
.getService(Components.interfaces.nsIWindowMediator); .getService(Components.interfaces.nsIWindowMediator);
var lastWin = wm.getMostRecentWindow("navigator:browser"); var lastWin = wm.getMostRecentWindow("navigator:browser");
// Open long tag fixer for every long tag in every editable library we're syncing // Open long tag fixer for library we're syncing
var editableLibraries = options.libraries let oldTagIDs = yield Zotero.Tags.getLongTagsInLibrary(object.libraryID);
.filter(x => Zotero.Libraries.get(x).editable);
for (let libraryID of editableLibraries) {
let oldTagIDs = yield Zotero.Tags.getLongTagsInLibrary(libraryID);
for (let oldTagID of oldTagIDs) { for (let oldTagID of oldTagIDs) {
let oldTag = Zotero.Tags.getName(oldTagID); let oldTag = Zotero.Tags.getName(oldTagID);
let dataOut = { result: null }; let dataOut = { result: null };
lastWin.openDialog( lastWin.openDialog(
'chrome://zotero/content/longTagFixer.xul', 'chrome://zotero/content/longTagFixer.xhtml',
'', '',
'chrome,modal,centerscreen', 'chrome,modal,centerscreen',
oldTag, { oldTag, isLongTag: true },
dataOut dataOut
); );
// If dialog was cancelled, stop // If dialog was cancelled, stop
if (!dataOut.result) { if (!dataOut.result) {
return; return;
} }
const itemIDs = yield Zotero.Tags.getTagItems(object.libraryID, oldTagID);
switch (dataOut.result.op) { switch (dataOut.result.op) {
case 'split': case 'split':
for (let libraryID of editableLibraries) {
let itemIDs = yield Zotero.Tags.getTagItems(libraryID, oldTagID);
yield Zotero.DB.executeTransaction(async function () { yield Zotero.DB.executeTransaction(async function () {
for (let itemID of itemIDs) { for (let itemID of itemIDs) {
let item = await Zotero.Items.getAsync(itemID); let item = await Zotero.Items.getAsync(itemID);
let tagType = item.getTagType(oldTag);
for (let tag of dataOut.result.tags) { for (let tag of dataOut.result.tags) {
item.addTag(tag); item.addTag(tag, tagType);
} }
item.removeTag(oldTag); item.removeTag(oldTag);
await item.save(); await item.save();
} }
await Zotero.Tags.purge(oldTagID); await Zotero.Tags.purge(oldTagID);
}); });
}
break; break;
case 'edit': case 'edit':
for (let libraryID of editableLibraries) {
let itemIDs = yield Zotero.Tags.getTagItems(libraryID, oldTagID);
yield Zotero.DB.executeTransaction(async function () { yield Zotero.DB.executeTransaction(async function () {
for (let itemID of itemIDs) { for (let itemID of itemIDs) {
let item = await Zotero.Items.getAsync(itemID); let item = await Zotero.Items.getAsync(itemID);
@ -1261,17 +1257,13 @@ Zotero.Sync.Runner_Module = function (options = {}) {
await item.save(); await item.save();
} }
}); });
}
break; break;
case 'delete': case 'delete':
for (let libraryID of editableLibraries) { yield Zotero.Tags.removeFromLibrary(object.libraryID, oldTagID);
yield Zotero.Tags.removeFromLibrary(libraryID, oldTagID);
}
break; break;
} }
} }
}
options.restartSync = true; options.restartSync = true;
}); });

View file

@ -1202,6 +1202,8 @@
oncommand="ZoteroPane.tagSelector.openColorPickerWindow(); event.stopPropagation();"/> oncommand="ZoteroPane.tagSelector.openColorPickerWindow(); event.stopPropagation();"/>
<menuitem label="&zotero.tagSelector.renameTag;" <menuitem label="&zotero.tagSelector.renameTag;"
oncommand="ZoteroPane.tagSelector.openRenamePrompt(); event.stopPropagation();"/> oncommand="ZoteroPane.tagSelector.openRenamePrompt(); event.stopPropagation();"/>
<menuitem id="split-tag" label="&zotero.tagSelector.splitTag;"
oncommand="ZoteroPane.tagSelector.openTagSplitterWindow(event)"/>
<menuitem label="&zotero.tagSelector.deleteTag;" <menuitem label="&zotero.tagSelector.deleteTag;"
oncommand="ZoteroPane.tagSelector.openDeletePrompt(); event.stopPropagation();"/> oncommand="ZoteroPane.tagSelector.openDeletePrompt(); event.stopPropagation();"/>
</menupopup> </menupopup>

View file

@ -139,6 +139,7 @@
<!ENTITY zotero.tagSelector.assignColor "Assign Color…"> <!ENTITY zotero.tagSelector.assignColor "Assign Color…">
<!ENTITY zotero.tagSelector.renameTag "Rename Tag…"> <!ENTITY zotero.tagSelector.renameTag "Rename Tag…">
<!ENTITY zotero.tagSelector.deleteTag "Delete Tag…"> <!ENTITY zotero.tagSelector.deleteTag "Delete Tag…">
<!ENTITY zotero.tagSelector.splitTag "Split…">
<!ENTITY zotero.tagColorChooser.title "Choose a Tag Color and Position"> <!ENTITY zotero.tagColorChooser.title "Choose a Tag Color and Position">
<!ENTITY zotero.tagColorChooser.color "Color:"> <!ENTITY zotero.tagColorChooser.color "Color:">

View file

@ -1,8 +0,0 @@
#zotero-new-tag-characters[invalid="true"] {
color: red;
}
#zotero-new-tag-character-count {
font-weight: bold;
margin-right: 0;
}

View file

@ -25,11 +25,14 @@
@import "components/autosuggest"; @import "components/autosuggest";
@import "components/button"; @import "components/button";
@import "components/clicky"; @import "components/clicky";
@import "components/collection-tree";
@import "components/createParent"; @import "components/createParent";
@import "components/dictionaryManager"; @import "components/dictionaryManager";
@import "components/editable"; @import "components/editable";
@import "components/exportOptions"; @import "components/exportOptions";
@import "components/icons"; @import "components/icons";
@import "components/item-tree";
@import "components/longTagFixer";
@import "components/mainWindow"; @import "components/mainWindow";
@import "components/notesList"; @import "components/notesList";
@import "components/progressMeter"; @import "components/progressMeter";
@ -38,9 +41,7 @@
@import "components/tabBar"; @import "components/tabBar";
@import "components/tagsBox"; @import "components/tagsBox";
@import "components/tagSelector"; @import "components/tagSelector";
@import "components/collection-tree";
@import "components/virtualized-table"; @import "components/virtualized-table";
@import "components/item-tree";
// Elements // Elements
// -------------------------------------------------- // --------------------------------------------------

View file

@ -2,3 +2,8 @@
// Utilities // Utilities
// -------------------------------------------------- // --------------------------------------------------
@mixin text-truncate($text-overflow: ellipsis) {
white-space: nowrap;
overflow: hidden;
text-overflow: $text-overflow;
}

View file

@ -0,0 +1,112 @@
#zotero-long-tag-fixer {
min-width: 400px; // with intro disabled, dialog tends to get to narrow
tab {
display: none;
@include variant("#zotero-long-tag-fixer.is-long-tag") {
display: revert;
}
}
tabpanels {
padding-top: 15px;
@include variant("#zotero-long-tag-fixer.is-long-tag") {
padding-top: 33px;
}
}
tab[visuallyselected="true"]:not(:-moz-window-inactive) {
color: unset;
}
#intro {
display: none;
flex-direction: column;
@include variant("#zotero-long-tag-fixer.is-long-tag") {
display: flex;
}
> label {
margin: .5em 0 0 0;
}
> textarea {
margin: 1em;
height: 50px;
border: none;
padding: .5em;
background-color: $shade-1;
appearance: none;
outline: none;
}
}
#zotero-new-tag-actions {
margin-top: 1em;
}
.split-tab {
.tag-list {
height: calc(8 * (1em + 10px));
overflow-x: hidden;
overflow-y: scroll;
> richlistitem {
display: block;
height: calc(1em + 10px);
overflow: hidden;
}
div {
display: flex;
align-items: center;
}
label {
// width of the label is set to the width of the viewport minus sum of widths of
// paddings, margins and a checkbox to produce ellipsis truncation.
width: calc(100vw - 100px);
@include text-truncate;
}
}
.delimiter-input {
width: 20px;
}
.delimiter-input-wrap {
display: flex;
align-items: center;
}
.tag-list + label {
padding: 0.5em 0;
}
}
.edit-tab {
display: flex;
flex-direction: column;
#zotero-new-tag-editor {
flex: 1 1 auto;
}
#zotero-new-tag-characters {
flex: 0 1 auto;
padding: .5em 0;
}
}
.invalid {
color: $red;
}
#zotero-new-tag-character-count {
font-weight: bold;
margin-right: 0;
}
}

View file

@ -1321,7 +1321,7 @@ describe("Zotero.Sync.Runner", function () {
} }
}); });
waitForDialog(null, 'accept', 'chrome://zotero/content/longTagFixer.xul'); waitForDialog(null, 'accept', 'chrome://zotero/content/longTagFixer.xhtml');
yield runner.sync({ libraries: [Zotero.Libraries.userLibraryID] }); yield runner.sync({ libraries: [Zotero.Libraries.userLibraryID] });
assert.isFalse(Zotero.Tags.getID(tag)); assert.isFalse(Zotero.Tags.getID(tag));
@ -1391,9 +1391,9 @@ describe("Zotero.Sync.Runner", function () {
} }
}); });
waitForDialog(function (dialog) { waitForDialog(function (window) {
dialog.Zotero_Long_Tag_Fixer.switchMode(2); window.Zotero_Long_Tag_Fixer.switchMode(2);
}, 'accept', 'chrome://zotero/content/longTagFixer.xul'); }, 'accept', 'chrome://zotero/content/longTagFixer.xhtml');
yield runner.sync({ libraries: [Zotero.Libraries.userLibraryID] }); yield runner.sync({ libraries: [Zotero.Libraries.userLibraryID] });
assert.isFalse(Zotero.Tags.getID(tag)); assert.isFalse(Zotero.Tags.getID(tag));