From c860380834595d5672ea92d1a24431702fe3a069 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 8 Feb 2016 23:49:30 +0100 Subject: [PATCH 01/84] Support multiple paragraphs as content of a def-item. --- extensions/math/math_converter.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/extensions/math/math_converter.js b/extensions/math/math_converter.js index 76fcc428..08c7d31a 100644 --- a/extensions/math/math_converter.js +++ b/extensions/math/math_converter.js @@ -108,11 +108,22 @@ MathConverter.Prototype = function MathConverterPrototype() { var enumItemNode = { type: 'enumeration-item', id: state.nextId('enumeration-item'), + children: [] }; var term = defItem.querySelector('term'); enumItemNode.label = this.annotatedText(state, term, [enumItemNode.id, 'label']); - var content = defItem.querySelector('def p'); - enumItemNode.children = _.pluck(this.paragraphGroup(state, content), "id"); + var pEls = defItem.querySelectorAll('def p'); + for (var j = 0; j < pEls.length; j++) { + var p = pEls[j]; + var children = this.paragraphGroup(state, p); + var pgroup = { + type: 'paragraph', + id: state.nextId('pgroup'), + children: _.pluck(children, 'id') + }; + state.doc.create(pgroup); + enumItemNode.children.push(pgroup.id); + } state.doc.create(enumItemNode); enumerationNode.items.push(enumItemNode.id); } From da07e8b900a3210e1bd2d7207cb847cea164a407 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 9 Feb 2016 00:06:22 +0100 Subject: [PATCH 02/84] Allow def-list as block-type within paragraphs. --- extensions/math/math_converter.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/extensions/math/math_converter.js b/extensions/math/math_converter.js index 08c7d31a..4e8110a5 100644 --- a/extensions/math/math_converter.js +++ b/extensions/math/math_converter.js @@ -21,6 +21,10 @@ MathConverter.Prototype = function MathConverterPrototype() { this._refTypeMapping["disp-formula"] = "formula_reference"; this._refTypeMapping["statement"] = "math_environment_reference"; + this.acceptedParagraphElements = _.extend(__super__.acceptedParagraphElements, { + "def-list": { handler: 'defList' } + }); + this.test = function(xmlDoc, documentUrl) { /* jshint unused:false */ var publisherName = xmlDoc.querySelector("publisher-name").textContent; @@ -96,7 +100,7 @@ MathConverter.Prototype = function MathConverterPrototype() { } }; - this._bodyNodes['def-list'] = function(state, defList) { + this._bodyNodes['def-list'] = this.defList = function(state, defList) { var enumerationNode = { type: 'enumeration', id: state.nextId('enumeration'), From bbdad6c0ab30fa23d5e98bccaca3d7624da4e169 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 9 Feb 2016 00:42:28 +0100 Subject: [PATCH 03/84] Do not break paragraphs when hitting unknown inline elements. --- converter/lens_converter.js | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index ca0bcfd5..9a90d951 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -176,7 +176,7 @@ NlmToLensConverter.Prototype = function() { // Overridden to create a Lens Article instance this.createDocument = function() { - + var doc = new Article(); return doc; }; @@ -1429,8 +1429,15 @@ NlmToLensConverter.Prototype = function() { // ignore some elements if (this.ignoredParagraphElements[type]) continue; + // paragraph block-types such as disp-formula + // i.e they are allowed within a paragraph, but + // we pull them out on the top level + if (this.acceptedParagraphElements[type]) { + blocks.push(_.extend({node: child}, this.acceptedParagraphElements[type])); + } // paragraph elements - if (type === "text" || this.isAnnotation(type) || this.inlineParagraphElements[type]) { + //if (type === "text" || this.isAnnotation(type) || this.inlineParagraphElements[type]) { + else { if (lastType !== "paragraph") { blocks.push({ handler: "paragraph", nodes: [] }); lastType = "paragraph"; @@ -1438,10 +1445,7 @@ NlmToLensConverter.Prototype = function() { _.last(blocks).nodes.push(child); continue; } - // other elements are treated as single blocks - else if (this.acceptedParagraphElements[type]) { - blocks.push(_.extend({node: child}, this.acceptedParagraphElements[type])); - } + lastType = type; } return blocks; @@ -1474,6 +1478,11 @@ NlmToLensConverter.Prototype = function() { return nodes; }; + // DEPRECATED: using this handler for

elements is + // deprecated, as in JATS

can contain certain block-level + // elements. Better use this.paragraphGroup in cases where you + // convert

elements. + // TODO: we should refactor this and make it a 'private' helper this.paragraph = function(state, children) { var doc = state.doc; @@ -1509,7 +1518,13 @@ NlmToLensConverter.Prototype = function() { // In that case, the iterator will still have more elements // and the loop is continued // Before descending, we reset the iterator to provide the current element again. - var annotatedText = this._annotatedText(state, iterator.back(), { offset: 0, breakOnUnknown: true }); + // TODO: We have disabled the described behavior as it seems + // worse to break automatically on unknown inline tags, + // than to render plain text, as it results in data loss. + // If you find a situation where you want to flatten structure + // found within a paragraph, use this.acceptedParagraphElements instead + // which is used in a preparation step before converting paragraphs. + var annotatedText = this._annotatedText(state, iterator.back(), { offset: 0, breakOnUnknown: false }); // Ignore empty paragraphs if (annotatedText.length > 0) { @@ -1521,7 +1536,6 @@ NlmToLensConverter.Prototype = function() { // popping the stack state.stack.pop(); } - // inline image node else if (type === "inline-graphic") { var url = child.getAttribute("xlink:href"); From 0ad09dd4330ed9226d8222e1bebf5fc54f4384b6 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 9 Feb 2016 00:50:39 +0100 Subject: [PATCH 04/84] Convert type name for custom_annotations. And changed css class of CustomAnnotatioView. --- article/nodes/custom_annotation/custom_annotation_view.js | 2 +- converter/lens_converter.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/article/nodes/custom_annotation/custom_annotation_view.js b/article/nodes/custom_annotation/custom_annotation_view.js index 64304098..e873cd9d 100644 --- a/article/nodes/custom_annotation/custom_annotation_view.js +++ b/article/nodes/custom_annotation/custom_annotation_view.js @@ -8,7 +8,7 @@ CustomAnnotationView.Prototype = function() { this.setClasses = function() { AnnotationView.prototype.setClasses.call(this); - this.$el.addClass(this.node.name); + this.$el.removeClass('custom_annotation').addClass(this.node.name); }; }; diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 9a90d951..63c7455d 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -2125,6 +2125,8 @@ NlmToLensConverter.Prototype = function() { } else if (type === 'inline-formula') { var formula = this.formula(state, el, "inline"); anno.target = formula.id; + } else if (anno.type === 'custom_annotation') { + anno.name = type; } }; From c711e7b85d75aea836c9272ddd096b4339eb1a20 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 9 Feb 2016 00:50:54 +0100 Subject: [PATCH 05/84] Convert roman annotations. --- extensions/math/math_converter.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extensions/math/math_converter.js b/extensions/math/math_converter.js index 4e8110a5..c4471095 100644 --- a/extensions/math/math_converter.js +++ b/extensions/math/math_converter.js @@ -25,6 +25,10 @@ MathConverter.Prototype = function MathConverterPrototype() { "def-list": { handler: 'defList' } }); + this._annotationTypes = _.extend(__super__._annotationTypes, { + "roman": "custom_annotation" + }); + this.test = function(xmlDoc, documentUrl) { /* jshint unused:false */ var publisherName = xmlDoc.querySelector("publisher-name").textContent; @@ -763,6 +767,7 @@ MathConverter.Prototype = function MathConverterPrototype() { } } }; + }; MathConverter.Prototype.prototype = LensConverter.prototype; From 8c8655b013c036c022c44e75bf90ba7742b75bcd Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 9 Feb 2016 01:15:10 +0100 Subject: [PATCH 06/84] Extract specific-use from . --- article/nodes/_affiliation/affiliation.js | 3 ++- converter/lens_converter.js | 7 ++++++- extensions/math/math_converter.js | 4 +++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/article/nodes/_affiliation/affiliation.js b/article/nodes/_affiliation/affiliation.js index 9fc038ce..bab60604 100644 --- a/article/nodes/_affiliation/affiliation.js +++ b/article/nodes/_affiliation/affiliation.js @@ -15,7 +15,8 @@ Affiliation.type = { "country": "string", "department": "string", "institution": "string", - "label": "string" + "label": "string", + "specific_use": "string" } }; diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 63c7455d..105434e6 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -600,6 +600,8 @@ NlmToLensConverter.Prototype = function() { var label = aff.querySelector("label"); var department = aff.querySelector("addr-line named-content[content-type=department]"); var city = aff.querySelector("addr-line named-content[content-type=city]"); + // TODO: there are a lot more elements which can have this. + var specific_use = aff.getAttribute('specific-use'); // TODO: this is a potential place for implementing a catch-bin // For that, iterate all children elements and fill into properties as needed or add content to the catch-bin @@ -612,7 +614,8 @@ NlmToLensConverter.Prototype = function() { department: department ? department.textContent : null, city: city ? city.textContent : null, institution: institution ? institution.textContent : null, - country: country ? country.textContent: null + country: country ? country.textContent: null, + specific_use: specific_use || null }; doc.create(affiliationNode); }; @@ -1128,6 +1131,8 @@ NlmToLensConverter.Prototype = function() { }, this); }; + // TODO: abstract should be a dedicated node + // as it can have some extra information in JATS, such as specific-use this.abstract = function(state, abs) { var doc = state.doc; var nodes = []; diff --git a/extensions/math/math_converter.js b/extensions/math/math_converter.js index c4471095..bc8814b3 100644 --- a/extensions/math/math_converter.js +++ b/extensions/math/math_converter.js @@ -515,6 +515,7 @@ MathConverter.Prototype = function MathConverterPrototype() { if (type === 'label' || !el.textContent) continue; institutionText += el.textContent; } + var specific_use = aff.getAttribute('specific-use'); // TODO: we might add a property to the affiliation node that collects // data which is not handled here @@ -524,7 +525,8 @@ MathConverter.Prototype = function MathConverterPrototype() { type: "affiliation", source_id: aff.getAttribute("id"), label: label ? label.textContent : null, - institution: institutionText + institution: institutionText, + specific_use: specific_use || null }; state.affiliations.push(affiliationNode.id); From 7f1555061e72899ec2d59a85f7867c63042ccdca Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 9 Feb 2016 10:49:12 +0100 Subject: [PATCH 07/84] Fix require paths. --- extensions/math/math_converter.js | 6 +++--- extensions/math/math_panel.js | 2 +- extensions/math/nodes/citation/citation_view.js | 2 +- extensions/math/nodes/citation/index.js | 2 +- extensions/math/nodes/enumeration/enumeration.js | 2 +- extensions/math/nodes/enumeration/enumeration_view.js | 2 +- extensions/math/nodes/enumeration_item/enumeration_item.js | 2 +- .../math/nodes/enumeration_item/enumeration_item_view.js | 4 ++-- extensions/math/nodes/formula/formula.js | 2 +- extensions/math/nodes/formula/formula_view.js | 6 +++--- .../math/nodes/formula_reference/formula_reference.js | 4 ++-- extensions/math/nodes/formula_reference/index.js | 2 +- extensions/math/nodes/math_environment/math_environment.js | 2 +- .../math/nodes/math_environment/math_environment_view.js | 6 +++--- extensions/math/nodes/math_environment_reference/index.js | 2 +- .../math_environment_reference.js | 4 ++-- extensions/math/nodes/plain_citation/plain_citation.js | 2 +- extensions/math/nodes/plain_citation/plain_citation_view.js | 6 +++--- extensions/math/nodes/proof/proof.js | 2 +- extensions/math/nodes/proof/proof_view.js | 4 ++-- extensions/math/workflows/toggle_formula.js | 2 +- extensions/math/workflows/toggle_math_environment.js | 2 +- extensions/math/workflows/zoom_formula.js | 2 +- reader/lens.js | 6 +++--- reader/lens_controller.js | 4 ++-- 25 files changed, 40 insertions(+), 40 deletions(-) diff --git a/extensions/math/math_converter.js b/extensions/math/math_converter.js index bc8814b3..28a690c3 100644 --- a/extensions/math/math_converter.js +++ b/extensions/math/math_converter.js @@ -1,8 +1,8 @@ var _ = require('underscore'); -var util = require("lens/substance/util"); -var LensConverter = require('lens/converter'); -var LensArticle = require("lens/article"); +var util = require("../../substance/util"); +var LensConverter = require('../../converter'); +var LensArticle = require("../../article"); var MathNodeTypes = require("./nodes"); // Options: diff --git a/extensions/math/math_panel.js b/extensions/math/math_panel.js index 9ec31814..72b8a240 100644 --- a/extensions/math/math_panel.js +++ b/extensions/math/math_panel.js @@ -1,6 +1,6 @@ "use strict"; -var Lens = require('lens/reader'); +var Lens = require('../../reader'); var ContainerPanel = Lens.ContainerPanel; var ContainerPanelController = Lens.ContainerPanelController; var ContainerPanelView = Lens.ContainerPanelView; diff --git a/extensions/math/nodes/citation/citation_view.js b/extensions/math/nodes/citation/citation_view.js index 5d376fa1..f9b88e5a 100644 --- a/extensions/math/nodes/citation/citation_view.js +++ b/extensions/math/nodes/citation/citation_view.js @@ -1,6 +1,6 @@ "use strict"; -var LensNodes = require('lens/article/nodes'); +var LensNodes = require('../../article/nodes'); var LensCitationView = LensNodes['citation'].View; diff --git a/extensions/math/nodes/citation/index.js b/extensions/math/nodes/citation/index.js index 8fca51c3..e9672eca 100644 --- a/extensions/math/nodes/citation/index.js +++ b/extensions/math/nodes/citation/index.js @@ -1,4 +1,4 @@ -var LensNodes = require('lens/article/nodes'); +var LensNodes = require('../../../../article/nodes'); module.exports = { Model: LensNodes['citation'].Model, diff --git a/extensions/math/nodes/enumeration/enumeration.js b/extensions/math/nodes/enumeration/enumeration.js index caa5dbd3..ca56d1c0 100644 --- a/extensions/math/nodes/enumeration/enumeration.js +++ b/extensions/math/nodes/enumeration/enumeration.js @@ -1,7 +1,7 @@ "use strict"; var _ = require("underscore"); -var Document = require("lens/substance/document"); +var Document = require("../../../../substance/document"); var DocumentNode = Document.Node; var Composite = Document.Composite; diff --git a/extensions/math/nodes/enumeration/enumeration_view.js b/extensions/math/nodes/enumeration/enumeration_view.js index 57d680fe..0403be47 100644 --- a/extensions/math/nodes/enumeration/enumeration_view.js +++ b/extensions/math/nodes/enumeration/enumeration_view.js @@ -1,6 +1,6 @@ "use strict"; -var LensNodes = require('lens/article/nodes'); +var LensNodes = require('../../../../article/nodes'); var NodeView = LensNodes['node'].View; var CompositeView = LensNodes['composite'].View; diff --git a/extensions/math/nodes/enumeration_item/enumeration_item.js b/extensions/math/nodes/enumeration_item/enumeration_item.js index 092c7c72..03a1e69d 100644 --- a/extensions/math/nodes/enumeration_item/enumeration_item.js +++ b/extensions/math/nodes/enumeration_item/enumeration_item.js @@ -1,7 +1,7 @@ "use strict"; var _ = require('underscore'); -var Document = require('lens/substance/document'); +var Document = require('../../../../substance/document'); var EnumerationItem = function(node, doc) { Document.Composite.call(this, node, doc); diff --git a/extensions/math/nodes/enumeration_item/enumeration_item_view.js b/extensions/math/nodes/enumeration_item/enumeration_item_view.js index f9d84f92..d2de789d 100644 --- a/extensions/math/nodes/enumeration_item/enumeration_item_view.js +++ b/extensions/math/nodes/enumeration_item/enumeration_item_view.js @@ -1,7 +1,7 @@ "use strict"; -var LensNodes = require("lens/article/nodes"); -var $$ = require("lens/substance/application").$$; +var LensNodes = require("../../../../article/nodes"); +var $$ = require("../../../../substance/application").$$; var NodeView = LensNodes["node"].View; var CompositeView = LensNodes["composite"].View; diff --git a/extensions/math/nodes/formula/formula.js b/extensions/math/nodes/formula/formula.js index 7c723803..8e20c2d3 100644 --- a/extensions/math/nodes/formula/formula.js +++ b/extensions/math/nodes/formula/formula.js @@ -1,6 +1,6 @@ "use strict"; -var Document = require('lens/substance/document'); +var Document = require('../../../../substance/document'); // Formula // ----------------- diff --git a/extensions/math/nodes/formula/formula_view.js b/extensions/math/nodes/formula/formula_view.js index ef2ac480..4a14caad 100644 --- a/extensions/math/nodes/formula/formula_view.js +++ b/extensions/math/nodes/formula/formula_view.js @@ -1,12 +1,12 @@ "use strict"; var _ = require('underscore'); -var LensNodes = require('lens/article/nodes'); +var LensNodes = require('../../../../article/nodes'); var NodeView = LensNodes["node"].View; -var LensArticle = require('lens/article'); +var LensArticle = require('../../../../article'); var ResourceView = LensArticle.ResourceView; -var $$ = require('lens/substance/application').$$; +var $$ = require('../../../../substance/application').$$; // FormulaView // =========== diff --git a/extensions/math/nodes/formula_reference/formula_reference.js b/extensions/math/nodes/formula_reference/formula_reference.js index 859762c4..aab49483 100644 --- a/extensions/math/nodes/formula_reference/formula_reference.js +++ b/extensions/math/nodes/formula_reference/formula_reference.js @@ -1,7 +1,7 @@ "use strict"; -var Document = require('lens/substance/document'); -var LensNodes = require('lens/article/nodes'); +var Document = require('../../../../substance/document'); +var LensNodes = require('../../../../article/nodes'); var Annotation = LensNodes['annotation'].Model; var ResourceReference = LensNodes['resource_reference'].Model; diff --git a/extensions/math/nodes/formula_reference/index.js b/extensions/math/nodes/formula_reference/index.js index 07a78d82..f6a72b7e 100644 --- a/extensions/math/nodes/formula_reference/index.js +++ b/extensions/math/nodes/formula_reference/index.js @@ -1,4 +1,4 @@ -var LensNodes = require('lens/article/nodes'); +var LensNodes = require('../../../../article/nodes'); module.exports = { Model: require('./formula_reference.js'), diff --git a/extensions/math/nodes/math_environment/math_environment.js b/extensions/math/nodes/math_environment/math_environment.js index dfed8829..3d7064f0 100644 --- a/extensions/math/nodes/math_environment/math_environment.js +++ b/extensions/math/nodes/math_environment/math_environment.js @@ -1,6 +1,6 @@ "use strict"; -var LensNodes = require('lens/article/nodes'); +var LensNodes = require('../../../../article/nodes'); var DocumentNode = LensNodes['node'].Model; var MathEnvironment = function(node, document) { diff --git a/extensions/math/nodes/math_environment/math_environment_view.js b/extensions/math/nodes/math_environment/math_environment_view.js index 9b93e380..31257507 100644 --- a/extensions/math/nodes/math_environment/math_environment_view.js +++ b/extensions/math/nodes/math_environment/math_environment_view.js @@ -1,12 +1,12 @@ "use strict"; var _ = require('underscore'); -var LensArticle = require('lens/article'); -var LensNodes = require('lens/article/nodes'); +var LensArticle = require('../../../../article'); +var LensNodes = require('../../../../article/nodes'); var NodeView = LensNodes["node"].View; var ResourceView = LensArticle.ResourceView; -var $$ = require('lens/substance/application').$$; +var $$ = require('../../../../substance/application').$$; // Lens.MathEnvironment.View // ========================================================================== diff --git a/extensions/math/nodes/math_environment_reference/index.js b/extensions/math/nodes/math_environment_reference/index.js index 7299bae3..e693d54c 100644 --- a/extensions/math/nodes/math_environment_reference/index.js +++ b/extensions/math/nodes/math_environment_reference/index.js @@ -1,4 +1,4 @@ -var LensNodes = require('lens/article/nodes'); +var LensNodes = require('../../../../article/nodes'); module.exports = { Model: require('./math_environment_reference.js'), diff --git a/extensions/math/nodes/math_environment_reference/math_environment_reference.js b/extensions/math/nodes/math_environment_reference/math_environment_reference.js index cadfaf09..c1224b10 100644 --- a/extensions/math/nodes/math_environment_reference/math_environment_reference.js +++ b/extensions/math/nodes/math_environment_reference/math_environment_reference.js @@ -1,7 +1,7 @@ "use strict"; -var Document = require('lens/substance/document'); -var LensNodes = require('lens/article/nodes'); +var Document = require('../../../../substance/document'); +var LensNodes = require('../../../../article/nodes'); var Annotation = LensNodes['annotation'].Model; var ResourceReference = LensNodes['resource_reference'].Model; diff --git a/extensions/math/nodes/plain_citation/plain_citation.js b/extensions/math/nodes/plain_citation/plain_citation.js index d6544f64..affad7ec 100644 --- a/extensions/math/nodes/plain_citation/plain_citation.js +++ b/extensions/math/nodes/plain_citation/plain_citation.js @@ -1,6 +1,6 @@ "use strict"; -var Document = require('lens/substance/document'); +var Document = require('../../../../substance/document'); var PlainCitation = function(node, doc) { Document.Node.call(this, node, doc); diff --git a/extensions/math/nodes/plain_citation/plain_citation_view.js b/extensions/math/nodes/plain_citation/plain_citation_view.js index faed8b2d..bd638eb9 100644 --- a/extensions/math/nodes/plain_citation/plain_citation_view.js +++ b/extensions/math/nodes/plain_citation/plain_citation_view.js @@ -6,11 +6,11 @@ var LABELS = { }; var _ = require('underscore'); -var LensArticle = require('lens/article'); -var LensNodes = require('lens/article/nodes'); +var LensArticle = require('../../../../article'); +var LensNodes = require('../../../../article/nodes'); var NodeView = LensNodes['node'].View; var ResourceView = LensArticle.ResourceView; -var $$ = require("lens/substance/application").$$; +var $$ = require("../../../../substance/application").$$; // Lens.Citation.View // ========================================================================== diff --git a/extensions/math/nodes/proof/proof.js b/extensions/math/nodes/proof/proof.js index b91e0e7d..0adc25bd 100644 --- a/extensions/math/nodes/proof/proof.js +++ b/extensions/math/nodes/proof/proof.js @@ -1,6 +1,6 @@ "use strict"; -var Document = require('lens/substance/document'); +var Document = require('../../../../substance/document'); var Composite = Document.Composite; // Lens.Proof diff --git a/extensions/math/nodes/proof/proof_view.js b/extensions/math/nodes/proof/proof_view.js index bf415745..8186afcd 100644 --- a/extensions/math/nodes/proof/proof_view.js +++ b/extensions/math/nodes/proof/proof_view.js @@ -1,9 +1,9 @@ "use strict"; -var LensNodes = require('lens/article/nodes'); +var LensNodes = require('../../../../article/nodes'); var NodeView = LensNodes["node"].View; var CompositeView = LensNodes["composite"].View; -var $$ = require("lens/substance/application").$$; +var $$ = require("../../../../substance/application").$$; // Lens.Proof.View diff --git a/extensions/math/workflows/toggle_formula.js b/extensions/math/workflows/toggle_formula.js index cd813065..3508f031 100644 --- a/extensions/math/workflows/toggle_formula.js +++ b/extensions/math/workflows/toggle_formula.js @@ -1,5 +1,5 @@ var _ = require('underscore'); -var Lens = require('lens/reader'); +var Lens = require('../../../reader'); var Workflow = Lens.Workflow; var ToggleFormula = function() { diff --git a/extensions/math/workflows/toggle_math_environment.js b/extensions/math/workflows/toggle_math_environment.js index 84d5afc0..57896e36 100644 --- a/extensions/math/workflows/toggle_math_environment.js +++ b/extensions/math/workflows/toggle_math_environment.js @@ -1,5 +1,5 @@ var _ = require('underscore'); -var Lens = require('lens/reader'); +var Lens = require('../../../reader'); var Workflow = Lens.Workflow; var ToggleMathEnvironment = function() { diff --git a/extensions/math/workflows/zoom_formula.js b/extensions/math/workflows/zoom_formula.js index a1e6e46f..52211e2b 100644 --- a/extensions/math/workflows/zoom_formula.js +++ b/extensions/math/workflows/zoom_formula.js @@ -1,5 +1,5 @@ var _ = require('underscore'); -var Lens = require('lens/reader'); +var Lens = require('../../../reader'); var Workflow = Lens.Workflow; var ZoomFormula = function() { diff --git a/reader/lens.js b/reader/lens.js index 7d8a74bf..a15cd22f 100644 --- a/reader/lens.js +++ b/reader/lens.js @@ -1,9 +1,9 @@ "use strict"; -var Application = require("../substance/application"); var LensController = require("./lens_controller"); -var LensConverter = require("lens/converter"); -var LensArticle = require("lens/article"); +var LensConverter = require("../converter"); +var Application = require("../substance/application"); +var LensArticle = require("../article"); var ResourcePanelViewFactory = require("./panels/resource_panel_viewfactory"); var ReaderController = require('./reader_controller'); var ReaderView = require('./reader_view'); diff --git a/reader/lens_controller.js b/reader/lens_controller.js index f385e34c..7f5222ec 100644 --- a/reader/lens_controller.js +++ b/reader/lens_controller.js @@ -5,8 +5,8 @@ var util = require("../substance/util"); var Controller = require('../substance/application').Controller; var LensView = require("./lens_view"); var ReaderController = require('./reader_controller'); -var LensArticle = require('lens/article'); -var NLMConverter = require('lens/converter'); +var LensArticle = require('../article'); +var NLMConverter = require('../converter'); // Lens.Controller From a6d57071cbb49bb601c373f541a32a027573ec6d Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 9 Feb 2016 11:01:30 +0100 Subject: [PATCH 08/84] Consider , and tags Fixes #142. --- converter/lens_converter.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 105434e6..aab8d2b0 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -19,6 +19,9 @@ NlmToLensConverter.Prototype = function() { "sub": "subscript", "sup": "superscript", "sc": "custom_annotation", + "roman": "custom_annotation", + "sans-serif": "custom_annotation", + "styled-content": "custom_annotation", "underline": "underline", "ext-link": "link", "xref": "", From d5b52384a92c126fc8ee58cd3b81d0f9f5bd9222 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 12 Feb 2016 10:56:21 +0100 Subject: [PATCH 09/84] Fix nested def-list conversion. --- extensions/math/math_converter.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/math/math_converter.js b/extensions/math/math_converter.js index 28a690c3..a80b6481 100644 --- a/extensions/math/math_converter.js +++ b/extensions/math/math_converter.js @@ -120,7 +120,8 @@ MathConverter.Prototype = function MathConverterPrototype() { }; var term = defItem.querySelector('term'); enumItemNode.label = this.annotatedText(state, term, [enumItemNode.id, 'label']); - var pEls = defItem.querySelectorAll('def p'); + var def = defItem.querySelector('def'); + var pEls = this.selectDirectChildren(def, 'p'); for (var j = 0; j < pEls.length; j++) { var p = pEls[j]; var children = this.paragraphGroup(state, p); From 9acf7785768ee60f0d7d734097c5db23f708ef8e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 12 Feb 2016 11:26:10 +0100 Subject: [PATCH 10/84] Skip converstion of broken references. --- extensions/math/math_converter.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/extensions/math/math_converter.js b/extensions/math/math_converter.js index a80b6481..cac433ff 100644 --- a/extensions/math/math_converter.js +++ b/extensions/math/math_converter.js @@ -113,14 +113,24 @@ MathConverter.Prototype = function MathConverterPrototype() { var defItems = this.selectDirectChildren(defList, 'def-item'); for (var i = 0; i < defItems.length; i++) { var defItem = defItems[i]; + var term = defItem.querySelector('term'); + var termId = term.id; + var def = defItem.querySelector('def'); var enumItemNode = { type: 'enumeration-item', + // TODO: enabling the correct id makes warnings disappear + // which are given when seeing references to this def + // However, to work properly, we would need nesting support + // for definition references + // so we leave it for now + // id: termId || state.nextId('enumeration-item'), id: state.nextId('enumeration-item'), children: [] }; - var term = defItem.querySelector('term'); + // convert label enumItemNode.label = this.annotatedText(state, term, [enumItemNode.id, 'label']); - var def = defItem.querySelector('def'); + // convert content + // TODO: is the assumption correct that def-item content is always wrapped in a p element? var pEls = this.selectDirectChildren(def, 'p'); for (var j = 0; j < pEls.length; j++) { var p = pEls[j]; @@ -694,6 +704,7 @@ MathConverter.Prototype = function MathConverterPrototype() { anno.target = targetNode.id; } else { console.log("Could not lookup math environment for reference", anno); + continue; } referencedMath[targetNode.id] = true; } else { @@ -702,6 +713,7 @@ MathConverter.Prototype = function MathConverterPrototype() { anno.target = targetNode.id; } else { console.log("Could not lookup targetNode for annotation", anno); + continue; } } } From a3c0bc545482ff1af8c31cb4ed0a9daf9f7eb40b Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 12 Feb 2016 13:44:52 +0100 Subject: [PATCH 11/84] Add support for appendices. --- converter/lens_converter.js | 74 +++++++++++++++++++++++++++++-- extensions/math/math_converter.js | 6 +++ 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index aab8d2b0..5e03dd0e 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -955,6 +955,10 @@ NlmToLensConverter.Prototype = function() { this.extractFigures(state, article); + // Extract back element + var back = article.querySelector("back"); + this.back(state,back); + this.enhanceArticle(state, article); }; @@ -2085,12 +2089,76 @@ NlmToLensConverter.Prototype = function() { // Article.Back // -------- - this.back = function(/*state, back*/) { - // No processing at the moment - return null; + this.back = function(state, back) { + var appGroups = back.querySelectorAll('app-group'); + + if (appGroups && appGroups.length > 0) { + _.each(appGroups, function(appGroup) { + this.appGroup(state, appGroup); + }.bind(this)); + } else { + // HACK: We treat element as app-group, sine there + // are docs that wrongly put elements into the back + // element directly. + this.appGroup(state, back); + } + }; + + this.appGroup = function(state, appGroup) { + var apps = appGroup.querySelectorAll('app'); + var doc = state.doc; + var title = appGroup.querySelector('title'); + if (!title) { + console.error("FIXME: every app should have a title", this.toHtml(title)); + } + + var headingId =state.nextId("heading"); + // Insert top level element for Appendix + var heading = doc.create({ + "type" : "heading", + "id" : headingId, + "level" : 1, + "content" : title ? this.annotatedText(state, title, [headingId, "content"]) : "Appendix" + }); + + this.show(state, [heading]); + _.each(apps, function(app) { + state.sectionLevel = 2; + this.app(state, app); + }.bind(this)); + }; + + this.app = function(state, app) { + var doc = state.doc; + var nodes = []; + var title = app.querySelector('title'); + if (!title) { + console.error("FIXME: every app should have a title", this.toHtml(title)); + } + + var headingId = state.nextId("heading"); + var heading = { + "type" : "heading", + "id" : headingId, + "level" : 2, + "content": title ? this.annotatedText(state, title, [headingId, "content"]) : "" + }; + var headingNode = doc.create(heading); + nodes.push(headingNode); + + // There may be multiple paragraphs per ack element + var pars = this.bodyNodes(state, util.dom.getChildren(app), { + ignore: ["title", "label", "ref-list"] + }); + _.each(pars, function(par) { + nodes.push(par); + }); + this.show(state, nodes); }; + + // Annotations // ----------- diff --git a/extensions/math/math_converter.js b/extensions/math/math_converter.js index cac433ff..b74dae2e 100644 --- a/extensions/math/math_converter.js +++ b/extensions/math/math_converter.js @@ -75,6 +75,7 @@ MathConverter.Prototype = function MathConverterPrototype() { return doc; }; + // TODO: the default implemenation should be plain, i.e. not adding an extra heading 'Main Text' // Instead the LensConverter should override this... // ...or we should consider adding an option (if the eLife way to do it is more often applicable...) @@ -150,6 +151,10 @@ MathConverter.Prototype = function MathConverterPrototype() { return enumerationNode; }; + // HACK: There is content that has nested elements, which is not allowed + // we just treat them as sections + this._bodyNodes['app'] = this._bodyNodes['sec']; + this.extractDefinitions = function(/*state, article*/) { // We don't want to show a definitions (glossary) panel // TODO: we should consider making this a static configuration for lens-converter @@ -372,6 +377,7 @@ MathConverter.Prototype = function MathConverterPrototype() { state.labelsForFormula[formulaId] = labels; return result; }; + this.formula = function(state, formulaElement, inline) { var doc = state.doc; var id = state.nextId("formula"); From a70c60ddff6894e84f3044233b26db4cc0aa647e Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 12 Feb 2016 14:07:22 +0100 Subject: [PATCH 12/84] Query figures globally. --- converter/lens_converter.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 5e03dd0e..34a09164 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -1039,8 +1039,10 @@ NlmToLensConverter.Prototype = function() { this.extractFigures = function(state, xmlDoc) { // Globally query all figure-ish content, , , , // mimetype="video" - var body = xmlDoc.querySelector("body"); - var figureElements = body.querySelectorAll("fig, table-wrap, supplementary-material, media[mimetype=video]"); + + // NOTE: We previously only considered figures within but since + // appendices can also have figures we now use a gobal selector. + var figureElements = xmlDoc.querySelectorAll("fig, table-wrap, supplementary-material, media[mimetype=video]"); var nodes = []; for (var i = 0; i < figureElements.length; i++) { var figEl = figureElements[i]; From af383cf3be564724660eccf5e9c64cf01b229bc6 Mon Sep 17 00:00:00 2001 From: Peter Krautzberger Date: Thu, 25 Feb 2016 20:56:25 +0100 Subject: [PATCH 13/84] lens-converter: add check for back element Fixes #145 --- converter/lens_converter.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 34a09164..95181c15 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -955,9 +955,11 @@ NlmToLensConverter.Prototype = function() { this.extractFigures(state, article); - // Extract back element + // Extract back element, if it exists var back = article.querySelector("back"); - this.back(state,back); + if (back){ + this.back(state,back); + } this.enhanceArticle(state, article); }; From fda704f12ed6128b0e310162a4134645857c756b Mon Sep 17 00:00:00 2001 From: Peter Krautzberger Date: Mon, 14 Mar 2016 13:06:03 +0100 Subject: [PATCH 14/84] Update lens_converter.js Fix selector for custom-meta tags; resolved #150 --- converter/lens_converter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 95181c15..0ce87892 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -442,7 +442,7 @@ NlmToLensConverter.Prototype = function() { var nodeIds = []; var doc = state.doc; - var customMetaEls = article.querySelectorAll('article-meta-group custom-meta'); + var customMetaEls = article.querySelectorAll('article-meta custom-meta'); if (customMetaEls.length === 0) return nodeIds; for (var i = 0; i < customMetaEls.length; i++) { From efffa9bdb864f2c127bb728760023baf93de8e78 Mon Sep 17 00:00:00 2001 From: Peter Krautzberger Date: Wed, 23 Mar 2016 15:58:36 +0100 Subject: [PATCH 15/84] Update lens_converter.js Check if suffix is empty; fixes #155. --- converter/lens_converter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 95181c15..e1b570ff 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -102,7 +102,7 @@ NlmToLensConverter.Prototype = function() { if (givenNamesEl) names.push(givenNamesEl.textContent); if (surnameEl) names.push(surnameEl.textContent); - if (suffix) return [names.join(" "), suffix.textContent].join(", "); + if (suffix && !(suffix.textContent.trim() === "")) return [names.join(" "), suffix.textContent].join(", "); return names.join(" "); }; From 1b62ed8d412331693c1d02788134a61eb64348eb Mon Sep 17 00:00:00 2001 From: Peter Krautzberger Date: Thu, 31 Mar 2016 10:00:44 +0200 Subject: [PATCH 16/84] [content_panel_view] simplify scrolling to node fixes #157 --- reader/panels/content/content_panel_view.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/reader/panels/content/content_panel_view.js b/reader/panels/content/content_panel_view.js index 65a405ae..7877486e 100644 --- a/reader/panels/content/content_panel_view.js +++ b/reader/panels/content/content_panel_view.js @@ -59,8 +59,7 @@ ContentPanelView.Prototype = function() { this.onTocItemSelected = function(nodeId) { var n = this.findNodeView(nodeId); if (n) { - var topOffset = $(n).position().top+CORRECTION; - this.surface.$el.scrollTop(topOffset); + n.scrollIntoView(); } }; @@ -136,4 +135,4 @@ ContentPanelView.Prototype.prototype = ContainerPanelView.prototype; ContentPanelView.prototype = new ContentPanelView.Prototype(); ContentPanelView.prototype.constructor = ContentPanelView; -module.exports = ContentPanelView; \ No newline at end of file +module.exports = ContentPanelView; From 8aa7dcef10482667abde4ad0c4af817cc8d0f734 Mon Sep 17 00:00:00 2001 From: Peter Krautzberger Date: Thu, 7 Apr 2016 11:48:34 +0200 Subject: [PATCH 17/84] [lens_converter] add support for generic funding-statement --- converter/lens_converter.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 95181c15..faa80a5a 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -228,6 +228,9 @@ NlmToLensConverter.Prototype = function() { // Article information var articleInfo = this.extractArticleInfo(state, article); + // Funding information + var fundingInfo = this.extractFundingInfo(state, article); + // Create PublicationInfo node // --------------- @@ -239,6 +242,7 @@ NlmToLensConverter.Prototype = function() { "related_article": relatedArticle ? relatedArticle.getAttribute("xlink:href") : "", "doi": articleDOI ? articleDOI.textContent : "", "article_info": articleInfo.id, + "funding_info": fundingInfo, // TODO: 'article_type' should not be optional; we need to find a good default implementation "article_type": "", // Optional fields not covered by the default implementation @@ -300,6 +304,20 @@ NlmToLensConverter.Prototype = function() { return articleInfo; }; + this.extractFundingInfo = function(state, article) { + var doc = state.doc; + + var fundingInfo = []; + + var fundingStatements = article.querySelectorAll("funding-statement"); + if (fundingStatements.length > 0){ + for (var i = 0; i < fundingStatements.length; i++){ + fundingInfo.push(fundingStatements[i].textContent); + } + } + return fundingInfo; + }; + // Get reviewing editor // -------------- // TODO: it is possible to have multiple editors. This does only show the first one @@ -1041,7 +1059,7 @@ NlmToLensConverter.Prototype = function() { this.extractFigures = function(state, xmlDoc) { // Globally query all figure-ish content, , , , // mimetype="video" - + // NOTE: We previously only considered figures within but since // appendices can also have figures we now use a gobal selector. var figureElements = xmlDoc.querySelectorAll("fig, table-wrap, supplementary-material, media[mimetype=video]"); From f188ee80bd41121eb92169ac30a79705cf0ad976 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 20 Apr 2016 10:45:49 +0200 Subject: [PATCH 18/84] Update footnote node. --- article/nodes/footnote/footnote.js | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/article/nodes/footnote/footnote.js b/article/nodes/footnote/footnote.js index 7fd4ac72..9a137d16 100644 --- a/article/nodes/footnote/footnote.js +++ b/article/nodes/footnote/footnote.js @@ -4,7 +4,6 @@ var Document = require('../../../substance/document'); var DocumentNode = Document.Node; var Paragraph = require('../paragraph').Model; - var Footnote = function(node, document) { Paragraph.call(this, node, document); }; @@ -13,21 +12,10 @@ Footnote.type = { "id": "footnote", "parent": "paragraph", "properties": { - "label": "string" - } -}; - -// This is used for the auto-generated docs -// ----------------- -// - -Footnote.description = { - "name": "Footnote", - "remarks": [ - "A Footnote is basically a Paragraph with a label." - ], - "properties": { - "label": "A string used as label", + "footnoteType": "string", + "specificUse": "string", + "label": "string", + "children": ["array", "string"] } }; From 992f659bb9b210dc2fbec24ad6fa4e3fdd876f52 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 20 Apr 2016 12:24:08 +0200 Subject: [PATCH 19/84] Convert footnotes. --- .../footnote_reference/footnote_reference.js | 28 +++++++ article/nodes/footnote_reference/index.js | 4 + article/nodes/index.js | 1 + converter/lens_converter.js | 79 +++++++++++++++++-- 4 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 article/nodes/footnote_reference/footnote_reference.js create mode 100644 article/nodes/footnote_reference/index.js diff --git a/article/nodes/footnote_reference/footnote_reference.js b/article/nodes/footnote_reference/footnote_reference.js new file mode 100644 index 00000000..faef8491 --- /dev/null +++ b/article/nodes/footnote_reference/footnote_reference.js @@ -0,0 +1,28 @@ + +var Document = require('../../../substance/document'); +var Annotation = require('../annotation/annotation'); +var ResourceReference = require('../resource_reference/resource_reference'); + +var FootnoteReference = function(node, doc) { + ResourceReference.call(this, node, doc); +}; + +FootnoteReference.type = { + id: "footnote_reference", + parent: "resource_reference", + properties: { + "target": "footnote" + } +}; + +FootnoteReference.Prototype = function() {}; +FootnoteReference.Prototype.prototype = ResourceReference.prototype; +FootnoteReference.prototype = new FootnoteReference.Prototype(); +FootnoteReference.prototype.constructor = FootnoteReference; + +// Do not fragment this annotation +FootnoteReference.fragmentation = Annotation.NEVER; + +Document.Node.defineProperties(FootnoteReference); + +module.exports = FootnoteReference; diff --git a/article/nodes/footnote_reference/index.js b/article/nodes/footnote_reference/index.js new file mode 100644 index 00000000..16c85281 --- /dev/null +++ b/article/nodes/footnote_reference/index.js @@ -0,0 +1,4 @@ +module.exports = { + Model: require('./footnote_reference.js'), + View: require('../resource_reference/resource_reference_view.js') +}; diff --git a/article/nodes/index.js b/article/nodes/index.js index 72042355..9c7f0cfc 100644 --- a/article/nodes/index.js +++ b/article/nodes/index.js @@ -22,6 +22,7 @@ module.exports = { "citation_reference": require("./citation_reference"), "definition_reference": require("./definition_reference"), "cross_reference": require("./cross_reference"), + "footnote_reference": require("./footnote_reference"), "publication_info": require("./publication_info"), /* Annotation'ish content types */ "link": require("./link"), diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 7d439551..9b7690d8 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -31,6 +31,10 @@ NlmToLensConverter.Prototype = function() { "uri": "link" }; + this._inlineNodeTypes = { + "fn": true, + }; + // mapping from xref.refType to node type this._refTypeMapping = { "bibr": "citation_reference", @@ -39,6 +43,7 @@ NlmToLensConverter.Prototype = function() { "supplementary-material": "figure_reference", "other": "figure_reference", "list": "definition_reference", + "fn": "footnote_reference", }; // mapping of contrib type to human readable names @@ -76,6 +81,10 @@ NlmToLensConverter.Prototype = function() { return this._annotationTypes[type] !== undefined; }; + this.isInlineNode = function(type) { + return this._inlineNodeTypes[type] !== undefined; + }; + this.isParagraphish = function(node) { for (var i = 0; i < node.childNodes.length; i++) { var el = node.childNodes[i]; @@ -102,7 +111,7 @@ NlmToLensConverter.Prototype = function() { if (givenNamesEl) names.push(givenNamesEl.textContent); if (surnameEl) names.push(surnameEl.textContent); - if (suffix && !(suffix.textContent.trim() === "")) return [names.join(" "), suffix.textContent].join(", "); + if (suffix && suffix.textContent.trim() !== "") return [names.join(" "), suffix.textContent].join(", "); return names.join(" "); }; @@ -305,8 +314,6 @@ NlmToLensConverter.Prototype = function() { }; this.extractFundingInfo = function(state, article) { - var doc = state.doc; - var fundingInfo = []; var fundingStatements = article.querySelectorAll("funding-statement"); @@ -1437,12 +1444,13 @@ NlmToLensConverter.Prototype = function() { this.acceptedParagraphElements = { "boxed-text": {handler: "boxedText"}, "list": { handler: "list" }, - "disp-formula": { handler: "formula" }, + "disp-formula": { handler: "formula" } }; this.inlineParagraphElements = { "inline-graphic": true, - "inline-formula": true + "inline-formula": true, + "fn": true, }; // Segments children elements of a NLM

element @@ -1944,6 +1952,30 @@ NlmToLensConverter.Prototype = function() { return formulaNode; }; + this.footnote = function(state, footnoteElement) { + var doc = state.doc; + var footnote = { + type: 'footnote', + id: state.nextId('fn'), + source_id: footnoteElement.getAttribute("id"), + label: '', + children: [] + }; + var children = footnoteElement.children; + var i = 0; + if (children[i].tagName.toLowerCase() === 'label') { + footnote.label = this.annotatedText(state, children[i], [footnote.id, 'label']); + i++; + } + footnote.children = []; + for (; i inline, we will create a footnote-reference + var footnote = this.footnote(state, el); + inlineNode.type = 'footnote_reference'; + inlineNode.target = footnote.id; + break; + } + }; + + this.enhanceInlineNodeData = function(state, inlineNode, el, tagName) { + /*jshint unused: false*/ + }; + // Parse annotated text // -------------------- // Make sure you call this method only for nodes where `this.isParagraphish(node) === true` @@ -2291,6 +2356,10 @@ NlmToLensConverter.Prototype = function() { } } } + else if (this.isInlineNode(type)) { + plainText += " "; + this.createInlineNode(state, el, charPos); + } // Unsupported... else if (!breakOnUnknown) { if (state.top().ignore.indexOf(type) < 0) { From b79132504aeb3d823305df4b39faca0506eb63c7 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 20 Apr 2016 13:31:03 +0200 Subject: [PATCH 20/84] Footnote view implementation. --- article/nodes/composite/composite_view.js | 4 -- article/nodes/footnote/footnote.js | 5 +- article/nodes/footnote/footnote_view.js | 17 ++----- .../footnote_reference_view.js | 48 +++++++++++++++++++ article/nodes/footnote_reference/index.js | 2 +- article/nodes/index.js | 3 +- article/nodes/paragraph/paragraph.css | 2 +- styles/reader.css | 39 ++++++++++++++- 8 files changed, 96 insertions(+), 24 deletions(-) create mode 100644 article/nodes/footnote_reference/footnote_reference_view.js diff --git a/article/nodes/composite/composite_view.js b/article/nodes/composite/composite_view.js index cb4cb8d1..9fbb9eea 100644 --- a/article/nodes/composite/composite_view.js +++ b/article/nodes/composite/composite_view.js @@ -16,10 +16,6 @@ CompositeView.Prototype = function() { // ============================= // - // Render Markup - // -------- - // - this.render = function() { NodeView.prototype.render.call(this); diff --git a/article/nodes/footnote/footnote.js b/article/nodes/footnote/footnote.js index 9a137d16..1ecd2c67 100644 --- a/article/nodes/footnote/footnote.js +++ b/article/nodes/footnote/footnote.js @@ -3,9 +3,10 @@ var Document = require('../../../substance/document'); var DocumentNode = Document.Node; var Paragraph = require('../paragraph').Model; +var Composite = Document.Composite; var Footnote = function(node, document) { - Paragraph.call(this, node, document); + Composite.call(this, node, document); }; Footnote.type = { @@ -42,6 +43,6 @@ Footnote.Prototype.prototype = Paragraph.prototype; Footnote.prototype = new Footnote.Prototype(); Footnote.prototype.constructor = Footnote; -DocumentNode.defineProperties(Footnote); +DocumentNode.defineProperties(Footnote.prototype, ["children", "label", "footnoteType", "specificUse"]); module.exports = Footnote; diff --git a/article/nodes/footnote/footnote_view.js b/article/nodes/footnote/footnote_view.js index d11367a9..5f025e4e 100644 --- a/article/nodes/footnote/footnote_view.js +++ b/article/nodes/footnote/footnote_view.js @@ -1,31 +1,20 @@ "use strict"; -var ParagraphView = require("../paragraph").View; +var CompositeView = require("../composite/composite_view"); // Substance.Image.View // ========================================================================== var FootnoteView = function(node, viewFactory) { - ParagraphView.call(this, node, viewFactory); + CompositeView.call(this, node, viewFactory); }; FootnoteView.Prototype = function() { - this.render = function() { - ParagraphView.prototype.render.call(this); - - var labelEl = document.createElement('span'); - labelEl.classList.add('label'); - labelEl.innerHTML = this.node.label; - - this.el.insertBefore(labelEl, this.content); - - return this; - }; }; -FootnoteView.Prototype.prototype = ParagraphView.prototype; +FootnoteView.Prototype.prototype = CompositeView.prototype; FootnoteView.prototype = new FootnoteView.Prototype(); module.exports = FootnoteView; diff --git a/article/nodes/footnote_reference/footnote_reference_view.js b/article/nodes/footnote_reference/footnote_reference_view.js new file mode 100644 index 00000000..eac65f9f --- /dev/null +++ b/article/nodes/footnote_reference/footnote_reference_view.js @@ -0,0 +1,48 @@ +"use strict"; + +var AnnotationView = require('../annotation/annotation_view'); +var $$ = require('../../../substance/application').$$; + +var FootnoteReferenceView = function(node, viewFactory) { + AnnotationView.call(this, node, viewFactory); + this.$el.addClass('footnote-reference'); + this._expanded = false; +}; + +FootnoteReferenceView.Prototype = function() { + + this.render = function() { + var footnote = this._getFootnote(); + // this.el.innerHTML = formulaView.render().el.innerHTML; + this.el.innerHTML = ""; + this.toggleEl = $$('a', {href: '#', html: footnote.properties.label}); + + $(this.toggleEl).on('click', this._onToggle.bind(this)); + this.$el.append(this.toggleEl); + this.footnoteView = this._createView(footnote).render(); + // HACK: some use xref with ref-type='fn' which will produce a different view class + this.footnoteView.$el.addClass('footnote'); + this.$el.append(this.footnoteView.el); + }; + + this._onToggle = function(e) { + e.preventDefault(); + this.$el.toggleClass('sm-expanded'); + }; + + this._createView = function(node) { + var view = this.viewFactory.createView(node); + return view; + }; + + this._getFootnote = function() { + var node = this.node.document.get(this.node.target); + return node; + }; +}; + +FootnoteReferenceView.Prototype.prototype = AnnotationView.prototype; +FootnoteReferenceView.prototype = new FootnoteReferenceView.Prototype(); + +module.exports = FootnoteReferenceView; + diff --git a/article/nodes/footnote_reference/index.js b/article/nodes/footnote_reference/index.js index 16c85281..0043da5a 100644 --- a/article/nodes/footnote_reference/index.js +++ b/article/nodes/footnote_reference/index.js @@ -1,4 +1,4 @@ module.exports = { Model: require('./footnote_reference.js'), - View: require('../resource_reference/resource_reference_view.js') + View: require('./footnote_reference_view.js') }; diff --git a/article/nodes/index.js b/article/nodes/index.js index 9c7f0cfc..09d667b2 100644 --- a/article/nodes/index.js +++ b/article/nodes/index.js @@ -48,5 +48,6 @@ module.exports = { "list": require("./list"), "codeblock": require("./codeblock"), "affiliation": require("./_affiliation"), - "footnote": require("./footnote") + "footnote": require("./footnote"), + "footnote_reference": require("./footnote_reference"), }; diff --git a/article/nodes/paragraph/paragraph.css b/article/nodes/paragraph/paragraph.css index 6ce5306e..2677e100 100644 --- a/article/nodes/paragraph/paragraph.css +++ b/article/nodes/paragraph/paragraph.css @@ -18,7 +18,7 @@ display:block; } -.content-node.paragraph .content-node.text div { +.content-node.paragraph > .content-node.text > div { display:inline; width: auto; } diff --git a/styles/reader.css b/styles/reader.css index 251425e7..b2656161 100644 --- a/styles/reader.css +++ b/styles/reader.css @@ -783,4 +783,41 @@ TOC .panel.document .nodes > .content-node > .focus-handle:hover { border-left: 3px solid #bbb; -} \ No newline at end of file +} + + +/* Footnote +=============================== */ + +.content-node.footnote { + font-size: 13px; + display: block !important; + margin: 20px 0; + border: 1px solid #ddd; + border-radius: 5px; + padding: 20px; +} + +.footnote-reference > a { + color: #444 ; + vertical-align: super; + padding: 0 2px; + border: 1px solid #ddd; + font-size: 13px; +} + +.footnote-reference > a:hover { + background: #eee; +} + +.footnote-reference.sm-expanded > a { + background: #ddd; +} + +.footnote-reference > .footnote { + display: none !important; +} + +.footnote-reference.sm-expanded >.footnote { + display: block !important; +} From 8447e735322430721bb0a11315ad09ee8712999f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 20 Apr 2016 14:45:44 +0200 Subject: [PATCH 21/84] Better error message for unsupported node types. --- converter/lens_converter.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 9b7690d8..6a23b943 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -304,7 +304,7 @@ NlmToLensConverter.Prototype = function() { nodes = nodes.concat(this.extractAcknowledgements(state, article)); // License and Copyright nodes = nodes.concat(this.extractCopyrightAndLicense(state, article)); - // Notes (Footnotes + Author notes) + // Notes ( elements) nodes = nodes.concat(this.extractNotes(state, article)); articleInfo.children = nodes; @@ -448,14 +448,12 @@ NlmToLensConverter.Prototype = function() { }; // - // Extracts footnotes that should be shown in article info + // Extracts notes that should be shown in article info // ------------------------------------------ // - // Needs to be overwritten in configuration - - this.extractNotes = function(/*state, article*/) { - var nodes = []; - return nodes; + this.extractNotes = function(state, article) { + /* jshint unused:false */ + return []; }; // Can be overridden by custom converter to ignore values. @@ -1248,7 +1246,7 @@ NlmToLensConverter.Prototype = function() { node = this.ignoredNode(state, child, type); if (node) nodes.push(node); } else { - console.error("Node not yet supported as top-level node: " + type); + console.error("Node not supported as block-level element: " + type +"\n"+child.outerHTML); } } return nodes; @@ -2369,7 +2367,7 @@ NlmToLensConverter.Prototype = function() { } } else { if (nested) { - console.error("Node not yet supported in annoted text: " + type); + console.error("Node not supported in annoted text: " + type +"\n"+el.outerHTML); } else { // on paragraph level other elements can break a text block From 51b7aa0b9c94f6f884cdb1b164a5d5ad3d1c3bd5 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 20 Apr 2016 14:46:29 +0200 Subject: [PATCH 22/84] Catch all for footnotes. --- converter/lens_converter.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 6a23b943..e1be1b77 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -978,6 +978,9 @@ NlmToLensConverter.Prototype = function() { this.extractFigures(state, article); + // catch all unhandled foot-notes + this.extractFootNotes(state, article); + // Extract back element, if it exists var back = article.querySelector("back"); if (back){ @@ -1091,6 +1094,17 @@ NlmToLensConverter.Prototype = function() { this.show(state, nodes); }; + // Catch-all implementation for footnotes that have not been + // converted yet. + this.extractFootNotes = function(state, article) { + var fnEls = article.querySelectorAll('fn'); + for (var i = 0; i < fnEls.length; i++) { + var fnEl = fnEls[i]; + if (fnEl.__converted__) continue; + this.footnote(state, fnEl); + } + }; + this.extractCitations = function(state, xmlDoc) { var refList = xmlDoc.querySelector("ref-list"); if (refList) { @@ -1971,6 +1985,9 @@ NlmToLensConverter.Prototype = function() { Array.prototype.push.apply(footnote.children, _.pluck(nodes, 'id')); } doc.create(footnote); + // leave a trace for the catch-all converter + // to know that this has been converted already + footnoteElement.__converted__ = true; return footnote; }; From 46f8a358bdddd9ed4015cbb989059fae22170cda Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 20 Apr 2016 14:47:58 +0200 Subject: [PATCH 23/84] Convert inline nodes on paragraph level. --- converter/lens_converter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index e1be1b77..ebf79a87 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -1557,7 +1557,7 @@ NlmToLensConverter.Prototype = function() { var type = util.dom.getNodeType(child); // annotated text node - if (type === "text" || this.isAnnotation(type)) { + if (type === "text" || this.isAnnotation(type) || this.isInlineNode(type)) { var textNode = { id: state.nextId("text"), type: "text", From 8719cfec32ae129801889b33cb2035a78fd200f6 Mon Sep 17 00:00:00 2001 From: Peter Krautzberger Date: Tue, 19 Apr 2016 15:05:49 +0200 Subject: [PATCH 24/84] [math extension] add support for HTML fragments * the HTML fragment needs to be inside element * the HTML fragment should be wrapped in CDATA tags * the HTML fragment can include xlink data for the math panel --- extensions/math/math_converter.js | 9 ++++++++- extensions/math/nodes/formula/formula_view.js | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/extensions/math/math_converter.js b/extensions/math/math_converter.js index b74dae2e..262244b9 100644 --- a/extensions/math/math_converter.js +++ b/extensions/math/math_converter.js @@ -311,7 +311,7 @@ MathConverter.Prototype = function MathConverterPrototype() { this._getFormulaData = function(state, formulaElement, formulaId, inline) { var result = []; - var labels = {'tex' : {}, 'svg': {}, 'math': {}}; + var labels = {'tex' : {}, 'svg': {}, 'html': {}, 'math': {}}; var el = formulaElement; var alternatives = el.querySelector('alternatives'); if (alternatives) el = alternatives; @@ -332,6 +332,13 @@ MathConverter.Prototype = function MathConverterPrototype() { data: this.toHtml(child) }); break; + case "textual-form": + labels.html = this._extractLabels(child); + result.push({ + format: "html", + data: $(child).text() + }); + break; case "mml:math": case "math": // HACK: make sure that mml in display-formulas has set display="block" diff --git a/extensions/math/nodes/formula/formula_view.js b/extensions/math/nodes/formula/formula_view.js index 4a14caad..ffb2ec0d 100644 --- a/extensions/math/nodes/formula/formula_view.js +++ b/extensions/math/nodes/formula/formula_view.js @@ -153,6 +153,14 @@ FormulaView.Prototype = function() { hasPreview = true; } break; + case "html": + // add only if no preview + if (!hasPreview) { + // don't use a preview element + this.$content.append($(data)); + hasPreview = true; + } + break; default: console.error("Unknown formula format:", format); } From 4c691ba04d386cd43d2fd720d23f9cbc3b410a51 Mon Sep 17 00:00:00 2001 From: Peter Krautzberger Date: Mon, 25 Apr 2016 16:15:26 +0200 Subject: [PATCH 25/84] check for MathJax before calling it --- extensions/math/workflows/zoom_formula.js | 8 +++++--- reader/reader_view.js | 14 ++++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/extensions/math/workflows/zoom_formula.js b/extensions/math/workflows/zoom_formula.js index 52211e2b..e26cbd4f 100644 --- a/extensions/math/workflows/zoom_formula.js +++ b/extensions/math/workflows/zoom_formula.js @@ -42,9 +42,11 @@ ZoomFormula.Prototype = function() { // var self = this; - MathJax.Hub.Register.MessageHook("End Process", function (message) { - self.fitFormulas(); - }); + if (window.MathJax){ + MathJax.Hub.Register.MessageHook("End Process", function (message) { + self.fitFormulas(); + }); + } this.readerView.doc.on('app:formulas:changed', this._handleFormulasChange); }; diff --git a/reader/reader_view.js b/reader/reader_view.js index 986924ce..6900f7de 100644 --- a/reader/reader_view.js +++ b/reader/reader_view.js @@ -165,11 +165,13 @@ ReaderView.Prototype = function() { var self = this; // MathJax requires the processed elements to be in the DOM - window.MathJax.Hub.Queue(["Typeset", window.MathJax.Hub]); - window.MathJax.Hub.Queue(function () { - // HACK: using updateState() instead of updateScrollbars() as it also knows how to scroll - self.updateState(); - }); + if (window.MathJax){ + window.MathJax.Hub.Queue(["Typeset", window.MathJax.Hub]); + window.MathJax.Hub.Queue(function () { + // HACK: using updateState() instead of updateScrollbars() as it also knows how to scroll + self.updateState(); + }); + } }, this), 1); return this; @@ -314,7 +316,7 @@ ReaderView.Prototype = function() { self.updateScrollbars(); _.delay(function() { - self.updateScrollbars(); + self.updateScrollbars(); }, 2000); }; From b8a6ab79df66d9affed548c6d3fb3111dce9a6f5 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Wed, 11 May 2016 08:24:40 +0100 Subject: [PATCH 26/84] Use HTTPS where possible --- README.md | 16 ++++++++-------- article/README.md | 4 ++-- article/nodes/citation/citation.js | 2 +- article/nodes/video/video.js | 8 ++++---- converter/elife_converter.js | 28 ++++++++++++++-------------- package.json | 2 +- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 2fe1a976..d05a1bf6 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ **Lens** provides a novel way of looking at content on the web. It is designed to make life easier for researchers, reviewers, authors and readers. -- **Read the [announcement](http://elifesciences.org/elife-news/lens)** -- **Watch the [introduction video](http://vimeo.com/67254579).** -- **See Lens in [action](http://lens.elifesciences.org/00778)** +- **Read the [announcement](https://elifesciences.org/elife-news/lens)** +- **Watch the [introduction video](https://vimeo.com/67254579).** +- **See Lens in [action](https://lens.elifesciences.org/00778)** ## Using Lens @@ -94,7 +94,7 @@ ElifeConverter.Prototype = function() { return [baseURL, node.url].join(''); } else { node.url = [ - "http://cdn.elifesciences.org/elife-articles/", + "https://cdn.elifesciences.org/elife-articles/", state.doc.id, "/suppl/", node.url @@ -203,7 +203,7 @@ Lens can easily be extended with a customized panel. It can be used to show addi - Pull in metrics (click count, number of articles citing that article etc.) - Retrieve related articles dynamically (e.g. important ones that reference the existing one) -For demonstration we will look at the implementation of a simple Altmetrics panel. It will pull data asynchronously from the Altmetrics API (http://api.altmetric.com/v1/doi/10.7554/eLife.00005) and render the information in Lens. +For demonstration we will look at the implementation of a simple Altmetrics panel. It will pull data asynchronously from the Altmetrics API (https://api.altmetric.com/v1/doi/10.7554/eLife.00005) and render the information in Lens. #### Panel Definition @@ -241,7 +241,7 @@ AltmetricsController.Prototype = function() { var doi = this.document.get('publication_info').doi; $.ajax({ - url: "http://api.altmetric.com/v1/doi/"+doi, + url: "https://api.altmetric.com/v1/doi/"+doi, dataType: "json", }).done(function(res) { cb(null, res); @@ -335,9 +335,9 @@ Mobile support has been removed with Lens 2.0 to reduce technical debt and itera ## Credits -Lens was developed in collaboration between [UC Berkeley](http://bioegrad.berkeley.edu/) graduate student [Ivan Grubisic](http://www.linkedin.com/pub/ivan-grubisic/26/353/739) and [eLife](http://elifesciences.org). The team of [Substance](http://substance.io) is helping with the technical execution. +Lens was developed in collaboration between [UC Berkeley](http://bioegrad.berkeley.edu/) graduate student [Ivan Grubisic](https://www.linkedin.com/pub/ivan-grubisic/26/353/739) and [eLife](https://elifesciences.org). The team of [Substance](http://substance.io) is helping with the technical execution. -Substantial contributions were made by [HighWire](highwire.org), which launched Lens for a number of science journals in fall 2014 (The Journal of Biological Chemistry, The Plant Cell, Journal of Lipid Research, mBio®, and more). [The American Mathematical Society (AMS)](http://ams.org/) made Lens ready for advanced rendering of math articles. +Substantial contributions were made by [HighWire](http://highwire.org), which launched Lens for a number of science journals in fall 2014 (The Journal of Biological Chemistry, The Plant Cell, Journal of Lipid Research, mBio®, and more). [The American Mathematical Society (AMS)](http://ams.org/) made Lens ready for advanced rendering of math articles. Thanks go to the following people, who made Lens possible: diff --git a/article/README.md b/article/README.md index 943fe3c1..1e2bec7d 100644 --- a/article/README.md +++ b/article/README.md @@ -1,7 +1,7 @@ Lens Article ===== -The Lens Article Format is an implementation the [Substance Document Model](http://github.com/substance/document) dedicated to scientific content. It features basic content types such as paragraphs, headings, and various figure types such as images, tables and videos complete with captions and cross-references. +The Lens Article Format is an implementation the [Substance Document Model](https://github.com/substance/document) dedicated to scientific content. It features basic content types such as paragraphs, headings, and various figure types such as images, tables and videos complete with captions and cross-references. The document defintions can be extended easily, so you can either create your own flavour or contribute to the Lens Article Format directly. @@ -9,4 +9,4 @@ The document defintions can be extended easily, so you can either create your ow - XML-based formats such as NML are hard to consume by webclients - Strict separation of content and style. Existing formats target print, and thus contain style information, which makes them hard to process by computer programs -- The greatest advantage of Lens Articles is that any of them can be viewed in [Lens](http://github.com/elifesciences/lens), a modern web-based interface for consuming science content. +- The greatest advantage of Lens Articles is that any of them can be viewed in [Lens](https://github.com/elifesciences/lens), a modern web-based interface for consuming science content. diff --git a/article/nodes/citation/citation.js b/article/nodes/citation/citation.js index 47aa1c64..60b943de 100644 --- a/article/nodes/citation/citation.js +++ b/article/nodes/citation/citation.js @@ -90,7 +90,7 @@ Citation.example = { "citation_urls": [ { "name": "PubMed", - "url": "http://www.ncbi.nlm.nih.gov/pubmed/19606141" + "url": "https://www.ncbi.nlm.nih.gov/pubmed/19606141" } ] }; diff --git a/article/nodes/video/video.js b/article/nodes/video/video.js index 29775c2c..55cc16d6 100644 --- a/article/nodes/video/video.js +++ b/article/nodes/video/video.js @@ -58,10 +58,10 @@ Video.example = { "id": "video_1", "type": "video", "label": "Video 1.", - "url": "http://cdn.elifesciences.org/video/eLifeLensIntro2.mp4", - "url_webm": "http://cdn.elifesciences.org/video/eLifeLensIntro2.webm", - "url_ogv": "http://cdn.elifesciences.org/video/eLifeLensIntro2.ogv", - "poster": "http://cdn.elifesciences.org/video/eLifeLensIntro2.png", + "url": "https://cdn.elifesciences.org/video/eLifeLensIntro2.mp4", + "url_webm": "https://cdn.elifesciences.org/video/eLifeLensIntro2.webm", + "url_ogv": "https://cdn.elifesciences.org/video/eLifeLensIntro2.ogv", + "poster": "https://cdn.elifesciences.org/video/eLifeLensIntro2.png", // "doi": "http://dx.doi.org/10.7554/Fake.doi.003", "caption": "caption_25" }; diff --git a/converter/elife_converter.js b/converter/elife_converter.js index ce9e7b9f..3b5e95a0 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -98,11 +98,11 @@ ElifeConverter.Prototype = function() { } node.breadcrumbs = [ - { name: "eLife", url: "http://elifesciences.org/", image: "http://lens.elifesciences.org/lens-elife/styles/elife.png" }, - { name: dispChannel, url: "http://elifesciences.org/category/"+dispChannel.replace(/ /g, '-').toLowerCase() }, + { name: "eLife", url: "https://elifesciences.org/", image: "https://lens.elifesciences.org/lens-elife/styles/elife.png" }, + { name: dispChannel, url: "https://elifesciences.org/category/"+dispChannel.replace(/ /g, '-').toLowerCase() }, ]; - if (category) node.breadcrumbs.push( { name: category, url: "http://elifesciences.org/category/"+category.replace(/ /g, '-').toLowerCase() } ); + if (category) node.breadcrumbs.push( { name: category, url: "https://elifesciences.org/category/"+category.replace(/ /g, '-').toLowerCase() } ); }; // Resolves figure url @@ -116,7 +116,7 @@ ElifeConverter.Prototype = function() { }; - // Example url to JPG: http://cdn.elifesciences.org/elife-articles/00768/svg/elife00768f001.jpg + // Example url to JPG: https://cdn.elifesciences.org/elife-articles/00768/svg/elife00768f001.jpg this.resolveURL = function(state, url) { // Use absolute URL if (url.match(/http:\/\//)) return url; @@ -137,7 +137,7 @@ ElifeConverter.Prototype = function() { } return [ - "http://publishing-cdn.elifesciences.org/", + "https://publishing-cdn.elifesciences.org/", state.doc.id, "/", url @@ -151,7 +151,7 @@ ElifeConverter.Prototype = function() { return [baseURL, node.url].join(''); } else { node.url = [ - "http://publishing-cdn.elifesciences.org/", + "https://publishing-cdn.elifesciences.org/", state.doc.id, "/", node.url @@ -219,7 +219,7 @@ ElifeConverter.Prototype = function() { if (pdfURI) { var pdfLink = [ - "http://publishing-cdn.elifesciences.org/", + "https://publishing-cdn.elifesciences.org/", state.doc.id, "/", pdfURI ? pdfURI.getAttribute("xlink:href") : "#" @@ -275,7 +275,7 @@ ElifeConverter.Prototype = function() { return [baseURL, node.url].join(''); } else { node.url = [ - "http://publishing-cdn.elifesciences.org/", + "https://publishing-cdn.elifesciences.org/", state.doc.id, "/", node.url @@ -286,13 +286,13 @@ ElifeConverter.Prototype = function() { this.enhanceVideo = function(state, node, element) { var href = element.getAttribute("xlink:href").split("."); var name = href[0]; - node.url = "http://api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file/"+name+".mp4"; - node.url_ogv = "http://api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file//"+name+".ogv"; - node.url_webm = "http://api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file//"+name+".webm"; - node.poster = "http://api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file/"+name+".jpg"; + node.url = "https://api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file/"+name+".mp4"; + node.url_ogv = "https://api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file//"+name+".ogv"; + node.url_webm = "https://api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file//"+name+".webm"; + node.poster = "https://api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file/"+name+".jpg"; }; - // Example url to JPG: http://cdn.elifesciences.org/elife-articles/00768/svg/elife00768f001.jpg + // Example url to JPG: https://cdn.elifesciences.org/elife-articles/00768/svg/elife00768f001.jpg this.resolveURL = function(state, url) { // Use absolute URL if (url.match(/http:\/\//)) return url; @@ -313,7 +313,7 @@ ElifeConverter.Prototype = function() { } return [ - "http://publishing-cdn.elifesciences.org/", + "https://publishing-cdn.elifesciences.org/", state.doc.id, "/", url diff --git a/package.json b/package.json index 0ed13374..b23f8852 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "lens", "version": "2.1.0", "description": "A novel way of seeing content.", - "url": "http://github.com/elifesciences/lens", + "url": "https://github.com/elifesciences/lens", "keywords": [ "digital documents", "linked-data", From 2fafc7af081b45e4dcd8fd764296c076d27ef353 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 16 Jun 2016 13:35:42 +0200 Subject: [PATCH 27/84] Add class 'sm-generated' for generated footnote refs. --- article/nodes/footnote_reference/footnote_reference_view.js | 6 +++++- converter/lens_converter.js | 2 ++ styles/reader.css | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/article/nodes/footnote_reference/footnote_reference_view.js b/article/nodes/footnote_reference/footnote_reference_view.js index eac65f9f..e787ef36 100644 --- a/article/nodes/footnote_reference/footnote_reference_view.js +++ b/article/nodes/footnote_reference/footnote_reference_view.js @@ -9,6 +9,7 @@ var FootnoteReferenceView = function(node, viewFactory) { this._expanded = false; }; + FootnoteReferenceView.Prototype = function() { this.render = function() { @@ -16,12 +17,15 @@ FootnoteReferenceView.Prototype = function() { // this.el.innerHTML = formulaView.render().el.innerHTML; this.el.innerHTML = ""; this.toggleEl = $$('a', {href: '#', html: footnote.properties.label}); - + $(this.toggleEl).on('click', this._onToggle.bind(this)); this.$el.append(this.toggleEl); this.footnoteView = this._createView(footnote).render(); // HACK: some use xref with ref-type='fn' which will produce a different view class this.footnoteView.$el.addClass('footnote'); + if (this.node.properties.generated) { + this.$el.addClass('sm-generated'); + } this.$el.append(this.footnoteView.el); }; diff --git a/converter/lens_converter.js b/converter/lens_converter.js index ebf79a87..264fddff 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -2308,6 +2308,8 @@ NlmToLensConverter.Prototype = function() { var footnote = this.footnote(state, el); inlineNode.type = 'footnote_reference'; inlineNode.target = footnote.id; + // We generate footnote references if we find an inline fn element + inlineNode.generated = true; break; } }; diff --git a/styles/reader.css b/styles/reader.css index b2656161..e78f5723 100644 --- a/styles/reader.css +++ b/styles/reader.css @@ -146,7 +146,7 @@ out (on iOS 5.1), or flicker (on iOS 6). */ position: relative; } -/* It's not exactly good to have the overflow-y: scroll for the container AND the surface. +/* It's not exactly good to have the overflow-y: scroll for the container AND the surface. There should be just one overflowing container, if possible */ @@ -795,7 +795,7 @@ TOC margin: 20px 0; border: 1px solid #ddd; border-radius: 5px; - padding: 20px; + padding: 20px; } .footnote-reference > a { From c6be068d42da1f6c331ee5d47d710dfb213ea07a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 20 Apr 2016 15:22:31 +0200 Subject: [PATCH 28/84] Removed trailing comma. --- converter/lens_converter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index dc474e19..c81cfd46 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -1479,7 +1479,7 @@ NlmToLensConverter.Prototype = function() { this.inlineParagraphElements = { "inline-graphic": true, "inline-formula": true, - "fn": true, + "fn": true }; // Segments children elements of a NLM

element From f6802adf06667477cd821d7af2b4f1feb9812911 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 16 Jun 2016 14:54:52 +0200 Subject: [PATCH 29/84] Simplified TextPropertyView.renderAnnotatedText(). --- article/nodes/node/node_view.js | 3 +-- article/nodes/text/text_property_view.js | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/article/nodes/node/node_view.js b/article/nodes/node/node_view.js index e80ea21b..2c23cab9 100644 --- a/article/nodes/node/node_view.js +++ b/article/nodes/node/node_view.js @@ -58,8 +58,7 @@ NodeView.Prototype = function() { }; this.renderAnnotatedText = function(path, el) { - var property = this.node.document.resolve(path); - var view = TextPropertyView.renderAnnotatedText(this.node.document, property, el, this.viewFactory); + var view = TextPropertyView.renderAnnotatedText(this.node.document, path, el, this.viewFactory); return view; }; diff --git a/article/nodes/text/text_property_view.js b/article/nodes/text/text_property_view.js index f790d824..26742e55 100644 --- a/article/nodes/text/text_property_view.js +++ b/article/nodes/text/text_property_view.js @@ -34,7 +34,7 @@ TextPropertyView.Prototype = function() { this.render = function() { this.el.innerHTML = ""; - TextPropertyView.renderAnnotatedText(this.document, this.property, this.el, this.viewFactory); + TextPropertyView.renderAnnotatedText(this.document, this.path, this.el, this.viewFactory); return this; }; @@ -81,10 +81,10 @@ TextPropertyView.Prototype = function() { TextPropertyView.Prototype.prototype = View.prototype; TextPropertyView.prototype = new TextPropertyView.Prototype(); -TextPropertyView.renderAnnotatedText = function(doc, property, el, viewFactory) { +TextPropertyView.renderAnnotatedText = function(doc, path, el, viewFactory) { var fragment = window.document.createDocumentFragment(); - var text = property.get(); - var annotations = doc.getIndex("annotations").get(property.path); + var text = doc.get(path); + var annotations = doc.getIndex("annotations").get(path); // this splits the text and annotations into smaller pieces // which is necessary to generate proper HTML. var annotationViews = []; From 770610b4adaeea5ccb69b27ae5eda6530175f84c Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 16 Jun 2016 14:55:23 +0200 Subject: [PATCH 30/84] Extract keywords and funding info with annotations. --- converter/lens_converter.js | 9 ++++----- extensions/math/math_converter.js | 18 ++++++++++++++---- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index c81cfd46..b6acee74 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -315,11 +315,10 @@ NlmToLensConverter.Prototype = function() { this.extractFundingInfo = function(state, article) { var fundingInfo = []; - - var fundingStatements = article.querySelectorAll("funding-statement"); - if (fundingStatements.length > 0){ - for (var i = 0; i < fundingStatements.length; i++){ - fundingInfo.push(fundingStatements[i].textContent); + var fundingStatementEls = article.querySelectorAll("funding-statement"); + if (fundingStatementEls.length > 0){ + for (var i = 0; i < fundingStatementEls.length; i++) { + fundingInfo.push(this.annotatedText(state, fundingStatementEls[i], ["publication_info", "funding_info", i])); } } return fundingInfo; diff --git a/extensions/math/math_converter.js b/extensions/math/math_converter.js index b74dae2e..f340ff22 100644 --- a/extensions/math/math_converter.js +++ b/extensions/math/math_converter.js @@ -577,7 +577,7 @@ MathConverter.Prototype = function MathConverterPrototype() { // lipid droplet // anti-bacterial // - var keyWords = articleMeta.querySelectorAll("kwd-group kwd"); + var keywordEls = articleMeta.querySelectorAll("kwd-group kwd"); // Extract subjects // ------------ @@ -589,7 +589,7 @@ MathConverter.Prototype = function MathConverterPrototype() { // Microbiology and infectious disease // - var subjects = articleMeta.querySelectorAll("subj-group[subj-group-type=heading] subject"); + var subjectEls = articleMeta.querySelectorAll("subj-group[subj-group-type=heading] subject"); // Article Type // @@ -634,8 +634,18 @@ MathConverter.Prototype = function MathConverterPrototype() { publicationInfo.raw_formats = rawFormats; - publicationInfo.keywords = _.pluck(keyWords, "textContent"); - publicationInfo.subjects = _.pluck(subjects, "textContent"); + var keywords = []; + for (var i = 0; i < keywordEls.length; i++) { + keywords.push(this.annotatedText(state, keywordEls[i], ["publication_info", "keywords", i])); + } + publicationInfo.keywords = keywords; + + var subjects = []; + for (var i = 0; i < subjectEls.length; i++) { + subjects.push(this.annotatedText(state, subjectEls[i], ["publication_info", "subjects", i])); + } + publicationInfo.subjects = subjects; + publicationInfo.article_type = articleType ? articleType.textContent : ""; publicationInfo.links = links; }; From 45e20cbff8166b833e3594e87a780ba7808ed3b2 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 16 Jun 2016 16:03:16 +0200 Subject: [PATCH 31/84] Repair cross references. --- .../cross_reference/cross_reference_view.js | 20 +++++++++++++++++++ article/nodes/cross_reference/index.js | 2 +- reader/panels/panel_view.js | 1 - reader/reader_view.js | 5 ++--- 4 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 article/nodes/cross_reference/cross_reference_view.js diff --git a/article/nodes/cross_reference/cross_reference_view.js b/article/nodes/cross_reference/cross_reference_view.js new file mode 100644 index 00000000..1ea2bf32 --- /dev/null +++ b/article/nodes/cross_reference/cross_reference_view.js @@ -0,0 +1,20 @@ +"use strict"; + +var AnnotationView = require('../annotation/annotation_view'); + +var CrossReferenceView = function(node, viewFactory) { + AnnotationView.call(this, node, viewFactory); + this.$el.addClass('cross-reference'); +}; + +CrossReferenceView.Prototype = function() { + this.createElement = function() { + var el = document.createElement('a'); + el.setAttribute('href', ''); + return el; + }; +}; +CrossReferenceView.Prototype.prototype = AnnotationView.prototype; +CrossReferenceView.prototype = new CrossReferenceView.Prototype(); + +module.exports = CrossReferenceView; diff --git a/article/nodes/cross_reference/index.js b/article/nodes/cross_reference/index.js index 66279861..733cf974 100644 --- a/article/nodes/cross_reference/index.js +++ b/article/nodes/cross_reference/index.js @@ -1,5 +1,5 @@ module.exports = { Model: require('./cross_reference.js'), - View: require('../resource_reference/resource_reference_view.js') + View: require('./cross_reference_view.js') }; diff --git a/reader/panels/panel_view.js b/reader/panels/panel_view.js index 32edfab0..3bf5aade 100644 --- a/reader/panels/panel_view.js +++ b/reader/panels/panel_view.js @@ -127,7 +127,6 @@ PanelView.Prototype = function() { return this.el.querySelector('*[data-id='+nodeId+']'); }; - // Event handling // -------- // diff --git a/reader/reader_view.js b/reader/reader_view.js index 986924ce..bb10ef76 100644 --- a/reader/reader_view.js +++ b/reader/reader_view.js @@ -31,8 +31,6 @@ var ReaderView = function(readerCtrl) { // Note: ATM, it is not possible to override the content panel + toc via panelSpecification this.contentView = readerCtrl.panelCtrls.content.createView(); this.tocView = this.contentView.getTocView(); - - this.panelViews = {}; // mapping to associate reference types to panels // NB, in Lens each resource type has one dedicated panel; @@ -78,6 +76,7 @@ var ReaderView = function(readerCtrl) { this.listenTo(panelView, "toggle-resource-reference", this.onToggleResourceReference); this.listenTo(panelView, "toggle-fullscreen", this.onToggleFullscreen); }, this); + // TODO: treat content panel as panelView and delegate to tocView where necessary this.listenTo(this.contentView, "toggle", this._onTogglePanel); this.listenTo(this.contentView, "toggle-resource", this.onToggleResource); @@ -314,7 +313,7 @@ ReaderView.Prototype = function() { self.updateScrollbars(); _.delay(function() { - self.updateScrollbars(); + self.updateScrollbars(); }, 2000); }; From 556218e40b7184892f7647bd47e79a1657522b9e Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 16 Jun 2016 16:08:43 +0200 Subject: [PATCH 32/84] Make scrollTo implementation robust against relative positioning. Use native bounding rectangles for computation. --- reader/panels/container_panel_view.js | 22 ++---- substance/util/getRelativeBoundingRect.js | 95 +++++++++++++++++++++++ 2 files changed, 100 insertions(+), 17 deletions(-) create mode 100644 substance/util/getRelativeBoundingRect.js diff --git a/reader/panels/container_panel_view.js b/reader/panels/container_panel_view.js index 43baa6e8..312ee7d3 100644 --- a/reader/panels/container_panel_view.js +++ b/reader/panels/container_panel_view.js @@ -4,8 +4,7 @@ var _ = require("underscore"); var Scrollbar = require("./surface_scrollbar"); var Surface = require("../lens_surface"); var PanelView = require("./panel_view"); - -var MENU_BAR_HEIGHT = 40; +var getRelativeBoundingRect = require('../../substance/util/getRelativeBoundingRect'); // TODO: try to get rid of DocumentController and use the Container node instead var ContainerPanelView = function( panelCtrl, viewFactory, config ) { @@ -59,29 +58,18 @@ ContainerPanelView.Prototype = function() { this.scrollTo = function(nodeId) { var n = this.findNodeView(nodeId); if (n) { - var $n = $(n); - - var windowHeight = $(window).height(); var panelHeight = this.surface.$el.height(); - var scrollTop; + var elRect = getRelativeBoundingRect([n], this.surface.$nodes[0]); + var elTop = elRect.top; + var elHeight = elRect.height; - scrollTop = this.surface.$el.scrollTop(); - var elTop = $n.offset().top; - var elHeight = $n.height(); - var topOffset; // Do not scroll if the element is fully visible if ((elTop > 0 && elTop + elHeight < panelHeight) || (elTop >= 0 && elTop < panelHeight)) { // everything fine return; } - // In all other cases scroll to the top of the element - else { - // HACK: we subtract the height of the menu bar to the scroll position, - // because elTop does not consider the offset - topOffset = scrollTop + elTop - MENU_BAR_HEIGHT; - } - this.surface.$el.scrollTop(topOffset); + this.surface.$el.scrollTop(elTop); this.scrollbar.update(); } else { console.info("ContainerPanelView.scrollTo(): Unknown resource '%s'", nodeId); diff --git a/substance/util/getRelativeBoundingRect.js b/substance/util/getRelativeBoundingRect.js new file mode 100644 index 00000000..3a8d4186 --- /dev/null +++ b/substance/util/getRelativeBoundingRect.js @@ -0,0 +1,95 @@ +'use strict'; + +var _ = require("underscore"); +var map = _.map; +var forEach = _.each; + +/* + Calculate a bounding rectangle for a set of rectangles. + + Note: Here, `bounds.right` and `bounds.bottom` are relative to + the left top of the viewport. +*/ +function _getBoundingRect(rects) { + var bounds = { + left: Number.POSITIVE_INFINITY, + top: Number.POSITIVE_INFINITY, + right: Number.NEGATIVE_INFINITY, + bottom: Number.NEGATIVE_INFINITY, + width: Number.NaN, + height: Number.NaN + }; + + forEach(rects, function(rect) { + if (rect.left < bounds.left) { + bounds.left = rect.left; + } + if (rect.top < bounds.top) { + bounds.top = rect.top; + } + if (rect.left + rect.width > bounds.right) { + bounds.right = rect.left + rect.width; + } + if (rect.top + rect.height > bounds.bottom) { + bounds.bottom = rect.top + rect.height; + } + }); + bounds.width = bounds.right - bounds.left; + bounds.height = bounds.bottom - bounds.top; + return bounds; +} + +/* + Calculate the bounding rect of a single element relative to a parent. + + The rectangle dimensions are calculated as the union of the given elements + clientRects. A selection fragment, for example, may appear as a multi-line span + element that consists of a single client rect per line of text in variable widths. +*/ +function _getBoundingOffsetsRect(el, relativeParentEl) { + var relativeParentElRect = relativeParentEl.getBoundingClientRect(); + var elRect = _getBoundingRect(el.getClientRects()); + + var left = elRect.left - relativeParentElRect.left; + var top = elRect.top - relativeParentElRect.top; + return { + left: left, + top: top, + right: relativeParentElRect.width - left - elRect.width, + bottom: relativeParentElRect.height - top - elRect.height, + width: elRect.width, + height: elRect.height + }; +} + +/** + Get bounding rectangle relative to a given parent element. Allows multiple + elements being passed (we need this for selections that consist of multiple + selection fragments). Takes a relative parent element that is used as a + reference point, instead of the browser's viewport. + + @param {Array} els elements to compute the bounding rectangle for + @param {DOMElement} containerEl relative parent used as a reference point + @return {object} rectangle description with left, top, right, bottom, width and height +*/ +function getRelativeBoundingRect(els, containerEl) { + if (els.length === undefined) { + els = [els]; + } + var elRects = map(els, function(el) { + return _getBoundingOffsetsRect(el, containerEl); + }); + + var elsRect = _getBoundingRect(elRects); + var containerElRect = containerEl.getBoundingClientRect(); + return { + left: elsRect.left, + top: elsRect.top, + right: containerElRect.width - elsRect.left - elsRect.width, + bottom: containerElRect.height - elsRect.top - elsRect.height, + width: elsRect.width, + height: elsRect.height + }; +} + +module.exports = getRelativeBoundingRect; \ No newline at end of file From 72c909003305cef019f36ebbdfa54f22c4dad872 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 29 Jun 2016 10:17:59 +0200 Subject: [PATCH 33/84] Remove toggle_math_environment workflow. Zooming now supported via MathJax. --- extensions/math/index.js | 3 +- extensions/math/workflows/zoom_formula.js | 161 ---------------------- 2 files changed, 1 insertion(+), 163 deletions(-) delete mode 100644 extensions/math/workflows/zoom_formula.js diff --git a/extensions/math/index.js b/extensions/math/index.js index f2a431a3..7e76711c 100644 --- a/extensions/math/index.js +++ b/extensions/math/index.js @@ -3,6 +3,5 @@ module.exports = { MathPanel: require("./math_panel"), MathNodes: require('./nodes'), ToggleFormula: require("./workflows/toggle_formula"), - ToggleMathEnvironment: require("./workflows/toggle_math_environment"), - ZoomFormula: require("./workflows/zoom_formula") + ToggleMathEnvironment: require("./workflows/toggle_math_environment") }; \ No newline at end of file diff --git a/extensions/math/workflows/zoom_formula.js b/extensions/math/workflows/zoom_formula.js deleted file mode 100644 index e26cbd4f..00000000 --- a/extensions/math/workflows/zoom_formula.js +++ /dev/null @@ -1,161 +0,0 @@ -var _ = require('underscore'); -var Lens = require('../../../reader'); -var Workflow = Lens.Workflow; - -var ZoomFormula = function() { - Workflow.call(this); - - this.formulaWidths = {}; - this.formulaHeights = {}; - this.formulaIsZoomed = {}; - - this._handleFormulasChange = function() { - this.fitFormulas(); - }.bind(this); - -}; - -ZoomFormula.Prototype = function() { - - this.registerHandlers = function() { - var self = this; - - // Listen for clicks on formulas to toggle scale/scroll - // ------------------ - // - // this way to handle the event is a hack! lens/substance infrastructure should be used here! - - $(this.readerView.$el).on("click",".formula .content .MathJax_Display.zoomable", - function(e) { self.toggleFormulaScaling(e,this); } - ); - - // Attach a lazy/debounced handler for resize events - // ------------------ - // - - $(window).resize(_.debounce(_.bind(function() { - this.fitFormulas(); - }, this), 1)); - - // Recompute zoom factors after MathJax has finished processing. - // ------------------ - // - - var self = this; - if (window.MathJax){ - MathJax.Hub.Register.MessageHook("End Process", function (message) { - self.fitFormulas(); - }); - } - - this.readerView.doc.on('app:formulas:changed', this._handleFormulasChange); - }; - - this.unRegisterHandlers = function() { - $(this.readerView.$el).off("click",".formula .content .MathJax_Display"); - this.readerView.doc.off('app:formulas:changed', this._handleFormulasChange); - }; - - this.fitFormula = function(nodeId,formulaNode) { - var mathjaxContainer = $(formulaNode).find('.MathJax_Display')[0]; - var mathEl = $(formulaNode).find('.math')[0]; - if (!mathEl) return; - - if(this.getFormulaIsZoomed(nodeId)) { // Zoomed - - mathEl.style["-webkit-transform-origin"] = ""; - mathEl.style["-moz-transform-origin"] = ""; - mathEl.style["-ms-transform-origin"] = ""; - mathEl.style.transformOrigin = ""; - mathEl.style["-webkit-transform"] = ""; - mathEl.style["-moz-transform"] = ""; - mathEl.style["-ms-transform"] = ""; - mathEl.style.transform = ""; - - mathjaxContainer.style.height = ""; - mathjaxContainer.style.overflowX = "auto"; - - } else { // Scaled - var containerWidth = $(mathjaxContainer).width(); - var INDENT = 3.0; - var style; - - if (!this.formulaWidths[nodeId]) { - var spanElement = $(mathjaxContainer).find(".math")[0]; - if (spanElement) { - style = window.getComputedStyle(spanElement); - this.formulaWidths[nodeId] = parseFloat(style.fontSize) * (spanElement.bbox.w + INDENT); - } - } - - if (!this.formulaHeights[nodeId]) { - style = window.getComputedStyle(mathjaxContainer); - this.formulaHeights[nodeId] = parseFloat(style.height); - } - var CORRECTION_FACTOR = 0.92; - var ratio = Math.min(containerWidth / this.formulaWidths[nodeId]*CORRECTION_FACTOR,1.0); - // mathEl.style.cursor = (ratio < 0.9 ? "zoom-in" : ""); //simple zoom UI - if (ratio < 0.9) { - mathjaxContainer.classList.add("zoomable"); - } else { - mathjaxContainer.classList.remove("zoomable"); - } - - mathEl.style["-webkit-transform-origin"] = "top left"; - mathEl.style["-moz-transform-origin"] = "top left"; - mathEl.style["-ms-transform-origin"] = "top left"; - mathEl.style.transformOrigin = "top left"; - mathEl.style["-webkit-transform"] = "scale("+ratio+")"; - mathEl.style["-moz-transform"] = "scale("+ratio+")"; - mathEl.style["-ms-transform"] = "scale("+ratio+")"; - mathEl.style.transform = "scale("+ratio+")"; - - mathjaxContainer.style.height = "" + (this.formulaHeights[nodeId] * ratio) + "px"; - mathjaxContainer.style.overflowX = "visible"; - } - }; - - // Trigger fitting all formulas in the document - // ----------------- - - this.fitFormulas = function() { - var self = this; - - $('.content-node.formula').each(function() { - var nodeId = $(this).find('.MathJax_Display .MathJax').attr("id"); - self.fitFormula(nodeId,this); - }); - }; - - // these methods handle the toggling logic - // ----------------- - - this.getFormulaIsZoomed = function(nodeId) { - if(this.formulaIsZoomed[nodeId] === undefined) { - return false; - } else { - return this.formulaIsZoomed[nodeId]; - } - }; - - this.setFormulaIsZoomed = function(nodeId,value) { - this.formulaIsZoomed[nodeId] = value; - }; - - this.toggleFormulaIsZoomed = function(nodeId) { - this.setFormulaIsZoomed(nodeId, !this.getFormulaIsZoomed(nodeId)); - }; - - this.toggleFormulaScaling = function(e, node) { - // var nodeId = $(e.currentTarget).find('.MathJax').attr("id"); - var nodeId = $(node).find('.MathJax').attr("id"); - var formulaNode = $(node).parents('.content-node.formula')[0]; - this.toggleFormulaIsZoomed(nodeId); - this.fitFormula(nodeId, formulaNode); - }; - -}; -ZoomFormula.Prototype.prototype = Workflow.prototype; -ZoomFormula.prototype = new ZoomFormula.Prototype(); - -module.exports = ZoomFormula; From 4796c7984e5fedab00303ab980991f1400ab0f0e Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 1 Jul 2016 16:34:46 +0200 Subject: [PATCH 34/84] Skip scroll into view if element already fully visible. --- reader/panels/container_panel_view.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/reader/panels/container_panel_view.js b/reader/panels/container_panel_view.js index 312ee7d3..33a1e530 100644 --- a/reader/panels/container_panel_view.js +++ b/reader/panels/container_panel_view.js @@ -59,17 +59,20 @@ ContainerPanelView.Prototype = function() { var n = this.findNodeView(nodeId); if (n) { var panelHeight = this.surface.$el.height(); + var screenTop = this.surface.$el.scrollTop(); + var screenBottom = screenTop + panelHeight; var elRect = getRelativeBoundingRect([n], this.surface.$nodes[0]); - var elTop = elRect.top; var elHeight = elRect.height; + var upperBound = elRect.top; // top-offset of upper bound to relative parent + var lowerBound = upperBound+elRect.height; // top-offset of lower bound to relative parent + // Do not scroll if the element is fully visible - if ((elTop > 0 && elTop + elHeight < panelHeight) || (elTop >= 0 && elTop < panelHeight)) { - // everything fine + if (upperBound>=screenTop && lowerBound <= screenBottom) { return; } - this.surface.$el.scrollTop(elTop); + this.surface.$el.scrollTop(upperBound); this.scrollbar.update(); } else { console.info("ContainerPanelView.scrollTo(): Unknown resource '%s'", nodeId); From 8e2f237f786b89f5cb5c677ae2b50ebc617a6290 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 4 Jul 2016 16:31:49 +0200 Subject: [PATCH 35/84] Show figures et al. also when they are inside environments. --- extensions/math/math_converter.js | 101 ++++++++++++------ .../math_environment/math_environment.js | 1 + 2 files changed, 69 insertions(+), 33 deletions(-) diff --git a/extensions/math/math_converter.js b/extensions/math/math_converter.js index 10a0a6be..48378771 100644 --- a/extensions/math/math_converter.js +++ b/extensions/math/math_converter.js @@ -753,6 +753,71 @@ MathConverter.Prototype = function MathConverterPrototype() { state.referencedMath = referencedMath; }; + function _showFigure(state, node) { + // show figures without captions are only in-flow + if (!node.caption) { + state.doc.show('content', node.id); + } + // all others are shown in the figures panel + else { + state.doc.show('figures', node.id); + // in addition a figure can be shown in-flow using position='anchor' + if (node.position === 'anchor') { + state.doc.show('content', node.id); + } + } + } + + function _showFormulaOrEnvironment(state, node, nested) { + var referencedMath = state.referencedMath; + var info = state.nodeInfo[node.id]; + // only show formulas and environments in the math panel + // - if they are referenced + // - or have specificUse='resource' set explicitly + if (referencedMath[node.id] || + (info && info.specificUse === "resource")) { + doc.show(MATH_PANEL, node.id); + } + if (!nested) { + doc.show('content', node.id); + } + // a math environment can have nested content + // such as figures or environments which need + // to be processed recursively + if (node.type === 'math_environment') { + _showNestedContent(state, node.body); + } + } + + function _showNestedContent(state, nodeIds) { + var referencedMath = state.referencedMath; + nodeIds.forEach(function(nodeId) { + var node = state.doc.get(nodeId); + var info = state.nodeInfo[nodeId]; + switch (node.type) { + case 'figure': + // only show figures in the figures panel, + // which have a caption + if (node.caption) { + state.doc.show('figures', nodeId); + } + break; + case 'formula': + case 'math_environment': + _showFormulaOrEnvironment(state, node, 'nested'); + break; + default: + // nothing + } + }); + } + + function _showProof(state, node) { + // proofs are always shown only in the content + state.doc.show('content', node.id); + _showNestedContent(state, node.children); + } + this.populatePanels = function(state) { var doc = state.doc; var referencedMath = state.referencedMath; @@ -761,44 +826,14 @@ MathConverter.Prototype = function MathConverterPrototype() { node = state.shownNodes[i]; switch (node.type) { case 'figure': - // show figures without captions are only in-flow - if (!node.caption) { - state.doc.show('content', node.id); - } - // all others are shown in the figures panel - else { - state.doc.show('figures', node.id); - // in addition a figure can be shown in-flow using position='anchor' - if (node.position === 'anchor') { - state.doc.show('content', node.id); - } - } + _showFigure(state, node); break; case 'formula': case 'math_environment': - info = state.nodeInfo[node.id]; - // only environments or formulas go into the math panel - // that ar referenced or forced using `specific-use='resource'` - if (referencedMath[node.id] || - (info && info.specificUse === "resource")) { - doc.show(MATH_PANEL, node.id); - } - doc.show('content', node.id); + _showFormulaOrEnvironment(state, node); break; - // Special treatment for proofs as they may contain equations - // which when referenced should be displayed in the resource panel case 'proof': - LensConverter.prototype.showNode.call(this, state, node); - for (var j = 0; j < node.children.length; j++) { - child = doc.get(node.children[j]); - if (child.type === 'formula' || child.type === 'math_environment') { - info = state.nodeInfo[child.id]; - if (referencedMath[child.id] || - (info && info.specificUse === "resource")) { - doc.show(MATH_PANEL, child.id); - } - } - } + _showProof(state, node); break; default: LensConverter.prototype.showNode.call(this, state, node); diff --git a/extensions/math/nodes/math_environment/math_environment.js b/extensions/math/nodes/math_environment/math_environment.js index 3d7064f0..93a6a704 100644 --- a/extensions/math/nodes/math_environment/math_environment.js +++ b/extensions/math/nodes/math_environment/math_environment.js @@ -8,6 +8,7 @@ var MathEnvironment = function(node, document) { }; MathEnvironment.type = { + "id": "math_environment", "parent": "content", "properties": { "source_id": "string", From 5d21f5a935be1b1fb9257f76a7bc0b3588704e07 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 4 Jul 2016 16:32:28 +0200 Subject: [PATCH 36/84] Show mark in content scrollbar for highlighted figures. --- reader/reader_view.js | 1 + styles/reader.css | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/reader/reader_view.js b/reader/reader_view.js index 22515469..40b18954 100644 --- a/reader/reader_view.js +++ b/reader/reader_view.js @@ -249,6 +249,7 @@ ReaderView.Prototype = function() { // HACK: abusing addHighlight for adding the fullscreen class // instead I would prefer to handle such focussing explicitely in a workflow if (state.fullscreen) classes.push("fullscreen"); + this.contentView.addHighlight(state.focussedNode, classes.concat('main-occurrence').join(' ')); currentPanelView.addHighlight(state.focussedNode, classes.join(' ')); currentPanelView.scrollTo(state.focussedNode); } diff --git a/styles/reader.css b/styles/reader.css index e78f5723..e1048f73 100644 --- a/styles/reader.css +++ b/styles/reader.css @@ -755,8 +755,11 @@ TOC /* Colors for scroll-bar overlays */ .article .resources .figures .surface-scrollbar .highlighted, -.article .content .surface-scrollbar .highlighted.figure_reference +.article .content .surface-scrollbar .highlighted.figure_reference, +.article .content .surface-scrollbar .highlighted.figure { background-color: rgba(145, 187, 4, 1); } +.article .content .surface-scrollbar .highlighted.figure.main-occurrence + { border-right: 3px solid #5C6148; } .article .resources .citations .surface-scrollbar .highlighted, .article .content .surface-scrollbar .highlighted.citation_reference From 4d56d9672f7322f4ee636ad4a509526aeb3b387b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 8 Jul 2016 13:46:46 +0200 Subject: [PATCH 37/84] Apply all rules for showing figures within math environments. --- extensions/math/math_converter.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/extensions/math/math_converter.js b/extensions/math/math_converter.js index 48378771..9e8040c2 100644 --- a/extensions/math/math_converter.js +++ b/extensions/math/math_converter.js @@ -754,7 +754,7 @@ MathConverter.Prototype = function MathConverterPrototype() { }; function _showFigure(state, node) { - // show figures without captions are only in-flow + // show figures without captions only in the content panel if (!node.caption) { state.doc.show('content', node.id); } @@ -791,15 +791,22 @@ MathConverter.Prototype = function MathConverterPrototype() { function _showNestedContent(state, nodeIds) { var referencedMath = state.referencedMath; - nodeIds.forEach(function(nodeId) { + for (var i = 0; i < nodeIds.length; i++) { + var nodeId = nodeIds[i] var node = state.doc.get(nodeId); var info = state.nodeInfo[nodeId]; switch (node.type) { case 'figure': - // only show figures in the figures panel, - // which have a caption + // showing a figure in figures panel if it has a caption + // and it is not explicitly anchored (position='anchor') + // If a figure doen't have a caption or is anchored explicitly, + // it is shown in the original position. if (node.caption) { - state.doc.show('figures', nodeId); + state.doc.show('figures', nodeId); + if (node.position !== 'anchor') { + nodeIds.splice(i, 1); + i--; + } } break; case 'formula': @@ -809,7 +816,7 @@ MathConverter.Prototype = function MathConverterPrototype() { default: // nothing } - }); + } } function _showProof(state, node) { From 6616888ce6f47b22e35d76a55f64e25e9f7c8f58 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 8 Jul 2016 14:33:55 +0200 Subject: [PATCH 38/84] Experimental: only show figures in the resouce panel which are referenced. --- extensions/math/math_converter.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/extensions/math/math_converter.js b/extensions/math/math_converter.js index 9e8040c2..f7e21e62 100644 --- a/extensions/math/math_converter.js +++ b/extensions/math/math_converter.js @@ -734,6 +734,7 @@ MathConverter.Prototype = function MathConverterPrototype() { targetNode = state.doc.getNodeBySourceId(anno.target) || state.doc.get(anno.target); if (targetNode) { anno.target = targetNode.id; + targetNode.isReferenced = true; } else { console.log("Could not lookup targetNode for annotation", anno); continue; @@ -755,7 +756,7 @@ MathConverter.Prototype = function MathConverterPrototype() { function _showFigure(state, node) { // show figures without captions only in the content panel - if (!node.caption) { + if (!node.isReferenced) { state.doc.show('content', node.id); } // all others are shown in the figures panel @@ -801,7 +802,7 @@ MathConverter.Prototype = function MathConverterPrototype() { // and it is not explicitly anchored (position='anchor') // If a figure doen't have a caption or is anchored explicitly, // it is shown in the original position. - if (node.caption) { + if (node.isReferenced) { state.doc.show('figures', nodeId); if (node.position !== 'anchor') { nodeIds.splice(i, 1); @@ -830,7 +831,7 @@ MathConverter.Prototype = function MathConverterPrototype() { var referencedMath = state.referencedMath; var node, child, info; for (var i = 0; i < state.shownNodes.length; i++) { - node = state.shownNodes[i]; + node = doc.get(state.shownNodes[i].id); switch (node.type) { case 'figure': _showFigure(state, node); From d21cfed4554b84963d7408825e5e0a526a6abd1b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 8 Jul 2016 14:47:25 +0200 Subject: [PATCH 39/84] Experimental: all figures in figures panel - unreferenced anchored ones into main. --- extensions/math/math_converter.js | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/extensions/math/math_converter.js b/extensions/math/math_converter.js index f7e21e62..0bf8973b 100644 --- a/extensions/math/math_converter.js +++ b/extensions/math/math_converter.js @@ -755,18 +755,12 @@ MathConverter.Prototype = function MathConverterPrototype() { }; function _showFigure(state, node) { - // show figures without captions only in the content panel - if (!node.isReferenced) { + // show all figures in the figures panel + state.doc.show('figures', node.id); + // show unreferenced and anchored figures in the main content + if (!node.isReferenced || node.position === 'anchor') { state.doc.show('content', node.id); } - // all others are shown in the figures panel - else { - state.doc.show('figures', node.id); - // in addition a figure can be shown in-flow using position='anchor' - if (node.position === 'anchor') { - state.doc.show('content', node.id); - } - } } function _showFormulaOrEnvironment(state, node, nested) { @@ -798,16 +792,12 @@ MathConverter.Prototype = function MathConverterPrototype() { var info = state.nodeInfo[nodeId]; switch (node.type) { case 'figure': - // showing a figure in figures panel if it has a caption - // and it is not explicitly anchored (position='anchor') - // If a figure doen't have a caption or is anchored explicitly, - // it is shown in the original position. - if (node.isReferenced) { - state.doc.show('figures', nodeId); - if (node.position !== 'anchor') { - nodeIds.splice(i, 1); - i--; - } + // show all figures in the figures panel + state.doc.show('figures', nodeId); + // hide referenced and unanchored figures from the environment + if (node.isReferenced && node.position !== 'anchor') { + nodeIds.splice(i, 1); + i--; } break; case 'formula': From b29ea979c45264b7df767354a9fa3b5d3cc0bf7f Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Wed, 13 Jul 2016 17:19:40 -0700 Subject: [PATCH 40/84] Parse affiliation institution in two possible formats. --- converter/lens_converter.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 34378d7b..e9c28595 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -620,10 +620,16 @@ NlmToLensConverter.Prototype = function() { this.affiliation = function(state, aff) { var doc = state.doc; - var institution = aff.querySelector("institution"); + var department = aff.querySelector("institution[content-type=dept]"); + if (department) { + var institution = aff.querySelector("institution:not([content-type=dept])"); + } else { + var department = aff.querySelector("addr-line named-content[content-type=department]"); + var institution = aff.querySelector("institution"); + } var country = aff.querySelector("country"); var label = aff.querySelector("label"); - var department = aff.querySelector("addr-line named-content[content-type=department]"); + var city = aff.querySelector("addr-line named-content[content-type=city]"); // TODO: there are a lot more elements which can have this. var specific_use = aff.getAttribute('specific-use'); From 73f3a924bbd10a355aba95aef9b4b349b1cca2a4 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 13 Oct 2016 14:43:23 +0200 Subject: [PATCH 41/84] Fix wrong require path. --- converter/elife_converter.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/converter/elife_converter.js b/converter/elife_converter.js index 3b5e95a0..d61218c9 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -3,7 +3,7 @@ var util = require("../substance/util"); var _ = require("underscore"); -var LensConverter = require('lens/converter'); +var LensConverter = require('./lens_converter'); var ElifeConverter = function(options) { LensConverter.call(this, options); @@ -135,7 +135,7 @@ ElifeConverter.Prototype = function() { } else if (!(url.match(/\.gif$/g))) { url = url+'.jpg' } - + return [ "https://publishing-cdn.elifesciences.org/", state.doc.id, @@ -225,7 +225,7 @@ ElifeConverter.Prototype = function() { pdfURI ? pdfURI.getAttribute("xlink:href") : "#" ].join(''); } - + // Version number from the PDF href, default to 1 var match = null; if (pdfURI) { @@ -304,14 +304,14 @@ ElifeConverter.Prototype = function() { return [baseURL, url].join(''); } else { // Use special URL resolving for production articles - + // File extension support if (url.match(/\.tif$/g)) { url = url.replace(/\.tif$/g, '.jpg') } else if (!(url.match(/\.gif$/g))) { url = url+'.jpg' } - + return [ "https://publishing-cdn.elifesciences.org/", state.doc.id, From 5ef89ef59f5213a51f789910f7e72a22834460fe Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 13 Oct 2016 14:43:47 +0200 Subject: [PATCH 42/84] Make some base styles less opinionated. --- article/nodes/publication_info/publication_info.css | 2 +- styles/reader.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/article/nodes/publication_info/publication_info.css b/article/nodes/publication_info/publication_info.css index 13835dac..ad2612a2 100644 --- a/article/nodes/publication_info/publication_info.css +++ b/article/nodes/publication_info/publication_info.css @@ -46,10 +46,10 @@ .article .resources .nodes > .content-node.publication-info .content-node[data-id=articleinfo] .heading.level-3 .content { font-size: 14px; font-weight: normal; - font-family: "Source Sans Pro"; color: #999; } .article .resources .nodes > .content-node.publication-info .content-node[data-id=articleinfo] .content-node { padding-top: 10px; } + diff --git a/styles/reader.css b/styles/reader.css index e1048f73..be30966c 100644 --- a/styles/reader.css +++ b/styles/reader.css @@ -404,7 +404,7 @@ span.annotation.formula_reference, span.publication_reference { .content-node .question { background-color: rgba(16, 167, 222, 0.3); } .content-node .error { background-color: rgba(237, 96, 48, 0.3); } -.content-node .link { color: #1B6685; font-weight: bold; } +.content-node .link { font-weight: bold; } .content-node .link:hover, .content-node .link.highlighted { color: rgba(11, 157, 217, 1); } /* Inline Code Annotations */ From 92836f06ac6a1796712e6bdc629689c41f3ea6f7 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 24 Oct 2016 14:13:08 +0200 Subject: [PATCH 43/84] Remove some hard-coded style definitions. --- article/nodes/cover/cover.css | 4 +--- article/nodes/heading/heading.css | 1 - converter/elife_converter.js | 2 +- styles/lens.css | 17 ++++++++--------- styles/reader.css | 4 ---- 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/article/nodes/cover/cover.css b/article/nodes/cover/cover.css index 1b0d758c..6677c33e 100644 --- a/article/nodes/cover/cover.css +++ b/article/nodes/cover/cover.css @@ -1,5 +1,5 @@ .lens-article .content-node.cover { - color: rgba(0,0,0,0.8); + } .lens-article .content-node.cover .breadcrumbs { @@ -31,8 +31,6 @@ } .lens-article .content-node.cover .published-on { - margin-top: 50px; - margin-bottom: 20px; color: #666; } diff --git a/article/nodes/heading/heading.css b/article/nodes/heading/heading.css index 8269f0fb..de388acc 100644 --- a/article/nodes/heading/heading.css +++ b/article/nodes/heading/heading.css @@ -14,7 +14,6 @@ .content-node.heading { } .content-node.heading .content { - color: rgba(0,0,0,0.8); font-weight: 600; line-height: 40px; } diff --git a/converter/elife_converter.js b/converter/elife_converter.js index d61218c9..1dd539f5 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -98,7 +98,7 @@ ElifeConverter.Prototype = function() { } node.breadcrumbs = [ - { name: "eLife", url: "https://elifesciences.org/", image: "https://lens.elifesciences.org/lens-elife/styles/elife.png" }, + // { name: "eLife", url: "https://elifesciences.org/", image: "https://lens.elifesciences.org/lens-elife/styles/elife.png" }, { name: dispChannel, url: "https://elifesciences.org/category/"+dispChannel.replace(/ /g, '-').toLowerCase() }, ]; diff --git a/styles/lens.css b/styles/lens.css index 198d3f24..96ae43bd 100644 --- a/styles/lens.css +++ b/styles/lens.css @@ -11,11 +11,10 @@ body { margin: 0; background-color: white; -/* -moz-transition: background-color 200ms linear; + /* -moz-transition: background-color 200ms linear; -o-transition: background-color 200ms linear; -webkit-transition: background-color 200ms linear; transition: background-color 200ms linear;*/ - } body.loading { @@ -43,7 +42,7 @@ body.reader { } /* -General Layout +General Layout --------------------------------------- */ #container { @@ -67,7 +66,7 @@ a { color: #1B6685; font-weight: normal; text-decoration: none; - + /* -moz-transition: background-color 100ms linear, color 100ms linear, opacity 100ms linear; -o-transition: background-color 100ms linear, color 100ms linear, opacity 100ms linear; -webkit-transition: background-color 100ms linear, color 100ms linear, opacity 100ms linear; @@ -86,7 +85,7 @@ img { strong { font-weight: 700; } -h1, h2, h3 { +h1, h2, h3 { font-weight: 700; } @@ -94,16 +93,16 @@ h1 a { color: white; } h1 a:hover { color: white; } h2 { - font-size: 1.75em; + font-size: 1.75em; padding-bottom: 20px; } - + h3, h4, h5, h6 { margin-bottom: 20px; font-size: 1em; font-weight: 700; } - + p { padding-bottom: 20px; } @@ -195,7 +194,7 @@ body.loading .spinner-wrapper { .spinner-wrapper .spinner { width: 40px; height: 40px; - margin: 0 auto; + margin: 0 auto; background: #444; -webkit-animation: rotateplane 1.2s infinite ease-in-out; animation: rotateplane 1.2s infinite ease-in-out; diff --git a/styles/reader.css b/styles/reader.css index be30966c..fd5d6ab3 100644 --- a/styles/reader.css +++ b/styles/reader.css @@ -184,7 +184,6 @@ out (on iOS 5.1), or flicker (on iOS 6). */ } .article .resources .nodes > .content-node { - color: #505050; position: relative; background: #fff; border-bottom: 1px solid #ddd; @@ -237,8 +236,6 @@ out (on iOS 5.1), or flicker (on iOS 6). */ .article .resources .resource-header .name { display: block; min-height: 30px; - - color: #444; font-size: 16px; line-height: 21px; padding: 0px 20px; @@ -802,7 +799,6 @@ TOC } .footnote-reference > a { - color: #444 ; vertical-align: super; padding: 0 2px; border: 1px solid #ddd; From d80a5dcf749b813da2149143a851db57256f241a Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 14 Nov 2016 18:58:18 +0100 Subject: [PATCH 44/84] Make article structure conform to new eLife standards. --- converter/elife_converter.js | 21 +++++++++++---------- converter/lens_converter.js | 13 ++++--------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/converter/elife_converter.js b/converter/elife_converter.js index 1dd539f5..b05b4ad4 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -43,15 +43,6 @@ ElifeConverter.Prototype = function() { id: state.nextId("heading"), type: "heading", level: 1, - content: "Article Commentary" - }; - doc.create(heading); - nodes.push(heading); - - heading = { - id: state.nextId("heading"), - type: "heading", - level: 2, content: "Decision letter" }; doc.create(heading); @@ -70,7 +61,7 @@ ElifeConverter.Prototype = function() { heading = { id: state.nextId("heading"), type: "heading", - level: 2, + level: 1, content: "Author response" }; doc.create(heading); @@ -334,6 +325,16 @@ ElifeConverter.Prototype = function() { } }; + this.back = function(state, back) { + var appGroups = back.querySelectorAll('app-group'); + + if (appGroups && appGroups.length > 0) { + _.each(appGroups, function(appGroup) { + this.appGroup(state, appGroup); + }.bind(this)); + } + }; + this.showNode = function(state, node) { switch(node.type) { // Boxes go into the figures view if these conditions are met diff --git a/converter/lens_converter.js b/converter/lens_converter.js index e9c28595..23bc0bc4 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -430,6 +430,7 @@ NlmToLensConverter.Prototype = function() { "level" : 3, "content" : title ? this.capitalized(title.textContent.toLowerCase(), "all") : "Acknowledgements" }; + doc.create(header); nodes.push(header.id); @@ -437,6 +438,7 @@ NlmToLensConverter.Prototype = function() { var pars = this.bodyNodes(state, util.dom.getChildren(ack), { ignore: ["title"] }); + _.each(pars, function(par) { nodes.push(par.id); }); @@ -1219,14 +1221,7 @@ NlmToLensConverter.Prototype = function() { this.body = function(state, body) { var doc = state.doc; - var heading = { - id: state.nextId("heading"), - type: "heading", - level: 1, - content: "Main Text" - }; - doc.create(heading); - var nodes = [heading].concat(this.bodyNodes(state, util.dom.getChildren(body))); + var nodes = this.bodyNodes(state, util.dom.getChildren(body)); if (nodes.length > 0) { this.show(state, nodes); } @@ -2602,7 +2597,7 @@ NlmToLensConverter.State = function(converter, xmlDoc, doc) { // of processed nodes to be able to associate other things (e.g., annotations) correctly. this.stack = []; - this.sectionLevel = 1; + this.sectionLevel = 0; // Tracks all available affiliations this.affiliations = []; From fd1779325a0074f7a405e28e67511568680bc98b Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 14 Nov 2016 18:58:34 +0100 Subject: [PATCH 45/84] Adjust colors in cover node. --- article/nodes/cover/cover.css | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/article/nodes/cover/cover.css b/article/nodes/cover/cover.css index 6677c33e..b81d62f3 100644 --- a/article/nodes/cover/cover.css +++ b/article/nodes/cover/cover.css @@ -30,14 +30,11 @@ padding-top: 20px; } -.lens-article .content-node.cover .published-on { - color: #666; -} +.lens-article .content-node.cover .published-on {} .lens-article .content-node.cover .doi { margin-top: 30px; margin-bottom: 20px; - color: #666; font-size: 14px; } From 165d276b183a3ebd5c86bad866c0cbb7ee5398cb Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 22 Nov 2016 19:14:16 +0100 Subject: [PATCH 46/84] Improved date formatting. --- article/article_util.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/article/article_util.js b/article/article_util.js index 8b40e272..eb294208 100644 --- a/article/article_util.js +++ b/article/article_util.js @@ -21,7 +21,7 @@ util.formatDate = function (pubDate) { // new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]]) // Note: months are 0-based var localDate = new Date(parts[0], parts[1]-1, parts[2]); - return localDate.toUTCString().slice(0, 16); + return localDate.toDateString().slice(4, 16) } else if (parts.length === 2) { var month = parts[1].replace(/^0/, ""); var year = parts[0]; From 9f6b8cc34a6e7900ffec9180c24e0e670a4fdc82 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 22 Nov 2016 20:11:20 +0100 Subject: [PATCH 47/84] Drop breadcrumbs in favor of a better structured Cover view. --- article/nodes/cover/cover_view.js | 46 +++++++++++++++---------------- converter/elife_converter.js | 17 ------------ 2 files changed, 23 insertions(+), 40 deletions(-) diff --git a/article/nodes/cover/cover_view.js b/article/nodes/cover/cover_view.js index 02c26d92..2569a23a 100644 --- a/article/nodes/cover/cover_view.js +++ b/article/nodes/cover/cover_view.js @@ -30,32 +30,16 @@ CoverView.Prototype = function() { var node = this.node; var pubInfo = this.node.document.get('publication_info'); - if (node.breadcrumbs && node.breadcrumbs.length > 0) { - var breadcrumbs = $$('.breadcrumbs', { - children: _.map(node.breadcrumbs, function(bc) { - var html; - if (bc.image) { - html = ''; - } else { - html = bc.name; - } - return $$('a', {href: bc.url, html: html}); - }) - }); - this.content.appendChild(breadcrumbs); - } + // Render Subject(s) if available + // -------------- + // if (pubInfo) { - var pubDate = pubInfo.published_on; - if (pubDate) { - var items = [articleUtil.formatDate(pubDate)]; - if (pubInfo.journal && !node.breadcrumbs) { - items.push(' in '+pubInfo.journal+''); - } - - this.content.appendChild($$('.published-on', { - html: items.join('') + var subjects = pubInfo.subjects; + if (subjects) { + this.content.appendChild($$('.subjects', { + html: subjects.join(' ') })); } } @@ -88,6 +72,22 @@ CoverView.Prototype = function() { this.content.appendChild(authors); + if (pubInfo) { + var pubDate = pubInfo.published_on; + var articleType = pubInfo.article_type; + if (pubDate) { + var items = [articleUtil.formatDate(pubDate)]; + + if (articleType) { + items.unshift(articleType) + } + + this.content.appendChild($$('.published-on', { + html: items.join(' ') + })); + } + } + // Render Links // -------------- // diff --git a/converter/elife_converter.js b/converter/elife_converter.js index b05b4ad4..2f033eb8 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -79,23 +79,6 @@ ElifeConverter.Prototype = function() { } }; - this.enhanceCover = function(state, node, element) { - var category; - var dispChannel = element.querySelector("subj-group[subj-group-type=display-channel] subject").textContent; - try { - category = element.querySelector("subj-group[subj-group-type=heading] subject").textContent; - } catch(err) { - category = null; - } - - node.breadcrumbs = [ - // { name: "eLife", url: "https://elifesciences.org/", image: "https://lens.elifesciences.org/lens-elife/styles/elife.png" }, - { name: dispChannel, url: "https://elifesciences.org/category/"+dispChannel.replace(/ /g, '-').toLowerCase() }, - ]; - - if (category) node.breadcrumbs.push( { name: category, url: "https://elifesciences.org/category/"+category.replace(/ /g, '-').toLowerCase() } ); - }; - // Resolves figure url // -------- // From 0f9d595a424dab6d835155238800d07539199587 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 22 Nov 2016 20:11:34 +0100 Subject: [PATCH 48/84] Improve funding source extraction. --- converter/lens_converter.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 23bc0bc4..7cff2c23 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -321,6 +321,7 @@ NlmToLensConverter.Prototype = function() { fundingInfo.push(this.annotatedText(state, fundingStatementEls[i], ["publication_info", "funding_info", i])); } } + return fundingInfo; }; @@ -807,7 +808,20 @@ NlmToLensConverter.Prototype = function() { // // // and we only want to display the first text node, excluding the funder id - var fundingSourceName = fundingSource.childNodes[0].textContent; + // or this + // + // They can also look like this + // + // + // + // http://dx.doi.org/10.13039/100005156 + // Alexander von Humboldt-Stiftung + // + // + // Then we take the institution element + + var institution = fundingSource.querySelector('institution') + var fundingSourceName = institution ? institution.textContent : fundingSource.childNodes[0].textContent; contribNode.fundings.push([fundingSourceName, awardId].join('')); } else if (xref.getAttribute("ref-type") === "corresp") { var correspId = xref.getAttribute("rid"); @@ -1336,9 +1350,9 @@ NlmToLensConverter.Prototype = function() { }; doc.create(quoteNode); return quoteNode; - }; + }; - this.datasets = function(state, datasets) { + this.datasets = function(state, datasets) { var nodes = []; for (var i=0;i Date: Tue, 22 Nov 2016 20:11:50 +0100 Subject: [PATCH 49/84] Improvements for cover styles. --- article/nodes/cover/cover.css | 15 ++++++++++----- .../nodes/publication_info/publication_info.css | 1 - 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/article/nodes/cover/cover.css b/article/nodes/cover/cover.css index b81d62f3..fe39600f 100644 --- a/article/nodes/cover/cover.css +++ b/article/nodes/cover/cover.css @@ -1,5 +1,5 @@ .lens-article .content-node.cover { - + text-align: center; } .lens-article .content-node.cover .breadcrumbs { @@ -13,8 +13,7 @@ .lens-article .content-node.cover .breadcrumbs a { margin-right: 20px; - display: block; - float: left; + display: inline-block; line-height: 40px; height: 40px; } @@ -30,7 +29,12 @@ padding-top: 20px; } -.lens-article .content-node.cover .published-on {} +.lens-article .content-node.cover .subjects { +} + +.lens-article .content-node.cover .published-on { + color: #999; +} .lens-article .content-node.cover .doi { margin-top: 30px; @@ -56,7 +60,8 @@ /* One para per author */ .lens-article .content-node.cover .authors .text { - float: left; + /*float: left;*/ + display: inline-block; padding: 0px; margin: 0px; font-size: 17px; diff --git a/article/nodes/publication_info/publication_info.css b/article/nodes/publication_info/publication_info.css index ad2612a2..2e8efbd8 100644 --- a/article/nodes/publication_info/publication_info.css +++ b/article/nodes/publication_info/publication_info.css @@ -46,7 +46,6 @@ .article .resources .nodes > .content-node.publication-info .content-node[data-id=articleinfo] .heading.level-3 .content { font-size: 14px; font-weight: normal; - color: #999; } .article .resources .nodes > .content-node.publication-info .content-node[data-id=articleinfo] .content-node { From c30764cc6aa1451dbd1d0c6c0cc86f7669df7b9e Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sun, 4 Dec 2016 12:52:54 +0100 Subject: [PATCH 50/84] Article Info style improvements. --- article/nodes/contributor/contributor.css | 24 ++-- article/nodes/contributor/contributor_view.js | 112 ++++++++++++------ article/nodes/cover/cover.css | 22 +--- .../publication_info/publication_info.css | 20 +--- styles/reader.css | 1 - 5 files changed, 100 insertions(+), 79 deletions(-) diff --git a/article/nodes/contributor/contributor.css b/article/nodes/contributor/contributor.css index 5ff11687..d4e02ebb 100644 --- a/article/nodes/contributor/contributor.css +++ b/article/nodes/contributor/contributor.css @@ -1,5 +1,5 @@ /* -Contributor +Contributor --------------------------------------- */ .lens-article .resources .content-node.contributor .resource-header .name { @@ -9,16 +9,16 @@ Contributor } .lens-article .content-node.contributor .content { - + } .lens-article .content-node.contributor .affiliation { - margin-top: 10px; - font-size: 14px; + margin-top: 12px; + margin-bottom: 12px; } .lens-article .content-node.contributor .contributor-bio { - padding-top: 30px; + padding-top: 30px; } .lens-article .content-node.contributor .contributor-bio .bio { @@ -44,8 +44,16 @@ Contributor margin-bottom: 20px; } -.lens-article .content-node.contributor .label { - font-size: 14px; +.lens-article .content-node.contributor .contrib-label { + font-weight: 600; +} + +.lens-article .content-node.contributor .contrib-data { + margin-bottom: 12px; +} + + +/*.lens-article .content-node.contributor .label { margin-top: 20px; color: #999; -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/article/nodes/contributor/contributor_view.js b/article/nodes/contributor/contributor_view.js index 51ce0da7..873bbc82 100644 --- a/article/nodes/contributor/contributor_view.js +++ b/article/nodes/contributor/contributor_view.js @@ -35,9 +35,9 @@ ContributorView.Prototype = function() { // ------- if (this.node.role) { - this.content.appendChild($$('.role', {text: this.node.role})); + this.content.appendChild($$('.role', {text: this.node.role})); } - + // Add Affiliations // ------- @@ -57,29 +57,47 @@ ContributorView.Prototype = function() { })); - // Present Address // ------- if (this.node.present_address) { - this.content.appendChild($$('.label', {text: 'Present address'})); - this.content.appendChild($$('.contribution', {text: this.node.present_address})); + this.content.appendChild( + $$('.present-address.contrib-data', { + children: [ + $$('span.contrib-label', {text: 'Present address: '}), + $$('span', {text: this.node.present_address}) + ] + }) + ); } // Contribution // ------- if (this.node.contribution) { - this.content.appendChild($$('.label', {text: 'Contribution'})); - this.content.appendChild($$('.contribution', {text: this.node.contribution})); + this.content.appendChild( + $$('.contribution.contrib-data', { + children: [ + $$('span.contrib-label', {text: 'Contribution: '}), + $$('span', {text: this.node.contribution}) + ] + }) + ); } // Equal contribution // ------- + if (this.node.equal_contrib && this.node.equal_contrib.length > 0) { - this.content.appendChild($$('.label', {text: 'Contributed equally with'})); - this.content.appendChild($$('.equal-contribution', {text: this.node.equal_contrib})); + this.content.appendChild( + $$('.equal-contribution.contrib-data', { + children: [ + $$('span.contrib-label', {text: 'Contributed equally with: '}), + $$('span', {text: this.node.equal_contrib}) + ] + }) + ); } @@ -87,38 +105,51 @@ ContributorView.Prototype = function() { // ------- if (this.node.emails.length > 0) { - this.content.appendChild($$('.label', {text: 'For correspondence'})); - this.content.appendChild($$('.emails', { - children: _.map(this.node.emails, function(email) { - return $$('a', {href: "mailto:"+email, text: email}); + this.content.appendChild( + $$('.emails.contrib-data', { + children: [ + $$('span.contrib-label', {text: 'For correspondence: '}), + $$('span', { + children: _.map(this.node.emails, function(email) { + return $$('a', {href: "mailto:"+email, text: email+' '}); + }) + }) + ] }) - })); + ); } - // Funding // ------- if (this.node.fundings.length > 0) { - this.content.appendChild($$('.label', {text: 'Funding'})); - this.content.appendChild($$('.fundings', { - children: _.map(this.node.fundings, function(funding) { - return $$('.funding', {text: funding}); + this.content.appendChild( + $$('.fundings.contrib-data', { + children: [ + $$('span.contrib-label', {text: 'Funding: '}), + $$('span', { + text: this.node.fundings.join('; ') + }) + ] }) - })); + ); } - // Competing interests // ------- - if (this.node.competing_interests.length > 0) { - this.content.appendChild($$('.label', {text: 'Competing Interests'})); - this.content.appendChild($$('.competing-interests', { - children: _.map(this.node.competing_interests, function(ci) { - return $$('.conflict', {text: ci}); + + if (this.node.competing_interests.length) { + this.content.appendChild( + $$('.competing-interests.contrib-data', { + children: [ + $$('span.contrib-label', {text: 'Competing Interests: '}), + $$('span', { + text: this.node.competing_interests.join(', ') + }) + ] }) - })); + ); } @@ -126,24 +157,34 @@ ContributorView.Prototype = function() { // ------- if (this.node.orcid) { - this.content.appendChild($$('.label', { text: 'ORCID' })); - this.content.appendChild($$('a.orcid', { href: this.node.orcid, text: this.node.orcid })); + this.content.appendChild( + $$('.contrib-data', { + children: [ + $$('span.contrib-label', {text: 'ORCID: '}), + $$('a.orcid', { href: this.node.orcid, text: this.node.orcid }) + ] + }) + ); } + // Group member (in case contributor is a person group) // ------- if (this.node.members.length > 0) { - this.content.appendChild($$('.label', {text: 'Group Members'})); - this.content.appendChild($$('.members', { - children: _.map(this.node.members, function(member) { - return $$('.member', {text: member}); + this.content.appendChild( + $$('.group-members.contrib-data', { + children: [ + $$('span.contrib-label', {text: 'Group Members: '}), + $$('span', { + text: this.node.members.join(', ') + }) + ] }) - })); + ); } - // Contributor Bio // ------- @@ -164,7 +205,6 @@ ContributorView.Prototype = function() { // ------- if (this.node.deceased) { - // this.content.appendChild($$('.label', {text: 'Present address'})); this.content.appendChild($$('.label', {text: "* Deceased"})); } diff --git a/article/nodes/cover/cover.css b/article/nodes/cover/cover.css index fe39600f..9fdedebe 100644 --- a/article/nodes/cover/cover.css +++ b/article/nodes/cover/cover.css @@ -2,22 +2,6 @@ text-align: center; } -.lens-article .content-node.cover .breadcrumbs { - font-size: 14px; - margin-top: 30px; - margin-bottom: 20px; - - /* Prevent from nasty scrollbars that appear when eLife logo is shown */ - overflow: hidden; -} - -.lens-article .content-node.cover .breadcrumbs a { - margin-right: 20px; - display: inline-block; - line-height: 40px; - height: 40px; -} - .lens-article .content-node.cover .content { background: none; } @@ -30,6 +14,7 @@ } .lens-article .content-node.cover .subjects { + } .lens-article .content-node.cover .published-on { @@ -46,6 +31,7 @@ padding-top: 30px; color: #1B6685; overflow: auto; + margin-bottom: 24px; } .lens-article .content-node.cover .content .links { @@ -60,13 +46,12 @@ /* One para per author */ .lens-article .content-node.cover .authors .text { - /*float: left;*/ display: inline-block; padding: 0px; margin: 0px; font-size: 17px; margin-right: 10px; - margin-bottom: 8px; + margin-bottom: 0px; } .lens-article .content-node.cover .authors .text.plain { @@ -74,7 +59,6 @@ padding-left: 1px; } - .lens-article .intro { font-size: 13px; background: #FFFEF5; diff --git a/article/nodes/publication_info/publication_info.css b/article/nodes/publication_info/publication_info.css index 2e8efbd8..170761ba 100644 --- a/article/nodes/publication_info/publication_info.css +++ b/article/nodes/publication_info/publication_info.css @@ -1,8 +1,8 @@ /* Publication Info */ .lens-article .content-node.publication-info { - font-size: 14px; color: #333; + font-size: 16px; } .lens-article .content-node.publication-info table { @@ -26,26 +26,16 @@ margin-left: 140px; } -.lens-article .content-node.publication-info .dates { - /*font-size: 14px;*/ -} - .article .resources .nodes > .content-node.publication-info > .content { border: none; padding: 20px; } -.article .resources .nodes > .content-node.publication-info .content-node[data-id=articleinfo] { - font-size: 14px; -} - -.article .resources .nodes > .content-node.publication-info .content-node[data-id=articleinfo] .heading.level-3 { - padding-top: 10px; -} - .article .resources .nodes > .content-node.publication-info .content-node[data-id=articleinfo] .heading.level-3 .content { - font-size: 14px; - font-weight: normal; + font-size: 20px; + line-height: 24px; + margin-top: 12px; + margin-bottom: 12px; } .article .resources .nodes > .content-node.publication-info .content-node[data-id=articleinfo] .content-node { diff --git a/styles/reader.css b/styles/reader.css index fd5d6ab3..7a3a6af7 100644 --- a/styles/reader.css +++ b/styles/reader.css @@ -169,7 +169,6 @@ out (on iOS 5.1), or flicker (on iOS 6). */ right: 0px; overflow-y: scroll; overflow-x: hidden; - font-size: 14px; -webkit-overflow-scrolling: touch; } From 42ab986c871199ef3789a210a16a47d4b02dacaf Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sun, 4 Dec 2016 15:54:18 +0100 Subject: [PATCH 51/84] Include default style. --- .../publication_info/publication_info.css | 1 - styles/default.scss | 300 ++++++++++++++++++ 2 files changed, 300 insertions(+), 1 deletion(-) create mode 100644 styles/default.scss diff --git a/article/nodes/publication_info/publication_info.css b/article/nodes/publication_info/publication_info.css index 170761ba..a6790344 100644 --- a/article/nodes/publication_info/publication_info.css +++ b/article/nodes/publication_info/publication_info.css @@ -33,7 +33,6 @@ .article .resources .nodes > .content-node.publication-info .content-node[data-id=articleinfo] .heading.level-3 .content { font-size: 20px; - line-height: 24px; margin-top: 12px; margin-bottom: 12px; } diff --git a/styles/default.scss b/styles/default.scss new file mode 100644 index 00000000..ebed210a --- /dev/null +++ b/styles/default.scss @@ -0,0 +1,300 @@ +/* Default style +=============================== */ + +$interface-font: "Avenir Next", "Helvetica", arial, sans-serif; +$prose-font: "PT Serif", "Georgia", serif; +$default-text-color: #212121; + +/* Used as a mixin */ +.contextual-label { + font-family: $interface-font; + font-weight: 600; + font-size: 11px; + text-transform: uppercase; + letter-spacing: .5px; +} + +html { + -webkit-font-smoothing: inherit; +} +body { + font-family: $interface-font; + font-weight: 500; + color: $default-text-color; +} + +/* Links */ +a { + color: #0277BD; + text-decoration: none; +} + +a:hover { + color: #0277BD; +} + +/* Line height overrides */ +.article .resources { + line-height: 24px; +} + +/* Bread crumbs */ +.lens-article .content-node.cover .breadcrumbs a { + @extend .contextual-label; +} + +/* Article title */ +.lens-article .content-node.cover .title { + font-size: 36px; + line-height: 48px; + font-weight: 600; +} + +/* Published date */ +.lens-article .content-node.cover .published-on { + @extend .contextual-label; +} + +.lens-article .content-node.cover .subjects { + @extend .contextual-label; +} + +/* Authors on cover page */ +.lens-article .content-node.cover .doi { + @extend .contextual-label; + border-top: 1px solid #e0e0e0; + border-bottom: 1px solid #e0e0e0; + margin: 24px 0; + padding: 11px 0; + + a { + text-transform: none; + color: #212121; + font-weight: 600; + } +} + +.lens-article .content-node.cover .authors .text a { + font-weight: 600; + font-size: 16px; + line-height: 24px; + margin: 0 0 12px; + color: $default-text-color; +} + +.lens-article .content-node.cover .authors .text a:hover { + background: none; + border-bottom: 1px solid #212121; +} + +.lens-article .content-node.cover .authors .contributor_reference.highlighted { + border-bottom: 1px solid #212121; + background: none; +} + +/* Links on cover page (PDF, Source XML, Lens JSON) */ +.lens-article .content-node.cover .content .links { + display: none; // hide links to PDF, Source XML, Lens JSON +} +.lens-article .content-node.cover .content .links a { + font-weight: 600; + @extend .contextual-label; +} + +/* Paragraph (only in main content) */ +.surface.content .content-node.paragraph { + font-family: $prose-font; + line-height: 1.5; + font-size: 16px; +} + +/* Headings */ +.content-node.heading.level-1 .content { + font-size: 26px; + line-height: 24px; + padding-top: 24px; + font-weight: 600; +} + +.content-node.heading.level-2 .content { + font-size: 22px; + line-height: 24px; + padding-top: 12px; + font-weight: 600; +} +.surface.content .nodes > .content-node.heading.level-2 { + padding-bottom: 0px; +} + +.content-node.heading.level-3 .content { + font-size: 20px; + line-height: 24px; + padding-top: 12px; + font-weight: 600; +} +.surface.content .nodes > .content-node.heading.level-3 { + padding-bottom: 0px; +} + +.content-node.heading.level-4 .content { + font-size: 18px; + line-height: 24px; + padding-top: 12px; + font-weight: 600; +} +.surface.content .nodes > .content-node.heading.level-4 { + padding-bottom: 0px; +} + +.content-node.heading.level-5 .content { + font-size: 16px; + line-height: 24px; + padding-top: 12px; + font-weight: 600; +} +.surface.content .nodes > .content-node.heading.level-5 { + padding-bottom: 0px; +} + +/* Headings in TOC */ +.resource-view.toc .heading-ref { + color: inherit; // reset color + padding: 0; + margin-bottom: 12px; + border: none; +} + +.resource-view.toc .heading-ref.active { + color: inherit; + border: none; + span { + text-decoration: underline; + } +} + +.resource-view.toc .heading-ref { + font-size: 16px; +} + +.resource-view.toc .heading-ref.level-2 { + font-weight: 500; + font-size: 16px; + padding-left: 24px; +} + +.resource-view.toc .heading-ref.level-3 { + font-weight: 500; + font-size: 16px; + padding-left: 48px; +} + +.resource-view.toc .heading-ref.level-4 { + padding-left: 48px; +} + +/* Reference card */ +.lens-article .resources .content-node.citation .resource-header .name { + font-weight: 600; +} + +.lens-article .resources .content-node.contributor .resource-header .name { + font-weight: 600; + font-size: 14px; +} + +/* Scrollbar default highlight color */ +.node.highlighted { + background: #666; +} + +/* Highlighted resource default style (e.g. contributor) */ +.article .resources .info .content-node.highlighted { + border-left: 3px solid #212121; +} + +/* Citation resource */ +.lens-article .resources .content-node.citation .resource-header .name { + @extend .contextual-label; +} + +.lens-article .resources .content-node.citation { + font-family: $prose-font; +} + +.lens-article .content-node.citation .content .authors { + font-family: $interface-font; + font-weight: 600; + font-size: 14px; +} + +.lens-article .content-node.citation .content .source, +.lens-article .content-node.citation .content .doi { + font-size: 11px; +} + +/* Change font-size for all resource nodes */ +.lens-article .resources .figures .nodes > .content-node { + font-size: 13px; +} + +/* Caption title (e.g. figure, table) */ +.lens-article .content-node.caption > .content > .content-node.caption-title { + font-size: 13px; + padding-bottom: 0px; +} + +/* Label for resources */ +.article .resources .resource-header .name { + font-size: 13px; +} + +/* HACK: Make sure always the interface font is in toggle buttons (focus, fullscreen) */ +.article .resources .content-node .resource-header .toggles { + font-family: $interface-font; +} + +/* Resource view */ + +.panel.info { + font-family: $prose-font; +} + +.lens-article .content-node.publication-info .label { + font-family: $interface-font; +} + +.article .resources .nodes > .content-node.publication-info .content-node[data-id=articleinfo] .heading .content { + font-weight: 600; +} + +.lens-article .content-node.contributor .label { + font-family: $interface-font; + color: $default-text-color; + font-weight: 600; +} + + +.article .resources .nodes > .content-node.publication-info .content-node[data-id=articleinfo] .heading.level-3 .content { + font-family: $interface-font; + font-weight: 600; +} + +.lens-article .resources .content-node.contributor .resource-header .name { + @extend .contextual-label; + font-size: 11px; +} + +.lens-article .content-node.publication-info .label { + color: $default-text-color; + font-weight: 600; + font-size: 14px; +} + +.lens-article .content-node.contributor .contributor-name { + font-family: $interface-font; + font-weight: 600; + font-size: 20px; + line-height: 24px; + margin-top: 12px; + margin-bottom: 12px; +} \ No newline at end of file From 25003ba27ad00965ee2bb28a188f668a2121df3b Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sun, 4 Dec 2016 15:54:46 +0100 Subject: [PATCH 52/84] Remove obsolete label style. --- article/nodes/contributor/contributor.css | 6 ------ 1 file changed, 6 deletions(-) diff --git a/article/nodes/contributor/contributor.css b/article/nodes/contributor/contributor.css index d4e02ebb..d6c66b49 100644 --- a/article/nodes/contributor/contributor.css +++ b/article/nodes/contributor/contributor.css @@ -51,9 +51,3 @@ Contributor .lens-article .content-node.contributor .contrib-data { margin-bottom: 12px; } - - -/*.lens-article .content-node.contributor .label { - margin-top: 20px; - color: #999; -}*/ \ No newline at end of file From 08a45ae351c95efcdf7c1971ad37e7ca9df711d2 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 5 Dec 2016 11:33:56 +0100 Subject: [PATCH 53/84] Fix margin for headings in publication info pane. --- article/nodes/publication_info/publication_info.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/article/nodes/publication_info/publication_info.css b/article/nodes/publication_info/publication_info.css index a6790344..9d9ef391 100644 --- a/article/nodes/publication_info/publication_info.css +++ b/article/nodes/publication_info/publication_info.css @@ -34,7 +34,8 @@ .article .resources .nodes > .content-node.publication-info .content-node[data-id=articleinfo] .heading.level-3 .content { font-size: 20px; margin-top: 12px; - margin-bottom: 12px; + /* The 'content-node paragraph' below has a padding top making the space between the heading and text 22px rather than 12. */ + /* margin-bottom: 12px; */ } .article .resources .nodes > .content-node.publication-info .content-node[data-id=articleinfo] .content-node { From 25483dedd2289b8de027b74914ce25121d810c7d Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 12 Dec 2016 19:48:02 +0100 Subject: [PATCH 54/84] Link subjects and article type. --- article/nodes/cover/cover.css | 7 +++++- article/nodes/cover/cover_view.js | 25 ++++++++++++++++--- .../publication_info/publication_info.js | 21 +++++++++++++++- converter/elife_converter.js | 3 +++ styles/default.scss | 12 ++++++--- 5 files changed, 59 insertions(+), 9 deletions(-) diff --git a/article/nodes/cover/cover.css b/article/nodes/cover/cover.css index 9fdedebe..3c6d8170 100644 --- a/article/nodes/cover/cover.css +++ b/article/nodes/cover/cover.css @@ -21,6 +21,11 @@ color: #999; } +.lens-article .content-node.cover .published-on a { + font-weight: 600; + color: #999; +} + .lens-article .content-node.cover .doi { margin-top: 30px; margin-bottom: 20px; @@ -80,4 +85,4 @@ .lens-article .intro .send-feedback:hover { color: #ff0000; -} \ No newline at end of file +} diff --git a/article/nodes/cover/cover_view.js b/article/nodes/cover/cover_view.js index 2569a23a..49ac45c3 100644 --- a/article/nodes/cover/cover_view.js +++ b/article/nodes/cover/cover_view.js @@ -38,9 +38,20 @@ CoverView.Prototype = function() { if (pubInfo) { var subjects = pubInfo.subjects; if (subjects) { - this.content.appendChild($$('.subjects', { - html: subjects.join(' ') - })); + var subjectsEl + if (pubInfo.subject_link) { + subjectsEl = $$('.subjects', { + children: _.map(pubInfo.getSubjectLinks(), function(subject) { + return $$('a', {href: subject.url, text: subject.name}) + }) + }) + + } else { + subjectsEl = $$('.subjects', { + html: subjects.join(' ') + }) + } + this.content.appendChild(subjectsEl); } } @@ -79,7 +90,13 @@ CoverView.Prototype = function() { var items = [articleUtil.formatDate(pubDate)]; if (articleType) { - items.unshift(articleType) + if (pubInfo.article_type_link) { + var linkData = pubInfo.getArticleTypeLink() + items.unshift(''+linkData.name+'') + } else { + items.unshift(articleType) + } + } this.content.appendChild($$('.published-on', { diff --git a/article/nodes/publication_info/publication_info.js b/article/nodes/publication_info/publication_info.js index b152804d..ab190a84 100644 --- a/article/nodes/publication_info/publication_info.js +++ b/article/nodes/publication_info/publication_info.js @@ -22,7 +22,10 @@ PublicationInfo.type = { "links": ["array", "objects"], "doi": "string", "related_article": "string", - "article_info": "paragraph" + "article_info": "paragraph", + // optional + "subject_link": "string", + "article_type_link": "string" } }; @@ -86,6 +89,22 @@ PublicationInfo.Prototype = function() { return this.document.get("articleinfo"); }; + this.getSubjectLinks = function() { + return this.subjects.map(function(subject) { + return { + name: subject, + url: this.subject_link + '/' + subject.replace(/ /g, '-').toLowerCase() + } + }.bind(this)) + } + + this.getArticleTypeLink = function() { + return { + name: this.article_type, + url: this.article_type_link + '/' + this.article_type.replace(/ /g, '-').toLowerCase() + } + } + }; PublicationInfo.Prototype.prototype = Document.Node.prototype; diff --git a/converter/elife_converter.js b/converter/elife_converter.js index 2f033eb8..203e7d37 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -240,6 +240,9 @@ ElifeConverter.Prototype = function() { publicationInfo.article_type = articleType ? articleType.textContent : ""; publicationInfo.links = links; + publicationInfo.subject_link = 'http://elifesciences.org/category' + publicationInfo.article_type_link = 'http://elifesciences.org/category' + if (publicationInfo.related_article) publicationInfo.related_article = "http://dx.doi.org/" + publicationInfo.related_article; }; diff --git a/styles/default.scss b/styles/default.scss index ebed210a..e47c1422 100644 --- a/styles/default.scss +++ b/styles/default.scss @@ -59,6 +59,10 @@ a:hover { @extend .contextual-label; } +.lens-article .content-node.cover .subjects a { + font-weight: 600; +} + /* Authors on cover page */ .lens-article .content-node.cover .doi { @extend .contextual-label; @@ -84,12 +88,14 @@ a:hover { .lens-article .content-node.cover .authors .text a:hover { background: none; - border-bottom: 1px solid #212121; + // border-bottom: 1px solid #212121; + color: #0277BD; } .lens-article .content-node.cover .authors .contributor_reference.highlighted { - border-bottom: 1px solid #212121; + // border-bottom: 1px solid #212121; background: none; + color: #0277BD; } /* Links on cover page (PDF, Source XML, Lens JSON) */ @@ -297,4 +303,4 @@ a:hover { line-height: 24px; margin-top: 12px; margin-bottom: 12px; -} \ No newline at end of file +} From 546d7f25eba9ad07de24fcf2850771a2573cdb89 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 12 Dec 2016 20:20:58 +0100 Subject: [PATCH 55/84] Underline active contributor. --- styles/default.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles/default.scss b/styles/default.scss index e47c1422..90472dc1 100644 --- a/styles/default.scss +++ b/styles/default.scss @@ -93,7 +93,7 @@ a:hover { } .lens-article .content-node.cover .authors .contributor_reference.highlighted { - // border-bottom: 1px solid #212121; + border-bottom: 1px solid #0277BD; background: none; color: #0277BD; } From ec162036d63764145897f7fab7ff3157b4f7eefe Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 14 Dec 2016 16:19:12 +0100 Subject: [PATCH 56/84] Hover style for article type. --- article/nodes/cover/cover.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/article/nodes/cover/cover.css b/article/nodes/cover/cover.css index 3c6d8170..ab03b997 100644 --- a/article/nodes/cover/cover.css +++ b/article/nodes/cover/cover.css @@ -26,6 +26,10 @@ color: #999; } +.lens-article .content-node.cover .published-on a:hover { + color: #0277BD; +} + .lens-article .content-node.cover .doi { margin-top: 30px; margin-bottom: 20px; From 9095b02cd0c9c23c665f1ff2c0216bceb6f158f3 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 14 Dec 2016 16:19:22 +0100 Subject: [PATCH 57/84] Strip leading zeros from date strings. --- article/article_util.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/article/article_util.js b/article/article_util.js index eb294208..041076f3 100644 --- a/article/article_util.js +++ b/article/article_util.js @@ -19,9 +19,9 @@ util.formatDate = function (pubDate) { var parts = pubDate.split("-"); if (parts.length >= 3) { // new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]]) - // Note: months are 0-based + // Note: months are 0-based, which are stripped using a regexp var localDate = new Date(parts[0], parts[1]-1, parts[2]); - return localDate.toDateString().slice(4, 16) + return localDate.toDateString().slice(4, 16).replace(/\b0+/g, '') } else if (parts.length === 2) { var month = parts[1].replace(/^0/, ""); var year = parts[0]; From d431ddf64ed442daaf73f591af68771339bdd08b Mon Sep 17 00:00:00 2001 From: Giorgio Sironi Date: Fri, 31 Mar 2017 16:48:38 +0100 Subject: [PATCH 58/84] Supported hostname for eLife's API --- converter/elife_converter.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/converter/elife_converter.js b/converter/elife_converter.js index 203e7d37..4d4b2aea 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -263,10 +263,10 @@ ElifeConverter.Prototype = function() { this.enhanceVideo = function(state, node, element) { var href = element.getAttribute("xlink:href").split("."); var name = href[0]; - node.url = "https://api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file/"+name+".mp4"; - node.url_ogv = "https://api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file//"+name+".ogv"; - node.url_webm = "https://api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file//"+name+".webm"; - node.poster = "https://api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file/"+name+".jpg"; + node.url = "https://master.api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file/"+name+".mp4"; + node.url_ogv = "https://master.api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file//"+name+".ogv"; + node.url_webm = "https://master.api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file//"+name+".webm"; + node.poster = "https://master.api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file/"+name+".jpg"; }; // Example url to JPG: https://cdn.elifesciences.org/elife-articles/00768/svg/elife00768f001.jpg From 057c7f553c6f419abe3475e9c16e917efe834685 Mon Sep 17 00:00:00 2001 From: Luke Skibinski Date: Fri, 7 Apr 2017 14:55:41 +0930 Subject: [PATCH 59/84] replaced instances of "publishing-cdn.elifesciences.org/" with "cdn.elifesciences.org/articles/" --- converter/elife_converter.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/converter/elife_converter.js b/converter/elife_converter.js index 203e7d37..2752fcc3 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -111,7 +111,7 @@ ElifeConverter.Prototype = function() { } return [ - "https://publishing-cdn.elifesciences.org/", + "https://cdn.elifesciences.org/articles/", state.doc.id, "/", url @@ -125,7 +125,7 @@ ElifeConverter.Prototype = function() { return [baseURL, node.url].join(''); } else { node.url = [ - "https://publishing-cdn.elifesciences.org/", + "https://cdn.elifesciences.org/articles/", state.doc.id, "/", node.url @@ -193,7 +193,7 @@ ElifeConverter.Prototype = function() { if (pdfURI) { var pdfLink = [ - "https://publishing-cdn.elifesciences.org/", + "https://cdn.elifesciences.org/articles/", state.doc.id, "/", pdfURI ? pdfURI.getAttribute("xlink:href") : "#" @@ -221,7 +221,7 @@ ElifeConverter.Prototype = function() { } links.push({ - url: "https://s3.amazonaws.com/elife-publishing-cdn/"+state.doc.id+"/elife-"+state.doc.id+"-v"+version+".xml", + url: "https://s3.amazonaws.com/prod-elife-published/articles/"+state.doc.id+"/elife-"+state.doc.id+"-v"+version+".xml", name: "Source XML", type: "xml" }); @@ -252,7 +252,7 @@ ElifeConverter.Prototype = function() { return [baseURL, node.url].join(''); } else { node.url = [ - "https://publishing-cdn.elifesciences.org/", + "https://cdn.elifesciences.org/articles/", state.doc.id, "/", node.url @@ -290,7 +290,7 @@ ElifeConverter.Prototype = function() { } return [ - "https://publishing-cdn.elifesciences.org/", + "https://cdn.elifesciences.org/articles/", state.doc.id, "/", url From f1173e5592d624dc535aebef38320cdd3121f547 Mon Sep 17 00:00:00 2001 From: Luke Skibinski Date: Mon, 10 Apr 2017 09:05:42 +0930 Subject: [PATCH 60/84] changed a reference from s3 to the cdn --- converter/elife_converter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/converter/elife_converter.js b/converter/elife_converter.js index 2752fcc3..cc84a5e3 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -221,7 +221,7 @@ ElifeConverter.Prototype = function() { } links.push({ - url: "https://s3.amazonaws.com/prod-elife-published/articles/"+state.doc.id+"/elife-"+state.doc.id+"-v"+version+".xml", + url: "https://cdn.elifesciences.org/articles/"+state.doc.id+"/elife-"+state.doc.id+"-v"+version+".xml", name: "Source XML", type: "xml" }); From 55db3904a0c1860104c80647d26e16cd21a61086 Mon Sep 17 00:00:00 2001 From: Luke Skibinski Date: Mon, 10 Apr 2017 09:09:44 +0930 Subject: [PATCH 61/84] upgraded some plain http://elifesciences.org links to https://elifesciences.org --- converter/elife_converter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/converter/elife_converter.js b/converter/elife_converter.js index cc84a5e3..9a8a0bc9 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -240,8 +240,8 @@ ElifeConverter.Prototype = function() { publicationInfo.article_type = articleType ? articleType.textContent : ""; publicationInfo.links = links; - publicationInfo.subject_link = 'http://elifesciences.org/category' - publicationInfo.article_type_link = 'http://elifesciences.org/category' + publicationInfo.subject_link = 'https://elifesciences.org/category' + publicationInfo.article_type_link = 'https://elifesciences.org/category' if (publicationInfo.related_article) publicationInfo.related_article = "http://dx.doi.org/" + publicationInfo.related_article; }; From 40a27714c02987052681c0444dd0b748fdf8e33b Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Thu, 13 Apr 2017 18:37:38 -0700 Subject: [PATCH 62/84] Do not add list-item to a list unless it is a direct child element, fixes #196. --- converter/lens_converter.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 7cff2c23..d2ef221b 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -1681,6 +1681,8 @@ NlmToLensConverter.Prototype = function() { var listItems = list.querySelectorAll("list-item"); for (var i = 0; i < listItems.length; i++) { var listItem = listItems[i]; + // Only consider direct children + if (listItem.parentNode !== list) continue; // Note: we do not care much about what is served as items // However, we do not have complex nodes on paragraph level // They will be extract as sibling items From e226faa1bec12569ccccdc1aeeaf7caf34d03ea1 Mon Sep 17 00:00:00 2001 From: Luke Skibinski Date: Tue, 18 Apr 2017 12:59:57 +0930 Subject: [PATCH 63/84] changed video urls to 'legacy--api' from 'master.api' --- converter/elife_converter.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/converter/elife_converter.js b/converter/elife_converter.js index 4d4b2aea..e042807e 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -263,10 +263,10 @@ ElifeConverter.Prototype = function() { this.enhanceVideo = function(state, node, element) { var href = element.getAttribute("xlink:href").split("."); var name = href[0]; - node.url = "https://master.api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file/"+name+".mp4"; - node.url_ogv = "https://master.api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file//"+name+".ogv"; - node.url_webm = "https://master.api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file//"+name+".webm"; - node.poster = "https://master.api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file/"+name+".jpg"; + node.url = "https://legacy--api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file/"+name+".mp4"; + node.url_ogv = "https://legacy--api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file//"+name+".ogv"; + node.url_webm = "https://legacy--api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file//"+name+".webm"; + node.poster = "https://legacy--api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file/"+name+".jpg"; }; // Example url to JPG: https://cdn.elifesciences.org/elife-articles/00768/svg/elife00768f001.jpg From 33d555be0ad0a9432276d8b68ad2b26b085c74b7 Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Tue, 20 Jun 2017 17:08:41 -0700 Subject: [PATCH 64/84] Add a comma between multiple subject values using CSS. --- styles/lens.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/styles/lens.css b/styles/lens.css index 96ae43bd..596eccaf 100644 --- a/styles/lens.css +++ b/styles/lens.css @@ -153,6 +153,10 @@ p:last-child { padding-bottom: 0; } color: gold; } +.lens-article .content-node.cover .subjects a:not(:last-child):after { + content: ', ' +} + /* main --------------------------------------- */ From bedfc772fbdf2339fba6139617c38866c0e37fc1 Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Fri, 30 Jun 2017 16:28:45 -0700 Subject: [PATCH 65/84] Fix for equal contributions on eLife articles, and join them with a comma-space. --- article/nodes/contributor/contributor_view.js | 2 +- converter/lens_converter.js | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/article/nodes/contributor/contributor_view.js b/article/nodes/contributor/contributor_view.js index 873bbc82..ed25daaf 100644 --- a/article/nodes/contributor/contributor_view.js +++ b/article/nodes/contributor/contributor_view.js @@ -94,7 +94,7 @@ ContributorView.Prototype = function() { $$('.equal-contribution.contrib-data', { children: [ $$('span.contrib-label', {text: 'Contributed equally with: '}), - $$('span', {text: this.node.equal_contrib}) + $$('span', {text: this.node.equal_contrib.join(', ')}) ] }) ); diff --git a/converter/lens_converter.js b/converter/lens_converter.js index d2ef221b..00616460 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -841,7 +841,11 @@ NlmToLensConverter.Prototype = function() { var fnType = fnElem.getAttribute("fn-type"); switch (fnType) { case "con": - contribNode.contribution = fnElem.textContent; + if (fnElem.getAttribute("id").indexOf("equal-contrib")>=0) { + equalContribs = this._getEqualContribs(state, contrib, fnElem.getAttribute("id")); + } else { + contribNode.contribution = fnElem.textContent; + } break; case "conflict": compInterests.push(fnElem.textContent.trim()); From bc389ef48f9658607648f4e42dfb603983c1d9eb Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Thu, 6 Jul 2017 16:07:22 -0700 Subject: [PATCH 66/84] For eLife articles, show boxed-text in the content panel. Fixes showing boxed-text and also showing some appendices that are wrapped in boxed-text. --- converter/elife_converter.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/converter/elife_converter.js b/converter/elife_converter.js index 3bbc4ad8..dcb2c183 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -325,11 +325,15 @@ ElifeConverter.Prototype = function() { switch(node.type) { // Boxes go into the figures view if these conditions are met // 1. box has a label (e.g. elife 00288) + // Disable it July 2017: no box has a label, and also cross reference links do not work if + // they do try to link to the figures panel + /* case "box": if (node.label) { state.doc.show("figures", node.id); } break; + */ default: __super__.showNode.apply(this, arguments); } From 21ef5f207e7728c5f6930accc219a62cc53d3da0 Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Fri, 7 Jul 2017 10:07:52 -0700 Subject: [PATCH 67/84] Set the level 1 heading for appendices to Appendices, so it does not duplicate the first heading twice. --- converter/lens_converter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 00616460..2cdccb9d 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -2224,7 +2224,7 @@ NlmToLensConverter.Prototype = function() { "type" : "heading", "id" : headingId, "level" : 1, - "content" : title ? this.annotatedText(state, title, [headingId, "content"]) : "Appendix" + "content" : "Appendices" }); this.show(state, [heading]); From 21562394e6d4459cdbfd55c2f53814ba0e53d971 Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Fri, 7 Jul 2017 10:24:36 -0700 Subject: [PATCH 68/84] Get the label for a box if available. --- converter/lens_converter.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 2cdccb9d..8d8374a0 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -1329,11 +1329,13 @@ NlmToLensConverter.Prototype = function() { // Assuming that there are no nested elements var childNodes = this.bodyNodes(state, util.dom.getChildren(box)); var boxId = state.nextId("box"); + // Optional heading label + var label = this.selectDirectChildren(box, "label")[0]; var boxNode = { "type": "box", "id": boxId, "source_id": box.getAttribute("id"), - "label": "", + "label": label ? label.textContent : "", "children": _.pluck(childNodes, 'id') }; doc.create(boxNode); From 6213cb822130694c495c34c30b657e25b8390b28 Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Fri, 7 Jul 2017 10:32:34 -0700 Subject: [PATCH 69/84] Update comments. --- converter/elife_converter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/converter/elife_converter.js b/converter/elife_converter.js index dcb2c183..e3c37e9a 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -325,8 +325,8 @@ ElifeConverter.Prototype = function() { switch(node.type) { // Boxes go into the figures view if these conditions are met // 1. box has a label (e.g. elife 00288) - // Disable it July 2017: no box has a label, and also cross reference links do not work if - // they do try to link to the figures panel + // Disable it July 2017: cross reference links do not work if box reference + // in the content panel tries to link to the figures panel /* case "box": if (node.label) { From 50c47c7c9a4031f71f7b855618a65d36b329c3ab Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Fri, 7 Jul 2017 11:21:33 -0700 Subject: [PATCH 70/84] Support parsing multiple table per table-wrap. Fixes #111. --- converter/lens_converter.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index 8d8374a0..e9e87921 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -1915,9 +1915,11 @@ NlmToLensConverter.Prototype = function() { }; // Note: using a DOM div element to create HTML - var table = tableWrap.querySelector("table"); + var table = tableWrap.querySelectorAll("table"); if (table) { - tableNode.content = this.toHtml(table); + for (var i = 0; i < table.length; i++) { + tableNode.content += this.toHtml(table[i]); + } } this.extractTableCaption(state, tableNode, tableWrap); From 1bc10a036c4af83fbd4e32d6884a699c78093037 Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Fri, 7 Jul 2017 17:43:33 -0700 Subject: [PATCH 71/84] Quick enhanceTables function for eLife to replace bold, italic, and table styles. Also add additional CSS author callout styles. --- converter/elife_converter.js | 14 ++++++++++++ styles/lens.css | 44 ++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/converter/elife_converter.js b/converter/elife_converter.js index e3c37e9a..bc5fb9f9 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -260,6 +260,20 @@ ElifeConverter.Prototype = function() { } }; + this.enhanceTable = function(state, tableNode, tableWrap) { + tableNode.content = this.enhanceHTML(tableNode.content); + } + + this.enhanceHTML = function(html) { + html = html.replace(/<(\/)?bold>/g, "<$1strong>"); + html = html.replace(/<(\/)?italic>/g, "<$1em>"); + // Table colours + html = html.replace(/]*)>/g, ""); + // named-content span + html = html.replace(/]*)>([^<]*)<\/named-content>/g, "$3"); + return html; + }; + this.enhanceVideo = function(state, node, element) { var href = element.getAttribute("xlink:href").split("."); var name = href[0]; diff --git a/styles/lens.css b/styles/lens.css index 596eccaf..a49f28d6 100644 --- a/styles/lens.css +++ b/styles/lens.css @@ -153,6 +153,50 @@ p:last-child { padding-bottom: 0; } color: gold; } +.author-callout-style-a1 { + color: rgb(54, 107, 251); // Blue +} + +.author-callout-style-a2 { + color: rgb(156, 39, 176); // Purple +} + +.author-callout-style-a3 { + color: rgb(213, 0, 0); // Red +} + +.author-callout-style-b1 { + background-color: rgb(144, 202, 249); // Blue +} + +.author-callout-style-b2 { + background-color: rgb(197, 225, 165); // Green +} + +.author-callout-style-b3 { + background-color: rgb(255, 183, 77); // Orange +} + +.author-callout-style-b4 { + background-color: rgb(255, 241, 118); // Yellow +} + +.author-callout-style-b5 { + background-color: rgb(158, 134, 201); // Purple +} + +.author-callout-style-b6 { + background-color: rgb(229, 115, 115); // Red +} + +.author-callout-style-b7 { + background-color: rgb(244, 143, 177); // Pink +} + +.author-callout-style-b8 { + background-color: rgb(230, 230, 230); // Grey +} + .lens-article .content-node.cover .subjects a:not(:last-child):after { content: ', ' } From 782c51cee068e83acfeff8b773689222a340b30c Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Fri, 14 Jul 2017 16:35:55 -0700 Subject: [PATCH 72/84] An HTML tag replacement method to link citation references in tables, for eLife only as part of enhanceHTML(). --- converter/elife_converter.js | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/converter/elife_converter.js b/converter/elife_converter.js index bc5fb9f9..bf23a10b 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -261,9 +261,31 @@ ElifeConverter.Prototype = function() { }; this.enhanceTable = function(state, tableNode, tableWrap) { + this.mapCitations(state); tableNode.content = this.enhanceHTML(tableNode.content); } + this.mapCitations = function (state) + { + // Map citation id to their citation reference for use in HTML replacements + this.citationCitationReferenceMap = []; + var citationSourceIdMap = []; + var doc = state.doc; + _.each(doc.nodes, function(node) { + if(node.type == "citation") + { + citationSourceIdMap[node.source_id] = node.id; + } + }.bind(this)); + var annotations = state.annotations; + _.each(annotations, function(anno) { + if(anno.type == "citation_reference") + { + this.citationCitationReferenceMap[anno.target] = anno.id; + } + }.bind(this)); + } + this.enhanceHTML = function(html) { html = html.replace(/<(\/)?bold>/g, "<$1strong>"); html = html.replace(/<(\/)?italic>/g, "<$1em>"); @@ -271,6 +293,19 @@ ElifeConverter.Prototype = function() { html = html.replace(/]*)>/g, ""); // named-content span html = html.replace(/]*)>([^<]*)<\/named-content>/g, "$3"); + // Hacky way to convert references inside tables + if(this.citationCitationReferenceMap) + { + var xref_pattern = /([^<]*)<\/xref>/g; + var matches = html.match(xref_pattern); + _.each(matches, function(match) { + var rid = match.replace(xref_pattern, "$1"); + var content = match.replace(xref_pattern, "$2"); + var citation_reference = this.citationCitationReferenceMap[rid]; + var replace_tag = ''+content+''; + html = html.replace(match, replace_tag); + }.bind(this)); + } return html; }; From dfa9aa295be293dac65b873d4bbeb00e6945a1d9 Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Fri, 14 Jul 2017 16:43:01 -0700 Subject: [PATCH 73/84] CSS style fix for table margin-bottom to take effect, now there can be multiple tables per table wrapper. --- article/nodes/html_table/html_table.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/article/nodes/html_table/html_table.css b/article/nodes/html_table/html_table.css index 4240c5f7..ec8b8ad2 100644 --- a/article/nodes/html_table/html_table.css +++ b/article/nodes/html_table/html_table.css @@ -19,8 +19,8 @@ position: relative; border-collapse: collapse; border-spacing: 0; - margin-bottom: 20px; margin: 0 auto; + margin-bottom: 20px; } .lens-article .content-node.html-table thead tr { From 968a4267f6e572d36d2f42ae2307758fc5ecaa99 Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Mon, 8 Jan 2018 18:15:00 -0800 Subject: [PATCH 74/84] Do not render fig as a body node, otherwise it gets added first to the figures node list, and results in the Figures tab elements to be out of order, not showing Figure 1 first, e.g. --- converter/lens_converter.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/converter/lens_converter.js b/converter/lens_converter.js index e9e87921..0e1138c1 100644 --- a/converter/lens_converter.js +++ b/converter/lens_converter.js @@ -1311,9 +1311,10 @@ NlmToLensConverter.Prototype = function() { this._bodyNodes["comment"] = function(state, child) { return this.comment(state, child); }; - this._bodyNodes["fig"] = function(state, child) { - return this.figure(state, child); - }; + // Disable fig as a body node, otherwise the order of nodes in the Figures tab can be incorrect + //this._bodyNodes["fig"] = function(state, child) { + // return this.figure(state, child); + //}; // Overwirte in specific converter this.ignoredNode = function(/*state, node, type*/) { From 93e83a94872a00a4e3581ef829666d41eaebea4a Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Fri, 6 Dec 2019 10:56:46 -0800 Subject: [PATCH 75/84] elife_converter, set assets urls from video_data. --- converter/elife_converter.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/converter/elife_converter.js b/converter/elife_converter.js index bf23a10b..74c988f0 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -310,12 +310,17 @@ ElifeConverter.Prototype = function() { }; this.enhanceVideo = function(state, node, element) { + var id = element.getAttribute("id"); var href = element.getAttribute("xlink:href").split("."); var name = href[0]; - node.url = "https://legacy--api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file/"+name+".mp4"; - node.url_ogv = "https://legacy--api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file//"+name+".ogv"; - node.url_webm = "https://legacy--api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file//"+name+".webm"; - node.poster = "https://legacy--api.elifesciences.org/v2/articles/"+state.doc.id+"/media/file/"+name+".jpg"; + + // set attributes from previously populated data in video_data + if(typeof video_data !== 'undefined' && id in video_data) { + node.url = video_data[id]['mp4_href']; + node.url_ogv = video_data[id]['ogv_href']; + node.url_webm = video_data[id]['webm_href']; + node.poster = video_data[id]['jpg_href']; + } }; // Example url to JPG: https://cdn.elifesciences.org/elife-articles/00768/svg/elife00768f001.jpg From b75dfd24764bc4e300913a88f6c96df9d6b26fd4 Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Wed, 11 Dec 2019 17:34:47 -0800 Subject: [PATCH 76/84] Fix for focus link on some elife videos. --- converter/elife_converter.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/converter/elife_converter.js b/converter/elife_converter.js index 74c988f0..08893b91 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -13,6 +13,12 @@ ElifeConverter.Prototype = function() { var __super__ = LensConverter.prototype; + // Fix to focus on videos from left reading pane to the right figures pane + if (!("video" in __super__._refTypeMapping)) + { + __super__._refTypeMapping["video"] = "figure_reference"; + } + this.test = function(xmlDoc, documentUrl) { var publisherName = xmlDoc.querySelector("publisher-name").textContent; return publisherName === "eLife Sciences Publications, Ltd"; From a24aa46837c1f0e83fa08d0e9e156cd711884160 Mon Sep 17 00:00:00 2001 From: Joel Summerfield <52923935+NuclearRedeye@users.noreply.github.com> Date: Wed, 30 Sep 2020 09:31:12 +0100 Subject: [PATCH 77/84] Update readme (#222) Updated the instructions for lens-starter to make it more explicit which versions of node and python are required. --- README.md | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index d05a1bf6..4050638b 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ However, now let's look into developing our own extensions. ### Prerequisites -For Lens development, you need to have Node.js >=0.10.x installed. +For Lens development, you need to have Node.js >=10.x installed. You need to repeat that install step whenever you updated the screwdriver repo. @@ -37,25 +37,37 @@ You need to repeat that install step whenever you updated the screwdriver repo. 1. Clone the `lens-starter` repository - ```bash - $ git clone https://github.com/elifesciences/lens-starter.git - ``` +```bash + git clone https://github.com/elifesciences/lens-starter.git + cd lens-starter +``` + +2. Configure System + +As stated above, you'll need version 10.x of Node installed, and you'll also need version 2.7.x of Python available. You can use [nvm](https://github.com/nvm-sh/nvm) to manage which version of node to use on a per-project basis, and [PyEnv](https://github.com/pyenv/pyenv) to do the same for Python. With both of these tools setup, you can... + +```bash +echo "lts/dubnium" > .nvmrc +nvm install +nvm use +echo "2.7.17" > .python-version +pyenv install +pvenv local +``` 2. Fetch dependencies - ```bash - $ cd lens-starter - $ npm install - ``` +```bash +npm install +``` 3. Run the server - ```bash - ~/projects/lens-starter $ node server - Lens running on port 4001 - http://127.0.0.1:4001/ - ``` +```bash +npm start +``` +Then navigate to http://127.0.0.1:4001/ in your web browser. ### Converter From 77f1099d94bf977fbf58b5e6434c18f8546abc18 Mon Sep 17 00:00:00 2001 From: Joel Summerfield <52923935+NuclearRedeye@users.noreply.github.com> Date: Wed, 30 Sep 2020 12:31:25 +0100 Subject: [PATCH 78/84] Update README.md Fix numbering --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4050638b..e6af288f 100644 --- a/README.md +++ b/README.md @@ -55,13 +55,13 @@ pyenv install pvenv local ``` -2. Fetch dependencies +3. Fetch dependencies ```bash npm install ``` -3. Run the server +4. Run the server ```bash npm start From 1b9057f0bf1765bde2dd21c994b3ef9993e905a5 Mon Sep 17 00:00:00 2001 From: David Moreno Cortina Date: Fri, 15 Jan 2021 20:09:04 +0100 Subject: [PATCH 79/84] Fix figures panel not showing when none of the figures has a paragraph. --- reader/panels/container_panel_view.js | 8 ++++---- substance/document/container.js | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/reader/panels/container_panel_view.js b/reader/panels/container_panel_view.js index 33a1e530..cdbcfb7b 100644 --- a/reader/panels/container_panel_view.js +++ b/reader/panels/container_panel_view.js @@ -33,12 +33,12 @@ ContainerPanelView.Prototype = function() { this.render = function() { // Hide the whole tab if there is no content - if (this.getContainer().getLength() === 0) { - this.hideToggle(); - this.hide(); - } else { + if (this.getContainer().hasContent()) { this.surface.render(); this.scrollbar.render(); + } else { + this.hideToggle(); + this.hide(); } return this; }; diff --git a/substance/document/container.js b/substance/document/container.js index c139a3c4..8510e9f3 100644 --- a/substance/document/container.js +++ b/substance/document/container.js @@ -136,6 +136,10 @@ Container.Prototype = function() { return this.listView.length; }; + this.hasContent = function(panelType) { + return this.listView.length > 0 || (panelType === 'resource' && this.treeView.length > 0); + }; + // Returns true if there is another node after a given position. // -------- // From 81b057f14461741a83c3d6c5ca46c5fab735d46d Mon Sep 17 00:00:00 2001 From: David Moreno Cortina Date: Sat, 30 Jan 2021 09:46:52 +0100 Subject: [PATCH 80/84] Fix figures panel not showing when none of the figures has a paragraph. --- reader/panels/container_panel_view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reader/panels/container_panel_view.js b/reader/panels/container_panel_view.js index cdbcfb7b..b98d1467 100644 --- a/reader/panels/container_panel_view.js +++ b/reader/panels/container_panel_view.js @@ -33,7 +33,7 @@ ContainerPanelView.Prototype = function() { this.render = function() { // Hide the whole tab if there is no content - if (this.getContainer().hasContent()) { + if (this.getContainer().hasContent(this.config.type)) { this.surface.render(); this.scrollbar.render(); } else { From d302339815b4f4d7ff486a490e1dabd575fa47a6 Mon Sep 17 00:00:00 2001 From: Joel Summerfield <52923935+NuclearRedeye@users.noreply.github.com> Date: Thu, 11 Mar 2021 08:00:15 +0000 Subject: [PATCH 81/84] chore: add maintainers.txt file --- maintainers.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 maintainers.txt diff --git a/maintainers.txt b/maintainers.txt new file mode 100644 index 00000000..2b2d44e4 --- /dev/null +++ b/maintainers.txt @@ -0,0 +1,2 @@ +gnott +NuclearRedeye From 29bfd7e57b17c546a5a5c5835a84f49eb170c652 Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Wed, 24 Mar 2021 17:20:02 -0700 Subject: [PATCH 82/84] Change decision letter parsing for eLife articles. --- converter/elife_converter.js | 51 +++++++++++------------------------- 1 file changed, 16 insertions(+), 35 deletions(-) diff --git a/converter/elife_converter.js b/converter/elife_converter.js index 08893b91..b02e0127 100644 --- a/converter/elife_converter.js +++ b/converter/elife_converter.js @@ -40,42 +40,23 @@ ElifeConverter.Prototype = function() { var doc = state.doc; var heading, body; - // Decision letter (if available) + // Decision letter and author response sub articles (if available) // ----------- - - var articleCommentary = article.querySelector("#SA1"); - if (articleCommentary) { - heading = { - id: state.nextId("heading"), - type: "heading", - level: 1, - content: "Decision letter" - }; - doc.create(heading); - nodes.push(heading); - - body = articleCommentary.querySelector("body"); - nodes = nodes.concat(this.bodyNodes(state, util.dom.getChildren(body))); - } - - // Author response - // ----------- - - var authorResponse = article.querySelector("#SA2"); - if (authorResponse) { - - heading = { - id: state.nextId("heading"), - type: "heading", - level: 1, - content: "Author response" - }; - doc.create(heading); - nodes.push(heading); - - body = authorResponse.querySelector("body"); - nodes = nodes.concat(this.bodyNodes(state, util.dom.getChildren(body))); - } + var subArticles = article.querySelectorAll("sub-article"); + _.each(subArticles, function(subArticle) { + var subArticleTitle = subArticle.querySelector("title-group article-title").textContent; + heading = { + id: state.nextId("heading"), + type: "heading", + level: 1, + content: subArticleTitle + }; + doc.create(heading); + nodes.push(heading); + + body = subArticle.querySelector("body"); + nodes = nodes.concat(this.bodyNodes(state, util.dom.getChildren(body))); + }.bind(this)); // Show them off // ---------- From df1ff6e748f76d12e70764590d32f31fbf8f7784 Mon Sep 17 00:00:00 2001 From: Graham Nott Date: Fri, 7 May 2021 17:01:25 -0700 Subject: [PATCH 83/84] Bump underscore version in dependencies. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b23f8852..cd59ada3 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "url": "https://github.com/elifesciences/lens.git" }, "dependencies": { - "underscore": "1.8.3" + "underscore": "1.12.1" }, "engines": { From f9d46f95f304d86e0750e1a6e82aa4f405f189c3 Mon Sep 17 00:00:00 2001 From: Joel Summerfield <52923935+NuclearRedeye@users.noreply.github.com> Date: Thu, 21 Apr 2022 12:06:20 +0100 Subject: [PATCH 84/84] chore: update project maintainers --- maintainers.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/maintainers.txt b/maintainers.txt index 2b2d44e4..39a7775b 100644 --- a/maintainers.txt +++ b/maintainers.txt @@ -1,2 +1 @@ gnott -NuclearRedeye