Skip to content
This repository has been archived by the owner on Mar 29, 2021. It is now read-only.

Commit

Permalink
feat: add support for PMCID resolution
Browse files Browse the repository at this point in the history
This adds support for automatic resolution for PMCID identifiers.

Now PMCID will be able to be cited automatically, along with PMID and
DOI.

Closes #240
  • Loading branch information
dsifford committed Nov 22, 2016
1 parent 5c3a65f commit a1e9d95
Show file tree
Hide file tree
Showing 18 changed files with 221 additions and 195 deletions.
2 changes: 1 addition & 1 deletion src/lib/js/__tests__/Frontend-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('Frontend', () => {
it('should render appropriately', () => {
const citation1 = document.getElementById('citation-1');
expect(citation1.getAttribute('data-citations')).toBe(
`<div id="aaaaaaaa">Test reference 1</div><div id="cccccccc">Test reference 3</div>`
`<div id="aaaaaaaa">Test reference 1</div><div id="cccccccc">Test reference 3</div>`,
);
});
it('should create a tooltip on click', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/js/components/__tests__/Spinner-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface SpinnerProps {

const setup = (props: SpinnerProps) => {
const component = mount(
<Spinner {...props} />
<Spinner {...props} />,
);
return {
component,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/js/components/__tests__/ToggleSwitch-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const setup = (checked = false) => {
checked={checked}
label="Test Label"
onChange={spy}
/>
/>,
);
return {
component,
Expand Down
10 changes: 8 additions & 2 deletions src/lib/js/reference-list/API.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { getFromDOI, getFromPMID } from '../utils/resolvers/';
import { getFromDOI, getFromPubmed } from '../utils/resolvers/';
import { generateID, processCSLDate } from '../utils/HelperFunctions';

export function getRemoteData(identifierList: string, mce: TinyMCE.WindowManager): Promise<CSL.Data[]> {
return new Promise(resolve => {
const pmidList: string[] = [];
const pmcidList: string[] = [];
const doiList: string[] = [];
const errList: string[] = [];
const identifiers = identifierList.replace(/\s/g, '');
Expand All @@ -18,10 +19,15 @@ export function getRemoteData(identifierList: string, mce: TinyMCE.WindowManager
pmidList.push(id);
return;
}
if (/^PMC\d+$/.test(id)) {
pmcidList.push(id.substring(3));
return;
}
errList.push(id);
});

if (pmidList.length > 0) promises.push(getFromPMID(pmidList.join(',')));
if (pmidList.length > 0) promises.push(getFromPubmed('PMID', pmidList.join(',')));
if (pmcidList.length > 0) promises.push(getFromPubmed('PMCID', pmcidList.join(',')));
if (doiList.length > 0) promises.push(getFromDOI(doiList));

if (promises.length === 0) {
Expand Down
27 changes: 16 additions & 11 deletions src/lib/js/reference-list/components/ReferenceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,20 +218,24 @@ export class ReferenceList extends React.Component<{store: Store}, {}> {
});
}

insertInlineCitation = (e?: React.MouseEvent<HTMLAnchorElement>, data: CSL.Data[] = []) => {

/* FIXME: Fix when PR closes in the react repo */
insertInlineCitation = (e?: React.MouseEvent<HTMLAnchorElement>, d: CSL.Data[]|Event = []) => {
let data: CSL.Data[] = [];
if (e) e.preventDefault();
this.editor.setProgressState(true);

/**
* If no data, then this must be a case where we're inserting from the
* list selection.
*/
if (data.length === 0) {
if (d instanceof Event || d.length === 0) {
this.selected.forEach(id => {
data.push(this.props.store.citations.CSL.get(id));
});
}
else {
data = d;
}

/**
* Checks to see if there is a inline citation selected. If so, extract the ids
Expand Down Expand Up @@ -415,15 +419,16 @@ export class ReferenceList extends React.Component<{store: Store}, {}> {

/**
* Vertical space that is already allocated.
* 200 = all static, non-participating sections of the list + padding
* 180 = all static, non-participating sections of the list + padding
* 84 = vertical height of menu when open
*/
const listOffset = 200 + topOffset + (this.menuOpen ? 91 : 0);
const listOffset = 180 + topOffset + (this.menuOpen ? 84 : 0);
const remainingHeight = window.innerHeight - listOffset;

list.style.top = `${topOffset}px`;
if (!bothOpen) {
this.citedListUI.maxHeight = `calc(100vh - ${listOffset}px + 38px)`;
this.uncitedListUI.maxHeight = `calc(100vh - ${listOffset}px + 38px)`;
this.citedListUI.maxHeight = `calc(100vh - ${listOffset}px)`;
this.uncitedListUI.maxHeight = `calc(100vh - ${listOffset}px)`;
return;
}

Expand All @@ -432,16 +437,16 @@ export class ReferenceList extends React.Component<{store: Store}, {}> {
let citedHeight = 0;
let uncitedHeight = 0;

for (let i = 0; i < cited.children.length; i++) {
citedHeight += cited.children[i].clientHeight + 1;
for (const child of Array.from(cited.children)) {
citedHeight += child.clientHeight + 1;
if (citedHeight > (remainingHeight / 2)) {
citedHeight = remainingHeight / 2;
break;
}
}

for (let i = 0; i < uncited.children.length; i++) {
uncitedHeight += uncited.children[i].clientHeight + 1;
for (const child of Array.from(uncited.children)) {
uncitedHeight += child.clientHeight + 1;
if (uncitedHeight > (remainingHeight / 2)) {
uncitedHeight = remainingHeight / 2;
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
jest.mock('../../../utils/CSLProcessor');
// jest.mock('../../../utils/TinymceFunctions');

import * as React from 'react';
import { mount } from 'enzyme';
Expand Down Expand Up @@ -333,23 +332,23 @@ describe('<ReferenceList />', () => {

// Toggle pinned state
instance.togglePinned();
expect(instance.citedListUI.maxHeight).toBe('372px');
expect(instance.citedListUI.maxHeight).toBe('392px');
expect(instance.uncitedListUI.maxHeight).toBe('101px');

// New dimentions
setupDimentions(100, [200, 250, 500]);
instance.togglePinned();
instance.togglePinned();
expect(instance.citedListUI.maxHeight).toBe('253.16666666666666px');
expect(instance.uncitedListUI.maxHeight).toBe('253.16666666666666px');
expect(instance.citedListUI.maxHeight).toBe('263.1666666666667px');
expect(instance.uncitedListUI.maxHeight).toBe('263.1666666666667px');

// New dimentions
setupDimentions(150, [50, 50, 650]);
instance.toggleMenu();
instance.togglePinned();
instance.togglePinned();
expect(instance.citedListUI.maxHeight).toBe('102px');
expect(instance.uncitedListUI.maxHeight).toBe('320px');
expect(instance.uncitedListUI.maxHeight).toBe('347px');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,6 @@ describe('<ImportWindow />', () => {
setup();
expect(ImportWindow.prototype.componentDidMount).toHaveBeenCalledTimes(1);
});
it('should trigger handleFileUpload when upload field changed', () => {
const { upload, component, instance } = setup();
const handleFileUpload = spyOn(instance, 'handleFileUpload');
component.update();
upload.simulate('change', { target: { files: [new File(['testdata'], 'test')], value: 'test.ris' } });
expect(handleFileUpload).toHaveBeenCalledTimes(1);
});
it('should set filename', () => {
spyOn(window, 'FileReader').and.returnValue({
addEventListener: () => null,
Expand Down
4 changes: 2 additions & 2 deletions src/lib/js/tinymce/components/pubmed-window/PubmedWindow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class PubmedWindow extends React.Component<{}, {}> {
}

@action
consumeQueryData = (data: PubMed.SingleReference[]) => {
consumeQueryData = (data: PubMed.DataPMID[]) => {
if (data.length === 0) {
top.tinyMCE.activeEditor.windowManager.alert(this.errors.noResults);
}
Expand All @@ -74,7 +74,7 @@ export class PubmedWindow extends React.Component<{}, {}> {
sendQuery = (e) => {
this.toggleLoadState();
e.preventDefault();
pubmedQuery(this.query, true)
pubmedQuery(this.query)
.then(this.consumeQueryData)
.catch(err => top.tinyMCE.activeEditor.windowManager.alert(err.message));
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/js/tinymce/components/pubmed-window/ResultList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { observer } from 'mobx-react';
import { preventScrollPropagation } from '../../../utils/HelperFunctions';

interface ResultListProps {
results: PubMed.SingleReference[];
results: PubMed.DataPMID[];
select(pmid: string): void;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import * as React from 'react';
import { mount } from 'enzyme';
import { ResultList } from '../ResultList';

const testData: PubMed.SingleReference[] = [
const testData: PubMed.DataPMID[] = [
{
authors: [
{ name: 'Author 1' },
{ name: 'Author 2' },
{ name: 'Author 3' },
{ name: 'NOT VISIBLE' },
{ authtype: 'Author', name: 'Author 1' },
{ authtype: 'Author', name: 'Author 2' },
{ authtype: 'Author', name: 'Author 3' },
{ authtype: 'Author', name: 'NOT VISIBLE' },
],
pubdate: '2016 May 1',
source: 'J Test 1',
Expand All @@ -17,10 +17,10 @@ const testData: PubMed.SingleReference[] = [
},
{
authors: [
{ name: 'First A' },
{ name: 'Second A' },
{ name: 'Third A' },
{ name: 'NOT VISIBLE' },
{ authtype: 'Author', name: 'First A' },
{ authtype: 'Author', name: 'Second A' },
{ authtype: 'Author', name: 'Third A' },
{ authtype: 'Author', name: 'NOT VISIBLE' },
],
pubdate: '2016 May 2',
source: 'J Test 2',
Expand Down Expand Up @@ -59,9 +59,9 @@ describe('<ResultList />', () => {
expect(spy.mock.calls[0]).toEqual(['11111']);
});
it('should scroll to the top on update', () => {
const { component, instance } = setup();
const { instance } = setup();
instance.element.scrollTop = 150;
component.update();
instance.componentDidUpdate();
expect(instance.element.scrollTop).toBe(0);
});
it('should handle scroll', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ export class ReferenceWindow extends React.Component<{}, {}> {
const titleKey = kind === 'chapter' ? 'container-title' : 'title';
this.manualData.merge({
accessed: new Date(Date.now()).toISOString().split('T')[0].split('-').join('/'),
'number-of-pages': meta.book['number-of-pages'],
issued: meta.book.issued,
'number-of-pages': meta.book['number-of-pages'],
publisher: meta.book.publisher,
[titleKey]: meta.book.title,
});
Expand Down
Loading

0 comments on commit a1e9d95

Please sign in to comment.