-
-
+
+
+ { item.attachmentFilename }
+
+
-
+
);
}
diff --git a/chrome/content/zotero/components/progressQueueTable.jsx b/chrome/content/zotero/components/progressQueueTable.jsx
index 58011f87bb..4b08ee4c44 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 8407a1992c..57eb0be005 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;
@@ -1658,7 +1657,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 {
@@ -1674,7 +1673,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 25aa8d5b17..467ca59263 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(),
@@ -772,9 +771,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 47c7999990..9d5db05864 100644
--- a/chrome/content/zotero/contextPane.js
+++ b/chrome/content/zotero/contextPane.js
@@ -931,13 +931,13 @@ var ZoteroContextPane = new function () {
// Info tab
var tabInfo = document.createXULElement('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.createXULElement('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.createXULElement('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);
tabbox.append(tabs, tabpanels);
diff --git a/chrome/content/zotero/itemTree.jsx b/chrome/content/zotero/itemTree.jsx
index 8283cef47f..719f61c2c6 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;
@@ -48,9 +47,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));
@@ -3707,7 +3704,7 @@ var ItemTree = class ItemTree extends LibraryTree {
// Restore Default Column Order
//
let menuitem = doc.createXULElement('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 a38f6e6649..91829b741f 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,21 +40,19 @@ 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}
- onColumnSort={null}
- 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}
+ onColumnSort={null}
+ 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 afd699d78c..0eee275765 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 = {
@@ -102,22 +101,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={selection => document.getElementById('styleManager-delete').disabled = !selection.count}
- 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={selection => document.getElementById('styleManager-delete').disabled = !selection.count}
+ onKeyDown={handleKeyDown}
+ getRowString={index => this.styles[index].title}
+ />
);
let styleManager = document.getElementById("styleManager");
diff --git a/chrome/content/zotero/preferences/preferences_export.jsx b/chrome/content/zotero/preferences/preferences_export.jsx
index 02f53220bc..33cbabba68 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 = {
@@ -479,22 +478,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(true)}
- />
-
+ 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(true)}
+ />
);
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 8b596779d7..167d6df9c8 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 = {
@@ -330,20 +329,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.xhtml b/chrome/content/zotero/preferences/preferences_sync.xhtml
index 75eb5bbb85..ad69bb1811 100644
--- a/chrome/content/zotero/preferences/preferences_sync.xhtml
+++ b/chrome/content/zotero/preferences/preferences_sync.xhtml
@@ -241,8 +241,8 @@
&zotero.preferences.sync.reset;
diff --git a/chrome/content/zotero/rtfScan.jsx b/chrome/content/zotero/rtfScan.jsx
index e049fd16ba..3cf30bd8ae 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);
@@ -765,17 +764,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 31f73a47c3..cbdce22832 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)));
@@ -129,6 +130,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 c3b2955fc2..7a63a832e7 100644
--- a/chrome/locale/en-US/zotero/preferences.dtd
+++ b/chrome/locale/en-US/zotero/preferences.dtd
@@ -86,10 +86,10 @@
-
-
-
-
+
+
+
+
diff --git a/test/tests/intlTest.js b/test/tests/intlTest.js
index 62d5038544..b54229bfee 100644
--- a/test/tests/intlTest.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));
+ }
+ });
});