Improve bidi & RTL support (#2415)
- Render cell text in its native direction - Fix context menu positioning - Fix item box (localizations needed) - Fix column resizing - Fix bidi text in collection tree - Always right-align in RTL, always left-align in LTR. I'm going off advice from this excellent guide for RTL website design by Ahmad Shadeed: https://rtlstyling.com/posts/rtl-styling#tables - Join creators in the tree ("Smith and Jones") using a format string to support languages like Arabic and Hebrew where there shouldn't be a space after the "and". - Fix tabs - Fix toolbar on Mac, flip icons on other platforms
This commit is contained in:
parent
93bba41dd5
commit
74492e40c4
24 changed files with 254 additions and 145 deletions
|
@ -1,10 +1,10 @@
|
||||||
#zotero-items-toolbar[state=collapsed]
|
#zotero-items-toolbar[state=collapsed]
|
||||||
{
|
{
|
||||||
margin-left: -8px !important;
|
margin-inline-start: -8px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-pane toolbarseparator {
|
#zotero-pane toolbarseparator {
|
||||||
margin-left: 7px;
|
margin-inline-start: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-tb-sync-stop .toolbarbutton-icon,
|
#zotero-tb-sync-stop .toolbarbutton-icon,
|
||||||
|
@ -19,14 +19,19 @@
|
||||||
.zotero-tb-button,
|
.zotero-tb-button,
|
||||||
.zotero-tb-button:first-child,
|
.zotero-tb-button:first-child,
|
||||||
.zotero-tb-button:last-child {
|
.zotero-tb-button:last-child {
|
||||||
-moz-margin-start: 0 !important;
|
margin-inline-start: 0 !important;
|
||||||
-moz-margin-end: 3px !important;
|
margin-inline-end: 3px !important;
|
||||||
-moz-padding-end: 10px !important;
|
padding-right: 10px !important;
|
||||||
background: url("chrome://zotero/skin/mac/menubutton-end.png") right center/auto 24px no-repeat;
|
background: url("chrome://zotero/skin/mac/menubutton-end.png") right center/auto 24px no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zotero-tb-button[type=menu] {
|
.zotero-tb-button[type=menu] {
|
||||||
-moz-padding-end: 8px !important;
|
padding-inline-end: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zotero-tb-button > .toolbarbutton-icon {
|
||||||
|
background: url("chrome://zotero/skin/mac/menubutton-start.png") left center/auto 24px no-repeat;
|
||||||
|
padding: 4px 4px 4px 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zotero-tb-button > .toolbarbutton-icon {
|
.zotero-tb-button > .toolbarbutton-icon {
|
||||||
|
@ -36,12 +41,35 @@
|
||||||
|
|
||||||
/* For menu buttons, decrease left padding by 1px */
|
/* For menu buttons, decrease left padding by 1px */
|
||||||
.zotero-tb-button[type=menu] > .toolbarbutton-icon {
|
.zotero-tb-button[type=menu] > .toolbarbutton-icon {
|
||||||
-moz-padding-start: 9px;
|
padding-left: 9px;
|
||||||
max-width: 29px;
|
max-width: 29px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A decent hack: reverse the effective order of the dropmarker and icon in RTL
|
||||||
|
mode so that the above CSS, which places the menubutton-start.png background
|
||||||
|
on the toolbarbutton-icon, will make sense. (Otherwise the dropmarker appears
|
||||||
|
outside the button.) Then just flip the entire thing horizontally! We want to
|
||||||
|
do that anyway so that the Locate button will point to the left and Sync will
|
||||||
|
rotate counter-clockwise.
|
||||||
|
|
||||||
|
The other way to do this would be to set direction: ltr on buttons in the
|
||||||
|
RTL toolbar, but that breaks popup positioning. */
|
||||||
|
#zotero-pane[dir=rtl] .zotero-tb-button > .toolbarbutton-menu-dropmarker {
|
||||||
|
-moz-box-ordinal-group: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#zotero-pane[dir=rtl] .zotero-tb-button > .toolbarbutton-icon {
|
||||||
|
-moz-box-ordinal-group: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#zotero-pane[dir=rtl] .zotero-tb-button,
|
||||||
|
#zotero-pane[dir=rtl] .zotero-tb-button:first-child,
|
||||||
|
#zotero-pane[dir=rtl] .zotero-tb-button:last-child {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
|
||||||
#zotero-collections-toolbar {
|
#zotero-collections-toolbar {
|
||||||
padding-left: 0;
|
padding-inline-start: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zotero-tb-button:-moz-window-inactive {
|
.zotero-tb-button:-moz-window-inactive {
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#zotero-pane[dir=rtl] .zotero-tb-button > .toolbarbutton-icon {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Fixes tabs missing styling on (GTK 3.20) Ubuntu 16.10. See https://bugzilla.mozilla.org/show_bug.cgi?id=1306425 */
|
/* Fixes tabs missing styling on (GTK 3.20) Ubuntu 16.10. See https://bugzilla.mozilla.org/show_bug.cgi?id=1306425 */
|
||||||
tabpanels {
|
tabpanels {
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
|
|
|
@ -44,6 +44,10 @@
|
||||||
padding-left: 2px;
|
padding-left: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#zotero-pane[dir=rtl] .zotero-tb-button > .toolbarbutton-icon {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
|
||||||
#zotero-collections-splitter:not([state=collapsed]),
|
#zotero-collections-splitter:not([state=collapsed]),
|
||||||
#zotero-items-splitter:not([state=collapsed]),
|
#zotero-items-splitter:not([state=collapsed]),
|
||||||
#zotero-tags-splitter:not([state=collapsed]),
|
#zotero-tags-splitter:not([state=collapsed]),
|
||||||
|
|
|
@ -278,6 +278,7 @@ var CollectionTree = class CollectionTree extends LibraryTree {
|
||||||
let label = document.createElement('span');
|
let label = document.createElement('span');
|
||||||
label.innerText = treeRow.getName();
|
label.innerText = treeRow.getName();
|
||||||
label.className = 'cell-text';
|
label.className = 'cell-text';
|
||||||
|
label.dir = 'auto';
|
||||||
|
|
||||||
// Editing input
|
// Editing input
|
||||||
div.classList.toggle('editing', treeRow == this._editing);
|
div.classList.toggle('editing', treeRow == this._editing);
|
||||||
|
|
|
@ -282,7 +282,7 @@ const TabBar = forwardRef(function (props, ref) {
|
||||||
onDragStart={(event) => handleDragStart(event, id, index)}
|
onDragStart={(event) => handleDragStart(event, id, index)}
|
||||||
onDragEnd={handleDragEnd}
|
onDragEnd={handleDragEnd}
|
||||||
>
|
>
|
||||||
<div className="tab-name">{iconBackgroundImage &&
|
<div className="tab-name" dir="auto">{iconBackgroundImage &&
|
||||||
<span className="icon-bg" style={{ backgroundImage: iconBackgroundImage }}/>}{title}</div>
|
<span className="icon-bg" style={{ backgroundImage: iconBackgroundImage }}/>}{title}</div>
|
||||||
<div
|
<div
|
||||||
className="tab-close"
|
className="tab-close"
|
||||||
|
@ -323,6 +323,7 @@ const TabBar = forwardRef(function (props, ref) {
|
||||||
onDragOver={handleTabBarDragOver}
|
onDragOver={handleTabBarDragOver}
|
||||||
onMouseOut={handleTabBarMouseOut}
|
onMouseOut={handleTabBarMouseOut}
|
||||||
onScroll={updateScrollArrows}
|
onScroll={updateScrollArrows}
|
||||||
|
dir={Zotero.dir}
|
||||||
>
|
>
|
||||||
{tabs.map((tab, index) => renderTab(tab, index))}
|
{tabs.map((tab, index) => renderTab(tab, index))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -805,8 +805,8 @@ class VirtualizedTable extends React.Component {
|
||||||
const aRect = a.getBoundingClientRect();
|
const aRect = a.getBoundingClientRect();
|
||||||
const bRect = b.getBoundingClientRect();
|
const bRect = b.getBoundingClientRect();
|
||||||
const resizingRect = resizing.getBoundingClientRect();
|
const resizingRect = resizing.getBoundingClientRect();
|
||||||
let offset = aRect.x;
|
let offset = aRect.left;
|
||||||
if (aColumn.dataKey != resizingColumn.dataKey) {
|
if (aColumn.dataKey != resizingColumn.dataKey && !Zotero.rtl) {
|
||||||
offset += resizingRect.width;
|
offset += resizingRect.width;
|
||||||
}
|
}
|
||||||
const widthSum = aRect.width + bRect.width;
|
const widthSum = aRect.width + bRect.width;
|
||||||
|
@ -1165,6 +1165,10 @@ class VirtualizedTable extends React.Component {
|
||||||
ref: ref => this._topDiv = ref,
|
ref: ref => this._topDiv = ref,
|
||||||
tabIndex: 0,
|
tabIndex: 0,
|
||||||
role: this.props.role,
|
role: this.props.role,
|
||||||
|
// XUL's chromedir attribute doesn't work with CSS :dir selectors,
|
||||||
|
// so we'll manually propagate the locale's script direction to the
|
||||||
|
// table.
|
||||||
|
dir: Zotero.Locale.defaultScriptDirection(Zotero.locale),
|
||||||
};
|
};
|
||||||
if (this.props.hide) {
|
if (this.props.hide) {
|
||||||
props.style = { display: "none" };
|
props.style = { display: "none" };
|
||||||
|
@ -1592,17 +1596,19 @@ var Columns = class {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function renderCell(index, data, column) {
|
function renderCell(index, data, column, dir = null) {
|
||||||
column = column || { columnName: "" }
|
column = column || { columnName: "" };
|
||||||
let span = document.createElement('span');
|
let span = document.createElement('span');
|
||||||
span.className = `cell ${column.className}`;
|
span.className = `cell ${column.className}`;
|
||||||
span.innerText = data;
|
span.innerText = data;
|
||||||
|
if (dir) span.dir = dir;
|
||||||
return span;
|
return span;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderCheckboxCell(index, data, column) {
|
function renderCheckboxCell(index, data, column, dir = null) {
|
||||||
let span = document.createElement('span');
|
let span = document.createElement('span');
|
||||||
span.className = `cell checkbox ${column.className}`;
|
span.className = `cell checkbox ${column.className}`;
|
||||||
|
if (dir) span.dir = dir;
|
||||||
span.setAttribute('role', 'checkbox');
|
span.setAttribute('role', 'checkbox');
|
||||||
span.setAttribute('aria-checked', data);
|
span.setAttribute('aria-checked', data);
|
||||||
if (data) {
|
if (data) {
|
||||||
|
|
|
@ -922,7 +922,7 @@
|
||||||
|
|
||||||
// Comma
|
// Comma
|
||||||
var comma = document.createElement("span");
|
var comma = document.createElement("span");
|
||||||
comma.textContent = ',';
|
comma.textContent = Zotero.getString('punctuation.comma');
|
||||||
comma.className = 'comma';
|
comma.className = 'comma';
|
||||||
firstlast.appendChild(comma);
|
firstlast.appendChild(comma);
|
||||||
|
|
||||||
|
@ -1447,7 +1447,25 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
valueElement.textContent = valueText;
|
valueElement.textContent = valueText;
|
||||||
|
|
||||||
|
// Attempt to make bidi things work automatically:
|
||||||
|
// If we have text to work off of, let the layout engine try to guess the text direction
|
||||||
|
if (valueText) {
|
||||||
|
valueElement.dir = 'auto';
|
||||||
|
}
|
||||||
|
// If not, assume it follows the locale's direction
|
||||||
|
else {
|
||||||
|
valueElement.dir = Zotero.dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regardless, align the text in the label consistently, following the locale's direction
|
||||||
|
if (Zotero.rtl) {
|
||||||
|
valueElement.style.textAlign = 'right';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
valueElement.style.textAlign = 'left';
|
||||||
|
}
|
||||||
|
|
||||||
if (isMultiline) {
|
if (isMultiline) {
|
||||||
valueElement.classList.add('multiline');
|
valueElement.classList.add('multiline');
|
||||||
}
|
}
|
||||||
|
@ -1677,6 +1695,9 @@
|
||||||
t.style.mozBoxFlex = 1;
|
t.style.mozBoxFlex = 1;
|
||||||
t.setAttribute('fieldname', fieldName);
|
t.setAttribute('fieldname', fieldName);
|
||||||
t.setAttribute('ztabindex', tabindex);
|
t.setAttribute('ztabindex', tabindex);
|
||||||
|
// We set dir in createValueElement(), so figure out what it was computed as
|
||||||
|
// and then propagate to the new text field
|
||||||
|
t.dir = getComputedStyle(elem).direction;
|
||||||
|
|
||||||
var box = elem.parentNode;
|
var box = elem.parentNode;
|
||||||
box.replaceChild(t, elem);
|
box.replaceChild(t, elem);
|
||||||
|
|
|
@ -38,8 +38,9 @@
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
let rect = this.getBoundingClientRect();
|
let rect = this.getBoundingClientRect();
|
||||||
|
let dir = getComputedStyle(this).direction;
|
||||||
popup.openPopupAtScreen(
|
popup.openPopupAtScreen(
|
||||||
window.screenX + rect.left,
|
window.screenX + (dir == 'rtl' ? rect.right : rect.left),
|
||||||
window.screenY + rect.bottom,
|
window.screenY + rect.bottom,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
@ -59,7 +60,7 @@
|
||||||
static get dropmarkerFragment() {
|
static get dropmarkerFragment() {
|
||||||
let frag = document.importNode(
|
let frag = document.importNode(
|
||||||
MozXULElement.parseXULToFragment(`
|
MozXULElement.parseXULToFragment(`
|
||||||
<image src="chrome://zotero/skin/searchbar-dropmarker${Zotero.hiDPISuffix}.png" width="7" height="4"/>
|
<image src="chrome://zotero/skin/searchbar-dropmarker${Zotero.hiDPISuffix}.png" width="7" height="4" class="toolbarbutton-menu-dropmarker"/>
|
||||||
`),
|
`),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
|
@ -1373,17 +1373,6 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
|
|
||||||
var creatorSortCache = {};
|
var creatorSortCache = {};
|
||||||
|
|
||||||
// Regexp to extract the whole string up to an optional "and" or "et al."
|
|
||||||
var andEtAlRegExp = new RegExp(
|
|
||||||
// Extract the beginning of the string in non-greedy mode
|
|
||||||
"^.+?"
|
|
||||||
// up to either the end of the string, "et al." at the end of string
|
|
||||||
+ "(?=(?: " + Zotero.getString('general.etAl').replace('.', '\\.') + ")?$"
|
|
||||||
// or ' and '
|
|
||||||
+ "| " + Zotero.getString('general.and').replace('.', '\\.') + " "
|
|
||||||
+ ")"
|
|
||||||
);
|
|
||||||
|
|
||||||
function creatorSort(a, b) {
|
function creatorSort(a, b) {
|
||||||
var itemA = a.ref;
|
var itemA = a.ref;
|
||||||
var itemB = b.ref;
|
var itemB = b.ref;
|
||||||
|
@ -1401,24 +1390,12 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
var sortStringB = itemB[prop];
|
var sortStringB = itemB[prop];
|
||||||
if (fieldA === undefined) {
|
if (fieldA === undefined) {
|
||||||
let firstCreator = Zotero.Items.getSortTitle(sortStringA);
|
let firstCreator = Zotero.Items.getSortTitle(sortStringA);
|
||||||
if (sortCreatorAsString) {
|
fieldA = firstCreator;
|
||||||
var fieldA = firstCreator;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var matches = andEtAlRegExp.exec(firstCreator);
|
|
||||||
fieldA = matches ? matches[0] : '';
|
|
||||||
}
|
|
||||||
creatorSortCache[aItemID] = fieldA;
|
creatorSortCache[aItemID] = fieldA;
|
||||||
}
|
}
|
||||||
if (fieldB === undefined) {
|
if (fieldB === undefined) {
|
||||||
let firstCreator = Zotero.Items.getSortTitle(sortStringB);
|
let firstCreator = Zotero.Items.getSortTitle(sortStringB);
|
||||||
if (sortCreatorAsString) {
|
fieldB = firstCreator;
|
||||||
var fieldB = firstCreator;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
matches = andEtAlRegExp.exec(firstCreator);
|
|
||||||
fieldB = matches ? matches[0] : '';
|
|
||||||
}
|
|
||||||
creatorSortCache[bItemID] = fieldB;
|
creatorSortCache[bItemID] = fieldB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2750,6 +2727,7 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
}
|
}
|
||||||
let textSpanAriaLabel = [textWithFullStop, itemTypeAriaLabel, tagAriaLabel, retractedAriaLabel].join(' ');
|
let textSpanAriaLabel = [textWithFullStop, itemTypeAriaLabel, tagAriaLabel, retractedAriaLabel].join(' ');
|
||||||
textSpan.className = "cell-text";
|
textSpan.className = "cell-text";
|
||||||
|
textSpan.dir = 'auto';
|
||||||
textSpan.setAttribute('aria-label', textSpanAriaLabel);
|
textSpan.setAttribute('aria-label', textSpanAriaLabel);
|
||||||
|
|
||||||
span.append(twisty, icon, retracted, ...tagSpans, textSpan);
|
span.append(twisty, icon, retracted, ...tagSpans, textSpan);
|
||||||
|
|
|
@ -1723,7 +1723,9 @@ Zotero.Items = function() {
|
||||||
if (matches.length === 2) {
|
if (matches.length === 2) {
|
||||||
let a = matches[0];
|
let a = matches[0];
|
||||||
let b = matches[1];
|
let b = matches[1];
|
||||||
return a.lastName + " " + Zotero.getString('general.and') + " " + b.lastName;
|
// \u2068 FIRST STRONG ISOLATE: Isolates the directionality of characters that follow
|
||||||
|
// \u2069 POP DIRECTIONAL ISOLATE: Pops the above isolation
|
||||||
|
return Zotero.getString('general.andJoiner', [`\u2068${a.lastName}\u2069`, `\u2068${b.lastName}\u2069`]);
|
||||||
}
|
}
|
||||||
if (matches.length >= 3) {
|
if (matches.length >= 3) {
|
||||||
return matches[0].lastName + " " + Zotero.getString('general.etAl');
|
return matches[0].lastName + " " + Zotero.getString('general.etAl');
|
||||||
|
@ -1786,8 +1788,8 @@ Zotero.Items = function() {
|
||||||
var contributorCreatorTypeID = Zotero.CreatorTypes.getID('contributor');
|
var contributorCreatorTypeID = Zotero.CreatorTypes.getID('contributor');
|
||||||
|
|
||||||
/* This whole block is to get the firstCreator */
|
/* This whole block is to get the firstCreator */
|
||||||
var localizedAnd = Zotero.getString('general.and');
|
var localizedAnd = Zotero.getString('general.andJoiner').replace(/%S/g, '%s');
|
||||||
var localizedEtAl = Zotero.getString('general.etAl');
|
var localizedEtAl = Zotero.getString('general.etAl');
|
||||||
var sql = "COALESCE(" +
|
var sql = "COALESCE(" +
|
||||||
// First try for primary creator types
|
// First try for primary creator types
|
||||||
"CASE (" +
|
"CASE (" +
|
||||||
|
@ -1804,16 +1806,21 @@ Zotero.Items = function() {
|
||||||
"WHERE itemID=O.itemID AND primaryField=1" +
|
"WHERE itemID=O.itemID AND primaryField=1" +
|
||||||
") " +
|
") " +
|
||||||
"WHEN 2 THEN (" +
|
"WHEN 2 THEN (" +
|
||||||
"SELECT " +
|
"SELECT PRINTF(" +
|
||||||
"(SELECT lastName FROM itemCreators IC NATURAL JOIN creators " +
|
`'${localizedAnd}'` +
|
||||||
"LEFT JOIN itemTypeCreatorTypes ITCT " +
|
", " +
|
||||||
"ON (IC.creatorTypeID=ITCT.creatorTypeID AND ITCT.itemTypeID=O.itemTypeID) " +
|
// \u2068 FIRST STRONG ISOLATE: Isolates the directionality of characters that follow
|
||||||
"WHERE itemID=O.itemID AND primaryField=1 ORDER BY orderIndex LIMIT 1)" +
|
// \u2069 POP DIRECTIONAL ISOLATE: Pops the above isolation
|
||||||
" || ' " + localizedAnd + " ' || " +
|
"(SELECT '\u2068' || lastName || '\u2069' FROM itemCreators IC NATURAL JOIN creators " +
|
||||||
"(SELECT lastName FROM itemCreators IC NATURAL JOIN creators " +
|
"LEFT JOIN itemTypeCreatorTypes ITCT " +
|
||||||
"LEFT JOIN itemTypeCreatorTypes ITCT " +
|
"ON (IC.creatorTypeID=ITCT.creatorTypeID AND ITCT.itemTypeID=O.itemTypeID) " +
|
||||||
"ON (IC.creatorTypeID=ITCT.creatorTypeID AND ITCT.itemTypeID=O.itemTypeID) " +
|
"WHERE itemID=O.itemID AND primaryField=1 ORDER BY orderIndex LIMIT 1)" +
|
||||||
"WHERE itemID=O.itemID AND primaryField=1 ORDER BY orderIndex LIMIT 1,1)" +
|
", " +
|
||||||
|
"(SELECT '\u2068' || lastName || '\u2069' FROM itemCreators IC NATURAL JOIN creators " +
|
||||||
|
"LEFT JOIN itemTypeCreatorTypes ITCT " +
|
||||||
|
"ON (IC.creatorTypeID=ITCT.creatorTypeID AND ITCT.itemTypeID=O.itemTypeID) " +
|
||||||
|
"WHERE itemID=O.itemID AND primaryField=1 ORDER BY orderIndex LIMIT 1,1)" +
|
||||||
|
")" +
|
||||||
") " +
|
") " +
|
||||||
"ELSE (" +
|
"ELSE (" +
|
||||||
"SELECT " +
|
"SELECT " +
|
||||||
|
@ -1836,14 +1843,17 @@ Zotero.Items = function() {
|
||||||
`WHERE itemID=O.itemID AND creatorTypeID=${editorCreatorTypeID}` +
|
`WHERE itemID=O.itemID AND creatorTypeID=${editorCreatorTypeID}` +
|
||||||
") " +
|
") " +
|
||||||
"WHEN 2 THEN (" +
|
"WHEN 2 THEN (" +
|
||||||
"SELECT " +
|
"SELECT PRINTF(" +
|
||||||
"(SELECT lastName FROM itemCreators NATURAL JOIN creators " +
|
`'${localizedAnd}'` +
|
||||||
`WHERE itemID=O.itemID AND creatorTypeID=${editorCreatorTypeID} ` +
|
", " +
|
||||||
"ORDER BY orderIndex LIMIT 1)" +
|
"(SELECT '\u2068' || lastName || '\u2069' FROM itemCreators NATURAL JOIN creators " +
|
||||||
" || ' " + localizedAnd + " ' || " +
|
`WHERE itemID=O.itemID AND creatorTypeID=${editorCreatorTypeID} ` +
|
||||||
"(SELECT lastName FROM itemCreators NATURAL JOIN creators " +
|
"ORDER BY orderIndex LIMIT 1)" +
|
||||||
`WHERE itemID=O.itemID AND creatorTypeID=${editorCreatorTypeID} ` +
|
", " +
|
||||||
"ORDER BY orderIndex LIMIT 1,1) " +
|
"(SELECT '\u2068' || lastName || '\u2069' FROM itemCreators NATURAL JOIN creators " +
|
||||||
|
`WHERE itemID=O.itemID AND creatorTypeID=${editorCreatorTypeID} ` +
|
||||||
|
"ORDER BY orderIndex LIMIT 1,1) " +
|
||||||
|
")" +
|
||||||
") " +
|
") " +
|
||||||
"ELSE (" +
|
"ELSE (" +
|
||||||
"SELECT " +
|
"SELECT " +
|
||||||
|
@ -1865,14 +1875,17 @@ Zotero.Items = function() {
|
||||||
`WHERE itemID=O.itemID AND creatorTypeID=${contributorCreatorTypeID}` +
|
`WHERE itemID=O.itemID AND creatorTypeID=${contributorCreatorTypeID}` +
|
||||||
") " +
|
") " +
|
||||||
"WHEN 2 THEN (" +
|
"WHEN 2 THEN (" +
|
||||||
"SELECT " +
|
"SELECT PRINTF(" +
|
||||||
"(SELECT lastName FROM itemCreators NATURAL JOIN creators " +
|
`'${localizedAnd}'` +
|
||||||
`WHERE itemID=O.itemID AND creatorTypeID=${contributorCreatorTypeID} ` +
|
", " +
|
||||||
"ORDER BY orderIndex LIMIT 1)" +
|
"(SELECT '\u2068' || lastName || '\u2069' FROM itemCreators NATURAL JOIN creators " +
|
||||||
" || ' " + localizedAnd + " ' || " +
|
`WHERE itemID=O.itemID AND creatorTypeID=${contributorCreatorTypeID} ` +
|
||||||
"(SELECT lastName FROM itemCreators NATURAL JOIN creators " +
|
"ORDER BY orderIndex LIMIT 1)" +
|
||||||
`WHERE itemID=O.itemID AND creatorTypeID=${contributorCreatorTypeID} ` +
|
", " +
|
||||||
"ORDER BY orderIndex LIMIT 1,1) " +
|
"(SELECT '\u2068' || lastName || '\u2069' FROM itemCreators NATURAL JOIN creators " +
|
||||||
|
`WHERE itemID=O.itemID AND creatorTypeID=${contributorCreatorTypeID} ` +
|
||||||
|
"ORDER BY orderIndex LIMIT 1,1) " +
|
||||||
|
")" +
|
||||||
") " +
|
") " +
|
||||||
"ELSE (" +
|
"ELSE (" +
|
||||||
"SELECT " +
|
"SELECT " +
|
||||||
|
|
|
@ -1628,7 +1628,9 @@ class EditorInstanceUtilities {
|
||||||
else if (authors.length === 2) {
|
else if (authors.length === 2) {
|
||||||
let a = authors[0].family || authors[0].literal;
|
let a = authors[0].family || authors[0].literal;
|
||||||
let b = authors[1].family || authors[1].literal;
|
let b = authors[1].family || authors[1].literal;
|
||||||
str = a + ' ' + Zotero.getString('general.and') + ' ' + b;
|
// \u2068 FIRST STRONG ISOLATE: Isolates the directionality of characters that follow
|
||||||
|
// \u2069 POP DIRECTIONAL ISOLATE: Pops the above isolation
|
||||||
|
str = Zotero.getString('general.andJoiner', [`\u2068${a}\u2069`, `\u2068${b}\u2069`]);
|
||||||
}
|
}
|
||||||
else if (authors.length >= 3) {
|
else if (authors.length >= 3) {
|
||||||
str = (authors[0].family || authors[0].literal) + ' ' + Zotero.getString('general.etAl');
|
str = (authors[0].family || authors[0].literal) + ' ' + Zotero.getString('general.etAl');
|
||||||
|
|
|
@ -2775,6 +2775,11 @@ var ZoteroPane = new function()
|
||||||
|
|
||||||
return this.itemsView.getSortDirection();
|
return this.itemsView.getSortDirection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function openPopup(popup, clientX, clientY) {
|
||||||
|
popup.openPopupAtScreen(clientX + 1, clientY + 1, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2782,9 +2787,9 @@ var ZoteroPane = new function()
|
||||||
*/
|
*/
|
||||||
this.onCollectionsContextMenuOpen = async function (event, x, y) {
|
this.onCollectionsContextMenuOpen = async function (event, x, y) {
|
||||||
await ZoteroPane.buildCollectionContextMenu();
|
await ZoteroPane.buildCollectionContextMenu();
|
||||||
x = x || event.screenX;
|
x = x || event.clientX;
|
||||||
y = y || event.screenY;
|
y = y || event.clientY;
|
||||||
document.getElementById('zotero-collectionmenu').openPopupAtScreen(x + 1, y + 1, true);
|
openPopup(document.getElementById('zotero-collectionmenu'), x, y);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2793,9 +2798,9 @@ var ZoteroPane = new function()
|
||||||
*/
|
*/
|
||||||
this.onItemsContextMenuOpen = async function (event, x, y) {
|
this.onItemsContextMenuOpen = async function (event, x, y) {
|
||||||
await ZoteroPane.buildItemContextMenu();
|
await ZoteroPane.buildItemContextMenu();
|
||||||
x = x || event.screenX;
|
x = x || event.clientX;
|
||||||
y = y || event.screenY;
|
y = y || event.clientY;
|
||||||
document.getElementById('zotero-itemmenu').openPopupAtScreen(x + 1, y + 1, true);
|
openPopup(document.getElementById('zotero-itemmenu'), x, y);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ general.notNow = Not Now
|
||||||
general.passed = Passed
|
general.passed = Passed
|
||||||
general.failed = Failed
|
general.failed = Failed
|
||||||
general.and = and
|
general.and = and
|
||||||
|
general.andJoiner = %S and %S
|
||||||
general.etAl = et al.
|
general.etAl = et al.
|
||||||
general.accessDenied = Access Denied
|
general.accessDenied = Access Denied
|
||||||
general.permissionDenied = Permission Denied
|
general.permissionDenied = Permission Denied
|
||||||
|
@ -116,6 +117,7 @@ punctuation.closingQMark = ”
|
||||||
punctuation.colon = :
|
punctuation.colon = :
|
||||||
punctuation.colon.withString = %S:
|
punctuation.colon.withString = %S:
|
||||||
punctuation.ellipsis = …
|
punctuation.ellipsis = …
|
||||||
|
punctuation.comma = ,
|
||||||
|
|
||||||
install.quickStartGuide = Zotero Quick Start Guide
|
install.quickStartGuide = Zotero Quick Start Guide
|
||||||
install.quickStartGuide.message.welcome = Welcome to Zotero!
|
install.quickStartGuide.message.welcome = Welcome to Zotero!
|
||||||
|
|
|
@ -207,12 +207,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-collections-toolbar {
|
#zotero-collections-toolbar {
|
||||||
margin-right: 10px; /* Set to width of splitter for visual aesthetics */
|
margin-inline-end: 10px; /* Set to width of splitter for visual aesthetics */
|
||||||
padding-left: 2px;
|
padding-inline-start: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-items-toolbar {
|
#zotero-items-toolbar {
|
||||||
margin-right: 10px;
|
margin-inline-end: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zotero-tb-button {
|
.zotero-tb-button {
|
||||||
|
@ -223,18 +223,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.zotero-tb-button:first-child {
|
.zotero-tb-button:first-child {
|
||||||
margin-left: 0 !important;
|
margin-inline-start: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zotero-tb-button:last-child {
|
.zotero-tb-button:last-child {
|
||||||
margin-right: 0 !important;
|
margin-inline-end: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zotero-tb-button[type="menu"] {
|
.zotero-tb-button[type="menu"] {
|
||||||
padding-left: 3px;
|
padding-inline-start: 3px;
|
||||||
padding-right: 3px;
|
padding-inline-end: 3px;
|
||||||
margin-left: 4px;
|
margin-inline-start: 4px;
|
||||||
margin-right: 2px;
|
margin-inline-end: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zotero-tb-button:hover:active {
|
.zotero-tb-button:hover:active {
|
||||||
|
@ -480,7 +480,7 @@
|
||||||
#zotero-tb-sync-stop
|
#zotero-tb-sync-stop
|
||||||
{
|
{
|
||||||
list-style-image: url(chrome://zotero/skin/control_stop_blue.png);
|
list-style-image: url(chrome://zotero/skin/control_stop_blue.png);
|
||||||
margin-right: 0;
|
margin-inline-end: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-tb-sync-progress
|
#zotero-tb-sync-progress
|
||||||
|
@ -488,7 +488,7 @@
|
||||||
min-width: 50px;
|
min-width: 50px;
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
margin-left: 0;
|
margin-inline-start: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-tb-sync-progress-tooltip-progress {
|
#zotero-tb-sync-progress-tooltip-progress {
|
||||||
|
@ -532,7 +532,7 @@
|
||||||
|
|
||||||
/* Sync error panel */
|
/* Sync error panel */
|
||||||
#zotero-sync-error-panel, #zotero-sync-reminder-panel {
|
#zotero-sync-error-panel, #zotero-sync-reminder-panel {
|
||||||
margin-right: 0;
|
margin-inline-end: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-sync-error-panel .error-header, #zotero-sync-reminder-panel .header {
|
#zotero-sync-error-panel .error-header, #zotero-sync-reminder-panel .header {
|
||||||
|
@ -561,9 +561,9 @@
|
||||||
|
|
||||||
#zotero-tb-sync {
|
#zotero-tb-sync {
|
||||||
list-style-image: url(chrome://zotero/skin/arrow_rotate_static.png);
|
list-style-image: url(chrome://zotero/skin/arrow_rotate_static.png);
|
||||||
margin-left: -6px;
|
margin-inline-start: -6px;
|
||||||
margin-right: -2px;
|
margin-inline-end: -2px;
|
||||||
padding-right: 6px;
|
padding-inline-end: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-tb-sync .toolbarbutton-icon {
|
#zotero-tb-sync .toolbarbutton-icon {
|
||||||
|
@ -606,7 +606,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.zotero-box {
|
.zotero-box {
|
||||||
margin-left: 5px;
|
margin-inline-start: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zotero-box-icon {
|
.zotero-box-icon {
|
||||||
|
@ -615,7 +615,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.zotero-box-label {
|
.zotero-box-label {
|
||||||
margin-left: 3px !important;
|
margin-inline-start: 3px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#item-box-container {
|
#item-box-container {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#prefs-search-container {
|
#prefs-search-container {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
padding-right: 8px;
|
padding-inline-end: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#prefs-search {
|
#prefs-search {
|
||||||
|
@ -113,8 +113,7 @@ groupbox > label > h2, groupbox > * > label > h2 {
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
left: calc(50% - 3px);
|
left: calc(50% - 3px);
|
||||||
border-right: 6px solid transparent;
|
border-inline: 6px solid transparent;
|
||||||
border-left: 6px solid transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-tooltip::before {
|
.search-tooltip::before {
|
||||||
|
@ -199,11 +198,11 @@ description label[class=zotero-text-link], label[class=zotero-text-link]
|
||||||
|
|
||||||
/* General pane */
|
/* General pane */
|
||||||
#zotero-prefpane-general .statusLine {
|
#zotero-prefpane-general .statusLine {
|
||||||
margin-left: .75em;
|
margin-inline-start: .75em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.indented-pref {
|
.indented-pref {
|
||||||
margin-left: 2em;
|
margin-inline-start: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fileHandler-menu .menulist-icon {
|
.fileHandler-menu .menulist-icon {
|
||||||
|
@ -230,28 +229,26 @@ description label[class=zotero-text-link], label[class=zotero-text-link]
|
||||||
|
|
||||||
#zotero-prefpane-sync .form-grid > hbox
|
#zotero-prefpane-sync .form-grid > hbox
|
||||||
{
|
{
|
||||||
margin-left: 4px;
|
margin-inline-start: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-prefpane-sync .form-grid > hbox label:first-child,
|
#zotero-prefpane-sync .form-grid > hbox label:first-child,
|
||||||
#zotero-prefpane-sync .form-grid > hbox menulist:first-child
|
#zotero-prefpane-sync .form-grid > hbox menulist:first-child
|
||||||
{
|
{
|
||||||
margin-left: 0;
|
margin-inline: 0;
|
||||||
margin-right: 0;
|
|
||||||
}
|
}
|
||||||
#zotero-prefpane-sync .form-grid > hbox textbox
|
#zotero-prefpane-sync .form-grid > hbox textbox
|
||||||
{
|
{
|
||||||
margin-left: 3px;
|
margin-inline: 3px;
|
||||||
margin-right: 3px;
|
|
||||||
}
|
}
|
||||||
#zotero-prefpane-sync .form-grid > hbox label:last-child
|
#zotero-prefpane-sync .form-grid > hbox label:last-child
|
||||||
{
|
{
|
||||||
margin-left: 0;
|
margin-inline-start: 0;
|
||||||
margin-right: 10px;
|
margin-inline-end: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-prefpane-sync #sync-auth-button {
|
#zotero-prefpane-sync #sync-auth-button {
|
||||||
margin-left: 0;
|
margin-inline-start: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-prefpane-sync #sync-status-indicator
|
#zotero-prefpane-sync #sync-status-indicator
|
||||||
|
@ -280,34 +277,34 @@ description label[class=zotero-text-link], label[class=zotero-text-link]
|
||||||
|
|
||||||
.storage-settings-download-options
|
.storage-settings-download-options
|
||||||
{
|
{
|
||||||
margin-left: 40px;
|
margin-inline-start: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#storage-verify, #storage-abort, #storage-clean
|
#storage-verify, #storage-abort, #storage-clean
|
||||||
{
|
{
|
||||||
margin-left: 0;
|
margin-inline-start: 0;
|
||||||
min-width: 8em;
|
min-width: 8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#storage-terms label
|
#storage-terms label
|
||||||
{
|
{
|
||||||
margin-left: 0;
|
margin-inline-start: 0;
|
||||||
font-size: .9em;
|
font-size: .9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#storage-terms label:first-child
|
#storage-terms label:first-child
|
||||||
{
|
{
|
||||||
margin-right: .25em;
|
margin-inline-end: .25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#storage-terms label[class=zotero-text-link]
|
#storage-terms label[class=zotero-text-link]
|
||||||
{
|
{
|
||||||
margin-right: 0;
|
margin-inline-end: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset tab */
|
/* Reset tab */
|
||||||
#sync-reset-form {
|
#sync-reset-form {
|
||||||
margin-left: 1em;
|
margin-inline-start: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#reset-sync-warning {
|
#reset-sync-warning {
|
||||||
|
@ -325,7 +322,7 @@ description label[class=zotero-text-link], label[class=zotero-text-link]
|
||||||
|
|
||||||
#sync-reset-library-menu {
|
#sync-reset-library-menu {
|
||||||
width: 14em;
|
width: 14em;
|
||||||
margin-left: .25em;
|
margin-inline-start: .25em;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
height: 1.6em;
|
height: 1.6em;
|
||||||
}
|
}
|
||||||
|
@ -365,7 +362,7 @@ description label[class=zotero-text-link], label[class=zotero-text-link]
|
||||||
}
|
}
|
||||||
|
|
||||||
#sync-reset-radiogroup > div radio .radio-check {
|
#sync-reset-radiogroup > div radio .radio-check {
|
||||||
margin-right: 1.05em;
|
margin-inline-end: 1.05em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sync-reset-radiogroup > div[disabled] span {
|
#sync-reset-radiogroup > div[disabled] span {
|
||||||
|
@ -446,7 +443,7 @@ description label[class=zotero-text-link], label[class=zotero-text-link]
|
||||||
/* Shortcut Keys pane */
|
/* Shortcut Keys pane */
|
||||||
#zotero-prefpane-advanced-keys-tab input
|
#zotero-prefpane-advanced-keys-tab input
|
||||||
{
|
{
|
||||||
margin-left: -1px;
|
margin-inline-start: -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Advanced pane */
|
/* Advanced pane */
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
.zotero-clicky-minus, .zotero-clicky-plus {
|
.zotero-clicky-minus, .zotero-clicky-plus {
|
||||||
color: transparent !important;
|
color: transparent !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
margin: 0 5px 0 0 !important;
|
margin: 0 !important;
|
||||||
|
margin-inline-end: 5px !important;
|
||||||
width: 18px;
|
width: 18px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,10 @@ td > input {
|
||||||
th > label {
|
th > label {
|
||||||
margin-top: 1px !important;
|
margin-top: 1px !important;
|
||||||
margin-bottom: 1px !important;
|
margin-bottom: 1px !important;
|
||||||
-moz-margin-start: 1px !important;
|
-moz-box-pack: start;
|
||||||
-moz-margin-end: 5px !important;
|
margin-inline-start: 1px !important;
|
||||||
padding: 0 2px 0 2px;
|
margin-inline-end: 5px !important;
|
||||||
|
padding: 0 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
td > [fieldname] {
|
td > [fieldname] {
|
||||||
|
@ -74,6 +75,7 @@ td > [fieldname] {
|
||||||
min-height: 1.5em !important;
|
min-height: 1.5em !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
|
margin-inline-end: 5px !important;
|
||||||
max-height: 1.5em !important;
|
max-height: 1.5em !important;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
|
@ -122,8 +124,8 @@ th {
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
margin-left: 5px !important;
|
margin-inline-start: 5px !important;
|
||||||
margin-right: 2px !important;
|
margin-inline-end: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#more-creators-label
|
#more-creators-label
|
||||||
|
@ -149,7 +151,7 @@ row label
|
||||||
|
|
||||||
.creator-type-label, .creator-type-value {
|
.creator-type-label, .creator-type-value {
|
||||||
-moz-box-align: center;
|
-moz-box-align: center;
|
||||||
-moz-box-pack: end;
|
-moz-box-pack: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.creator-name-box {
|
.creator-name-box {
|
||||||
|
@ -171,8 +173,9 @@ row label
|
||||||
|
|
||||||
.creator-type-label > label
|
.creator-type-label > label
|
||||||
{
|
{
|
||||||
margin: 1px 4px 1px 0 !important;
|
margin: 1px 0 !important;
|
||||||
padding-right: 2px !important;
|
margin-inline-end: 4px !important;
|
||||||
|
padding-inline-end: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.creator-type-dropmarker {
|
.creator-type-dropmarker {
|
||||||
|
@ -185,17 +188,21 @@ row label
|
||||||
}
|
}
|
||||||
|
|
||||||
.creator-name-box, .date-box > span {
|
.creator-name-box, .date-box > span {
|
||||||
margin: 1px 0 1px 0;
|
margin: 1px 0 !important;
|
||||||
|
margin-inline-start: 1px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comma {
|
.comma {
|
||||||
margin: 1px 3px 1px 0 !important;
|
margin: 1px 0 !important;
|
||||||
|
margin-inline-end: 3px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-date-field-status
|
#zotero-date-field-status
|
||||||
{
|
{
|
||||||
color: #666;
|
color: #666;
|
||||||
padding: 0 10px 0 1px !important;
|
padding: 0 !important;
|
||||||
|
padding-inline-start: 1px !important;
|
||||||
|
padding-inline-end: 10px !important;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +212,8 @@ row label
|
||||||
max-width: 27px !important;
|
max-width: 27px !important;
|
||||||
min-width: 27px !important;
|
min-width: 27px !important;
|
||||||
height: 14px;
|
height: 14px;
|
||||||
margin: 0 5px 0 0 !important;
|
margin: 0 !important;
|
||||||
|
margin-inline-end: 5px !important;
|
||||||
background-repeat: no-repeat !important;
|
background-repeat: no-repeat !important;
|
||||||
background-position: center !important;
|
background-position: center !important;
|
||||||
border-width: 0 !important;
|
border-width: 0 !important;
|
||||||
|
|
|
@ -144,7 +144,15 @@
|
||||||
|
|
||||||
.tab-close {
|
.tab-close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 6px;
|
|
||||||
|
&:dir(ltr) {
|
||||||
|
right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:dir(rtl) {
|
||||||
|
left: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
top: 6px;
|
top: 6px;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
|
|
@ -44,7 +44,6 @@
|
||||||
cursor: default;
|
cursor: default;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
flex-shrink: 1;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
&.primary {
|
&.primary {
|
||||||
|
@ -56,7 +55,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.cell-text {
|
.cell-text {
|
||||||
flex-shrink: 1;
|
flex-grow: 1;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin-inline-start: 5px;
|
margin-inline-start: 5px;
|
||||||
|
@ -64,6 +63,23 @@
|
||||||
|
|
||||||
.twisty + .cell-text, .spacer-twisty + .cell-text {
|
.twisty + .cell-text, .spacer-twisty + .cell-text {
|
||||||
margin-inline-start: 0;
|
margin-inline-start: 0;
|
||||||
|
margin-inline-end: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put the margin on the other side if the directionality of the
|
||||||
|
// .cell-text is the opposite of that of the table
|
||||||
|
&:dir(ltr) .cell-text:dir(rtl),
|
||||||
|
&:dir(rtl) .cell-text:dir(ltr) {
|
||||||
|
margin-inline-start: 0;
|
||||||
|
margin-inline-end: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:dir(ltr) .cell-text {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:dir(rtl) .cell-text {
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
input {
|
input
|
||||||
padding: 1px 2px 1px 1px;
|
{
|
||||||
margin: -1px 0 -1px 0;
|
padding: 1px 0;
|
||||||
|
padding-inline-start: 1px;
|
||||||
|
padding-inline-end: 2px;
|
||||||
|
margin: -1px 0;
|
||||||
}
|
}
|
|
@ -24,8 +24,11 @@ th > label, .creator-type-label, #more-creators-label {
|
||||||
max-height: 7px;
|
max-height: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
td > input, .creator-name-box > input {
|
td > input {
|
||||||
margin: -1px 5px -2.5px 0;
|
margin-top: -1px;
|
||||||
|
margin-bottom: -2.5px;
|
||||||
|
margin-inline-start: 0;
|
||||||
|
margin-inline-end: 5px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
background-image: linear-gradient(#ddd, #ddd);
|
background-image: linear-gradient(#ddd, #ddd);
|
||||||
background-size: 1px 80%;
|
background-size: 1px 80%;
|
||||||
background-position: left;
|
background-position: left;
|
||||||
|
&:dir(rtl) {
|
||||||
|
background-position: right;
|
||||||
|
}
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ row > vbox
|
||||||
|
|
||||||
row vbox[fieldname]
|
row vbox[fieldname]
|
||||||
{
|
{
|
||||||
margin-left: 1px;
|
margin-inline-start: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.creator-type-label image {
|
.creator-type-label image {
|
||||||
|
@ -17,12 +17,16 @@ row vbox[fieldname]
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
padding: 2px 2px 2px 2px;
|
padding: 2px;
|
||||||
margin: -1px 0 -1px 1px;
|
margin: -1px 0;
|
||||||
|
margin-inline-start: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#item-type-menu
|
#item-type-menu
|
||||||
{
|
{
|
||||||
padding: 0 0 0 1px !important;
|
padding: 0 !important;
|
||||||
margin: 0 5px 0 1px !important;
|
padding-inline-start: 1px !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
margin-inline-start: 1px !important;
|
||||||
|
margin-inline-end: 5px !important;
|
||||||
}
|
}
|
|
@ -1116,7 +1116,7 @@ describe("Zotero.Items", function () {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
'B ' + Zotero.getString('general.and') + ' D',
|
Zotero.getString('general.andJoiner', ['B', 'D']),
|
||||||
creatorType
|
creatorType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1186,7 +1186,7 @@ describe("Zotero.Items", function () {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
'D ' + Zotero.getString('general.and') + ' H',
|
Zotero.getString('general.andJoiner', ['D', 'H']),
|
||||||
creatorType
|
creatorType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue