-
-
+
+
+ { item.attachmentFilename }
+
+
-
+
);
}
diff --git a/chrome/content/zotero/components/progressQueueTable.jsx b/chrome/content/zotero/components/progressQueueTable.jsx
index 4406080979..53bf1a0732 100644
--- a/chrome/content/zotero/components/progressQueueTable.jsx
+++ b/chrome/content/zotero/components/progressQueueTable.jsx
@@ -25,7 +25,6 @@
import React, { memo, useCallback, useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import { getDOMElement } from 'components/icons';
-import { IntlProvider } from 'react-intl';
import VirtualizedTable, { renderCell } from 'components/virtualized-table';
import { noop } from './utils';
@@ -101,17 +100,15 @@ const ProgressQueueTable = ({ onActivate = noop, progressQueue }) => {
}, []); // eslint-disable-line react-hooks/exhaustive-deps
return (
-
-
-
+
);
};
diff --git a/chrome/content/zotero/components/tagSelector/tagSelectorList.jsx b/chrome/content/zotero/components/tagSelector/tagSelectorList.jsx
index 29045e7e0f..f2a67d803d 100644
--- a/chrome/content/zotero/components/tagSelector/tagSelectorList.jsx
+++ b/chrome/content/zotero/components/tagSelector/tagSelectorList.jsx
@@ -25,7 +25,6 @@
const React = require('react');
const PropTypes = require('prop-types');
-const { FormattedMessage } = require('react-intl');
var { Collection } = require('react-virtualized');
// See also .tag-selector-item in _tag-selector.scss
@@ -191,14 +190,14 @@ class TagList extends React.PureComponent {
if (!this.props.loaded) {
tagList = (
-
+ {Zotero.getString('zotero.tagSelector.loadingTags')}
);
}
else if (tagCount == 0) {
tagList = (
-
+ {Zotero.getString('zotero.tagSelector.noTagsToDisplay')}
);
}
diff --git a/chrome/content/zotero/components/virtualized-table.jsx b/chrome/content/zotero/components/virtualized-table.jsx
index 91a2f79eca..f6a109ae71 100644
--- a/chrome/content/zotero/components/virtualized-table.jsx
+++ b/chrome/content/zotero/components/virtualized-table.jsx
@@ -30,7 +30,6 @@ const PropTypes = require('prop-types');
const cx = require('classnames');
const WindowedList = require('./windowed-list');
const Draggable = require('./draggable');
-const { injectIntl } = require('react-intl');
const { IconDownChevron, getDOMElement } = require('components/icons');
const TYPING_TIMEOUT = 1000;
@@ -1636,7 +1635,7 @@ function makeRowRenderer(getRowData) {
function formatColumnName(column) {
if (column.label in Zotero.Intl.strings) {
- return Zotero.Intl.strings[column.label];
+ return Zotero.getString(column.label);
}
else if (/^[^\s]+\w\.\w[^\s]+$/.test(column.label)) {
try {
@@ -1652,7 +1651,7 @@ function formatColumnName(column) {
return column.label;
}
-module.exports = injectIntl(VirtualizedTable, { forwardRef: true });
+module.exports = VirtualizedTable;
module.exports.TreeSelection = TreeSelection;
module.exports.TreeSelectionStub = TreeSelectionStub;
module.exports.renderCell = renderCell;
diff --git a/chrome/content/zotero/containers/tagSelectorContainer.jsx b/chrome/content/zotero/containers/tagSelectorContainer.jsx
index 48c3d76647..819a1d5cfc 100644
--- a/chrome/content/zotero/containers/tagSelectorContainer.jsx
+++ b/chrome/content/zotero/containers/tagSelectorContainer.jsx
@@ -31,7 +31,6 @@
const React = require('react');
const ReactDOM = require('react-dom');
const PropTypes = require('prop-types');
-const { IntlProvider } = require('react-intl');
const TagSelector = require('components/tagSelector.js');
const defaults = {
tagColors: new Map(),
@@ -762,9 +761,7 @@ Zotero.TagSelector = class TagSelectorContainer extends React.PureComponent {
static init(domEl, opts) {
var ref;
let elem = (
-
- ref = c } {...opts} />
-
+
ref = c } {...opts} />
);
ReactDOM.render(elem, domEl);
ref.domEl = domEl;
diff --git a/chrome/content/zotero/contextPane.js b/chrome/content/zotero/contextPane.js
index e79c49fd71..d31a386e28 100644
--- a/chrome/content/zotero/contextPane.js
+++ b/chrome/content/zotero/contextPane.js
@@ -937,13 +937,13 @@ var ZoteroContextPane = new function () {
// Info tab
var tabInfo = document.createElement('tab');
- tabInfo.setAttribute('label', Zotero.Intl.strings['zotero.tabs.info.label']);
+ tabInfo.setAttribute('label', Zotero.getString('zotero.tabs.info.label'));
// Tags tab
var tabTags = document.createElement('tab');
- tabTags.setAttribute('label', Zotero.Intl.strings['zotero.tabs.tags.label']);
+ tabTags.setAttribute('label', Zotero.getString('zotero.tabs.tags.label'));
// Related tab
var tabRelated = document.createElement('tab');
- tabRelated.setAttribute('label', Zotero.Intl.strings['zotero.tabs.related.label']);
+ tabRelated.setAttribute('label', Zotero.getString('zotero.tabs.related.label'));
tabs.append(tabInfo, tabTags, tabRelated);
diff --git a/chrome/content/zotero/itemTree.jsx b/chrome/content/zotero/itemTree.jsx
index bc3dc5bc11..3a5b68a0d8 100644
--- a/chrome/content/zotero/itemTree.jsx
+++ b/chrome/content/zotero/itemTree.jsx
@@ -27,7 +27,6 @@ const { noop, getDragTargetOrient } = require("components/utils");
const PropTypes = require("prop-types");
const React = require('react');
const ReactDOM = require('react-dom');
-const { IntlProvider } = require('react-intl');
const LibraryTree = require('./libraryTree');
const VirtualizedTable = require('components/virtualized-table');
const { renderCell, formatColumnName } = VirtualizedTable;
@@ -49,9 +48,7 @@ var ItemTree = class ItemTree extends LibraryTree {
var ref;
opts.domEl = domEl;
let elem = (
-
- ref = c } {...opts} />
-
+ ref = c } {...opts} />
);
await new Promise(resolve => ReactDOM.render(elem, domEl, resolve));
@@ -3730,7 +3727,7 @@ var ItemTree = class ItemTree extends LibraryTree {
// Restore Default Column Order
//
let menuitem = doc.createElementNS(ns, 'menuitem');
- menuitem.setAttribute('label', Zotero.Intl.strings['zotero.items.restoreColumnOrder.label']);
+ menuitem.setAttribute('label', Zotero.getString('zotero.items.restoreColumnOrder.label'));
menuitem.setAttribute('anonid', prefix + 'restore-order');
menuitem.addEventListener('command', () => this.tree._columns.restoreDefaultOrder());
menupopup.appendChild(menuitem);
diff --git a/chrome/content/zotero/locateManager.jsx b/chrome/content/zotero/locateManager.jsx
index 0297e6eb08..3f84e4f8a2 100644
--- a/chrome/content/zotero/locateManager.jsx
+++ b/chrome/content/zotero/locateManager.jsx
@@ -24,7 +24,6 @@
*/
import VirtualizedTable from 'components/virtualized-table';
-const { IntlProvider } = require('react-intl');
import React from 'react';
import ReactDOM from 'react-dom';
@@ -41,20 +40,18 @@ function init() {
engines = Zotero.LocateManager.getEngines();
const domEl = document.querySelector('#locateManager-tree');
let elem = (
-
- engines.length}
- id="locateManager-table"
- ref={ref => tree = ref}
- renderItem={VirtualizedTable.makeRowRenderer(getRowData)}
- showHeader={true}
- multiSelect={true}
- columns={columns}
- disableFontSizeScaling={true}
- getRowString={index => getRowData(index).name}
- onActivate={handleActivate}
- />
-
+ engines.length}
+ id="locateManager-table"
+ ref={ref => tree = ref}
+ renderItem={VirtualizedTable.makeRowRenderer(getRowData)}
+ showHeader={true}
+ multiSelect={true}
+ columns={columns}
+ disableFontSizeScaling={true}
+ getRowString={index => getRowData(index).name}
+ onActivate={handleActivate}
+ />
);
return new Promise(resolve => ReactDOM.render(elem, domEl, resolve));
}
diff --git a/chrome/content/zotero/preferences/preferences_cite.jsx b/chrome/content/zotero/preferences/preferences_cite.jsx
index ae9b538736..84e795574d 100644
--- a/chrome/content/zotero/preferences/preferences_cite.jsx
+++ b/chrome/content/zotero/preferences/preferences_cite.jsx
@@ -30,7 +30,6 @@ import FilePicker from 'zotero/modules/filePicker';
var React = require('react');
var ReactDOM = require('react-dom');
var VirtualizedTable = require('components/virtualized-table');
-var { IntlProvider } = require('react-intl');
var { makeRowRenderer } = VirtualizedTable;
Zotero_Preferences.Cite = {
@@ -118,22 +117,20 @@ Zotero_Preferences.Cite = {
}
};
let elem = (
-
- this.styles.length}
- id="styleManager-table"
- ref={ref => this._tree = ref}
- renderItem={makeRowRenderer(index => this.styles[index])}
- showHeader={true}
- multiSelect={true}
- columns={columns}
- staticColumns={true}
- disableFontSizeScaling={true}
- onSelectionChange={() => document.getElementById('styleManager-delete').disabled = undefined}
- onKeyDown={handleKeyDown}
- getRowString={index => this.styles[index].title}
- />
-
+ this.styles.length}
+ id="styleManager-table"
+ ref={ref => this._tree = ref}
+ renderItem={makeRowRenderer(index => this.styles[index])}
+ showHeader={true}
+ multiSelect={true}
+ columns={columns}
+ staticColumns={true}
+ disableFontSizeScaling={true}
+ onSelectionChange={() => document.getElementById('styleManager-delete').disabled = undefined}
+ onKeyDown={handleKeyDown}
+ getRowString={index => this.styles[index].title}
+ />
);
await new Promise(resolve => ReactDOM.render(elem, document.getElementById("styleManager"), resolve));
}
diff --git a/chrome/content/zotero/preferences/preferences_export.jsx b/chrome/content/zotero/preferences/preferences_export.jsx
index cb9d73382a..d9a8c0f79c 100644
--- a/chrome/content/zotero/preferences/preferences_export.jsx
+++ b/chrome/content/zotero/preferences/preferences_export.jsx
@@ -28,7 +28,6 @@
var React = require('react');
var ReactDOM = require('react-dom');
var VirtualizedTable = require('components/virtualized-table');
-var { IntlProvider } = require('react-intl');
var { makeRowRenderer } = VirtualizedTable;
Zotero_Preferences.Export = {
@@ -492,22 +491,20 @@ Zotero_Preferences.Export = {
};
let elem = (
-
- this._rows.length}
- id="quickCopy-siteSettings-table"
- ref={ref => this._tree = ref}
- renderItem={makeRowRenderer(index => this._rows[index])}
- showHeader={true}
- columns={columns}
- staticColumns={true}
- disableFontSizeScaling={true}
- onSelectionChange={handleSelectionChange}
- onKeyDown={handleKeyDown}
- getRowString={index => this._rows[index].domain}
- onActivate={(event, indices) => Zotero_Preferences.Export.showQuickCopySiteEditor()}
- />
-
+ this._rows.length}
+ id="quickCopy-siteSettings-table"
+ ref={ref => this._tree = ref}
+ renderItem={makeRowRenderer(index => this._rows[index])}
+ showHeader={true}
+ columns={columns}
+ staticColumns={true}
+ disableFontSizeScaling={true}
+ onSelectionChange={handleSelectionChange}
+ onKeyDown={handleKeyDown}
+ getRowString={index => this._rows[index].domain}
+ onActivate={(event, indices) => Zotero_Preferences.Export.showQuickCopySiteEditor()}
+ />
);
await new Promise(resolve => ReactDOM.render(elem, document.getElementById("quickCopy-siteSettings"), resolve));
} else {
diff --git a/chrome/content/zotero/preferences/preferences_sync.jsx b/chrome/content/zotero/preferences/preferences_sync.jsx
index d5e6b973f9..96eebabd44 100644
--- a/chrome/content/zotero/preferences/preferences_sync.jsx
+++ b/chrome/content/zotero/preferences/preferences_sync.jsx
@@ -32,7 +32,6 @@ var React = require('react');
var ReactDOM = require('react-dom');
var VirtualizedTable = require('components/virtualized-table');
var { getDOMElement } = require('components/icons');
-var { IntlProvider } = require('react-intl');
var { renderCell } = VirtualizedTable;
Zotero_Preferences.Sync = {
@@ -319,20 +318,18 @@ Zotero_Preferences.Sync = {
}
};
let elem = (
-
- this._rows.length}
- id="librariesToSync-table"
- ref={ref => this._tree = ref}
- renderItem={renderItem}
- showHeader={true}
- columns={columns}
- staticColumns={true}
- getRowString={index => this._rows[index].name}
- disableFontSizeScaling={true}
- onKeyDown={handleKeyDown}
- />
-
+ this._rows.length}
+ id="librariesToSync-table"
+ ref={ref => this._tree = ref}
+ renderItem={renderItem}
+ showHeader={true}
+ columns={columns}
+ staticColumns={true}
+ getRowString={index => this._rows[index].name}
+ disableFontSizeScaling={true}
+ onKeyDown={handleKeyDown}
+ />
);
ReactDOM.render(elem, document.getElementById("libraries-to-sync-tree"));
diff --git a/chrome/content/zotero/preferences/preferences_sync.xul b/chrome/content/zotero/preferences/preferences_sync.xul
index 3f56e1baae..a408d9d7eb 100644
--- a/chrome/content/zotero/preferences/preferences_sync.xul
+++ b/chrome/content/zotero/preferences/preferences_sync.xul
@@ -288,15 +288,15 @@
- &zotero.preferences.sync.reset.restoreToServer;
- &zotero.preferences.sync.reset.restoreToServer.desc;
+ &zotero.preferences.sync.reset.restoreToOnlineLibrary;
+ &zotero.preferences.sync.reset.restoreToOnlineLibrary.desc;
diff --git a/chrome/content/zotero/rtfScan.jsx b/chrome/content/zotero/rtfScan.jsx
index 00895dac62..59b478617c 100644
--- a/chrome/content/zotero/rtfScan.jsx
+++ b/chrome/content/zotero/rtfScan.jsx
@@ -31,7 +31,6 @@ import FilePicker from 'zotero/modules/filePicker';
import React from 'react';
import ReactDOM from 'react-dom';
import VirtualizedTable from 'components/virtualized-table';
-import { IntlProvider } from 'react-intl';
import { getDOMElement } from 'components/icons';
/**
@@ -51,9 +50,9 @@ var Zotero_RTFScan = new function() {
var ids = 0;
var tree;
this._rows = [
- { id: 'unmapped', rtf: Zotero.Intl.strings['zotero.rtfScan.unmappedCitations.label'], collapsed: false },
- { id: 'ambiguous', rtf: Zotero.Intl.strings['zotero.rtfScan.ambiguousCitations.label'], collapsed: false },
- { id: 'mapped', rtf: Zotero.Intl.strings['zotero.rtfScan.mappedCitations.label'], collapsed: false },
+ { id: 'unmapped', rtf: Zotero.getString('zotero.rtfScan.unmappedCitations.label'), collapsed: false },
+ { id: 'ambiguous', rtf: Zotero.getString('zotero.rtfScan.ambiguousCitations.label'), collapsed: false },
+ { id: 'mapped', rtf: Zotero.getString('zotero.rtfScan.mappedCitations.label'), collapsed: false },
];
this._rowMap = {};
this._rows.forEach((row, index) => this._rowMap[row.id] = index);
@@ -388,9 +387,9 @@ var Zotero_RTFScan = new function() {
document.documentElement.currentPage = document.getElementById('intro-page');
this._rows = [
- { id: 'unmapped', rtf: Zotero.Intl.strings['zotero.rtfScan.unmappedCitations.label'], collapsed: false },
- { id: 'ambiguous', rtf: Zotero.Intl.strings['zotero.rtfScan.ambiguousCitations.label'], collapsed: false },
- { id: 'mapped', rtf: Zotero.Intl.strings['zotero.rtfScan.mappedCitations.label'], collapsed: false },
+ { id: 'unmapped', rtf: Zotero.getString('zotero.rtfScan.unmappedCitations.label'), collapsed: false },
+ { id: 'ambiguous', rtf: Zotero.getString('zotero.rtfScan.ambiguousCitations.label'), collapsed: false },
+ { id: 'mapped', rtf: Zotero.getString('zotero.rtfScan.mappedCitations.label'), collapsed: false },
];
this._rowMap = {};
this._rows.forEach((row, index) => this._rowMap[row.id] = index);
@@ -768,17 +767,15 @@ var Zotero_RTFScan = new function() {
this._initCitationTree = function () {
const domEl = document.querySelector('#tree');
const elem = (
-
- this._rows.length}
- id="rtfScan-table"
- ref={ref => tree = ref}
- renderItem={this._renderItem}
- showHeader={true}
- columns={columns}
- disableFontSizeScaling={true}
- />
-
+ this._rows.length}
+ id="rtfScan-table"
+ ref={ref => tree = ref}
+ renderItem={this._renderItem}
+ showHeader={true}
+ columns={columns}
+ disableFontSizeScaling={true}
+ />
);
return new Promise(resolve => ReactDOM.render(elem, domEl, resolve));
};
diff --git a/chrome/content/zotero/xpcom/intl.js b/chrome/content/zotero/xpcom/intl.js
index 8b5fe0f98c..f360eeaf98 100644
--- a/chrome/content/zotero/xpcom/intl.js
+++ b/chrome/content/zotero/xpcom/intl.js
@@ -55,7 +55,8 @@ Zotero.Intl = new function () {
Components.utils.import("resource://gre/modules/PluralForm.jsm");
- bundle = Services.strings.createBundle('chrome://zotero/locale/zotero.properties');
+ // Exposed for tests
+ this._bundle = bundle = Services.strings.createBundle('chrome://zotero/locale/zotero.properties');
intlProps = Services.strings.createBundle('chrome://zotero/locale/mozilla/intl.properties');
[pluralFormGet, pluralFormNumForms] = PluralForm.makeGetter(parseInt(getIntlProp('pluralRule', 1)));
@@ -105,6 +106,9 @@ Zotero.Intl = new function () {
}
l10n = bundle.formatStringFromName(name, params, params.length);
}
+ else if (this.strings[name]) {
+ return this.strings[name];
+ }
else {
l10n = bundle.GetStringFromName(name);
}
diff --git a/chrome/locale/en-US/zotero/preferences.dtd b/chrome/locale/en-US/zotero/preferences.dtd
index fb20dd2fa7..3b081d7ed6 100644
--- a/chrome/locale/en-US/zotero/preferences.dtd
+++ b/chrome/locale/en-US/zotero/preferences.dtd
@@ -76,10 +76,10 @@
-
-
-
-
+
+
+
+
diff --git a/test/tests/zoteroIntlTest.js b/test/tests/intlTest.js
similarity index 73%
rename from test/tests/zoteroIntlTest.js
rename to test/tests/intlTest.js
index 62d5038544..b54229bfee 100644
--- a/test/tests/zoteroIntlTest.js
+++ b/test/tests/intlTest.js
@@ -18,9 +18,16 @@ describe("Zotero.Intl", function() {
it("shouldn't ignore whitespace", function () {
assert.equal(Zotero.localeCompare("Chang", "Chan H"), 1);
});
-
+
it("shouldn't ignore leading punctuation", function () {
assert.equal(Zotero.localeCompare("_Abcd", "Abcd"), -1);
});
});
+
+ it("there should not be duplicate string keys in .dtd and .properties files", function () {
+ let dtdStrings = Object.keys(Zotero.Intl.strings);
+ for (let key of dtdStrings) {
+ assert.throws(() => Zotero.Intl._bundle.GetStringFromName(key));
+ }
+ });
});