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:
Abe Jellinek 2022-11-20 18:23:17 -05:00 committed by GitHub
parent 93bba41dd5
commit 74492e40c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 254 additions and 145 deletions

View file

@ -1,10 +1,10 @@
#zotero-items-toolbar[state=collapsed]
{
margin-left: -8px !important;
margin-inline-start: -8px !important;
}
#zotero-pane toolbarseparator {
margin-left: 7px;
margin-inline-start: 7px;
}
#zotero-tb-sync-stop .toolbarbutton-icon,
@ -19,14 +19,19 @@
.zotero-tb-button,
.zotero-tb-button:first-child,
.zotero-tb-button:last-child {
-moz-margin-start: 0 !important;
-moz-margin-end: 3px !important;
-moz-padding-end: 10px !important;
margin-inline-start: 0 !important;
margin-inline-end: 3px !important;
padding-right: 10px !important;
background: url("chrome://zotero/skin/mac/menubutton-end.png") right center/auto 24px no-repeat;
}
.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 {
@ -36,12 +41,35 @@
/* For menu buttons, decrease left padding by 1px */
.zotero-tb-button[type=menu] > .toolbarbutton-icon {
-moz-padding-start: 9px;
padding-left: 9px;
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 {
padding-left: 0;
padding-inline-start: 0;
}
.zotero-tb-button:-moz-window-inactive {

View file

@ -17,6 +17,10 @@
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 */
tabpanels {
-moz-appearance: none;

View file

@ -44,6 +44,10 @@
padding-left: 2px;
}
#zotero-pane[dir=rtl] .zotero-tb-button > .toolbarbutton-icon {
transform: scaleX(-1);
}
#zotero-collections-splitter:not([state=collapsed]),
#zotero-items-splitter:not([state=collapsed]),
#zotero-tags-splitter:not([state=collapsed]),

View file

@ -278,6 +278,7 @@ var CollectionTree = class CollectionTree extends LibraryTree {
let label = document.createElement('span');
label.innerText = treeRow.getName();
label.className = 'cell-text';
label.dir = 'auto';
// Editing input
div.classList.toggle('editing', treeRow == this._editing);

View file

@ -282,7 +282,7 @@ const TabBar = forwardRef(function (props, ref) {
onDragStart={(event) => handleDragStart(event, id, index)}
onDragEnd={handleDragEnd}
>
<div className="tab-name">{iconBackgroundImage &&
<div className="tab-name" dir="auto">{iconBackgroundImage &&
<span className="icon-bg" style={{ backgroundImage: iconBackgroundImage }}/>}{title}</div>
<div
className="tab-close"
@ -323,6 +323,7 @@ const TabBar = forwardRef(function (props, ref) {
onDragOver={handleTabBarDragOver}
onMouseOut={handleTabBarMouseOut}
onScroll={updateScrollArrows}
dir={Zotero.dir}
>
{tabs.map((tab, index) => renderTab(tab, index))}
</div>

View file

@ -805,8 +805,8 @@ class VirtualizedTable extends React.Component {
const aRect = a.getBoundingClientRect();
const bRect = b.getBoundingClientRect();
const resizingRect = resizing.getBoundingClientRect();
let offset = aRect.x;
if (aColumn.dataKey != resizingColumn.dataKey) {
let offset = aRect.left;
if (aColumn.dataKey != resizingColumn.dataKey && !Zotero.rtl) {
offset += resizingRect.width;
}
const widthSum = aRect.width + bRect.width;
@ -1165,6 +1165,10 @@ class VirtualizedTable extends React.Component {
ref: ref => this._topDiv = ref,
tabIndex: 0,
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) {
props.style = { display: "none" };
@ -1592,17 +1596,19 @@ var Columns = class {
}
};
function renderCell(index, data, column) {
column = column || { columnName: "" }
function renderCell(index, data, column, dir = null) {
column = column || { columnName: "" };
let span = document.createElement('span');
span.className = `cell ${column.className}`;
span.innerText = data;
if (dir) span.dir = dir;
return span;
}
function renderCheckboxCell(index, data, column) {
function renderCheckboxCell(index, data, column, dir = null) {
let span = document.createElement('span');
span.className = `cell checkbox ${column.className}`;
if (dir) span.dir = dir;
span.setAttribute('role', 'checkbox');
span.setAttribute('aria-checked', data);
if (data) {

View file

@ -922,7 +922,7 @@
// Comma
var comma = document.createElement("span");
comma.textContent = ',';
comma.textContent = Zotero.getString('punctuation.comma');
comma.className = 'comma';
firstlast.appendChild(comma);
@ -1447,7 +1447,25 @@
}
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) {
valueElement.classList.add('multiline');
}
@ -1677,6 +1695,9 @@
t.style.mozBoxFlex = 1;
t.setAttribute('fieldname', fieldName);
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;
box.replaceChild(t, elem);

View file

@ -38,8 +38,9 @@
event.preventDefault();
let rect = this.getBoundingClientRect();
let dir = getComputedStyle(this).direction;
popup.openPopupAtScreen(
window.screenX + rect.left,
window.screenX + (dir == 'rtl' ? rect.right : rect.left),
window.screenY + rect.bottom,
true
);
@ -59,7 +60,7 @@
static get dropmarkerFragment() {
let frag = document.importNode(
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
);

View file

@ -1373,17 +1373,6 @@ var ItemTree = class ItemTree extends LibraryTree {
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) {
var itemA = a.ref;
var itemB = b.ref;
@ -1401,24 +1390,12 @@ var ItemTree = class ItemTree extends LibraryTree {
var sortStringB = itemB[prop];
if (fieldA === undefined) {
let firstCreator = Zotero.Items.getSortTitle(sortStringA);
if (sortCreatorAsString) {
var fieldA = firstCreator;
}
else {
var matches = andEtAlRegExp.exec(firstCreator);
fieldA = matches ? matches[0] : '';
}
fieldA = firstCreator;
creatorSortCache[aItemID] = fieldA;
}
if (fieldB === undefined) {
let firstCreator = Zotero.Items.getSortTitle(sortStringB);
if (sortCreatorAsString) {
var fieldB = firstCreator;
}
else {
matches = andEtAlRegExp.exec(firstCreator);
fieldB = matches ? matches[0] : '';
}
fieldB = firstCreator;
creatorSortCache[bItemID] = fieldB;
}
@ -2750,6 +2727,7 @@ var ItemTree = class ItemTree extends LibraryTree {
}
let textSpanAriaLabel = [textWithFullStop, itemTypeAriaLabel, tagAriaLabel, retractedAriaLabel].join(' ');
textSpan.className = "cell-text";
textSpan.dir = 'auto';
textSpan.setAttribute('aria-label', textSpanAriaLabel);
span.append(twisty, icon, retracted, ...tagSpans, textSpan);

View file

@ -1723,7 +1723,9 @@ Zotero.Items = function() {
if (matches.length === 2) {
let a = matches[0];
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) {
return matches[0].lastName + " " + Zotero.getString('general.etAl');
@ -1786,8 +1788,8 @@ Zotero.Items = function() {
var contributorCreatorTypeID = Zotero.CreatorTypes.getID('contributor');
/* This whole block is to get the firstCreator */
var localizedAnd = Zotero.getString('general.and');
var localizedEtAl = Zotero.getString('general.etAl');
var localizedAnd = Zotero.getString('general.andJoiner').replace(/%S/g, '%s');
var localizedEtAl = Zotero.getString('general.etAl');
var sql = "COALESCE(" +
// First try for primary creator types
"CASE (" +
@ -1804,16 +1806,21 @@ Zotero.Items = function() {
"WHERE itemID=O.itemID AND primaryField=1" +
") " +
"WHEN 2 THEN (" +
"SELECT " +
"(SELECT lastName 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)" +
" || ' " + localizedAnd + " ' || " +
"(SELECT lastName 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)" +
"SELECT PRINTF(" +
`'${localizedAnd}'` +
", " +
// \u2068 FIRST STRONG ISOLATE: Isolates the directionality of characters that follow
// \u2069 POP DIRECTIONAL ISOLATE: Pops the above isolation
"(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)" +
", " +
"(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 (" +
"SELECT " +
@ -1836,14 +1843,17 @@ Zotero.Items = function() {
`WHERE itemID=O.itemID AND creatorTypeID=${editorCreatorTypeID}` +
") " +
"WHEN 2 THEN (" +
"SELECT " +
"(SELECT lastName FROM itemCreators NATURAL JOIN creators " +
`WHERE itemID=O.itemID AND creatorTypeID=${editorCreatorTypeID} ` +
"ORDER BY orderIndex LIMIT 1)" +
" || ' " + localizedAnd + " ' || " +
"(SELECT lastName FROM itemCreators NATURAL JOIN creators " +
`WHERE itemID=O.itemID AND creatorTypeID=${editorCreatorTypeID} ` +
"ORDER BY orderIndex LIMIT 1,1) " +
"SELECT PRINTF(" +
`'${localizedAnd}'` +
", " +
"(SELECT '\u2068' || lastName || '\u2069' FROM itemCreators NATURAL JOIN creators " +
`WHERE itemID=O.itemID AND creatorTypeID=${editorCreatorTypeID} ` +
"ORDER BY orderIndex LIMIT 1)" +
", " +
"(SELECT '\u2068' || lastName || '\u2069' FROM itemCreators NATURAL JOIN creators " +
`WHERE itemID=O.itemID AND creatorTypeID=${editorCreatorTypeID} ` +
"ORDER BY orderIndex LIMIT 1,1) " +
")" +
") " +
"ELSE (" +
"SELECT " +
@ -1865,14 +1875,17 @@ Zotero.Items = function() {
`WHERE itemID=O.itemID AND creatorTypeID=${contributorCreatorTypeID}` +
") " +
"WHEN 2 THEN (" +
"SELECT " +
"(SELECT lastName FROM itemCreators NATURAL JOIN creators " +
`WHERE itemID=O.itemID AND creatorTypeID=${contributorCreatorTypeID} ` +
"ORDER BY orderIndex LIMIT 1)" +
" || ' " + localizedAnd + " ' || " +
"(SELECT lastName FROM itemCreators NATURAL JOIN creators " +
`WHERE itemID=O.itemID AND creatorTypeID=${contributorCreatorTypeID} ` +
"ORDER BY orderIndex LIMIT 1,1) " +
"SELECT PRINTF(" +
`'${localizedAnd}'` +
", " +
"(SELECT '\u2068' || lastName || '\u2069' FROM itemCreators NATURAL JOIN creators " +
`WHERE itemID=O.itemID AND creatorTypeID=${contributorCreatorTypeID} ` +
"ORDER BY orderIndex LIMIT 1)" +
", " +
"(SELECT '\u2068' || lastName || '\u2069' FROM itemCreators NATURAL JOIN creators " +
`WHERE itemID=O.itemID AND creatorTypeID=${contributorCreatorTypeID} ` +
"ORDER BY orderIndex LIMIT 1,1) " +
")" +
") " +
"ELSE (" +
"SELECT " +

View file

@ -1628,7 +1628,9 @@ class EditorInstanceUtilities {
else if (authors.length === 2) {
let a = authors[0].family || authors[0].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) {
str = (authors[0].family || authors[0].literal) + ' ' + Zotero.getString('general.etAl');

View file

@ -2775,6 +2775,11 @@ var ZoteroPane = new function()
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) {
await ZoteroPane.buildCollectionContextMenu();
x = x || event.screenX;
y = y || event.screenY;
document.getElementById('zotero-collectionmenu').openPopupAtScreen(x + 1, y + 1, true);
x = x || event.clientX;
y = y || event.clientY;
openPopup(document.getElementById('zotero-collectionmenu'), x, y);
};
@ -2793,9 +2798,9 @@ var ZoteroPane = new function()
*/
this.onItemsContextMenuOpen = async function (event, x, y) {
await ZoteroPane.buildItemContextMenu();
x = x || event.screenX;
y = y || event.screenY;
document.getElementById('zotero-itemmenu').openPopupAtScreen(x + 1, y + 1, true);
x = x || event.clientX;
y = y || event.clientY;
openPopup(document.getElementById('zotero-itemmenu'), x, y);
};

View file

@ -35,6 +35,7 @@ general.notNow = Not Now
general.passed = Passed
general.failed = Failed
general.and = and
general.andJoiner = %S and %S
general.etAl = et al.
general.accessDenied = Access Denied
general.permissionDenied = Permission Denied
@ -116,6 +117,7 @@ punctuation.closingQMark = ”
punctuation.colon = :
punctuation.colon.withString = %S:
punctuation.ellipsis =
punctuation.comma = ,
install.quickStartGuide = Zotero Quick Start Guide
install.quickStartGuide.message.welcome = Welcome to Zotero!

View file

@ -207,12 +207,12 @@
}
#zotero-collections-toolbar {
margin-right: 10px; /* Set to width of splitter for visual aesthetics */
padding-left: 2px;
margin-inline-end: 10px; /* Set to width of splitter for visual aesthetics */
padding-inline-start: 2px;
}
#zotero-items-toolbar {
margin-right: 10px;
margin-inline-end: 10px;
}
.zotero-tb-button {
@ -223,18 +223,18 @@
}
.zotero-tb-button:first-child {
margin-left: 0 !important;
margin-inline-start: 0 !important;
}
.zotero-tb-button:last-child {
margin-right: 0 !important;
margin-inline-end: 0 !important;
}
.zotero-tb-button[type="menu"] {
padding-left: 3px;
padding-right: 3px;
margin-left: 4px;
margin-right: 2px;
padding-inline-start: 3px;
padding-inline-end: 3px;
margin-inline-start: 4px;
margin-inline-end: 2px;
}
.zotero-tb-button:hover:active {
@ -480,7 +480,7 @@
#zotero-tb-sync-stop
{
list-style-image: url(chrome://zotero/skin/control_stop_blue.png);
margin-right: 0;
margin-inline-end: 0;
}
#zotero-tb-sync-progress
@ -488,7 +488,7 @@
min-width: 50px;
width: 50px;
height: 10px;
margin-left: 0;
margin-inline-start: 0;
}
#zotero-tb-sync-progress-tooltip-progress {
@ -532,7 +532,7 @@
/* Sync error 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 {
@ -561,9 +561,9 @@
#zotero-tb-sync {
list-style-image: url(chrome://zotero/skin/arrow_rotate_static.png);
margin-left: -6px;
margin-right: -2px;
padding-right: 6px;
margin-inline-start: -6px;
margin-inline-end: -2px;
padding-inline-end: 6px;
}
#zotero-tb-sync .toolbarbutton-icon {
@ -606,7 +606,7 @@
}
.zotero-box {
margin-left: 5px;
margin-inline-start: 5px;
}
.zotero-box-icon {
@ -615,7 +615,7 @@
}
.zotero-box-label {
margin-left: 3px !important;
margin-inline-start: 3px !important;
}
#item-box-container {

View file

@ -10,7 +10,7 @@
#prefs-search-container {
height: 40px;
padding-right: 8px;
padding-inline-end: 8px;
}
#prefs-search {
@ -113,8 +113,7 @@ groupbox > label > h2, groupbox > * > label > h2 {
width: 0;
height: 0;
left: calc(50% - 3px);
border-right: 6px solid transparent;
border-left: 6px solid transparent;
border-inline: 6px solid transparent;
}
.search-tooltip::before {
@ -199,11 +198,11 @@ description label[class=zotero-text-link], label[class=zotero-text-link]
/* General pane */
#zotero-prefpane-general .statusLine {
margin-left: .75em;
margin-inline-start: .75em;
}
.indented-pref {
margin-left: 2em;
margin-inline-start: 2em;
}
.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
{
margin-left: 4px;
margin-inline-start: 4px;
}
#zotero-prefpane-sync .form-grid > hbox label:first-child,
#zotero-prefpane-sync .form-grid > hbox menulist:first-child
{
margin-left: 0;
margin-right: 0;
margin-inline: 0;
}
#zotero-prefpane-sync .form-grid > hbox textbox
{
margin-left: 3px;
margin-right: 3px;
margin-inline: 3px;
}
#zotero-prefpane-sync .form-grid > hbox label:last-child
{
margin-left: 0;
margin-right: 10px;
margin-inline-start: 0;
margin-inline-end: 10px;
}
#zotero-prefpane-sync #sync-auth-button {
margin-left: 0;
margin-inline-start: 0;
}
#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
{
margin-left: 40px;
margin-inline-start: 40px;
}
#storage-verify, #storage-abort, #storage-clean
{
margin-left: 0;
margin-inline-start: 0;
min-width: 8em;
}
#storage-terms label
{
margin-left: 0;
margin-inline-start: 0;
font-size: .9em;
}
#storage-terms label:first-child
{
margin-right: .25em;
margin-inline-end: .25em;
}
#storage-terms label[class=zotero-text-link]
{
margin-right: 0;
margin-inline-end: 0;
}
/* Reset tab */
#sync-reset-form {
margin-left: 1em;
margin-inline-start: 1em;
}
#reset-sync-warning {
@ -325,7 +322,7 @@ description label[class=zotero-text-link], label[class=zotero-text-link]
#sync-reset-library-menu {
width: 14em;
margin-left: .25em;
margin-inline-start: .25em;
font-size: 15px;
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 {
margin-right: 1.05em;
margin-inline-end: 1.05em;
}
#sync-reset-radiogroup > div[disabled] span {
@ -446,7 +443,7 @@ description label[class=zotero-text-link], label[class=zotero-text-link]
/* Shortcut Keys pane */
#zotero-prefpane-advanced-keys-tab input
{
margin-left: -1px;
margin-inline-start: -1px;
}
/* Advanced pane */

View file

@ -7,7 +7,8 @@
.zotero-clicky-minus, .zotero-clicky-plus {
color: transparent !important;
padding: 0 !important;
margin: 0 5px 0 0 !important;
margin: 0 !important;
margin-inline-end: 5px !important;
width: 18px;
height: 18px;
}

View file

@ -40,9 +40,10 @@ td > input {
th > label {
margin-top: 1px !important;
margin-bottom: 1px !important;
-moz-margin-start: 1px !important;
-moz-margin-end: 5px !important;
padding: 0 2px 0 2px;
-moz-box-pack: start;
margin-inline-start: 1px !important;
margin-inline-end: 5px !important;
padding: 0 2px;
}
td > [fieldname] {
@ -74,6 +75,7 @@ td > [fieldname] {
min-height: 1.5em !important;
padding: 0 !important;
margin: 0 !important;
margin-inline-end: 5px !important;
max-height: 1.5em !important;
flex: 1;
@ -122,8 +124,8 @@ th {
align-self: stretch;
font-weight: normal;
text-align: right;
margin-left: 5px !important;
margin-right: 2px !important;
margin-inline-start: 5px !important;
margin-inline-end: 2px !important;
}
#more-creators-label
@ -149,7 +151,7 @@ row label
.creator-type-label, .creator-type-value {
-moz-box-align: center;
-moz-box-pack: end;
-moz-box-pack: right;
}
.creator-name-box {
@ -171,8 +173,9 @@ row label
.creator-type-label > label
{
margin: 1px 4px 1px 0 !important;
padding-right: 2px !important;
margin: 1px 0 !important;
margin-inline-end: 4px !important;
padding-inline-end: 2px !important;
}
.creator-type-dropmarker {
@ -185,17 +188,21 @@ row label
}
.creator-name-box, .date-box > span {
margin: 1px 0 1px 0;
margin: 1px 0 !important;
margin-inline-start: 1px !important;
}
.comma {
margin: 1px 3px 1px 0 !important;
margin: 1px 0 !important;
margin-inline-end: 3px !important;
}
#zotero-date-field-status
{
color: #666;
padding: 0 10px 0 1px !important;
padding: 0 !important;
padding-inline-start: 1px !important;
padding-inline-end: 10px !important;
white-space: nowrap;
}
@ -205,7 +212,8 @@ row label
max-width: 27px !important;
min-width: 27px !important;
height: 14px;
margin: 0 5px 0 0 !important;
margin: 0 !important;
margin-inline-end: 5px !important;
background-repeat: no-repeat !important;
background-position: center !important;
border-width: 0 !important;

View file

@ -144,7 +144,15 @@
.tab-close {
position: absolute;
right: 6px;
&:dir(ltr) {
right: 6px;
}
&:dir(rtl) {
left: 6px;
}
top: 6px;
width: 16px;
height: 16px;

View file

@ -44,7 +44,6 @@
cursor: default;
white-space: nowrap;
flex-grow: 1;
flex-shrink: 1;
box-sizing: border-box;
&.primary {
@ -56,7 +55,7 @@
}
.cell-text {
flex-shrink: 1;
flex-grow: 1;
text-overflow: ellipsis;
overflow: hidden;
margin-inline-start: 5px;
@ -64,6 +63,23 @@
.twisty + .cell-text, .spacer-twisty + .cell-text {
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;
}
}

View file

@ -1,4 +1,7 @@
input {
padding: 1px 2px 1px 1px;
margin: -1px 0 -1px 0;
input
{
padding: 1px 0;
padding-inline-start: 1px;
padding-inline-end: 2px;
margin: -1px 0;
}

View file

@ -24,8 +24,11 @@ th > label, .creator-type-label, #more-creators-label {
max-height: 7px;
}
td > input, .creator-name-box > input {
margin: -1px 5px -2.5px 0;
td > input {
margin-top: -1px;
margin-bottom: -2.5px;
margin-inline-start: 0;
margin-inline-end: 5px;
padding: 0;
}

View file

@ -26,6 +26,9 @@
background-image: linear-gradient(#ddd, #ddd);
background-size: 1px 80%;
background-position: left;
&:dir(rtl) {
background-position: right;
}
background-repeat: no-repeat;
height: 100%;
}

View file

@ -9,7 +9,7 @@ row > vbox
row vbox[fieldname]
{
margin-left: 1px;
margin-inline-start: 1px;
}
.creator-type-label image {
@ -17,12 +17,16 @@ row vbox[fieldname]
}
input {
padding: 2px 2px 2px 2px;
margin: -1px 0 -1px 1px;
padding: 2px;
margin: -1px 0;
margin-inline-start: 1px;
}
#item-type-menu
{
padding: 0 0 0 1px !important;
margin: 0 5px 0 1px !important;
padding: 0 !important;
padding-inline-start: 1px !important;
margin: 0 !important;
margin-inline-start: 1px !important;
margin-inline-end: 5px !important;
}

View file

@ -1116,7 +1116,7 @@ describe("Zotero.Items", function () {
}
]
),
'B ' + Zotero.getString('general.and') + ' D',
Zotero.getString('general.andJoiner', ['B', 'D']),
creatorType
);
}
@ -1186,7 +1186,7 @@ describe("Zotero.Items", function () {
}
]
),
'D ' + Zotero.getString('general.and') + ' H',
Zotero.getString('general.andJoiner', ['D', 'H']),
creatorType
);
}