From 9b281415721ec6b785309fa13ca2e50d359e768b Mon Sep 17 00:00:00 2001 From: Derek P Sifford Date: Sun, 17 Sep 2017 14:20:12 -0400 Subject: [PATCH] move all js globals into a single global --- lib/fixtures.ts | 6 +- lib/scripts/before-test.ts | 15 +- lib/types/ABT.d.ts | 137 ++++++++++++ lib/types/globals.d.ts | 209 +++--------------- src/js/components/callout.tsx | 4 +- src/js/dialogs/add/autocite.tsx | 2 +- src/js/dialogs/add/button-row.tsx | 2 +- src/js/dialogs/add/identifier-input.tsx | 2 +- src/js/dialogs/add/index.tsx | 40 +++- src/js/dialogs/add/manual-entry-container.tsx | 34 +-- src/js/dialogs/add/meta-fields.tsx | 12 +- src/js/dialogs/add/people.tsx | 6 +- src/js/dialogs/container.tsx | 2 +- src/js/dialogs/edit/index.tsx | 2 +- src/js/dialogs/import/index.tsx | 4 +- src/js/dialogs/index.tsx | 2 +- src/js/dialogs/pubmed/index.tsx | 4 +- src/js/dialogs/pubmed/paginate.tsx | 2 +- src/js/dialogs/pubmed/result-list.tsx | 2 +- src/js/reference-list/__tests__/store-test.ts | 8 +- src/js/reference-list/api.ts | 4 +- .../components/__tests__/menu-test.tsx | 18 +- .../__tests__/reference-list-test.tsx | 2 +- src/js/reference-list/components/menu.tsx | 14 +- .../components/reference-list.tsx | 4 +- src/js/reference-list/index.tsx | 3 +- src/js/reference-list/store.ts | 2 +- src/js/utils/CSLProcessor.ts | 13 +- src/js/utils/__tests__/CSLProcessor-test.ts | 4 +- src/js/utils/editor.ts | 2 +- src/js/utils/logger.ts | 4 +- src/js/utils/resolvers/isbn.ts | 4 +- src/js/utils/resolvers/pubmed.ts | 2 +- src/js/utils/resolvers/url.ts | 2 +- src/php/backend.php | 14 +- 35 files changed, 303 insertions(+), 284 deletions(-) diff --git a/lib/fixtures.ts b/lib/fixtures.ts index be47db3c..c5240248 100644 --- a/lib/fixtures.ts +++ b/lib/fixtures.ts @@ -1,4 +1,4 @@ -export const ABT_wp: BackendGlobals.ABT_wp = { +export const wpInfo: ABT.Backend['wp'] = { abt_url: 'http://localhost:8080/wp-content/plugins/academic-bloggers-toolkit', home_url: 'http://localhost:8080', plugins_url: 'http://localhost:8080/wp-content/plugins', @@ -26,7 +26,7 @@ export const ABT_wp: BackendGlobals.ABT_wp = { }, }; -export const ABT_Reflist_State: BackendGlobals.ABT_Reflist_State = { +export const state: ABT.Backend['state'] = { bibOptions: { heading: 'Bibliography', style: 'fixed', @@ -202,7 +202,7 @@ export const ABT_Reflist_State: BackendGlobals.ABT_Reflist_State = { }, }; -export const ABT_i18n: BackendGlobals.ABT_i18n = { +export const i18n: ABT.Backend['i18n'] = { misc: { footnotes: 'Footnotes', }, diff --git a/lib/scripts/before-test.ts b/lib/scripts/before-test.ts index ec391e77..ece4d456 100644 --- a/lib/scripts/before-test.ts +++ b/lib/scripts/before-test.ts @@ -1,7 +1,12 @@ require('ts-node/register'); -const { ABT_i18n, ABT_Reflist_State, ABT_wp } = require('../fixtures.ts'); +const { i18n, state, wpInfo } = require('../fixtures.ts'); const styles = require('../../src/vendor/citation-styles.json'); -window.ABT_i18n = ABT_i18n; -window.ABT_Reflist_State = ABT_Reflist_State; -window.ABT_wp = ABT_wp; -window.ABT_CitationStyles = styles; +window.ABT = { + state, + i18n, + wp: wpInfo, + styles, + custom_csl: { + label: '', + }, +}; diff --git a/lib/types/ABT.d.ts b/lib/types/ABT.d.ts index 8fd20643..56515d4c 100644 --- a/lib/types/ABT.d.ts +++ b/lib/types/ABT.d.ts @@ -144,4 +144,141 @@ declare namespace ABT { attachInline: boolean; identifierList: string; } + + interface i18n { + citationTypes: CitationTypes; + errors: { + missingPhpFeatures: 'Your WordPress PHP installation is incomplete. You must have the following PHP extensions enabled to use this feature: "dom", "libxml"'; + badRequest: 'Request not valid'; + denied: 'Site denied request'; + fileExtensionError: 'Invalid file extension. Extension must be .ris, .bib, or .bibtex'; + filetypeError: 'The file could not be processed'; + identifiersNotFound: { + all: 'No identifiers could be found for your request'; + some: 'The following identifiers could not be found'; + }; + networkError: 'Network Error'; + noResults: 'Your search returned 0 results'; + prefix: 'Error'; + risLeftovers: 'The following references were unable to be processed'; + statusError: 'Request returned a non-200 status code'; + warnings: { + warning: 'Warning'; + reason: 'Reason'; + noBib: { + message: 'Cannot create publication list for currently selected citation style'; + reason: 'Style does not include bibliography'; + }; + }; + unexpected: { + message: 'An unexpected error occurred'; + reportInstructions: 'Please report this error, including the steps taken to trigger it, here: \nhttps://github.com/dsifford/academic-bloggers-toolkit/issues'; // tslint:disable-line + }; + }; + fieldmaps: FieldMappings; + misc: { + footnotes: 'Footnotes'; + }; + referenceList: { + menu: { + styleLabels: { + custom: 'Custom Style'; + predefined: 'Pre-defined Styles'; + }; + toggleLabel: 'Toggle menu'; + tooltips: { + destroy: 'Delete all references'; + help: 'Usage instructions'; + importRIS: 'Import references'; + refresh: 'Refresh reference list'; + staticPubList: 'Insert static publication list'; + }; + }; + citedItems: 'Cited Items'; + tooltips: { + add: 'Add reference'; + insert: 'Insert selected references'; + pin: 'Pin reference list'; + remove: 'Remove selected references'; + }; + uncitedItems: 'Uncited Items'; + }; + dialogs: { + closeLabel: 'Close dialog'; + edit: { + title: 'Edit Reference'; + confirm: 'Confirm'; + }; + import: { + importBtn: 'Import'; + title: 'Import References'; + upload: 'Choose File'; + }; + pubmed: { + addReference: 'Select'; + next: 'Next'; + previous: 'Previous'; + search: 'Search'; + title: 'Search PubMed'; + viewReference: 'View'; + }; + add: { + buttonRow: { + addManually: 'Add Manually'; + addReference: 'Add Reference'; + addWithIdentifier: 'Add with Identifier'; + insertInline: 'Insert citation inline'; + searchPubmed: 'Search PubMed'; + }; + identifierInput: { + label: 'DOI/PMID/PMCID'; + }; + manualEntryContainer: { + autocite: 'Autocite'; + citationType: 'Citation Type'; + ISBN: 'ISBN'; + search: 'Search'; + URL: 'URL'; + }; + people: { + add: 'Add Contributor'; + contributors: 'Contributors'; + given: 'Given Name, M.I.'; + surname: 'Surname'; + }; + title: 'Add References'; + }; + }; + } + + interface EditorState { + bibOptions: { + heading: string; + headingLevel: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + style: 'fixed' | 'toggle'; + }; + cache: { + style: string; + links: LinkStyle; + locale: string; + }; + citationByIndex: Citeproc.CitationByIndex; + CSL: { + [id: string]: CSL.Data; + }; + } + + interface CustomCSL { + CSL?: string; + label: string; + value?: string; + } + + interface Backend { + state: ABT.EditorState; + i18n: ABT.i18n; + styles: CitationStyles; + wp: WP_info; + custom_csl: ABT.CustomCSL; + } } diff --git a/lib/types/globals.d.ts b/lib/types/globals.d.ts index d4bd9ef3..d1dd6daa 100644 --- a/lib/types/globals.d.ts +++ b/lib/types/globals.d.ts @@ -11,6 +11,39 @@ interface CitationStyles { styles: StyleObj[]; } +interface WP_info { + abt_url: string; + home_url: string; + plugins_url: string; + wp_upload_dir: { + /* /folder-of-wp-installation/wp-content/uploads */ + basedir: string; + /* http(s)://siteurl.com/wp-content/uploads */ + baseurl: string; + error: boolean; + /* /folder-of-wp-installation/wp-content/uploads/2016/08 */ + path: string; + /* /2016/08 */ + subdir: string; + /* http(s)://siteurl.com/wp-content/uploads/2016/08 */ + url: string; + }; + info: { + site: { + language: string; + name: string; + plugins: string[]; + theme: string; + url: string; + }; + versions: { + abt: string; + php: string; + wordpress: string; + }; + }; +} + interface IRollbar { log(msg: string, e?: any): void; debug(msg: string, e?: any): void; @@ -20,188 +53,18 @@ interface IRollbar { critical(msg: string, e?: any): void; } -declare const ABT_CitationStyles: CitationStyles; -declare const ABT_Custom_CSL: BackendGlobals.ABT_Custom_CSL; +// declare const ABT_Custom_CSL: BackendGlobals.ABT_Custom_CSL; declare const DocumentTouch: any; +declare const Rollbar: IRollbar; interface Window { - ABT_CitationStyles: CitationStyles; - ABT_Custom_CSL: BackendGlobals.ABT_Custom_CSL; - ABT_Reflist_State: BackendGlobals.ABT_Reflist_State; - ABT_i18n: BackendGlobals.ABT_i18n; - ABT_wp: BackendGlobals.ABT_wp; + ABT: ABT.Backend; DocumentTouch?: any; Rollbar: IRollbar; ajaxurl: string; tinyMCE: TinyMCE.MCE; } -declare const Rollbar: IRollbar; - -declare namespace BackendGlobals { - interface ABT_i18n { - citationTypes: ABT.CitationTypes; - errors: { - missingPhpFeatures: 'Your WordPress PHP installation is incomplete. You must have the following PHP extensions enabled to use this feature: "dom", "libxml"'; - badRequest: 'Request not valid'; - denied: 'Site denied request'; - fileExtensionError: 'Invalid file extension. Extension must be .ris, .bib, or .bibtex'; - filetypeError: 'The file could not be processed'; - identifiersNotFound: { - all: 'No identifiers could be found for your request'; - some: 'The following identifiers could not be found'; - }; - networkError: 'Network Error'; - noResults: 'Your search returned 0 results'; - prefix: 'Error'; - risLeftovers: 'The following references were unable to be processed'; - statusError: 'Request returned a non-200 status code'; - warnings: { - warning: 'Warning'; - reason: 'Reason'; - noBib: { - message: 'Cannot create publication list for currently selected citation style'; - reason: 'Style does not include bibliography'; - }; - }; - unexpected: { - message: 'An unexpected error occurred'; - reportInstructions: 'Please report this error, including the steps taken to trigger it, here: \nhttps://github.com/dsifford/academic-bloggers-toolkit/issues'; // tslint:disable-line - }; - }; - fieldmaps: ABT.FieldMappings; - misc: { - footnotes: 'Footnotes'; - }; - referenceList: { - menu: { - styleLabels: { - custom: 'Custom Style'; - predefined: 'Pre-defined Styles'; - }; - toggleLabel: 'Toggle menu'; - tooltips: { - destroy: 'Delete all references'; - help: 'Usage instructions'; - importRIS: 'Import references'; - refresh: 'Refresh reference list'; - staticPubList: 'Insert static publication list'; - }; - }; - citedItems: 'Cited Items'; - tooltips: { - add: 'Add reference'; - insert: 'Insert selected references'; - pin: 'Pin reference list'; - remove: 'Remove selected references'; - }; - uncitedItems: 'Uncited Items'; - }; - dialogs: { - closeLabel: 'Close dialog'; - edit: { - title: 'Edit Reference'; - confirm: 'Confirm'; - }; - import: { - importBtn: 'Import'; - title: 'Import References'; - upload: 'Choose File'; - }; - pubmed: { - addReference: 'Select'; - next: 'Next'; - previous: 'Previous'; - search: 'Search'; - title: 'Search PubMed'; - viewReference: 'View'; - }; - add: { - buttonRow: { - addManually: 'Add Manually'; - addReference: 'Add Reference'; - addWithIdentifier: 'Add with Identifier'; - insertInline: 'Insert citation inline'; - searchPubmed: 'Search PubMed'; - }; - identifierInput: { - label: 'DOI/PMID/PMCID'; - }; - manualEntryContainer: { - autocite: 'Autocite'; - citationType: 'Citation Type'; - ISBN: 'ISBN'; - search: 'Search'; - URL: 'URL'; - }; - people: { - add: 'Add Contributor'; - contributors: 'Contributors'; - given: 'Given Name, M.I.'; - surname: 'Surname'; - }; - title: 'Add References'; - }; - }; - } - - interface ABT_Reflist_State { - bibOptions: { - heading: string; - headingLevel: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; - style: 'fixed' | 'toggle'; - }; - cache: { - style: string; - links: ABT.LinkStyle; - locale: string; - }; - citationByIndex: Citeproc.CitationByIndex; - CSL: { - [id: string]: CSL.Data; - }; - } - - interface ABT_wp { - abt_url: string; - home_url: string; - plugins_url: string; - wp_upload_dir: { - /* /folder-of-wp-installation/wp-content/uploads */ - basedir: string; - /* http(s)://siteurl.com/wp-content/uploads */ - baseurl: string; - error: boolean; - /* /folder-of-wp-installation/wp-content/uploads/2016/08 */ - path: string; - /* /2016/08 */ - subdir: string; - /* http(s)://siteurl.com/wp-content/uploads/2016/08 */ - url: string; - }; - info: { - site: { - language: string; - name: string; - plugins: string[]; - theme: string; - url: string; - }; - versions: { - abt: string; - php: string; - wordpress: string; - }; - }; - } - - interface ABT_Custom_CSL { - CSL?: string; - label: string; - value?: string; - } -} - // ============== declare module 'common-tags'; diff --git a/src/js/components/callout.tsx b/src/js/components/callout.tsx index 6a8c56ef..23467873 100644 --- a/src/js/components/callout.tsx +++ b/src/js/components/callout.tsx @@ -20,8 +20,8 @@ export default class Callout extends React.PureComponent { }; static prefixes = { - warning: top.ABT_i18n.errors.warnings.warning, - error: top.ABT_i18n.errors.prefix, + warning: top.ABT.i18n.errors.warnings.warning, + error: top.ABT.i18n.errors.prefix, }; render() { diff --git a/src/js/dialogs/add/autocite.tsx b/src/js/dialogs/add/autocite.tsx index 909d3ae3..e8bba76f 100644 --- a/src/js/dialogs/add/autocite.tsx +++ b/src/js/dialogs/add/autocite.tsx @@ -22,7 +22,7 @@ interface Props { @observer export default class AutoCite extends React.PureComponent { - static readonly labels = top.ABT_i18n.dialogs.add.manualEntryContainer; + static readonly labels = top.ABT.i18n.dialogs.add.manualEntryContainer; /** Ref to the input field (needed for validation) */ input: HTMLInputElement; diff --git a/src/js/dialogs/add/button-row.tsx b/src/js/dialogs/add/button-row.tsx index 32f78300..7b1b41c4 100644 --- a/src/js/dialogs/add/button-row.tsx +++ b/src/js/dialogs/add/button-row.tsx @@ -24,7 +24,7 @@ interface Props { @observer export default class ButtonRow extends React.PureComponent { - static readonly labels = top.ABT_i18n.dialogs.add.buttonRow; + static readonly labels = top.ABT.i18n.dialogs.add.buttonRow; render() { const { addManually, diff --git a/src/js/dialogs/add/identifier-input.tsx b/src/js/dialogs/add/identifier-input.tsx index be1f18c0..e40602e1 100644 --- a/src/js/dialogs/add/identifier-input.tsx +++ b/src/js/dialogs/add/identifier-input.tsx @@ -13,7 +13,7 @@ interface Props { @observer export default class IdentifierInput extends React.PureComponent { - static readonly labels = top.ABT_i18n.dialogs.add.identifierInput; + static readonly labels = top.ABT.i18n.dialogs.add.identifierInput; render() { return ( diff --git a/src/js/dialogs/add/index.tsx b/src/js/dialogs/add/index.tsx index 2091903a..f1da376a 100644 --- a/src/js/dialogs/add/index.tsx +++ b/src/js/dialogs/add/index.tsx @@ -28,7 +28,7 @@ type AutoCiteMeta = BookMeta | URLMeta; @observer export default class AddDialog extends React.Component { - static readonly pubmedLabel = top.ABT_i18n.dialogs.pubmed.title; + static readonly pubmedLabel = top.ABT.i18n.dialogs.pubmed.title; /** Describes the active state of `ManualEntryContainer` */ addManually = observable(false); @@ -71,7 +71,12 @@ export default class AddDialog extends React.Component { @action appendPMID = (pmid: string) => { const ids = new Set( - this.identifierList.get().split(',').map(i => i.trim()).concat(pmid).filter(Boolean), + this.identifierList + .get() + .split(',') + .map(i => i.trim()) + .concat(pmid) + .filter(Boolean), ); this.identifierList.set(Array.from(ids).join(', ')); if (this.identifierInputField) this.identifierInputField.focus(); @@ -83,9 +88,15 @@ export default class AddDialog extends React.Component { case 'webpage': this.manualData.merge({ URL: meta.url, - accessed: meta.accessed.split('T')[0].split('-').join('/'), + accessed: meta.accessed + .split('T')[0] + .split('-') + .join('/'), 'container-title': meta.site_title, - issued: meta.issued.split('T')[0].split('-').join('/'), + issued: meta.issued + .split('T')[0] + .split('-') + .join('/'), title: meta.content_title, }); this.people.replace( @@ -100,7 +111,11 @@ export default class AddDialog extends React.Component { case 'book': const titleKey = meta.kind === 'chapter' ? 'container-title' : 'title'; this.manualData.merge({ - accessed: new Date(Date.now()).toISOString().split('T')[0].split('-').join('/'), + accessed: new Date(Date.now()) + .toISOString() + .split('T')[0] + .split('-') + .join('/'), issued: meta.issued, 'number-of-pages': meta['number-of-pages'], publisher: meta.publisher, @@ -192,7 +207,7 @@ export default class AddDialog extends React.Component { return (
{this.isLoading.get() && } - {this.currentDialog.get() === 'PUBMED' && + {this.currentDialog.get() === 'PUBMED' && ( { onClose={this.closePubmedDialog} > - } + + )}
- {!this.addManually.get() && + {!this.addManually.get() && ( } - {this.addManually.get() && + /> + )} + {this.addManually.get() && ( } + /> + )} { - static readonly citationTypes = top.ABT_i18n.citationTypes; - static readonly labels = top.ABT_i18n.dialogs.add.manualEntryContainer; + static readonly citationTypes = top.ABT.i18n.citationTypes; + static readonly labels = top.ABT.i18n.dialogs.add.manualEntryContainer; @action dismissError = () => { @@ -80,22 +80,22 @@ export default class ManualEntryContainer extends React.PureComponent
{renderAutocite && - itemType === 'webpage' && ( - - )} + itemType === 'webpage' && ( + + )} {renderAutocite && - ['book', 'chapter'].includes(itemType) && ( - - )} + ['book', 'chapter'].includes(itemType) && ( + + )}
{ - static readonly fieldmaps = top.ABT_i18n.fieldmaps; + static readonly fieldmaps = top.ABT.i18n.fieldmaps; @action updateField = (e: React.FormEvent) => { @@ -22,18 +22,16 @@ export default class MetaFields extends React.Component { const fields = MetaFields.fieldmaps[citationType].fields; return (
-

- {title} -

+

{title}

- {fields.map((field: ABT.Field, i: number) => + {fields.map((field: ABT.Field, i: number) => ( , - )} + /> + ))}