From 9649638e1ace77412655156cd3717dbf2f54146c Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 6 Jul 2016 16:47:56 +0200 Subject: [PATCH 001/167] Switch to substance#devel --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 06c026660..476bbee13 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "A scientific editor and reader for JATS files.", "dependencies": { "lodash": "^4.2.1", - "substance": "substance/substance#97456fc530c3e081db593fa29795c03dbaa57cdb" + "substance": "substance/substance#devel" }, "devDependencies": { "browserify": "substance/node-browserify#d3caeb6dcdaa97a258d099c7231a57f0f60ec876", From 8e1e83ce831dedf0095e735c1656cc5cf1127e41 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 6 Jul 2016 17:05:37 +0200 Subject: [PATCH 002/167] Updated README.md --- README.md | 306 +++--------------------------------------------------- 1 file changed, 16 insertions(+), 290 deletions(-) diff --git a/README.md b/README.md index a9379c551..5696df44c 100644 --- a/README.md +++ b/README.md @@ -50,298 +50,24 @@ $ npm run bundle ## Roadmap -### Beta - -*ETA: Fall 2016* - -- First class JATS editing -- Author mode (classic word-style editing) -- Publisher mode (visual JATS editing) -- Add references via CrossRef search or pasting BibTex -- Visually select xref targets. +### Alpha 2 +*ETA: 25 July 2016 -### Beta 2 +- Update to Substance Beta 5 +- Author: + - Cover editing (title, abstract, authors, etc.) +- Publisher: + - Front matter editor (JATS ``) + - XML navigation bar (breadcrumbs, similar to XPath) + - Edit references (XML, for fixing) + - Add references (template for ``) -- Math support (inline and block formulas) -- Structure mode (restructure sections with a dedicated interface) - - - \ No newline at end of file +- Creating content (contextual) +- Add references via CrossRef search or pasting BibTex +- Support more elements +- Extended JATS, Stencila Package From a9db627adaccb036cc19041553ead08282bf0d28 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 6 Jul 2016 17:06:40 +0200 Subject: [PATCH 003/167] Updated README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5696df44c..ba69aae53 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ $ npm run bundle ### Alpha 2 -*ETA: 25 July 2016 +*ETA: 25 July 2016* - Update to Substance Beta 5 - Author: From 3facddb1d87d51cfd390bf70007cc336e209eb01 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 6 Jul 2016 17:10:12 +0200 Subject: [PATCH 004/167] Updated README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index ba69aae53..3b6ecb85f 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,13 @@ Navigate to the source directory. $ cd scientist ``` +At the moment, the default branch provides the develop version. +To get the latest stable version switch to the `master` branch: + +```bash +$ git checkout master +``` + Install via npm ```bash From 1b81266b48a802449bbf2f20ed417a207e4a5295 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 6 Jul 2016 17:22:57 +0200 Subject: [PATCH 005/167] Update travis badge to show 'develop' --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b6ecb85f..4c00cf43e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Substance Scientist [![Build Status](https://travis-ci.org/substance/scientist.svg?branch=devel)](https://travis-ci.org/substance/scientist) +# Substance Scientist [![Build Status](https://travis-ci.org/substance/scientist.svg?branch=develop)](https://travis-ci.org/substance/scientist) This is a work-in progress. The project name Scientist is temporary and may be changed with the first beta release. From ed760a8e33c29d2335163a9212bc2059b80a4ee7 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 7 Jul 2016 16:33:48 +0200 Subject: [PATCH 006/167] Add license. --- LICENSE.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 000000000..9472aee23 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,20 @@ +Copyright (c) 2016 Substance Software GmbH + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From 6b31bbe08d1a3c1ae45560eebec0c5926a68c1ca Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 7 Jul 2016 17:00:05 +0200 Subject: [PATCH 007/167] Update README.md --- README.md | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4c00cf43e..6e1a09d66 100644 --- a/README.md +++ b/README.md @@ -49,11 +49,11 @@ $ npm test See [CONTRIBUTING.md](CONTRIBUTING.md). - ## Roadmap @@ -77,4 +77,24 @@ $ npm run bundle - Creating content (contextual) - Add references via CrossRef search or pasting BibTex - Support more elements -- Extended JATS, Stencila Package +- Extended JATS, [Stencila](https://stenci.la/) Package + +# Credits + +Scientist is developed by the [Substance Consortium](http://substance.io/consortium/) formed by the [Public Knowledge Project](https://pkp.sfu.ca/2016/04/27/substance-consortium/) (PKP), the [Collaborative Knowledge Foundation](http://coko.foundation/blog.html#substance_consortium) (CoKo) and [Érudit](https://apropos.erudit.org/fr/creation-dun-consortium-autour-de-substance/). + +Thanks goes to the following people, who made Scientist possible: + +- Alex Garnett (leadership, concept) +- Juan Pablo Alperin (concept) +- Alex Smecher (concept, dev) +- Kristen Ratan (leadership) +- Adam Hyde (leadership) +- Jure Triglav (concept, dev) +- Tanja Niemann (leadership) +- Davin Baragiotta (concept, dev) +- David Cormier (dev) +- Sophy Ouch (design) +- Michael Aufreiter (dev) +- Oliver Buchtala (dev) +- ... From 96087d60799607d61e10671a0dd817782bdd7a0c Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 7 Jul 2016 17:11:00 +0200 Subject: [PATCH 008/167] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6e1a09d66..372f765ed 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ Scientist is developed by the [Substance Consortium](http://substance.io/consort Thanks goes to the following people, who made Scientist possible: - Alex Garnett (leadership, concept) -- Juan Pablo Alperin (concept) +- Juan Pablo Alperin (leadership, concept) - Alex Smecher (concept, dev) - Kristen Ratan (leadership) - Adam Hyde (leadership) From a6514ad3ecb16137d577408a9e117727be773a91 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 7 Jul 2016 17:17:54 +0200 Subject: [PATCH 009/167] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 372f765ed..431ff7f2e 100644 --- a/README.md +++ b/README.md @@ -45,16 +45,16 @@ To run the test suite headless: $ npm test ``` -## Contribute - -See [CONTRIBUTING.md](CONTRIBUTING.md). - -# Bundle examples +## Bundle examples ```bash $ npm run bundle ``` +## Contribute + +See [CONTRIBUTING.md](CONTRIBUTING.md). + ## Roadmap ### Alpha 2 From 3a7c068b5e3d008b49cecf10b244d3fe46833ed6 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 7 Jul 2016 20:31:36 +0200 Subject: [PATCH 010/167] Use two configuration levels. On top level we configure the Scientist. The ScientistConfigurator then contains separate configurators for each mode (PublisherConfigurator, AuthorConfigurator). --- examples/jats-editor/app.js | 20 +++---- examples/jats-editor/package.js | 6 +- packages/author/Author.js | 1 + packages/author/AuthorConfigurator.js | 10 ++++ packages/common/BaseConfigurator.js | 23 -------- packages/common/BasicApp.js | 53 ----------------- packages/publisher/PublisherConfigurator.js | 11 ++++ .../scientist/Scientist.js | 43 +++++++++++--- packages/scientist/ScientistConfigurator.js | 59 +++++++++++++++++++ packages/scientist/package.js | 15 +++++ server.js | 4 +- 11 files changed, 144 insertions(+), 101 deletions(-) create mode 100644 packages/author/AuthorConfigurator.js delete mode 100644 packages/common/BaseConfigurator.js delete mode 100644 packages/common/BasicApp.js create mode 100644 packages/publisher/PublisherConfigurator.js rename examples/jats-editor/JATSEditor.js => packages/scientist/Scientist.js (65%) create mode 100644 packages/scientist/ScientistConfigurator.js create mode 100644 packages/scientist/package.js diff --git a/examples/jats-editor/app.js b/examples/jats-editor/app.js index 625999ee4..7fe63a9bd 100644 --- a/examples/jats-editor/app.js +++ b/examples/jats-editor/app.js @@ -3,9 +3,11 @@ var substanceGlobals = require('substance/util/substanceGlobals'); substanceGlobals.DEBUG_RENDERING = true; -var BasicApp = require('../../packages/common/BasicApp'); -var JATSEditor = require('./JATSEditor'); +var Component = require('substance/ui/Component'); +var Scientist = require('../../packages/scientist/Scientist'); +var ScientistConfigurator = require('../../packages/scientist/ScientistConfigurator'); var JATSEditorPackage = require('./package'); +var configurator = new ScientistConfigurator(JATSEditorPackage); function App() { App.super.apply(this, arguments); @@ -13,30 +15,26 @@ function App() { App.Prototype = function() { - this.getDefaultState = function() { + this.getInitialState = function() { return { documentId: 'elife-00007', }; }; - this.getConfiguration = function() { - return JATSEditorPackage; - }; - this.render = function($$) { var documentId = this.state.documentId; var el = $$('div').append( - $$(JATSEditor, { - mode: 'write', + $$(Scientist, { + mode: 'publisher', documentId: documentId, - configurator: this.configurator + configurator: configurator }) ); return el; }; }; -BasicApp.extend(App); +Component.extend(App); window.onload = function() { window.app = App.static.mount(document.body); diff --git a/examples/jats-editor/package.js b/examples/jats-editor/package.js index 7b86cb719..f6ac05a82 100644 --- a/examples/jats-editor/package.js +++ b/examples/jats-editor/package.js @@ -1,14 +1,14 @@ 'use strict'; -var PublisherPackage = require('../../packages/publisher/package'); +var ScientistPackage = require('../../packages/scientist/package'); var ExampleXMLStore = require('../ExampleXMLStore'); var path = require('path'); module.exports = { name: 'jats-editor', configure: function(config) { - // Base package with regular JATS support - config.import(PublisherPackage); + // Use the default Scientist package + config.import(ScientistPackage); // Define XML Store config.setXMLStore(ExampleXMLStore); diff --git a/packages/author/Author.js b/packages/author/Author.js index 297f65154..02b478e70 100644 --- a/packages/author/Author.js +++ b/packages/author/Author.js @@ -89,6 +89,7 @@ Author.Prototype = function() { }; }; + this._getTOCProvider = function() { return new AuthorTOCProvider(this.documentSession); }; diff --git a/packages/author/AuthorConfigurator.js b/packages/author/AuthorConfigurator.js new file mode 100644 index 000000000..6ce859eb3 --- /dev/null +++ b/packages/author/AuthorConfigurator.js @@ -0,0 +1,10 @@ +'use strict'; +var Configurator = require('substance/util/Configurator'); + +function AuthorConfigurator() { + AuthorConfigurator.super.apply(this, arguments); +} + +Configurator.extend(AuthorConfigurator); + +module.exports = AuthorConfigurator; \ No newline at end of file diff --git a/packages/common/BaseConfigurator.js b/packages/common/BaseConfigurator.js deleted file mode 100644 index afb70dd58..000000000 --- a/packages/common/BaseConfigurator.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict'; - -var Configurator = require('substance/util/Configurator'); - -function BaseConfigurator() { - BaseConfigurator.super.apply(this, arguments); -} - -BaseConfigurator.Prototype = function() { - - this.setXMLStore = function(XMLStoreClass) { - this.config.XMLStoreClass = XMLStoreClass; - }; - - this.getXMLStore = function() { - var XMLStoreClass = this.config.XMLStoreClass; - return new XMLStoreClass(); - }; -}; - -Configurator.extend(BaseConfigurator); - -module.exports = BaseConfigurator; \ No newline at end of file diff --git a/packages/common/BasicApp.js b/packages/common/BasicApp.js deleted file mode 100644 index 3fac291a3..000000000 --- a/packages/common/BasicApp.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict'; - -var extend = require('lodash/extend'); -var Component = require('substance/ui/Component'); -var Router = require('substance/ui/Router'); -var Configurator = require('./BaseConfigurator'); - -function BasicApp() { - BasicApp.super.apply(this, arguments); - - this.router = new Router(); - this.configurator = new Configurator(this.getConfiguration()); -} - -BasicApp.Prototype = function() { - - this.didMount = function() { - this.router.on('route:changed', this.onRouteChange, this); - this.router.start(); - }; - - this.dispose = function() { - this.router.off(this); - this.router.dispose(); - }; - - this.getDefaultState = function() { - return {}; - }; - - this.getConfiguration = function() { - throw new Error('This method is abstract'); - }; - - this.getInitialState = function() { - this.router = new Router(); - var state = extend({}, this.getDefaultState(), this.router.readRoute()); - return state; - }; - - this.render = function($$) { // eslint-disable-line - throw new Error('This method is abstract.'); - }; - - this.onRouteChange = function(newState) { - this.setState(extend({}, this.getDefaultState(), newState)); - }; - -}; - -Component.extend(BasicApp); - -module.exports = BasicApp; diff --git a/packages/publisher/PublisherConfigurator.js b/packages/publisher/PublisherConfigurator.js new file mode 100644 index 000000000..aa12ed87e --- /dev/null +++ b/packages/publisher/PublisherConfigurator.js @@ -0,0 +1,11 @@ +'use strict'; + +var Configurator = require('substance/util/Configurator'); + +function PublisherConfigurator() { + PublisherConfigurator.super.apply(this, arguments); +} + +Configurator.extend(PublisherConfigurator); + +module.exports = PublisherConfigurator; \ No newline at end of file diff --git a/examples/jats-editor/JATSEditor.js b/packages/scientist/Scientist.js similarity index 65% rename from examples/jats-editor/JATSEditor.js rename to packages/scientist/Scientist.js index 6f7924ab3..0e9980a21 100644 --- a/examples/jats-editor/JATSEditor.js +++ b/packages/scientist/Scientist.js @@ -3,20 +3,21 @@ var Component = require('substance/ui/Component'); var DocumentSession = require('substance/model/DocumentSession'); var Publisher = require('../../packages/publisher/Publisher'); +var Author = require('../../packages/author/Author'); /* JATSEditor Component - Based on given props displays an editor or viewer + Based on given mode prop, displays the Publisher, Author or Reader component */ -function JATSEditor() { +function Scientist() { Component.apply(this, arguments); var configurator = this.props.configurator; this.xmlStore = configurator.getXMLStore(); } -JATSEditor.Prototype = function() { +Scientist.Prototype = function() { this.getChildContext = function() { return { @@ -44,8 +45,18 @@ JATSEditor.Prototype = function() { } }; + this.dispose = function() { + this._dispose(); + }; + + this._dispose = function() { + // Note: we need to clear everything, as the childContext + // changes which is immutable + this.empty(); + }; + this._loadDocument = function() { - var configurator = this.props.configurator; + var configurator = this.getChildConfigurator(); this.xmlStore.readXML(this.props.documentId, function(err, xml) { if (err) { @@ -68,12 +79,16 @@ JATSEditor.Prototype = function() { }.bind(this)); }; + this.getChildConfigurator = function() { + var scientistConfigurator = this.props.configurator; + return scientistConfigurator.getConfigurator(this.props.mode); + }; + // Rendering // ------------------------------------ this.render = function($$) { - var configurator = this.props.configurator; - var el = $$('div').addClass('sc-JATSEditor'); + var el = $$('div').addClass('sc-scientist'); if (this.state.error) { el.append('ERROR: ', this.state.error.message); @@ -84,9 +99,19 @@ JATSEditor.Prototype = function() { return el; } + // Depending on the chosen mode, instantiate + var ActiveModeClass; + var configurator = this.getChildConfigurator(); + + if (this.props.mode === 'publisher') { + ActiveModeClass = Publisher; + } else if (this.props.mode === 'author') { + ActiveModeClass = Author; + } + // Display reader for mobile and writer on desktop el.append( - $$(Publisher, { + $$(ActiveModeClass, { documentId: this.props.documentId, documentSession: this.state.documentSession, configurator: configurator @@ -96,6 +121,6 @@ JATSEditor.Prototype = function() { }; }; -Component.extend(JATSEditor); +Component.extend(Scientist); -module.exports = JATSEditor; +module.exports = Scientist; diff --git a/packages/scientist/ScientistConfigurator.js b/packages/scientist/ScientistConfigurator.js new file mode 100644 index 000000000..ee00675bb --- /dev/null +++ b/packages/scientist/ScientistConfigurator.js @@ -0,0 +1,59 @@ +'use strict'; + +var Configurator = require('substance/util/Configurator'); +var forEach = require('lodash/forEach'); +var uniq = require('lodash/uniq'); + +/* + Top-level configurator for scientist. Has sub-configurators for + all available modules (author, publisher, reader). +*/ +function ScientistConfigurator() { + ScientistConfigurator.super.apply(this, arguments); +} + +ScientistConfigurator.Prototype = function() { + + /* + Provision of sub configurators (e.g. Author, Publisher, Reader + receive their own configurator) + */ + this.addConfigurator = function(name, configurator) { + if (!this.config.configurators) { + this.config.configurators = {}; + } + this.config.configurators[name] = configurator; + }; + + this.getConfigurator = function(name) { + if (!this.config.configurators) { + return undefined; + } + return this.config.configurators[name]; + }; + + this.setXMLStore = function(XMLStoreClass) { + this.config.XMLStoreClass = XMLStoreClass; + }; + + this.getXMLStore = function() { + var XMLStoreClass = this.config.XMLStoreClass; + return new XMLStoreClass(); + }; + + this.getStyles = function() { + var styles = [].concat(this.config.styles); + + forEach(this.config.configurators, function(configurator) { + styles = styles.concat(configurator.getStyles()); + }); + + // Remove duplicates with _.uniq, since publisher, author, + // reader use a lot of shared styles + return uniq(styles); + }; +}; + +Configurator.extend(ScientistConfigurator); + +module.exports = ScientistConfigurator; \ No newline at end of file diff --git a/packages/scientist/package.js b/packages/scientist/package.js new file mode 100644 index 000000000..6089d8cf2 --- /dev/null +++ b/packages/scientist/package.js @@ -0,0 +1,15 @@ +'use strict'; + +var AuthorPackage = require('../author/package'); +var AuthorConfigurator = require('../author/AuthorConfigurator'); +var PublisherPackage = require('../publisher/package'); +var PublisherConfigurator = require('../publisher/PublisherConfigurator'); + +module.exports = { + name: 'scientist', + configure: function(config) { + // Default configuration for available scientist modes + config.addConfigurator('author', new AuthorConfigurator(AuthorPackage)); + config.addConfigurator('publisher', new PublisherConfigurator(PublisherPackage)); + } +}; diff --git a/server.js b/server.js index 7a96905f4..e11759551 100644 --- a/server.js +++ b/server.js @@ -11,7 +11,7 @@ var app = express(); // Writer example integration serverUtils.serveStyles(app, '/jats-editor/app.css', { rootDir: __dirname, - configuratorPath: require.resolve('./packages/common/BaseConfigurator'), + configuratorPath: require.resolve('./packages/scientist/ScientistConfigurator'), configPath: require.resolve('./examples/jats-editor/package') }); serverUtils.serveJS(app, '/jats-editor/app.js', path.join(__dirname, 'examples/jats-editor', 'app.js')); @@ -19,7 +19,7 @@ serverUtils.serveHTML(app, '/jats-editor', path.join(__dirname, 'examples/jats-e serverUtils.serveStyles(app, '/science-writer/app.css', { rootDir: __dirname, - configuratorPath: require.resolve('./packages/common/BaseConfigurator'), + configuratorPath: require.resolve('./packages/scientist/ScientistConfigurator'), configPath: require.resolve('./examples/science-writer/package'), }); serverUtils.serveJS(app, '/science-writer/app.js', path.join(__dirname, 'examples/science-writer', 'app.js')); From dbfc1f8d08a513f304aa0927b9712a3f701a77bd Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 7 Jul 2016 20:43:38 +0200 Subject: [PATCH 011/167] Fix test suite. --- packages/jats/JATSConfigurator.js | 13 +++++++++++++ test/jats/createJATSConfigurator.js | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 packages/jats/JATSConfigurator.js diff --git a/packages/jats/JATSConfigurator.js b/packages/jats/JATSConfigurator.js new file mode 100644 index 000000000..82de56b94 --- /dev/null +++ b/packages/jats/JATSConfigurator.js @@ -0,0 +1,13 @@ +'use strict'; + +/* Used only by test suite to test JATS converter functionality. */ + +var Configurator = require('substance/util/Configurator'); + +function JATSConfigurator() { + JATSConfigurator.super.apply(this, arguments); +} + +Configurator.extend(JATSConfigurator); + +module.exports = JATSConfigurator; \ No newline at end of file diff --git a/test/jats/createJATSConfigurator.js b/test/jats/createJATSConfigurator.js index 941517493..3833fb74d 100644 --- a/test/jats/createJATSConfigurator.js +++ b/test/jats/createJATSConfigurator.js @@ -1,6 +1,6 @@ 'use strict'; -var Configurator = require('../../packages/common/BaseConfigurator'); +var Configurator = require('../../packages/jats/JATSConfigurator'); var JATSPackage = require('../../packages/jats/package'); var InlineWrapperPackage = require('../../packages/inline-wrapper/InlineWrapperPackage'); var UnsupportedNodePackage = require('../../packages/unsupported/UnsupportedNodePackage'); From 03190716546d0b53f40c72ee53945de8d084a367 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 7 Jul 2016 23:30:39 +0200 Subject: [PATCH 012/167] Simplify JATS editor example. --- examples/jats-editor/app.js | 33 +++++---------------------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/examples/jats-editor/app.js b/examples/jats-editor/app.js index 7fe63a9bd..33ea2d92c 100644 --- a/examples/jats-editor/app.js +++ b/examples/jats-editor/app.js @@ -9,33 +9,10 @@ var ScientistConfigurator = require('../../packages/scientist/ScientistConfigura var JATSEditorPackage = require('./package'); var configurator = new ScientistConfigurator(JATSEditorPackage); -function App() { - App.super.apply(this, arguments); -} - -App.Prototype = function() { - - this.getInitialState = function() { - return { - documentId: 'elife-00007', - }; - }; - - this.render = function($$) { - var documentId = this.state.documentId; - var el = $$('div').append( - $$(Scientist, { - mode: 'publisher', - documentId: documentId, - configurator: configurator - }) - ); - return el; - }; -}; - -Component.extend(App); - window.onload = function() { - window.app = App.static.mount(document.body); + window.app = Scientist.static.mount({ + mode: 'publisher', + documentId: 'elife-00007', + configurator: configurator + }, document.body); }; From 8758dfdaf63572d32127ca96bc381247dd9cdf34 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 8 Jul 2016 01:55:06 +0200 Subject: [PATCH 013/167] Streamline author example. --- examples/ExampleXMLStore.js | 4 +- examples/jats-editor/app.js | 2 +- examples/jats-editor/package.js | 3 +- examples/science-writer/ScienceWriter.js | 106 ----------------------- examples/science-writer/app.js | 45 ++-------- examples/science-writer/package.js | 9 +- index.js | 5 ++ packages/author/Author.js | 10 +-- packages/author/AuthorExporter.js | 22 +++++ packages/author/AuthorImporter.js | 23 +++++ packages/author/AuthorTOCProvider.js | 2 +- packages/author/package.js | 7 ++ 12 files changed, 75 insertions(+), 163 deletions(-) delete mode 100644 examples/science-writer/ScienceWriter.js create mode 100644 index.js create mode 100644 packages/author/AuthorExporter.js create mode 100644 packages/author/AuthorImporter.js diff --git a/examples/ExampleXMLStore.js b/examples/ExampleXMLStore.js index 97bc0259b..ac01ce1a9 100644 --- a/examples/ExampleXMLStore.js +++ b/examples/ExampleXMLStore.js @@ -3,9 +3,7 @@ var oo = require('substance/util/oo'); var request = require('substance/util/request'); -function ExampleXMLStore() { - -} +function ExampleXMLStore() {} ExampleXMLStore.Prototype = function() { this.readXML = function(documentId, cb) { diff --git a/examples/jats-editor/app.js b/examples/jats-editor/app.js index 33ea2d92c..6cc023c69 100644 --- a/examples/jats-editor/app.js +++ b/examples/jats-editor/app.js @@ -3,7 +3,6 @@ var substanceGlobals = require('substance/util/substanceGlobals'); substanceGlobals.DEBUG_RENDERING = true; -var Component = require('substance/ui/Component'); var Scientist = require('../../packages/scientist/Scientist'); var ScientistConfigurator = require('../../packages/scientist/ScientistConfigurator'); var JATSEditorPackage = require('./package'); @@ -16,3 +15,4 @@ window.onload = function() { configurator: configurator }, document.body); }; + diff --git a/examples/jats-editor/package.js b/examples/jats-editor/package.js index f6ac05a82..f6079b672 100644 --- a/examples/jats-editor/package.js +++ b/examples/jats-editor/package.js @@ -2,7 +2,6 @@ var ScientistPackage = require('../../packages/scientist/package'); var ExampleXMLStore = require('../ExampleXMLStore'); -var path = require('path'); module.exports = { name: 'jats-editor', @@ -12,6 +11,6 @@ module.exports = { // Define XML Store config.setXMLStore(ExampleXMLStore); - config.addStyle(path.join(__dirname, 'app.scss')); + config.addStyle(__dirname, 'app.scss'); } }; diff --git a/examples/science-writer/ScienceWriter.js b/examples/science-writer/ScienceWriter.js deleted file mode 100644 index efa43e936..000000000 --- a/examples/science-writer/ScienceWriter.js +++ /dev/null @@ -1,106 +0,0 @@ -'use strict'; - -var Component = require('substance/ui/Component'); -var DocumentSession = require('substance/model/DocumentSession'); -var Author = require('../../packages/author/Author'); -var JATSTransformer = require('../../packages/author/JATSTransformer'); - -/* - ScienceWriter Component - - Based on given props displays an editor or viewer -*/ -function ScienceWriter() { - Component.apply(this, arguments); - - var configurator = this.props.configurator; - this.xmlStore = configurator.getXMLStore(); -} - -ScienceWriter.Prototype = function() { - - this.getChildContext = function() { - return { - xmlStore: this.xmlStore - }; - }; - - this.getInitialState = function() { - return { - documentSession: null, - error: null - }; - }; - - this.didMount = function() { - // load the document after mounting - this._loadDocument(this.props.documentId); - }; - - this.willReceiveProps = function(newProps) { - if (newProps.documentId !== this.props.documentId) { - this.dispose(); - this.state = this.getInitialState(); - this._loadDocument(newProps.documentId); - } - }; - - this._loadDocument = function() { - var configurator = this.props.configurator; - - this.xmlStore.readXML(this.props.documentId, function(err, xml) { - if (err) { - console.error(err); - this.setState({ - error: new Error('Loading failed') - }); - return; - } - - var importer = configurator.createImporter('jats'); - - var doc = importer.importDocument(xml); - var trafo = new JATSTransformer(); - doc = trafo.fromJATS(doc); - - // HACK: For debug purposes - window.doc = doc; - var documentSession = new DocumentSession(doc); - - this.setState({ - documentSession: documentSession - }); - }.bind(this)); - }; - - // Rendering - // ------------------------------------ - - this.render = function($$) { - var configurator = this.props.configurator; - var el = $$('div').addClass('sc-science-writer'); - - if (this.state.error) { - el.append('ERROR: ', this.state.error.message); - return el; - } - - if (!this.state.documentSession) { - return el; - } - - // Display reader for mobile and writer on desktop - el.append( - $$(Author, { - documentId: this.props.documentId, - documentSession: this.state.documentSession, - configurator: configurator - }).ref('publisher') - ); - return el; - }; -}; - -Component.extend(ScienceWriter); - -module.exports = ScienceWriter; diff --git a/examples/science-writer/app.js b/examples/science-writer/app.js index dda0ff6a8..0c7e13d10 100644 --- a/examples/science-writer/app.js +++ b/examples/science-writer/app.js @@ -3,42 +3,15 @@ var substanceGlobals = require('substance/util/substanceGlobals'); substanceGlobals.DEBUG_RENDERING = true; -var BasicApp = require('../../packages/common/BasicApp'); -var ScienceWriter = require('./ScienceWriter'); -var ScienceWriterPackage = require('./package'); - -function App() { - App.super.apply(this, arguments); -} - -App.Prototype = function() { - - this.getDefaultState = function() { - return { - // documentId: 'elife-00007', - documentId: 'kitchen-sink-author', - }; - }; - - this.getConfiguration = function() { - return ScienceWriterPackage; - }; - - this.render = function($$) { - var documentId = this.state.documentId; - var el = $$('div').append( - $$(ScienceWriter, { - mode: 'write', - documentId: documentId, - configurator: this.configurator - }) - ); - return el; - }; -}; - -BasicApp.extend(App); +var Scientist = require('../../packages/scientist/Scientist'); +var ScientistConfigurator = require('../../packages/scientist/ScientistConfigurator'); +var JATSEditorPackage = require('./package'); +var configurator = new ScientistConfigurator(JATSEditorPackage); window.onload = function() { - window.app = App.static.mount(document.body); + window.app = Scientist.static.mount({ + mode: 'author', + documentId: 'elife-00007', + configurator: configurator + }, document.body); }; diff --git a/examples/science-writer/package.js b/examples/science-writer/package.js index ade4f4d16..6a371a071 100644 --- a/examples/science-writer/package.js +++ b/examples/science-writer/package.js @@ -1,17 +1,16 @@ 'use strict'; -var AuthorPackage = require('../../packages/author/package'); +var ScientistPackage = require('../../packages/scientist/package'); var ExampleXMLStore = require('../ExampleXMLStore'); -var path = require('path'); module.exports = { name: 'science-writer', configure: function(config) { - // Base package with regular JATS support - config.import(AuthorPackage); + // Use the default Scientist package + config.import(ScientistPackage); // Define XML Store config.setXMLStore(ExampleXMLStore); - config.addStyle(path.join(__dirname, 'app.scss')); + config.addStyle(__dirname, 'app.scss'); } }; diff --git a/index.js b/index.js new file mode 100644 index 000000000..7b10c3159 --- /dev/null +++ b/index.js @@ -0,0 +1,5 @@ +'use strict'; + +var Scientist = require('./packages/scientist/Scientist'); + +module.exports = Scientist; \ No newline at end of file diff --git a/packages/author/Author.js b/packages/author/Author.js index 02b478e70..c56f21e96 100644 --- a/packages/author/Author.js +++ b/packages/author/Author.js @@ -79,17 +79,9 @@ Author.Prototype = function() { }; this._getExporter = function() { - var jatsExporter = this.props.configurator.createExporter('jats'); - var trafo = new JATSTransformer(); - return { - exportDocument: function(doc) { - doc = trafo.toJATS(doc); - return jatsExporter.exportDocument(doc); - } - }; + this.props.configurator.createExporter('jats'); }; - this._getTOCProvider = function() { return new AuthorTOCProvider(this.documentSession); }; diff --git a/packages/author/AuthorExporter.js b/packages/author/AuthorExporter.js new file mode 100644 index 000000000..03ac78f1f --- /dev/null +++ b/packages/author/AuthorExporter.js @@ -0,0 +1,22 @@ +'use strict'; + +var JATSExporter = require('../jats/JATSExporter'); +var JATSTransformer = require('./JATSTransformer'); + +function AuthorExporter() { + AuthorExporter.super.apply(this, arguments); +} + +AuthorExporter.Prototype = function() { + var _super = AuthorExporter.super.prototype; + + this.exportDocument = function(doc) { + var trafo = new JATSTransformer(); + doc = trafo.toJATS(doc); + return _super.exportDocument.exportDocument.call(this, doc); + }; +}; + +JATSExporter.extend(AuthorExporter); + +module.exports = AuthorExporter; diff --git a/packages/author/AuthorImporter.js b/packages/author/AuthorImporter.js new file mode 100644 index 000000000..3ec98b884 --- /dev/null +++ b/packages/author/AuthorImporter.js @@ -0,0 +1,23 @@ +'use strict'; + +var JATSImporter = require('../jats/JATSImporter'); +var JATSTransformer = require('./JATSTransformer'); + +function AuthorImporter() { + AuthorImporter.super.apply(this, arguments); +} + +AuthorImporter.Prototype = function() { + var _super = AuthorImporter.super.prototype; + + this.importDocument = function() { + var doc = _super.importDocument.apply(this, arguments); + var trafo = new JATSTransformer(); + doc = trafo.fromJATS(doc); + return doc; + }; +}; + +JATSImporter.extend(AuthorImporter); + +module.exports = AuthorImporter; \ No newline at end of file diff --git a/packages/author/AuthorTOCProvider.js b/packages/author/AuthorTOCProvider.js index 25595b252..bd8e51968 100644 --- a/packages/author/AuthorTOCProvider.js +++ b/packages/author/AuthorTOCProvider.js @@ -10,4 +10,4 @@ function AuthorTOCProvider(documentSession) { TOCProvider.extend(AuthorTOCProvider); -module.exports = AuthorTOCProvider; +module.exports = AuthorTOCProvider; \ No newline at end of file diff --git a/packages/author/package.js b/packages/author/package.js index 496a63802..fa76f4b2e 100644 --- a/packages/author/package.js +++ b/packages/author/package.js @@ -3,6 +3,9 @@ var Overlay = require('substance/ui/Overlay'); var Toolbar = require('substance/ui/Toolbar'); +var AuthorImporter = require('./AuthorImporter'); +var AuthorExporter = require('./AuthorExporter'); + module.exports = { name: 'author', configure: function(config) { @@ -23,5 +26,9 @@ module.exports = { config.import(require('../inline-wrapper/InlineWrapperPackage')); // catch all converters config.import(require('../unsupported/UnsupportedNodePackage')); + + // Override Importer/Exporter + config.addImporter('jats', AuthorImporter); + config.addExporter('jats', AuthorExporter); } }; \ No newline at end of file From 19532be20a53f27aeac92b04c5fc721b12faf3cb Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 8 Jul 2016 01:55:19 +0200 Subject: [PATCH 014/167] Add usage section to README. --- README.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/README.md b/README.md index 431ff7f2e..bf945e20d 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,75 @@ To run the test suite headless: $ npm test ``` +## Usage + +Here's how you can integrate Scientist into your web app. + +```js +// app.js +var Scientist = require('substance-scientist'); +var myScientistPackage = require('./myScientistPackage'); +var configurator = new Scientist.Configurator(myScientistPackage); + +window.onload = function() { + window.app = Scientist.static.mount({ + mode: 'publisher', // or 'author' or 'reader' + documentId: 'doc-1', + configurator: configurator + }, document.body); +}; +``` + +Scientist is fully configurable. So you need to supply a custom configuration via a package defintion. + +```js +// myScientistPackage.js +var MyXMLStore = require('../MyXMLStore'); +var scientistPackage = require('substance-scientist/packages/scientist/package'); +var path = require('path'); + +module.exports = { + name: 'my-scientist', + configure: function(config) { + // Use the default Scientist package + config.import(scientistPackage); + + // Define XML Store + config.setXMLStore(MyXMLStore); + // Add your custom app styles + config.addStyle(__dirname, 'my-scientist.scss'); + } +}; +``` + +In order to connect Scientist to a backend you need to define an XML Store: + +```js +// MyXMLStore.js +var oo = require('substance/util/oo'); +var request = require('substance/util/request'); + +function MyXMLStore() {} + +MyXMLStore.Prototype = function() { + this.readXML = function(documentId, cb) { + request('GET', 'https://myserver.com/documents/'+documentId+'.xml', null, cb); + }; + + // TODO make functional + this.writeXML = function(documentId, xml, cb) { + var data = {content: xml}; + var url = 'https://myserver.com/documents/'+documentId+'.xml' + request('PUT', url, data, cb); + }; +}; + +oo.initClass(MyXMLStore); + +module.exports = MyXMLStore; +``` + + ## Bundle examples ```bash From 1e9e956aac66e6d8e4b9c031bdbb163e5b068ace Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 8 Jul 2016 02:18:35 +0200 Subject: [PATCH 015/167] Linting. --- packages/author/Author.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/author/Author.js b/packages/author/Author.js index c56f21e96..da72f4aeb 100644 --- a/packages/author/Author.js +++ b/packages/author/Author.js @@ -7,7 +7,6 @@ var Layout = require('substance/ui/Layout'); var Overlay = require('substance/ui/DefaultOverlay'); var AuthorTOCProvider = require('./AuthorTOCProvider'); var TOC = require('substance/ui/TOC'); -var JATSTransformer = require('./JATSTransformer'); function Author() { Author.super.apply(this, arguments); From 95cbf2e1b510fbca26ed874688fbc10258748185 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 8 Jul 2016 15:10:00 +0200 Subject: [PATCH 016/167] Remove unneeded Configurators. We now have ProseEditorConfigurator to configure Publisher and Author and ScientistConfigurator to configure the top level Scientist component. --- examples/jats-editor/app.js | 4 ++-- examples/science-writer/app.js | 2 +- packages/author/Author.js | 2 +- packages/author/AuthorConfigurator.js | 10 ---------- packages/author/AuthorExporter.js | 2 +- packages/jats/JATSConfigurator.js | 13 ------------- packages/publisher/PublisherConfigurator.js | 11 ----------- packages/scientist/ScientistConfigurator.js | 10 ++++------ packages/scientist/package.js | 8 ++++---- test/jats/createJATSConfigurator.js | 2 +- 10 files changed, 14 insertions(+), 50 deletions(-) delete mode 100644 packages/author/AuthorConfigurator.js delete mode 100644 packages/jats/JATSConfigurator.js delete mode 100644 packages/publisher/PublisherConfigurator.js diff --git a/examples/jats-editor/app.js b/examples/jats-editor/app.js index 6cc023c69..58a609bf7 100644 --- a/examples/jats-editor/app.js +++ b/examples/jats-editor/app.js @@ -6,7 +6,8 @@ substanceGlobals.DEBUG_RENDERING = true; var Scientist = require('../../packages/scientist/Scientist'); var ScientistConfigurator = require('../../packages/scientist/ScientistConfigurator'); var JATSEditorPackage = require('./package'); -var configurator = new ScientistConfigurator(JATSEditorPackage); + +var configurator = new ScientistConfigurator().import(JATSEditorPackage); window.onload = function() { window.app = Scientist.static.mount({ @@ -15,4 +16,3 @@ window.onload = function() { configurator: configurator }, document.body); }; - diff --git a/examples/science-writer/app.js b/examples/science-writer/app.js index 0c7e13d10..9a8419c8f 100644 --- a/examples/science-writer/app.js +++ b/examples/science-writer/app.js @@ -6,7 +6,7 @@ substanceGlobals.DEBUG_RENDERING = true; var Scientist = require('../../packages/scientist/Scientist'); var ScientistConfigurator = require('../../packages/scientist/ScientistConfigurator'); var JATSEditorPackage = require('./package'); -var configurator = new ScientistConfigurator(JATSEditorPackage); +var configurator = new ScientistConfigurator().import(JATSEditorPackage); window.onload = function() { window.app = Scientist.static.mount({ diff --git a/packages/author/Author.js b/packages/author/Author.js index da72f4aeb..ee397b388 100644 --- a/packages/author/Author.js +++ b/packages/author/Author.js @@ -78,7 +78,7 @@ Author.Prototype = function() { }; this._getExporter = function() { - this.props.configurator.createExporter('jats'); + return this.props.configurator.createExporter('jats'); }; this._getTOCProvider = function() { diff --git a/packages/author/AuthorConfigurator.js b/packages/author/AuthorConfigurator.js deleted file mode 100644 index 6ce859eb3..000000000 --- a/packages/author/AuthorConfigurator.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; -var Configurator = require('substance/util/Configurator'); - -function AuthorConfigurator() { - AuthorConfigurator.super.apply(this, arguments); -} - -Configurator.extend(AuthorConfigurator); - -module.exports = AuthorConfigurator; \ No newline at end of file diff --git a/packages/author/AuthorExporter.js b/packages/author/AuthorExporter.js index 03ac78f1f..dc29778ee 100644 --- a/packages/author/AuthorExporter.js +++ b/packages/author/AuthorExporter.js @@ -13,7 +13,7 @@ AuthorExporter.Prototype = function() { this.exportDocument = function(doc) { var trafo = new JATSTransformer(); doc = trafo.toJATS(doc); - return _super.exportDocument.exportDocument.call(this, doc); + return _super.exportDocument.call(this, doc); }; }; diff --git a/packages/jats/JATSConfigurator.js b/packages/jats/JATSConfigurator.js deleted file mode 100644 index 82de56b94..000000000 --- a/packages/jats/JATSConfigurator.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; - -/* Used only by test suite to test JATS converter functionality. */ - -var Configurator = require('substance/util/Configurator'); - -function JATSConfigurator() { - JATSConfigurator.super.apply(this, arguments); -} - -Configurator.extend(JATSConfigurator); - -module.exports = JATSConfigurator; \ No newline at end of file diff --git a/packages/publisher/PublisherConfigurator.js b/packages/publisher/PublisherConfigurator.js deleted file mode 100644 index aa12ed87e..000000000 --- a/packages/publisher/PublisherConfigurator.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -var Configurator = require('substance/util/Configurator'); - -function PublisherConfigurator() { - PublisherConfigurator.super.apply(this, arguments); -} - -Configurator.extend(PublisherConfigurator); - -module.exports = PublisherConfigurator; \ No newline at end of file diff --git a/packages/scientist/ScientistConfigurator.js b/packages/scientist/ScientistConfigurator.js index ee00675bb..59bb73ac5 100644 --- a/packages/scientist/ScientistConfigurator.js +++ b/packages/scientist/ScientistConfigurator.js @@ -10,6 +10,10 @@ var uniq = require('lodash/uniq'); */ function ScientistConfigurator() { ScientistConfigurator.super.apply(this, arguments); + + // Extend config + this.config.configurators = {}; + this.config.XMLStoreClass = null; } ScientistConfigurator.Prototype = function() { @@ -19,16 +23,10 @@ ScientistConfigurator.Prototype = function() { receive their own configurator) */ this.addConfigurator = function(name, configurator) { - if (!this.config.configurators) { - this.config.configurators = {}; - } this.config.configurators[name] = configurator; }; this.getConfigurator = function(name) { - if (!this.config.configurators) { - return undefined; - } return this.config.configurators[name]; }; diff --git a/packages/scientist/package.js b/packages/scientist/package.js index 6089d8cf2..e5efabdba 100644 --- a/packages/scientist/package.js +++ b/packages/scientist/package.js @@ -1,15 +1,15 @@ 'use strict'; +var ProseEditorConfigurator = require('substance/packages/prose-editor/ProseEditorConfigurator'); + var AuthorPackage = require('../author/package'); -var AuthorConfigurator = require('../author/AuthorConfigurator'); var PublisherPackage = require('../publisher/package'); -var PublisherConfigurator = require('../publisher/PublisherConfigurator'); module.exports = { name: 'scientist', configure: function(config) { // Default configuration for available scientist modes - config.addConfigurator('author', new AuthorConfigurator(AuthorPackage)); - config.addConfigurator('publisher', new PublisherConfigurator(PublisherPackage)); + config.addConfigurator('author', new ProseEditorConfigurator().import(AuthorPackage)); + config.addConfigurator('publisher', new ProseEditorConfigurator().import(PublisherPackage)); } }; diff --git a/test/jats/createJATSConfigurator.js b/test/jats/createJATSConfigurator.js index 3833fb74d..7e0ea70d4 100644 --- a/test/jats/createJATSConfigurator.js +++ b/test/jats/createJATSConfigurator.js @@ -1,6 +1,6 @@ 'use strict'; -var Configurator = require('../../packages/jats/JATSConfigurator'); +var Configurator = require('substance/util/Configurator'); var JATSPackage = require('../../packages/jats/package'); var InlineWrapperPackage = require('../../packages/inline-wrapper/InlineWrapperPackage'); var UnsupportedNodePackage = require('../../packages/unsupported/UnsupportedNodePackage'); From c1591c93c93c99d0e5ded04b1c6889b49800c30c Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 8 Jul 2016 16:53:21 +0200 Subject: [PATCH 017/167] Use relative paths for links to files. --- CONTRIBUTING.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 31a7fde72..fc07d1e32 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Implement a new JATS element -Each JATS element is realized as a [package](https://github.com/substance/scientist/tree/devel/packages/jats/caption), containing a node definition, a converter and a component for rendering / editing. +Each JATS element is realized as a [package](packages/jats/caption), containing a node definition, a converter and a component for rendering / editing. ## Choose the right node type @@ -46,22 +46,22 @@ Example elements: ``, `` Use the following examples as a reference implementation. -- [Paragraph](https://github.com/substance/scientist/blob/devel/packages/jats/paragraph/Paragraph.js) (Text Node) -- [ExtLink](https://github.com/substance/scientist/blob/devel/packages/jats/ext-link/ExtLink.js) (Annotation Node) -- [XRef](https://github.com/substance/scientist/blob/devel/packages/jats/xref/XRef.js) (Inline Node) -- [Body](https://github.com/substance/scientist/blob/devel/packages/jats/body/Body.js) (Container Node) -- [Figure](https://github.com/substance/scientist/blob/devel/packages/jats/figure/Figure.js) (Document Node) +- [Paragraph](packages/jats/paragraph/Paragraph.js) (Text Node) +- [ExtLink](packages/jats/ext-link/ExtLink.js) (Annotation Node) +- [XRef](packages/jats/xref/XRef.js) (Inline Node) +- [Body](packages/jats/body/Body.js) (Container Node) +- [Figure](packages/jats/figure/Figure.js) (Document Node) ## Define a converter A converter is need to map from JATS XML to Substance document nodes. -- [Paragraph Converter](https://github.com/substance/scientist/blob/devel/packages/jats/paragraph/ParagraphConverter.js) (Text Node) -- [ExtLink Converter](https://github.com/substance/scientist/blob/devel/packages/jats/ext-link/ExtLinkConverter.js) (Annotation Node) -- [XRef Converter](https://github.com/substance/scientist/blob/devel/packages/jats/xref/XRefConverter.js) (Inline Node) -- [Body Converter](https://github.com/substance/scientist/blob/devel/packages/jats/body/BodyConverter.js) (Container Node) -- [Figure Converter](https://github.com/substance/scientist/blob/devel/packages/jats/figure/FigureConverter.js) (Document Node) +- [Paragraph Converter](packages/jats/paragraph/ParagraphConverter.js) (Text Node) +- [ExtLink Converter](packages/jats/ext-link/ExtLinkConverter.js) (Annotation Node) +- [XRef Converter](packages/jats/xref/XRefConverter.js) (Inline Node) +- [Body Converter](packages/jats/body/BodyConverter.js) (Container Node) +- [Figure Converter](packages/jats/figure/FigureConverter.js) (Document Node) ## Write a converter test @@ -69,19 +69,19 @@ A converter is need to map from JATS XML to Substance document nodes. It's important you test your converter throughly. The following examples can be used as a reference. -- [Paragraph Test](https://github.com/substance/scientist/blob/devel/test/jats/paragraph.test.js) (Text Node) -- [ExtLink Test](https://github.com/substance/scientist/blob/devel/test/jats/ext-link.test.js) (Annotation Node) -- [XRef Test](https://github.com/substance/scientist/blob/devel/test/jats/xref-link.test.js) (Inline Node) -- [Body Test](https://github.com/substance/scientist/blob/devel/test/jats/body-link.test.js) (Container Node) -- [Figure Test](https://github.com/substance/scientist/blob/devel/test/jats/figure.test.js) (Document Node) +- [Paragraph Test](test/jats/paragraph.test.js) (Text Node) +- [ExtLink Test](test/jats/ext-link.test.js) (Annotation Node) +- [XRef Test](test/jats/xref-link.test.js) (Inline Node) +- [Body Test](test/jats/body-link.test.js) (Container Node) +- [Figure Test](test/jats/figure.test.js) (Document Node) ## Defining a component In order to make the content editable, you have to define components for each JATS element. -- [Paragraph Component](https://github.com/substance/scientist/blob/devel/packages/jats/paragraph/Paragraph.js) (Text Node) -- [ExtLink Component](https://github.com/substance/scientist/blob/devel/packages/jats/ext-link/ExtLink.js) (Annotation Node) -- [XRef Component](https://github.com/substance/scientist/blob/devel/packages/jats/xref/XRef.js) (Inline Node) -- [Body Component](https://github.com/substance/scientist/blob/devel/packages/jats/body/Body.js) (Container Node) -- [Figure Component](https://github.com/substance/scientist/blob/devel/packages/jats/figure/Figure.js) (Document Node) +- [Paragraph Component](packages/jats/paragraph/Paragraph.js) (Text Node) +- [ExtLink Component](packages/jats/ext-link/ExtLink.js) (Annotation Node) +- [XRef Component](packages/jats/xref/XRef.js) (Inline Node) +- [Body Component](packages/jats/body/Body.js) (Container Node) +- [Figure Component](packages/jats/figure/Figure.js) (Document Node) From 2d9b202b2777b5f14dcdf15f3627bf29f20be7a5 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 8 Jul 2016 16:54:48 +0200 Subject: [PATCH 018/167] Fix broken links. --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fc07d1e32..c2bdd5e5b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,8 +71,8 @@ It's important you test your converter throughly. The following examples can be - [Paragraph Test](test/jats/paragraph.test.js) (Text Node) - [ExtLink Test](test/jats/ext-link.test.js) (Annotation Node) -- [XRef Test](test/jats/xref-link.test.js) (Inline Node) -- [Body Test](test/jats/body-link.test.js) (Container Node) +- [XRef Test](test/jats/xref.test.js) (Inline Node) +- [Body Test](test/jats/body.test.js) (Container Node) - [Figure Test](test/jats/figure.test.js) (Document Node) From a0647e837246e2971b7792884bcfc32ac2f8498c Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 8 Jul 2016 16:56:19 +0200 Subject: [PATCH 019/167] Fixes for contribution guidelines. --- CONTRIBUTING.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c2bdd5e5b..11c2dcaf8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -55,7 +55,7 @@ Use the following examples as a reference implementation. ## Define a converter -A converter is need to map from JATS XML to Substance document nodes. +A converter is needed to map from JATS XML to Substance document nodes. - [Paragraph Converter](packages/jats/paragraph/ParagraphConverter.js) (Text Node) - [ExtLink Converter](packages/jats/ext-link/ExtLinkConverter.js) (Annotation Node) @@ -66,8 +66,7 @@ A converter is need to map from JATS XML to Substance document nodes. ## Write a converter test -It's important you test your converter throughly. The following examples can be used as a reference. - +It's important you test your converter throughly, otherwise content could be lost. The following examples can be used as a reference. - [Paragraph Test](test/jats/paragraph.test.js) (Text Node) - [ExtLink Test](test/jats/ext-link.test.js) (Annotation Node) From 1d9bb9ef34cd966b7e24af2af04d0351bddffe66 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 8 Jul 2016 18:51:45 +0200 Subject: [PATCH 020/167] README fix. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index bf945e20d..b70bba6f9 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,6 @@ MyXMLStore.Prototype = function() { request('GET', 'https://myserver.com/documents/'+documentId+'.xml', null, cb); }; - // TODO make functional this.writeXML = function(documentId, xml, cb) { var data = {content: xml}; var url = 'https://myserver.com/documents/'+documentId+'.xml' From 4d4735633846085230f3b40755e19e1fe85d9d69 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 12 Jul 2016 21:54:20 +0200 Subject: [PATCH 021/167] Add support for article-meta element. --- packages/jats/JATS.js | 66 +++++----- packages/jats/article-meta/ArticleMeta.js | 18 +++ .../jats/article-meta/ArticleMetaComponent.js | 38 ++++++ .../jats/article-meta/ArticleMetaConverter.js | 122 ++++++++++++++++++ packages/jats/article-meta/package.js | 14 ++ packages/jats/front/FrontComponent.js | 20 +-- packages/jats/package.js | 1 + 7 files changed, 238 insertions(+), 41 deletions(-) create mode 100644 packages/jats/article-meta/ArticleMeta.js create mode 100644 packages/jats/article-meta/ArticleMetaComponent.js create mode 100644 packages/jats/article-meta/ArticleMetaConverter.js create mode 100644 packages/jats/article-meta/package.js diff --git a/packages/jats/JATS.js b/packages/jats/JATS.js index df5778e0f..465086c5b 100644 --- a/packages/jats/JATS.js +++ b/packages/jats/JATS.js @@ -4,39 +4,43 @@ // everything here is taken from JATS 1.1 green http://jats.nlm.nih.gov/archiving/tag-library/1.1/ var JATS = { - ACCESS: ["alt-text","long-desc"], - ADDRESS_LINK: ["email","ext-link","uri"], - APPEARANCE: ["hr"], - BLOCK_MATH: ["disp-formula", "disp-formula-group"], - BLOCK_DISPLAY: ["address","alternatives","array","boxed-text", - "chem-struct-wrap", "code","fig","fig-group","graphic","media", - "preformat","supplementary-material", "table-wrap","table-wrap-group"], - BREAK: ["break"], - CHEM_STRUCT: ["chem-struct-wrap"], - CITATION: ["citation-alternatives","element-citation","mixed-citation","nlm-citation"], - DISLAY_BACK_MATTER: ["attrib","permissions"], - EMPHASIS: ["bold","fixed-case","italic","monospace","overline", - "overline-start","overline-end","roman","sans-serif","sc","strike", - "underline","underline-start","underline-end","ruby"], - FUNDING: ["award-id","funding-source","open-access"], - INLINE_DISPLAY: ["alternatives", "inline-graphic", "private-char"], - INLINE_MATH: ["chem-struct","inline-formula"], - INTABLE_PARA: ["disp-quote","speech", "statement","verse-group"], - JUST_PARA: ["p"], - JUST_TABLE: ["table-wrap"], - LIST: ["def-list","list"], - MATH: ["tex-math","mml:math"], - NOTHING_BUT_PARA: ["p"], - PHRASE: ["abbrev","milestone-end","milestone-start","named-content","styled-content"], - RELATED_ARTICLE: ["related-article","related-object"], - REST_OF_PARA: ["ack","disp-quote","speech","statement","verse-group"], - SIMPLE_DISPLAY: ["alternatives","array","code","graphic","media","preformat"], - SIMPLE_LINK: ["fn","target","xref"], - SUBSUP: ["sub","sup"], - X: ["x"], + ABSTRACT: ['abstract'], + ACCESS: ['alt-text','long-desc'], + ADDRESS_LINK: ['email','ext-link','uri'], + AFF_ALTERNATIVES: ['aff', 'aff-alternatives'], + APPEARANCE: ['hr'], + BLOCK_MATH: ['disp-formula', 'disp-formula-group'], + BLOCK_DISPLAY: ['address','alternatives','array','boxed-text', + 'chem-struct-wrap', 'code','fig','fig-group','graphic','media', + 'preformat','supplementary-material', 'table-wrap','table-wrap-group'], + BREAK: ['break'], + CHEM_STRUCT: ['chem-struct-wrap'], + CITATION: ['citation-alternatives','element-citation','mixed-citation','nlm-citation'], + CONTRIB_GROUP: ['contrib-group'], + DISLAY_BACK_MATTER: ['attrib','permissions'], + EMPHASIS: ['bold','fixed-case','italic','monospace','overline', + 'overline-start','overline-end','roman','sans-serif','sc','strike', + 'underline','underline-start','underline-end','ruby'], + FUNDING: ['award-id','funding-source','open-access'], + INLINE_DISPLAY: ['alternatives', 'inline-graphic', 'private-char'], + INLINE_MATH: ['chem-struct','inline-formula'], + INTABLE_PARA: ['disp-quote','speech', 'statement','verse-group'], + JUST_PARA: ['p'], + JUST_TABLE: ['table-wrap'], + KWD_GROUP: ['kwd-group'], + LIST: ['def-list','list'], + MATH: ['tex-math','mml:math'], + NOTHING_BUT_PARA: ['p'], + PHRASE: ['abbrev','milestone-end','milestone-start','named-content','styled-content'], + RELATED_ARTICLE: ['related-article','related-object'], + REST_OF_PARA: ['ack','disp-quote','speech','statement','verse-group'], + SIMPLE_DISPLAY: ['alternatives','array','code','graphic','media','preformat'], + SIMPLE_LINK: ['fn','target','xref'], + SUBSUP: ['sub','sup'], + X: ['x'], }; -JATS.ARTICLE_LINK = ["inline-supplementary-material"].concat(JATS.RELATED_ARTICLE); +JATS.ARTICLE_LINK = ['inline-supplementary-material'].concat(JATS.RELATED_ARTICLE); JATS.ALL_PHRASE = JATS.ADDRESS_LINK .concat(JATS.ARTICLE_LINK) .concat(JATS.APPEARANCE) diff --git a/packages/jats/article-meta/ArticleMeta.js b/packages/jats/article-meta/ArticleMeta.js new file mode 100644 index 000000000..e2e8b3d16 --- /dev/null +++ b/packages/jats/article-meta/ArticleMeta.js @@ -0,0 +1,18 @@ +'use strict'; + +var DocumentNode = require('substance/model/DocumentNode'); + +function ArticleMeta() { + ArticleMeta.super.apply(this, arguments); +} + +DocumentNode.extend(ArticleMeta); + +ArticleMeta.static.name = 'article-meta'; + +ArticleMeta.static.defineSchema({ + attributes: { type: 'object', default: {} }, + nodes: { type: ['id'], default: [] } +}); + +module.exports = ArticleMeta; diff --git a/packages/jats/article-meta/ArticleMetaComponent.js b/packages/jats/article-meta/ArticleMetaComponent.js new file mode 100644 index 000000000..a074be6cd --- /dev/null +++ b/packages/jats/article-meta/ArticleMetaComponent.js @@ -0,0 +1,38 @@ +'use strict'; + +var Component = require('substance/ui/Component'); +var renderNodeComponent = require('../../../util/renderNodeComponent'); + + +function ArticleMetaComponent() { + Component.apply(this, arguments); +} + +ArticleMetaComponent.Prototype = function() { + + this.render = function($$) { + var node = this.props.node; + var doc = node.getDocument(); + + var el = $$('div') + .addClass('sc-article-meta') + .attr('data-id', this.props.node.id); + + var children = node.nodes; + children.forEach(function(nodeId) { + var childNode = doc.get(nodeId); + if (childNode.type !== 'unsupported') { + el.append( + renderNodeComponent(this, $$, childNode, { + disabled: this.props.disabled + }) + ); + } + }.bind(this)); + return el; + }; +}; + +Component.extend(ArticleMetaComponent); + +module.exports = ArticleMetaComponent; \ No newline at end of file diff --git a/packages/jats/article-meta/ArticleMetaConverter.js b/packages/jats/article-meta/ArticleMetaConverter.js new file mode 100644 index 000000000..a434ed039 --- /dev/null +++ b/packages/jats/article-meta/ArticleMetaConverter.js @@ -0,0 +1,122 @@ +'use strict'; + +var XMLIterator = require('../../../util/XMLIterator'); + +var JATS = require('../JATS'); + +module.exports = { + + type: 'article-meta', + tagName: 'article-meta', + + /* + Attributes + id Document Internal Identifier + xml:base Base + Content + (article-id*, article-categories?, + title-group?, + (%contrib-group.class; | + %aff-alternatives.class; | %x.class;)*, + author-notes?, pub-date*, + volume*, volume-id*, volume-series?, + issue*, issue-id*, issue-title*, + issue-sponsor*, issue-part?, + volume-issue-group*, isbn*, + supplement?, + ( ( (fpage, lpage?)?, page-range?) | + elocation-id )?, + (%address-link.class; | product | + supplementary-material)*, + history?, permissions?, self-uri*, + (%related-article.class;)*, + (%abstract.class;)*, trans-abstract*, + (%kwd-group.class;)*, funding-group*, + conference*, counts?, custom-meta-group?) + */ + import: function(el, node, converter) { + node.id = 'article-meta'; // there is only one element + var iterator = new XMLIterator(el.getChildren()); + var elements; + + iterator.manyOf(['article-id'], function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + iterator.optional('article-categories', function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + iterator.optional('title-group', function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + // %contrib-group.class; | %aff-alternatives.class; | %x.class; + elements = JATS.CONTRIB_GROUP + .concat(JATS.AFF_ALTERNATIVES) + .concat(JATS.X); + iterator.manyOf(elements, function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + iterator.optional('author-notes', function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + // pub-date*, volume*, volume-id* + iterator.manyOf(['pub-date', 'volume', 'volume-id'], function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + iterator.optional('volume-series', function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + iterator.manyOf(['issue', 'issue-id', 'issue-title', 'issue-sponsor'], function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + iterator.optional('issue-part', function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + iterator.manyOf(['volume-issue-group', 'isbn'], function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + iterator.optional('supplement', function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + // ( ( (fpage, lpage?)?, page-range?) | + // elocation-id )?, + // + // TODO: XMLIterator can't handle such complex optionals atm + iterator.manyOf(['fpage', 'lpage', 'page-range', 'elocation-id'], function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + // (%address-link.class; | product | + // supplementary-material)*, + elements = JATS.ADDRESS_LINK.concat(['product', 'supplementary-material']); + iterator.manyOf(elements, function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + iterator.optional('history', function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + iterator.optional('permissions', function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + elements = ['self-uri'] + .concat(JATS.RELATED_ARTICLE) + .concat(JATS.ABSTRACT) + .concat(['trans-abstract']) + .concat(JATS.KWD_GROUP) + .concat(['funding-group', 'conference']) + iterator.manyOf(elements, function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + iterator.optional('counts', function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + iterator.optional('custom-meta-group', function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML); + }, + + export: function(node, el, converter) { + el.append(converter.convertNodes(node.nodes)); + } +}; + + diff --git a/packages/jats/article-meta/package.js b/packages/jats/article-meta/package.js new file mode 100644 index 000000000..a51b72ac8 --- /dev/null +++ b/packages/jats/article-meta/package.js @@ -0,0 +1,14 @@ +'use strict'; + +var ArticleMeta = require('./ArticleMeta'); +var ArticleMetaConverter = require('./ArticleMetaConverter'); +var ArticleMetaComponent = require('./ArticleMetaComponent'); + +module.exports = { + name: 'article-meta', + configure: function(config) { + config.addNode(ArticleMeta); + config.addConverter('jats', ArticleMetaConverter); + config.addComponent(ArticleMeta.static.name, ArticleMetaComponent); + } +}; \ No newline at end of file diff --git a/packages/jats/front/FrontComponent.js b/packages/jats/front/FrontComponent.js index 1f2195b6c..efe65818e 100644 --- a/packages/jats/front/FrontComponent.js +++ b/packages/jats/front/FrontComponent.js @@ -2,6 +2,7 @@ var Component = require('substance/ui/Component'); var ContainerEditor = require('substance/ui/ContainerEditor'); +var renderNodeComponent = require('../../../util/renderNodeComponent'); function FrontComponent() { Component.apply(this, arguments); @@ -11,22 +12,21 @@ FrontComponent.Prototype = function() { this.render = function($$) { var node = this.props.node; + var doc = node.getDocument(); var configurator = this.props.configurator; var el = $$('div') .addClass('sc-front') .attr('data-id', this.props.node.id); - if (node.nodes.length > 0) { - el.append( - $$(ContainerEditor, { - disabled: this.props.disabled, - node: node, - commands: configurator.getSurfaceCommandNames(), - textTypes: configurator.getTextTypes() - }).ref('front') - ); - } + // Render articlemeta + var articleMeta = doc.get(node.articleMeta); + + el.append( + renderNodeComponent(this, $$, articleMeta, { + disabled: this.props.disabled + }) + ); return el; }; diff --git a/packages/jats/package.js b/packages/jats/package.js index 14beb3af8..89c7e58d6 100644 --- a/packages/jats/package.js +++ b/packages/jats/package.js @@ -7,6 +7,7 @@ module.exports = { name: 'jats', configure: function(config) { config.import(require('./article/package')); + config.import(require('./article-meta/package')); config.import(require('./back/package')); config.import(require('./body/package')); config.import(require('./bold/package')); From 7ecfd852fa54413197915c507f9e34ee0c0b8379 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 13 Jul 2016 19:14:47 +0200 Subject: [PATCH 022/167] Add title-group + article-title elements. --- packages/jats/JATS.js | 1 + .../jats/article-meta/ArticleMetaConverter.js | 2 +- packages/jats/article-title/ArticleTitle.js | 17 +++++++ .../article-title/ArticleTitleComponent.js | 23 ++++++++++ .../article-title/ArticleTitleConverter.js | 8 ++++ .../jats/article-title/_article-title.scss | 6 +++ packages/jats/article-title/package.js | 15 ++++++ packages/jats/front/FrontComponent.js | 2 - packages/jats/package.js | 2 + packages/jats/title-group/TitleGroup.js | 25 ++++++++++ .../jats/title-group/TitleGroupComponent.js | 37 +++++++++++++++ .../jats/title-group/TitleGroupConverter.js | 46 +++++++++++++++++++ packages/jats/title-group/package.js | 14 ++++++ 13 files changed, 195 insertions(+), 3 deletions(-) create mode 100644 packages/jats/article-title/ArticleTitle.js create mode 100644 packages/jats/article-title/ArticleTitleComponent.js create mode 100644 packages/jats/article-title/ArticleTitleConverter.js create mode 100644 packages/jats/article-title/_article-title.scss create mode 100644 packages/jats/article-title/package.js create mode 100644 packages/jats/title-group/TitleGroup.js create mode 100644 packages/jats/title-group/TitleGroupComponent.js create mode 100644 packages/jats/title-group/TitleGroupConverter.js create mode 100644 packages/jats/title-group/package.js diff --git a/packages/jats/JATS.js b/packages/jats/JATS.js index 465086c5b..4cddb461c 100644 --- a/packages/jats/JATS.js +++ b/packages/jats/JATS.js @@ -37,6 +37,7 @@ var JATS = { SIMPLE_DISPLAY: ['alternatives','array','code','graphic','media','preformat'], SIMPLE_LINK: ['fn','target','xref'], SUBSUP: ['sub','sup'], + TITLE_GROUP: ['article-title', 'subtitle', 'trans-title-group', 'alt-title', 'fn-group'], X: ['x'], }; diff --git a/packages/jats/article-meta/ArticleMetaConverter.js b/packages/jats/article-meta/ArticleMetaConverter.js index a434ed039..99b5c1ad3 100644 --- a/packages/jats/article-meta/ArticleMetaConverter.js +++ b/packages/jats/article-meta/ArticleMetaConverter.js @@ -101,7 +101,7 @@ module.exports = { .concat(JATS.ABSTRACT) .concat(['trans-abstract']) .concat(JATS.KWD_GROUP) - .concat(['funding-group', 'conference']) + .concat(['funding-group', 'conference']); iterator.manyOf(elements, function(child) { node.nodes.push(converter.convertElement(child).id); }); diff --git a/packages/jats/article-title/ArticleTitle.js b/packages/jats/article-title/ArticleTitle.js new file mode 100644 index 000000000..c5873939b --- /dev/null +++ b/packages/jats/article-title/ArticleTitle.js @@ -0,0 +1,17 @@ +'use strict'; + +var TextNode = require('substance/model/TextNode'); + +function ArticleTitle() { + ArticleTitle.super.apply(this, arguments); +} + +TextNode.extend(ArticleTitle); + +ArticleTitle.static.name = 'article-title'; + +ArticleTitle.static.defineSchema({ + attributes: { type: 'object', default: {} }, +}); + +module.exports = ArticleTitle; \ No newline at end of file diff --git a/packages/jats/article-title/ArticleTitleComponent.js b/packages/jats/article-title/ArticleTitleComponent.js new file mode 100644 index 000000000..37507bcae --- /dev/null +++ b/packages/jats/article-title/ArticleTitleComponent.js @@ -0,0 +1,23 @@ +'use strict'; + +var TitleComponent = require('../title/TitleComponent'); + +function ArticleTitleComponent() { + ArticleTitleComponent.super.apply(this, arguments); + +} + +ArticleTitleComponent.Prototype = function() { + var _super = ArticleTitleComponent.super.prototype; + + this.render = function() { + var el = _super.render.apply(this, arguments); + el.removeClass('sc-title'); + el.addClass('sc-article-title'); + return el; + }; +}; + +TitleComponent.extend(ArticleTitleComponent); + +module.exports = ArticleTitleComponent; \ No newline at end of file diff --git a/packages/jats/article-title/ArticleTitleConverter.js b/packages/jats/article-title/ArticleTitleConverter.js new file mode 100644 index 000000000..2dcaedea9 --- /dev/null +++ b/packages/jats/article-title/ArticleTitleConverter.js @@ -0,0 +1,8 @@ +'use strict'; + +var TextNodeConverter = require('../TextNodeConverter'); + +module.exports = TextNodeConverter.extend({ + type: 'article-title', + tagName: 'article-title', +}); diff --git a/packages/jats/article-title/_article-title.scss b/packages/jats/article-title/_article-title.scss new file mode 100644 index 000000000..ca61df7c3 --- /dev/null +++ b/packages/jats/article-title/_article-title.scss @@ -0,0 +1,6 @@ + .sc-article-title { + padding-bottom: $default-padding; + font-weight: $strong-font-weight; + letter-spacing: $heading-letterspacing; + font-size: $title-font-size; + } \ No newline at end of file diff --git a/packages/jats/article-title/package.js b/packages/jats/article-title/package.js new file mode 100644 index 000000000..4b7938fb6 --- /dev/null +++ b/packages/jats/article-title/package.js @@ -0,0 +1,15 @@ +'use strict'; + +var ArticleTitle = require('./ArticleTitle'); +var ArticleTitleConverter = require('./ArticleTitleConverter'); +var ArticleTitleComponent = require('./ArticleTitleComponent'); + +module.exports = { + name: 'article-title', + configure: function(config) { + config.addNode(ArticleTitle); + config.addConverter('jats', ArticleTitleConverter); + config.addComponent(ArticleTitle.static.name, ArticleTitleComponent); + config.addStyle(__dirname, '_article-title.scss'); + } +}; diff --git a/packages/jats/front/FrontComponent.js b/packages/jats/front/FrontComponent.js index efe65818e..ab121b895 100644 --- a/packages/jats/front/FrontComponent.js +++ b/packages/jats/front/FrontComponent.js @@ -1,7 +1,6 @@ 'use strict'; var Component = require('substance/ui/Component'); -var ContainerEditor = require('substance/ui/ContainerEditor'); var renderNodeComponent = require('../../../util/renderNodeComponent'); function FrontComponent() { @@ -13,7 +12,6 @@ FrontComponent.Prototype = function() { this.render = function($$) { var node = this.props.node; var doc = node.getDocument(); - var configurator = this.props.configurator; var el = $$('div') .addClass('sc-front') diff --git a/packages/jats/package.js b/packages/jats/package.js index 89c7e58d6..d5b56cc58 100644 --- a/packages/jats/package.js +++ b/packages/jats/package.js @@ -8,6 +8,8 @@ module.exports = { configure: function(config) { config.import(require('./article/package')); config.import(require('./article-meta/package')); + config.import(require('./title-group/package')); + config.import(require('./article-title/package')); config.import(require('./back/package')); config.import(require('./body/package')); config.import(require('./bold/package')); diff --git a/packages/jats/title-group/TitleGroup.js b/packages/jats/title-group/TitleGroup.js new file mode 100644 index 000000000..e7e6a8498 --- /dev/null +++ b/packages/jats/title-group/TitleGroup.js @@ -0,0 +1,25 @@ +'use strict'; + +var Container = require('substance/model/Container'); + +function TitleGroup() { + TitleGroup.super.apply(this, arguments); +} + +Container.extend(TitleGroup); + +TitleGroup.static.name = "title-group"; + +/* + Content + ( + article-title, subtitle*, trans-title-group*, alt-title*, fn-group? + ) +*/ +TitleGroup.static.defineSchema({ + attributes: { type: 'object', default: {} }, + nodes: { type: ['id'], default: [] } +}); + + +module.exports = TitleGroup; diff --git a/packages/jats/title-group/TitleGroupComponent.js b/packages/jats/title-group/TitleGroupComponent.js new file mode 100644 index 000000000..ba6eed6eb --- /dev/null +++ b/packages/jats/title-group/TitleGroupComponent.js @@ -0,0 +1,37 @@ +'use strict'; + +var Component = require('substance/ui/Component'); +var renderNodeComponent = require('../../../util/renderNodeComponent'); + +function TitleGroupComponent() { + Component.apply(this, arguments); +} + +TitleGroupComponent.Prototype = function() { + + this.render = function($$) { + var node = this.props.node; + var doc = node.getDocument(); + + var el = $$('div') + .addClass('sc-title-group') + .attr('data-id', this.props.node.id); + + var children = node.nodes; + children.forEach(function(nodeId) { + var childNode = doc.get(nodeId); + if (childNode.type !== 'unsupported') { + el.append( + renderNodeComponent(this, $$, childNode, { + disabled: this.props.disabled + }) + ); + } + }.bind(this)); + return el; + }; +}; + +Component.extend(TitleGroupComponent); + +module.exports = TitleGroupComponent; \ No newline at end of file diff --git a/packages/jats/title-group/TitleGroupConverter.js b/packages/jats/title-group/TitleGroupConverter.js new file mode 100644 index 000000000..7cc42edae --- /dev/null +++ b/packages/jats/title-group/TitleGroupConverter.js @@ -0,0 +1,46 @@ +'use strict'; + +var JATS = require('../JATS'); +var XMLIterator = require('../../../util/XMLIterator'); + +module.exports = { + + type: 'title-group', + tagName: 'title-group', + + /* + Attributes + id Document Internal Identifier + specific-use Specific Use + xml:base Base + + Content + %title-group-model; + */ + + import: function(el, node, converter) { + node.id = 'title-group'; // there is only be one body element + node.xmlAttributes = el.getAttributes(); + + var children = el.getChildren(); + var iterator = new XMLIterator(children); + + // TODO: This is not strict enough. We want to check for the + // element cardinalities: + // (article-title, subtitle*, trans-title-group*, alt-title*, fn-group?) + // We may want to use a helper for this (see #64) + iterator.manyOf(JATS.TITLE_GROUP, function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML); + }, + + export: function(node, el, converter) { + el.attr(node.xmlAttributes); + el.append(converter.convertNodes(node.nodes)); + if (node.sigBlock) { + el.append(converter.convertNode(node.sigBlock)); + } + } + +}; diff --git a/packages/jats/title-group/package.js b/packages/jats/title-group/package.js new file mode 100644 index 000000000..f480b9eb3 --- /dev/null +++ b/packages/jats/title-group/package.js @@ -0,0 +1,14 @@ +'use strict'; + +var TitleGroup = require('./TitleGroup'); +var TitleGroupConverter = require('./TitleGroupConverter'); +var TitleGroupComponent = require('./TitleGroupComponent'); + +module.exports = { + name: 'title-group', + configure: function(config) { + config.addNode(TitleGroup); + config.addConverter('jats', TitleGroupConverter); + config.addComponent(TitleGroup.static.name, TitleGroupComponent); + } +}; From e7c00b43ff785d485e4b61312dbba8282da8e5ba Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 13 Jul 2016 22:29:29 +0200 Subject: [PATCH 023/167] Add support for contrib-group and contrib elements. --- packages/jats/JATS.js | 3 ++ packages/jats/contrib-group/ContribGroup.js | 19 ++++++++ .../contrib-group/ContribGroupComponent.js | 37 +++++++++++++++ .../contrib-group/ContribGroupConverter.js | 33 +++++++++++++ .../jats/contrib-group/_contrib-group.scss | 8 ++++ packages/jats/contrib-group/package.js | 15 ++++++ packages/jats/contrib/Contrib.js | 27 +++++++++++ packages/jats/contrib/ContribComponent.js | 20 ++++++++ packages/jats/contrib/ContribConverter.js | 18 +++++++ packages/jats/contrib/contribToHTML.js | 47 +++++++++++++++++++ packages/jats/contrib/package.js | 14 ++++++ packages/jats/package.js | 2 + 12 files changed, 243 insertions(+) create mode 100644 packages/jats/contrib-group/ContribGroup.js create mode 100644 packages/jats/contrib-group/ContribGroupComponent.js create mode 100644 packages/jats/contrib-group/ContribGroupConverter.js create mode 100644 packages/jats/contrib-group/_contrib-group.scss create mode 100644 packages/jats/contrib-group/package.js create mode 100644 packages/jats/contrib/Contrib.js create mode 100644 packages/jats/contrib/ContribComponent.js create mode 100644 packages/jats/contrib/ContribConverter.js create mode 100644 packages/jats/contrib/contribToHTML.js create mode 100644 packages/jats/contrib/package.js diff --git a/packages/jats/JATS.js b/packages/jats/JATS.js index 4cddb461c..62ce717f4 100644 --- a/packages/jats/JATS.js +++ b/packages/jats/JATS.js @@ -63,3 +63,6 @@ JATS.PARA_LEVEL = JATS.BLOCK_DISPLAY .concat(JATS.X); module.exports = JATS; + + + diff --git a/packages/jats/contrib-group/ContribGroup.js b/packages/jats/contrib-group/ContribGroup.js new file mode 100644 index 000000000..cad0923da --- /dev/null +++ b/packages/jats/contrib-group/ContribGroup.js @@ -0,0 +1,19 @@ +'use strict'; + +var Container = require('substance/model/Container'); + +function ContribGroup() { + ContribGroup.super.apply(this, arguments); +} + +Container.extend(ContribGroup); + +ContribGroup.static.name = "contrib-group"; + +ContribGroup.static.defineSchema({ + attributes: { type: 'object', default: {} }, + nodes: { type: ['id'], default: [] } +}); + + +module.exports = ContribGroup; diff --git a/packages/jats/contrib-group/ContribGroupComponent.js b/packages/jats/contrib-group/ContribGroupComponent.js new file mode 100644 index 000000000..7ba03acef --- /dev/null +++ b/packages/jats/contrib-group/ContribGroupComponent.js @@ -0,0 +1,37 @@ +'use strict'; + +var Component = require('substance/ui/Component'); +var renderNodeComponent = require('../../../util/renderNodeComponent'); + +function ContribGroupComponent() { + Component.apply(this, arguments); +} + +ContribGroupComponent.Prototype = function() { + + this.render = function($$) { + var node = this.props.node; + var doc = node.getDocument(); + + var el = $$('div') + .addClass('sc-contrib-group') + .attr('data-id', this.props.node.id); + + var children = node.nodes; + children.forEach(function(nodeId) { + var childNode = doc.get(nodeId); + if (childNode.type !== 'unsupported') { + el.append( + renderNodeComponent(this, $$, childNode, { + disabled: this.props.disabled + }) + ); + } + }.bind(this)); + return el; + }; +}; + +Component.extend(ContribGroupComponent); + +module.exports = ContribGroupComponent; \ No newline at end of file diff --git a/packages/jats/contrib-group/ContribGroupConverter.js b/packages/jats/contrib-group/ContribGroupConverter.js new file mode 100644 index 000000000..37024d22a --- /dev/null +++ b/packages/jats/contrib-group/ContribGroupConverter.js @@ -0,0 +1,33 @@ +'use strict'; + +var XMLIterator = require('../../../util/XMLIterator'); + +var CONTRIB_GROUP = ['contrib', 'address', 'aff', 'aff-alternatives', 'author-comment', 'bio', 'email', 'etal', 'ext-link', 'fn', 'on-behalf-of', 'role', 'uri', 'xref', 'x']; + +module.exports = { + + type: 'contrib-group', + tagName: 'contrib-group', + + import: function(el, node, converter) { + // node.id = 'contrib-group'; // there is only be one body element + node.xmlAttributes = el.getAttributes(); + + var children = el.getChildren(); + var iterator = new XMLIterator(children); + + iterator.oneOrMoreOf(CONTRIB_GROUP, function(child) { + node.nodes.push(converter.convertElement(child).id); + }); + if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML); + }, + + export: function(node, el, converter) { + el.attr(node.xmlAttributes); + el.append(converter.convertNodes(node.nodes)); + if (node.sigBlock) { + el.append(converter.convertNode(node.sigBlock)); + } + } + +}; diff --git a/packages/jats/contrib-group/_contrib-group.scss b/packages/jats/contrib-group/_contrib-group.scss new file mode 100644 index 000000000..cce896212 --- /dev/null +++ b/packages/jats/contrib-group/_contrib-group.scss @@ -0,0 +1,8 @@ +.sc-contrib-group { + overflow: auto; + + > * { + float: left; + margin-right: $default-padding; + } +} \ No newline at end of file diff --git a/packages/jats/contrib-group/package.js b/packages/jats/contrib-group/package.js new file mode 100644 index 000000000..5514ec304 --- /dev/null +++ b/packages/jats/contrib-group/package.js @@ -0,0 +1,15 @@ +'use strict'; + +var ContribGroup = require('./ContribGroup'); +var ContribGroupConverter = require('./ContribGroupConverter'); +var ContribGroupComponent = require('./ContribGroupComponent'); + +module.exports = { + name: 'contrib-group', + configure: function(config) { + config.addNode(ContribGroup); + config.addConverter('jats', ContribGroupConverter); + config.addComponent(ContribGroup.static.name, ContribGroupComponent); + config.addStyle(__dirname, '_contrib-group.scss'); + } +}; diff --git a/packages/jats/contrib/Contrib.js b/packages/jats/contrib/Contrib.js new file mode 100644 index 000000000..e332ea123 --- /dev/null +++ b/packages/jats/contrib/Contrib.js @@ -0,0 +1,27 @@ +'use strict'; + +var DocumentNode = require('substance/model/DocumentNode'); + +/* + ref + + One item in a bibliographic list. +*/ +function Contrib() { + Contrib.super.apply(this, arguments); +} + +DocumentNode.extend(Contrib); + +Contrib.static.name = 'contrib'; + +/* + Content + (label?, (citation-alternatives | element-citation | mixed-citation | nlm-citation | note | x)+) +*/ +Contrib.static.defineSchema({ + attributes: { type: 'object', default: {} }, + xmlContent: {type: 'string', default: ''} +}); + +module.exports = Contrib; diff --git a/packages/jats/contrib/ContribComponent.js b/packages/jats/contrib/ContribComponent.js new file mode 100644 index 000000000..395aaa1ee --- /dev/null +++ b/packages/jats/contrib/ContribComponent.js @@ -0,0 +1,20 @@ +'use strict'; + +var Component = require('substance/ui/Component'); +var contribToHTML = require('./contribToHTML'); + +function ContribComponent() { + ContribComponent.super.apply(this, arguments); +} + +ContribComponent.Prototype = function() { + this.render = function($$) { + var el = $$('div').addClass('sc-contrib'); + el.html(contribToHTML(this.props.node.xmlContent)); + return el; + }; +}; + +Component.extend(ContribComponent); + +module.exports = ContribComponent; diff --git a/packages/jats/contrib/ContribConverter.js b/packages/jats/contrib/ContribConverter.js new file mode 100644 index 000000000..c536b58fd --- /dev/null +++ b/packages/jats/contrib/ContribConverter.js @@ -0,0 +1,18 @@ +'use strict'; + +module.exports = { + + type: 'contrib', + tagName: 'contrib', + + /* + (label?, (citation-alternatives | element-citation | mixed-citation | nlm-citation | note | x)+) + */ + import: function(el, node, converter) { // eslint-disable-line + node.xmlContent = el.innerHTML; + }, + + export: function(node, el, converter) { // eslint-disable-line + el.innerHTML = node.xmlContent; + } +}; diff --git a/packages/jats/contrib/contribToHTML.js b/packages/jats/contrib/contribToHTML.js new file mode 100644 index 000000000..37924d931 --- /dev/null +++ b/packages/jats/contrib/contribToHTML.js @@ -0,0 +1,47 @@ +'use strict'; + +var DOMElement = require('substance/ui/DefaultDOMElement'); + +// TODO: this is dup of refToHTML -> generalize +var namesToHTML = function (el) { + var nameElements = el.findAll('name'); + var nameEls = []; + for (var i = 0; i < nameElements.length; i++) { + var name = nameElements[i]; + var nameEl = DOMElement.createElement('span'); + nameEl.addClass('name'); + + nameEl.text(name.find('surname').text() + ' ' + name.find('given-names').text()); + if (i > 0 && i < nameElements.length) { + var comma = DOMElement.createElement('span'); + comma.text(', '); + nameEls.push(comma); + } + nameEls.push(nameEl); + } + return nameEls; +}; + +var contribToHTML = function (contrib) { + // + // + // Schuman + // Meredith C + // + // + // + // + // + // + // + + contrib = DOMElement.parseXML(''+contrib+''); + var el = DOMElement.createElement('div'); + var names = namesToHTML(contrib); + for (var i = 0; i < names.length; i++) { + el.appendChild(names[i]); + } + return el.outerHTML; +}; + +module.exports = contribToHTML; \ No newline at end of file diff --git a/packages/jats/contrib/package.js b/packages/jats/contrib/package.js new file mode 100644 index 000000000..76861f819 --- /dev/null +++ b/packages/jats/contrib/package.js @@ -0,0 +1,14 @@ +'use strict'; + +var Contrib = require('./Contrib'); +var ContribComponent = require('./ContribComponent'); +var ContribConverter = require('./ContribConverter'); + +module.exports = { + name: 'contrib', + configure: function(config) { + config.addNode(Contrib); + config.addComponent(Contrib.static.name, ContribComponent); + config.addConverter('jats', ContribConverter); + } +}; \ No newline at end of file diff --git a/packages/jats/package.js b/packages/jats/package.js index d5b56cc58..796d5fd6f 100644 --- a/packages/jats/package.js +++ b/packages/jats/package.js @@ -10,6 +10,8 @@ module.exports = { config.import(require('./article-meta/package')); config.import(require('./title-group/package')); config.import(require('./article-title/package')); + config.import(require('./contrib-group/package')); + config.import(require('./contrib/package')); config.import(require('./back/package')); config.import(require('./body/package')); config.import(require('./bold/package')); From d19a7990c8a1b52adb4972d5e6c48645693b7dfd Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 13 Jul 2016 22:31:36 +0200 Subject: [PATCH 024/167] Add padding for contrib group. --- packages/jats/contrib-group/ContribGroup.js | 1 - packages/jats/contrib-group/_contrib-group.scss | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jats/contrib-group/ContribGroup.js b/packages/jats/contrib-group/ContribGroup.js index cad0923da..297ce8e19 100644 --- a/packages/jats/contrib-group/ContribGroup.js +++ b/packages/jats/contrib-group/ContribGroup.js @@ -15,5 +15,4 @@ ContribGroup.static.defineSchema({ nodes: { type: ['id'], default: [] } }); - module.exports = ContribGroup; diff --git a/packages/jats/contrib-group/_contrib-group.scss b/packages/jats/contrib-group/_contrib-group.scss index cce896212..5177f8d2c 100644 --- a/packages/jats/contrib-group/_contrib-group.scss +++ b/packages/jats/contrib-group/_contrib-group.scss @@ -1,4 +1,5 @@ .sc-contrib-group { + padding-bottom: $default-padding; overflow: auto; > * { From 8e657a5ee1721d707b2105ce37199c8e2be7fab7 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 15 Jul 2016 14:55:54 +0200 Subject: [PATCH 025/167] Add tests for contrib element. --- test/jats/contrib.test.js | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 test/jats/contrib.test.js diff --git a/test/jats/contrib.test.js b/test/jats/contrib.test.js new file mode 100644 index 000000000..088be429f --- /dev/null +++ b/test/jats/contrib.test.js @@ -0,0 +1,39 @@ +'use strict'; + +var test = require('./test').module('jats/contrib'); + +// ATTENTION: refs are treated only as XML +var withAttributes = + ''+ + ' corresp="test">'+ + ' deceased="test">'+ + ' equal-contrib="test">'+ + ' rid="test">'+ + ' specific-use="test">'+ + ' xlink:actuate="test">'+ + ' xlink:href="test">'+ + ' xlink:role="test">'+ + ' xlink:show="test">'+ + ' xlink:title="test">'+ + ' xml:base="test">'+ + ' xmlns:xlink="test">'+ + ' '+ + ''; +test.attributesConversion(withAttributes, 'contrib'); + +var simple = ''; + +test.withFixture(simple, 'Im-/Exporting simple contrib', function(t) { + // import + var importer = t.fixture.createImporter('contrib'); + var node = importer.convertElement(t.fixture.xmlElement); + t.notNil(node.xmlContent, 'node should have XML content after import'); + // export + var exporter = t.fixture.createExporter(); + var el = exporter.convertNode(node); + t.ok(el.is('contrib'), 'should have exported a contrib element'); + t.ok(el.getChildAt(0).is('name'), '.. with name element'); + t.ok(el.getChildAt(1).is('xref'), '.. with xref element'); + t.end(); +}); From e615821f133553a3f693816e85fd88eeee73b5c7 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 15 Jul 2016 14:57:28 +0200 Subject: [PATCH 026/167] Implement XML editing of contrib nodes. --- packages/author/package.js | 2 + packages/common/EditXML.js | 81 +++++++++++++++++++ packages/common/XMLAttributeEditor.js | 50 ++++++++++++ packages/common/XMLEditor.js | 30 +++++++ packages/common/_edit-xml.scss | 34 ++++++++ packages/common/package.js | 8 ++ .../contrib-group/ContribGroupComponent.js | 2 + .../jats/contrib-group/_contrib-group.scss | 4 + packages/jats/contrib/ContribComponent.js | 45 ++++++++++- packages/jats/contrib/_contrib.scss | 5 ++ packages/jats/contrib/contribToHTML.js | 13 +-- packages/jats/contrib/package.js | 1 + packages/publisher/package.js | 1 + util/toDOM.js | 15 ++++ 14 files changed, 280 insertions(+), 11 deletions(-) create mode 100644 packages/common/EditXML.js create mode 100644 packages/common/XMLAttributeEditor.js create mode 100644 packages/common/XMLEditor.js create mode 100644 packages/common/_edit-xml.scss create mode 100644 packages/common/package.js create mode 100644 packages/jats/contrib/_contrib.scss create mode 100644 util/toDOM.js diff --git a/packages/author/package.js b/packages/author/package.js index fa76f4b2e..7708e5a13 100644 --- a/packages/author/package.js +++ b/packages/author/package.js @@ -19,8 +19,10 @@ module.exports = { config.import(require('../jats/package')); config.import(require('./heading/package')); + config.import(require('../common/package')); config.addStyle(__dirname, '_author'); + // support inline wrappers, for all hybrid types that can be // block-level but also inline. config.import(require('../inline-wrapper/InlineWrapperPackage')); diff --git a/packages/common/EditXML.js b/packages/common/EditXML.js new file mode 100644 index 000000000..bea2319f5 --- /dev/null +++ b/packages/common/EditXML.js @@ -0,0 +1,81 @@ +'use strict'; + +var Component = require('substance/ui/Component'); +var XMLAttributeEditor = require('./XMLAttributeEditor'); +var XMLEditor = require('./XMLEditor'); +var Button = require('substance/ui/Button'); + +function EditXML() { + EditXML.super.apply(this, arguments); +} + +EditXML.Prototype = function() { + this.render = function($$) { + var node = this.props.node; + var el = $$('div').addClass('sc-edit-xml'); + + el.append( + $$('div').addClass('se-tag sm-open-tag-start').append('') + ); + + el.append( + $$(XMLEditor, { + xml: node.xmlContent + }).ref('xmlEditor') + ); + + el.append( + $$('div').addClass('se-tag sm-end-tag').append('') + ); + + el.append( + $$('div').addClass('se-actions').append( + $$(Button).append('Save').on('click', this._save), + $$(Button).addClass('se-cancel').append('Cancel').on('click', this._cancel), + $$(Button).addClass('se-delete').append('Delete').on('click', this._delete) + ) + ); + return el; + }; + + this._cancel = function() { + this.send('closeModal'); + }; + + this._delete = function() { + console.log('Not yet implemented'); + // TODO: this is actually not very trivial as we don't + // know the node's context. E.g. when deleting + // a contrib node we need to remove the id from + }; + + this._save = function() { + var documentSession = this.context.documentSession; + var node = this.props.node; + + var newAttributes = this.refs.attributesEditor.getAttributes(); + var newXML = this.refs.xmlEditor.getXML(); + + // TODO: add validity checks. E.g. try to parse XML string + + documentSession.transaction(function(tx) { + tx.set([node.id, 'xmlContent'], newXML); + tx.set([node.id, 'attributes'], newAttributes); + }); + this.send('closeModal'); + }; +}; + +Component.extend(EditXML); + +module.exports = EditXML; diff --git a/packages/common/XMLAttributeEditor.js b/packages/common/XMLAttributeEditor.js new file mode 100644 index 000000000..f78daf72d --- /dev/null +++ b/packages/common/XMLAttributeEditor.js @@ -0,0 +1,50 @@ +'use strict'; + +var Component = require('substance/ui/Component'); +var map = require('lodash/map'); + +function XMLAttributeEditor() { + XMLAttributeEditor.super.apply(this, arguments); +} + +XMLAttributeEditor.Prototype = function() { + + this._getAttributeString = function() { + return map(this.props.attributes, function(val, key) { + return key+'='+val; + }).join('\n'); + }; + + this._parseAttributesFromString = function(newAttrs) { + newAttrs = newAttrs.split('\n'); + var res = {}; + + newAttrs.forEach(function(attr) { + var parts = attr.split('='); + res[parts[0]] = parts[1]; + }); + return res; + }; + + /* Returns the changed attributes */ + this.getAttributes = function() { + var attrStr = this.refs.attributesEditor.val(); + return this._parseAttributesFromString(attrStr); + }; + + this.render = function($$) { + var node = this.props.node; + var el = $$('div').addClass('sc-edit-xml-attributes'); + var attributeStr = this._getAttributeString(node); + el.append( + $$('textarea') + .ref('attributesEditor') + .append(attributeStr) + ); + return el; + }; +}; + +Component.extend(XMLAttributeEditor); + +module.exports = XMLAttributeEditor; diff --git a/packages/common/XMLEditor.js b/packages/common/XMLEditor.js new file mode 100644 index 000000000..600fd2623 --- /dev/null +++ b/packages/common/XMLEditor.js @@ -0,0 +1,30 @@ +'use strict'; + +var Component = require('substance/ui/Component'); + +function XMLEditor() { + XMLEditor.super.apply(this, arguments); +} + +XMLEditor.Prototype = function() { + + this.getXML = function() { + return this.refs.xml.val(); + }; + + this.render = function($$) { + var el = $$('div').addClass('sc-xml-editor'); + + el.append( + $$('textarea') + .ref('xml') + .append(this.props.xml) + ); + return el; + }; + +}; + +Component.extend(XMLEditor); + +module.exports = XMLEditor; diff --git a/packages/common/_edit-xml.scss b/packages/common/_edit-xml.scss new file mode 100644 index 000000000..fbf9d3113 --- /dev/null +++ b/packages/common/_edit-xml.scss @@ -0,0 +1,34 @@ +.sc-edit-xml { + padding: $default-padding; + + textarea { + font-family: $font-family-code; + font-size: $font-size-code; + border: 1px solid #ddd; + padding: 20px; + resize: none; + } + + .se-tag { + opacity: 0.5; + } + + .se-actions { + padding-top: 20px; + + .sc-button { + margin-right: 20px; + } + } +} + +.sc-xml-attribute-editor textarea { + width: 100%; + height: 100px; +} + +.sc-xml-editor textarea { + width: 100%; + height: 300px; +} + diff --git a/packages/common/package.js b/packages/common/package.js new file mode 100644 index 000000000..ac081abf8 --- /dev/null +++ b/packages/common/package.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = { + name: 'common', + configure: function(config) { + config.addStyle(__dirname, '_edit-xml.scss'); + } +}; \ No newline at end of file diff --git a/packages/jats/contrib-group/ContribGroupComponent.js b/packages/jats/contrib-group/ContribGroupComponent.js index 7ba03acef..01d4b5c70 100644 --- a/packages/jats/contrib-group/ContribGroupComponent.js +++ b/packages/jats/contrib-group/ContribGroupComponent.js @@ -28,6 +28,8 @@ ContribGroupComponent.Prototype = function() { ); } }.bind(this)); + + el.append($$('button').addClass('se-add-author').append('Add Author')); return el; }; }; diff --git a/packages/jats/contrib-group/_contrib-group.scss b/packages/jats/contrib-group/_contrib-group.scss index 5177f8d2c..6f21624bb 100644 --- a/packages/jats/contrib-group/_contrib-group.scss +++ b/packages/jats/contrib-group/_contrib-group.scss @@ -6,4 +6,8 @@ float: left; margin-right: $default-padding; } + + .se-add-author { + color: $link-color; + } } \ No newline at end of file diff --git a/packages/jats/contrib/ContribComponent.js b/packages/jats/contrib/ContribComponent.js index 395aaa1ee..35c74ac80 100644 --- a/packages/jats/contrib/ContribComponent.js +++ b/packages/jats/contrib/ContribComponent.js @@ -1,18 +1,59 @@ 'use strict'; var Component = require('substance/ui/Component'); +var Modal = require('substance/ui/Modal'); +var EditXML = require('../../common/EditXML'); var contribToHTML = require('./contribToHTML'); function ContribComponent() { ContribComponent.super.apply(this, arguments); + + this.handleActions({ + 'closeModal': this._closeModal, + 'xmlSaved': this._closeModal + }); + + this.props.node.on('properties:changed', this.rerender, this); } ContribComponent.Prototype = function() { + this.render = function($$) { - var el = $$('div').addClass('sc-contrib'); - el.html(contribToHTML(this.props.node.xmlContent)); + console.log('rendering contrib'); + var node = this.props.node; + var el = $$('div').addClass('sc-contrib') + .append( + $$('div').addClass('se-name').html(contribToHTML(node)) + .on('click', this._toggleEditor) + ); + + if (this.state.editXML) { + el.append( + $$(Modal, { + width: 'medium' + }).append( + $$(EditXML, { + node: node + }) + ) + ); + } return el; }; + + this._closeModal = function() { + this.setState({ + editXML: false + }); + }; + + this._toggleEditor = function() { + console.log('toggle editor'); + this.setState({ + editXML: true + }); + }; + }; Component.extend(ContribComponent); diff --git a/packages/jats/contrib/_contrib.scss b/packages/jats/contrib/_contrib.scss new file mode 100644 index 000000000..a6bc88aef --- /dev/null +++ b/packages/jats/contrib/_contrib.scss @@ -0,0 +1,5 @@ +.sc-contrib .se-name { + background: #eee; + cursor: pointer; + padding: 0px 3px; +} \ No newline at end of file diff --git a/packages/jats/contrib/contribToHTML.js b/packages/jats/contrib/contribToHTML.js index 37924d931..6d696b7f5 100644 --- a/packages/jats/contrib/contribToHTML.js +++ b/packages/jats/contrib/contribToHTML.js @@ -1,6 +1,7 @@ 'use strict'; var DOMElement = require('substance/ui/DefaultDOMElement'); +var toDOM = require('../../../util/toDOM'); // TODO: this is dup of refToHTML -> generalize var namesToHTML = function (el) { @@ -29,18 +30,12 @@ var contribToHTML = function (contrib) { // Meredith C // // - // - // - // - // // + var contribEl = toDOM(contrib); - contrib = DOMElement.parseXML(''+contrib+''); var el = DOMElement.createElement('div'); - var names = namesToHTML(contrib); - for (var i = 0; i < names.length; i++) { - el.appendChild(names[i]); - } + el.append(namesToHTML(contribEl)); + return el.outerHTML; }; diff --git a/packages/jats/contrib/package.js b/packages/jats/contrib/package.js index 76861f819..85b690048 100644 --- a/packages/jats/contrib/package.js +++ b/packages/jats/contrib/package.js @@ -10,5 +10,6 @@ module.exports = { config.addNode(Contrib); config.addComponent(Contrib.static.name, ContribComponent); config.addConverter('jats', ContribConverter); + config.addStyle(__dirname, '_contrib.scss'); } }; \ No newline at end of file diff --git a/packages/publisher/package.js b/packages/publisher/package.js index 48c30500c..16fcd1f72 100644 --- a/packages/publisher/package.js +++ b/packages/publisher/package.js @@ -16,6 +16,7 @@ module.exports = { config.addStyle(__dirname, '_publisher'); config.import(require('../jats/package')); + config.import(require('../common/package')); // support inline wrappers, for all hybrid types that can be // block-level but also inline. diff --git a/util/toDOM.js b/util/toDOM.js new file mode 100644 index 000000000..792bfa75b --- /dev/null +++ b/util/toDOM.js @@ -0,0 +1,15 @@ +'use strict'; + +var DOMElement = require('substance/ui/DefaultDOMElement'); + +/* + Converts a node into its DOM representation + + @return {substance/ui/DOMElement} A wrapped DOM element +*/ +module.exports = function toDOM(node) { + var tagName = node.constructor.static.tagName || node.constructor.static.name; + var el = DOMElement.parseXML('<'+tagName+'>'+node.xmlContent+''); + el.attr(node.attributes); + return el; +}; \ No newline at end of file From 8f8a5bdb4e4bc567d21a62c5110461f89dd4f180 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 15 Jul 2016 14:58:45 +0200 Subject: [PATCH 027/167] Linting. --- packages/common/EditXML.js | 2 +- packages/jats/contrib/ContribComponent.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/common/EditXML.js b/packages/common/EditXML.js index bea2319f5..8ff1f90f0 100644 --- a/packages/common/EditXML.js +++ b/packages/common/EditXML.js @@ -53,7 +53,7 @@ EditXML.Prototype = function() { }; this._delete = function() { - console.log('Not yet implemented'); + console.warn('Not yet implemented'); // TODO: this is actually not very trivial as we don't // know the node's context. E.g. when deleting // a contrib node we need to remove the id from diff --git a/packages/jats/contrib/ContribComponent.js b/packages/jats/contrib/ContribComponent.js index 35c74ac80..add855916 100644 --- a/packages/jats/contrib/ContribComponent.js +++ b/packages/jats/contrib/ContribComponent.js @@ -19,7 +19,6 @@ function ContribComponent() { ContribComponent.Prototype = function() { this.render = function($$) { - console.log('rendering contrib'); var node = this.props.node; var el = $$('div').addClass('sc-contrib') .append( @@ -48,7 +47,6 @@ ContribComponent.Prototype = function() { }; this._toggleEditor = function() { - console.log('toggle editor'); this.setState({ editXML: true }); From 1b8ddfab8430d5b1e2828476f587a23d1a524869 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 20 Jul 2016 14:19:58 +0200 Subject: [PATCH 028/167] Fix package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 476bbee13..70322b9d0 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "A scientific editor and reader for JATS files.", "dependencies": { "lodash": "^4.2.1", - "substance": "substance/substance#devel" + "substance": "substance/substance#develop" }, "devDependencies": { "browserify": "substance/node-browserify#d3caeb6dcdaa97a258d099c7231a57f0f60ec876", From 50c741754dd6e8a4701042cccefd011eed510cf4 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sun, 24 Jul 2016 18:44:55 +0300 Subject: [PATCH 029/167] Renaming. --- packages/{author => _author}/Author.js | 0 packages/{author => _author}/AuthorExporter.js | 0 packages/{author => _author}/AuthorImporter.js | 0 packages/{author => _author}/AuthorTOCProvider.js | 0 packages/{author => _author}/JATSTransformer.js | 0 packages/{author => _author}/_author.scss | 0 packages/{author => _author}/heading/Heading.js | 0 packages/{author => _author}/heading/_heading.scss | 0 packages/{author => _author}/heading/package.js | 0 packages/{author => _author}/package.js | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename packages/{author => _author}/Author.js (100%) rename packages/{author => _author}/AuthorExporter.js (100%) rename packages/{author => _author}/AuthorImporter.js (100%) rename packages/{author => _author}/AuthorTOCProvider.js (100%) rename packages/{author => _author}/JATSTransformer.js (100%) rename packages/{author => _author}/_author.scss (100%) rename packages/{author => _author}/heading/Heading.js (100%) rename packages/{author => _author}/heading/_heading.scss (100%) rename packages/{author => _author}/heading/package.js (100%) rename packages/{author => _author}/package.js (100%) diff --git a/packages/author/Author.js b/packages/_author/Author.js similarity index 100% rename from packages/author/Author.js rename to packages/_author/Author.js diff --git a/packages/author/AuthorExporter.js b/packages/_author/AuthorExporter.js similarity index 100% rename from packages/author/AuthorExporter.js rename to packages/_author/AuthorExporter.js diff --git a/packages/author/AuthorImporter.js b/packages/_author/AuthorImporter.js similarity index 100% rename from packages/author/AuthorImporter.js rename to packages/_author/AuthorImporter.js diff --git a/packages/author/AuthorTOCProvider.js b/packages/_author/AuthorTOCProvider.js similarity index 100% rename from packages/author/AuthorTOCProvider.js rename to packages/_author/AuthorTOCProvider.js diff --git a/packages/author/JATSTransformer.js b/packages/_author/JATSTransformer.js similarity index 100% rename from packages/author/JATSTransformer.js rename to packages/_author/JATSTransformer.js diff --git a/packages/author/_author.scss b/packages/_author/_author.scss similarity index 100% rename from packages/author/_author.scss rename to packages/_author/_author.scss diff --git a/packages/author/heading/Heading.js b/packages/_author/heading/Heading.js similarity index 100% rename from packages/author/heading/Heading.js rename to packages/_author/heading/Heading.js diff --git a/packages/author/heading/_heading.scss b/packages/_author/heading/_heading.scss similarity index 100% rename from packages/author/heading/_heading.scss rename to packages/_author/heading/_heading.scss diff --git a/packages/author/heading/package.js b/packages/_author/heading/package.js similarity index 100% rename from packages/author/heading/package.js rename to packages/_author/heading/package.js diff --git a/packages/author/package.js b/packages/_author/package.js similarity index 100% rename from packages/author/package.js rename to packages/_author/package.js From 25ae8d631d01e09450eec2cdef1bd4bce28e00c3 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sun, 24 Jul 2016 18:45:42 +0300 Subject: [PATCH 030/167] Renaming. --- packages/{_author => author}/Author.js | 0 packages/{_author => author}/AuthorExporter.js | 0 packages/{_author => author}/AuthorImporter.js | 0 packages/{_author => author}/AuthorTOCProvider.js | 0 packages/{_author => author}/JATSTransformer.js | 0 packages/{_author => author}/_author.scss | 0 packages/{_author => author}/heading/Heading.js | 0 packages/{_author => author}/heading/_heading.scss | 0 packages/{_author => author}/heading/package.js | 0 packages/{_author => author}/package.js | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename packages/{_author => author}/Author.js (100%) rename packages/{_author => author}/AuthorExporter.js (100%) rename packages/{_author => author}/AuthorImporter.js (100%) rename packages/{_author => author}/AuthorTOCProvider.js (100%) rename packages/{_author => author}/JATSTransformer.js (100%) rename packages/{_author => author}/_author.scss (100%) rename packages/{_author => author}/heading/Heading.js (100%) rename packages/{_author => author}/heading/_heading.scss (100%) rename packages/{_author => author}/heading/package.js (100%) rename packages/{_author => author}/package.js (100%) diff --git a/packages/_author/Author.js b/packages/author/Author.js similarity index 100% rename from packages/_author/Author.js rename to packages/author/Author.js diff --git a/packages/_author/AuthorExporter.js b/packages/author/AuthorExporter.js similarity index 100% rename from packages/_author/AuthorExporter.js rename to packages/author/AuthorExporter.js diff --git a/packages/_author/AuthorImporter.js b/packages/author/AuthorImporter.js similarity index 100% rename from packages/_author/AuthorImporter.js rename to packages/author/AuthorImporter.js diff --git a/packages/_author/AuthorTOCProvider.js b/packages/author/AuthorTOCProvider.js similarity index 100% rename from packages/_author/AuthorTOCProvider.js rename to packages/author/AuthorTOCProvider.js diff --git a/packages/_author/JATSTransformer.js b/packages/author/JATSTransformer.js similarity index 100% rename from packages/_author/JATSTransformer.js rename to packages/author/JATSTransformer.js diff --git a/packages/_author/_author.scss b/packages/author/_author.scss similarity index 100% rename from packages/_author/_author.scss rename to packages/author/_author.scss diff --git a/packages/_author/heading/Heading.js b/packages/author/heading/Heading.js similarity index 100% rename from packages/_author/heading/Heading.js rename to packages/author/heading/Heading.js diff --git a/packages/_author/heading/_heading.scss b/packages/author/heading/_heading.scss similarity index 100% rename from packages/_author/heading/_heading.scss rename to packages/author/heading/_heading.scss diff --git a/packages/_author/heading/package.js b/packages/author/heading/package.js similarity index 100% rename from packages/_author/heading/package.js rename to packages/author/heading/package.js diff --git a/packages/_author/package.js b/packages/author/package.js similarity index 100% rename from packages/_author/package.js rename to packages/author/package.js From 9be0ee61c47ca8e11ea982b9d97c2aa9f77b8e7b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sun, 24 Jul 2016 19:05:20 +0300 Subject: [PATCH 031/167] Don't use 'static' --- examples/jats-editor/app.js | 2 +- examples/science-writer/app.js | 2 +- examples/server-rendering.js | 2 +- packages/author/heading/Heading.js | 4 ++-- packages/author/heading/package.js | 2 +- packages/jats/article-meta/ArticleMeta.js | 4 ++-- packages/jats/article-meta/package.js | 4 ++-- packages/jats/article-title/ArticleTitle.js | 4 ++-- packages/jats/article-title/package.js | 2 +- packages/jats/article/ArticleNode.js | 4 ++-- packages/jats/article/package.js | 2 +- packages/jats/back/Back.js | 4 ++-- packages/jats/back/package.js | 2 +- packages/jats/body/Body.js | 4 ++-- packages/jats/body/package.js | 2 +- packages/jats/bold/Bold.js | 4 ++-- packages/jats/bold/BoldCommand.js | 2 -- packages/jats/bold/BoldTool.js | 4 ---- packages/jats/bold/package.js | 8 ++++---- packages/jats/caption/Caption.js | 4 ++-- packages/jats/caption/package.js | 2 +- packages/jats/contrib-group/ContribGroup.js | 4 ++-- packages/jats/contrib-group/package.js | 2 +- packages/jats/contrib/Contrib.js | 4 ++-- packages/jats/contrib/package.js | 2 +- packages/jats/ext-link/EditExtLinkTool.js | 10 +++------- packages/jats/ext-link/ExtLink.js | 6 +++--- packages/jats/ext-link/ExtLinkCommand.js | 2 -- packages/jats/ext-link/ExtLinkTool.js | 1 - packages/jats/ext-link/package.js | 14 +++++++------- packages/jats/figure/Figure.js | 4 ++-- packages/jats/figure/package.js | 6 +++--- packages/jats/footnote/Footnote.js | 4 ++-- packages/jats/footnote/package.js | 2 +- packages/jats/front/Front.js | 4 ++-- packages/jats/front/package.js | 2 +- packages/jats/graphic/Graphic.js | 4 ++-- packages/jats/graphic/package.js | 2 +- packages/jats/italic/Italic.js | 4 ++-- packages/jats/label/Label.js | 4 ++-- packages/jats/label/package.js | 2 +- packages/jats/monospace/Monospace.js | 4 ++-- packages/jats/paragraph/Paragraph.js | 4 ++-- packages/jats/paragraph/package.js | 8 ++++---- packages/jats/ref-list/RefList.js | 4 ++-- packages/jats/ref-list/RefListComponent.js | 4 ++-- packages/jats/ref-list/package.js | 2 +- packages/jats/ref/Ref.js | 4 ++-- packages/jats/ref/RefComponent.js | 4 ++-- packages/jats/ref/package.js | 4 ++-- packages/jats/section/Section.js | 4 ++-- packages/jats/section/SectionComponent.js | 4 ++-- packages/jats/subscript/Subscript.js | 4 ++-- packages/jats/superscript/Superscript.js | 4 ++-- packages/jats/table-wrap/TableWrap.js | 2 +- packages/jats/table-wrap/package.js | 2 +- packages/jats/table/Table.js | 4 ++-- packages/jats/table/package.js | 2 +- packages/jats/title-group/TitleGroup.js | 4 ++-- packages/jats/title-group/package.js | 2 +- packages/jats/title/Title.js | 4 ++-- packages/jats/title/package.js | 2 +- packages/jats/xref/XRef.js | 8 ++++---- packages/jats/xref/XRefCommand.js | 6 ------ packages/jats/xref/XRefTool.js | 6 ++---- packages/jats/xref/package.js | 8 ++++---- packages/unsupported/UnsupportedInlineNode.js | 4 ++-- .../unsupported/UnsupportedInlineNodeCommand.js | 4 +++- packages/unsupported/UnsupportedInlineNodeTool.js | 4 +--- packages/unsupported/UnsupportedNode.js | 4 ++-- packages/unsupported/UnsupportedNodeComponent.js | 4 ++-- packages/unsupported/UnsupportedNodePackage.js | 10 +++++----- util/toDOM.js | 2 +- 73 files changed, 133 insertions(+), 154 deletions(-) diff --git a/examples/jats-editor/app.js b/examples/jats-editor/app.js index 58a609bf7..e2195bd80 100644 --- a/examples/jats-editor/app.js +++ b/examples/jats-editor/app.js @@ -10,7 +10,7 @@ var JATSEditorPackage = require('./package'); var configurator = new ScientistConfigurator().import(JATSEditorPackage); window.onload = function() { - window.app = Scientist.static.mount({ + window.app = Scientist.mount({ mode: 'publisher', documentId: 'elife-00007', configurator: configurator diff --git a/examples/science-writer/app.js b/examples/science-writer/app.js index 9a8419c8f..25300fe17 100644 --- a/examples/science-writer/app.js +++ b/examples/science-writer/app.js @@ -9,7 +9,7 @@ var JATSEditorPackage = require('./package'); var configurator = new ScientistConfigurator().import(JATSEditorPackage); window.onload = function() { - window.app = Scientist.static.mount({ + window.app = Scientist.mount({ mode: 'author', documentId: 'elife-00007', configurator: configurator diff --git a/examples/server-rendering.js b/examples/server-rendering.js index e537085cb..667b961bf 100644 --- a/examples/server-rendering.js +++ b/examples/server-rendering.js @@ -34,6 +34,6 @@ var Reader = Component.extend({ }); var $el = jQuery('
'); -Reader.static.mount($el[0]); +Reader.mount($el[0]); fs.writeFileSync('./prerendered.html', $el.html()); diff --git a/packages/author/heading/Heading.js b/packages/author/heading/Heading.js index 2f7af2995..f95fac10c 100644 --- a/packages/author/heading/Heading.js +++ b/packages/author/heading/Heading.js @@ -8,9 +8,9 @@ function HeadingNode() { TextBlock.extend(HeadingNode); -HeadingNode.static.name = "heading"; +HeadingNode.type = "heading"; -HeadingNode.static.defineSchema({ +HeadingNode.define({ // just a reference to the original node // which will be used to retain XML attributes sectionId: { type: 'id', optional: true }, diff --git a/packages/author/heading/package.js b/packages/author/heading/package.js index 339ab8e56..0233dc3dc 100644 --- a/packages/author/heading/package.js +++ b/packages/author/heading/package.js @@ -8,7 +8,7 @@ module.exports = { name: 'heading', configure: function(config) { config.addNode(Heading); - config.addComponent(Heading.static.name, HeadingComponent); + config.addComponent(Heading.type, HeadingComponent); config.addConverter('html', HeadingHTMLConverter); config.addTextType({ name: 'heading1', diff --git a/packages/jats/article-meta/ArticleMeta.js b/packages/jats/article-meta/ArticleMeta.js index e2e8b3d16..7a318e5fe 100644 --- a/packages/jats/article-meta/ArticleMeta.js +++ b/packages/jats/article-meta/ArticleMeta.js @@ -8,9 +8,9 @@ function ArticleMeta() { DocumentNode.extend(ArticleMeta); -ArticleMeta.static.name = 'article-meta'; +ArticleMeta.type = 'article-meta'; -ArticleMeta.static.defineSchema({ +ArticleMeta.define({ attributes: { type: 'object', default: {} }, nodes: { type: ['id'], default: [] } }); diff --git a/packages/jats/article-meta/package.js b/packages/jats/article-meta/package.js index a51b72ac8..19591aa91 100644 --- a/packages/jats/article-meta/package.js +++ b/packages/jats/article-meta/package.js @@ -9,6 +9,6 @@ module.exports = { configure: function(config) { config.addNode(ArticleMeta); config.addConverter('jats', ArticleMetaConverter); - config.addComponent(ArticleMeta.static.name, ArticleMetaComponent); + config.addComponent(ArticleMeta.type, ArticleMetaComponent); } -}; \ No newline at end of file +}; diff --git a/packages/jats/article-title/ArticleTitle.js b/packages/jats/article-title/ArticleTitle.js index c5873939b..af90b9081 100644 --- a/packages/jats/article-title/ArticleTitle.js +++ b/packages/jats/article-title/ArticleTitle.js @@ -8,9 +8,9 @@ function ArticleTitle() { TextNode.extend(ArticleTitle); -ArticleTitle.static.name = 'article-title'; +ArticleTitle.type = 'article-title'; -ArticleTitle.static.defineSchema({ +ArticleTitle.define({ attributes: { type: 'object', default: {} }, }); diff --git a/packages/jats/article-title/package.js b/packages/jats/article-title/package.js index 4b7938fb6..567a68df4 100644 --- a/packages/jats/article-title/package.js +++ b/packages/jats/article-title/package.js @@ -9,7 +9,7 @@ module.exports = { configure: function(config) { config.addNode(ArticleTitle); config.addConverter('jats', ArticleTitleConverter); - config.addComponent(ArticleTitle.static.name, ArticleTitleComponent); + config.addComponent(ArticleTitle.type, ArticleTitleComponent); config.addStyle(__dirname, '_article-title.scss'); } }; diff --git a/packages/jats/article/ArticleNode.js b/packages/jats/article/ArticleNode.js index 7c6aa0935..0ce4d0f44 100644 --- a/packages/jats/article/ArticleNode.js +++ b/packages/jats/article/ArticleNode.js @@ -8,7 +8,7 @@ function ArticleNode() { DocumentNode.extend(ArticleNode); -ArticleNode.static.name = 'article'; +ArticleNode.type = 'article'; /* Attributes @@ -27,7 +27,7 @@ ArticleNode.static.name = 'article'; (front, body?, back?, floats-group?, (sub-article* | response*)) */ -ArticleNode.static.defineSchema({ +ArticleNode.define({ attributes: { type: 'object', default: {} }, front: { type: 'id' }, body: { type: 'id', optional: true }, diff --git a/packages/jats/article/package.js b/packages/jats/article/package.js index d5ddf1c0e..d5f20b32e 100644 --- a/packages/jats/article/package.js +++ b/packages/jats/article/package.js @@ -16,6 +16,6 @@ module.exports = { config.addNode(ArticleNode); config.addConverter('jats', ArticleConverter); - config.addComponent(ArticleNode.static.name, ArticleComponent); + config.addComponent(ArticleNode.type, ArticleComponent); } }; \ No newline at end of file diff --git a/packages/jats/back/Back.js b/packages/jats/back/Back.js index ba28c98c0..c37fe297a 100644 --- a/packages/jats/back/Back.js +++ b/packages/jats/back/Back.js @@ -13,7 +13,7 @@ function Back() { Container.extend(Back); -Back.static.name = 'back'; +Back.type = 'back'; /* Attributes @@ -24,7 +24,7 @@ Back.static.name = 'back'; (label?, title*, (ack | app-group | bio | fn-group | glossary | ref-list | notes | sec)*) */ -Back.static.defineSchema({ +Back.define({ attributes: { type: 'object', default: {} }, label: { type: 'label', optional:true }, titles: { type: ['title'], default: [] }, diff --git a/packages/jats/back/package.js b/packages/jats/back/package.js index 9e8ed08e1..8ba28bbf0 100644 --- a/packages/jats/back/package.js +++ b/packages/jats/back/package.js @@ -9,6 +9,6 @@ module.exports = { configure: function(config) { config.addNode(Back); config.addConverter('jats', BackConverter); - config.addComponent(Back.static.name, BackComponent); + config.addComponent(Back.type, BackComponent); } }; \ No newline at end of file diff --git a/packages/jats/body/Body.js b/packages/jats/body/Body.js index c6d12f35c..68474d9b9 100644 --- a/packages/jats/body/Body.js +++ b/packages/jats/body/Body.js @@ -8,7 +8,7 @@ function Body() { Container.extend(Body); -Body.static.name = "body"; +Body.type = "body"; /* Content @@ -17,7 +17,7 @@ Body.static.name = "body"; sig-block? */ -Body.static.defineSchema({ +Body.define({ attributes: { type: 'object', default: {} }, nodes: { type: ['id'], default: [] }, sigBlock: { type: ['sig-block'], optional: true } diff --git a/packages/jats/body/package.js b/packages/jats/body/package.js index 797a8a758..e5e529a16 100644 --- a/packages/jats/body/package.js +++ b/packages/jats/body/package.js @@ -9,6 +9,6 @@ module.exports = { configure: function(config) { config.addNode(Body); config.addConverter('jats', BodyConverter); - config.addComponent(Body.static.name, BodyComponent); + config.addComponent(Body.type, BodyComponent); } }; \ No newline at end of file diff --git a/packages/jats/bold/Bold.js b/packages/jats/bold/Bold.js index c22a4fb77..3d7660b44 100644 --- a/packages/jats/bold/Bold.js +++ b/packages/jats/bold/Bold.js @@ -8,9 +8,9 @@ function Bold() { Annotation.extend(Bold); -Bold.static.name = 'bold'; +Bold.type = 'bold'; -Bold.static.defineSchema({ +Bold.define({ attributes: { type: 'object', default: {} }, }); diff --git a/packages/jats/bold/BoldCommand.js b/packages/jats/bold/BoldCommand.js index 3e9e0f05a..666628f71 100644 --- a/packages/jats/bold/BoldCommand.js +++ b/packages/jats/bold/BoldCommand.js @@ -8,6 +8,4 @@ function BoldCommand() { AnnotationCommand.extend(BoldCommand); -BoldCommand.static.name = 'bold'; - module.exports = BoldCommand; \ No newline at end of file diff --git a/packages/jats/bold/BoldTool.js b/packages/jats/bold/BoldTool.js index f7df06adb..5e3e6afc9 100644 --- a/packages/jats/bold/BoldTool.js +++ b/packages/jats/bold/BoldTool.js @@ -1,12 +1,8 @@ 'use strict'; -var AnnotationTool = require('substance/ui/AnnotationTool'); - function BoldTool() { BoldTool.super.apply(this, arguments); } AnnotationTool.extend(BoldTool); -BoldTool.static.name = 'bold'; - module.exports = BoldTool; \ No newline at end of file diff --git a/packages/jats/bold/package.js b/packages/jats/bold/package.js index c40380d3f..3e2a18d6c 100644 --- a/packages/jats/bold/package.js +++ b/packages/jats/bold/package.js @@ -10,11 +10,11 @@ module.exports = { configure: function(config) { config.addNode(Bold); config.addConverter('jats', BoldConverter); - config.addCommand(BoldCommand); - config.addTool(BoldTool); - config.addIcon(BoldCommand.static.name, { 'fontawesome': 'fa-bold' }); + config.addCommand(Bold.type, BoldCommand, { nodeType: Bold.type }); + config.addTool(Bold.type, BoldTool); + config.addIcon(Bold.type, { 'fontawesome': 'fa-bold' }); config.addStyle(__dirname, '_bold.scss'); - config.addLabel('bold', { + config.addLabel(Bold.type, { en: 'Bold' }); } diff --git a/packages/jats/caption/Caption.js b/packages/jats/caption/Caption.js index 33433137a..e27518a2a 100644 --- a/packages/jats/caption/Caption.js +++ b/packages/jats/caption/Caption.js @@ -19,7 +19,7 @@ Caption.Prototype = function() { Container.extend(Caption); -Caption.static.name = 'caption'; +Caption.type = 'caption'; /* Attributes @@ -33,7 +33,7 @@ Caption.static.name = 'caption'; Content ( title?, (p)* ) */ -Caption.static.defineSchema({ +Caption.define({ attributes: { type: 'object', default: {} }, title: { type: 'title', optional: true }, nodes: { type: ['p'], default: [] } diff --git a/packages/jats/caption/package.js b/packages/jats/caption/package.js index 39ad2b4ec..0d47c9403 100644 --- a/packages/jats/caption/package.js +++ b/packages/jats/caption/package.js @@ -8,7 +8,7 @@ module.exports = { name: 'caption', configure: function(config) { config.addNode(Caption); - config.addComponent(Caption.static.name, CaptionComponent); + config.addComponent(Caption.type, CaptionComponent); config.addConverter('jats', CaptionConverter); } }; \ No newline at end of file diff --git a/packages/jats/contrib-group/ContribGroup.js b/packages/jats/contrib-group/ContribGroup.js index 297ce8e19..0779c8433 100644 --- a/packages/jats/contrib-group/ContribGroup.js +++ b/packages/jats/contrib-group/ContribGroup.js @@ -8,9 +8,9 @@ function ContribGroup() { Container.extend(ContribGroup); -ContribGroup.static.name = "contrib-group"; +ContribGroup.type = "contrib-group"; -ContribGroup.static.defineSchema({ +ContribGroup.define({ attributes: { type: 'object', default: {} }, nodes: { type: ['id'], default: [] } }); diff --git a/packages/jats/contrib-group/package.js b/packages/jats/contrib-group/package.js index 5514ec304..b4159f6a7 100644 --- a/packages/jats/contrib-group/package.js +++ b/packages/jats/contrib-group/package.js @@ -9,7 +9,7 @@ module.exports = { configure: function(config) { config.addNode(ContribGroup); config.addConverter('jats', ContribGroupConverter); - config.addComponent(ContribGroup.static.name, ContribGroupComponent); + config.addComponent(ContribGroup.type, ContribGroupComponent); config.addStyle(__dirname, '_contrib-group.scss'); } }; diff --git a/packages/jats/contrib/Contrib.js b/packages/jats/contrib/Contrib.js index e332ea123..2673b26d8 100644 --- a/packages/jats/contrib/Contrib.js +++ b/packages/jats/contrib/Contrib.js @@ -13,13 +13,13 @@ function Contrib() { DocumentNode.extend(Contrib); -Contrib.static.name = 'contrib'; +Contrib.type = 'contrib'; /* Content (label?, (citation-alternatives | element-citation | mixed-citation | nlm-citation | note | x)+) */ -Contrib.static.defineSchema({ +Contrib.define({ attributes: { type: 'object', default: {} }, xmlContent: {type: 'string', default: ''} }); diff --git a/packages/jats/contrib/package.js b/packages/jats/contrib/package.js index 85b690048..e0af66c71 100644 --- a/packages/jats/contrib/package.js +++ b/packages/jats/contrib/package.js @@ -8,7 +8,7 @@ module.exports = { name: 'contrib', configure: function(config) { config.addNode(Contrib); - config.addComponent(Contrib.static.name, ContribComponent); + config.addComponent(Contrib.type, ContribComponent); config.addConverter('jats', ContribConverter); config.addStyle(__dirname, '_contrib.scss'); } diff --git a/packages/jats/ext-link/EditExtLinkTool.js b/packages/jats/ext-link/EditExtLinkTool.js index cf8529d3f..c9480d6fe 100644 --- a/packages/jats/ext-link/EditExtLinkTool.js +++ b/packages/jats/ext-link/EditExtLinkTool.js @@ -7,15 +7,11 @@ function EditExtLinkTool() { EditExtLinkTool.super.apply(this, arguments); } -EditExtLinkTool.Prototype = function() { -}; - EditLinkTool.extend(EditExtLinkTool); -EditExtLinkTool.static.urlPropertyPath = ['attributes', 'xlink:href']; -EditExtLinkTool.static.name = 'edit-ext-link'; +EditExtLinkTool.urlPropertyPath = ['attributes', 'xlink:href']; -EditExtLinkTool.static.getProps = function(commandStates) { +EditExtLinkTool.getProps = function(commandStates) { if (commandStates['ext-link'].mode === 'edit') { return clone(commandStates['ext-link']); } else { @@ -23,4 +19,4 @@ EditExtLinkTool.static.getProps = function(commandStates) { } }; -module.exports = EditExtLinkTool; \ No newline at end of file +module.exports = EditExtLinkTool; diff --git a/packages/jats/ext-link/ExtLink.js b/packages/jats/ext-link/ExtLink.js index a7d8275fd..1d6129610 100644 --- a/packages/jats/ext-link/ExtLink.js +++ b/packages/jats/ext-link/ExtLink.js @@ -9,14 +9,14 @@ function ExtLink() { PropertyAnnotation.extend(ExtLink); -ExtLink.static.name = "ext-link"; +ExtLink.type = "ext-link"; -ExtLink.static.defineSchema({ +ExtLink.define({ attributes: { type: 'object', default: {} }, }); // in presence of overlapping annotations will try to render this as one element -ExtLink.static.fragmentation = Fragmenter.SHOULD_NOT_SPLIT; +ExtLink.fragmentation = Fragmenter.SHOULD_NOT_SPLIT; module.exports = ExtLink; diff --git a/packages/jats/ext-link/ExtLinkCommand.js b/packages/jats/ext-link/ExtLinkCommand.js index 7b26f7018..23f71519b 100644 --- a/packages/jats/ext-link/ExtLinkCommand.js +++ b/packages/jats/ext-link/ExtLinkCommand.js @@ -18,6 +18,4 @@ ExtLinkCommand.Prototype = function() { LinkCommand.extend(ExtLinkCommand); -ExtLinkCommand.static.name = 'ext-link'; - module.exports = ExtLinkCommand; \ No newline at end of file diff --git a/packages/jats/ext-link/ExtLinkTool.js b/packages/jats/ext-link/ExtLinkTool.js index ca5925693..e677f077e 100644 --- a/packages/jats/ext-link/ExtLinkTool.js +++ b/packages/jats/ext-link/ExtLinkTool.js @@ -7,6 +7,5 @@ function ExtLinkTool() { } AnnotationTool.extend(ExtLinkTool); -ExtLinkTool.static.name = 'ext-link'; module.exports = ExtLinkTool; \ No newline at end of file diff --git a/packages/jats/ext-link/package.js b/packages/jats/ext-link/package.js index 3825275e6..24b1b313e 100644 --- a/packages/jats/ext-link/package.js +++ b/packages/jats/ext-link/package.js @@ -13,16 +13,16 @@ module.exports = { configure: function(config) { config.addNode(ExtLink); config.addConverter('jats', ExtLinkConverter); - config.addComponent(ExtLink.static.name, ExtLinkComponent); + config.addComponent(ExtLink.type, ExtLinkComponent); - config.addCommand(ExtLinkCommand); - config.addTool(ExtLinkTool); - config.addTool(EditExtLinkTool, { overlay: true }); - config.addIcon(ExtLinkCommand.static.name, { 'fontawesome': 'fa-link'}); + config.addCommand(ExtLink.type, ExtLinkCommand, {nodeType: ExtLink.type}); + config.addTool(ExtLink.type, ExtLinkTool); + config.addTool('edit-ext-link', EditExtLinkTool, { overlay: true }); + config.addIcon(ExtLink.type, { 'fontawesome': 'fa-link'}); config.addIcon('open-link', { 'fontawesome': 'fa-external-link' }); - config.addLabel('ext-link', { + config.addLabel(ExtLink.type, { en: 'Link' }); config.addStyle(__dirname, '_ext-link.scss'); } -}; \ No newline at end of file +}; diff --git a/packages/jats/figure/Figure.js b/packages/jats/figure/Figure.js index 228eb03d2..f3473ccef 100644 --- a/packages/jats/figure/Figure.js +++ b/packages/jats/figure/Figure.js @@ -8,7 +8,7 @@ function Figure() { DocumentNode.extend(Figure); -Figure.static.name = 'figure'; +Figure.type = 'figure'; /* Attribute @@ -31,7 +31,7 @@ Figure.static.name = 'figure'; (attrib | permissions)* ) */ -Figure.static.defineSchema({ +Figure.define({ attributes: { type: 'object', default: {} }, objectIds: { type: ['string'], default: [] }, label: { type: 'label', optional: true }, diff --git a/packages/jats/figure/package.js b/packages/jats/figure/package.js index 00dacc112..19de540f9 100644 --- a/packages/jats/figure/package.js +++ b/packages/jats/figure/package.js @@ -9,10 +9,10 @@ module.exports = { name: 'figure', configure: function(config) { config.addNode(Figure); - config.addComponent(Figure.static.name, FigureComponent); - config.addComponent(Figure.static.name+'-target', FigureTarget); + config.addComponent(Figure.type, FigureComponent); + config.addComponent(Figure.type+'-target', FigureTarget); config.addConverter('jats', FigureConverter); config.addStyle(__dirname, '_figure.scss'); config.addStyle(__dirname, '_figure-target.scss'); } -}; \ No newline at end of file +}; diff --git a/packages/jats/footnote/Footnote.js b/packages/jats/footnote/Footnote.js index 048fab51b..592175111 100644 --- a/packages/jats/footnote/Footnote.js +++ b/packages/jats/footnote/Footnote.js @@ -8,13 +8,13 @@ function Footnote() { Container.extend(Footnote); -Footnote.static.name = 'footnote'; +Footnote.type = 'footnote'; /* Content (label?, p+) */ -Footnote.static.defineSchema({ +Footnote.define({ attributes: { type: 'object', default: {} }, label: { type: 'label', optional: true }, nodes: { type: ['p'], default: [] } diff --git a/packages/jats/footnote/package.js b/packages/jats/footnote/package.js index 74c18f374..481601cf9 100644 --- a/packages/jats/footnote/package.js +++ b/packages/jats/footnote/package.js @@ -8,7 +8,7 @@ module.exports = { name: 'footnote', configure: function(config) { config.addNode(Footnote); - config.addComponent(Footnote.static.name, FootnoteComponent); + config.addComponent(Footnote.type, FootnoteComponent); config.addConverter('jats', FootnoteConverter); config.addStyle(__dirname, '_footnote.scss'); } diff --git a/packages/jats/front/Front.js b/packages/jats/front/Front.js index 4dcfa7ee6..31d0fdb6c 100644 --- a/packages/jats/front/Front.js +++ b/packages/jats/front/Front.js @@ -8,7 +8,7 @@ function Front() { Container.extend(Front); -Front.static.name = "front"; +Front.type = "front"; /* Content @@ -18,7 +18,7 @@ Front.static.name = "front"; ) */ -Front.static.defineSchema({ +Front.define({ attributes: { type: 'object', default: {} }, journalMeta: { type: 'journal-meta', optional: true }, articleMeta: { type: 'article-meta' }, diff --git a/packages/jats/front/package.js b/packages/jats/front/package.js index 0503a8c96..1c54879c6 100644 --- a/packages/jats/front/package.js +++ b/packages/jats/front/package.js @@ -9,6 +9,6 @@ module.exports = { configure: function(config) { config.addNode(Front); config.addConverter('jats', FrontConverter); - config.addComponent(Front.static.name, FrontComponent); + config.addComponent(Front.type, FrontComponent); } }; \ No newline at end of file diff --git a/packages/jats/graphic/Graphic.js b/packages/jats/graphic/Graphic.js index 4148e564f..d987188c5 100644 --- a/packages/jats/graphic/Graphic.js +++ b/packages/jats/graphic/Graphic.js @@ -16,9 +16,9 @@ Graphic.Prototype = function() { Container.extend(Graphic); -Graphic.static.name = 'graphic'; +Graphic.type= 'graphic'; -Graphic.static.defineSchema({ +Graphic.define({ attributes: { type: 'object', default: {} }, }); diff --git a/packages/jats/graphic/package.js b/packages/jats/graphic/package.js index dcfb89e3b..4a1f06909 100644 --- a/packages/jats/graphic/package.js +++ b/packages/jats/graphic/package.js @@ -8,7 +8,7 @@ module.exports = { name: 'graphic', configure: function(config) { config.addNode(Graphic); - config.addComponent(Graphic.static.name, GraphicComponent); + config.addComponent(Graphic.type, GraphicComponent); config.addConverter('jats', GraphicConverter); config.addStyle(__dirname, '_graphic.scss'); } diff --git a/packages/jats/italic/Italic.js b/packages/jats/italic/Italic.js index 9dd001e97..512efecaa 100644 --- a/packages/jats/italic/Italic.js +++ b/packages/jats/italic/Italic.js @@ -8,9 +8,9 @@ function Italic() { Annotation.extend(Italic); -Italic.static.name = 'italic'; +Italic.type = 'italic'; -Italic.static.defineSchema({ +Italic.define({ attributes: { type: 'object', default: {} }, }); diff --git a/packages/jats/label/Label.js b/packages/jats/label/Label.js index e1f587e47..c5ccd6845 100644 --- a/packages/jats/label/Label.js +++ b/packages/jats/label/Label.js @@ -8,9 +8,9 @@ function Label() { TextNode.extend(Label); -Label.static.name = 'label'; +Label.type = 'label'; -Label.static.defineSchema({ +Label.define({ attributes: { type: 'object', default: {} }, }); diff --git a/packages/jats/label/package.js b/packages/jats/label/package.js index 3832c345f..b8b51d61d 100644 --- a/packages/jats/label/package.js +++ b/packages/jats/label/package.js @@ -8,7 +8,7 @@ module.exports = { name: 'label', configure: function(config) { config.addNode(Label); - config.addComponent(Label.static.name, LabelComponent); + config.addComponent(Label.type, LabelComponent); config.addConverter('jats', LabelConverter); } }; diff --git a/packages/jats/monospace/Monospace.js b/packages/jats/monospace/Monospace.js index 0c2f737d9..98b0dac75 100644 --- a/packages/jats/monospace/Monospace.js +++ b/packages/jats/monospace/Monospace.js @@ -8,9 +8,9 @@ function Monospace() { Annotation.extend(Monospace); -Monospace.static.name = 'monospace'; +Monospace.type = 'monospace'; -Monospace.static.defineSchema({ +Monospace.define({ attributes: { type: 'object', default: {} }, }); diff --git a/packages/jats/paragraph/Paragraph.js b/packages/jats/paragraph/Paragraph.js index f334f5989..c79f71692 100644 --- a/packages/jats/paragraph/Paragraph.js +++ b/packages/jats/paragraph/Paragraph.js @@ -8,9 +8,9 @@ function ParagraphNode() { TextBlock.extend(ParagraphNode); -ParagraphNode.static.name = "paragraph"; +ParagraphNode.type = "paragraph"; -ParagraphNode.static.defineSchema({ +ParagraphNode.define({ attributes: { type: 'object', default: {} }, }); diff --git a/packages/jats/paragraph/package.js b/packages/jats/paragraph/package.js index 307e0215a..f53b5d300 100644 --- a/packages/jats/paragraph/package.js +++ b/packages/jats/paragraph/package.js @@ -10,13 +10,13 @@ module.exports = { configure: function(config) { config.addNode(Paragraph); - config.addComponent(Paragraph.static.name, ParagraphComponent); + config.addComponent(Paragraph.type, ParagraphComponent); config.addConverter('jats', ParagraphConverter); config.addTextType({ - name: 'paragraph', - data: {type: 'paragraph'} + name: Paragraph.type, + data: {type: Paragraph.type} }); - config.addLabel('paragraph', { + config.addLabel(Paragraph.type, { en: 'Paragraph', de: 'Paragraph' }); diff --git a/packages/jats/ref-list/RefList.js b/packages/jats/ref-list/RefList.js index 9ccbeba71..f57eefb94 100644 --- a/packages/jats/ref-list/RefList.js +++ b/packages/jats/ref-list/RefList.js @@ -13,7 +13,7 @@ function RefList() { Container.extend(RefList); -RefList.static.name = 'ref-list'; +RefList.type = 'ref-list'; /* ( @@ -29,7 +29,7 @@ RefList.static.name = 'ref-list'; (ref-list)* ) */ -RefList.static.defineSchema({ +RefList.define({ attributes: { type: 'object', default: {} }, label: { type: 'label', optional: true }, title: { type: 'title', optional: true }, diff --git a/packages/jats/ref-list/RefListComponent.js b/packages/jats/ref-list/RefListComponent.js index fbe424c45..698cfebc6 100644 --- a/packages/jats/ref-list/RefListComponent.js +++ b/packages/jats/ref-list/RefListComponent.js @@ -35,7 +35,7 @@ RefListComponent.Prototype = function() { Component.extend(RefListComponent); // Isolated Nodes config -RefListComponent.static.fullWidth = true; -RefListComponent.static.noStyle = true; +RefListComponent.fullWidth = true; +RefListComponent.noStyle = true; module.exports = RefListComponent; \ No newline at end of file diff --git a/packages/jats/ref-list/package.js b/packages/jats/ref-list/package.js index 214d659df..6146bbf92 100644 --- a/packages/jats/ref-list/package.js +++ b/packages/jats/ref-list/package.js @@ -8,7 +8,7 @@ module.exports = { name: 'ref-list', configure: function(config) { config.addNode(RefList); - config.addComponent(RefList.static.name, RefListComponent); + config.addComponent(RefList.type, RefListComponent); config.addConverter('jats', RefListConverter); config.addStyle(__dirname, '_ref-list.scss'); } diff --git a/packages/jats/ref/Ref.js b/packages/jats/ref/Ref.js index 3550ba47c..bf0f4071b 100644 --- a/packages/jats/ref/Ref.js +++ b/packages/jats/ref/Ref.js @@ -13,13 +13,13 @@ function Ref() { DocumentNode.extend(Ref); -Ref.static.name = 'ref'; +Ref.type = 'ref'; /* Content (label?, (citation-alternatives | element-citation | mixed-citation | nlm-citation | note | x)+) */ -Ref.static.defineSchema({ +Ref.define({ attributes: { type: 'object', default: {} }, xmlContent: {type: 'string', default: ''} }); diff --git a/packages/jats/ref/RefComponent.js b/packages/jats/ref/RefComponent.js index 039861a31..2224272cb 100644 --- a/packages/jats/ref/RefComponent.js +++ b/packages/jats/ref/RefComponent.js @@ -19,7 +19,7 @@ RefComponent.Prototype = function() { Component.extend(RefComponent); // Isolated Nodes config -RefComponent.static.fullWidth = true; -RefComponent.static.noStyle = true; +RefComponent.fullWidth = true; +RefComponent.noStyle = true; module.exports = RefComponent; diff --git a/packages/jats/ref/package.js b/packages/jats/ref/package.js index db5da2240..4032e7bb2 100644 --- a/packages/jats/ref/package.js +++ b/packages/jats/ref/package.js @@ -9,8 +9,8 @@ module.exports = { name: 'ref', configure: function(config) { config.addNode(Ref); - config.addComponent(Ref.static.name, RefComponent); - config.addComponent(Ref.static.name+'-target', RefTarget); + config.addComponent(Ref.type, RefComponent); + config.addComponent(Ref.type+'-target', RefTarget); config.addConverter('jats', RefConverter); config.addStyle(__dirname, '_ref.scss'); } diff --git a/packages/jats/section/Section.js b/packages/jats/section/Section.js index 378008081..d042244fb 100644 --- a/packages/jats/section/Section.js +++ b/packages/jats/section/Section.js @@ -18,7 +18,7 @@ Section.Prototype = function() { Container.extend(Section); -Section.static.name = "section"; +Section.type = "section"; /* Content Model @@ -33,7 +33,7 @@ Section.static.name = "section"; ) */ -Section.static.defineSchema({ +Section.define({ attributes: { type: 'object', default: {} }, meta: { type: 'id', optional: true }, label: { type: 'id', optional:true }, diff --git a/packages/jats/section/SectionComponent.js b/packages/jats/section/SectionComponent.js index 7ea1e9c12..45acb4f76 100644 --- a/packages/jats/section/SectionComponent.js +++ b/packages/jats/section/SectionComponent.js @@ -32,7 +32,7 @@ SectionComponent.Prototype = function() { Component.extend(SectionComponent); -SectionComponent.static.fullWidth = true; -SectionComponent.static.noStyle = true; +SectionComponent.fullWidth = true; +SectionComponent.noStyle = true; module.exports = SectionComponent; diff --git a/packages/jats/subscript/Subscript.js b/packages/jats/subscript/Subscript.js index a528621d6..c08fc1994 100644 --- a/packages/jats/subscript/Subscript.js +++ b/packages/jats/subscript/Subscript.js @@ -8,9 +8,9 @@ function Subscript() { Annotation.extend(Subscript); -Subscript.static.name = 'subscript'; +Subscript.type = 'subscript'; -Subscript.static.defineSchema({ +Subscript.define({ attributes: { type: 'object', default: {} }, }); diff --git a/packages/jats/superscript/Superscript.js b/packages/jats/superscript/Superscript.js index 0fcc3d188..71ea5e54c 100644 --- a/packages/jats/superscript/Superscript.js +++ b/packages/jats/superscript/Superscript.js @@ -8,9 +8,9 @@ function Superscript() { Annotation.extend(Superscript); -Superscript.static.name = 'superscript'; +Superscript.type = 'superscript'; -Superscript.static.defineSchema({ +Superscript.define({ attributes: { type: 'object', default: {} }, }); diff --git a/packages/jats/table-wrap/TableWrap.js b/packages/jats/table-wrap/TableWrap.js index 75b506612..c16e60850 100644 --- a/packages/jats/table-wrap/TableWrap.js +++ b/packages/jats/table-wrap/TableWrap.js @@ -8,6 +8,6 @@ function TableWrap() { Figure.extend(TableWrap); -TableWrap.static.name = 'table-wrap'; +TableWrap.type = 'table-wrap'; module.exports = TableWrap; \ No newline at end of file diff --git a/packages/jats/table-wrap/package.js b/packages/jats/table-wrap/package.js index f1edac35b..cf94dcdf9 100644 --- a/packages/jats/table-wrap/package.js +++ b/packages/jats/table-wrap/package.js @@ -8,7 +8,7 @@ module.exports = { name: 'table-wrap', configure: function(config) { config.addNode(TableWrap); - config.addComponent(TableWrap.static.name, TableWrapComponent); + config.addComponent(TableWrap.type, TableWrapComponent); config.addConverter('jats', TableWrapConverter); } }; \ No newline at end of file diff --git a/packages/jats/table/Table.js b/packages/jats/table/Table.js index 88b78bb01..3ac261dd6 100644 --- a/packages/jats/table/Table.js +++ b/packages/jats/table/Table.js @@ -10,8 +10,8 @@ function Table() { BlockNode.extend(Table); -Table.static.name = 'table'; -Table.static.defineSchema({ +Table.type = 'table'; +Table.define({ attributes: { type: 'object', default: {} }, htmlContent: {type: 'string'} }); diff --git a/packages/jats/table/package.js b/packages/jats/table/package.js index 6a24c60be..ec855814f 100644 --- a/packages/jats/table/package.js +++ b/packages/jats/table/package.js @@ -8,7 +8,7 @@ module.exports = { name: 'table', configure: function(config) { config.addNode(Table); - config.addComponent(Table.static.name, TableComponent); + config.addComponent(Table.type, TableComponent); config.addConverter('jats', TableConverter); } }; \ No newline at end of file diff --git a/packages/jats/title-group/TitleGroup.js b/packages/jats/title-group/TitleGroup.js index e7e6a8498..28bbb51f6 100644 --- a/packages/jats/title-group/TitleGroup.js +++ b/packages/jats/title-group/TitleGroup.js @@ -8,7 +8,7 @@ function TitleGroup() { Container.extend(TitleGroup); -TitleGroup.static.name = "title-group"; +TitleGroup.type = "title-group"; /* Content @@ -16,7 +16,7 @@ TitleGroup.static.name = "title-group"; article-title, subtitle*, trans-title-group*, alt-title*, fn-group? ) */ -TitleGroup.static.defineSchema({ +TitleGroup.define({ attributes: { type: 'object', default: {} }, nodes: { type: ['id'], default: [] } }); diff --git a/packages/jats/title-group/package.js b/packages/jats/title-group/package.js index f480b9eb3..5e3c8735c 100644 --- a/packages/jats/title-group/package.js +++ b/packages/jats/title-group/package.js @@ -9,6 +9,6 @@ module.exports = { configure: function(config) { config.addNode(TitleGroup); config.addConverter('jats', TitleGroupConverter); - config.addComponent(TitleGroup.static.name, TitleGroupComponent); + config.addComponent(TitleGroup.type, TitleGroupComponent); } }; diff --git a/packages/jats/title/Title.js b/packages/jats/title/Title.js index f3f517671..297f711d5 100644 --- a/packages/jats/title/Title.js +++ b/packages/jats/title/Title.js @@ -8,9 +8,9 @@ function Title() { TextNode.extend(Title); -Title.static.name = 'title'; +Title.type = 'title'; -Title.static.defineSchema({ +Title.define({ attributes: { type: 'object', default: {} }, }); diff --git a/packages/jats/title/package.js b/packages/jats/title/package.js index b789f60d0..127e098f9 100644 --- a/packages/jats/title/package.js +++ b/packages/jats/title/package.js @@ -9,7 +9,7 @@ module.exports = { configure: function(config) { config.addNode(Title); config.addConverter('jats', TitleConverter); - config.addComponent(Title.static.name, TitleComponent); + config.addComponent(Title.type, TitleComponent); config.addStyle(__dirname, '_title.scss'); } }; diff --git a/packages/jats/xref/XRef.js b/packages/jats/xref/XRef.js index b8bbc2654..bfc51e063 100644 --- a/packages/jats/xref/XRef.js +++ b/packages/jats/xref/XRef.js @@ -9,9 +9,9 @@ function XRef() { InlineNode.extend(XRef); -XRef.static.name = 'xref'; +XRef.type = 'xref'; -XRef.static.defineSchema({ +XRef.define({ attributes: { type: 'object', default: {} }, targets: {type: ['id'], default: []}, label: { type: 'text', optional: true } @@ -29,6 +29,6 @@ Object.defineProperties(XRef.prototype, { }); // In presence of overlapping annotations will try to render this as one element -XRef.static.fragmentation = Fragmenter.SHOULD_NOT_SPLIT; +XRef.fragmentation = Fragmenter.SHOULD_NOT_SPLIT; -module.exports = XRef; \ No newline at end of file +module.exports = XRef; diff --git a/packages/jats/xref/XRefCommand.js b/packages/jats/xref/XRefCommand.js index a1ae0b5e5..039af43ca 100644 --- a/packages/jats/xref/XRefCommand.js +++ b/packages/jats/xref/XRefCommand.js @@ -6,12 +6,6 @@ function XRefCommand() { XRefCommand.super.apply(this, arguments); } -XRefCommand.Prototype = function() { - -}; - InlineNodeCommand.extend(XRefCommand); -XRefCommand.static.name = 'xref'; - module.exports = XRefCommand; \ No newline at end of file diff --git a/packages/jats/xref/XRefTool.js b/packages/jats/xref/XRefTool.js index 75a87f798..96d12934e 100644 --- a/packages/jats/xref/XRefTool.js +++ b/packages/jats/xref/XRefTool.js @@ -73,7 +73,7 @@ XRefTool.Prototype = function() { Component.extend(XRefTool); -XRefTool.static.getProps = function(commandStates) { +XRefTool.getProps = function(commandStates) { if (commandStates['xref'].active) { return clone(commandStates['xref']); } else { @@ -81,6 +81,4 @@ XRefTool.static.getProps = function(commandStates) { } }; -XRefTool.static.name = 'xref'; - -module.exports = XRefTool; \ No newline at end of file +module.exports = XRefTool; diff --git a/packages/jats/xref/package.js b/packages/jats/xref/package.js index b7797f0f4..9c2459fdf 100644 --- a/packages/jats/xref/package.js +++ b/packages/jats/xref/package.js @@ -10,12 +10,12 @@ module.exports = { name: 'xref', configure: function(config) { config.addNode(XRef); - config.addComponent(XRef.static.name, XRefComponent); + config.addComponent(XRef.type, XRefComponent); config.addConverter('jats', XRefConverter); - config.addCommand(XRefCommand); - config.addTool(XRefTool, { overlay: true }); + config.addCommand(XRef.type, XRefCommand, {nodeType: XRef.type}); + config.addTool(XRef.type, XRefTool, { overlay: true }); config.addStyle(__dirname, '_xref.scss'); - config.addLabel('xref', { + config.addLabel(XRef.type, { en: 'Cross Reference' }); config.addLabel('edit-xref', { diff --git a/packages/unsupported/UnsupportedInlineNode.js b/packages/unsupported/UnsupportedInlineNode.js index 464beab09..1e2127386 100644 --- a/packages/unsupported/UnsupportedInlineNode.js +++ b/packages/unsupported/UnsupportedInlineNode.js @@ -8,9 +8,9 @@ function UnsupportedInlineNode() { InlineNode.extend(UnsupportedInlineNode); -UnsupportedInlineNode.static.name = 'unsupported-inline'; +UnsupportedInlineNode.type = 'unsupported-inline'; -UnsupportedInlineNode.static.defineSchema({ +UnsupportedInlineNode.define({ xml: 'string', tagName: 'string' }); diff --git a/packages/unsupported/UnsupportedInlineNodeCommand.js b/packages/unsupported/UnsupportedInlineNodeCommand.js index 1ccee415c..86d98862f 100644 --- a/packages/unsupported/UnsupportedInlineNodeCommand.js +++ b/packages/unsupported/UnsupportedInlineNodeCommand.js @@ -7,5 +7,7 @@ function UnsupportedInlineNodeCommand() { } InlineNodeCommand.extend(UnsupportedInlineNodeCommand); -UnsupportedInlineNodeCommand.static.name = 'unsupported-inline'; + +UnsupportedInlineNodeCommand.type = 'unsupported-inline'; + module.exports = UnsupportedInlineNodeCommand; diff --git a/packages/unsupported/UnsupportedInlineNodeTool.js b/packages/unsupported/UnsupportedInlineNodeTool.js index 8a18481d3..2b83f945a 100644 --- a/packages/unsupported/UnsupportedInlineNodeTool.js +++ b/packages/unsupported/UnsupportedInlineNodeTool.js @@ -72,7 +72,7 @@ UnsupportedInlineNodeTool.Prototype = function() { Component.extend(UnsupportedInlineNodeTool); -UnsupportedInlineNodeTool.static.getProps = function(commandStates) { +UnsupportedInlineNodeTool.getProps = function(commandStates) { if (commandStates['unsupported-inline'].active) { return clone(commandStates['unsupported-inline']); } else { @@ -80,6 +80,4 @@ UnsupportedInlineNodeTool.static.getProps = function(commandStates) { } }; -UnsupportedInlineNodeTool.static.name = 'unsupported-inline'; - module.exports = UnsupportedInlineNodeTool; \ No newline at end of file diff --git a/packages/unsupported/UnsupportedNode.js b/packages/unsupported/UnsupportedNode.js index ba8d561d1..85ed99b4a 100644 --- a/packages/unsupported/UnsupportedNode.js +++ b/packages/unsupported/UnsupportedNode.js @@ -8,9 +8,9 @@ function UnsupportedNode() { BlockNode.extend(UnsupportedNode); -UnsupportedNode.static.name = 'unsupported'; +UnsupportedNode.type = 'unsupported'; -UnsupportedNode.static.defineSchema({ +UnsupportedNode.define({ xml: 'string', tagName: 'string' }); diff --git a/packages/unsupported/UnsupportedNodeComponent.js b/packages/unsupported/UnsupportedNodeComponent.js index 0a4785f41..1e20503cb 100644 --- a/packages/unsupported/UnsupportedNodeComponent.js +++ b/packages/unsupported/UnsupportedNodeComponent.js @@ -28,7 +28,7 @@ UnsupportedNodeComponent.Prototype = function() { Component.extend(UnsupportedNodeComponent); -UnsupportedNodeComponent.static.fullWidth = true; -UnsupportedNodeComponent.static.noStyle = true; +UnsupportedNodeComponent.fullWidth = true; +UnsupportedNodeComponent.noStyle = true; module.exports = UnsupportedNodeComponent; \ No newline at end of file diff --git a/packages/unsupported/UnsupportedNodePackage.js b/packages/unsupported/UnsupportedNodePackage.js index 40663698b..4ff302a3f 100644 --- a/packages/unsupported/UnsupportedNodePackage.js +++ b/packages/unsupported/UnsupportedNodePackage.js @@ -14,11 +14,11 @@ module.exports = { configure: function(config) { config.addNode(UnsupportedNode); config.addNode(UnsupportedInlineNode); - config.addComponent(UnsupportedNode.static.name, UnsupportedNodeComponent); - config.addComponent(UnsupportedInlineNode.static.name, UnsupportedInlineNodeComponent); - config.addCommand(UnsupportedInlineNodeCommand); - config.addTool(UnsupportedInlineNodeTool, { overlay: true }); + config.addComponent(UnsupportedNode.type, UnsupportedNodeComponent); + config.addComponent(UnsupportedInlineNode.type, UnsupportedInlineNodeComponent); + config.addCommand(UnsupportedInlineNode.type, UnsupportedInlineNodeCommand, {nodeType: UnsupportedInlineNode.type}); + config.addTool(UnsupportedInlineNode.type, UnsupportedInlineNodeTool, { overlay: true }); config.addConverter('jats', UnsupportedNodeJATSConverter); config.addConverter('jats', UnsupportedInlineNodeJATSConverter); } -}; \ No newline at end of file +}; diff --git a/util/toDOM.js b/util/toDOM.js index 792bfa75b..e5e7d7d10 100644 --- a/util/toDOM.js +++ b/util/toDOM.js @@ -8,7 +8,7 @@ var DOMElement = require('substance/ui/DefaultDOMElement'); @return {substance/ui/DOMElement} A wrapped DOM element */ module.exports = function toDOM(node) { - var tagName = node.constructor.static.tagName || node.constructor.static.name; + var tagName = node.constructor.tagName || node.constructor.type; var el = DOMElement.parseXML('<'+tagName+'>'+node.xmlContent+''); el.attr(node.attributes); return el; From 3f773eac5ae6be48066d299fe94c264df65075f6 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sun, 24 Jul 2016 19:35:31 +0300 Subject: [PATCH 032/167] Fix regressions. --- packages/jats/bold/BoldTool.js | 2 ++ packages/jats/xref/XRefTool.js | 4 ++-- .../unsupported/UnsupportedInlineNodeTool.js | 4 ++-- server.js | 16 +++++++++++++--- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/jats/bold/BoldTool.js b/packages/jats/bold/BoldTool.js index 5e3e6afc9..6a7cbfbae 100644 --- a/packages/jats/bold/BoldTool.js +++ b/packages/jats/bold/BoldTool.js @@ -1,5 +1,7 @@ 'use strict'; +var AnnotationTool = require('substance/ui/AnnotationTool'); + function BoldTool() { BoldTool.super.apply(this, arguments); } diff --git a/packages/jats/xref/XRefTool.js b/packages/jats/xref/XRefTool.js index 96d12934e..863f61d1c 100644 --- a/packages/jats/xref/XRefTool.js +++ b/packages/jats/xref/XRefTool.js @@ -1,6 +1,6 @@ 'use strict'; -var Component = require('substance/ui/Component'); +var Tool = require('substance/ui/Tool'); var clone = require('lodash/clone'); var Modal = require('substance/ui/Modal'); var XRefTargets = require('./XRefTargets'); @@ -71,7 +71,7 @@ XRefTool.Prototype = function() { }; }; -Component.extend(XRefTool); +Tool.extend(XRefTool); XRefTool.getProps = function(commandStates) { if (commandStates['xref'].active) { diff --git a/packages/unsupported/UnsupportedInlineNodeTool.js b/packages/unsupported/UnsupportedInlineNodeTool.js index 2b83f945a..8018c2529 100644 --- a/packages/unsupported/UnsupportedInlineNodeTool.js +++ b/packages/unsupported/UnsupportedInlineNodeTool.js @@ -1,6 +1,6 @@ 'use strict'; -var Component = require('substance/ui/Component'); +var Tool = require('substance/ui/Tool'); var clone = require('lodash/clone'); var Modal = require('substance/ui/Modal'); var Prompt = require('substance/ui/Prompt'); @@ -70,7 +70,7 @@ UnsupportedInlineNodeTool.Prototype = function() { }; }; -Component.extend(UnsupportedInlineNodeTool); +Tool.extend(UnsupportedInlineNodeTool); UnsupportedInlineNodeTool.getProps = function(commandStates) { if (commandStates['unsupported-inline'].active) { diff --git a/server.js b/server.js index e11759551..e5680fa93 100644 --- a/server.js +++ b/server.js @@ -8,13 +8,20 @@ var PORT = process.env.PORT || 5001; var serverUtils = require('substance/util/server'); var app = express(); +var browserifyConfig = { + debug: true +}; + // Writer example integration serverUtils.serveStyles(app, '/jats-editor/app.css', { rootDir: __dirname, configuratorPath: require.resolve('./packages/scientist/ScientistConfigurator'), - configPath: require.resolve('./examples/jats-editor/package') + configPath: require.resolve('./examples/jats-editor/package'), +}); +serverUtils.serveJS(app, '/jats-editor/app.js', { + sourcePath: path.join(__dirname, 'examples/jats-editor', 'app.js'), + browserify: browserifyConfig, }); -serverUtils.serveJS(app, '/jats-editor/app.js', path.join(__dirname, 'examples/jats-editor', 'app.js')); serverUtils.serveHTML(app, '/jats-editor', path.join(__dirname, 'examples/jats-editor', 'index.html'), {}); serverUtils.serveStyles(app, '/science-writer/app.css', { @@ -22,7 +29,10 @@ serverUtils.serveStyles(app, '/science-writer/app.css', { configuratorPath: require.resolve('./packages/scientist/ScientistConfigurator'), configPath: require.resolve('./examples/science-writer/package'), }); -serverUtils.serveJS(app, '/science-writer/app.js', path.join(__dirname, 'examples/science-writer', 'app.js')); +serverUtils.serveJS(app, '/science-writer/app.js', { + sourcePath: path.join(__dirname, 'examples/science-writer', 'app.js'), + browserify: browserifyConfig, +}); serverUtils.serveHTML(app, '/science-writer', path.join(__dirname, 'examples/science-writer', 'index.html'), {}); // static served data From 75eb5b38d83ffde2f0ed1a1a79375a405a01d27f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sun, 24 Jul 2016 19:42:24 +0300 Subject: [PATCH 033/167] Switch to substance#refactorings --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 70322b9d0..34dd95fb1 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "A scientific editor and reader for JATS files.", "dependencies": { "lodash": "^4.2.1", - "substance": "substance/substance#develop" + "substance": "substance/substance#refactorings" }, "devDependencies": { "browserify": "substance/node-browserify#d3caeb6dcdaa97a258d099c7231a57f0f60ec876", From b50964a081a58658b32573b1e631901b85d3ddfb Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sun, 24 Jul 2016 18:51:39 +0200 Subject: [PATCH 034/167] Unsupported nodes improvements Store attributes and xmlContent separately in unsupported nodes. Reuse generic EditXML component. --- packages/unsupported/UnsupportedInlineNode.js | 3 ++- .../UnsupportedInlineNodeJATSConverter.js | 14 +++------- .../unsupported/UnsupportedInlineNodeTool.js | 4 +-- packages/unsupported/UnsupportedNode.js | 3 ++- .../UnsupportedNodeJATSConverter.js | 7 ++--- test/jats/unsupported.test.js | 26 +++++++++++++++++++ 6 files changed, 40 insertions(+), 17 deletions(-) create mode 100644 test/jats/unsupported.test.js diff --git a/packages/unsupported/UnsupportedInlineNode.js b/packages/unsupported/UnsupportedInlineNode.js index 1e2127386..f4fd275a2 100644 --- a/packages/unsupported/UnsupportedInlineNode.js +++ b/packages/unsupported/UnsupportedInlineNode.js @@ -11,7 +11,8 @@ InlineNode.extend(UnsupportedInlineNode); UnsupportedInlineNode.type = 'unsupported-inline'; UnsupportedInlineNode.define({ - xml: 'string', + attributes: { type: 'object', default: {} }, + xmlContent: {type: 'string', default: ''}, tagName: 'string' }); diff --git a/packages/unsupported/UnsupportedInlineNodeJATSConverter.js b/packages/unsupported/UnsupportedInlineNodeJATSConverter.js index 2d14f04d6..3ccda0147 100644 --- a/packages/unsupported/UnsupportedInlineNodeJATSConverter.js +++ b/packages/unsupported/UnsupportedInlineNodeJATSConverter.js @@ -1,5 +1,7 @@ 'use strict'; +var UnsupportedNodeJATSConverter = require('./UnsupportedNodeJATSConverter'); + module.exports = { type: 'unsupported-inline', @@ -8,14 +10,6 @@ module.exports = { return true; }, - import: function(el, node) { - node.xml = el.outerHTML; - node.tagName = el.tagName; - }, - - export: function(node, el) { - el.innerHTML = node.xml; - return el.children[0]; - } - + import: UnsupportedNodeJATSConverter.import, + export: UnsupportedNodeJATSConverter.export }; diff --git a/packages/unsupported/UnsupportedInlineNodeTool.js b/packages/unsupported/UnsupportedInlineNodeTool.js index 8018c2529..6ede37980 100644 --- a/packages/unsupported/UnsupportedInlineNodeTool.js +++ b/packages/unsupported/UnsupportedInlineNodeTool.js @@ -4,7 +4,7 @@ var Tool = require('substance/ui/Tool'); var clone = require('lodash/clone'); var Modal = require('substance/ui/Modal'); var Prompt = require('substance/ui/Prompt'); -var EditXML = require('./EditXML'); +var EditXML = require('../common/EditXML'); var deleteSelection = require('substance/model/transform/deleteSelection'); /* @@ -61,7 +61,7 @@ UnsupportedInlineNodeTool.Prototype = function() { width: 'medium' }).append( $$(EditXML, { - path: [node.id, 'xml'] + node: node }) ) ); diff --git a/packages/unsupported/UnsupportedNode.js b/packages/unsupported/UnsupportedNode.js index 85ed99b4a..ee4206ba4 100644 --- a/packages/unsupported/UnsupportedNode.js +++ b/packages/unsupported/UnsupportedNode.js @@ -11,7 +11,8 @@ BlockNode.extend(UnsupportedNode); UnsupportedNode.type = 'unsupported'; UnsupportedNode.define({ - xml: 'string', + attributes: { type: 'object', default: {} }, + xmlContent: {type: 'string', default: ''}, tagName: 'string' }); diff --git a/packages/unsupported/UnsupportedNodeJATSConverter.js b/packages/unsupported/UnsupportedNodeJATSConverter.js index 2bfe1b98a..1ab4f43fe 100644 --- a/packages/unsupported/UnsupportedNodeJATSConverter.js +++ b/packages/unsupported/UnsupportedNodeJATSConverter.js @@ -9,13 +9,14 @@ module.exports = { }, import: function(el, node) { - node.xml = el.outerHTML; + node.xmlContent = el.innerHTML; node.tagName = el.tagName; }, export: function(node, el) { - el.innerHTML = node.xml; - return el.children[0]; + el.tagName = node.tagName; + el.innerHTML = node.xmlContent; + return el; } }; diff --git a/test/jats/unsupported.test.js b/test/jats/unsupported.test.js new file mode 100644 index 000000000..f16eddb3c --- /dev/null +++ b/test/jats/unsupported.test.js @@ -0,0 +1,26 @@ +'use strict'; + +var test = require('./test').module('jats/unsupported'); + +// attributes should be preserved +var withAttributes = + ''; +test.attributesConversion(withAttributes, 'foo-bar'); + +var simple = + ''+ + 'hello'+ + 'world'+ + ''; +test.withFixture(simple, 'Im-/Exporting of unsupported node type', function(t) { + // import + var importer = t.fixture.createImporter('article'); + var node = importer.convertElement(t.fixture.xmlElement); + t.equal(node.xmlContent, 'helloworld'); + // export + var exporter = t.fixture.createExporter(); + var el = exporter.convertNode(node); + t.ok(el.getChildAt(0).is('x'), '.. having an '); + t.ok(el.getChildAt(1).is('y'), '.. having a '); + t.end(); +}); From c0f1cb979c3275df94d486d8092201133b48ef47 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sun, 24 Jul 2016 19:07:35 +0200 Subject: [PATCH 035/167] Minor XML Editor fixes. --- packages/common/XMLAttributeEditor.js | 2 +- packages/common/_edit-xml.scss | 9 ++-- packages/unsupported/EditXML.js | 47 ------------------- .../unsupported/UnsupportedNodeComponent.js | 2 +- 4 files changed, 7 insertions(+), 53 deletions(-) delete mode 100644 packages/unsupported/EditXML.js diff --git a/packages/common/XMLAttributeEditor.js b/packages/common/XMLAttributeEditor.js index f78daf72d..7a498c4fa 100644 --- a/packages/common/XMLAttributeEditor.js +++ b/packages/common/XMLAttributeEditor.js @@ -34,7 +34,7 @@ XMLAttributeEditor.Prototype = function() { this.render = function($$) { var node = this.props.node; - var el = $$('div').addClass('sc-edit-xml-attributes'); + var el = $$('div').addClass('sc-xml-attribute-editor'); var attributeStr = this._getAttributeString(node); el.append( $$('textarea') diff --git a/packages/common/_edit-xml.scss b/packages/common/_edit-xml.scss index fbf9d3113..3614575d3 100644 --- a/packages/common/_edit-xml.scss +++ b/packages/common/_edit-xml.scss @@ -3,10 +3,11 @@ textarea { font-family: $font-family-code; - font-size: $font-size-code; + font-size: $font-size-code - 2px; border: 1px solid #ddd; - padding: 20px; - resize: none; + padding: 10px; + width: 100%; + // resize: none; } .se-tag { @@ -29,6 +30,6 @@ .sc-xml-editor textarea { width: 100%; - height: 300px; + height: 270px; } diff --git a/packages/unsupported/EditXML.js b/packages/unsupported/EditXML.js deleted file mode 100644 index ca351b0cc..000000000 --- a/packages/unsupported/EditXML.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict'; - -var Component = require('substance/ui/Component'); - -/* - Takes a path to an XML string and makes it editable -*/ -function EditXML() { - Component.apply(this, arguments); -} - -EditXML.Prototype = function() { - - this._save = function() { - var newXML = this.refs.xml.val(); - var path = this.props.path; - var documentSession = this.context.documentSession; - - documentSession.transaction(function(tx) { - tx.set(path, newXML); - }); - this.send('xmlSaved', newXML); - }; - - this.render = function($$) { - var el = $$('div').addClass('sc-edit-xml'); - var documentSession = this.context.documentSession; - var doc = documentSession.getDocument(); - var xml = doc.get(this.props.path); - - el.append( - $$('textarea') - .ref('xml') - .append(xml) - ); - - el.append( - $$('button').append('Save').on('click', this._save) - ); - - return el; - }; -}; - -Component.extend(EditXML); -module.exports = EditXML; - diff --git a/packages/unsupported/UnsupportedNodeComponent.js b/packages/unsupported/UnsupportedNodeComponent.js index 1e20503cb..25360af10 100644 --- a/packages/unsupported/UnsupportedNodeComponent.js +++ b/packages/unsupported/UnsupportedNodeComponent.js @@ -17,7 +17,7 @@ UnsupportedNodeComponent.Prototype = function() { $$('button').addClass('se-toggle').append( $$('pre').append( $$('code').append( - this.props.node.tagName + '<'+this.props.node.tagName+'>' ) ) ) From a288600902a01eab73686995636500eaac0f2ecb Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sun, 24 Jul 2016 21:06:04 +0200 Subject: [PATCH 036/167] Improved styles. --- packages/author/Author.js | 8 +++--- packages/author/_author.scss | 4 +-- packages/common/_isolated-node.scss | 39 +++++++++++++++++++++++++++++ packages/common/package.js | 1 + packages/jats/article/_article.scss | 4 +++ packages/jats/article/package.js | 1 + packages/jats/section/_section.scss | 31 ----------------------- packages/publisher/Publisher.js | 8 +++--- packages/publisher/_publisher.scss | 6 ++++- 9 files changed, 60 insertions(+), 42 deletions(-) create mode 100644 packages/common/_isolated-node.scss create mode 100644 packages/jats/article/_article.scss diff --git a/packages/author/Author.js b/packages/author/Author.js index ee397b388..bb5ab9fa0 100644 --- a/packages/author/Author.js +++ b/packages/author/Author.js @@ -17,9 +17,9 @@ Author.Prototype = function() { this.render = function($$) { var el = $$('div').addClass('sc-author'); el.append( - $$(SplitPane, {splitType: 'vertical', sizeA: '300px'}).append( - this._renderContextSection($$), - this._renderMainSection($$) + $$(SplitPane, {splitType: 'vertical', sizeB: '400px'}).append( + this._renderMainSection($$), + this._renderContextSection($$) ) ); return el; @@ -49,7 +49,7 @@ Author.Prototype = function() { var contentPanel = $$(ScrollPane, { tocProvider: this.tocProvider, scrollbarType: 'substance', - scrollbarPosition: 'right', + scrollbarPosition: 'left', overlay: Overlay, }).ref('contentPanel'); diff --git a/packages/author/_author.scss b/packages/author/_author.scss index 49ae1e3b7..c45e9d0b1 100644 --- a/packages/author/_author.scss +++ b/packages/author/_author.scss @@ -5,14 +5,14 @@ $fa-font-path: "../fonts" !default; .se-context-section { background: #fafafa; - border-right: 1px solid $border-color; + border-left: 1px solid $border-color; .se-toc-entries { padding-right: 20px; } } - .se-body-section > .sc-container-editor * + * { + .sc-body > .sc-container-editor > * { margin-bottom: 20px; } diff --git a/packages/common/_isolated-node.scss b/packages/common/_isolated-node.scss new file mode 100644 index 000000000..66065efaf --- /dev/null +++ b/packages/common/_isolated-node.scss @@ -0,0 +1,39 @@ +/* + Custom stlye for isolated node overlays etc. +*/ +.sc-isolated-node { + position: relative; +} + +.sm-selected > .se-container ::selection { + background: transparent; +} + +.sc-isolated-node.sm-selected > .se-container, { + background: rgba(163, 205, 253, 0.3); + outline: 2px solid #A3CDFD; +} + +/* + Enable below rules for debugging to check whether proper + modifiers are applied +*/ + +// .sc-isolated-node > .se-container:hover, { +// background: rgba(163, 205, 253, 0.3); +// outline: 2px solid #A3CDFD; // rgba(#A3CDFD, 0.4); +// } + +// .sc-isolated-node > .se-container { +// // padding: 10px 5px; +// } + +// .sc-isolated-node.sm-co-focused > .se-container { +// background: #fff; +// outline: none; +// } + +// .sc-isolated-node.sm-focused > .se-container { +// background: #fff; +// outline: 2px solid #A3CDFD; +// } \ No newline at end of file diff --git a/packages/common/package.js b/packages/common/package.js index ac081abf8..9d918173f 100644 --- a/packages/common/package.js +++ b/packages/common/package.js @@ -3,6 +3,7 @@ module.exports = { name: 'common', configure: function(config) { + config.addStyle(__dirname, '_isolated-node.scss'); config.addStyle(__dirname, '_edit-xml.scss'); } }; \ No newline at end of file diff --git a/packages/jats/article/_article.scss b/packages/jats/article/_article.scss new file mode 100644 index 000000000..d81d4bedf --- /dev/null +++ b/packages/jats/article/_article.scss @@ -0,0 +1,4 @@ +.sc-article { + padding-left: 20px; + padding-right: 20px; +} \ No newline at end of file diff --git a/packages/jats/article/package.js b/packages/jats/article/package.js index d5f20b32e..2b23f687b 100644 --- a/packages/jats/article/package.js +++ b/packages/jats/article/package.js @@ -14,6 +14,7 @@ module.exports = { defaultTextType: 'paragraph' }); + config.addStyle(__dirname, '_article.scss'); config.addNode(ArticleNode); config.addConverter('jats', ArticleConverter); config.addComponent(ArticleNode.type, ArticleComponent); diff --git a/packages/jats/section/_section.scss b/packages/jats/section/_section.scss index 04f2217dd..6c35460fc 100644 --- a/packages/jats/section/_section.scss +++ b/packages/jats/section/_section.scss @@ -1,34 +1,3 @@ -/* Isolated nodes hacks */ -// .sc-isolated-node.sm-section { -.sc-isolated-node { - position: relative; - - &.sm-selected > .se-container ::selection { - background: transparent; - } -} - -.sc-isolated-node > .se-container { - padding: 10px 20px; - outline: 2px solid transparent; -} - -.sc-isolated-node > .se-container:hover, { - // background: rgba(163, 205, 253, 0.1); - outline: 2px solid rgba(#A3CDFD, 0.4); -} - -.sc-isolated-node.sm-selected > .se-container, { - background: rgba(163, 205, 253, 0.3); - outline: 2px solid rgba(#A3CDFD, 1); -} - -.sc-isolated-node.sm-focused > .se-container { - background: #fff; - outline: none; - outline: 2px solid #A3CDFD; -} - .sc-section > .se-title { font-size: $h1-font-size; margin-bottom: $h1-font-size; diff --git a/packages/publisher/Publisher.js b/packages/publisher/Publisher.js index e20f7f1de..230166477 100644 --- a/packages/publisher/Publisher.js +++ b/packages/publisher/Publisher.js @@ -17,9 +17,9 @@ PublisherWriter.Prototype = function() { this.render = function($$) { var el = $$('div').addClass('sc-publisher'); el.append( - $$(SplitPane, {splitType: 'vertical', sizeA: '300px'}).append( - this._renderContextSection($$), - this._renderMainSection($$) + $$(SplitPane, {splitType: 'vertical', sizeB: '400px'}).append( + this._renderMainSection($$), + this._renderContextSection($$) ) ); return el; @@ -47,7 +47,7 @@ PublisherWriter.Prototype = function() { var contentPanel = $$(ScrollPane, { tocProvider: this.tocProvider, scrollbarType: 'substance', - scrollbarPosition: 'right', + scrollbarPosition: 'left', overlay: Overlay, }).ref('contentPanel'); diff --git a/packages/publisher/_publisher.scss b/packages/publisher/_publisher.scss index 0cad77d99..7d2c1616e 100644 --- a/packages/publisher/_publisher.scss +++ b/packages/publisher/_publisher.scss @@ -4,13 +4,17 @@ $fa-font-path: "../fonts" !default; .sc-publisher { .se-context-section { background: #fafafa; - border-right: 1px solid $border-color; + border-left: 1px solid $border-color; .se-toc-entries { padding-right: 20px; } } + .sc-body .sc-container-editor > * { + margin-bottom: 20px; + } + .sc-toolbar { border-bottom: 1px solid $border-color; } From 4964c02a7b6066dd38ccaf59b15d0800e8fac80c Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sun, 24 Jul 2016 21:33:30 +0200 Subject: [PATCH 037/167] Various UI/UX improvements. --- packages/common/EditXML.js | 5 ++-- packages/jats/back/BackComponent.js | 27 ++++++++++++++-------- packages/jats/back/_back.scss | 4 ++++ packages/jats/back/package.js | 1 + packages/jats/contrib/Contrib.js | 8 ++----- packages/jats/contrib/ContribConverter.js | 1 + packages/jats/ref-list/RefListComponent.js | 21 +++++++++++++---- packages/jats/ref-list/_ref-list.scss | 4 ++++ 8 files changed, 48 insertions(+), 23 deletions(-) create mode 100644 packages/jats/back/_back.scss diff --git a/packages/common/EditXML.js b/packages/common/EditXML.js index 8ff1f90f0..15a11d1bd 100644 --- a/packages/common/EditXML.js +++ b/packages/common/EditXML.js @@ -13,9 +13,10 @@ EditXML.Prototype = function() { this.render = function($$) { var node = this.props.node; var el = $$('div').addClass('sc-edit-xml'); + var tagName = node.tagName; el.append( - $$('div').addClass('se-tag sm-open-tag-start').append('') + $$('div').addClass('se-tag sm-end-tag').append('') ); el.append( diff --git a/packages/jats/back/BackComponent.js b/packages/jats/back/BackComponent.js index 581693996..dc6c4db3d 100644 --- a/packages/jats/back/BackComponent.js +++ b/packages/jats/back/BackComponent.js @@ -1,7 +1,7 @@ 'use strict'; var Component = require('substance/ui/Component'); -var ContainerEditor = require('substance/ui/ContainerEditor'); +var renderNodeComponent = require('../../../util/renderNodeComponent'); function BackComponent() { Component.apply(this, arguments); @@ -11,19 +11,26 @@ BackComponent.Prototype = function() { this.render = function($$) { var node = this.props.node; - var configurator = this.props.configurator; + var doc = node.getDocument(); + var el = $$('div') .addClass('sc-back') .attr('data-id', this.props.node.id); - el.append( - $$(ContainerEditor, { - disabled: this.props.disabled, - node: node, - commands: configurator.getSurfaceCommandNames(), - textTypes: configurator.getTextTypes() - }).ref('back') - ); + // Ref elements + var children = node.nodes; + children.forEach(function(nodeId) { + var childNode = doc.get(nodeId); + if (childNode.type !== 'unsupported') { + el.append( + renderNodeComponent(this, $$, childNode, { + disabled: this.props.disabled + }) + ); + } else { + console.info(childNode.type+ ' inside currently not supported by the editor.'); + } + }.bind(this)); return el; }; diff --git a/packages/jats/back/_back.scss b/packages/jats/back/_back.scss new file mode 100644 index 000000000..bf4b58886 --- /dev/null +++ b/packages/jats/back/_back.scss @@ -0,0 +1,4 @@ +.sc-back { + border-top: 1px dotted #ddd; + margin-top: 40px; +} \ No newline at end of file diff --git a/packages/jats/back/package.js b/packages/jats/back/package.js index 8ba28bbf0..673df89b2 100644 --- a/packages/jats/back/package.js +++ b/packages/jats/back/package.js @@ -10,5 +10,6 @@ module.exports = { config.addNode(Back); config.addConverter('jats', BackConverter); config.addComponent(Back.type, BackComponent); + config.addStyle(__dirname, '_back.scss'); } }; \ No newline at end of file diff --git a/packages/jats/contrib/Contrib.js b/packages/jats/contrib/Contrib.js index 2673b26d8..b8166e05a 100644 --- a/packages/jats/contrib/Contrib.js +++ b/packages/jats/contrib/Contrib.js @@ -2,11 +2,6 @@ var DocumentNode = require('substance/model/DocumentNode'); -/* - ref - - One item in a bibliographic list. -*/ function Contrib() { Contrib.super.apply(this, arguments); } @@ -21,7 +16,8 @@ Contrib.type = 'contrib'; */ Contrib.define({ attributes: { type: 'object', default: {} }, - xmlContent: {type: 'string', default: ''} + xmlContent: {type: 'string', default: ''}, + tagName: 'string' }); module.exports = Contrib; diff --git a/packages/jats/contrib/ContribConverter.js b/packages/jats/contrib/ContribConverter.js index c536b58fd..3c2950e7b 100644 --- a/packages/jats/contrib/ContribConverter.js +++ b/packages/jats/contrib/ContribConverter.js @@ -10,6 +10,7 @@ module.exports = { */ import: function(el, node, converter) { // eslint-disable-line node.xmlContent = el.innerHTML; + node.tagName = el.tagName; }, export: function(node, el, converter) { // eslint-disable-line diff --git a/packages/jats/ref-list/RefListComponent.js b/packages/jats/ref-list/RefListComponent.js index 698cfebc6..5f384b171 100644 --- a/packages/jats/ref-list/RefListComponent.js +++ b/packages/jats/ref-list/RefListComponent.js @@ -1,7 +1,6 @@ 'use strict'; var Component = require('substance/ui/Component'); -var ContainerEditor = require('substance/ui/ContainerEditor'); var renderNodeComponent = require('../../../util/renderNodeComponent'); function RefListComponent() { @@ -24,10 +23,22 @@ RefListComponent.Prototype = function() { }) ); } - el.append( - $$(ContainerEditor, { node: node }).ref('contentEditor') - .addClass('se-content') - ); + + // Ref elements + var children = node.nodes; + children.forEach(function(nodeId) { + var childNode = doc.get(nodeId); + if (childNode.type !== 'unsupported') { + el.append( + renderNodeComponent(this, $$, childNode, { + disabled: this.props.disabled + }) + ); + } else { + console.info(childNode.type+ ' inside currently not supported by the editor.'); + } + }.bind(this)); + return el; }; }; diff --git a/packages/jats/ref-list/_ref-list.scss b/packages/jats/ref-list/_ref-list.scss index 23197c41f..dc665a1cf 100644 --- a/packages/jats/ref-list/_ref-list.scss +++ b/packages/jats/ref-list/_ref-list.scss @@ -1,3 +1,7 @@ .sc-ref-list { + font-size: $small-font-size; + .sc-ref { + margin-bottom: 20px; + } } \ No newline at end of file From 3a0df20ddadc49220bd31e8b30459f30a6adcde4 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 25 Jul 2016 02:55:14 +0200 Subject: [PATCH 038/167] No need for an article converter here. --- test/jats/unsupported.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jats/unsupported.test.js b/test/jats/unsupported.test.js index f16eddb3c..dc0085532 100644 --- a/test/jats/unsupported.test.js +++ b/test/jats/unsupported.test.js @@ -14,7 +14,7 @@ var simple = ''; test.withFixture(simple, 'Im-/Exporting of unsupported node type', function(t) { // import - var importer = t.fixture.createImporter('article'); + var importer = t.fixture.createImporter(); var node = importer.convertElement(t.fixture.xmlElement); t.equal(node.xmlContent, 'helloworld'); // export From 8843b4dbc79ceb6f8dfab409c000bf98be7d38c0 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 25 Jul 2016 03:09:06 +0200 Subject: [PATCH 039/167] Remove debug styles. --- packages/common/_isolated-node.scss | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/packages/common/_isolated-node.scss b/packages/common/_isolated-node.scss index 66065efaf..6355f8933 100644 --- a/packages/common/_isolated-node.scss +++ b/packages/common/_isolated-node.scss @@ -12,28 +12,4 @@ .sc-isolated-node.sm-selected > .se-container, { background: rgba(163, 205, 253, 0.3); outline: 2px solid #A3CDFD; -} - -/* - Enable below rules for debugging to check whether proper - modifiers are applied -*/ - -// .sc-isolated-node > .se-container:hover, { -// background: rgba(163, 205, 253, 0.3); -// outline: 2px solid #A3CDFD; // rgba(#A3CDFD, 0.4); -// } - -// .sc-isolated-node > .se-container { -// // padding: 10px 5px; -// } - -// .sc-isolated-node.sm-co-focused > .se-container { -// background: #fff; -// outline: none; -// } - -// .sc-isolated-node.sm-focused > .se-container { -// background: #fff; -// outline: 2px solid #A3CDFD; -// } \ No newline at end of file +} \ No newline at end of file From f6c22dd6dc5c0b1f35915a4f9c58288a1212c66d Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 25 Jul 2016 03:21:05 +0200 Subject: [PATCH 040/167] Point Substance back to develop branch. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 34dd95fb1..70322b9d0 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "A scientific editor and reader for JATS files.", "dependencies": { "lodash": "^4.2.1", - "substance": "substance/substance#refactorings" + "substance": "substance/substance#develop" }, "devDependencies": { "browserify": "substance/node-browserify#d3caeb6dcdaa97a258d099c7231a57f0f60ec876", From 54b4267e87a07b48d32b5a88b4f2ee967b7be79a Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 28 Jul 2016 09:24:35 -0400 Subject: [PATCH 041/167] Update README.md --- README.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index b70bba6f9..a2a05599c 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,19 @@ -# Substance Scientist [![Build Status](https://travis-ci.org/substance/scientist.svg?branch=develop)](https://travis-ci.org/substance/scientist) +# Texture [![Build Status](https://travis-ci.org/substance/texture.svg?branch=develop)](https://travis-ci.org/substance/texture) -This is a work-in progress. The project name Scientist is temporary and may be changed with the first beta release. +Texture is a collection of components for realizing content production systems. It has first-class support for JATS, the de facto standard for archiving and interchange of scientific open-access journals and its contents with XML. ## Install Clone the repository. ```bash -$ git clone https://github.com/substance/scientist.git +$ git clone https://github.com/substance/texture.git ``` Navigate to the source directory. ```bash -$ cd scientist +$ cd texture ``` At the moment, the default branch provides the develop version. @@ -47,16 +47,16 @@ $ npm test ## Usage -Here's how you can integrate Scientist into your web app. +Here's how you can integrate Texture into your web app. ```js // app.js -var Scientist = require('substance-scientist'); -var myScientistPackage = require('./myScientistPackage'); -var configurator = new Scientist.Configurator(myScientistPackage); +var Texture = require('substance-texture'); +var myTexturePackage = require('./myTexturePackage'); +var configurator = new Texture.Configurator(myTexturePackage); window.onload = function() { - window.app = Scientist.static.mount({ + window.app = Texture.mount({ mode: 'publisher', // or 'author' or 'reader' documentId: 'doc-1', configurator: configurator @@ -64,29 +64,29 @@ window.onload = function() { }; ``` -Scientist is fully configurable. So you need to supply a custom configuration via a package defintion. +Texture is fully configurable. So you need to supply a custom configuration via a package defintion. ```js -// myScientistPackage.js +// myTexturePackage.js var MyXMLStore = require('../MyXMLStore'); -var scientistPackage = require('substance-scientist/packages/scientist/package'); +var texturePackage = require('substance-texture/packages/texture/package'); var path = require('path'); module.exports = { - name: 'my-scientist', + name: 'my-texture', configure: function(config) { - // Use the default Scientist package - config.import(scientistPackage); + // Use the default Texture package + config.import(texturePackage); // Define XML Store config.setXMLStore(MyXMLStore); // Add your custom app styles - config.addStyle(__dirname, 'my-scientist.scss'); + config.addStyle(__dirname, 'my-texture.scss'); } }; ``` -In order to connect Scientist to a backend you need to define an XML Store: +In order to connect Texture to a backend you need to define an XML Store: ```js // MyXMLStore.js @@ -149,9 +149,9 @@ See [CONTRIBUTING.md](CONTRIBUTING.md). # Credits -Scientist is developed by the [Substance Consortium](http://substance.io/consortium/) formed by the [Public Knowledge Project](https://pkp.sfu.ca/2016/04/27/substance-consortium/) (PKP), the [Collaborative Knowledge Foundation](http://coko.foundation/blog.html#substance_consortium) (CoKo) and [Érudit](https://apropos.erudit.org/fr/creation-dun-consortium-autour-de-substance/). +Texture is developed by the [Substance Consortium](http://substance.io/consortium/) formed by the [Public Knowledge Project](https://pkp.sfu.ca/2016/04/27/substance-consortium/) (PKP), the [Collaborative Knowledge Foundation](http://coko.foundation/blog.html#substance_consortium) (CoKo) and [Érudit](https://apropos.erudit.org/fr/creation-dun-consortium-autour-de-substance/). -Thanks goes to the following people, who made Scientist possible: +Thanks goes to the following people, who make Texture possible: - Alex Garnett (leadership, concept) - Juan Pablo Alperin (leadership, concept) From 0d1416ccdeb5d225b0579f9e522cb64c33da531a Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 28 Jul 2016 11:48:37 -0400 Subject: [PATCH 042/167] Scientist is now Texture. --- examples/author/app.js | 16 +++++++++++ examples/{science-writer => author}/app.scss | 0 .../{science-writer => author}/index.html | 0 examples/{jats-editor => author}/package.js | 8 +++--- examples/config.js | 2 +- examples/data/kitchen-sink-author.xml | 28 +++++++++---------- examples/index.html | 4 +-- examples/jats-editor/app.js | 18 ------------ examples/publisher/app.js | 17 +++++++++++ examples/{jats-editor => publisher}/app.scss | 0 .../{jats-editor => publisher}/index.html | 0 .../{science-writer => publisher}/package.js | 7 ++--- examples/science-writer/app.js | 17 ----------- packages/jats/back/_back.scss | 2 +- .../Scientist.js => texture/Texture.js} | 13 ++++----- .../TextureConfigurator.js} | 10 +++---- packages/{scientist => texture}/package.js | 0 server.js | 24 ++++++++-------- 18 files changed, 80 insertions(+), 86 deletions(-) create mode 100644 examples/author/app.js rename examples/{science-writer => author}/app.scss (100%) rename examples/{science-writer => author}/index.html (100%) rename examples/{jats-editor => author}/package.js (58%) delete mode 100644 examples/jats-editor/app.js create mode 100644 examples/publisher/app.js rename examples/{jats-editor => publisher}/app.scss (100%) rename examples/{jats-editor => publisher}/index.html (100%) rename examples/{science-writer => publisher}/package.js (57%) delete mode 100644 examples/science-writer/app.js rename packages/{scientist/Scientist.js => texture/Texture.js} (91%) rename packages/{scientist/ScientistConfigurator.js => texture/TextureConfigurator.js} (85%) rename packages/{scientist => texture}/package.js (100%) diff --git a/examples/author/app.js b/examples/author/app.js new file mode 100644 index 000000000..b4464ef51 --- /dev/null +++ b/examples/author/app.js @@ -0,0 +1,16 @@ +'use strict'; + +var substanceGlobals = require('substance/util/substanceGlobals'); +substanceGlobals.DEBUG_RENDERING = true; + +var Texture = require('../../packages/texture/Texture'); +var TextureConfigurator = require('../../packages/texture/TextureConfigurator'); +var configurator = new TextureConfigurator().import(require('./package')); + +window.onload = function() { + window.app = Texture.mount({ + mode: 'author', + documentId: 'kitchen-sink-author', + configurator: configurator + }, document.body); +}; diff --git a/examples/science-writer/app.scss b/examples/author/app.scss similarity index 100% rename from examples/science-writer/app.scss rename to examples/author/app.scss diff --git a/examples/science-writer/index.html b/examples/author/index.html similarity index 100% rename from examples/science-writer/index.html rename to examples/author/index.html diff --git a/examples/jats-editor/package.js b/examples/author/package.js similarity index 58% rename from examples/jats-editor/package.js rename to examples/author/package.js index f6079b672..7bd21f18b 100644 --- a/examples/jats-editor/package.js +++ b/examples/author/package.js @@ -1,13 +1,13 @@ 'use strict'; -var ScientistPackage = require('../../packages/scientist/package'); +var TexturePackage = require('../../packages/texture/package'); var ExampleXMLStore = require('../ExampleXMLStore'); module.exports = { - name: 'jats-editor', + name: 'author-example', configure: function(config) { - // Use the default Scientist package - config.import(ScientistPackage); + // Use the default Texture package + config.import(TexturePackage); // Define XML Store config.setXMLStore(ExampleXMLStore); diff --git a/examples/config.js b/examples/config.js index f960300d2..f245cb078 100644 --- a/examples/config.js +++ b/examples/config.js @@ -1,5 +1,5 @@ 'use strict'; module.exports = { - examples: ['jats-editor', 'science-writer'] + examples: ['author', 'publisher'] }; diff --git a/examples/data/kitchen-sink-author.xml b/examples/data/kitchen-sink-author.xml index 7a47d7d3d..cb9e200ac 100644 --- a/examples/data/kitchen-sink-author.xml +++ b/examples/data/kitchen-sink-author.xml @@ -7,29 +7,27 @@ Kitchen sink example for authors - - - + - Doe - John + Forster + Anne Williams - -

John Doe biography

-
+ research physiotherapist + +
- + - Doe - Jane + Young + John G. - -

Jane Doe biography

-
+ consultant physician +
+ Department of Health Care for the Elderly, St Luke’s Hospital, Bradford BD5 0NA + Academic Section of Geriatric Medicine, Royal Infirmary, Glasgow G4 0SF
-

This is an article abstract, with a single paragraph

diff --git a/examples/index.html b/examples/index.html index 4367791bc..8794d7478 100644 --- a/examples/index.html +++ b/examples/index.html @@ -1,6 +1,6 @@

Scientist Examples

    -
  • Science Writer (for authors, co-authors, reviewers, word-like editing interface)
  • -
  • JATS Editor (for Publishers exposing XML elements)
  • +
  • Author - word-like editing interface
  • +
  • Publisher - QC-interface for publishers
diff --git a/examples/jats-editor/app.js b/examples/jats-editor/app.js deleted file mode 100644 index e2195bd80..000000000 --- a/examples/jats-editor/app.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -var substanceGlobals = require('substance/util/substanceGlobals'); -substanceGlobals.DEBUG_RENDERING = true; - -var Scientist = require('../../packages/scientist/Scientist'); -var ScientistConfigurator = require('../../packages/scientist/ScientistConfigurator'); -var JATSEditorPackage = require('./package'); - -var configurator = new ScientistConfigurator().import(JATSEditorPackage); - -window.onload = function() { - window.app = Scientist.mount({ - mode: 'publisher', - documentId: 'elife-00007', - configurator: configurator - }, document.body); -}; diff --git a/examples/publisher/app.js b/examples/publisher/app.js new file mode 100644 index 000000000..bdd8dc374 --- /dev/null +++ b/examples/publisher/app.js @@ -0,0 +1,17 @@ +'use strict'; + +var substanceGlobals = require('substance/util/substanceGlobals'); +substanceGlobals.DEBUG_RENDERING = true; + +var Texture = require('../../packages/texture/Texture'); +var TextureConfigurator = require('../../packages/texture/TextureConfigurator'); + +var configurator = new TextureConfigurator().import(require('./package')); + +window.onload = function() { + window.app = Texture.mount({ + mode: 'publisher', + documentId: 'elife-00007', + configurator: configurator + }, document.body); +}; diff --git a/examples/jats-editor/app.scss b/examples/publisher/app.scss similarity index 100% rename from examples/jats-editor/app.scss rename to examples/publisher/app.scss diff --git a/examples/jats-editor/index.html b/examples/publisher/index.html similarity index 100% rename from examples/jats-editor/index.html rename to examples/publisher/index.html diff --git a/examples/science-writer/package.js b/examples/publisher/package.js similarity index 57% rename from examples/science-writer/package.js rename to examples/publisher/package.js index 6a371a071..8c8bcafd3 100644 --- a/examples/science-writer/package.js +++ b/examples/publisher/package.js @@ -1,13 +1,12 @@ 'use strict'; -var ScientistPackage = require('../../packages/scientist/package'); +var TexturePackage = require('../../packages/texture/package'); var ExampleXMLStore = require('../ExampleXMLStore'); module.exports = { - name: 'science-writer', + name: 'publisher-example', configure: function(config) { - // Use the default Scientist package - config.import(ScientistPackage); + config.import(TexturePackage); // Define XML Store config.setXMLStore(ExampleXMLStore); diff --git a/examples/science-writer/app.js b/examples/science-writer/app.js deleted file mode 100644 index 25300fe17..000000000 --- a/examples/science-writer/app.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict'; - -var substanceGlobals = require('substance/util/substanceGlobals'); -substanceGlobals.DEBUG_RENDERING = true; - -var Scientist = require('../../packages/scientist/Scientist'); -var ScientistConfigurator = require('../../packages/scientist/ScientistConfigurator'); -var JATSEditorPackage = require('./package'); -var configurator = new ScientistConfigurator().import(JATSEditorPackage); - -window.onload = function() { - window.app = Scientist.mount({ - mode: 'author', - documentId: 'elife-00007', - configurator: configurator - }, document.body); -}; diff --git a/packages/jats/back/_back.scss b/packages/jats/back/_back.scss index bf4b58886..0330d5db8 100644 --- a/packages/jats/back/_back.scss +++ b/packages/jats/back/_back.scss @@ -1,4 +1,4 @@ .sc-back { border-top: 1px dotted #ddd; - margin-top: 40px; + padding-top: 40px; } \ No newline at end of file diff --git a/packages/scientist/Scientist.js b/packages/texture/Texture.js similarity index 91% rename from packages/scientist/Scientist.js rename to packages/texture/Texture.js index 0e9980a21..e4627a8fb 100644 --- a/packages/scientist/Scientist.js +++ b/packages/texture/Texture.js @@ -10,14 +10,14 @@ var Author = require('../../packages/author/Author'); Based on given mode prop, displays the Publisher, Author or Reader component */ -function Scientist() { +function Texture() { Component.apply(this, arguments); var configurator = this.props.configurator; this.xmlStore = configurator.getXMLStore(); } -Scientist.Prototype = function() { +Texture.Prototype = function() { this.getChildContext = function() { return { @@ -88,7 +88,7 @@ Scientist.Prototype = function() { // ------------------------------------ this.render = function($$) { - var el = $$('div').addClass('sc-scientist'); + var el = $$('div').addClass('sc-texture'); if (this.state.error) { el.append('ERROR: ', this.state.error.message); @@ -109,18 +109,17 @@ Scientist.Prototype = function() { ActiveModeClass = Author; } - // Display reader for mobile and writer on desktop el.append( $$(ActiveModeClass, { documentId: this.props.documentId, documentSession: this.state.documentSession, configurator: configurator - }).ref('publisher') + }).ref(this.props.mode) ); return el; }; }; -Component.extend(Scientist); +Component.extend(Texture); -module.exports = Scientist; +module.exports = Texture; diff --git a/packages/scientist/ScientistConfigurator.js b/packages/texture/TextureConfigurator.js similarity index 85% rename from packages/scientist/ScientistConfigurator.js rename to packages/texture/TextureConfigurator.js index 59bb73ac5..f2d24eab4 100644 --- a/packages/scientist/ScientistConfigurator.js +++ b/packages/texture/TextureConfigurator.js @@ -8,15 +8,15 @@ var uniq = require('lodash/uniq'); Top-level configurator for scientist. Has sub-configurators for all available modules (author, publisher, reader). */ -function ScientistConfigurator() { - ScientistConfigurator.super.apply(this, arguments); +function TextureConfigurator() { + TextureConfigurator.super.apply(this, arguments); // Extend config this.config.configurators = {}; this.config.XMLStoreClass = null; } -ScientistConfigurator.Prototype = function() { +TextureConfigurator.Prototype = function() { /* Provision of sub configurators (e.g. Author, Publisher, Reader @@ -52,6 +52,6 @@ ScientistConfigurator.Prototype = function() { }; }; -Configurator.extend(ScientistConfigurator); +Configurator.extend(TextureConfigurator); -module.exports = ScientistConfigurator; \ No newline at end of file +module.exports = TextureConfigurator; \ No newline at end of file diff --git a/packages/scientist/package.js b/packages/texture/package.js similarity index 100% rename from packages/scientist/package.js rename to packages/texture/package.js diff --git a/server.js b/server.js index e5680fa93..8eab6761a 100644 --- a/server.js +++ b/server.js @@ -13,27 +13,27 @@ var browserifyConfig = { }; // Writer example integration -serverUtils.serveStyles(app, '/jats-editor/app.css', { +serverUtils.serveStyles(app, '/publisher/app.css', { rootDir: __dirname, - configuratorPath: require.resolve('./packages/scientist/ScientistConfigurator'), - configPath: require.resolve('./examples/jats-editor/package'), + configuratorPath: require.resolve('./packages/texture/TextureConfigurator'), + configPath: require.resolve('./examples/publisher/package'), }); -serverUtils.serveJS(app, '/jats-editor/app.js', { - sourcePath: path.join(__dirname, 'examples/jats-editor', 'app.js'), +serverUtils.serveJS(app, '/publisher/app.js', { + sourcePath: path.join(__dirname, 'examples/publisher', 'app.js'), browserify: browserifyConfig, }); -serverUtils.serveHTML(app, '/jats-editor', path.join(__dirname, 'examples/jats-editor', 'index.html'), {}); +serverUtils.serveHTML(app, '/publisher', path.join(__dirname, 'examples/publisher', 'index.html'), {}); -serverUtils.serveStyles(app, '/science-writer/app.css', { +serverUtils.serveStyles(app, '/author/app.css', { rootDir: __dirname, - configuratorPath: require.resolve('./packages/scientist/ScientistConfigurator'), - configPath: require.resolve('./examples/science-writer/package'), + configuratorPath: require.resolve('./packages/texture/TextureConfigurator'), + configPath: require.resolve('./examples/author/package'), }); -serverUtils.serveJS(app, '/science-writer/app.js', { - sourcePath: path.join(__dirname, 'examples/science-writer', 'app.js'), +serverUtils.serveJS(app, '/author/app.js', { + sourcePath: path.join(__dirname, 'examples/author', 'app.js'), browserify: browserifyConfig, }); -serverUtils.serveHTML(app, '/science-writer', path.join(__dirname, 'examples/science-writer', 'index.html'), {}); +serverUtils.serveHTML(app, '/author', path.join(__dirname, 'examples/author', 'index.html'), {}); // static served data app.use('/data', express.static(path.join(__dirname, 'examples/data'))); From f3522e4927e58a2704b9b377c49f6d374b934aa6 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 29 Jul 2016 09:07:32 -0400 Subject: [PATCH 043/167] Add screenshot to README. --- README.md | 4 +++- texture.png | Bin 0 -> 710602 bytes 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 texture.png diff --git a/README.md b/README.md index a2a05599c..de121597c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Texture [![Build Status](https://travis-ci.org/substance/texture.svg?branch=develop)](https://travis-ci.org/substance/texture) -Texture is a collection of components for realizing content production systems. It has first-class support for JATS, the de facto standard for archiving and interchange of scientific open-access journals and its contents with XML. +Texture is a collection of components for realizing content production systems. It has first-class support for JATS, the de facto standard for archiving and interchange of scientific open-access contents with XML. + +![Texture User Interface](texture.png) ## Install diff --git a/texture.png b/texture.png new file mode 100644 index 0000000000000000000000000000000000000000..c3f3da77b1e5e1ca4f2585012cdc9f5136b14e16 GIT binary patch literal 710602 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�%TwWGfD+2u{?R| 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�szEgjaew;mE&%Nr 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®F>+aT`Ns7}u%_*QgMP_nuu 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

CH_{>WqusD57l9@Q2T_S0`L^BWri3Le3)78D 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ΜJRN7vVg9U~fil^v}Y$UQ;&eda*?4gQ_g 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࢛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

JSZPfRc(oy#E0S;SM%Bz2Y6=pUnU|U{}Hw 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

$K} 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

-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

  • 8vguG0^zu198-{j;=KXizQV=s#gQwOc>a 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®>bNHvHw2t5s z7j-1re_H{$ds!#AT2Kej=f&zoMGY$LW?^vpWr6+F1V*HQcdG%9$m+l40J0j+47-$| zH%L1M5(@9I>ktC<{4MdF@|1lianE~mIx|c&Q4`o|gqFn{m8A;=SlMV8oYqZm;-BV0 zVg@4Fmhp-?(9`0ja^8d9O%dWmo1hx?>n_4~ue}?pXluprZ8iW>Ae~qqtypCNOap40 zrlV{iH|1>mVuFmL@=8%mMK=|O!nWhKk00h|X8DbgpR2sz;{)2=-aULM7IkgcYPe^- zRn5Dsts*3gq!d8n7JNb#P83u&y`8)e7@}@X(@bPE= zgOB?U?%Zqtb$CrqD7;uXRNluq5SEJEoj!?a!VJ-yszH#86?pfc$jH_9)lO+k>6wL* ze2^)m1_m_=M5Anp?QKSYVHG_8_qnGorQQmzq<-JD(0{ZCqAkX^QkE;3qFxa2x zA=eEro@Kw2#M#kuT)^)%4BR8Jf%Gr@nlqDInxkMfNXz`z04E|%5Z1A0=Vn8Yd?A#{ zElVnK@*HcGM3__`&Rs+Tc7O5SseP18A9TRTK88`O;Av*_I6Uc1ljcM;E292$eg)?#HpZEDYl+mfmdM^JsFlk2#$Akcl>dOeex}VY?%>Oua{$0 zRqG)-P$pGMNgx$3NXg+h6$GGp@hYc`r#3arl43MxyGa?D?w86zGW5i&jf2|3+Z%%l zlg|bV)>u%5nahc)Hkyx8lt4aQayOv$0_`cFip%OXMwZnHZC?^4%0w;nrCF6%fsG8= zqHr}2)m}KE+}G@VzlcbKU&n|669EBr2)&8A`iCl9)F7@$ixrGGz3NCAD*w}fzZQ_l zlq%HpB)-;m8v4$*k-xcllO>u!weyXvTRAa4rb?!0Fp)8u!!@?E9WB^a-wgYZ^G@#J zcBn#*qI<+kM_Z`o>T_iaenD;F@EbXOreRY}v5VE8Z!7nhx7}p7o~`fW*5zyxCarP~ zw#qX>faXf@`!ULy@Gw3Q^if(cNVy&5)FF2xm?pdWwD??sEDMo-xuy&r_}U^>_)XP; zb8&mu9p>HKhsjc4gaw>b1HN0i%Is^IFugxAgB#+a6lfe!3PgNtf;rQdAWA*5I#3{> zrt}v0isz=v>VV9L9Ker9zx+QZ27jAIiH-i?asADNlncJ64Q0WVeFB2_&_BHoLYJe= z&#J^~yhxT78^{`tZBL7^BPv@)={1DfSt1`n7JNTnM@JF0dFJcqO`NhT!r-hUzyt>{ zysDH8V$U*TfJ9cpyzolLsnSkbWIVYuPIY*@Mr?Jsib};VJ_-BBP#wIkEmv5Fv%B(xoY6;O;>sWXU_`t@8eJu7aK@kls24 zy*0b>+vj(Cbj^VY=4NE-WjUGSd3VZsFKg_TR0Po&wfGqZQQVX>QcbLx;5d4bmHS;} z%(Pebgl!3=PH$9@U^&uyQJ|9rH^JV%XXM-D1Y9U?Y>E{ofe z!QsJz`=cKU2hb?5R`YScR2B00VVd*zwrX`5AY8hMF)GGGZX{~-wKwCXjzoTOTzgIglUv}?N7UzWz3Yzj4Ese~txbXsM=CW* zB~@8JMQwg73CZi-eUf!oD4Uyc>Gvf%bOD zCIlwy@x*YeC>A6MhI}vOI9kLMtFE3k|`;0=NrklkjA(IBUs6z%@#0@#64?Hxw+oZcE3HK(*Zp z^oV9qNv<*8%Abzom6+DKgiD@UQ33+|d-oFP7X)du+)+R#h$DHR!`++F=3|qmP4C0wNsV30oz6_};zS z?8KhKVH#`4CUMeEz<)~z?y*Nmm8RVtIjQ&*-XPs(%&l)deQ)b?Ov-x`cWI1nv#J5e zut4?UU&9a!Ik>E+ZY!Ht{{4U z<$16c-Pehl`60SM4j@490{}mhtNkJgkifFkvvmUEt`cJI`M!KPNJ`|i5D*{B!nQEo zD||HsTfo#R`0-cLXJUC+CQK4#)*oz*6yYwg0^1%eGaM6_a_Uj*^)fWKB7O*?|Gate zbM+JaY=}7gP*%5#;l}Ni+wj`3h(j?w71x-AWb{^adu;}6(@wQgzF*&nO~B!%mp)Zej&JCeAmszhOM+XXa( zUpFr!ESj6A=kHrSW`E~fZM*BZWZwlI?dMX?;r?QSV)Ic-X4RPp3^jzC~(BIHHd5=*G`leS>&oK&Q^r^Rd>bs)3l`zC zZI|I#K-z&*kTatR_?~+d5@Yj1So$HX>Q6OWBjgb|me!Kix(UH6Cg6DN<(S&?NO>Ia z+YGP#303zUln7)VEF%_H2Vep0*`3^dT8`0i3HX#rm=@Q=n`Iiv-o8gl=D$9y_=2*@ z`StHyvfY=1x178J|0zm=draVH_ifWW?g-ROm_#{>jI%vcP3q4~4TQ8XHN1E`2{G4c zg6B8tw`(E}rS^z{QmHn^D`$^i#I3OqX$!z3%h`fgljHtnRMRdW*gzA7>DdD;s|q6> z3@ZtAtuk`r`jO|ig+JQ$X90*)7du8J10~r&UMZi0UtX?}%lJBKMwKcKWea$VSBNc+QPSI#(Zny0ln)nQ;hGF$Dt8RP7 zBYqr#`WmQ*z*ryo;D9gh3}m#??6<|6^~-WJ;L%)Kg(d^0BMy3DV505p7vgsoNjt$(x6etDK=)0lU<*2mMSOxZDf9wMlzur|eG2S@Tu z+SMksdM*MLv$ZDA%u!FP&buhBez`Ot`}Wgyz2g7bcv+IDOmNnO(@stUR1#^c`pnkc zu?u#}7&W@0Fcqu>d16B%a1erJeM-a?tU)zYrE3t^U~17O?cwC%tYiKzqQ|FJG`Sz$ zKC>1XwmcK`%(*1~rJd6%pU_&(CfzkE1A~C{xK@O6?#$r;K#k)*>wPBShh3TK*=3>X zx98mF=DN4tDd~Uc%;Vwm!D*w}0x#bT_liiW?@#?({tMnd3B3~h_}l*5^SBrgDx%XM zVh%k^@^-BG{76fIuK|c9hB(Cb@It@HCWUp2W~2!;C3?EXEk-np%0IGAS-x|G(|Glc zokK9*0x-|SnQl^Q=Y8rxDR?;a(Dc-WwJyq(O5WT-&E`-Y=fu)7-~a*`1`5=Xtm@1m zOmRMrtw(X21(KEWfUDB3Q_$~HOgs9>mu8@;MR6~yieppI`dR1#}CD22Et z@Zj2Zhnl?^K~anis>0G-g!6QdBV5?IzIC;z-Z3%rg6jGSM zTTjdZbfn~Wc-Oe)r%pPu2fysP{q;BC-UKagx5@sFKUWOKqx70TD#?-{IYKJtuRFL! zZ3AxJ#3Q{o{aOSm*8N-K#@b#{%>;E0EF_%dgH~1%XY;^?JNlbjW1Y_#(w8Q;W#l|V2 zIrld1l569z@BLsRyMOQnXgUZp#7W+S9re)OdNg4F* z5l-U|m%le~TLKQ>T)49@1`!vSQf;xT$Wp)zA}Y9pVynuNH*k^IH2u!6p2q!mYZ`cK zgYPuP;sa@X>ddMHaOgU{9;ASq5&Ml^SEJiLRnen!cr;pOCe40FlpYu%y7?F4bh-i) zFOud1Ytx)%)Fa-n4w~3VE~rKm8`L)Tx%~Q+_kos`L{thtbrl`lSwZyqtgKa?K;Nn> zHjz0w#EvMnXC3mGfHwzB()O)#vM|n2qVAxe3Kewj9Jf7onYZ0T^f~myx4@q5IgJ)= z5}xy%T7auYs*n% zE_#pW51mwRbbsCv}UkGtVCnwTXtZgZA^V{rkU+EWQ& z2=iZH5%5~!#Tc?VkvH0cfogJE@5C)l@Ln;c0aFbwWGucp`5^=T;3bz#HaPNRd~kom zA@^#CO5UHNV*AzPzU2`aRZq@p3+0BNeORLg)t#x~t?G)8mipZk>qt{K_d)9Qbrryp zG@qeC7WOc-wh^TRBmUBknratwDw0!qy~P>gGWiWQoh%vx> zRU&8+yH1^Sk~`iH6Hf=*7$X;n8@glQ$3#DpR;`Y1hb?f+oOk={S7Joc)xvB zs(Hjy=x;0OK5gMHt|lhh4|;{x-uz4Q6nVO(+8R$TdPsvxjE~=#=<&YeWCVkA1V3m@ zIVlj2KzG&S0l;9{0gNrmR6F5z$8PlR8JG5#hkjvqk_g@!aYeG35HWp3aU(wn{0vAXE3E26W+Q)-iP*xl;da$m1|u{-=Tgq?D+J~AZzawf;vZ|S8G1j6H8i*=Lu zv31Dc-0~xLp62!LEWFDTA6fK@ zB*kt>_RYt%ERIPKrYJRr`*GdE?S*LF7_eAsoQnYb>1S)6Q-_6#4)K;(OJ09&^7ewU z-+(3_TL?3!$>DvVqrUB0hsfALHrm|pTeP$TE-ohf z>h%OMalf(R`U(<{@}0%!_I9fv}sAN z-5nE6h1#R8pxJufLem`>Gv9oXzl_jWo{nBR2iT2-(>l}eMU z>8@3v!8nd?`quV6?~1ACQtk^PD#AFqNk-idwCQPnqtLOB9hd$rHkMX)YFjxv<`OcJd=p+5X6H zj&;MydR$RG2@NfL9QJS#hku8Lwx?W08-K24_>CQ1@_IIUB}d(C-bmD{ux+_+;x^6N z4A%1Q;k}>h>*nq4T&HQ)eNEI_=jV-K$08}xcyC<^9EK{i{bmore_j7N{pIF?Q}2$q zCp(euDP}%=2EH5q`skhSh2|jf*N7LVyZ%yzkAyMyWPC;Z!D_oK1<#UN@3@M}*%z;? zi>|7ZmJ-x=w>EX)jFM-V^fn|d`HD^EofKlT@F{HwH3t7u+l(69MO0+OedrF^-wk&S zYh}N)qBi?Fp(ngvsP-g23BPK@;I3(WoCQ+p(Xv+7O4jt~C5;5e5P725f>W8IOque{ zv*x~Qm46SS{d=|XS2pm;qUWZ2{!(j-)=eDLU~+ln$9|x5?oD%9NX{C2eQwS_#^~Ws zAhc3yqie8PJtAt>Fn+kUX{C!L1<;>h3url&OdLt?5j`%hmyV2a^U-$iVci7TKKF88 zO1Lx8KAbkZUF}6*r87vQ?fYEoEUF*~-1)2KBi60=0pw~2)%cAxvY8id!j zLCc8f=0&?MXX=SDOidpRA9t0P1V@bU-cJT+Ba->yv&?3blQl`|^K=UxHcE*sp1IBH zXhLK~<&t&f-gjL^|A38d4H*zw!7hWaKB|k8QdAUMnvQYHQP=NxGM_U<&;~7{sLc z6o&Y@n634#3YPCpl8;z~W(~E3-5G&#ww@1O$#hKC8X>e(%yrsQy|4a!6u((#>0gmc zPMYLTCvU~3R16kioMBYu-9wg?C*Pd&9#`p#efl5hn6AlHq? zcD{fe-Pwcq%ICjDrXL+Z@Y^T%hc%Pkl*im?VPgB%qR-t5-%;Fo#I{kNY=tBq+2NIl z-2drs{VPu6hfAH5K2>z3k+Ow--h`YYm!nN5P{>EnQ@AoJ|03LCzNLKGwGn|Bb8rPr zeKd)+hnw2(x0LRUH@#TZIxaRBE}*~kaBYi$9)^E;pmk?gI2Yq4!f$P?o5C^oUz0Y# z_opwUf8=VcYkjS`;hB$1Y+<=`BYD|bZhOPO8mNbS&zf)U%(VUP!w+5ko%<{7-|x6j z&+E7!FppUk{HWpL!+{X{eP=|ZbD;Iq|Mc$vccSfoyX)U;;b-vnx%(`~G`yqlfY?|2 z2m8v`&U@Ftar#gH`_un%aIx>7*!zJ#;Kf9JA~zxDPe(jDPObhP5&T)!wL233^4_aE zTna;82T$xh82vk6iMOC@L;vcJyxa!gBF~jce7dGePrK+>PJoOmJ8Al_xQ%XvirX(9 zIC@G`vuEQ!T>kc@--B;Io4Ug-z2d={_m7^|)cs$+efovvYp1TwI`hoIi@}16nkfk` z;J9lv?DHG4@2~LsGW43J_etfl*N9!!)D%B5=r zQzWT)y-Q0EzW&h*+54tfq@vx>DG$yJQeMZI-Q3>%k9Yfjo9jth!1aw{+U)8F8&u(x zuebP|x8Hd78kPH5kjvMs)!J`->0nb!YdWQ%Dnr_y4(N h-}C09rDyJY?e832yW@qYz@K;Cj{PhDtq=bG{{VF^ Date: Tue, 9 Aug 2016 12:51:58 +0200 Subject: [PATCH 044/167] Update roadmap. --- README.md | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index de121597c..3865ccdc5 100644 --- a/README.md +++ b/README.md @@ -129,25 +129,43 @@ See [CONTRIBUTING.md](CONTRIBUTING.md). ### Alpha 2 -*ETA: 25 July 2016* +*ETA: September 2016* - Update to Substance Beta 5 -- Author: - - Cover editing (title, abstract, authors, etc.) -- Publisher: - - Front matter editor (JATS ``) - - XML navigation bar (breadcrumbs, similar to XPath) - - Edit references (XML, for fixing) - - Add references (template for ``) +- Front matter editing for title + abstract (JATS ``) +- Editing of authors (create, update and delete contrib elements) +- Create and edit xref elements -### Beta -*ETA: Fall 2016* +### Alpha 3 + +*ETA: October 2016* + +Goal is to provide proof of concepts for the discussed tagging workflow (get from unstructured text to structured JATS). For example: + +- Quality measures for Meta data (#72) +- Identify authors in the text and turn them into nodes (#75) +- Turn a sequence of paragraphs into a reference list (#74) +- Identify title as text and tag as article title (#76) +- Update to Substance Beta 6 + +### Alpha 4 + +Elaborate results of Alpha 3 based on an agreed minimal set of functionalities. For example: + +- Document structure fixes (tag headings and set heading level) +- Author tagging +- Figure tagging (caption editing etc.) +- Figure placement +- Bibliography tagging + +With these results organisations can start to test Texture-based QC-workflow with real articles. + +*ETA: Winter 2016* + +### Beta -- Creating content (contextual) -- Add references via CrossRef search or pasting BibTex -- Support more elements -- Extended JATS, [Stencila](https://stenci.la/) Package +Feature-complete release ready to be tested by publishers. # Credits From 2cd80ba7ae0b7510e1dcffe858daf35fabb674b6 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 2 Sep 2016 23:04:01 +0200 Subject: [PATCH 045/167] Move towards pure CSS. --- examples/author/app.css | 3 +++ examples/author/app.scss | 3 --- package.json | 2 +- server.js | 4 ++++ texture.css | 1 + 5 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 examples/author/app.css delete mode 100644 examples/author/app.scss create mode 100644 texture.css diff --git a/examples/author/app.css b/examples/author/app.css new file mode 100644 index 000000000..a3f31f0e1 --- /dev/null +++ b/examples/author/app.css @@ -0,0 +1,3 @@ +@import '../substance/substance.css'; +@import '../substance/substance-base.css'; +@import '../texture.css'; \ No newline at end of file diff --git a/examples/author/app.scss b/examples/author/app.scss deleted file mode 100644 index 022306f69..000000000 --- a/examples/author/app.scss +++ /dev/null @@ -1,3 +0,0 @@ -body { - overflow: hidden; -} diff --git a/package.json b/package.json index 70322b9d0..6b9c937b0 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "A scientific editor and reader for JATS files.", "dependencies": { "lodash": "^4.2.1", - "substance": "substance/substance#develop" + "substance": "substance/substance#pure-css" }, "devDependencies": { "browserify": "substance/node-browserify#d3caeb6dcdaa97a258d099c7231a57f0f60ec876", diff --git a/server.js b/server.js index 8eab6761a..f390b740a 100644 --- a/server.js +++ b/server.js @@ -12,6 +12,7 @@ var browserifyConfig = { debug: true }; + // Writer example integration serverUtils.serveStyles(app, '/publisher/app.css', { rootDir: __dirname, @@ -40,6 +41,9 @@ app.use('/data', express.static(path.join(__dirname, 'examples/data'))); app.use(express.static(path.join(__dirname, 'examples'))); app.use('/fonts', express.static(path.join(__dirname, 'node_modules/font-awesome/fonts'))); +app.use(express.static(__dirname)); +app.use('/substance', express.static(path.join(__dirname, 'node_modules/substance'))); + serverUtils.serveTestSuite(app, "test/**/*.test.js"); app.listen(PORT); diff --git a/texture.css b/texture.css new file mode 100644 index 000000000..b569bb1ab --- /dev/null +++ b/texture.css @@ -0,0 +1 @@ +@import 'packages/_index.css'; \ No newline at end of file From 667c1d0d80d349ec0e8ccb67a20d6ae9ce0d1632 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 5 Sep 2016 16:04:28 +0200 Subject: [PATCH 046/167] Complete the switch to plain CSS. --- examples/author/app.css | 12 +++++- examples/author/index.html | 2 +- examples/publisher/app.css | 11 +++++ examples/publisher/app.scss | 3 -- examples/publisher/index.html | 2 +- packages/_index.css | 5 +++ packages/author/_author.scss | 22 ---------- packages/author/_index.css | 4 ++ packages/author/heading/_heading.scss | 41 ------------------- packages/author/heading/package.js | 1 - packages/common/_edit-xml.css | 13 ++++++ packages/common/_edit-xml.scss | 35 ---------------- packages/common/_index.css | 2 + ..._isolated-node.scss => _isolated-node.css} | 0 packages/jats/_index.css | 19 +++++++++ .../jats/article-title/_article-title.scss | 6 --- packages/jats/article-title/_index.css | 6 +++ .../article/{_article.scss => _index.css} | 0 packages/jats/article/package.js | 2 - packages/jats/back/{_back.scss => _index.css} | 0 packages/jats/bold/{_bold.scss => _index.css} | 0 .../jats/contrib-group/_contrib-group.scss | 13 ------ packages/jats/contrib-group/_index.css | 3 ++ packages/jats/contrib-group/package.js | 1 - .../contrib/{_contrib.scss => _index.css} | 0 packages/jats/contrib/package.js | 1 - packages/jats/ext-link/_ext-link.scss | 3 -- packages/jats/ext-link/_index.css | 1 + packages/jats/ext-link/package.js | 1 - packages/jats/figure/_figure-target.css | 27 ++++++++++++ packages/jats/figure/_figure-target.scss | 33 --------------- packages/jats/figure/_figure.scss | 4 -- packages/jats/figure/_index.css | 6 +++ packages/jats/footnote/_footnote.scss | 8 ---- packages/jats/footnote/_index.css | 8 ++++ packages/jats/graphic/_graphic.scss | 6 --- packages/jats/graphic/_index.css | 4 ++ packages/jats/graphic/package.js | 1 - .../jats/italic/{_italic.scss => _index.css} | 0 packages/jats/italic/package.js | 1 - packages/jats/monospace/_index.css | 4 ++ packages/jats/monospace/_monospace.scss | 4 -- packages/jats/monospace/package.js | 1 - packages/jats/package.js | 1 - packages/jats/ref-list/_index.css | 6 +++ packages/jats/ref-list/_ref-list.scss | 7 ---- packages/jats/ref-list/package.js | 1 - packages/jats/ref/_index.css | 16 ++++++++ packages/jats/ref/_ref.scss | 19 --------- packages/jats/section/_index.css | 29 +++++++++++++ packages/jats/section/_section.scss | 29 ------------- packages/jats/section/package.js | 1 - .../subscript/{_subscript.scss => _index.css} | 0 packages/jats/subscript/package.js | 1 - .../{_superscript.scss => _index.css} | 0 packages/jats/superscript/package.js | 1 - packages/jats/title/_index.css | 6 +++ packages/jats/title/_title.scss | 6 --- packages/jats/xref/_index.css | 25 +++++++++++ packages/jats/xref/_xref.scss | 29 ------------- packages/jats/xref/package.js | 1 - packages/publisher/_index.css | 5 +++ packages/publisher/_publisher.scss | 21 ---------- packages/unsupported/_index.css | 20 +++++++++ packages/unsupported/_unsupported.scss | 21 ---------- server.js | 22 +++++----- texture.css | 2 +- 67 files changed, 244 insertions(+), 341 deletions(-) create mode 100644 examples/publisher/app.css delete mode 100644 examples/publisher/app.scss create mode 100644 packages/_index.css delete mode 100644 packages/author/_author.scss create mode 100644 packages/author/_index.css delete mode 100644 packages/author/heading/_heading.scss create mode 100644 packages/common/_edit-xml.css delete mode 100644 packages/common/_edit-xml.scss create mode 100644 packages/common/_index.css rename packages/common/{_isolated-node.scss => _isolated-node.css} (100%) create mode 100644 packages/jats/_index.css delete mode 100644 packages/jats/article-title/_article-title.scss create mode 100644 packages/jats/article-title/_index.css rename packages/jats/article/{_article.scss => _index.css} (100%) rename packages/jats/back/{_back.scss => _index.css} (100%) rename packages/jats/bold/{_bold.scss => _index.css} (100%) delete mode 100644 packages/jats/contrib-group/_contrib-group.scss create mode 100644 packages/jats/contrib-group/_index.css rename packages/jats/contrib/{_contrib.scss => _index.css} (100%) delete mode 100644 packages/jats/ext-link/_ext-link.scss create mode 100644 packages/jats/ext-link/_index.css create mode 100644 packages/jats/figure/_figure-target.css delete mode 100644 packages/jats/figure/_figure-target.scss delete mode 100644 packages/jats/figure/_figure.scss create mode 100644 packages/jats/figure/_index.css delete mode 100644 packages/jats/footnote/_footnote.scss create mode 100644 packages/jats/footnote/_index.css delete mode 100644 packages/jats/graphic/_graphic.scss create mode 100644 packages/jats/graphic/_index.css rename packages/jats/italic/{_italic.scss => _index.css} (100%) create mode 100644 packages/jats/monospace/_index.css delete mode 100644 packages/jats/monospace/_monospace.scss create mode 100644 packages/jats/ref-list/_index.css delete mode 100644 packages/jats/ref-list/_ref-list.scss create mode 100644 packages/jats/ref/_index.css delete mode 100644 packages/jats/ref/_ref.scss create mode 100644 packages/jats/section/_index.css delete mode 100644 packages/jats/section/_section.scss rename packages/jats/subscript/{_subscript.scss => _index.css} (100%) rename packages/jats/superscript/{_superscript.scss => _index.css} (100%) create mode 100644 packages/jats/title/_index.css delete mode 100644 packages/jats/title/_title.scss create mode 100644 packages/jats/xref/_index.css delete mode 100644 packages/jats/xref/_xref.scss create mode 100644 packages/publisher/_index.css delete mode 100644 packages/publisher/_publisher.scss create mode 100644 packages/unsupported/_index.css delete mode 100644 packages/unsupported/_unsupported.scss diff --git a/examples/author/app.css b/examples/author/app.css index a3f31f0e1..d994158d6 100644 --- a/examples/author/app.css +++ b/examples/author/app.css @@ -1,3 +1,11 @@ +/* Substance Component styles */ @import '../substance/substance.css'; -@import '../substance/substance-base.css'; -@import '../texture.css'; \ No newline at end of file +/* Texture Component styles */ +@import '../texture.css'; +/* You may want to use your own reset and pagestyle */ +@import '../substance/substance-reset.css'; +@import '../substance/substance-pagestyle.css'; +/* Using url here, so font-awesome does not get bundled. */ +@import url('../font-awesome/css/font-awesome.min.css'); +body { overflow: hidden; } +.sc-author { position: absolute; left: 0px; right: 0px; bottom: 0px; top: 0px; } \ No newline at end of file diff --git a/examples/author/index.html b/examples/author/index.html index e96983300..472bca7cf 100644 --- a/examples/author/index.html +++ b/examples/author/index.html @@ -1,6 +1,6 @@ - Science Writer + Texture Author diff --git a/examples/publisher/app.css b/examples/publisher/app.css new file mode 100644 index 000000000..52dc7c5d5 --- /dev/null +++ b/examples/publisher/app.css @@ -0,0 +1,11 @@ +/* Substance Component styles */ +@import '../substance/substance.css'; +/* Texture Component styles */ +@import '../texture.css'; +/* You may want to use your own reset and pagestyle */ +@import '../substance/substance-reset.css'; +@import '../substance/substance-pagestyle.css'; +/* Using url here, so font-awesome does not get bundled. */ +@import url('../font-awesome/css/font-awesome.min.css'); +body { overflow: hidden; } +.sc-publisher { position: absolute; left: 0px; right: 0px; bottom: 0px; top: 0px; } \ No newline at end of file diff --git a/examples/publisher/app.scss b/examples/publisher/app.scss deleted file mode 100644 index 8d61cffc7..000000000 --- a/examples/publisher/app.scss +++ /dev/null @@ -1,3 +0,0 @@ -body { - overflow: hidden; -} \ No newline at end of file diff --git a/examples/publisher/index.html b/examples/publisher/index.html index 70797b68b..c3f5ee657 100644 --- a/examples/publisher/index.html +++ b/examples/publisher/index.html @@ -1,6 +1,6 @@ - JATS Editor + Texture Publisher diff --git a/packages/_index.css b/packages/_index.css new file mode 100644 index 000000000..2313e134f --- /dev/null +++ b/packages/_index.css @@ -0,0 +1,5 @@ +@import './jats/_index.css'; +@import './unsupported/_index.css'; +@import './common/_index.css'; +@import './author/_index.css'; +@import './publisher/_index.css'; diff --git a/packages/author/_author.scss b/packages/author/_author.scss deleted file mode 100644 index c45e9d0b1..000000000 --- a/packages/author/_author.scss +++ /dev/null @@ -1,22 +0,0 @@ -$fa-font-path: "../fonts" !default; -@import '../../node_modules/font-awesome/scss/font-awesome'; - -.sc-author { - - .se-context-section { - background: #fafafa; - border-left: 1px solid $border-color; - - .se-toc-entries { - padding-right: 20px; - } - } - - .sc-body > .sc-container-editor > * { - margin-bottom: 20px; - } - - .sc-toolbar { - border-bottom: 1px solid $border-color; - } -} diff --git a/packages/author/_index.css b/packages/author/_index.css new file mode 100644 index 000000000..3af462eef --- /dev/null +++ b/packages/author/_index.css @@ -0,0 +1,4 @@ +.sc-author .se-context-section { background: #fafafa; border-left: 1px solid var(--border-color); } +.sc-author .se-context-section .se-toc-entries { padding-right: 20px; } +.sc-author .sc-body > .sc-container-editor > * { margin-bottom: 20px; } +.sc-author .sc-toolbar { border-bottom: 1px solid var(--border-color); } diff --git a/packages/author/heading/_heading.scss b/packages/author/heading/_heading.scss deleted file mode 100644 index 2f6dca6e8..000000000 --- a/packages/author/heading/_heading.scss +++ /dev/null @@ -1,41 +0,0 @@ -.sc-heading { - font-weight: $strong-font-weight; - letter-spacing: $heading-letterspacing; -} - -.sc-heading.sm-level-1 { - font-size: $h1-font-size; -} - -.sc-heading.sm-level-2 { - font-size: $h2-font-size; -} - -.sc-heading.sm-level-3 { - font-size: $h3-font-size; -} - -.sc-heading.sm-level-3 { - font-size: $h4-font-size; -} - -/* Overrides for SwitchTextType tool */ -.sc-switch-text-type .se-option.sm-heading1 { - font-size: $h1-font-size; - font-weight: $strong-font-weight; -} - -.sc-switch-text-type .se-option.sm-heading2 { - font-size: $h2-font-size; - font-weight: $strong-font-weight; -} - -.sc-switch-text-type .se-option.sm-heading3 { - font-size: $h3-font-size; - font-weight: $strong-font-weight; -} - -.sc-switch-text-type .se-option.sm-heading4 { - font-size: $h4-font-size; - font-weight: $strong-font-weight; -} diff --git a/packages/author/heading/package.js b/packages/author/heading/package.js index 0233dc3dc..3b17d2adc 100644 --- a/packages/author/heading/package.js +++ b/packages/author/heading/package.js @@ -34,6 +34,5 @@ module.exports = { en: 'Heading 3', de: 'Überschrift 3' }); - config.addStyle(__dirname+"/_heading.scss"); } }; diff --git a/packages/common/_edit-xml.css b/packages/common/_edit-xml.css new file mode 100644 index 000000000..8c32cec6d --- /dev/null +++ b/packages/common/_edit-xml.css @@ -0,0 +1,13 @@ +.sc-edit-xml { padding: $default-padding; } +.sc-edit-xml textarea { + font-family: $font-family-code; + font-size: $font-size-code - 2px; + border: 1px solid #ddd; + padding: 10px; + width: 100%; +} +.sc-edit-xml .se-tag { opacity: 0.5; } +.sc-edit-xml .se-actions { padding-top: 20px; } +.sc-edit-xml .se-actions .sc-button { margin-right: 20px; } +.sc-xml-attribute-editor textarea { width: 100%; height: 100px; } +.sc-xml-editor textarea { width: 100%; height: 270px; } diff --git a/packages/common/_edit-xml.scss b/packages/common/_edit-xml.scss deleted file mode 100644 index 3614575d3..000000000 --- a/packages/common/_edit-xml.scss +++ /dev/null @@ -1,35 +0,0 @@ -.sc-edit-xml { - padding: $default-padding; - - textarea { - font-family: $font-family-code; - font-size: $font-size-code - 2px; - border: 1px solid #ddd; - padding: 10px; - width: 100%; - // resize: none; - } - - .se-tag { - opacity: 0.5; - } - - .se-actions { - padding-top: 20px; - - .sc-button { - margin-right: 20px; - } - } -} - -.sc-xml-attribute-editor textarea { - width: 100%; - height: 100px; -} - -.sc-xml-editor textarea { - width: 100%; - height: 270px; -} - diff --git a/packages/common/_index.css b/packages/common/_index.css new file mode 100644 index 000000000..255ec51b9 --- /dev/null +++ b/packages/common/_index.css @@ -0,0 +1,2 @@ +@import './_edit-xml.css'; +@import './_isolated-node.css'; \ No newline at end of file diff --git a/packages/common/_isolated-node.scss b/packages/common/_isolated-node.css similarity index 100% rename from packages/common/_isolated-node.scss rename to packages/common/_isolated-node.css diff --git a/packages/jats/_index.css b/packages/jats/_index.css new file mode 100644 index 000000000..16305218d --- /dev/null +++ b/packages/jats/_index.css @@ -0,0 +1,19 @@ +@import './article/_index.css'; +@import './article-title/_index.css'; +@import './back/_index.css'; +@import './bold/_index.css'; +@import './contrib/_index.css'; +@import './contrib-group/_index.css'; +@import './ext-link/_index.css'; +@import './figure/_index.css'; +@import './footnote/_index.css'; +@import './graphic/_index.css'; +@import './italic/_index.css'; +@import './monospace/_index.css'; +@import './ref/_index.css'; +@import './ref-list/_index.css'; +@import './section/_index.css'; +@import './subscript/_index.css'; +@import './superscript/_index.css'; +@import './title/_index.css'; +@import './xref/_index.css'; \ No newline at end of file diff --git a/packages/jats/article-title/_article-title.scss b/packages/jats/article-title/_article-title.scss deleted file mode 100644 index ca61df7c3..000000000 --- a/packages/jats/article-title/_article-title.scss +++ /dev/null @@ -1,6 +0,0 @@ - .sc-article-title { - padding-bottom: $default-padding; - font-weight: $strong-font-weight; - letter-spacing: $heading-letterspacing; - font-size: $title-font-size; - } \ No newline at end of file diff --git a/packages/jats/article-title/_index.css b/packages/jats/article-title/_index.css new file mode 100644 index 000000000..7521a7754 --- /dev/null +++ b/packages/jats/article-title/_index.css @@ -0,0 +1,6 @@ +.sc-article-title { + padding-bottom: var(--default-padding); + font-weight: var(--strong-font-weight); + letter-spacing: var(--heading-letterspacing); + font-size: var(--title-font-size); +} \ No newline at end of file diff --git a/packages/jats/article/_article.scss b/packages/jats/article/_index.css similarity index 100% rename from packages/jats/article/_article.scss rename to packages/jats/article/_index.css diff --git a/packages/jats/article/package.js b/packages/jats/article/package.js index 2b23f687b..e0051eb3a 100644 --- a/packages/jats/article/package.js +++ b/packages/jats/article/package.js @@ -13,8 +13,6 @@ module.exports = { ArticleClass: ScientistArticle, defaultTextType: 'paragraph' }); - - config.addStyle(__dirname, '_article.scss'); config.addNode(ArticleNode); config.addConverter('jats', ArticleConverter); config.addComponent(ArticleNode.type, ArticleComponent); diff --git a/packages/jats/back/_back.scss b/packages/jats/back/_index.css similarity index 100% rename from packages/jats/back/_back.scss rename to packages/jats/back/_index.css diff --git a/packages/jats/bold/_bold.scss b/packages/jats/bold/_index.css similarity index 100% rename from packages/jats/bold/_bold.scss rename to packages/jats/bold/_index.css diff --git a/packages/jats/contrib-group/_contrib-group.scss b/packages/jats/contrib-group/_contrib-group.scss deleted file mode 100644 index 6f21624bb..000000000 --- a/packages/jats/contrib-group/_contrib-group.scss +++ /dev/null @@ -1,13 +0,0 @@ -.sc-contrib-group { - padding-bottom: $default-padding; - overflow: auto; - - > * { - float: left; - margin-right: $default-padding; - } - - .se-add-author { - color: $link-color; - } -} \ No newline at end of file diff --git a/packages/jats/contrib-group/_index.css b/packages/jats/contrib-group/_index.css new file mode 100644 index 000000000..0705a2dc4 --- /dev/null +++ b/packages/jats/contrib-group/_index.css @@ -0,0 +1,3 @@ +.sc-contrib-group { padding-bottom: var(--default-padding); overflow: auto; } +.sc-contrib-group > * { float: left; margin-right: var(--default-padding); } +.sc-contrib-group .se-add-author { color: var(--link-color); } \ No newline at end of file diff --git a/packages/jats/contrib-group/package.js b/packages/jats/contrib-group/package.js index b4159f6a7..7218a30d2 100644 --- a/packages/jats/contrib-group/package.js +++ b/packages/jats/contrib-group/package.js @@ -10,6 +10,5 @@ module.exports = { config.addNode(ContribGroup); config.addConverter('jats', ContribGroupConverter); config.addComponent(ContribGroup.type, ContribGroupComponent); - config.addStyle(__dirname, '_contrib-group.scss'); } }; diff --git a/packages/jats/contrib/_contrib.scss b/packages/jats/contrib/_index.css similarity index 100% rename from packages/jats/contrib/_contrib.scss rename to packages/jats/contrib/_index.css diff --git a/packages/jats/contrib/package.js b/packages/jats/contrib/package.js index e0af66c71..34602088c 100644 --- a/packages/jats/contrib/package.js +++ b/packages/jats/contrib/package.js @@ -10,6 +10,5 @@ module.exports = { config.addNode(Contrib); config.addComponent(Contrib.type, ContribComponent); config.addConverter('jats', ContribConverter); - config.addStyle(__dirname, '_contrib.scss'); } }; \ No newline at end of file diff --git a/packages/jats/ext-link/_ext-link.scss b/packages/jats/ext-link/_ext-link.scss deleted file mode 100644 index 391318fca..000000000 --- a/packages/jats/ext-link/_ext-link.scss +++ /dev/null @@ -1,3 +0,0 @@ -.sc-ext-link { - color: #2079DC; -} \ No newline at end of file diff --git a/packages/jats/ext-link/_index.css b/packages/jats/ext-link/_index.css new file mode 100644 index 000000000..9c319e924 --- /dev/null +++ b/packages/jats/ext-link/_index.css @@ -0,0 +1 @@ +.sc-ext-link { color: #2079DC; } \ No newline at end of file diff --git a/packages/jats/ext-link/package.js b/packages/jats/ext-link/package.js index 24b1b313e..22efa46b9 100644 --- a/packages/jats/ext-link/package.js +++ b/packages/jats/ext-link/package.js @@ -23,6 +23,5 @@ module.exports = { config.addLabel(ExtLink.type, { en: 'Link' }); - config.addStyle(__dirname, '_ext-link.scss'); } }; diff --git a/packages/jats/figure/_figure-target.css b/packages/jats/figure/_figure-target.css new file mode 100644 index 000000000..7eab2ec21 --- /dev/null +++ b/packages/jats/figure/_figure-target.css @@ -0,0 +1,27 @@ +.sc-figure-target { + font-size: var(--small-font-size); + border-bottom: 1px solid 10; + padding: var(--default-padding); + background: #fafafa; + border-left: 4px solid transparent; + cursor: pointer; + overflow: auto; +} +.sc-figure-target:hover { + background: #fff; +} +.sc-figure-target.sm-selected { + border-left: 4px solid #91bb04; + background: #fff; +} +.sc-figure-target .se-thumbnail { + margin-right: var(--default-padding); + width: 100px; + float: left; +} +.sc-figure-target .se-label { + float: left; +} +.sc-figure-target .se-title { + float: left; +} diff --git a/packages/jats/figure/_figure-target.scss b/packages/jats/figure/_figure-target.scss deleted file mode 100644 index 1c55642c3..000000000 --- a/packages/jats/figure/_figure-target.scss +++ /dev/null @@ -1,33 +0,0 @@ -.sc-figure-target { - - font-size: $small-font-size; - border-bottom: 1px solid $border-color; - padding: $default-padding; - - background: #fafafa; - border-left: 4px solid transparent; - cursor: pointer; - overflow: auto; - - &:hover { - background: #fff; - } - - &.sm-selected { - border-left: 4px solid #91bb04; - background: #fff; - } - - .se-thumbnail { - margin-right: $default-padding; - width: 100px; - float: left; - } - - .se-label { - float: left; - } - .se-title { - float: left; - } -} \ No newline at end of file diff --git a/packages/jats/figure/_figure.scss b/packages/jats/figure/_figure.scss deleted file mode 100644 index cb8b14666..000000000 --- a/packages/jats/figure/_figure.scss +++ /dev/null @@ -1,4 +0,0 @@ -.sc-figure { - padding: $default-padding; - border: 1px solid $border-color; -} diff --git a/packages/jats/figure/_index.css b/packages/jats/figure/_index.css new file mode 100644 index 000000000..a44db303f --- /dev/null +++ b/packages/jats/figure/_index.css @@ -0,0 +1,6 @@ +@import './_figure-target.css'; + +.sc-figure { + padding: var(--default-padding); + border: 1px solid var(--border-color); +} diff --git a/packages/jats/footnote/_footnote.scss b/packages/jats/footnote/_footnote.scss deleted file mode 100644 index 475b38a19..000000000 --- a/packages/jats/footnote/_footnote.scss +++ /dev/null @@ -1,8 +0,0 @@ -.sc-footnote { - background: $fill-light-color; - font-size: $small-font-size; - padding-left: $default-padding; - padding-right: $default-padding; - border: 1px solid $border-color; - border-radius: $border-radius; -} \ No newline at end of file diff --git a/packages/jats/footnote/_index.css b/packages/jats/footnote/_index.css new file mode 100644 index 000000000..27258dce3 --- /dev/null +++ b/packages/jats/footnote/_index.css @@ -0,0 +1,8 @@ +.sc-footnote { + background: var(--fill-light-color); + font-size: var(--small-font-size); + padding-left: var(--default-padding); + padding-right: var(--default-padding); + border: 1px solid var(--border-color); + border-radius: var(--border-radius); +} \ No newline at end of file diff --git a/packages/jats/graphic/_graphic.scss b/packages/jats/graphic/_graphic.scss deleted file mode 100644 index d375dba8e..000000000 --- a/packages/jats/graphic/_graphic.scss +++ /dev/null @@ -1,6 +0,0 @@ -.sc-graphic { - img { - max-width: 100%; - display: block; - } -} \ No newline at end of file diff --git a/packages/jats/graphic/_index.css b/packages/jats/graphic/_index.css new file mode 100644 index 000000000..d00ab8b87 --- /dev/null +++ b/packages/jats/graphic/_index.css @@ -0,0 +1,4 @@ +.sc-graphic img { + max-width: 100%; + display: block; +} \ No newline at end of file diff --git a/packages/jats/graphic/package.js b/packages/jats/graphic/package.js index 4a1f06909..3cb587702 100644 --- a/packages/jats/graphic/package.js +++ b/packages/jats/graphic/package.js @@ -10,6 +10,5 @@ module.exports = { config.addNode(Graphic); config.addComponent(Graphic.type, GraphicComponent); config.addConverter('jats', GraphicConverter); - config.addStyle(__dirname, '_graphic.scss'); } }; \ No newline at end of file diff --git a/packages/jats/italic/_italic.scss b/packages/jats/italic/_index.css similarity index 100% rename from packages/jats/italic/_italic.scss rename to packages/jats/italic/_index.css diff --git a/packages/jats/italic/package.js b/packages/jats/italic/package.js index cbad2f033..1e1118aaf 100644 --- a/packages/jats/italic/package.js +++ b/packages/jats/italic/package.js @@ -8,6 +8,5 @@ module.exports = { configure: function(config) { config.addNode(Italic); config.addConverter('jats', ItalicConverter); - config.addStyle(__dirname, '_italic.scss'); } }; diff --git a/packages/jats/monospace/_index.css b/packages/jats/monospace/_index.css new file mode 100644 index 000000000..b0bf67b0c --- /dev/null +++ b/packages/jats/monospace/_index.css @@ -0,0 +1,4 @@ +.sc-monospace { + font-family: var(--font-family-code); + font-size: var(--font-size-code); +} \ No newline at end of file diff --git a/packages/jats/monospace/_monospace.scss b/packages/jats/monospace/_monospace.scss deleted file mode 100644 index 28b55b0d1..000000000 --- a/packages/jats/monospace/_monospace.scss +++ /dev/null @@ -1,4 +0,0 @@ -.sc-monospace { - font-family: $font-family-code; - font-size: $font-size-code; -} \ No newline at end of file diff --git a/packages/jats/monospace/package.js b/packages/jats/monospace/package.js index 6e201256f..ef0ed4340 100644 --- a/packages/jats/monospace/package.js +++ b/packages/jats/monospace/package.js @@ -8,6 +8,5 @@ module.exports = { configure: function(config) { config.addNode(Monospace); config.addConverter('jats', MonospaceConverter); - config.addStyle(__dirname, '_monospace.scss'); } }; diff --git a/packages/jats/package.js b/packages/jats/package.js index 796d5fd6f..7151293fe 100644 --- a/packages/jats/package.js +++ b/packages/jats/package.js @@ -32,7 +32,6 @@ module.exports = { config.import(require('./subscript/package')); config.import(require('./superscript/package')); config.import(require('./table/package')); - // config.import(require('./table-wrap/package')); config.import(require('./title/package')); config.addImporter('jats', JATSImporter); diff --git a/packages/jats/ref-list/_index.css b/packages/jats/ref-list/_index.css new file mode 100644 index 000000000..4211c4cab --- /dev/null +++ b/packages/jats/ref-list/_index.css @@ -0,0 +1,6 @@ +.sc-ref-list { + font-size: var(--small-font-size); +} +.sc-ref { + margin-bottom: 20px; +} \ No newline at end of file diff --git a/packages/jats/ref-list/_ref-list.scss b/packages/jats/ref-list/_ref-list.scss deleted file mode 100644 index dc665a1cf..000000000 --- a/packages/jats/ref-list/_ref-list.scss +++ /dev/null @@ -1,7 +0,0 @@ -.sc-ref-list { - font-size: $small-font-size; - - .sc-ref { - margin-bottom: 20px; - } -} \ No newline at end of file diff --git a/packages/jats/ref-list/package.js b/packages/jats/ref-list/package.js index 6146bbf92..a1d825c00 100644 --- a/packages/jats/ref-list/package.js +++ b/packages/jats/ref-list/package.js @@ -10,6 +10,5 @@ module.exports = { config.addNode(RefList); config.addComponent(RefList.type, RefListComponent); config.addConverter('jats', RefListConverter); - config.addStyle(__dirname, '_ref-list.scss'); } }; \ No newline at end of file diff --git a/packages/jats/ref/_index.css b/packages/jats/ref/_index.css new file mode 100644 index 000000000..fb5913a39 --- /dev/null +++ b/packages/jats/ref/_index.css @@ -0,0 +1,16 @@ +.sc-ref-target { + font-size: var(--small-font-size); + border-bottom: 1px solid var(--border-color); + padding: var(--default-padding); + background: #fafafa; + border-bottom: 1px solid #ddd; + border-left: 4px solid transparent; + cursor: pointer; +} +.sc-ref-target:hover { + background: #fff; +} +.sc-ref-target.sm-selected { + border-left: 4px solid #0b9dd9; + background: #fff; +} diff --git a/packages/jats/ref/_ref.scss b/packages/jats/ref/_ref.scss deleted file mode 100644 index ca327edf1..000000000 --- a/packages/jats/ref/_ref.scss +++ /dev/null @@ -1,19 +0,0 @@ -.sc-ref-target { - font-size: $small-font-size; - border-bottom: 1px solid $border-color; - padding: $default-padding; - - background: #fafafa; - border-bottom: 1px solid #ddd; - border-left: 4px solid transparent; - cursor: pointer; - - &:hover { - background: #fff; - } - - &.sm-selected { - border-left: 4px solid #0b9dd9; - background: #fff; - } -} \ No newline at end of file diff --git a/packages/jats/section/_index.css b/packages/jats/section/_index.css new file mode 100644 index 000000000..a48718c61 --- /dev/null +++ b/packages/jats/section/_index.css @@ -0,0 +1,29 @@ +.sc-section > .se-title { + font-size: var(--h1-font-size); + margin-bottom: var(--h1-font-size); +} + +.sc-section .sc-section > .se-title { + font-size: var(--h2-font-size); + margin-bottom: var(--h2-font-size); +} + +.sc-section .sc-section .sc-section > .se-title { + font-size: var(--h3-font-size); + margin-bottom: var(--h3-font-size); +} + +.sc-section > .se-section { + font-size: var(--h1-font-size); + margin-bottom: var(--h1-font-size); +} + +.sc-section .sc-section > .se-title { + font-size: var(--h2-font-size); + margin-bottom: var(--h2-font-size); +} + +.sc-section .sc-section .sc-section > .se-title { + font-size: var(--h3-font-size); + margin-bottom: var(--h3-font-size); +} diff --git a/packages/jats/section/_section.scss b/packages/jats/section/_section.scss deleted file mode 100644 index 6c35460fc..000000000 --- a/packages/jats/section/_section.scss +++ /dev/null @@ -1,29 +0,0 @@ -.sc-section > .se-title { - font-size: $h1-font-size; - margin-bottom: $h1-font-size; -} - -.sc-section .sc-section > .se-title { - font-size: $h2-font-size; - margin-bottom: $h2-font-size; -} - -.sc-section .sc-section .sc-section > .se-title { - font-size: $h3-font-size; - margin-bottom: $h3-font-size; -} - -.sc-section > .se-section { - font-size: $h1-font-size; - margin-bottom: $h1-font-size; -} - -.sc-section .sc-section > .se-title { - font-size: $h2-font-size; - margin-bottom: $h2-font-size; -} - -.sc-section .sc-section .sc-section > .se-title { - font-size: $h3-font-size; - margin-bottom: $h3-font-size; -} diff --git a/packages/jats/section/package.js b/packages/jats/section/package.js index 8beb540b1..85af81a9a 100644 --- a/packages/jats/section/package.js +++ b/packages/jats/section/package.js @@ -10,6 +10,5 @@ module.exports = { config.addNode(Section); config.addComponent('section', SectionComponent); config.addConverter('jats', SectionConverter); - config.addStyle(__dirname, '_section.scss'); } }; diff --git a/packages/jats/subscript/_subscript.scss b/packages/jats/subscript/_index.css similarity index 100% rename from packages/jats/subscript/_subscript.scss rename to packages/jats/subscript/_index.css diff --git a/packages/jats/subscript/package.js b/packages/jats/subscript/package.js index 0474935eb..4ea6f25b7 100644 --- a/packages/jats/subscript/package.js +++ b/packages/jats/subscript/package.js @@ -8,6 +8,5 @@ module.exports = { configure: function(config) { config.addNode(Subscript); config.addConverter('jats', SubscriptConverter); - config.addStyle(__dirname, '_subscript.scss'); } }; diff --git a/packages/jats/superscript/_superscript.scss b/packages/jats/superscript/_index.css similarity index 100% rename from packages/jats/superscript/_superscript.scss rename to packages/jats/superscript/_index.css diff --git a/packages/jats/superscript/package.js b/packages/jats/superscript/package.js index f7b1bd964..148407320 100644 --- a/packages/jats/superscript/package.js +++ b/packages/jats/superscript/package.js @@ -8,6 +8,5 @@ module.exports = { configure: function(config) { config.addNode(Superscript); config.addConverter('jats', SuperscriptConverter); - config.addStyle(__dirname, '_superscript.scss'); } }; diff --git a/packages/jats/title/_index.css b/packages/jats/title/_index.css new file mode 100644 index 000000000..7b229d09e --- /dev/null +++ b/packages/jats/title/_index.css @@ -0,0 +1,6 @@ +.sc-title { + padding-bottom: var(--default-padding); + font-weight: var(--strong-font-weight); + letter-spacing: var(--heading-letterspacing); + font-size: var(--h1-font-size); +} \ No newline at end of file diff --git a/packages/jats/title/_title.scss b/packages/jats/title/_title.scss deleted file mode 100644 index 7fd82d60e..000000000 --- a/packages/jats/title/_title.scss +++ /dev/null @@ -1,6 +0,0 @@ - .sc-title { - padding-bottom: $default-padding; - font-weight: $strong-font-weight; - letter-spacing: $heading-letterspacing; - font-size: $h1-font-size; - } \ No newline at end of file diff --git a/packages/jats/xref/_index.css b/packages/jats/xref/_index.css new file mode 100644 index 000000000..b13a077a1 --- /dev/null +++ b/packages/jats/xref/_index.css @@ -0,0 +1,25 @@ +.sc-xref { + background: rgba(0, 0, 0, 0.075); + border-bottom: 1px solid rgba(0, 0, 0, 0.3); + white-space: nowrap; +} +.sc-xref.sm-bibr { + background: rgba(11, 157, 217, 0.075); + color: #1B6685; + border-bottom: 1px solid rgba(11, 157, 217, 0.4); +} +.sc-xref.sm-fig { + background: rgba(145, 187, 4, 0.15); + border-bottom: 1px solid rgba(145, 187, 4, 0.6); + color: #495A11; +} + +.sc-xref-targets { + max-height: 600px; + overflow: auto; +} + +.sc-xref-tool > .se-actions > button { + padding: 5px; + font-size: var(--small-font-size); +} diff --git a/packages/jats/xref/_xref.scss b/packages/jats/xref/_xref.scss deleted file mode 100644 index ff25bb0ef..000000000 --- a/packages/jats/xref/_xref.scss +++ /dev/null @@ -1,29 +0,0 @@ -.sc-xref { - background: rgba(0,0,0,0.075); - border-bottom: 1px solid rgba(0,0,0,0.3); - white-space: nowrap; - - &.sm-bibr { - background: rgba(11, 157, 217, 0.075); - color: #1B6685; - border-bottom: 1px solid rgba(11, 157, 217, 0.4); - } - - &.sm-fig { - background: rgba(145, 187, 4, 0.15); - border-bottom: 1px solid rgba(145, 187, 4, 0.6); - color: #495A11; - } -} - -.sc-xref-targets { - max-height: 600px; - overflow: auto; -} - -.sc-xref-tool { - > .se-actions > button { - padding: 5px; - font-size: $small-font-size; - } -} \ No newline at end of file diff --git a/packages/jats/xref/package.js b/packages/jats/xref/package.js index 9c2459fdf..61ee70db5 100644 --- a/packages/jats/xref/package.js +++ b/packages/jats/xref/package.js @@ -14,7 +14,6 @@ module.exports = { config.addConverter('jats', XRefConverter); config.addCommand(XRef.type, XRefCommand, {nodeType: XRef.type}); config.addTool(XRef.type, XRefTool, { overlay: true }); - config.addStyle(__dirname, '_xref.scss'); config.addLabel(XRef.type, { en: 'Cross Reference' }); diff --git a/packages/publisher/_index.css b/packages/publisher/_index.css new file mode 100644 index 000000000..3f7945e79 --- /dev/null +++ b/packages/publisher/_index.css @@ -0,0 +1,5 @@ +.sc-publisher {} +.sc-publisher .se-context-section { background: #fafafa; border-left: 1px solid var(--border-color); } +.sc-publisher .se-context-section .se-toc-entries { padding-right: 20px; } +.sc-publisher .sc-body .sc-container-editor > * { margin-bottom: 20px; } +.sc-publisher .sc-toolbar { border-bottom: 1px solid var(--border-color); } diff --git a/packages/publisher/_publisher.scss b/packages/publisher/_publisher.scss deleted file mode 100644 index 7d2c1616e..000000000 --- a/packages/publisher/_publisher.scss +++ /dev/null @@ -1,21 +0,0 @@ -$fa-font-path: "../fonts" !default; -@import '../../node_modules/font-awesome/scss/font-awesome'; - -.sc-publisher { - .se-context-section { - background: #fafafa; - border-left: 1px solid $border-color; - - .se-toc-entries { - padding-right: 20px; - } - } - - .sc-body .sc-container-editor > * { - margin-bottom: 20px; - } - - .sc-toolbar { - border-bottom: 1px solid $border-color; - } -} diff --git a/packages/unsupported/_index.css b/packages/unsupported/_index.css new file mode 100644 index 000000000..222fd0ff5 --- /dev/null +++ b/packages/unsupported/_index.css @@ -0,0 +1,20 @@ +.sc-unsupported-block-node { + font-family: var(--font-family-code); + font-size: var(--small-font-size) - 2; + border: 1px dashed var(--border-color); +} + +.sc-unsupported-inline-node { + font-family: var(--font-family-code); + font-size: var(--small-font-size) - 2; + border: 1px dashed var(--border-color); + color: #E3710C; + cursor: pointer !important; +} + +.sc-edit-xml { padding: var(--default-padding); } + +.sc-edit-xml textarea { + width: 100%; + height: 400px; +} \ No newline at end of file diff --git a/packages/unsupported/_unsupported.scss b/packages/unsupported/_unsupported.scss deleted file mode 100644 index 60c865dbf..000000000 --- a/packages/unsupported/_unsupported.scss +++ /dev/null @@ -1,21 +0,0 @@ -.sc-unsupported-block-node { - font-family: $font-family-code; - font-size: $small-font-size - 2; - border: 1px dashed $border-color; -} - -.sc-unsupported-inline-node { - font-family: $font-family-code; - font-size: $small-font-size - 2; - border: 1px dashed $border-color; - color: #E3710C; - cursor: pointer !important; -} - -.sc-edit-xml { - padding: $default-padding; - textarea { - width: 100%; - height: 400px; - } -} \ No newline at end of file diff --git a/server.js b/server.js index f390b740a..7b3b2319a 100644 --- a/server.js +++ b/server.js @@ -12,24 +12,23 @@ var browserifyConfig = { debug: true }; - // Writer example integration -serverUtils.serveStyles(app, '/publisher/app.css', { - rootDir: __dirname, - configuratorPath: require.resolve('./packages/texture/TextureConfigurator'), - configPath: require.resolve('./examples/publisher/package'), -}); +// serverUtils.serveStyles(app, '/publisher/app.css', { +// rootDir: __dirname, +// configuratorPath: require.resolve('./packages/texture/TextureConfigurator'), +// configPath: require.resolve('./examples/publisher/package'), +// }); serverUtils.serveJS(app, '/publisher/app.js', { sourcePath: path.join(__dirname, 'examples/publisher', 'app.js'), browserify: browserifyConfig, }); serverUtils.serveHTML(app, '/publisher', path.join(__dirname, 'examples/publisher', 'index.html'), {}); -serverUtils.serveStyles(app, '/author/app.css', { - rootDir: __dirname, - configuratorPath: require.resolve('./packages/texture/TextureConfigurator'), - configPath: require.resolve('./examples/author/package'), -}); +// serverUtils.serveStyles(app, '/author/app.css', { +// rootDir: __dirname, +// configuratorPath: require.resolve('./packages/texture/TextureConfigurator'), +// configPath: require.resolve('./examples/author/package'), +// }); serverUtils.serveJS(app, '/author/app.js', { sourcePath: path.join(__dirname, 'examples/author', 'app.js'), browserify: browserifyConfig, @@ -43,6 +42,7 @@ app.use('/fonts', express.static(path.join(__dirname, 'node_modules/font-awesome app.use(express.static(__dirname)); app.use('/substance', express.static(path.join(__dirname, 'node_modules/substance'))); +app.use('/font-awesome', express.static(path.join(__dirname, 'node_modules/font-awesome'))); serverUtils.serveTestSuite(app, "test/**/*.test.js"); diff --git a/texture.css b/texture.css index b569bb1ab..d78fad989 100644 --- a/texture.css +++ b/texture.css @@ -1 +1 @@ -@import 'packages/_index.css'; \ No newline at end of file +@import './packages/_index.css'; \ No newline at end of file From e53febfce9083210ad20594c8d8ed3850514730e Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 5 Sep 2016 17:10:07 +0200 Subject: [PATCH 047/167] Ditch addStyle configurator API. --- README.md | 2 -- examples/publisher/package.js | 1 - packages/author/package.js | 2 -- packages/common/package.js | 2 -- packages/jats/article-title/package.js | 1 - packages/jats/back/package.js | 1 - packages/jats/bold/package.js | 1 - packages/jats/figure/package.js | 2 -- packages/jats/footnote/package.js | 1 - packages/jats/ref/package.js | 1 - packages/jats/title/package.js | 1 - packages/publisher/package.js | 5 ----- 12 files changed, 20 deletions(-) diff --git a/README.md b/README.md index 3865ccdc5..ae4c7ea8e 100644 --- a/README.md +++ b/README.md @@ -82,8 +82,6 @@ module.exports = { // Define XML Store config.setXMLStore(MyXMLStore); - // Add your custom app styles - config.addStyle(__dirname, 'my-texture.scss'); } }; ``` diff --git a/examples/publisher/package.js b/examples/publisher/package.js index 8c8bcafd3..2d654d4f4 100644 --- a/examples/publisher/package.js +++ b/examples/publisher/package.js @@ -10,6 +10,5 @@ module.exports = { // Define XML Store config.setXMLStore(ExampleXMLStore); - config.addStyle(__dirname, 'app.scss'); } }; diff --git a/packages/author/package.js b/packages/author/package.js index 7708e5a13..2c0938749 100644 --- a/packages/author/package.js +++ b/packages/author/package.js @@ -20,8 +20,6 @@ module.exports = { config.import(require('../jats/package')); config.import(require('./heading/package')); config.import(require('../common/package')); - config.addStyle(__dirname, '_author'); - // support inline wrappers, for all hybrid types that can be // block-level but also inline. diff --git a/packages/common/package.js b/packages/common/package.js index 9d918173f..8d22bbd6d 100644 --- a/packages/common/package.js +++ b/packages/common/package.js @@ -3,7 +3,5 @@ module.exports = { name: 'common', configure: function(config) { - config.addStyle(__dirname, '_isolated-node.scss'); - config.addStyle(__dirname, '_edit-xml.scss'); } }; \ No newline at end of file diff --git a/packages/jats/article-title/package.js b/packages/jats/article-title/package.js index 567a68df4..7dcea75f5 100644 --- a/packages/jats/article-title/package.js +++ b/packages/jats/article-title/package.js @@ -10,6 +10,5 @@ module.exports = { config.addNode(ArticleTitle); config.addConverter('jats', ArticleTitleConverter); config.addComponent(ArticleTitle.type, ArticleTitleComponent); - config.addStyle(__dirname, '_article-title.scss'); } }; diff --git a/packages/jats/back/package.js b/packages/jats/back/package.js index 673df89b2..8ba28bbf0 100644 --- a/packages/jats/back/package.js +++ b/packages/jats/back/package.js @@ -10,6 +10,5 @@ module.exports = { config.addNode(Back); config.addConverter('jats', BackConverter); config.addComponent(Back.type, BackComponent); - config.addStyle(__dirname, '_back.scss'); } }; \ No newline at end of file diff --git a/packages/jats/bold/package.js b/packages/jats/bold/package.js index 3e2a18d6c..9102c5803 100644 --- a/packages/jats/bold/package.js +++ b/packages/jats/bold/package.js @@ -13,7 +13,6 @@ module.exports = { config.addCommand(Bold.type, BoldCommand, { nodeType: Bold.type }); config.addTool(Bold.type, BoldTool); config.addIcon(Bold.type, { 'fontawesome': 'fa-bold' }); - config.addStyle(__dirname, '_bold.scss'); config.addLabel(Bold.type, { en: 'Bold' }); diff --git a/packages/jats/figure/package.js b/packages/jats/figure/package.js index 19de540f9..389b1d4d7 100644 --- a/packages/jats/figure/package.js +++ b/packages/jats/figure/package.js @@ -12,7 +12,5 @@ module.exports = { config.addComponent(Figure.type, FigureComponent); config.addComponent(Figure.type+'-target', FigureTarget); config.addConverter('jats', FigureConverter); - config.addStyle(__dirname, '_figure.scss'); - config.addStyle(__dirname, '_figure-target.scss'); } }; diff --git a/packages/jats/footnote/package.js b/packages/jats/footnote/package.js index 481601cf9..78cc8b78c 100644 --- a/packages/jats/footnote/package.js +++ b/packages/jats/footnote/package.js @@ -10,6 +10,5 @@ module.exports = { config.addNode(Footnote); config.addComponent(Footnote.type, FootnoteComponent); config.addConverter('jats', FootnoteConverter); - config.addStyle(__dirname, '_footnote.scss'); } }; \ No newline at end of file diff --git a/packages/jats/ref/package.js b/packages/jats/ref/package.js index 4032e7bb2..8349de40e 100644 --- a/packages/jats/ref/package.js +++ b/packages/jats/ref/package.js @@ -12,6 +12,5 @@ module.exports = { config.addComponent(Ref.type, RefComponent); config.addComponent(Ref.type+'-target', RefTarget); config.addConverter('jats', RefConverter); - config.addStyle(__dirname, '_ref.scss'); } }; \ No newline at end of file diff --git a/packages/jats/title/package.js b/packages/jats/title/package.js index 127e098f9..34604c052 100644 --- a/packages/jats/title/package.js +++ b/packages/jats/title/package.js @@ -10,6 +10,5 @@ module.exports = { config.addNode(Title); config.addConverter('jats', TitleConverter); config.addComponent(Title.type, TitleComponent); - config.addStyle(__dirname, '_title.scss'); } }; diff --git a/packages/publisher/package.js b/packages/publisher/package.js index 16fcd1f72..c813d8af7 100644 --- a/packages/publisher/package.js +++ b/packages/publisher/package.js @@ -9,19 +9,14 @@ module.exports = { // Now import base packages config.import(require('substance/packages/base/BasePackage')); config.import(require('substance/packages/persistence/PersistencePackage')); - // TODO: see substance#712 config.addComponent('overlay', Overlay); // TODO: this should be used as default, too config.setToolbarClass(Toolbar); - config.addStyle(__dirname, '_publisher'); - config.import(require('../jats/package')); config.import(require('../common/package')); - // support inline wrappers, for all hybrid types that can be // block-level but also inline. config.import(require('../inline-wrapper/InlineWrapperPackage')); - // catch all converters config.import(require('../unsupported/UnsupportedNodePackage')); } From 2245faa30244525efdd02294c5a9046db4b75179 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 6 Sep 2016 15:47:54 +0200 Subject: [PATCH 048/167] Fix CSS syntax error. --- packages/common/_isolated-node.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/_isolated-node.css b/packages/common/_isolated-node.css index 6355f8933..d9f087434 100644 --- a/packages/common/_isolated-node.css +++ b/packages/common/_isolated-node.css @@ -9,7 +9,7 @@ background: transparent; } -.sc-isolated-node.sm-selected > .se-container, { +.sc-isolated-node.sm-selected > .se-container { background: rgba(163, 205, 253, 0.3); outline: 2px solid #A3CDFD; } \ No newline at end of file From 05a6b1aa77ef7bf273026ae548b1d099698e7b1b Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 6 Sep 2016 15:48:14 +0200 Subject: [PATCH 049/167] Cleanup server.js Soon to be obsolete once we have Substance bundler in place. --- server.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/server.js b/server.js index 7b3b2319a..4982e30c7 100644 --- a/server.js +++ b/server.js @@ -1,7 +1,6 @@ 'use strict'; /* eslint-disable no-console */ - var express = require('express'); var path = require('path'); var PORT = process.env.PORT || 5001; @@ -12,23 +11,12 @@ var browserifyConfig = { debug: true }; -// Writer example integration -// serverUtils.serveStyles(app, '/publisher/app.css', { -// rootDir: __dirname, -// configuratorPath: require.resolve('./packages/texture/TextureConfigurator'), -// configPath: require.resolve('./examples/publisher/package'), -// }); serverUtils.serveJS(app, '/publisher/app.js', { sourcePath: path.join(__dirname, 'examples/publisher', 'app.js'), browserify: browserifyConfig, }); serverUtils.serveHTML(app, '/publisher', path.join(__dirname, 'examples/publisher', 'index.html'), {}); -// serverUtils.serveStyles(app, '/author/app.css', { -// rootDir: __dirname, -// configuratorPath: require.resolve('./packages/texture/TextureConfigurator'), -// configPath: require.resolve('./examples/author/package'), -// }); serverUtils.serveJS(app, '/author/app.js', { sourcePath: path.join(__dirname, 'examples/author', 'app.js'), browserify: browserifyConfig, From 8816590e3d59faa99084c09fd175ed39bc07006f Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 6 Sep 2016 15:50:16 +0200 Subject: [PATCH 050/167] Update package.json. --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 6b9c937b0..2e6d3b1a4 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "A scientific editor and reader for JATS files.", "dependencies": { "lodash": "^4.2.1", - "substance": "substance/substance#pure-css" + "substance": "substance/substance#develop" }, "devDependencies": { "browserify": "substance/node-browserify#d3caeb6dcdaa97a258d099c7231a57f0f60ec876", @@ -32,5 +32,5 @@ "bundle": "gulp", "test": "gulp test" }, - "version": "1.0.0-alpha" + "version": "1.0.0-alpha.2" } From de21f21d260866387b62ea981ca4e9f2093be914 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 6 Sep 2016 16:26:05 +0200 Subject: [PATCH 051/167] addStyle is no longer. --- examples/author/package.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/author/package.js b/examples/author/package.js index 7bd21f18b..a9f9aae36 100644 --- a/examples/author/package.js +++ b/examples/author/package.js @@ -8,9 +8,7 @@ module.exports = { configure: function(config) { // Use the default Texture package config.import(TexturePackage); - // Define XML Store config.setXMLStore(ExampleXMLStore); - config.addStyle(__dirname, 'app.scss'); } }; From 14c243de1e9548e908b946192bb2ff9b0c7abb50 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 6 Sep 2016 16:27:02 +0200 Subject: [PATCH 052/167] Remove experimental functionality (contrib) Remove contrib, add contrib will be implemented in next version. --- README.md | 1 - packages/common/EditXML.js | 4 +--- packages/jats/contrib-group/ContribGroupComponent.js | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ae4c7ea8e..bc0c1bda6 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,6 @@ See [CONTRIBUTING.md](CONTRIBUTING.md). - Editing of authors (create, update and delete contrib elements) - Create and edit xref elements - ### Alpha 3 *ETA: October 2016* diff --git a/packages/common/EditXML.js b/packages/common/EditXML.js index 15a11d1bd..b31dfd792 100644 --- a/packages/common/EditXML.js +++ b/packages/common/EditXML.js @@ -42,8 +42,7 @@ EditXML.Prototype = function() { el.append( $$('div').addClass('se-actions').append( $$(Button).append('Save').on('click', this._save), - $$(Button).addClass('se-cancel').append('Cancel').on('click', this._cancel), - $$(Button).addClass('se-delete').append('Delete').on('click', this._delete) + $$(Button).addClass('se-cancel').append('Cancel').on('click', this._cancel) ) ); return el; @@ -68,7 +67,6 @@ EditXML.Prototype = function() { var newXML = this.refs.xmlEditor.getXML(); // TODO: add validity checks. E.g. try to parse XML string - documentSession.transaction(function(tx) { tx.set([node.id, 'xmlContent'], newXML); tx.set([node.id, 'attributes'], newAttributes); diff --git a/packages/jats/contrib-group/ContribGroupComponent.js b/packages/jats/contrib-group/ContribGroupComponent.js index 01d4b5c70..b05481934 100644 --- a/packages/jats/contrib-group/ContribGroupComponent.js +++ b/packages/jats/contrib-group/ContribGroupComponent.js @@ -29,7 +29,7 @@ ContribGroupComponent.Prototype = function() { } }.bind(this)); - el.append($$('button').addClass('se-add-author').append('Add Author')); + // el.append($$('button').addClass('se-add-author').append('Add Author')); return el; }; }; From b758b5ba226ec4deff13ff06c45f10e67e4b7307 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 6 Sep 2016 17:46:14 +0200 Subject: [PATCH 053/167] Add new xref tool. --- packages/jats/xref/AddXRefCommand.js | 22 ++++++++++++++++++++++ packages/jats/xref/AddXRefTool.js | 11 +++++++++++ packages/jats/xref/package.js | 10 +++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 packages/jats/xref/AddXRefCommand.js create mode 100644 packages/jats/xref/AddXRefTool.js diff --git a/packages/jats/xref/AddXRefCommand.js b/packages/jats/xref/AddXRefCommand.js new file mode 100644 index 000000000..704d9e8d1 --- /dev/null +++ b/packages/jats/xref/AddXRefCommand.js @@ -0,0 +1,22 @@ +'use strict'; + +var InlineNodeCommand = require('substance/ui/InlineNodeCommand'); + +function AddXRefCommand() { + AddXRefCommand.super.apply(this, arguments); +} + +AddXRefCommand.Prototype = function() { + this.createNodeData = function() { + return { + attributes: {'ref-type': 'bibr'}, + targets: [], + label: '???', + type: 'xref' + }; + }; +}; + +InlineNodeCommand.extend(AddXRefCommand); + +module.exports = AddXRefCommand; \ No newline at end of file diff --git a/packages/jats/xref/AddXRefTool.js b/packages/jats/xref/AddXRefTool.js new file mode 100644 index 000000000..418bf9c60 --- /dev/null +++ b/packages/jats/xref/AddXRefTool.js @@ -0,0 +1,11 @@ +'use strict'; + +var AnnotationTool = require('substance/ui/AnnotationTool'); + +function AddXRefTool() { + AddXRefTool.super.apply(this, arguments); +} + +AnnotationTool.extend(AddXRefTool); + +module.exports = AddXRefTool; \ No newline at end of file diff --git a/packages/jats/xref/package.js b/packages/jats/xref/package.js index 61ee70db5..6cbe09bab 100644 --- a/packages/jats/xref/package.js +++ b/packages/jats/xref/package.js @@ -5,6 +5,8 @@ var XRefComponent = require('./XRefComponent'); var XRefConverter = require('./XRefConverter'); var XRefCommand = require('./XRefCommand'); var XRefTool = require('./XRefTool'); +var AddXRefCommand = require('./AddXRefCommand'); +var AddXRefTool = require('./AddXRefTool'); module.exports = { name: 'xref', @@ -12,8 +14,14 @@ module.exports = { config.addNode(XRef); config.addComponent(XRef.type, XRefComponent); config.addConverter('jats', XRefConverter); + + // TODO: is there a way to use only one command for the two different tools config.addCommand(XRef.type, XRefCommand, {nodeType: XRef.type}); + config.addCommand('add-xref', AddXRefCommand, {nodeType: XRef.type}); + config.addTool('add-xref', AddXRefTool); config.addTool(XRef.type, XRefTool, { overlay: true }); + + config.addIcon('add-xref', { 'fontawesome': 'fa-external-link' }); config.addLabel(XRef.type, { en: 'Cross Reference' }); @@ -24,4 +32,4 @@ module.exports = { en: 'Delete Reference' }); } -}; \ No newline at end of file +}; From c7c95fb304cbe0f8a22cd954df1895bd07d5ab86 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 7 Sep 2016 17:18:23 +0200 Subject: [PATCH 054/167] Implement tagging of references. --- .eslintrc.js | 6 +- examples/data/kitchen-sink-author.xml | 71 +++++-------------- packages/common/package.js | 3 +- packages/jats/article/ScientistArticle.js | 11 --- packages/jats/article/TextureArticle.js | 16 +++++ packages/jats/article/package.js | 6 +- packages/jats/contrib/Contrib.js | 10 ++- packages/jats/ref-list/RefListComponent.js | 23 ++++--- packages/jats/ref/Ref.js | 19 +++++ packages/jats/ref/RefComponent.js | 2 +- packages/jats/ref/RefTarget.js | 2 +- packages/jats/ref/TagRefCommand.js | 80 ++++++++++++++++++++++ packages/jats/ref/TagRefTool.js | 10 +++ packages/jats/ref/package.js | 5 ++ packages/jats/ref/refToHTML.js | 15 ++-- 15 files changed, 185 insertions(+), 94 deletions(-) delete mode 100644 packages/jats/article/ScientistArticle.js create mode 100644 packages/jats/article/TextureArticle.js create mode 100644 packages/jats/ref/TagRefCommand.js create mode 100644 packages/jats/ref/TagRefTool.js diff --git a/.eslintrc.js b/.eslintrc.js index c05e295de..a482fe8e1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,6 +4,10 @@ module.exports = { "commonjs": true, "node": true }, + "parserOptions": { + "sourceType": "module", + "ecmaVersion": 6 + }, "extends": "eslint:recommended", "globals": { "QUnit": true @@ -43,7 +47,7 @@ module.exports = { "use-isnan": 2, "valid-jsdoc": 0, "valid-typeof": 2, - "strict": [2, "safe"], + "strict": 0, // [2, "safe"], // Best practices "accessor-pairs": 0, diff --git a/examples/data/kitchen-sink-author.xml b/examples/data/kitchen-sink-author.xml index cb9e200ac..b7af0839c 100644 --- a/examples/data/kitchen-sink-author.xml +++ b/examples/data/kitchen-sink-author.xml @@ -5,28 +5,24 @@ - Kitchen sink example for authors + Turn Word documents into structured JATS with Texture - Forster - Anne Williams + Aufreiter + Michael - research physiotherapist - - + - Young - John G. + Buchtala + Oliver - consultant physician - + - Department of Health Care for the Elderly, St Luke’s Hospital, Bradford BD5 0NA - Academic Section of Geriatric Medicine, Royal Infirmary, Glasgow G4 0SF + Substance Software GmbH, Linz, Austria @@ -36,12 +32,15 @@ - First Section -

    This is a basic JATS-compatible article, using a reduced set of tags. It supports citing references ([1,2]) and figures.

    + Introduction +

    Texture is a tool for publishers for creating structured JATS documents based on Word or InDesign submissions. Texture is developed by the Substance Consortium ([1]) formed by the Public Knowledge Project (PKP), the Collaborative Knowledge Foundation (CoKo) and Érudit.

    +

    The tool is available as open source on Github ([2]) and

    - Second Section -

    This is the second paragraph

    + Create a bibliography +

    Below is a list of unstructured references. Use the tag tool to turn them into bibliographic entries. After tagging you can cite them from within the text.

    +

    Albert I, Mavrich TN, Tomsho LP, Qi J, Zanton SJ, Schuster SC, et al. 2007. Translational and rotational settings of H2A.Z nucleosomes across the Saccharomyces cerevisiae genome. Nature 446:572–6.

    +

    Altman-Price N, Mevarech M. 2009. Genetic evidence for the importance of protein acetylation and protein deacetylation in the halophilic archaeon Haloferax volcanii. J Bacteriol 191:1610–7.

    @@ -49,46 +48,10 @@ References - - - - Allison - JD - - - Hare - JD - - - 2009 - Learned and naïve natural enemy responses and the interpretation of volatile organic compounds as cues or signals - New Phytol - 184 - 768 - 782 - 10.1111/j.1469-8137.2009.03046.x - + Bailey KA, Pereira SL, Widom J, Reeve JN. 2000. Archaeal histone selection of nucleosome positioning sequences and the procaryotic origin of histone-dependent genome evolution. J Mol Biol 303:25–34. - - - - Allmann - S - - - Baldwin - IT - - - 2010 - Insects betray themselves in nature to predators by rapid isomerization of green leaf volatiles - Science - 329 - 1075 - 1078 - 10.1126/science.1191634 - + Altschul SF, Gish W, Miller W, Myers EW, Lipman DJ. 1990. Basic local alignment search tool. J Mol Biol 215:403–10. diff --git a/packages/common/package.js b/packages/common/package.js index 8d22bbd6d..eaa38c234 100644 --- a/packages/common/package.js +++ b/packages/common/package.js @@ -2,6 +2,5 @@ module.exports = { name: 'common', - configure: function(config) { - } + configure: function() {} }; \ No newline at end of file diff --git a/packages/jats/article/ScientistArticle.js b/packages/jats/article/ScientistArticle.js deleted file mode 100644 index f68cd4ed5..000000000 --- a/packages/jats/article/ScientistArticle.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -var Document = require('substance/model/Document'); - -function ScientistArticle(schema) { - ScientistArticle.super.call(this, schema); -} - -Document.extend(ScientistArticle); - -module.exports = ScientistArticle; diff --git a/packages/jats/article/TextureArticle.js b/packages/jats/article/TextureArticle.js new file mode 100644 index 000000000..ad48943eb --- /dev/null +++ b/packages/jats/article/TextureArticle.js @@ -0,0 +1,16 @@ +'use strict'; + +var Document = require('substance/model/Document'); + +class TextureArticle extends Document { + /* + Get first RefList + */ + getRefList() { + var refLists = this.getIndex('type').get('ref-list'); + var refListId = Object.keys(refLists)[0]; + return refListId ? this.get(refListId) : undefined; + } +} + +module.exports = TextureArticle; diff --git a/packages/jats/article/package.js b/packages/jats/article/package.js index e0051eb3a..d8ff1bfbd 100644 --- a/packages/jats/article/package.js +++ b/packages/jats/article/package.js @@ -2,15 +2,15 @@ var ArticleNode = require('./ArticleNode'); var ArticleConverter = require('./ArticleConverter'); -var ScientistArticle = require('./ScientistArticle'); +var TextureArticle = require('./TextureArticle'); var ArticleComponent = require('./ArticleComponent'); module.exports = { name: 'article', configure: function(config) { config.defineSchema({ - name: 'scientist-article', - ArticleClass: ScientistArticle, + name: 'texture-article', + ArticleClass: TextureArticle, defaultTextType: 'paragraph' }); config.addNode(ArticleNode); diff --git a/packages/jats/contrib/Contrib.js b/packages/jats/contrib/Contrib.js index b8166e05a..ddfd1b801 100644 --- a/packages/jats/contrib/Contrib.js +++ b/packages/jats/contrib/Contrib.js @@ -12,11 +12,17 @@ Contrib.type = 'contrib'; /* Content - (label?, (citation-alternatives | element-citation | mixed-citation | nlm-citation | note | x)+) + ( + ( + anonymous | collab | name | name-alternatives | string-name | degrees | + address | aff | aff-alternatives | author-comment | bio | email | etal | ext-link | + fn | on-behalf-of | role | uri | xref | x + )* + ) */ Contrib.define({ attributes: { type: 'object', default: {} }, - xmlContent: {type: 'string', default: ''}, + xmlContent: { type: 'string', default: ''}, tagName: 'string' }); diff --git a/packages/jats/ref-list/RefListComponent.js b/packages/jats/ref-list/RefListComponent.js index 5f384b171..9ae93f5ea 100644 --- a/packages/jats/ref-list/RefListComponent.js +++ b/packages/jats/ref-list/RefListComponent.js @@ -3,13 +3,20 @@ var Component = require('substance/ui/Component'); var renderNodeComponent = require('../../../util/renderNodeComponent'); -function RefListComponent() { - Component.apply(this, arguments); -} +class RefListComponent extends Component { + didMount() { + super.didMount(); + var node = this.props.node; + node.on('nodes:changed', this.rerender, this); + } -RefListComponent.Prototype = function() { + dispose() { + super.dispose(); + var node = this.props.node; + node.off(this); + } - this.render = function($$) { + render($$) { var node = this.props.node; var doc = node.getDocument(); var el = $$('div').addClass('sc-ref-list'); @@ -40,10 +47,8 @@ RefListComponent.Prototype = function() { }.bind(this)); return el; - }; -}; - -Component.extend(RefListComponent); + } +} // Isolated Nodes config RefListComponent.fullWidth = true; diff --git a/packages/jats/ref/Ref.js b/packages/jats/ref/Ref.js index bf0f4071b..a4c8d7293 100644 --- a/packages/jats/ref/Ref.js +++ b/packages/jats/ref/Ref.js @@ -1,6 +1,7 @@ 'use strict'; var DocumentNode = require('substance/model/DocumentNode'); +var DOMElement = require('substance/ui/DefaultDOMElement'); /* ref @@ -11,6 +12,24 @@ function Ref() { Ref.super.apply(this, arguments); } +Ref.Prototype = function() { + /* + Checks if ref is a plain text citation, with no formatting / tagging etc. + */ + this.isPlain = function() { + + }; + + /* + Get parsed DOM version of XML content + */ + this.getDOM = function() { + return DOMElement.parseXML(this.xmlContent); + }; + +}; + + DocumentNode.extend(Ref); Ref.type = 'ref'; diff --git a/packages/jats/ref/RefComponent.js b/packages/jats/ref/RefComponent.js index 2224272cb..bf4a9edee 100644 --- a/packages/jats/ref/RefComponent.js +++ b/packages/jats/ref/RefComponent.js @@ -11,7 +11,7 @@ function RefComponent() { RefComponent.Prototype = function() { this.render = function($$) { var el = $$('div').addClass('sc-ref'); - el.html(refToHTML(this.props.node.xmlContent)); + el.html(refToHTML(this.props.node)); return el; }; }; diff --git a/packages/jats/ref/RefTarget.js b/packages/jats/ref/RefTarget.js index ed5a894f8..5faf6e25d 100644 --- a/packages/jats/ref/RefTarget.js +++ b/packages/jats/ref/RefTarget.js @@ -21,7 +21,7 @@ RefTarget.Prototype = function() { el.addClass('sm-selected'); } var node = this.props.node; - el.html(refToHTML(node.xmlContent)); + el.html(refToHTML(node)); return el; }; }; diff --git a/packages/jats/ref/TagRefCommand.js b/packages/jats/ref/TagRefCommand.js new file mode 100644 index 000000000..5f6a7bde6 --- /dev/null +++ b/packages/jats/ref/TagRefCommand.js @@ -0,0 +1,80 @@ +'use strict'; + +var Command = require('substance/ui/Command'); +var uuid = require('substance/util/uuid'); +var Selection = require('substance/model/Selection'); + +class TagRefCommand extends Command { + + getCommandState(params, context) { + var documentSession = context.documentSession; + var doc = documentSession.getDocument(); + + var sel = this._getSelection(params); + var disabled = true; + var nodeIds; // all nodes included in the selection + + if (sel.isPropertySelection()) { + disabled = false; + nodeIds = [ sel.path[0] ]; + } else if (sel.isContainerSelection()) { + var fragments = sel.getFragments(); + nodeIds = + fragments.map(frag => frag.path[0]); + var isParagraph = + nodeId => doc.get(nodeId).type === 'paragraph'; + var onlyParagraphs = + (nodeIds) => nodeIds.every(isParagraph); + + if (onlyParagraphs(nodeIds)) { + disabled = false; + } + } + + return { + disabled: disabled, + nodeIds: nodeIds, + active: false + }; + } + + execute(params, context) { + var nodeIds = params.nodeIds; + var documentSession = context.documentSession; + var focusedSurface = context.surfaceManager.getFocusedSurface(); + + documentSession.transaction(function(tx) { + var refListId = tx.document.getRefList().id; + var refListNode = tx.get(refListId); + + nodeIds.forEach(nodeId => { + var p = tx.get(nodeId); + var newRef = { + id: uuid('ref'), + type: 'ref', + xmlContent: ''+p.content+'' + }; + var refNode = tx.create(newRef); + refListNode.show(refNode.id); + + // Remove original paragraphs from container + // We need to look up the owning container + // by inspecting the focused surface. + var containerId = focusedSurface.getContainerId(); + if (containerId) { + var container = tx.get(containerId); + container.hide(nodeId); + tx.delete(nodeId); + } + }); + + return { + selection: Selection.nullSelection + }; + }); + + return {status: 'ok'}; + } + +} +module.exports = TagRefCommand; diff --git a/packages/jats/ref/TagRefTool.js b/packages/jats/ref/TagRefTool.js new file mode 100644 index 000000000..279417b9f --- /dev/null +++ b/packages/jats/ref/TagRefTool.js @@ -0,0 +1,10 @@ +'use strict'; + +var Tool = require('substance/ui/Tool'); + +function TagRefTool() { + TagRefTool.super.apply(this, arguments); +} +Tool.extend(TagRefTool); + +module.exports = TagRefTool; diff --git a/packages/jats/ref/package.js b/packages/jats/ref/package.js index 8349de40e..3ae8bcbda 100644 --- a/packages/jats/ref/package.js +++ b/packages/jats/ref/package.js @@ -4,6 +4,8 @@ var Ref = require('./Ref'); var RefComponent = require('./RefComponent'); var RefTarget = require('./RefTarget'); var RefConverter = require('./RefConverter'); +var TagRefCommand = require('./TagRefCommand'); +var TagRefTool = require('./TagRefTool'); module.exports = { name: 'ref', @@ -12,5 +14,8 @@ module.exports = { config.addComponent(Ref.type, RefComponent); config.addComponent(Ref.type+'-target', RefTarget); config.addConverter('jats', RefConverter); + config.addCommand('tag-ref', TagRefCommand); + config.addTool('tag-ref', TagRefTool); + config.addIcon('tag-ref', { 'fontawesome': 'fa-bullseye' }); } }; \ No newline at end of file diff --git a/packages/jats/ref/refToHTML.js b/packages/jats/ref/refToHTML.js index 8deabf686..0aba990fc 100644 --- a/packages/jats/ref/refToHTML.js +++ b/packages/jats/ref/refToHTML.js @@ -2,14 +2,13 @@ var DOMElement = require('substance/ui/DefaultDOMElement'); -var namesToHTML = function (ref) { +var namesToHTML = function(ref) { var nameElements = ref.findAll('name'); var nameEls = []; for (var i = 0; i < nameElements.length; i++) { var name = nameElements[i]; var nameEl = DOMElement.createElement('span'); nameEl.addClass('name'); - nameEl.text(name.find('surname').text() + ' ' + name.find('given-names').text()); if (i > 0 && i < nameElements.length) { var comma = DOMElement.createElement('span'); @@ -18,7 +17,6 @@ var namesToHTML = function (ref) { } nameEls.push(nameEl); } - return nameEls; }; @@ -135,25 +133,22 @@ var refToHTML = function (ref) { // // - ref = DOMElement.parseXML(ref); + ref = ref.getDOM(); // TODO: remove safeguard for multiple citation elements if(Array.isArray(ref)) { ref = ref[0]; } - var el = DOMElement.createElement('div'); - - if (ref.is('mixed-citation') || ref.is('element-citation')) { + if (ref.is('mixed-citation')) { + el.appendChild(ref.textContent); + } else if (ref.is('element-citation')) { el.appendChild(titleToHTML(ref)); var names = namesToHTML(ref); - for (var i = 0; i < names.length; i++) { el.appendChild(names[i]); } - el.appendChild(metaToHTML(ref)); - el.appendChild(URItoHTML(ref)); } else { el.text('Citation type is unsupported'); From e4fae35e67228f93ba2f158a769a858bfea5532a Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 8 Sep 2016 20:03:47 +0200 Subject: [PATCH 055/167] Implemented author tagging. --- packages/jats/article/TextureArticle.js | 9 ++++ .../contrib-group/ContribGroupComponent.js | 22 +++++--- packages/jats/contrib/Contrib.js | 4 +- packages/jats/contrib/ContribConverter.js | 2 +- packages/jats/contrib/TagContribCommand.js | 54 +++++++++++++++++++ packages/jats/contrib/TagContribTool.js | 7 +++ packages/jats/contrib/contribToHTML.js | 13 ++++- packages/jats/contrib/package.js | 5 ++ packages/jats/ref/Ref.js | 2 +- 9 files changed, 104 insertions(+), 14 deletions(-) create mode 100644 packages/jats/contrib/TagContribCommand.js create mode 100644 packages/jats/contrib/TagContribTool.js diff --git a/packages/jats/article/TextureArticle.js b/packages/jats/article/TextureArticle.js index ad48943eb..75e554068 100644 --- a/packages/jats/article/TextureArticle.js +++ b/packages/jats/article/TextureArticle.js @@ -11,6 +11,15 @@ class TextureArticle extends Document { var refListId = Object.keys(refLists)[0]; return refListId ? this.get(refListId) : undefined; } + + /* + Get first ContribGroup + */ + getContribGroup() { + var contribGroups = this.getIndex('type').get('contrib-group'); + var contribGroupId = Object.keys(contribGroups)[0]; + return contribGroupId ? this.get(contribGroupId) : undefined; + } } module.exports = TextureArticle; diff --git a/packages/jats/contrib-group/ContribGroupComponent.js b/packages/jats/contrib-group/ContribGroupComponent.js index b05481934..9e6ad0ae9 100644 --- a/packages/jats/contrib-group/ContribGroupComponent.js +++ b/packages/jats/contrib-group/ContribGroupComponent.js @@ -3,13 +3,20 @@ var Component = require('substance/ui/Component'); var renderNodeComponent = require('../../../util/renderNodeComponent'); -function ContribGroupComponent() { - Component.apply(this, arguments); -} +class ContribGroupComponent extends Component { + didMount() { + super.didMount(); + var node = this.props.node; + node.on('nodes:changed', this.rerender, this); + } -ContribGroupComponent.Prototype = function() { + dispose() { + super.dispose(); + var node = this.props.node; + node.off(this); + } - this.render = function($$) { + render($$) { var node = this.props.node; var doc = node.getDocument(); @@ -31,9 +38,8 @@ ContribGroupComponent.Prototype = function() { // el.append($$('button').addClass('se-add-author').append('Add Author')); return el; - }; -}; + } -Component.extend(ContribGroupComponent); +} module.exports = ContribGroupComponent; \ No newline at end of file diff --git a/packages/jats/contrib/Contrib.js b/packages/jats/contrib/Contrib.js index ddfd1b801..79d09faf2 100644 --- a/packages/jats/contrib/Contrib.js +++ b/packages/jats/contrib/Contrib.js @@ -22,8 +22,8 @@ Contrib.type = 'contrib'; */ Contrib.define({ attributes: { type: 'object', default: {} }, - xmlContent: { type: 'string', default: ''}, - tagName: 'string' + xmlContent: { type: 'string', default: ''}// , + // tagName: 'string' }); module.exports = Contrib; diff --git a/packages/jats/contrib/ContribConverter.js b/packages/jats/contrib/ContribConverter.js index 3c2950e7b..e34416871 100644 --- a/packages/jats/contrib/ContribConverter.js +++ b/packages/jats/contrib/ContribConverter.js @@ -10,7 +10,7 @@ module.exports = { */ import: function(el, node, converter) { // eslint-disable-line node.xmlContent = el.innerHTML; - node.tagName = el.tagName; + // node.tagName = el.tagName; }, export: function(node, el, converter) { // eslint-disable-line diff --git a/packages/jats/contrib/TagContribCommand.js b/packages/jats/contrib/TagContribCommand.js new file mode 100644 index 000000000..5edcb082f --- /dev/null +++ b/packages/jats/contrib/TagContribCommand.js @@ -0,0 +1,54 @@ +'use strict'; + +var Command = require('substance/ui/Command'); +var uuid = require('substance/util/uuid'); +var documentHelpers = require('substance/model/documentHelpers'); +var deleteSelection = require('substance/model/transform/deleteSelection'); + + +class TagContribCommand extends Command { + + getCommandState(params, context) { + var documentSession = context.documentSession; + var doc = documentSession.getDocument(); + + var sel = this._getSelection(params); + var disabled = true; + var stringName; // author name without components + + if (sel.isPropertySelection() && !sel.isCollapsed()) { + disabled = false; + stringName = documentHelpers.getTextForSelection(doc, sel); + } + + return { + disabled: disabled, + stringName: stringName, + active: false + }; + } + + execute(params, context) { + var stringName = params.stringName; + var documentSession = context.documentSession; + + documentSession.transaction(function(tx, args) { + var contribGroupNodeId = tx.document.getContribGroup().id; + var contribGroupNode = tx.get(contribGroupNodeId); + var newContrib = { + id: uuid('contrib'), + type: 'contrib', + xmlContent: ''+stringName+'' + }; + + var contribNode = tx.create(newContrib); + contribGroupNode.show(contribNode.id); + args = deleteSelection(tx, args); + return args; + }); + + return {status: 'ok'}; + } + +} +module.exports = TagContribCommand; diff --git a/packages/jats/contrib/TagContribTool.js b/packages/jats/contrib/TagContribTool.js new file mode 100644 index 000000000..ca85ca090 --- /dev/null +++ b/packages/jats/contrib/TagContribTool.js @@ -0,0 +1,7 @@ +'use strict'; + +var Tool = require('substance/ui/Tool'); + +class TagContribTool extends Tool {} + +module.exports = TagContribTool; diff --git a/packages/jats/contrib/contribToHTML.js b/packages/jats/contrib/contribToHTML.js index 6d696b7f5..5f8d01f4d 100644 --- a/packages/jats/contrib/contribToHTML.js +++ b/packages/jats/contrib/contribToHTML.js @@ -3,13 +3,14 @@ var DOMElement = require('substance/ui/DefaultDOMElement'); var toDOM = require('../../../util/toDOM'); -// TODO: this is dup of refToHTML -> generalize +// TODO: this is partially a dup of refToHTML -> generalize var namesToHTML = function (el) { var nameElements = el.findAll('name'); var nameEls = []; + var nameEl; for (var i = 0; i < nameElements.length; i++) { var name = nameElements[i]; - var nameEl = DOMElement.createElement('span'); + nameEl = DOMElement.createElement('span'); nameEl.addClass('name'); nameEl.text(name.find('surname').text() + ' ' + name.find('given-names').text()); @@ -20,6 +21,14 @@ var namesToHTML = function (el) { } nameEls.push(nameEl); } + + // Consider first string-name element if present + var stringNameElement = el.find('string-name'); + if (stringNameElement) { + nameEl = DOMElement.createElement('span').addClass('name'); + nameEl.text(stringNameElement.textContent); + nameEls.push(nameEl); + } return nameEls; }; diff --git a/packages/jats/contrib/package.js b/packages/jats/contrib/package.js index 34602088c..5570715cb 100644 --- a/packages/jats/contrib/package.js +++ b/packages/jats/contrib/package.js @@ -3,6 +3,8 @@ var Contrib = require('./Contrib'); var ContribComponent = require('./ContribComponent'); var ContribConverter = require('./ContribConverter'); +var TagContribCommand = require('./TagContribCommand'); +var TagContribTool = require('./TagContribTool'); module.exports = { name: 'contrib', @@ -10,5 +12,8 @@ module.exports = { config.addNode(Contrib); config.addComponent(Contrib.type, ContribComponent); config.addConverter('jats', ContribConverter); + config.addCommand('tag-contrib', TagContribCommand); + config.addTool('tag-contrib', TagContribTool); + config.addIcon('tag-contrib', { 'fontawesome': 'fa-bullseye' }); } }; \ No newline at end of file diff --git a/packages/jats/ref/Ref.js b/packages/jats/ref/Ref.js index a4c8d7293..eea87d84d 100644 --- a/packages/jats/ref/Ref.js +++ b/packages/jats/ref/Ref.js @@ -17,7 +17,7 @@ Ref.Prototype = function() { Checks if ref is a plain text citation, with no formatting / tagging etc. */ this.isPlain = function() { - + // TODO: }; /* From 5b1e3cc1c8752affd47750f93eb12027a7c962c0 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 8 Sep 2016 20:04:40 +0200 Subject: [PATCH 056/167] Streamline example article. --- examples/data/kitchen-sink-author.xml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/examples/data/kitchen-sink-author.xml b/examples/data/kitchen-sink-author.xml index b7af0839c..50a82a84e 100644 --- a/examples/data/kitchen-sink-author.xml +++ b/examples/data/kitchen-sink-author.xml @@ -9,20 +9,14 @@ - - Aufreiter - Michael - + Michael Aufreiter - - Buchtala - Oliver - + Oliver Buchtala - Substance Software GmbH, Linz, Austria + Substance Software GmbH, Linz, Austria From 46883818eadd09c83eeee17c5590eb4455fb408e Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 8 Sep 2016 21:21:45 +0200 Subject: [PATCH 057/167] Introduce basic support for affiliations. --- packages/jats/_index.css | 1 + packages/jats/aff/Aff.js | 43 ++++++++++++++++++++ packages/jats/aff/AffComponent.js | 18 +++++++++ packages/jats/aff/AffConverter.js | 15 +++++++ packages/jats/aff/TagAffCommand.js | 54 ++++++++++++++++++++++++++ packages/jats/aff/TagAffTool.js | 7 ++++ packages/jats/aff/_aff.css | 3 ++ packages/jats/aff/_index.css | 1 + packages/jats/aff/package.js | 19 +++++++++ packages/jats/contrib-group/_index.css | 2 +- packages/jats/package.js | 1 + 11 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 packages/jats/aff/Aff.js create mode 100644 packages/jats/aff/AffComponent.js create mode 100644 packages/jats/aff/AffConverter.js create mode 100644 packages/jats/aff/TagAffCommand.js create mode 100644 packages/jats/aff/TagAffTool.js create mode 100644 packages/jats/aff/_aff.css create mode 100644 packages/jats/aff/_index.css create mode 100644 packages/jats/aff/package.js diff --git a/packages/jats/_index.css b/packages/jats/_index.css index 16305218d..9ec99e678 100644 --- a/packages/jats/_index.css +++ b/packages/jats/_index.css @@ -1,3 +1,4 @@ +@import './aff/_index.css'; @import './article/_index.css'; @import './article-title/_index.css'; @import './back/_index.css'; diff --git a/packages/jats/aff/Aff.js b/packages/jats/aff/Aff.js new file mode 100644 index 000000000..95d99ed27 --- /dev/null +++ b/packages/jats/aff/Aff.js @@ -0,0 +1,43 @@ +'use strict'; + +var DocumentNode = require('substance/model/DocumentNode'); +var toDOM = require('../../../util/toDOM'); + +class Aff extends DocumentNode { + toElement() { + return toDOM(this); + } + + /* + Turns the xmlContent string into JSON, ready to be + rendered by a component. + */ + getObject() { + var el = this.toElement(); + return { + name: el.textContent + }; + } +} + +Aff.type = 'aff'; + +/* + Content + ( + #PCDATA | addr-line | city | country | fax | institution | institution-wrap | phone | + postal-code | state | email | ext-link | uri | inline-supplementary-material | + related-article | related-object | hr | bold | fixed-case | italic | monospace | + overline | overline-start | overline-end | roman | sans-serif | sc | strike | + underline | underline-start | underline-end | ruby | alternatives | inline-graphic | + private-char | chem-struct | inline-formula | tex-math | mml:math | abbrev | milestone-end | + milestone-start | named-content | styled-content | fn | target | xref | sub | sup | x | + break | label + )* +*/ +Aff.define({ + attributes: { type: 'object', default: {} }, + xmlContent: { type: 'string', default: ''} +}); + +module.exports = Aff; diff --git a/packages/jats/aff/AffComponent.js b/packages/jats/aff/AffComponent.js new file mode 100644 index 000000000..048b923ec --- /dev/null +++ b/packages/jats/aff/AffComponent.js @@ -0,0 +1,18 @@ +'use strict'; + +var Component = require('substance/ui/Component'); + +class AffComponent extends Component { + constructor(...args) { + super(...args); + } + + render($$) { + var aff = this.props.node.getObject(); + var el = $$('div').addClass('sc-aff') + .append(aff.name); + return el; + } +} + +module.exports = AffComponent; diff --git a/packages/jats/aff/AffConverter.js b/packages/jats/aff/AffConverter.js new file mode 100644 index 000000000..ab27f4f39 --- /dev/null +++ b/packages/jats/aff/AffConverter.js @@ -0,0 +1,15 @@ +'use strict'; + +module.exports = { + + type: 'aff', + tagName: 'aff', + + import: function(el, node, converter) { // eslint-disable-line + node.xmlContent = el.innerHTML; + }, + + export: function(node, el, converter) { // eslint-disable-line + el.innerHTML = node.xmlContent; + } +}; diff --git a/packages/jats/aff/TagAffCommand.js b/packages/jats/aff/TagAffCommand.js new file mode 100644 index 000000000..53123f9ad --- /dev/null +++ b/packages/jats/aff/TagAffCommand.js @@ -0,0 +1,54 @@ +'use strict'; + +var Command = require('substance/ui/Command'); +var uuid = require('substance/util/uuid'); +var documentHelpers = require('substance/model/documentHelpers'); +var deleteSelection = require('substance/model/transform/deleteSelection'); + + +class TagAffCommand extends Command { + + getCommandState(params, context) { + var documentSession = context.documentSession; + var doc = documentSession.getDocument(); + + var sel = this._getSelection(params); + var disabled = true; + var stringName; // author name without components + + if (sel.isPropertySelection() && !sel.isCollapsed()) { + disabled = false; + stringName = documentHelpers.getTextForSelection(doc, sel); + } + + return { + disabled: disabled, + stringName: stringName, + active: false + }; + } + + execute(params, context) { + var stringName = params.stringName; + var documentSession = context.documentSession; + + documentSession.transaction(function(tx, args) { + var contribGroupNodeId = tx.document.getContribGroup().id; + var contribGroupNode = tx.get(contribGroupNodeId); + var newAff = { + id: uuid('aff'), + type: 'aff', + xmlContent: stringName + }; + + var affNode = tx.create(newAff); + contribGroupNode.show(affNode.id); + args = deleteSelection(tx, args); + return args; + }); + + return {status: 'ok'}; + } + +} +module.exports = TagAffCommand; diff --git a/packages/jats/aff/TagAffTool.js b/packages/jats/aff/TagAffTool.js new file mode 100644 index 000000000..2074bc670 --- /dev/null +++ b/packages/jats/aff/TagAffTool.js @@ -0,0 +1,7 @@ +'use strict'; + +var Tool = require('substance/ui/Tool'); + +class TagAffTool extends Tool {} + +module.exports = TagAffTool; diff --git a/packages/jats/aff/_aff.css b/packages/jats/aff/_aff.css new file mode 100644 index 000000000..b11437546 --- /dev/null +++ b/packages/jats/aff/_aff.css @@ -0,0 +1,3 @@ +.sc-aff { + clear: both; +} \ No newline at end of file diff --git a/packages/jats/aff/_index.css b/packages/jats/aff/_index.css new file mode 100644 index 000000000..7c2170c94 --- /dev/null +++ b/packages/jats/aff/_index.css @@ -0,0 +1 @@ +@import './_aff.css'; \ No newline at end of file diff --git a/packages/jats/aff/package.js b/packages/jats/aff/package.js new file mode 100644 index 000000000..2e25c0862 --- /dev/null +++ b/packages/jats/aff/package.js @@ -0,0 +1,19 @@ +'use strict'; + +var Aff = require('./Aff'); +var AffComponent = require('./AffComponent'); +var AffConverter = require('./AffConverter'); +var TagAffCommand = require('./TagAffCommand'); +var TagAffTool = require('./TagAffTool'); + +module.exports = { + name: 'aff', + configure: function(config) { + config.addNode(Aff); + config.addComponent(Aff.type, AffComponent); + config.addConverter('jats', AffConverter); + config.addCommand('tag-aff', TagAffCommand); + config.addTool('tag-aff', TagAffTool); + config.addIcon('tag-aff', { 'fontawesome': 'fa-bullseye' }); + } +}; \ No newline at end of file diff --git a/packages/jats/contrib-group/_index.css b/packages/jats/contrib-group/_index.css index 0705a2dc4..88affd21d 100644 --- a/packages/jats/contrib-group/_index.css +++ b/packages/jats/contrib-group/_index.css @@ -1,3 +1,3 @@ .sc-contrib-group { padding-bottom: var(--default-padding); overflow: auto; } -.sc-contrib-group > * { float: left; margin-right: var(--default-padding); } +.sc-contrib-group > .sc-contrib { float: left; margin-right: var(--default-padding); } .sc-contrib-group .se-add-author { color: var(--link-color); } \ No newline at end of file diff --git a/packages/jats/package.js b/packages/jats/package.js index 7151293fe..fb39f336b 100644 --- a/packages/jats/package.js +++ b/packages/jats/package.js @@ -6,6 +6,7 @@ var JATSExporter = require('./JATSExporter'); module.exports = { name: 'jats', configure: function(config) { + config.import(require('./aff/package')); config.import(require('./article/package')); config.import(require('./article-meta/package')); config.import(require('./title-group/package')); From fd4f299286f0435c72f8dd90baebab70a9a53bc2 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 9 Sep 2016 11:53:29 +0200 Subject: [PATCH 058/167] Streamline rendering for contrib nodes. --- examples/index.html | 2 +- packages/jats/contrib/Contrib.js | 28 +++++++++++-- packages/jats/contrib/ContribComponent.js | 6 ++- packages/jats/contrib/contribToHTML.js | 51 ----------------------- packages/jats/ref/refToHTML.js | 4 ++ util/extractFullName.js | 20 +++++++++ 6 files changed, 54 insertions(+), 57 deletions(-) delete mode 100644 packages/jats/contrib/contribToHTML.js create mode 100644 util/extractFullName.js diff --git a/examples/index.html b/examples/index.html index 8794d7478..112fb518d 100644 --- a/examples/index.html +++ b/examples/index.html @@ -1,4 +1,4 @@ -

    Scientist Examples

    +

    Texture Examples

    • Author - word-like editing interface
    • diff --git a/packages/jats/contrib/Contrib.js b/packages/jats/contrib/Contrib.js index 79d09faf2..b881e44ed 100644 --- a/packages/jats/contrib/Contrib.js +++ b/packages/jats/contrib/Contrib.js @@ -1,12 +1,34 @@ 'use strict'; var DocumentNode = require('substance/model/DocumentNode'); +var toDOM = require('../../../util/toDOM'); +var extractFullName = require('../../../util/extractFullName'); -function Contrib() { - Contrib.super.apply(this, arguments); +function extractAffiliations(el) { + var xrefs = el.findAll('xref[ref-type=aff]'); + var affIds = xrefs.map(xref => xref.getAttribute('rid')); + return affIds; } -DocumentNode.extend(Contrib); +class Contrib extends DocumentNode { + + toElement() { + return toDOM(this); + } + + /* + Turns the xmlContent string into JSON, ready to be + rendered by a component. + */ + getObject() { + var el = this.toElement(); + + return { + fullName: extractFullName(el), + affiliations: extractAffiliations(el) + }; + } +} Contrib.type = 'contrib'; diff --git a/packages/jats/contrib/ContribComponent.js b/packages/jats/contrib/ContribComponent.js index add855916..bf2c6e9fc 100644 --- a/packages/jats/contrib/ContribComponent.js +++ b/packages/jats/contrib/ContribComponent.js @@ -3,7 +3,6 @@ var Component = require('substance/ui/Component'); var Modal = require('substance/ui/Modal'); var EditXML = require('../../common/EditXML'); -var contribToHTML = require('./contribToHTML'); function ContribComponent() { ContribComponent.super.apply(this, arguments); @@ -20,9 +19,12 @@ ContribComponent.Prototype = function() { this.render = function($$) { var node = this.props.node; + var contrib = node.getObject(); + console.log('contrib', contrib); var el = $$('div').addClass('sc-contrib') .append( - $$('div').addClass('se-name').html(contribToHTML(node)) + $$('div').addClass('se-name') + .append(contrib.fullName) .on('click', this._toggleEditor) ); diff --git a/packages/jats/contrib/contribToHTML.js b/packages/jats/contrib/contribToHTML.js deleted file mode 100644 index 5f8d01f4d..000000000 --- a/packages/jats/contrib/contribToHTML.js +++ /dev/null @@ -1,51 +0,0 @@ -'use strict'; - -var DOMElement = require('substance/ui/DefaultDOMElement'); -var toDOM = require('../../../util/toDOM'); - -// TODO: this is partially a dup of refToHTML -> generalize -var namesToHTML = function (el) { - var nameElements = el.findAll('name'); - var nameEls = []; - var nameEl; - for (var i = 0; i < nameElements.length; i++) { - var name = nameElements[i]; - nameEl = DOMElement.createElement('span'); - nameEl.addClass('name'); - - nameEl.text(name.find('surname').text() + ' ' + name.find('given-names').text()); - if (i > 0 && i < nameElements.length) { - var comma = DOMElement.createElement('span'); - comma.text(', '); - nameEls.push(comma); - } - nameEls.push(nameEl); - } - - // Consider first string-name element if present - var stringNameElement = el.find('string-name'); - if (stringNameElement) { - nameEl = DOMElement.createElement('span').addClass('name'); - nameEl.text(stringNameElement.textContent); - nameEls.push(nameEl); - } - return nameEls; -}; - -var contribToHTML = function (contrib) { - // - // - // Schuman - // Meredith C - // - // - // - var contribEl = toDOM(contrib); - - var el = DOMElement.createElement('div'); - el.append(namesToHTML(contribEl)); - - return el.outerHTML; -}; - -module.exports = contribToHTML; \ No newline at end of file diff --git a/packages/jats/ref/refToHTML.js b/packages/jats/ref/refToHTML.js index 0aba990fc..3862576bc 100644 --- a/packages/jats/ref/refToHTML.js +++ b/packages/jats/ref/refToHTML.js @@ -2,6 +2,10 @@ var DOMElement = require('substance/ui/DefaultDOMElement'); +/* + TODO: Get rid of HTML renderer. Instead extract data as + JSON and then pass it to a component for rendering +*/ var namesToHTML = function(ref) { var nameElements = ref.findAll('name'); var nameEls = []; diff --git a/util/extractFullName.js b/util/extractFullName.js new file mode 100644 index 000000000..91d967248 --- /dev/null +++ b/util/extractFullName.js @@ -0,0 +1,20 @@ +'use strict'; + +/* + Extract name from elements that contain + name or string-name nodes (e.g. contrib, mixed-citation, element-citation) +*/ +function extractFullName(el) { + var name = el.find('name'); + var stringName = el.find('string-name'); + + if (name) { + var surname = name.find('surname').text(); + var givenNames = name.find('given-names').text(); + return [givenNames, surname]; + } else if (stringName) { + return stringName.text(); + } +} + +module.exports = extractFullName; \ No newline at end of file From 63f420ae69b6d6a90cd441a729558a937ee49451 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 9 Sep 2016 12:55:13 +0200 Subject: [PATCH 059/167] Prepare for visual author editing. --- examples/data/kitchen-sink-author.xml | 8 +++---- packages/common/EditXML.js | 2 +- packages/jats/aff/TagAffCommand.js | 5 ++++- packages/jats/contrib/Contrib.js | 18 ++++++++++------ packages/jats/contrib/ContribComponent.js | 12 ++++++++++- packages/jats/contrib/EditContrib.js | 25 ++++++++++++++++++++++ packages/jats/contrib/TagContribCommand.js | 5 ++++- packages/jats/ref/TagRefCommand.js | 5 ++++- 8 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 packages/jats/contrib/EditContrib.js diff --git a/examples/data/kitchen-sink-author.xml b/examples/data/kitchen-sink-author.xml index 50a82a84e..1b0cd2116 100644 --- a/examples/data/kitchen-sink-author.xml +++ b/examples/data/kitchen-sink-author.xml @@ -12,11 +12,11 @@ Michael Aufreiter - + Oliver Buchtala - Substance Software GmbH, Linz, Austria + Substance Software GmbH, Linz, Austria @@ -41,10 +41,10 @@ References - + Bailey KA, Pereira SL, Widom J, Reeve JN. 2000. Archaeal histone selection of nucleosome positioning sequences and the procaryotic origin of histone-dependent genome evolution. J Mol Biol 303:25–34. - + Altschul SF, Gish W, Miller W, Myers EW, Lipman DJ. 1990. Basic local alignment search tool. J Mol Biol 215:403–10. diff --git a/packages/common/EditXML.js b/packages/common/EditXML.js index b31dfd792..6699762c1 100644 --- a/packages/common/EditXML.js +++ b/packages/common/EditXML.js @@ -13,7 +13,7 @@ EditXML.Prototype = function() { this.render = function($$) { var node = this.props.node; var el = $$('div').addClass('sc-edit-xml'); - var tagName = node.tagName; + var tagName = node.tagName || node.constructor.type; el.append( $$('div').addClass('se-tag sm-open-tag-start').append('<'+tagName) diff --git a/packages/jats/aff/TagAffCommand.js b/packages/jats/aff/TagAffCommand.js index 53123f9ad..2f01e92c3 100644 --- a/packages/jats/aff/TagAffCommand.js +++ b/packages/jats/aff/TagAffCommand.js @@ -38,7 +38,10 @@ class TagAffCommand extends Command { var newAff = { id: uuid('aff'), type: 'aff', - xmlContent: stringName + xmlContent: stringName, + attributes: { + generator: 'texture' + } }; var affNode = tx.create(newAff); diff --git a/packages/jats/contrib/Contrib.js b/packages/jats/contrib/Contrib.js index b881e44ed..e058e88c3 100644 --- a/packages/jats/contrib/Contrib.js +++ b/packages/jats/contrib/Contrib.js @@ -12,10 +12,6 @@ function extractAffiliations(el) { class Contrib extends DocumentNode { - toElement() { - return toDOM(this); - } - /* Turns the xmlContent string into JSON, ready to be rendered by a component. @@ -28,6 +24,17 @@ class Contrib extends DocumentNode { affiliations: extractAffiliations(el) }; } + + /* + Returns true if node follows strict texture-enforced markup + */ + isStrict() { + return this.attributes.generator === 'texture'; + } + + toElement() { + return toDOM(this); + } } Contrib.type = 'contrib'; @@ -44,8 +51,7 @@ Contrib.type = 'contrib'; */ Contrib.define({ attributes: { type: 'object', default: {} }, - xmlContent: { type: 'string', default: ''}// , - // tagName: 'string' + xmlContent: { type: 'string', default: ''} }); module.exports = Contrib; diff --git a/packages/jats/contrib/ContribComponent.js b/packages/jats/contrib/ContribComponent.js index bf2c6e9fc..678365f72 100644 --- a/packages/jats/contrib/ContribComponent.js +++ b/packages/jats/contrib/ContribComponent.js @@ -3,6 +3,7 @@ var Component = require('substance/ui/Component'); var Modal = require('substance/ui/Modal'); var EditXML = require('../../common/EditXML'); +var EditContrib = require('./EditContrib'); function ContribComponent() { ContribComponent.super.apply(this, arguments); @@ -29,11 +30,20 @@ ContribComponent.Prototype = function() { ); if (this.state.editXML) { + // Conforms to strict markup enforced by texture + // for visual editing + var EditorClass; + if (node.isStrict()) { + EditorClass = EditContrib; + } else { + EditorClass = EditXML; + } + el.append( $$(Modal, { width: 'medium' }).append( - $$(EditXML, { + $$(EditorClass, { node: node }) ) diff --git a/packages/jats/contrib/EditContrib.js b/packages/jats/contrib/EditContrib.js new file mode 100644 index 000000000..eed6e407b --- /dev/null +++ b/packages/jats/contrib/EditContrib.js @@ -0,0 +1,25 @@ +'use strict'; + +var Component = require('substance/ui/Component'); + +class EditContrib extends Component { + + getXML() { + return this.refs.xml.val(); + } + + render($$) { + var el = $$('div').addClass('sc-edit-contrib'); + + el.append( + 'TODO: Implement form editor for contrib nodes' + // $$('textarea') + // .ref('xml') + // .append(this.props.xml) + ); + return el; + } + +} + +module.exports = EditContrib; diff --git a/packages/jats/contrib/TagContribCommand.js b/packages/jats/contrib/TagContribCommand.js index 5edcb082f..63b3299b4 100644 --- a/packages/jats/contrib/TagContribCommand.js +++ b/packages/jats/contrib/TagContribCommand.js @@ -38,7 +38,10 @@ class TagContribCommand extends Command { var newContrib = { id: uuid('contrib'), type: 'contrib', - xmlContent: ''+stringName+'' + xmlContent: ''+stringName+'', + attributes: { + generator: 'texture' + } }; var contribNode = tx.create(newContrib); diff --git a/packages/jats/ref/TagRefCommand.js b/packages/jats/ref/TagRefCommand.js index 5f6a7bde6..bd97d16fb 100644 --- a/packages/jats/ref/TagRefCommand.js +++ b/packages/jats/ref/TagRefCommand.js @@ -52,7 +52,10 @@ class TagRefCommand extends Command { var newRef = { id: uuid('ref'), type: 'ref', - xmlContent: ''+p.content+'' + xmlContent: ''+p.content+'', + attributes: { + generator: 'texture' + } }; var refNode = tx.create(newRef); refListNode.show(refNode.id); From 97014ef50a781cebcc78dea06302d1da52eba892 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 9 Sep 2016 20:49:02 +0200 Subject: [PATCH 060/167] Implement visual contrib editor. Complete with selecting affiliations. --- examples/data/kitchen-sink-author.xml | 8 ++- packages/jats/aff/Aff.js | 14 ---- packages/jats/aff/AffComponent.js | 8 ++- packages/jats/aff/_aff.css | 2 + packages/jats/aff/affUtils.js | 30 ++++++++ packages/jats/contrib/Contrib.js | 31 -------- packages/jats/contrib/ContribComponent.js | 11 ++- packages/jats/contrib/ContribConverter.js | 1 - packages/jats/contrib/EditContrib.js | 79 +++++++++++++++++++-- packages/jats/contrib/_contrib.css | 5 ++ packages/jats/contrib/_edit-contrib.css | 5 ++ packages/jats/contrib/_index.css | 7 +- packages/jats/contrib/contribUtils.js | 62 ++++++++++++++++ util/{extractFullName.js => getFullName.js} | 7 +- 14 files changed, 201 insertions(+), 69 deletions(-) create mode 100644 packages/jats/aff/affUtils.js create mode 100644 packages/jats/contrib/_contrib.css create mode 100644 packages/jats/contrib/_edit-contrib.css create mode 100644 packages/jats/contrib/contribUtils.js rename util/{extractFullName.js => getFullName.js} (78%) diff --git a/examples/data/kitchen-sink-author.xml b/examples/data/kitchen-sink-author.xml index 1b0cd2116..7742bea5a 100644 --- a/examples/data/kitchen-sink-author.xml +++ b/examples/data/kitchen-sink-author.xml @@ -8,7 +8,7 @@ Turn Word documents into structured JATS with Texture - + Michael Aufreiter @@ -17,6 +17,8 @@ Substance Software GmbH, Linz, Austria + Consortium Erudit, Montreal, Canada + Collaborative Knowledge Foundation, San Francisco, US @@ -27,8 +29,8 @@ Introduction -

      Texture is a tool for publishers for creating structured JATS documents based on Word or InDesign submissions. Texture is developed by the Substance Consortium ([1]) formed by the Public Knowledge Project (PKP), the Collaborative Knowledge Foundation (CoKo) and Érudit.

      -

      The tool is available as open source on Github ([2]) and

      +

      Texture is a tool for publishers for creating structured JATS documents based on Word or InDesign submissions.

      +

      The original document is imported with annotations preserved. Then the user starts tagging semantic entities in the document, such as marking up the reference list, the authors, affiliations etc. Saving the document produces valid JATS 1.1 XML.

      Create a bibliography diff --git a/packages/jats/aff/Aff.js b/packages/jats/aff/Aff.js index 95d99ed27..e03a429cb 100644 --- a/packages/jats/aff/Aff.js +++ b/packages/jats/aff/Aff.js @@ -4,20 +4,6 @@ var DocumentNode = require('substance/model/DocumentNode'); var toDOM = require('../../../util/toDOM'); class Aff extends DocumentNode { - toElement() { - return toDOM(this); - } - - /* - Turns the xmlContent string into JSON, ready to be - rendered by a component. - */ - getObject() { - var el = this.toElement(); - return { - name: el.textContent - }; - } } Aff.type = 'aff'; diff --git a/packages/jats/aff/AffComponent.js b/packages/jats/aff/AffComponent.js index 048b923ec..cd804342a 100644 --- a/packages/jats/aff/AffComponent.js +++ b/packages/jats/aff/AffComponent.js @@ -1,6 +1,9 @@ 'use strict'; var Component = require('substance/ui/Component'); +var Icon = require('substance/ui/FontAwesomeIcon'); + +var getAdapter = require('./affUtils').getAdapter; class AffComponent extends Component { constructor(...args) { @@ -8,9 +11,10 @@ class AffComponent extends Component { } render($$) { - var aff = this.props.node.getObject(); + var aff = getAdapter(this.props.node); var el = $$('div').addClass('sc-aff') - .append(aff.name); + .append($$(Icon, {icon: 'fa-building-o'})) + .append(' '+aff.name); return el; } } diff --git a/packages/jats/aff/_aff.css b/packages/jats/aff/_aff.css index b11437546..1f30a2353 100644 --- a/packages/jats/aff/_aff.css +++ b/packages/jats/aff/_aff.css @@ -1,3 +1,5 @@ .sc-aff { clear: both; + padding-top: 20px; + font-size: var(--small-font-size); } \ No newline at end of file diff --git a/packages/jats/aff/affUtils.js b/packages/jats/aff/affUtils.js new file mode 100644 index 000000000..53295d855 --- /dev/null +++ b/packages/jats/aff/affUtils.js @@ -0,0 +1,30 @@ +'use strict'; + +var toDOM = require('../../../util/toDOM'); + +/* + Get all affiliations for a doc +*/ +function getAffs(doc) { + var affs = doc.getIndex('type').get('aff'); + // Convert to array and get the view for the node + affs = Object.keys(affs).map(affId => getAdapter(affs[affId])); + return affs; +} + +/* + Turns the xmlContent string into JSON, ready to be + rendered by the component. +*/ +function getAdapter(node) { + var el = toDOM(node); + return { + node: node, + name: el.textContent + }; +} + +module.exports = { + getAffs: getAffs, + getAdapter: getAdapter +}; \ No newline at end of file diff --git a/packages/jats/contrib/Contrib.js b/packages/jats/contrib/Contrib.js index e058e88c3..66b9c987d 100644 --- a/packages/jats/contrib/Contrib.js +++ b/packages/jats/contrib/Contrib.js @@ -1,40 +1,9 @@ 'use strict'; var DocumentNode = require('substance/model/DocumentNode'); -var toDOM = require('../../../util/toDOM'); -var extractFullName = require('../../../util/extractFullName'); - -function extractAffiliations(el) { - var xrefs = el.findAll('xref[ref-type=aff]'); - var affIds = xrefs.map(xref => xref.getAttribute('rid')); - return affIds; -} class Contrib extends DocumentNode { - /* - Turns the xmlContent string into JSON, ready to be - rendered by a component. - */ - getObject() { - var el = this.toElement(); - - return { - fullName: extractFullName(el), - affiliations: extractAffiliations(el) - }; - } - - /* - Returns true if node follows strict texture-enforced markup - */ - isStrict() { - return this.attributes.generator === 'texture'; - } - - toElement() { - return toDOM(this); - } } Contrib.type = 'contrib'; diff --git a/packages/jats/contrib/ContribComponent.js b/packages/jats/contrib/ContribComponent.js index 678365f72..1a4fbdfbe 100644 --- a/packages/jats/contrib/ContribComponent.js +++ b/packages/jats/contrib/ContribComponent.js @@ -4,6 +4,7 @@ var Component = require('substance/ui/Component'); var Modal = require('substance/ui/Modal'); var EditXML = require('../../common/EditXML'); var EditContrib = require('./EditContrib'); +var getAdapter = require('./contribUtils').getAdapter; function ContribComponent() { ContribComponent.super.apply(this, arguments); @@ -19,9 +20,7 @@ function ContribComponent() { ContribComponent.Prototype = function() { this.render = function($$) { - var node = this.props.node; - var contrib = node.getObject(); - console.log('contrib', contrib); + var contrib = getAdapter(this.props.node); var el = $$('div').addClass('sc-contrib') .append( $$('div').addClass('se-name') @@ -33,7 +32,7 @@ ContribComponent.Prototype = function() { // Conforms to strict markup enforced by texture // for visual editing var EditorClass; - if (node.isStrict()) { + if (contrib.strict) { EditorClass = EditContrib; } else { EditorClass = EditXML; @@ -43,9 +42,7 @@ ContribComponent.Prototype = function() { $$(Modal, { width: 'medium' }).append( - $$(EditorClass, { - node: node - }) + $$(EditorClass, contrib) ) ); } diff --git a/packages/jats/contrib/ContribConverter.js b/packages/jats/contrib/ContribConverter.js index e34416871..c536b58fd 100644 --- a/packages/jats/contrib/ContribConverter.js +++ b/packages/jats/contrib/ContribConverter.js @@ -10,7 +10,6 @@ module.exports = { */ import: function(el, node, converter) { // eslint-disable-line node.xmlContent = el.innerHTML; - // node.tagName = el.tagName; }, export: function(node, el, converter) { // eslint-disable-line diff --git a/packages/jats/contrib/EditContrib.js b/packages/jats/contrib/EditContrib.js index eed6e407b..dfc0399d0 100644 --- a/packages/jats/contrib/EditContrib.js +++ b/packages/jats/contrib/EditContrib.js @@ -1,6 +1,9 @@ 'use strict'; var Component = require('substance/ui/Component'); +var Input = require('substance/ui/Input'); +var Button = require('substance/ui/Button'); +var saveContrib = require('./contribUtils').saveContrib; class EditContrib extends Component { @@ -10,16 +13,84 @@ class EditContrib extends Component { render($$) { var el = $$('div').addClass('sc-edit-contrib'); + var affs = this.props.affs; + var fullName = this.props.fullName; + var selectedAffs = this.props.selectedAffs; + + var affSel = $$('select').attr({multiple: 'multiple'}).ref('affSel'); + + affs.forEach(function(a) { + var opt = $$('option') + .attr({value: a.node.id}) + .append(a.name); + + if (selectedAffs[a.node.id]) { + opt.attr('selected', 'selected'); + } + affSel.append(opt); + }); el.append( - 'TODO: Implement form editor for contrib nodes' - // $$('textarea') - // .ref('xml') - // .append(this.props.xml) + $$('div').addClass('se-label').append('Name:'), + $$('div').addClass('se-fullname').append( + $$(Input, { + type: 'text', + value: fullName, + placeholder: 'Enter full name of author' + }).ref('fullName') + ), + $$('div').addClass('se-label').append('Affiliations:'), + affSel + ); + + el.append( + $$('div').addClass('se-actions').append( + $$(Button).append('Save').on('click', this._save), + $$(Button).addClass('se-cancel').append('Cancel').on('click', this._cancel) + ) ); return el; } + _save() { + var contribData = { + id: this.props.node.id, + selectedAffs: getSelectedOptions(this.refs.affSel.el.el), + fullName: this.refs.fullName.val() + }; + + var documentSession = this.context.documentSession; + saveContrib(documentSession, contribData); + this.send('closeModal'); + } + + _cancel() { + this.send('closeModal'); + } +} + + +// arguments: reference to select list, callback function (optional) +function getSelectedOptions(sel, fn) { + var opts = [], opt; + + // loop through options in select list + for (var i=0, len=sel.options.length; i Date: Thu, 8 Sep 2016 20:03:06 +0200 Subject: [PATCH 061/167] Introducing substance-bundler --- .eslintrc.js | 4 +-- .gitignore | 10 ------ .jshint | 18 ---------- .jshintrc | 17 ---------- gulpfile.js | 92 ---------------------------------------------------- package.json | 24 +++----------- 6 files changed, 7 insertions(+), 158 deletions(-) delete mode 100644 .jshint delete mode 100644 .jshintrc delete mode 100644 gulpfile.js diff --git a/.eslintrc.js b/.eslintrc.js index a482fe8e1..7bb3185a7 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -10,12 +10,12 @@ module.exports = { }, "extends": "eslint:recommended", "globals": { - "QUnit": true + "Promise": true }, "rules": { // 0 - off, 1 - warning, 2 - error "indent": ["error", 2, { "SwitchCase": 1 }], - "semi": [2, "always"], + "semi": [0, "never"], "comma-dangle": [2, "only-multiline"], "no-cond-assign": 2, "no-console": [2, { allow: ["warn", "info", "error", "assert"] }], diff --git a/.gitignore b/.gitignore index b8a63c9f0..2dbfcc9e4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,5 @@ -# Logs logs *.log - -# Bundles dist - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependencies node_modules - -# Users Environment Variables .lock-wscript diff --git a/.jshint b/.jshint deleted file mode 100644 index b9bac8f43..000000000 --- a/.jshint +++ /dev/null @@ -1,18 +0,0 @@ -{ - "esnext": true, - "node": true, - "devel": true, - "latedef": true, - "undef": true, - "unused": true, - "sub": true, - "predef": [ - "localStorage", - "React", - "WebSocket", - "window", - "document", - "i18n", - "QUnit" - ] -} \ No newline at end of file diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 4411711d7..000000000 --- a/.jshintrc +++ /dev/null @@ -1,17 +0,0 @@ -{ - "esnext": true, - "node": true, - "jquery": false, - "devel": true, - "latedef": "nofunc", - "undef": true, - "unused": true, - "sub": true, - "predef": [ - "localStorage", - "React", - "window", - "document", - "i18n" - ] -} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index cdf21900b..000000000 --- a/gulpfile.js +++ /dev/null @@ -1,92 +0,0 @@ -'use strict'; -/* eslint-disable no-console, no-invalid-this */ - -var gulp = require('gulp'); -var browserify = require('browserify'); -var uglify = require('gulp-uglify'); -var through2 = require('through2'); -var eslint = require('gulp-eslint'); -var tape = require('gulp-tape'); -var tapSpec = require('tap-spec'); -var bundleStyles = require('substance/util/bundleStyles'); -var examples = require('./examples/config').examples; -var fs = require('fs'); -var path = require('path'); -var gulpFile = require('gulp-file'); - -gulp.task('assets', function () { - examples.forEach(function(exampleFolder) { - gulp.src('./examples/'+exampleFolder+'/index.html') - .pipe(gulp.dest('dist/'+exampleFolder)); - }); - gulp.src('examples/data/*') - .pipe(gulp.dest('./dist/data')); - gulp.src('node_modules/font-awesome/fonts/*') - .pipe(gulp.dest('./dist/fonts')); -}); - -gulp.task('sass', function(done) { - Promise.all(examples.map(function(exampleFolder) { - return bundleStyles({ - rootDir: __dirname, - configuratorPath: require.resolve('./packages/common/BaseConfigurator'), - configPath: require.resolve('./examples/'+exampleFolder+'/package'), - sass: { - sourceMap: false, - outputStyle: 'compressed' - } - }).then(function(css) { - var distPath = path.join(__dirname, 'dist', exampleFolder); - gulpFile('app.css', css, { src: true }) - .pipe(gulp.dest(distPath)); - }).catch(function(err) { - console.error(err); - }); - })).then(function() { - done(); - }); -}); - -gulp.task('browserify', function() { - examples.forEach(function(exampleFolder) { - gulp.src('./examples/'+exampleFolder+'/app.js') - .pipe(through2.obj(function (file, enc, next) { - browserify(file.path) - .bundle(function (err, res) { - if (err) { return next(err); } - file.contents = res; - next(null, file); - }); - })) - .on('error', function (error) { - console.log(error.stack); - this.emit('end'); - }) - .pipe(uglify().on('error', function(err){console.log(err); })) - .pipe(gulp.dest('./dist/'+exampleFolder)); - }); -}); - - -gulp.task('lint', function() { - return gulp.src([ - './examples/**/*.js', - './packages/**/*.js', - './test/**/*.js', - ]).pipe(eslint()) - .pipe(eslint.format()) - .pipe(eslint.failAfterError()); -}); - -gulp.task('test:server', ['lint'], function() { - return gulp.src([ - 'test/jats/*.test.js' - ]) - .pipe(tape({ - reporter: tapSpec() - })); -}); - -gulp.task('test', ['test:server']); - -gulp.task('default', ['assets', 'sass', 'browserify']); diff --git a/package.json b/package.json index 2e6d3b1a4..fe8fcef24 100644 --- a/package.json +++ b/package.json @@ -2,34 +2,20 @@ "name": "substance-scientist", "description": "A scientific editor and reader for JATS files.", "dependencies": { - "lodash": "^4.2.1", + "lodash": "^4.14.1", "substance": "substance/substance#develop" }, "devDependencies": { - "browserify": "substance/node-browserify#d3caeb6dcdaa97a258d099c7231a57f0f60ec876", + "eslint": "^3.2.2", "express": "4.13.4", "font-awesome": "4.5.0", - "glob": "7.0.3", - "gulp": "3.9.1", - "gulp-eslint": "2.0.0", - "gulp-file": "^0.3.0", - "gulp-if": "2.0.1", - "gulp-rename": "1.2.2", - "gulp-sass": "2.3.1", - "gulp-sourcemaps": "1.6.0", - "gulp-tape": "0.0.9", - "gulp-uglify": "1.5.3", - "gulp-util": "3.0.7", - "node-sass": "3.8.0", + "substance-bundler": "*", "tap-spec": "4.1.1", "tape": "4.5.1", - "through2": "2.0.1", - "vinyl-buffer": "1.0.0", - "vinyl-source-stream": "1.1.0", - "yargs": "4.7.1" + "yargs": "^4.8.1" }, "scripts": { - "bundle": "gulp", + "bundle": "node make", "test": "gulp test" }, "version": "1.0.0-alpha.2" From 9e7ec137b2c8805f4924256fa7d1a4a49bb50d0b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 8 Sep 2016 20:03:23 +0200 Subject: [PATCH 062/167] Removed obsolete files --- examples/__mini-journal/MiniJournal.js | 41 ------------------- examples/__mini-journal/MiniJournalBackend.js | 1 - examples/__mini-journal/MiniJournalConfig.js | 1 - examples/__mini-journal/MiniJournalRouter.js | 16 -------- examples/__mini-journal/README.md | 1 - examples/server-rendering.js | 39 ------------------ 6 files changed, 99 deletions(-) delete mode 100644 examples/__mini-journal/MiniJournal.js delete mode 100644 examples/__mini-journal/MiniJournalBackend.js delete mode 100644 examples/__mini-journal/MiniJournalConfig.js delete mode 100644 examples/__mini-journal/MiniJournalRouter.js delete mode 100644 examples/__mini-journal/README.md delete mode 100644 examples/server-rendering.js diff --git a/examples/__mini-journal/MiniJournal.js b/examples/__mini-journal/MiniJournal.js deleted file mode 100644 index fa4f3df1d..000000000 --- a/examples/__mini-journal/MiniJournal.js +++ /dev/null @@ -1,41 +0,0 @@ -'use strict'; - -var extend = require('lodash/extend'); -var DocumentPage = require('./DocumentPage'); -var DashboardPage = require('./DashboardPage'); -var ResponsiveApplication = require('./ResponsiveApplication'); -var ScientistRouter = require('./ScientistRouter'); - -var I18n = require('substance/ui/i18n'); -I18n.instance.load(require('../i18n/en')); - -function MiniJournal() { - ResponsiveApplication.apply(this, arguments); - - this.addPage('document', DocumentPage); - this.addPage('dashboard', DashboardPage); -} - -MiniJournal.Prototype = function() { - - var _super = MiniJournal.super.prototype; - - this.getDefaultPage = function() { - return 'dashboard'; - }; - - this.getRouter = function() { - return new ScientistRouter(this); - }; - - this.getChildContext = function() { - var context = _super.getChildContext.call(this); - return extend({}, context, { - i18n: I18n.instance - }); - }; - -}; - -ResponsiveApplication.extend(MiniJournal); -module.exports = MiniJournal; \ No newline at end of file diff --git a/examples/__mini-journal/MiniJournalBackend.js b/examples/__mini-journal/MiniJournalBackend.js deleted file mode 100644 index 9ec515c2b..000000000 --- a/examples/__mini-journal/MiniJournalBackend.js +++ /dev/null @@ -1 +0,0 @@ -// TODO: implement backend \ No newline at end of file diff --git a/examples/__mini-journal/MiniJournalConfig.js b/examples/__mini-journal/MiniJournalConfig.js deleted file mode 100644 index 0ffdd02fc..000000000 --- a/examples/__mini-journal/MiniJournalConfig.js +++ /dev/null @@ -1 +0,0 @@ -// TODO \ No newline at end of file diff --git a/examples/__mini-journal/MiniJournalRouter.js b/examples/__mini-journal/MiniJournalRouter.js deleted file mode 100644 index fa7ff1262..000000000 --- a/examples/__mini-journal/MiniJournalRouter.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -var Router = require('substance/ui/Router'); - -function ScientistRouter(app) { - Router.apply(this, arguments); - this.app = app; -} - -ScientistRouter.Prototype = function() { - -}; - -Router.extend(ScientistRouter); - -module.exports = ScientistRouter; \ No newline at end of file diff --git a/examples/__mini-journal/README.md b/examples/__mini-journal/README.md deleted file mode 100644 index 6b0edd93e..000000000 --- a/examples/__mini-journal/README.md +++ /dev/null @@ -1 +0,0 @@ -This is not functional yet. We just wanted to preserve an earlier working implementation using substance/ui/ResponsiveApplication. \ No newline at end of file diff --git a/examples/server-rendering.js b/examples/server-rendering.js deleted file mode 100644 index 667b961bf..000000000 --- a/examples/server-rendering.js +++ /dev/null @@ -1,39 +0,0 @@ -'use strict'; - -var fs = require('fs'); -var forEach = require('lodash/forEach'); -var jQuery = require('substance/util/jquery'); -var Component = require('substance/ui/Component'); -var Registry = require('substance/util/Registry'); - -var JATSImporter = require('../converter/JATSImporter'); -var ArticleComponent = require('../ui/nodes/ArticleComponent'); -var components = require('../ui/nodes'); - -var xml = fs.readFileSync(__dirname + '/../data/elife-00007.xml'); -var importer = new JATSImporter(); -var doc = importer.importDocument(xml); - -var componentRegistry = new Registry(); -forEach(components, function(ComponentClass, type) { - componentRegistry.add(type, ComponentClass); -}); - -// TODO: we should put this into dedicated class -var Reader = Component.extend({ - getChildContext: function() { - return { - doc: doc, - componentRegistry: componentRegistry - }; - }, - render: function($$) { - var articleNode = doc.get('article'); - return $$('div').append($$(ArticleComponent, { node: articleNode })); - }, -}); - -var $el = jQuery('
      '); -Reader.mount($el[0]); - -fs.writeFileSync('./prerendered.html', $el.html()); From de6da71ab6739dde7b88483d8c2abf8b7081044f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 8 Sep 2016 20:04:45 +0200 Subject: [PATCH 063/167] Switching to es6 modules --- examples/ExampleXMLStore.js | 21 ++-- examples/author/app.js | 29 +++--- examples/author/package.js | 8 +- examples/config.js | 1 + examples/publisher/app.js | 12 +-- examples/publisher/package.js | 12 +-- packages/author/Author.js | 98 ++++++++----------- packages/author/AuthorExporter.js | 8 +- packages/author/AuthorImporter.js | 8 +- packages/author/AuthorTOCProvider.js | 6 +- packages/author/JATSTransformer.js | 10 +- packages/author/heading/Heading.js | 6 +- packages/author/heading/HeadingComponent.js | 12 +++ packages/author/heading/package.js | 14 ++- packages/author/package.js | 35 ++++--- packages/common/AbstractWriter.js | 9 +- packages/common/EditXML.js | 11 +-- packages/common/SaveHandler.js | 20 ++-- packages/common/XMLAttributeEditor.js | 8 +- packages/common/XMLEditor.js | 6 +- packages/common/package.js | 6 +- .../InlineWrapperJATSConverter.js | 2 +- .../inline-wrapper/InlineWrapperPackage.js | 13 +-- packages/jats/JATS.js | 2 +- packages/jats/JATSExporter.js | 6 +- packages/jats/JATSImporter.js | 13 +-- packages/jats/TextNodeConverter.js | 4 +- packages/jats/article-meta/ArticleMeta.js | 6 +- .../jats/article-meta/ArticleMetaComponent.js | 7 +- .../jats/article-meta/ArticleMetaConverter.js | 6 +- packages/jats/article-meta/package.js | 8 +- packages/jats/article-title/ArticleTitle.js | 4 +- .../article-title/ArticleTitleComponent.js | 4 +- .../article-title/ArticleTitleConverter.js | 4 +- packages/jats/article-title/package.js | 10 +- packages/jats/article/ArticleComponent.js | 8 +- packages/jats/article/ArticleConverter.js | 6 +- packages/jats/article/ArticleNode.js | 6 +- packages/jats/article/package.js | 14 ++- packages/jats/back/Back.js | 4 +- packages/jats/back/BackComponent.js | 6 +- packages/jats/back/BackConverter.js | 4 +- packages/jats/back/package.js | 8 +- packages/jats/body/Body.js | 4 +- packages/jats/body/BodyComponent.js | 5 +- packages/jats/body/BodyConverter.js | 6 +- packages/jats/body/package.js | 8 +- packages/jats/bold/Bold.js | 4 +- packages/jats/bold/BoldCommand.js | 4 +- packages/jats/bold/BoldConverter.js | 2 +- packages/jats/bold/BoldTool.js | 4 +- packages/jats/bold/package.js | 10 +- packages/jats/caption/Caption.js | 4 +- packages/jats/caption/CaptionComponent.js | 6 +- packages/jats/caption/CaptionConverter.js | 4 +- packages/jats/caption/package.js | 8 +- packages/jats/contrib-group/ContribGroup.js | 4 +- .../contrib-group/ContribGroupComponent.js | 6 +- .../contrib-group/ContribGroupConverter.js | 4 +- packages/jats/contrib-group/package.js | 8 +- packages/jats/contrib/Contrib.js | 4 +- packages/jats/contrib/ContribComponent.js | 12 +-- packages/jats/contrib/ContribConverter.js | 2 +- packages/jats/contrib/package.js | 16 ++- packages/jats/ext-link/EditExtLinkTool.js | 8 +- packages/jats/ext-link/ExtLink.js | 7 +- packages/jats/ext-link/ExtLinkCommand.js | 6 +- packages/jats/ext-link/ExtLinkComponent.js | 4 +- packages/jats/ext-link/ExtLinkConverter.js | 2 +- packages/jats/ext-link/ExtLinkTool.js | 4 +- packages/jats/ext-link/package.js | 17 ++-- packages/jats/figure/Figure.js | 4 +- packages/jats/figure/FigureComponent.js | 6 +- packages/jats/figure/FigureConverter.js | 6 +- packages/jats/figure/FigureTarget.js | 6 +- packages/jats/figure/package.js | 10 +- packages/jats/footnote/Footnote.js | 4 +- packages/jats/footnote/FootnoteComponent.js | 9 +- packages/jats/footnote/FootnoteConverter.js | 4 +- packages/jats/footnote/package.js | 8 +- packages/jats/front/Front.js | 4 +- packages/jats/front/FrontComponent.js | 6 +- packages/jats/front/FrontConverter.js | 4 +- packages/jats/front/package.js | 8 +- packages/jats/graphic/Graphic.js | 4 +- packages/jats/graphic/GraphicComponent.js | 4 +- packages/jats/graphic/GraphicConverter.js | 6 +- packages/jats/graphic/package.js | 8 +- packages/jats/italic/Italic.js | 4 +- packages/jats/italic/ItalicConverter.js | 2 +- packages/jats/italic/package.js | 6 +- packages/jats/label/Label.js | 4 +- packages/jats/label/LabelComponent.js | 5 +- packages/jats/label/LabelConverter.js | 4 +- packages/jats/label/package.js | 8 +- packages/jats/monospace/Monospace.js | 4 +- packages/jats/monospace/MonospaceConverter.js | 2 +- packages/jats/monospace/package.js | 6 +- packages/jats/package.js | 94 +++++++++++------- packages/jats/paragraph/Paragraph.js | 4 +- packages/jats/paragraph/ParagraphComponent.js | 4 +- packages/jats/paragraph/ParagraphConverter.js | 4 +- packages/jats/paragraph/package.js | 8 +- packages/jats/ref-list/RefList.js | 4 +- packages/jats/ref-list/RefListComponent.js | 6 +- packages/jats/ref-list/RefListConverter.js | 6 +- packages/jats/ref-list/package.js | 8 +- packages/jats/ref/Ref.js | 5 +- packages/jats/ref/RefComponent.js | 6 +- packages/jats/ref/RefConverter.js | 2 +- packages/jats/ref/RefTarget.js | 6 +- packages/jats/ref/package.js | 18 ++-- packages/jats/ref/refToHTML.js | 4 +- packages/jats/section/Section.js | 4 +- packages/jats/section/SectionComponent.js | 6 +- packages/jats/section/SectionConverter.js | 6 +- packages/jats/section/package.js | 8 +- packages/jats/subscript/Subscript.js | 4 +- packages/jats/subscript/SubscriptConverter.js | 2 +- packages/jats/subscript/package.js | 6 +- packages/jats/superscript/Superscript.js | 4 +- .../jats/superscript/SuperscriptConverter.js | 2 +- packages/jats/superscript/package.js | 6 +- packages/jats/table-wrap/TableWrap.js | 4 +- .../jats/table-wrap/TableWrapComponent.js | 4 +- .../jats/table-wrap/TableWrapConverter.js | 4 +- packages/jats/table-wrap/package.js | 8 +- packages/jats/table/Table.js | 6 +- packages/jats/table/TableComponent.js | 4 +- packages/jats/table/TableConverter.js | 2 +- packages/jats/table/package.js | 8 +- packages/jats/title-group/TitleGroup.js | 4 +- .../jats/title-group/TitleGroupComponent.js | 6 +- .../jats/title-group/TitleGroupConverter.js | 6 +- packages/jats/title-group/package.js | 8 +- packages/jats/title/Title.js | 4 +- packages/jats/title/TitleComponent.js | 5 +- packages/jats/title/TitleConverter.js | 4 +- packages/jats/title/package.js | 8 +- packages/jats/xref/XRef.js | 5 +- packages/jats/xref/XRefCommand.js | 4 +- packages/jats/xref/XRefComponent.js | 5 +- packages/jats/xref/XRefConverter.js | 2 +- packages/jats/xref/XRefTargets.js | 12 +-- packages/jats/xref/XRefTool.js | 11 +-- packages/jats/xref/getXRefTargets.js | 8 +- packages/jats/xref/package.js | 18 ++-- packages/publisher/Publisher.js | 14 +-- packages/publisher/PublisherTOCProvider.js | 7 +- packages/publisher/package.js | 29 +++--- packages/texture/Texture.js | 11 +-- packages/texture/TextureConfigurator.js | 10 +- packages/texture/package.js | 14 +-- packages/unsupported/UnsupportedInlineNode.js | 6 +- .../UnsupportedInlineNodeCommand.js | 6 +- .../UnsupportedInlineNodeComponent.js | 6 +- .../UnsupportedInlineNodeJATSConverter.js | 9 +- .../unsupported/UnsupportedInlineNodeTool.js | 13 +-- packages/unsupported/UnsupportedNode.js | 6 +- .../unsupported/UnsupportedNodeComponent.js | 4 +- .../UnsupportedNodeJATSConverter.js | 4 +- .../unsupported/UnsupportedNodePackage.js | 18 ++-- test/jats/JATSExporter.test.js | 2 +- test/jats/createJATSConfigurator.js | 10 +- test/jats/inline-wrapper.test.js | 2 +- test/jats/label.test.js | 2 +- test/jats/paragraph.test.js | 2 +- test/jats/test.js | 18 ++-- test/jats/testTextNode.js | 2 +- test/jats/title.test.js | 2 +- util/XMLIterator.js | 51 ++++------ util/renderNodeComponent.js | 4 +- util/toDOM.js | 6 +- 173 files changed, 674 insertions(+), 765 deletions(-) create mode 100644 packages/author/heading/HeadingComponent.js diff --git a/examples/ExampleXMLStore.js b/examples/ExampleXMLStore.js index ac01ce1a9..3947ef5bf 100644 --- a/examples/ExampleXMLStore.js +++ b/examples/ExampleXMLStore.js @@ -1,26 +1,21 @@ -'use strict'; +import { request } from 'substance' -var oo = require('substance/util/oo'); -var request = require('substance/util/request'); +class ExampleXMLStore { -function ExampleXMLStore() {} - -ExampleXMLStore.Prototype = function() { - this.readXML = function(documentId, cb) { + readXML(documentId, cb) { var cached = localStorage.getItem(documentId); if (cached) { return cb(null, cached); } request('GET', '../data/'+documentId+'.xml', null, cb); - }; + } // TODO make functional - this.writeXML = function(documentId, xml, cb) { + writeXML(documentId, xml, cb) { localStorage.setItem(documentId, xml); cb(null); - }; -}; + } -oo.initClass(ExampleXMLStore); +} -module.exports = ExampleXMLStore; +export default ExampleXMLStore; diff --git a/examples/author/app.js b/examples/author/app.js index b4464ef51..2cb4d81fc 100644 --- a/examples/author/app.js +++ b/examples/author/app.js @@ -1,16 +1,21 @@ -'use strict'; +import { substanceGlobals } from 'substance' +import Package from './package' +import TextureConfigurator from '../../packages/texture/TextureConfigurator' +import Texture from '../../packages/texture/Texture' -var substanceGlobals = require('substance/util/substanceGlobals'); substanceGlobals.DEBUG_RENDERING = true; +var config = new TextureConfigurator().import(Package); -var Texture = require('../../packages/texture/Texture'); -var TextureConfigurator = require('../../packages/texture/TextureConfigurator'); -var configurator = new TextureConfigurator().import(require('./package')); +if (typeof window !== 'undefined') { + window.onload = function() { + window.app = Texture.mount({ + mode: 'author', + documentId: 'kitchen-sink-author', + configurator: config + }, document.body); + }; +} -window.onload = function() { - window.app = Texture.mount({ - mode: 'author', - documentId: 'kitchen-sink-author', - configurator: configurator - }, document.body); -}; +export default { + config: config +} diff --git a/examples/author/package.js b/examples/author/package.js index a9f9aae36..f370f0bcb 100644 --- a/examples/author/package.js +++ b/examples/author/package.js @@ -1,9 +1,7 @@ -'use strict'; +import TexturePackage from '../../packages/texture/package' +import ExampleXMLStore from '../ExampleXMLStore' -var TexturePackage = require('../../packages/texture/package'); -var ExampleXMLStore = require('../ExampleXMLStore'); - -module.exports = { +export default { name: 'author-example', configure: function(config) { // Use the default Texture package diff --git a/examples/config.js b/examples/config.js index f245cb078..77a36d62e 100644 --- a/examples/config.js +++ b/examples/config.js @@ -1,5 +1,6 @@ 'use strict'; +// this needs to stay commonjs as it is used only during build module.exports = { examples: ['author', 'publisher'] }; diff --git a/examples/publisher/app.js b/examples/publisher/app.js index bdd8dc374..da1d92107 100644 --- a/examples/publisher/app.js +++ b/examples/publisher/app.js @@ -1,12 +1,10 @@ -'use strict'; +import { substanceGlobals } from 'substance' +import Package from './package' +import Texture from '../../packages/texture/Texture' +import TextureConfigurator from '../../packages/texture/TextureConfigurator' -var substanceGlobals = require('substance/util/substanceGlobals'); substanceGlobals.DEBUG_RENDERING = true; - -var Texture = require('../../packages/texture/Texture'); -var TextureConfigurator = require('../../packages/texture/TextureConfigurator'); - -var configurator = new TextureConfigurator().import(require('./package')); +var configurator = new TextureConfigurator().import(Package); window.onload = function() { window.app = Texture.mount({ diff --git a/examples/publisher/package.js b/examples/publisher/package.js index 2d654d4f4..7464ef87c 100644 --- a/examples/publisher/package.js +++ b/examples/publisher/package.js @@ -1,14 +1,12 @@ -'use strict'; +import TexturePackage from '../../packages/texture/package' +import ExampleXMLStore from '../ExampleXMLStore' -var TexturePackage = require('../../packages/texture/package'); -var ExampleXMLStore = require('../ExampleXMLStore'); - -module.exports = { +export default { name: 'publisher-example', configure: function(config) { config.import(TexturePackage); - // Define XML Store config.setXMLStore(ExampleXMLStore); } -}; +} + diff --git a/packages/author/Author.js b/packages/author/Author.js index bb5ab9fa0..620a29d7f 100644 --- a/packages/author/Author.js +++ b/packages/author/Author.js @@ -1,65 +1,53 @@ -'use strict'; +import { SplitPane, ScrollPane, Layout, Overlay, TOC } from 'substance' +import AbstractWriter from '../common/AbstractWriter' +import AuthorTOCProvider from './AuthorTOCProvider' -var AbstractWriter = require('../common/AbstractWriter'); -var SplitPane = require('substance/ui/SplitPane'); -var ScrollPane = require('substance/ui/ScrollPane'); -var Layout = require('substance/ui/Layout'); -var Overlay = require('substance/ui/DefaultOverlay'); -var AuthorTOCProvider = require('./AuthorTOCProvider'); -var TOC = require('substance/ui/TOC'); +class Author extends AbstractWriter { -function Author() { - Author.super.apply(this, arguments); -} - -Author.Prototype = function() { - - this.render = function($$) { - var el = $$('div').addClass('sc-author'); + render($$) { + let el = $$('div').addClass('sc-author') el.append( $$(SplitPane, {splitType: 'vertical', sizeB: '400px'}).append( this._renderMainSection($$), this._renderContextSection($$) ) - ); - return el; - }; + ) + return el + } - this._renderContextSection = function($$) { + _renderContextSection($$) { return $$('div').addClass('se-context-section').append( $$(TOC) - ); - }; + ) + } - this._renderMainSection = function($$) { - var mainSection = $$('div').addClass('se-main-sectin'); - var splitPane = $$(SplitPane, {splitType: 'horizontal'}).append( + _renderMainSection($$) { + let mainSection = $$('div').addClass('se-main-sectin') + let splitPane = $$(SplitPane, {splitType: 'horizontal'}).append( // inherited from ProseEditor this._renderToolbar($$), this._renderContentPanel($$) - ); - mainSection.append(splitPane); - return mainSection; - }; - + ) + mainSection.append(splitPane) + return mainSection + } - this._renderContentPanel = function($$) { - var doc = this.documentSession.getDocument(); + _renderContentPanel($$) { + const doc = this.documentSession.getDocument() + const ArticleComponent = this.componentRegistry.get('article') + const article = doc.get('article') - var contentPanel = $$(ScrollPane, { + let contentPanel = $$(ScrollPane, { tocProvider: this.tocProvider, scrollbarType: 'substance', scrollbarPosition: 'left', overlay: Overlay, - }).ref('contentPanel'); + }).ref('contentPanel') - var layout = $$(Layout, { + let layout = $$(Layout, { width: 'large' - }); + }) - var ArticleComponent = this.componentRegistry.get('article'); - - var article = doc.get('article'); layout.append( $$(ArticleComponent, { node: article, @@ -67,26 +55,24 @@ Author.Prototype = function() { disabled: this.props.disabled, configurator: this.props.configurator }) - ); - - contentPanel.append(layout); - return contentPanel; - }; + ) - this._scrollTo = function(nodeId) { - this.refs.contentPanel.scrollTo(nodeId); - }; + contentPanel.append(layout) + return contentPanel + } - this._getExporter = function() { - return this.props.configurator.createExporter('jats'); - }; + _scrollTo(nodeId) { + this.refs.contentPanel.scrollTo(nodeId) + } - this._getTOCProvider = function() { - return new AuthorTOCProvider(this.documentSession); - }; + _getExporter() { + return this.props.configurator.createExporter('jats') + } -}; + _getTOCProvider() { + return new AuthorTOCProvider(this.documentSession) + } -AbstractWriter.extend(Author); +} -module.exports = Author; +export default Author diff --git a/packages/author/AuthorExporter.js b/packages/author/AuthorExporter.js index dc29778ee..a5a3667ab 100644 --- a/packages/author/AuthorExporter.js +++ b/packages/author/AuthorExporter.js @@ -1,7 +1,5 @@ -'use strict'; - -var JATSExporter = require('../jats/JATSExporter'); -var JATSTransformer = require('./JATSTransformer'); +import JATSExporter from '../jats/JATSExporter' +import JATSTransformer from './JATSTransformer' function AuthorExporter() { AuthorExporter.super.apply(this, arguments); @@ -19,4 +17,4 @@ AuthorExporter.Prototype = function() { JATSExporter.extend(AuthorExporter); -module.exports = AuthorExporter; +export default AuthorExporter; diff --git a/packages/author/AuthorImporter.js b/packages/author/AuthorImporter.js index 3ec98b884..f038dc9a5 100644 --- a/packages/author/AuthorImporter.js +++ b/packages/author/AuthorImporter.js @@ -1,7 +1,5 @@ -'use strict'; - -var JATSImporter = require('../jats/JATSImporter'); -var JATSTransformer = require('./JATSTransformer'); +import JATSImporter from '../jats/JATSImporter' +import JATSTransformer from './JATSTransformer' function AuthorImporter() { AuthorImporter.super.apply(this, arguments); @@ -20,4 +18,4 @@ AuthorImporter.Prototype = function() { JATSImporter.extend(AuthorImporter); -module.exports = AuthorImporter; \ No newline at end of file +export default AuthorImporter; \ No newline at end of file diff --git a/packages/author/AuthorTOCProvider.js b/packages/author/AuthorTOCProvider.js index bd8e51968..770bf0589 100644 --- a/packages/author/AuthorTOCProvider.js +++ b/packages/author/AuthorTOCProvider.js @@ -1,6 +1,4 @@ -'use strict'; - -var TOCProvider = require('substance/ui/TOCProvider'); +import { TOCProvider } from 'substance' function AuthorTOCProvider(documentSession) { TOCProvider.call(this, documentSession.getDocument(), { @@ -10,4 +8,4 @@ function AuthorTOCProvider(documentSession) { TOCProvider.extend(AuthorTOCProvider); -module.exports = AuthorTOCProvider; \ No newline at end of file +export default AuthorTOCProvider; diff --git a/packages/author/JATSTransformer.js b/packages/author/JATSTransformer.js index 517c9e6c6..08460582a 100644 --- a/packages/author/JATSTransformer.js +++ b/packages/author/JATSTransformer.js @@ -1,9 +1,5 @@ -'use strict'; - -var last = require('lodash/last'); -var oo = require('substance/util/oo'); -var JSONConverter = require('substance/model/JSONConverter'); -var annotationHelpers = require('substance/model/annotationHelpers'); +import last from 'lodash/last' +import { oo, JSONConverter, annotationHelpers } from 'substance' /* EXPERIMENTAL: @@ -153,4 +149,4 @@ JATSTransformer.Prototype = function() { oo.initClass(JATSTransformer); -module.exports = JATSTransformer; +export default JATSTransformer; diff --git a/packages/author/heading/Heading.js b/packages/author/heading/Heading.js index f95fac10c..3cc352e0f 100644 --- a/packages/author/heading/Heading.js +++ b/packages/author/heading/Heading.js @@ -1,6 +1,4 @@ -'use strict'; - -var TextBlock = require('substance/model/TextBlock'); +import { TextBlock } from 'substance' function HeadingNode() { HeadingNode.super.apply(this, arguments); @@ -17,4 +15,4 @@ HeadingNode.define({ level: { type: "number", default: 1 }, }); -module.exports = HeadingNode; +export default HeadingNode; diff --git a/packages/author/heading/HeadingComponent.js b/packages/author/heading/HeadingComponent.js new file mode 100644 index 000000000..f77e805d0 --- /dev/null +++ b/packages/author/heading/HeadingComponent.js @@ -0,0 +1,12 @@ +import { TextBlockComponent } from 'substance' + +class HeadingComponent extends TextBlockComponent { + + render($$) { + var el = super.render($$); + return el.addClass("sc-heading sm-level-"+this.props.node.level); + } + +} + +export default HeadingComponent; diff --git a/packages/author/heading/package.js b/packages/author/heading/package.js index 3b17d2adc..33aff5bed 100644 --- a/packages/author/heading/package.js +++ b/packages/author/heading/package.js @@ -1,15 +1,13 @@ -'use strict'; +import Heading from './Heading' +import HeadingComponent from './HeadingComponent' +import { HeadingPackage as CorePackage } from 'substance' -var Heading = require('./Heading'); -var HeadingComponent = require('substance/packages/heading/HeadingComponent'); -var HeadingHTMLConverter = require('substance/packages/heading/HeadingHTMLConverter'); - -module.exports = { +export default { name: 'heading', configure: function(config) { config.addNode(Heading); config.addComponent(Heading.type, HeadingComponent); - config.addConverter('html', HeadingHTMLConverter); + config.addConverter('html', CorePackage.HeadingHTMLConverter); config.addTextType({ name: 'heading1', data: {type: 'heading', level: 1} @@ -35,4 +33,4 @@ module.exports = { de: 'Überschrift 3' }); } -}; +} diff --git a/packages/author/package.js b/packages/author/package.js index 2c0938749..c9eed9284 100644 --- a/packages/author/package.js +++ b/packages/author/package.js @@ -1,34 +1,33 @@ -'use strict'; +import { Toolbar, BasePackage, PersistencePackage } from 'substance' +import AuthorImporter from './AuthorImporter' +import AuthorExporter from './AuthorExporter' +import JATSPackage from '../jats/package' +import HeadingPackage from './heading/package' +import CommonPackage from '../common/package' +import InlineWrapperPackage from '../inline-wrapper/InlineWrapperPackage' +import UnsupportedNodePackage from '../unsupported/UnsupportedNodePackage' -var Overlay = require('substance/ui/Overlay'); -var Toolbar = require('substance/ui/Toolbar'); - -var AuthorImporter = require('./AuthorImporter'); -var AuthorExporter = require('./AuthorExporter'); - -module.exports = { +export default { name: 'author', configure: function(config) { // Now import base packages - config.import(require('substance/packages/base/BasePackage')); - config.import(require('substance/packages/persistence/PersistencePackage')); - // TODO: see substance#712 - config.addComponent('overlay', Overlay); + config.import(BasePackage); + config.import(PersistencePackage); // TODO: this should be used as default, too config.setToolbarClass(Toolbar); - config.import(require('../jats/package')); - config.import(require('./heading/package')); - config.import(require('../common/package')); + config.import(JATSPackage); + config.import(HeadingPackage); + config.import(CommonPackage); // support inline wrappers, for all hybrid types that can be // block-level but also inline. - config.import(require('../inline-wrapper/InlineWrapperPackage')); + config.import(InlineWrapperPackage); // catch all converters - config.import(require('../unsupported/UnsupportedNodePackage')); + config.import(UnsupportedNodePackage); // Override Importer/Exporter config.addImporter('jats', AuthorImporter); config.addExporter('jats', AuthorExporter); } -}; \ No newline at end of file +} diff --git a/packages/common/AbstractWriter.js b/packages/common/AbstractWriter.js index 7d02b2012..4787f290e 100644 --- a/packages/common/AbstractWriter.js +++ b/packages/common/AbstractWriter.js @@ -1,7 +1,6 @@ -'use strict'; - -var ProseEditor = require('substance/packages/prose-editor/ProseEditor'); -var SaveHandler = require('./SaveHandler'); +import { ProseEditorPackage } from 'substance' +import SaveHandler from './SaveHandler' +const ProseEditor = ProseEditorPackage.ProseEditor // TODO: we need to think if it is really a good idea to // derive from ProseEditor here @@ -69,4 +68,4 @@ AbstractWriter.Prototype = function() { ProseEditor.extend(AbstractWriter); -module.exports = AbstractWriter; +export default AbstractWriter; diff --git a/packages/common/EditXML.js b/packages/common/EditXML.js index 6699762c1..6c37891ec 100644 --- a/packages/common/EditXML.js +++ b/packages/common/EditXML.js @@ -1,9 +1,6 @@ -'use strict'; - -var Component = require('substance/ui/Component'); -var XMLAttributeEditor = require('./XMLAttributeEditor'); -var XMLEditor = require('./XMLEditor'); -var Button = require('substance/ui/Button'); +import { Button, Component } from 'substance' +import XMLAttributeEditor from './XMLAttributeEditor' +import XMLEditor from './XMLEditor' function EditXML() { EditXML.super.apply(this, arguments); @@ -77,4 +74,4 @@ EditXML.Prototype = function() { Component.extend(EditXML); -module.exports = EditXML; +export default EditXML; diff --git a/packages/common/SaveHandler.js b/packages/common/SaveHandler.js index ecf83ffd1..984cea4ec 100644 --- a/packages/common/SaveHandler.js +++ b/packages/common/SaveHandler.js @@ -1,20 +1,14 @@ -'use strict'; +export default class SaveHandler { -var oo = require('substance/util/oo'); + constructor(context) { + this.context = context; + } -function SaveHandler(context) { - this.context = context; -} - -SaveHandler.Prototype = function() { - this.saveDocument = function(doc, changes, cb) { + saveDocument(doc, changes, cb) { var exporter = this.context.exporter; var xml = exporter.exportDocument(doc); // console.log('### SAVING XML', xml); this.context.xmlStore.writeXML(this.context.documentId, xml, cb); - }; -}; + } -oo.initClass(SaveHandler); - -module.exports = SaveHandler; +} diff --git a/packages/common/XMLAttributeEditor.js b/packages/common/XMLAttributeEditor.js index 7a498c4fa..d02fd8e83 100644 --- a/packages/common/XMLAttributeEditor.js +++ b/packages/common/XMLAttributeEditor.js @@ -1,7 +1,5 @@ -'use strict'; - -var Component = require('substance/ui/Component'); -var map = require('lodash/map'); +import map from 'lodash/map' +import { Component } from 'substance' function XMLAttributeEditor() { XMLAttributeEditor.super.apply(this, arguments); @@ -47,4 +45,4 @@ XMLAttributeEditor.Prototype = function() { Component.extend(XMLAttributeEditor); -module.exports = XMLAttributeEditor; +export default XMLAttributeEditor; diff --git a/packages/common/XMLEditor.js b/packages/common/XMLEditor.js index 600fd2623..2324f146e 100644 --- a/packages/common/XMLEditor.js +++ b/packages/common/XMLEditor.js @@ -1,6 +1,4 @@ -'use strict'; - -var Component = require('substance/ui/Component'); +import { Component } from 'substance' function XMLEditor() { XMLEditor.super.apply(this, arguments); @@ -27,4 +25,4 @@ XMLEditor.Prototype = function() { Component.extend(XMLEditor); -module.exports = XMLEditor; +export default XMLEditor; diff --git a/packages/common/package.js b/packages/common/package.js index eaa38c234..9d5c08079 100644 --- a/packages/common/package.js +++ b/packages/common/package.js @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = { +export default { name: 'common', configure: function() {} -}; \ No newline at end of file +} diff --git a/packages/inline-wrapper/InlineWrapperJATSConverter.js b/packages/inline-wrapper/InlineWrapperJATSConverter.js index 3a5589c90..ce6aa984e 100644 --- a/packages/inline-wrapper/InlineWrapperJATSConverter.js +++ b/packages/inline-wrapper/InlineWrapperJATSConverter.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports = { +export default { type: 'inline-wrapper', diff --git a/packages/inline-wrapper/InlineWrapperPackage.js b/packages/inline-wrapper/InlineWrapperPackage.js index ebab13f88..f71fe3927 100644 --- a/packages/inline-wrapper/InlineWrapperPackage.js +++ b/packages/inline-wrapper/InlineWrapperPackage.js @@ -1,13 +1,10 @@ -'use strict'; +import { InlineWrapperPackage } from 'substance' +import InlineWrapperJATSConverter from './InlineWrapperJATSConverter' -var SubstanceInlineWrapperPackage = require('substance/packages/inline-wrapper/InlineWrapperPackage'); -var InlineWrapperJATSConverter = require('./InlineWrapperJATSConverter'); - -module.exports = { +export default { name: 'inline-wrapper', - configure: function(config) { - config.import(SubstanceInlineWrapperPackage); + config.import(InlineWrapperPackage); config.addConverter('jats', InlineWrapperJATSConverter); } -}; +} diff --git a/packages/jats/JATS.js b/packages/jats/JATS.js index 62ce717f4..351559f32 100644 --- a/packages/jats/JATS.js +++ b/packages/jats/JATS.js @@ -62,7 +62,7 @@ JATS.PARA_LEVEL = JATS.BLOCK_DISPLAY .concat(JATS.REST_OF_PARA) .concat(JATS.X); -module.exports = JATS; +export default JATS; diff --git a/packages/jats/JATSExporter.js b/packages/jats/JATSExporter.js index 16e27d244..026e619e9 100644 --- a/packages/jats/JATSExporter.js +++ b/packages/jats/JATSExporter.js @@ -1,7 +1,7 @@ 'use strict'; -var isString = require('lodash/isString'); -var XMLExporter = require('substance/model/XMLExporter'); +import isString from 'lodash/isString' +import { XMLExporter } from 'substance' function JATSExporter(config) { JATSExporter.super.call(this, config); @@ -45,4 +45,4 @@ JATSExporter.Prototype = function() { XMLExporter.extend(JATSExporter); -module.exports = JATSExporter; +export default JATSExporter; diff --git a/packages/jats/JATSImporter.js b/packages/jats/JATSImporter.js index 2f789a9f2..4a744ab50 100644 --- a/packages/jats/JATSImporter.js +++ b/packages/jats/JATSImporter.js @@ -1,11 +1,6 @@ -'use strict'; - -var last = require('lodash/last'); -var DOMImporter = require('substance/model/DOMImporter'); -var XMLImporter = require('substance/model/XMLImporter'); -var DefaultDOMElement = require('substance/ui/DefaultDOMElement'); -var UnsupportedNodeJATSConverter = require('../unsupported/UnsupportedNodeJATSConverter'); -var inBrowser = require('substance/util/inBrowser'); +import last from 'lodash/last' +import { DefaultDOMElement, DOMImporter, XMLImporter, inBrowser } from 'substance' +import UnsupportedNodeJATSConverter from '../unsupported/UnsupportedNodeJATSConverter' function JATSImporter(config) { config.enableInlineWrapper = true; @@ -109,4 +104,4 @@ JATSImporter.State.Prototype = function() { DOMImporter.State.extend(JATSImporter.State); -module.exports = JATSImporter; +export default JATSImporter; diff --git a/packages/jats/TextNodeConverter.js b/packages/jats/TextNodeConverter.js index 8afd9d96c..e81516db0 100644 --- a/packages/jats/TextNodeConverter.js +++ b/packages/jats/TextNodeConverter.js @@ -1,8 +1,8 @@ 'use strict'; -var extend = require('lodash/extend'); +import extend from 'lodash/extend' -module.exports = { +export default { import: function(el, node, converter) { node.content = converter.annotatedText(el, [node.id, 'content']); }, diff --git a/packages/jats/article-meta/ArticleMeta.js b/packages/jats/article-meta/ArticleMeta.js index 7a318e5fe..f5f9b1ddc 100644 --- a/packages/jats/article-meta/ArticleMeta.js +++ b/packages/jats/article-meta/ArticleMeta.js @@ -1,6 +1,4 @@ -'use strict'; - -var DocumentNode = require('substance/model/DocumentNode'); +import { DocumentNode } from 'substance' function ArticleMeta() { ArticleMeta.super.apply(this, arguments); @@ -15,4 +13,4 @@ ArticleMeta.define({ nodes: { type: ['id'], default: [] } }); -module.exports = ArticleMeta; +export default ArticleMeta; diff --git a/packages/jats/article-meta/ArticleMetaComponent.js b/packages/jats/article-meta/ArticleMetaComponent.js index a074be6cd..78df501e3 100644 --- a/packages/jats/article-meta/ArticleMetaComponent.js +++ b/packages/jats/article-meta/ArticleMetaComponent.js @@ -1,8 +1,7 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var renderNodeComponent = require('../../../util/renderNodeComponent'); - +import { Component } from 'substance' +import renderNodeComponent from '../../../util/renderNodeComponent' function ArticleMetaComponent() { Component.apply(this, arguments); @@ -35,4 +34,4 @@ ArticleMetaComponent.Prototype = function() { Component.extend(ArticleMetaComponent); -module.exports = ArticleMetaComponent; \ No newline at end of file +export default ArticleMetaComponent; \ No newline at end of file diff --git a/packages/jats/article-meta/ArticleMetaConverter.js b/packages/jats/article-meta/ArticleMetaConverter.js index 99b5c1ad3..7e126f3db 100644 --- a/packages/jats/article-meta/ArticleMetaConverter.js +++ b/packages/jats/article-meta/ArticleMetaConverter.js @@ -1,10 +1,10 @@ 'use strict'; -var XMLIterator = require('../../../util/XMLIterator'); +import XMLIterator from '../../../util/XMLIterator' -var JATS = require('../JATS'); +import JATS from '../JATS' -module.exports = { +export default { type: 'article-meta', tagName: 'article-meta', diff --git a/packages/jats/article-meta/package.js b/packages/jats/article-meta/package.js index 19591aa91..611e22d81 100644 --- a/packages/jats/article-meta/package.js +++ b/packages/jats/article-meta/package.js @@ -1,10 +1,10 @@ 'use strict'; -var ArticleMeta = require('./ArticleMeta'); -var ArticleMetaConverter = require('./ArticleMetaConverter'); -var ArticleMetaComponent = require('./ArticleMetaComponent'); +import ArticleMeta from './ArticleMeta' +import ArticleMetaConverter from './ArticleMetaConverter' +import ArticleMetaComponent from './ArticleMetaComponent' -module.exports = { +export default { name: 'article-meta', configure: function(config) { config.addNode(ArticleMeta); diff --git a/packages/jats/article-title/ArticleTitle.js b/packages/jats/article-title/ArticleTitle.js index af90b9081..94e180fda 100644 --- a/packages/jats/article-title/ArticleTitle.js +++ b/packages/jats/article-title/ArticleTitle.js @@ -1,6 +1,6 @@ 'use strict'; -var TextNode = require('substance/model/TextNode'); +import { TextNode } from 'substance' function ArticleTitle() { ArticleTitle.super.apply(this, arguments); @@ -14,4 +14,4 @@ ArticleTitle.define({ attributes: { type: 'object', default: {} }, }); -module.exports = ArticleTitle; \ No newline at end of file +export default ArticleTitle; \ No newline at end of file diff --git a/packages/jats/article-title/ArticleTitleComponent.js b/packages/jats/article-title/ArticleTitleComponent.js index 37507bcae..3167837c4 100644 --- a/packages/jats/article-title/ArticleTitleComponent.js +++ b/packages/jats/article-title/ArticleTitleComponent.js @@ -1,6 +1,6 @@ 'use strict'; -var TitleComponent = require('../title/TitleComponent'); +import TitleComponent from '../title/TitleComponent' function ArticleTitleComponent() { ArticleTitleComponent.super.apply(this, arguments); @@ -20,4 +20,4 @@ ArticleTitleComponent.Prototype = function() { TitleComponent.extend(ArticleTitleComponent); -module.exports = ArticleTitleComponent; \ No newline at end of file +export default ArticleTitleComponent; \ No newline at end of file diff --git a/packages/jats/article-title/ArticleTitleConverter.js b/packages/jats/article-title/ArticleTitleConverter.js index 2dcaedea9..c95dfac75 100644 --- a/packages/jats/article-title/ArticleTitleConverter.js +++ b/packages/jats/article-title/ArticleTitleConverter.js @@ -1,8 +1,8 @@ 'use strict'; -var TextNodeConverter = require('../TextNodeConverter'); +import TextNodeConverter from '../TextNodeConverter' -module.exports = TextNodeConverter.extend({ +export default TextNodeConverter.extend({ type: 'article-title', tagName: 'article-title', }); diff --git a/packages/jats/article-title/package.js b/packages/jats/article-title/package.js index 7dcea75f5..fb19279e4 100644 --- a/packages/jats/article-title/package.js +++ b/packages/jats/article-title/package.js @@ -1,14 +1,14 @@ 'use strict'; -var ArticleTitle = require('./ArticleTitle'); -var ArticleTitleConverter = require('./ArticleTitleConverter'); -var ArticleTitleComponent = require('./ArticleTitleComponent'); +import ArticleTitle from './ArticleTitle' +import ArticleTitleConverter from './ArticleTitleConverter' +import ArticleTitleComponent from './ArticleTitleComponent' -module.exports = { +export default { name: 'article-title', configure: function(config) { config.addNode(ArticleTitle); config.addConverter('jats', ArticleTitleConverter); config.addComponent(ArticleTitle.type, ArticleTitleComponent); } -}; +} diff --git a/packages/jats/article/ArticleComponent.js b/packages/jats/article/ArticleComponent.js index 578fac7f3..3c73b6616 100644 --- a/packages/jats/article/ArticleComponent.js +++ b/packages/jats/article/ArticleComponent.js @@ -1,7 +1,5 @@ -'use strict'; - -var Component = require('substance/ui/Component'); -var renderNodeComponent = require('../../../util/renderNodeComponent'); +import { Component } from 'substance' +import renderNodeComponent from '../../../util/renderNodeComponent' function ArticleComponent() { Component.apply(this, arguments); @@ -53,4 +51,4 @@ ArticleComponent.Prototype = function() { Component.extend(ArticleComponent); -module.exports = ArticleComponent; \ No newline at end of file +export default ArticleComponent; \ No newline at end of file diff --git a/packages/jats/article/ArticleConverter.js b/packages/jats/article/ArticleConverter.js index f688749a5..d2e9b00a9 100644 --- a/packages/jats/article/ArticleConverter.js +++ b/packages/jats/article/ArticleConverter.js @@ -1,8 +1,6 @@ -'use strict'; +import XMLIterator from '../../../util/XMLIterator' -var XMLIterator = require('../../../util/XMLIterator'); - -module.exports = { +export default { type: 'article', tagName: 'article', diff --git a/packages/jats/article/ArticleNode.js b/packages/jats/article/ArticleNode.js index 0ce4d0f44..9b22a95c4 100644 --- a/packages/jats/article/ArticleNode.js +++ b/packages/jats/article/ArticleNode.js @@ -1,6 +1,4 @@ -'use strict'; - -var DocumentNode = require('substance/model/DocumentNode'); +import { DocumentNode } from 'substance' function ArticleNode() { ArticleNode.super.apply(this, arguments); @@ -37,4 +35,4 @@ ArticleNode.define({ responses: { type: ['id'], optional: true }, }); -module.exports = ArticleNode; +export default ArticleNode; diff --git a/packages/jats/article/package.js b/packages/jats/article/package.js index d8ff1bfbd..79dd14901 100644 --- a/packages/jats/article/package.js +++ b/packages/jats/article/package.js @@ -1,11 +1,9 @@ -'use strict'; +import ArticleNode from './ArticleNode' +import ArticleConverter from './ArticleConverter' +import TextureArticle from './TextureArticle' +import ArticleComponent from './ArticleComponent' -var ArticleNode = require('./ArticleNode'); -var ArticleConverter = require('./ArticleConverter'); -var TextureArticle = require('./TextureArticle'); -var ArticleComponent = require('./ArticleComponent'); - -module.exports = { +export default { name: 'article', configure: function(config) { config.defineSchema({ @@ -17,4 +15,4 @@ module.exports = { config.addConverter('jats', ArticleConverter); config.addComponent(ArticleNode.type, ArticleComponent); } -}; \ No newline at end of file +} diff --git a/packages/jats/back/Back.js b/packages/jats/back/Back.js index c37fe297a..b872a3425 100644 --- a/packages/jats/back/Back.js +++ b/packages/jats/back/Back.js @@ -1,6 +1,6 @@ 'use strict'; -var Container = require('substance/model/Container'); +import { Container } from 'substance' /* Back matter @@ -31,4 +31,4 @@ Back.define({ nodes: { type: ['id'], default: [] }, }); -module.exports = Back; +export default Back; diff --git a/packages/jats/back/BackComponent.js b/packages/jats/back/BackComponent.js index dc6c4db3d..ca8929a0b 100644 --- a/packages/jats/back/BackComponent.js +++ b/packages/jats/back/BackComponent.js @@ -1,7 +1,7 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var renderNodeComponent = require('../../../util/renderNodeComponent'); +import { Component } from 'substance' +import renderNodeComponent from '../../../util/renderNodeComponent' function BackComponent() { Component.apply(this, arguments); @@ -38,4 +38,4 @@ BackComponent.Prototype = function() { Component.extend(BackComponent); -module.exports = BackComponent; \ No newline at end of file +export default BackComponent; \ No newline at end of file diff --git a/packages/jats/back/BackConverter.js b/packages/jats/back/BackConverter.js index f7ea4640a..000cc2bcb 100644 --- a/packages/jats/back/BackConverter.js +++ b/packages/jats/back/BackConverter.js @@ -1,9 +1,9 @@ 'use strict'; -var XMLIterator = require('../../../util/XMLIterator'); +import XMLIterator from '../../../util/XMLIterator' var BACK_CONTENT = ["ack", "app-group", "bio", "fn-group", "glossary", "ref-list", "notes", "sec"]; -module.exports = { +export default { type: 'back', tagName: 'back', diff --git a/packages/jats/back/package.js b/packages/jats/back/package.js index 8ba28bbf0..7a06c2cd2 100644 --- a/packages/jats/back/package.js +++ b/packages/jats/back/package.js @@ -1,10 +1,10 @@ 'use strict'; -var Back = require('./Back'); -var BackConverter = require('./BackConverter'); -var BackComponent = require('./BackComponent'); +import Back from './Back' +import BackConverter from './BackConverter' +import BackComponent from './BackComponent' -module.exports = { +export default { name: 'back', configure: function(config) { config.addNode(Back); diff --git a/packages/jats/body/Body.js b/packages/jats/body/Body.js index 68474d9b9..08e46aacc 100644 --- a/packages/jats/body/Body.js +++ b/packages/jats/body/Body.js @@ -1,6 +1,6 @@ 'use strict'; -var Container = require('substance/model/Container'); +import { Container } from 'substance' function Body() { Body.super.apply(this, arguments); @@ -24,4 +24,4 @@ Body.define({ }); -module.exports = Body; +export default Body; diff --git a/packages/jats/body/BodyComponent.js b/packages/jats/body/BodyComponent.js index 1be83b29c..61d9f06d4 100644 --- a/packages/jats/body/BodyComponent.js +++ b/packages/jats/body/BodyComponent.js @@ -1,7 +1,6 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var ContainerEditor = require('substance/ui/ContainerEditor'); +import { Component, ContainerEditor } from 'substance' function BodyComponent() { Component.apply(this, arguments); @@ -31,4 +30,4 @@ BodyComponent.Prototype = function() { Component.extend(BodyComponent); -module.exports = BodyComponent; \ No newline at end of file +export default BodyComponent; \ No newline at end of file diff --git a/packages/jats/body/BodyConverter.js b/packages/jats/body/BodyConverter.js index a99b0c670..a0d08c046 100644 --- a/packages/jats/body/BodyConverter.js +++ b/packages/jats/body/BodyConverter.js @@ -1,9 +1,9 @@ 'use strict'; -var JATS = require('../JATS'); -var XMLIterator = require('../../../util/XMLIterator'); +import JATS from '../JATS' +import XMLIterator from '../../../util/XMLIterator' -module.exports = { +export default { type: 'body', tagName: 'body', diff --git a/packages/jats/body/package.js b/packages/jats/body/package.js index e5e529a16..be3ea8b1c 100644 --- a/packages/jats/body/package.js +++ b/packages/jats/body/package.js @@ -1,10 +1,10 @@ 'use strict'; -var Body = require('./Body'); -var BodyConverter = require('./BodyConverter'); -var BodyComponent = require('./BodyComponent'); +import Body from './Body' +import BodyConverter from './BodyConverter' +import BodyComponent from './BodyComponent' -module.exports = { +export default { name: 'body', configure: function(config) { config.addNode(Body); diff --git a/packages/jats/bold/Bold.js b/packages/jats/bold/Bold.js index 3d7660b44..1d37e09cb 100644 --- a/packages/jats/bold/Bold.js +++ b/packages/jats/bold/Bold.js @@ -1,6 +1,6 @@ 'use strict'; -var Annotation = require('substance/model/Annotation'); +import { Annotation } from 'substance' function Bold() { Bold.super.apply(this, arguments); @@ -14,4 +14,4 @@ Bold.define({ attributes: { type: 'object', default: {} }, }); -module.exports = Bold; +export default Bold; diff --git a/packages/jats/bold/BoldCommand.js b/packages/jats/bold/BoldCommand.js index 666628f71..674309f5a 100644 --- a/packages/jats/bold/BoldCommand.js +++ b/packages/jats/bold/BoldCommand.js @@ -1,6 +1,6 @@ 'use strict'; -var AnnotationCommand = require('substance/ui/AnnotationCommand'); +import { AnnotationCommand } from 'substance' function BoldCommand() { BoldCommand.super.apply(this, arguments); @@ -8,4 +8,4 @@ function BoldCommand() { AnnotationCommand.extend(BoldCommand); -module.exports = BoldCommand; \ No newline at end of file +export default BoldCommand; \ No newline at end of file diff --git a/packages/jats/bold/BoldConverter.js b/packages/jats/bold/BoldConverter.js index 344f6e42e..b51bc0d89 100644 --- a/packages/jats/bold/BoldConverter.js +++ b/packages/jats/bold/BoldConverter.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports = { +export default { type: 'bold', tagName: 'bold' }; diff --git a/packages/jats/bold/BoldTool.js b/packages/jats/bold/BoldTool.js index 6a7cbfbae..4e65354d0 100644 --- a/packages/jats/bold/BoldTool.js +++ b/packages/jats/bold/BoldTool.js @@ -1,10 +1,10 @@ 'use strict'; -var AnnotationTool = require('substance/ui/AnnotationTool'); +import { AnnotationTool } from 'substance' function BoldTool() { BoldTool.super.apply(this, arguments); } AnnotationTool.extend(BoldTool); -module.exports = BoldTool; \ No newline at end of file +export default BoldTool; \ No newline at end of file diff --git a/packages/jats/bold/package.js b/packages/jats/bold/package.js index 9102c5803..7db830e53 100644 --- a/packages/jats/bold/package.js +++ b/packages/jats/bold/package.js @@ -1,11 +1,11 @@ 'use strict'; -var Bold = require('./Bold'); -var BoldConverter = require('./BoldConverter'); -var BoldTool = require('./BoldTool'); -var BoldCommand = require('./BoldCommand'); +import Bold from './Bold' +import BoldConverter from './BoldConverter' +import BoldTool from './BoldTool' +import BoldCommand from './BoldCommand' -module.exports = { +export default { name: 'bold', configure: function(config) { config.addNode(Bold); diff --git a/packages/jats/caption/Caption.js b/packages/jats/caption/Caption.js index e27518a2a..c423c53b5 100644 --- a/packages/jats/caption/Caption.js +++ b/packages/jats/caption/Caption.js @@ -1,6 +1,6 @@ 'use strict'; -var Container = require('substance/model/Container'); +import { Container } from 'substance' function Caption() { Caption.super.apply(this, arguments); @@ -39,4 +39,4 @@ Caption.define({ nodes: { type: ['p'], default: [] } }); -module.exports = Caption; \ No newline at end of file +export default Caption; \ No newline at end of file diff --git a/packages/jats/caption/CaptionComponent.js b/packages/jats/caption/CaptionComponent.js index 85f459d49..0933626ac 100644 --- a/packages/jats/caption/CaptionComponent.js +++ b/packages/jats/caption/CaptionComponent.js @@ -1,8 +1,6 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var TextPropertyEditor = require('substance/ui/TextPropertyEditor'); -var ContainerEditor = require('substance/ui/ContainerEditor'); +import { Component, ContainerEditor, TextPropertyEditor } from 'substance' function CaptionComponent() { Component.apply(this, arguments); @@ -40,4 +38,4 @@ CaptionComponent.Prototype = function() { Component.extend(CaptionComponent); -module.exports = CaptionComponent; +export default CaptionComponent; diff --git a/packages/jats/caption/CaptionConverter.js b/packages/jats/caption/CaptionConverter.js index e09b752b6..43917820d 100644 --- a/packages/jats/caption/CaptionConverter.js +++ b/packages/jats/caption/CaptionConverter.js @@ -1,8 +1,8 @@ 'use strict'; -var XMLIterator = require('../../../util/XMLIterator'); +import XMLIterator from '../../../util/XMLIterator' -module.exports = { +export default { type: 'caption', tagName: 'caption', diff --git a/packages/jats/caption/package.js b/packages/jats/caption/package.js index 0d47c9403..8e1229d0b 100644 --- a/packages/jats/caption/package.js +++ b/packages/jats/caption/package.js @@ -1,10 +1,10 @@ 'use strict'; -var Caption = require('./Caption'); -var CaptionComponent = require('./CaptionComponent'); -var CaptionConverter = require('./CaptionConverter'); +import Caption from './Caption' +import CaptionComponent from './CaptionComponent' +import CaptionConverter from './CaptionConverter' -module.exports = { +export default { name: 'caption', configure: function(config) { config.addNode(Caption); diff --git a/packages/jats/contrib-group/ContribGroup.js b/packages/jats/contrib-group/ContribGroup.js index 0779c8433..4a4c460c5 100644 --- a/packages/jats/contrib-group/ContribGroup.js +++ b/packages/jats/contrib-group/ContribGroup.js @@ -1,6 +1,6 @@ 'use strict'; -var Container = require('substance/model/Container'); +import { Container } from 'substance' function ContribGroup() { ContribGroup.super.apply(this, arguments); @@ -15,4 +15,4 @@ ContribGroup.define({ nodes: { type: ['id'], default: [] } }); -module.exports = ContribGroup; +export default ContribGroup; diff --git a/packages/jats/contrib-group/ContribGroupComponent.js b/packages/jats/contrib-group/ContribGroupComponent.js index 9e6ad0ae9..1b1439c4d 100644 --- a/packages/jats/contrib-group/ContribGroupComponent.js +++ b/packages/jats/contrib-group/ContribGroupComponent.js @@ -1,7 +1,7 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var renderNodeComponent = require('../../../util/renderNodeComponent'); +import { Component } from 'substance' +import renderNodeComponent from '../../../util/renderNodeComponent' class ContribGroupComponent extends Component { didMount() { @@ -42,4 +42,4 @@ class ContribGroupComponent extends Component { } -module.exports = ContribGroupComponent; \ No newline at end of file +export default ContribGroupComponent; \ No newline at end of file diff --git a/packages/jats/contrib-group/ContribGroupConverter.js b/packages/jats/contrib-group/ContribGroupConverter.js index 37024d22a..850d076b2 100644 --- a/packages/jats/contrib-group/ContribGroupConverter.js +++ b/packages/jats/contrib-group/ContribGroupConverter.js @@ -1,10 +1,10 @@ 'use strict'; -var XMLIterator = require('../../../util/XMLIterator'); +import XMLIterator from '../../../util/XMLIterator' var CONTRIB_GROUP = ['contrib', 'address', 'aff', 'aff-alternatives', 'author-comment', 'bio', 'email', 'etal', 'ext-link', 'fn', 'on-behalf-of', 'role', 'uri', 'xref', 'x']; -module.exports = { +export default { type: 'contrib-group', tagName: 'contrib-group', diff --git a/packages/jats/contrib-group/package.js b/packages/jats/contrib-group/package.js index 7218a30d2..2bde9a4c3 100644 --- a/packages/jats/contrib-group/package.js +++ b/packages/jats/contrib-group/package.js @@ -1,10 +1,10 @@ 'use strict'; -var ContribGroup = require('./ContribGroup'); -var ContribGroupConverter = require('./ContribGroupConverter'); -var ContribGroupComponent = require('./ContribGroupComponent'); +import ContribGroup from './ContribGroup' +import ContribGroupConverter from './ContribGroupConverter' +import ContribGroupComponent from './ContribGroupComponent' -module.exports = { +export default { name: 'contrib-group', configure: function(config) { config.addNode(ContribGroup); diff --git a/packages/jats/contrib/Contrib.js b/packages/jats/contrib/Contrib.js index 66b9c987d..6fc7ddd9d 100644 --- a/packages/jats/contrib/Contrib.js +++ b/packages/jats/contrib/Contrib.js @@ -1,6 +1,6 @@ 'use strict'; -var DocumentNode = require('substance/model/DocumentNode'); +import { DocumentNode } from 'substance' class Contrib extends DocumentNode { @@ -23,4 +23,4 @@ Contrib.define({ xmlContent: { type: 'string', default: ''} }); -module.exports = Contrib; +export default Contrib; diff --git a/packages/jats/contrib/ContribComponent.js b/packages/jats/contrib/ContribComponent.js index 1a4fbdfbe..18ed34e77 100644 --- a/packages/jats/contrib/ContribComponent.js +++ b/packages/jats/contrib/ContribComponent.js @@ -1,10 +1,10 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var Modal = require('substance/ui/Modal'); -var EditXML = require('../../common/EditXML'); -var EditContrib = require('./EditContrib'); -var getAdapter = require('./contribUtils').getAdapter; +import { Component, Modal } from 'substance' +import EditXML from '../../common/EditXML' +import contribToHTML from './contribToHTML' +import EditContrib from './EditContrib' +import { getAdapter } from './contribUtils' function ContribComponent() { ContribComponent.super.apply(this, arguments); @@ -65,4 +65,4 @@ ContribComponent.Prototype = function() { Component.extend(ContribComponent); -module.exports = ContribComponent; +export default ContribComponent; diff --git a/packages/jats/contrib/ContribConverter.js b/packages/jats/contrib/ContribConverter.js index c536b58fd..db83fa9d7 100644 --- a/packages/jats/contrib/ContribConverter.js +++ b/packages/jats/contrib/ContribConverter.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports = { +export default { type: 'contrib', tagName: 'contrib', diff --git a/packages/jats/contrib/package.js b/packages/jats/contrib/package.js index 5570715cb..22c18af65 100644 --- a/packages/jats/contrib/package.js +++ b/packages/jats/contrib/package.js @@ -1,12 +1,10 @@ -'use strict'; +import Contrib from './Contrib' +import ContribComponent from './ContribComponent' +import ContribConverter from './ContribConverter' +import TagContribCommand from './TagContribCommand' +import TagContribTool from './TagContribTool' -var Contrib = require('./Contrib'); -var ContribComponent = require('./ContribComponent'); -var ContribConverter = require('./ContribConverter'); -var TagContribCommand = require('./TagContribCommand'); -var TagContribTool = require('./TagContribTool'); - -module.exports = { +export default { name: 'contrib', configure: function(config) { config.addNode(Contrib); @@ -16,4 +14,4 @@ module.exports = { config.addTool('tag-contrib', TagContribTool); config.addIcon('tag-contrib', { 'fontawesome': 'fa-bullseye' }); } -}; \ No newline at end of file +} diff --git a/packages/jats/ext-link/EditExtLinkTool.js b/packages/jats/ext-link/EditExtLinkTool.js index c9480d6fe..3893ea41c 100644 --- a/packages/jats/ext-link/EditExtLinkTool.js +++ b/packages/jats/ext-link/EditExtLinkTool.js @@ -1,13 +1,13 @@ 'use strict'; -var EditLinkTool = require('substance/packages/link/EditLinkTool'); -var clone = require('lodash/clone'); +import { LinkPackage } from 'substance' +import clone from 'lodash/clone' function EditExtLinkTool() { EditExtLinkTool.super.apply(this, arguments); } -EditLinkTool.extend(EditExtLinkTool); +LinkPackage.EditLinkTool.extend(EditExtLinkTool); EditExtLinkTool.urlPropertyPath = ['attributes', 'xlink:href']; @@ -19,4 +19,4 @@ EditExtLinkTool.getProps = function(commandStates) { } }; -module.exports = EditExtLinkTool; +export default EditExtLinkTool; diff --git a/packages/jats/ext-link/ExtLink.js b/packages/jats/ext-link/ExtLink.js index 1d6129610..30a9deb4b 100644 --- a/packages/jats/ext-link/ExtLink.js +++ b/packages/jats/ext-link/ExtLink.js @@ -1,13 +1,12 @@ 'use strict'; -var PropertyAnnotation = require('substance/model/PropertyAnnotation'); -var Fragmenter = require('substance/model/Fragmenter'); +import { Annotation, Fragmenter } from 'substance' function ExtLink() { ExtLink.super.apply(this, arguments); } -PropertyAnnotation.extend(ExtLink); +Annotation.extend(ExtLink); ExtLink.type = "ext-link"; @@ -19,4 +18,4 @@ ExtLink.define({ // in presence of overlapping annotations will try to render this as one element ExtLink.fragmentation = Fragmenter.SHOULD_NOT_SPLIT; -module.exports = ExtLink; +export default ExtLink; diff --git a/packages/jats/ext-link/ExtLinkCommand.js b/packages/jats/ext-link/ExtLinkCommand.js index 23f71519b..c32c094fd 100644 --- a/packages/jats/ext-link/ExtLinkCommand.js +++ b/packages/jats/ext-link/ExtLinkCommand.js @@ -1,6 +1,6 @@ 'use strict'; -var LinkCommand = require('substance/packages/link/LinkCommand'); +import { LinkPackage } from 'substance' function ExtLinkCommand() { ExtLinkCommand.super.apply(this, arguments); @@ -16,6 +16,6 @@ ExtLinkCommand.Prototype = function() { }; }; -LinkCommand.extend(ExtLinkCommand); +LinkPackage.LinkCommand.extend(ExtLinkCommand); -module.exports = ExtLinkCommand; \ No newline at end of file +export default ExtLinkCommand; \ No newline at end of file diff --git a/packages/jats/ext-link/ExtLinkComponent.js b/packages/jats/ext-link/ExtLinkComponent.js index 3351f389f..0ba0588aa 100644 --- a/packages/jats/ext-link/ExtLinkComponent.js +++ b/packages/jats/ext-link/ExtLinkComponent.js @@ -1,6 +1,6 @@ 'use strict'; -var AnnotationComponent = require('substance/ui/AnnotationComponent'); +import { AnnotationComponent } from 'substance' function ExtLinkComponent() { ExtLinkComponent.super.apply(this, arguments); @@ -38,4 +38,4 @@ ExtLinkComponent.Prototype = function() { AnnotationComponent.extend(ExtLinkComponent); -module.exports = ExtLinkComponent; +export default ExtLinkComponent; diff --git a/packages/jats/ext-link/ExtLinkConverter.js b/packages/jats/ext-link/ExtLinkConverter.js index 42a401c53..7eaed83ba 100644 --- a/packages/jats/ext-link/ExtLinkConverter.js +++ b/packages/jats/ext-link/ExtLinkConverter.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports = { +export default { type: "ext-link", tagName: "ext-link", diff --git a/packages/jats/ext-link/ExtLinkTool.js b/packages/jats/ext-link/ExtLinkTool.js index e677f077e..15a744021 100644 --- a/packages/jats/ext-link/ExtLinkTool.js +++ b/packages/jats/ext-link/ExtLinkTool.js @@ -1,6 +1,6 @@ 'use strict'; -var AnnotationTool = require('substance/ui/AnnotationTool'); +import { AnnotationTool } from 'substance' function ExtLinkTool() { ExtLinkTool.super.apply(this, arguments); @@ -8,4 +8,4 @@ function ExtLinkTool() { AnnotationTool.extend(ExtLinkTool); -module.exports = ExtLinkTool; \ No newline at end of file +export default ExtLinkTool; \ No newline at end of file diff --git a/packages/jats/ext-link/package.js b/packages/jats/ext-link/package.js index 22efa46b9..94be87aac 100644 --- a/packages/jats/ext-link/package.js +++ b/packages/jats/ext-link/package.js @@ -1,14 +1,13 @@ 'use strict'; -var ExtLink = require('./ExtLink'); -var ExtLinkConverter = require('./ExtLinkConverter'); -var ExtLinkComponent = require('./ExtLinkComponent'); -var ExtLinkTool = require('./ExtLinkTool'); -var ExtLinkCommand = require('./ExtLinkCommand'); -var EditExtLinkTool = require('./EditExtLinkTool'); +import ExtLink from './ExtLink' +import ExtLinkConverter from './ExtLinkConverter' +import ExtLinkComponent from './ExtLinkComponent' +import ExtLinkTool from './ExtLinkTool' +import ExtLinkCommand from './ExtLinkCommand' +import EditExtLinkTool from './EditExtLinkTool' - -module.exports = { +export default { name: 'ext-link', configure: function(config) { config.addNode(ExtLink); @@ -24,4 +23,4 @@ module.exports = { en: 'Link' }); } -}; +} diff --git a/packages/jats/figure/Figure.js b/packages/jats/figure/Figure.js index f3473ccef..8f85d5c26 100644 --- a/packages/jats/figure/Figure.js +++ b/packages/jats/figure/Figure.js @@ -1,6 +1,6 @@ 'use strict'; -var DocumentNode = require('substance/model/DocumentNode'); +import { DocumentNode } from 'substance' function Figure() { Figure.super.apply(this, arguments); @@ -48,4 +48,4 @@ Figure.define({ permissions: { type: ['permissions'], default: [] }, }); -module.exports = Figure; +export default Figure; diff --git a/packages/jats/figure/FigureComponent.js b/packages/jats/figure/FigureComponent.js index ed2da7279..e58f13566 100644 --- a/packages/jats/figure/FigureComponent.js +++ b/packages/jats/figure/FigureComponent.js @@ -1,7 +1,7 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var renderNodeComponent = require('../../../util/renderNodeComponent'); +import { Component } from 'substance' +import renderNodeComponent from '../../../util/renderNodeComponent' function FigureComponent() { Component.apply(this, arguments); @@ -54,4 +54,4 @@ FigureComponent.Prototype = function() { Component.extend(FigureComponent); -module.exports = FigureComponent; \ No newline at end of file +export default FigureComponent; \ No newline at end of file diff --git a/packages/jats/figure/FigureConverter.js b/packages/jats/figure/FigureConverter.js index 328a27a4a..9e18acd0e 100644 --- a/packages/jats/figure/FigureConverter.js +++ b/packages/jats/figure/FigureConverter.js @@ -1,7 +1,7 @@ 'use strict'; -var JATS = require('../JATS'); -var XMLIterator = require('../../../util/XMLIterator'); +import JATS from '../JATS' +import XMLIterator from '../../../util/XMLIterator' var ACCESS_OR_LINK = JATS.ACCESS.concat(JATS.ADDRESS_LINK); var FIGURE_CONTENT = JATS.BLOCK_MATH @@ -12,7 +12,7 @@ var FIGURE_CONTENT = JATS.BLOCK_MATH .concat(JATS.LIST) .concat(JATS.SIMPLE_DISPLAY); -module.exports = { +export default { type: 'figure', tagName: 'fig', diff --git a/packages/jats/figure/FigureTarget.js b/packages/jats/figure/FigureTarget.js index ed9780a5e..25011584a 100644 --- a/packages/jats/figure/FigureTarget.js +++ b/packages/jats/figure/FigureTarget.js @@ -1,7 +1,7 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var renderNodeComponent = require('../../../util/renderNodeComponent'); +import { Component } from 'substance' +import renderNodeComponent from '../../../util/renderNodeComponent' /* Renders a keyboard-selectable figure target item @@ -74,4 +74,4 @@ FigureTarget.Prototype = function() { Component.extend(FigureTarget); -module.exports = FigureTarget; \ No newline at end of file +export default FigureTarget; \ No newline at end of file diff --git a/packages/jats/figure/package.js b/packages/jats/figure/package.js index 389b1d4d7..b2eb2c834 100644 --- a/packages/jats/figure/package.js +++ b/packages/jats/figure/package.js @@ -1,11 +1,11 @@ 'use strict'; -var Figure = require('./Figure'); -var FigureComponent = require('./FigureComponent'); -var FigureTarget = require('./FigureTarget'); -var FigureConverter = require('./FigureConverter'); +import Figure from './Figure' +import FigureComponent from './FigureComponent' +import FigureTarget from './FigureTarget' +import FigureConverter from './FigureConverter' -module.exports = { +export default { name: 'figure', configure: function(config) { config.addNode(Figure); diff --git a/packages/jats/footnote/Footnote.js b/packages/jats/footnote/Footnote.js index 592175111..db05a46c7 100644 --- a/packages/jats/footnote/Footnote.js +++ b/packages/jats/footnote/Footnote.js @@ -1,6 +1,6 @@ 'use strict'; -var Container = require('substance/model/Container'); +import { Container } from 'substance' function Footnote() { Footnote.super.apply(this, arguments); @@ -20,4 +20,4 @@ Footnote.define({ nodes: { type: ['p'], default: [] } }); -module.exports = Footnote; +export default Footnote; diff --git a/packages/jats/footnote/FootnoteComponent.js b/packages/jats/footnote/FootnoteComponent.js index 2633c8714..2735ed11a 100644 --- a/packages/jats/footnote/FootnoteComponent.js +++ b/packages/jats/footnote/FootnoteComponent.js @@ -1,8 +1,7 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var TextProperty = require('substance/ui/TextPropertyComponent'); -var renderNodeComponent = require('../../../util/renderNodeComponent'); +import { Component, TextPropertyComponent } from 'substance' +import renderNodeComponent from '../../../util/renderNodeComponent' function FootnoteComponent() { Component.apply(this, arguments); @@ -20,7 +19,7 @@ FootnoteComponent.Prototype = function() { if (node.label) { var label = doc.get(node.label); - el.append($$(TextProperty, { + el.append($$(TextPropertyComponent, { path: label.getTextPath() })); } @@ -41,4 +40,4 @@ FootnoteComponent.Prototype = function() { Component.extend(FootnoteComponent); -module.exports = FootnoteComponent; \ No newline at end of file +export default FootnoteComponent; \ No newline at end of file diff --git a/packages/jats/footnote/FootnoteConverter.js b/packages/jats/footnote/FootnoteConverter.js index 97ce66147..490dce6cd 100644 --- a/packages/jats/footnote/FootnoteConverter.js +++ b/packages/jats/footnote/FootnoteConverter.js @@ -1,8 +1,8 @@ 'use strict'; -var XMLIterator = require('../../../util/XMLIterator'); +import XMLIterator from '../../../util/XMLIterator' -module.exports = { +export default { type: 'footnote', tagName: 'fn', diff --git a/packages/jats/footnote/package.js b/packages/jats/footnote/package.js index 78cc8b78c..ba0a41496 100644 --- a/packages/jats/footnote/package.js +++ b/packages/jats/footnote/package.js @@ -1,10 +1,10 @@ 'use strict'; -var Footnote = require('./Footnote'); -var FootnoteComponent = require('./FootnoteComponent'); -var FootnoteConverter = require('./FootnoteConverter'); +import Footnote from './Footnote' +import FootnoteComponent from './FootnoteComponent' +import FootnoteConverter from './FootnoteConverter' -module.exports = { +export default { name: 'footnote', configure: function(config) { config.addNode(Footnote); diff --git a/packages/jats/front/Front.js b/packages/jats/front/Front.js index 31d0fdb6c..7db1df702 100644 --- a/packages/jats/front/Front.js +++ b/packages/jats/front/Front.js @@ -1,6 +1,6 @@ 'use strict'; -var Container = require('substance/model/Container'); +import { Container } from 'substance' function Front() { Front.super.apply(this, arguments); @@ -25,4 +25,4 @@ Front.define({ nodes: { type: ['id'], default: [] } }); -module.exports = Front; +export default Front; diff --git a/packages/jats/front/FrontComponent.js b/packages/jats/front/FrontComponent.js index ab121b895..a89ad5563 100644 --- a/packages/jats/front/FrontComponent.js +++ b/packages/jats/front/FrontComponent.js @@ -1,7 +1,7 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var renderNodeComponent = require('../../../util/renderNodeComponent'); +import { Component } from 'substance' +import renderNodeComponent from '../../../util/renderNodeComponent' function FrontComponent() { Component.apply(this, arguments); @@ -32,4 +32,4 @@ FrontComponent.Prototype = function() { Component.extend(FrontComponent); -module.exports = FrontComponent; \ No newline at end of file +export default FrontComponent; \ No newline at end of file diff --git a/packages/jats/front/FrontConverter.js b/packages/jats/front/FrontConverter.js index 65fe5ec61..d8f058ac4 100644 --- a/packages/jats/front/FrontConverter.js +++ b/packages/jats/front/FrontConverter.js @@ -1,10 +1,10 @@ 'use strict'; -var XMLIterator = require('../../../util/XMLIterator'); +import XMLIterator from '../../../util/XMLIterator' var FRONT_CONTENT = ['def-list', 'list', 'ack', 'bio', 'fn-group', 'glossary', 'notes']; -module.exports = { +export default { type: 'front', tagName: 'front', diff --git a/packages/jats/front/package.js b/packages/jats/front/package.js index 1c54879c6..e01eaa4bc 100644 --- a/packages/jats/front/package.js +++ b/packages/jats/front/package.js @@ -1,10 +1,10 @@ 'use strict'; -var Front = require('./Front'); -var FrontConverter = require('./FrontConverter'); -var FrontComponent = require('./FrontComponent'); +import Front from './Front' +import FrontConverter from './FrontConverter' +import FrontComponent from './FrontComponent' -module.exports = { +export default { name: 'front', configure: function(config) { config.addNode(Front); diff --git a/packages/jats/graphic/Graphic.js b/packages/jats/graphic/Graphic.js index d987188c5..40925b161 100644 --- a/packages/jats/graphic/Graphic.js +++ b/packages/jats/graphic/Graphic.js @@ -1,6 +1,6 @@ 'use strict'; -var Container = require('substance/model/Container'); +import { Container } from 'substance' function Graphic() { Graphic.super.apply(this, arguments); @@ -22,4 +22,4 @@ Graphic.define({ attributes: { type: 'object', default: {} }, }); -module.exports = Graphic; \ No newline at end of file +export default Graphic; \ No newline at end of file diff --git a/packages/jats/graphic/GraphicComponent.js b/packages/jats/graphic/GraphicComponent.js index 8970a431c..c5f5ce869 100644 --- a/packages/jats/graphic/GraphicComponent.js +++ b/packages/jats/graphic/GraphicComponent.js @@ -1,6 +1,6 @@ 'use strict'; -var Component = require('substance/ui/Component'); +import { Component } from 'substance' function GraphicComponent() { Component.apply(this, arguments); @@ -24,4 +24,4 @@ GraphicComponent.Prototype = function() { Component.extend(GraphicComponent); -module.exports = GraphicComponent; \ No newline at end of file +export default GraphicComponent; \ No newline at end of file diff --git a/packages/jats/graphic/GraphicConverter.js b/packages/jats/graphic/GraphicConverter.js index fe912ef93..343b97dc3 100644 --- a/packages/jats/graphic/GraphicConverter.js +++ b/packages/jats/graphic/GraphicConverter.js @@ -1,14 +1,14 @@ 'use strict'; -var JATS = require('../JATS'); -var XMLIterator = require('../../../util/XMLIterator'); +import JATS from '../JATS' +import XMLIterator from '../../../util/XMLIterator' var GRAPHIC_ELEMENTS = JATS.ACCESS .concat(JATS.ADDRESS_LINK) .concat(['caption', 'object-id', 'kwd-group', 'label']) .concat(JATS.DISPLAY_BACK_MATTER); -module.exports = { +export default { type: 'graphic', tagName: 'graphic', diff --git a/packages/jats/graphic/package.js b/packages/jats/graphic/package.js index 3cb587702..d3d156619 100644 --- a/packages/jats/graphic/package.js +++ b/packages/jats/graphic/package.js @@ -1,10 +1,10 @@ 'use strict'; -var Graphic = require('./Graphic'); -var GraphicComponent = require('./GraphicComponent'); -var GraphicConverter = require('./GraphicConverter'); +import Graphic from './Graphic' +import GraphicComponent from './GraphicComponent' +import GraphicConverter from './GraphicConverter' -module.exports = { +export default { name: 'graphic', configure: function(config) { config.addNode(Graphic); diff --git a/packages/jats/italic/Italic.js b/packages/jats/italic/Italic.js index 512efecaa..dc6822ed9 100644 --- a/packages/jats/italic/Italic.js +++ b/packages/jats/italic/Italic.js @@ -1,6 +1,6 @@ 'use strict'; -var Annotation = require('substance/model/Annotation'); +import { Annotation } from 'substance' function Italic() { Italic.super.apply(this, arguments); @@ -14,4 +14,4 @@ Italic.define({ attributes: { type: 'object', default: {} }, }); -module.exports = Italic; +export default Italic; diff --git a/packages/jats/italic/ItalicConverter.js b/packages/jats/italic/ItalicConverter.js index c69dd8a64..612174da1 100644 --- a/packages/jats/italic/ItalicConverter.js +++ b/packages/jats/italic/ItalicConverter.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports = { +export default { type: 'italic', tagName: 'italic' }; diff --git a/packages/jats/italic/package.js b/packages/jats/italic/package.js index 1e1118aaf..242af3831 100644 --- a/packages/jats/italic/package.js +++ b/packages/jats/italic/package.js @@ -1,9 +1,9 @@ 'use strict'; -var Italic = require('./Italic'); -var ItalicConverter = require('./ItalicConverter'); +import Italic from './Italic' +import ItalicConverter from './ItalicConverter' -module.exports = { +export default { name: 'italic', configure: function(config) { config.addNode(Italic); diff --git a/packages/jats/label/Label.js b/packages/jats/label/Label.js index c5ccd6845..8ef816ffb 100644 --- a/packages/jats/label/Label.js +++ b/packages/jats/label/Label.js @@ -1,6 +1,6 @@ 'use strict'; -var TextNode = require('substance/model/TextNode'); +import { TextNode } from 'substance' function Label() { Label.super.apply(this, arguments); @@ -14,4 +14,4 @@ Label.define({ attributes: { type: 'object', default: {} }, }); -module.exports = Label; \ No newline at end of file +export default Label; \ No newline at end of file diff --git a/packages/jats/label/LabelComponent.js b/packages/jats/label/LabelComponent.js index 0f00c95de..0e0d919e5 100644 --- a/packages/jats/label/LabelComponent.js +++ b/packages/jats/label/LabelComponent.js @@ -1,7 +1,6 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var TextPropertyEditor = require('substance/ui/TextPropertyEditor'); +import { Component, TextPropertyEditor } from 'substance' function LabelComponent() { LabelComponent.super.apply(this, arguments); @@ -23,4 +22,4 @@ LabelComponent.Prototype = function() { Component.extend(LabelComponent); -module.exports = LabelComponent; \ No newline at end of file +export default LabelComponent; \ No newline at end of file diff --git a/packages/jats/label/LabelConverter.js b/packages/jats/label/LabelConverter.js index b6fb8d49e..7db7aac5f 100644 --- a/packages/jats/label/LabelConverter.js +++ b/packages/jats/label/LabelConverter.js @@ -1,8 +1,8 @@ 'use strict'; -var TextNodeConverter = require('../TextNodeConverter'); +import TextNodeConverter from '../TextNodeConverter' -module.exports = TextNodeConverter.extend({ +export default TextNodeConverter.extend({ type: 'label', tagName: 'label', }); diff --git a/packages/jats/label/package.js b/packages/jats/label/package.js index b8b51d61d..889029c12 100644 --- a/packages/jats/label/package.js +++ b/packages/jats/label/package.js @@ -1,10 +1,10 @@ 'use strict'; -var Label = require('./Label'); -var LabelConverter = require('./LabelConverter'); -var LabelComponent = require('./LabelComponent'); +import Label from './Label' +import LabelConverter from './LabelConverter' +import LabelComponent from './LabelComponent' -module.exports = { +export default { name: 'label', configure: function(config) { config.addNode(Label); diff --git a/packages/jats/monospace/Monospace.js b/packages/jats/monospace/Monospace.js index 98b0dac75..a966a9c9c 100644 --- a/packages/jats/monospace/Monospace.js +++ b/packages/jats/monospace/Monospace.js @@ -1,6 +1,6 @@ 'use strict'; -var Annotation = require('substance/model/Annotation'); +import { Annotation } from 'substance' function Monospace() { Monospace.super.apply(this, arguments); @@ -14,4 +14,4 @@ Monospace.define({ attributes: { type: 'object', default: {} }, }); -module.exports = Monospace; +export default Monospace; diff --git a/packages/jats/monospace/MonospaceConverter.js b/packages/jats/monospace/MonospaceConverter.js index c8664652a..052d6673b 100644 --- a/packages/jats/monospace/MonospaceConverter.js +++ b/packages/jats/monospace/MonospaceConverter.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports = { +export default { type: 'monospace', tagName: 'monospace' }; diff --git a/packages/jats/monospace/package.js b/packages/jats/monospace/package.js index ef0ed4340..5d02251ff 100644 --- a/packages/jats/monospace/package.js +++ b/packages/jats/monospace/package.js @@ -1,9 +1,9 @@ 'use strict'; -var Monospace = require('./Monospace'); -var MonospaceConverter = require('./MonospaceConverter'); +import Monospace from './Monospace' +import MonospaceConverter from './MonospaceConverter' -module.exports = { +export default { name: 'monospace', configure: function(config) { config.addNode(Monospace); diff --git a/packages/jats/package.js b/packages/jats/package.js index fb39f336b..58658141f 100644 --- a/packages/jats/package.js +++ b/packages/jats/package.js @@ -1,41 +1,69 @@ -'use strict'; +import JATSImporter from './JATSImporter' +import JATSExporter from './JATSExporter' -var JATSImporter = require('./JATSImporter'); -var JATSExporter = require('./JATSExporter'); +import AffPackage from './aff/package' +import ArticlePackage from './article/package' +import ArticleMetaPackage from './article-meta/package' +import ArticleTitlePackage from './article-title/package' +import ContribPackage from './contrib/package' +import ContribGroupPackage from './contrib-group/package' +import BackPackage from './back/package' +import BodyPackage from './body/package' +import BoldPackage from './bold/package' +import CaptionPackage from './caption/package' +import ExtLinkPackage from './ext-link/package' +import FigurePackage from './figure/package' +import FootnotePackage from './footnote/package' +import FrontPackage from './front/package' +import GraphicPackage from './graphic/package' +import ItalicPackage from './italic/package' +import LabelPackage from './label/package' +import MonospacePackage from './monospace/package' +import ParagraphPackage from './paragraph/package' +import RefPackage from './ref/package' +import RefListPackage from './ref-list/package' +import SectionPackage from './section/package' +import SubscriptPackage from './subscript/package' +import SuperscriptPackage from './superscript/package' +import TablePackage from './table/package' +import TitlePackage from './title/package' +import TitleGroupPackage from './title-group/package' +import XrefPackage from './xref/package' -module.exports = { + +export default { name: 'jats', configure: function(config) { - config.import(require('./aff/package')); - config.import(require('./article/package')); - config.import(require('./article-meta/package')); - config.import(require('./title-group/package')); - config.import(require('./article-title/package')); - config.import(require('./contrib-group/package')); - config.import(require('./contrib/package')); - config.import(require('./back/package')); - config.import(require('./body/package')); - config.import(require('./bold/package')); - config.import(require('./caption/package')); - config.import(require('./xref/package')); - config.import(require('./ext-link/package')); - config.import(require('./figure/package')); - config.import(require('./footnote/package')); - config.import(require('./front/package')); - config.import(require('./graphic/package')); - config.import(require('./italic/package')); - config.import(require('./label/package')); - config.import(require('./monospace/package')); - config.import(require('./paragraph/package')); - config.import(require('./ref/package')); - config.import(require('./ref-list/package')); - config.import(require('./section/package')); - config.import(require('./subscript/package')); - config.import(require('./superscript/package')); - config.import(require('./table/package')); - config.import(require('./title/package')); + config.import(AffPackage) + config.import(ArticlePackage) + config.import(ArticleMetaPackage) + config.import(ArticleTitlePackage) + config.import(ContribPackage) + config.import(ContribGroupPackage) + config.import(BackPackage) + config.import(BodyPackage) + config.import(BoldPackage) + config.import(CaptionPackage) + config.import(ExtLinkPackage) + config.import(FigurePackage) + config.import(FootnotePackage) + config.import(FrontPackage) + config.import(GraphicPackage) + config.import(ItalicPackage) + config.import(LabelPackage) + config.import(MonospacePackage) + config.import(ParagraphPackage) + config.import(RefPackage) + config.import(RefListPackage) + config.import(SectionPackage) + config.import(SubscriptPackage) + config.import(SuperscriptPackage) + config.import(TablePackage) + config.import(TitlePackage) + config.import(TitleGroupPackage) + config.import(XrefPackage) config.addImporter('jats', JATSImporter); config.addExporter('jats', JATSExporter); } -}; \ No newline at end of file +} diff --git a/packages/jats/paragraph/Paragraph.js b/packages/jats/paragraph/Paragraph.js index c79f71692..6394d9012 100644 --- a/packages/jats/paragraph/Paragraph.js +++ b/packages/jats/paragraph/Paragraph.js @@ -1,6 +1,6 @@ 'use strict'; -var TextBlock = require('substance/model/TextBlock'); +import { TextBlock } from 'substance' function ParagraphNode() { ParagraphNode.super.apply(this, arguments); @@ -14,4 +14,4 @@ ParagraphNode.define({ attributes: { type: 'object', default: {} }, }); -module.exports = ParagraphNode; +export default ParagraphNode; diff --git a/packages/jats/paragraph/ParagraphComponent.js b/packages/jats/paragraph/ParagraphComponent.js index 1b4efce0e..f8643db78 100644 --- a/packages/jats/paragraph/ParagraphComponent.js +++ b/packages/jats/paragraph/ParagraphComponent.js @@ -1,6 +1,6 @@ 'use strict'; -var TextBlockComponent = require('substance/ui/TextBlockComponent'); +import { TextBlockComponent } from 'substance' function ParagraphComponent() { ParagraphComponent.super.apply(this, arguments); @@ -16,4 +16,4 @@ ParagraphComponent.Prototype = function() { TextBlockComponent.extend(ParagraphComponent); -module.exports = ParagraphComponent; +export default ParagraphComponent; diff --git a/packages/jats/paragraph/ParagraphConverter.js b/packages/jats/paragraph/ParagraphConverter.js index 4821b2ef7..2332ae698 100644 --- a/packages/jats/paragraph/ParagraphConverter.js +++ b/packages/jats/paragraph/ParagraphConverter.js @@ -1,8 +1,8 @@ 'use strict'; -var TextNodeConverter = require('../TextNodeConverter'); +import TextNodeConverter from '../TextNodeConverter' -module.exports = TextNodeConverter.extend({ +export default TextNodeConverter.extend({ type: 'paragraph', tagName: 'p', }); diff --git a/packages/jats/paragraph/package.js b/packages/jats/paragraph/package.js index f53b5d300..c0ff2c74d 100644 --- a/packages/jats/paragraph/package.js +++ b/packages/jats/paragraph/package.js @@ -1,10 +1,10 @@ 'use strict'; -var Paragraph = require('./Paragraph'); -var ParagraphComponent = require('./ParagraphComponent'); -var ParagraphConverter = require('./ParagraphConverter'); +import Paragraph from './Paragraph' +import ParagraphComponent from './ParagraphComponent' +import ParagraphConverter from './ParagraphConverter' -module.exports = { +export default { name: 'paragraph', diff --git a/packages/jats/ref-list/RefList.js b/packages/jats/ref-list/RefList.js index f57eefb94..6bd63c7e0 100644 --- a/packages/jats/ref-list/RefList.js +++ b/packages/jats/ref-list/RefList.js @@ -1,6 +1,6 @@ 'use strict'; -var Container = require('substance/model/Container'); +import { Container } from 'substance' /* ref-list @@ -36,4 +36,4 @@ RefList.define({ nodes: { type: ['id'], default: [] }, }); -module.exports = RefList; +export default RefList; diff --git a/packages/jats/ref-list/RefListComponent.js b/packages/jats/ref-list/RefListComponent.js index 9ae93f5ea..c6aca6e10 100644 --- a/packages/jats/ref-list/RefListComponent.js +++ b/packages/jats/ref-list/RefListComponent.js @@ -1,7 +1,7 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var renderNodeComponent = require('../../../util/renderNodeComponent'); +import { Component } from 'substance' +import renderNodeComponent from '../../../util/renderNodeComponent' class RefListComponent extends Component { didMount() { @@ -54,4 +54,4 @@ class RefListComponent extends Component { RefListComponent.fullWidth = true; RefListComponent.noStyle = true; -module.exports = RefListComponent; \ No newline at end of file +export default RefListComponent; \ No newline at end of file diff --git a/packages/jats/ref-list/RefListConverter.js b/packages/jats/ref-list/RefListConverter.js index b36bdcb90..4565df720 100644 --- a/packages/jats/ref-list/RefListConverter.js +++ b/packages/jats/ref-list/RefListConverter.js @@ -1,11 +1,11 @@ 'use strict'; -var JATS = require('../JATS'); -var XMLIterator = require('../../../util/XMLIterator'); +import JATS from '../JATS' +import XMLIterator from '../../../util/XMLIterator' var REFLIST_CONTENT = ['ref', 'ref-list'].concat(JATS.PARA_LEVEL); -module.exports = { +export default { type: 'ref-list', tagName: 'ref-list', diff --git a/packages/jats/ref-list/package.js b/packages/jats/ref-list/package.js index a1d825c00..6523bdfb9 100644 --- a/packages/jats/ref-list/package.js +++ b/packages/jats/ref-list/package.js @@ -1,10 +1,10 @@ 'use strict'; -var RefList = require('./RefList'); -var RefListConverter = require('./RefListConverter'); -var RefListComponent = require('./RefListComponent'); +import RefList from './RefList' +import RefListConverter from './RefListConverter' +import RefListComponent from './RefListComponent' -module.exports = { +export default { name: 'ref-list', configure: function(config) { config.addNode(RefList); diff --git a/packages/jats/ref/Ref.js b/packages/jats/ref/Ref.js index eea87d84d..529a2bd3d 100644 --- a/packages/jats/ref/Ref.js +++ b/packages/jats/ref/Ref.js @@ -1,7 +1,6 @@ 'use strict'; -var DocumentNode = require('substance/model/DocumentNode'); -var DOMElement = require('substance/ui/DefaultDOMElement'); +import { DocumentNode, DefaultDOMElement as DOMElement } from 'substance' /* ref @@ -43,4 +42,4 @@ Ref.define({ xmlContent: {type: 'string', default: ''} }); -module.exports = Ref; +export default Ref; diff --git a/packages/jats/ref/RefComponent.js b/packages/jats/ref/RefComponent.js index bf4a9edee..85ffc66fb 100644 --- a/packages/jats/ref/RefComponent.js +++ b/packages/jats/ref/RefComponent.js @@ -1,7 +1,7 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var refToHTML = require('./refToHTML'); +import { Component } from 'substance' +import refToHTML from './refToHTML' function RefComponent() { @@ -22,4 +22,4 @@ Component.extend(RefComponent); RefComponent.fullWidth = true; RefComponent.noStyle = true; -module.exports = RefComponent; +export default RefComponent; diff --git a/packages/jats/ref/RefConverter.js b/packages/jats/ref/RefConverter.js index 49c63c1ff..190f61ac9 100644 --- a/packages/jats/ref/RefConverter.js +++ b/packages/jats/ref/RefConverter.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports = { +export default { type: 'ref', tagName: 'ref', diff --git a/packages/jats/ref/RefTarget.js b/packages/jats/ref/RefTarget.js index 5faf6e25d..7fd7278be 100644 --- a/packages/jats/ref/RefTarget.js +++ b/packages/jats/ref/RefTarget.js @@ -1,7 +1,7 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var refToHTML = require('./refToHTML'); +import { Component } from 'substance' +import refToHTML from './refToHTML' /* Renders a keyboard-selectable ref target item @@ -28,4 +28,4 @@ RefTarget.Prototype = function() { Component.extend(RefTarget); -module.exports = RefTarget; \ No newline at end of file +export default RefTarget; \ No newline at end of file diff --git a/packages/jats/ref/package.js b/packages/jats/ref/package.js index 3ae8bcbda..91b74694f 100644 --- a/packages/jats/ref/package.js +++ b/packages/jats/ref/package.js @@ -1,13 +1,11 @@ -'use strict'; +import Ref from './Ref' +import RefComponent from './RefComponent' +import RefTarget from './RefTarget' +import RefConverter from './RefConverter' +import TagRefCommand from './TagRefCommand' +import TagRefTool from './TagRefTool' -var Ref = require('./Ref'); -var RefComponent = require('./RefComponent'); -var RefTarget = require('./RefTarget'); -var RefConverter = require('./RefConverter'); -var TagRefCommand = require('./TagRefCommand'); -var TagRefTool = require('./TagRefTool'); - -module.exports = { +export default { name: 'ref', configure: function(config) { config.addNode(Ref); @@ -18,4 +16,4 @@ module.exports = { config.addTool('tag-ref', TagRefTool); config.addIcon('tag-ref', { 'fontawesome': 'fa-bullseye' }); } -}; \ No newline at end of file +} diff --git a/packages/jats/ref/refToHTML.js b/packages/jats/ref/refToHTML.js index 3862576bc..a9ffe4322 100644 --- a/packages/jats/ref/refToHTML.js +++ b/packages/jats/ref/refToHTML.js @@ -1,6 +1,6 @@ 'use strict'; -var DOMElement = require('substance/ui/DefaultDOMElement'); +import { DefaultDOMElement as DOMElement } from 'substance' /* TODO: Get rid of HTML renderer. Instead extract data as @@ -162,4 +162,4 @@ var refToHTML = function (ref) { }; -module.exports = refToHTML; \ No newline at end of file +export default refToHTML; \ No newline at end of file diff --git a/packages/jats/section/Section.js b/packages/jats/section/Section.js index d042244fb..359bb683c 100644 --- a/packages/jats/section/Section.js +++ b/packages/jats/section/Section.js @@ -1,6 +1,6 @@ 'use strict'; -var Container = require('substance/model/Container'); +import { Container } from 'substance' function Section() { Section.super.apply(this, arguments); @@ -42,5 +42,5 @@ Section.define({ backMatter: { type: ['id'], default: [] } }); -module.exports = Section; +export default Section; diff --git a/packages/jats/section/SectionComponent.js b/packages/jats/section/SectionComponent.js index 45acb4f76..3828657b4 100644 --- a/packages/jats/section/SectionComponent.js +++ b/packages/jats/section/SectionComponent.js @@ -1,8 +1,6 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var TextPropertyEditor = require('substance/ui/TextPropertyEditor'); -var ContainerEditor = require('substance/ui/ContainerEditor'); +import { Component, ContainerEditor, TextPropertyEditor } from 'substance' function SectionComponent() { SectionComponent.super.apply(this, arguments); @@ -35,4 +33,4 @@ Component.extend(SectionComponent); SectionComponent.fullWidth = true; SectionComponent.noStyle = true; -module.exports = SectionComponent; +export default SectionComponent; diff --git a/packages/jats/section/SectionConverter.js b/packages/jats/section/SectionConverter.js index 9ea155dbd..89a8e5b71 100644 --- a/packages/jats/section/SectionConverter.js +++ b/packages/jats/section/SectionConverter.js @@ -1,9 +1,9 @@ 'use strict'; -var JATS = require('../JATS'); -var XMLIterator = require('../../../util/XMLIterator'); +import JATS from '../JATS' +import XMLIterator from '../../../util/XMLIterator' -module.exports = { +export default { type: 'section', tagName: 'sec', diff --git a/packages/jats/section/package.js b/packages/jats/section/package.js index 85af81a9a..9fb0eb2a2 100644 --- a/packages/jats/section/package.js +++ b/packages/jats/section/package.js @@ -1,10 +1,10 @@ 'use strict'; -var Section = require('./Section'); -var SectionComponent = require('./SectionComponent'); -var SectionConverter = require('./SectionConverter'); +import Section from './Section' +import SectionComponent from './SectionComponent' +import SectionConverter from './SectionConverter' -module.exports = { +export default { name: 'section', configure: function(config) { config.addNode(Section); diff --git a/packages/jats/subscript/Subscript.js b/packages/jats/subscript/Subscript.js index c08fc1994..ed6b3a5a6 100644 --- a/packages/jats/subscript/Subscript.js +++ b/packages/jats/subscript/Subscript.js @@ -1,6 +1,6 @@ 'use strict'; -var Annotation = require('substance/model/Annotation'); +import { Annotation } from 'substance' function Subscript() { Subscript.super.apply(this, arguments); @@ -14,4 +14,4 @@ Subscript.define({ attributes: { type: 'object', default: {} }, }); -module.exports = Subscript; +export default Subscript; diff --git a/packages/jats/subscript/SubscriptConverter.js b/packages/jats/subscript/SubscriptConverter.js index 4b87f83f4..691dbd572 100644 --- a/packages/jats/subscript/SubscriptConverter.js +++ b/packages/jats/subscript/SubscriptConverter.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports = { +export default { type: 'subscript', tagName: 'sub' }; diff --git a/packages/jats/subscript/package.js b/packages/jats/subscript/package.js index 4ea6f25b7..44dcbbf93 100644 --- a/packages/jats/subscript/package.js +++ b/packages/jats/subscript/package.js @@ -1,9 +1,9 @@ 'use strict'; -var Subscript = require('./Subscript'); -var SubscriptConverter = require('./SubscriptConverter'); +import Subscript from './Subscript' +import SubscriptConverter from './SubscriptConverter' -module.exports = { +export default { name: 'subscript', configure: function(config) { config.addNode(Subscript); diff --git a/packages/jats/superscript/Superscript.js b/packages/jats/superscript/Superscript.js index 71ea5e54c..2d54af3e6 100644 --- a/packages/jats/superscript/Superscript.js +++ b/packages/jats/superscript/Superscript.js @@ -1,6 +1,6 @@ 'use strict'; -var Annotation = require('substance/model/Annotation'); +import { Annotation } from 'substance' function Superscript() { Superscript.super.apply(this, arguments); @@ -14,4 +14,4 @@ Superscript.define({ attributes: { type: 'object', default: {} }, }); -module.exports = Superscript; +export default Superscript; diff --git a/packages/jats/superscript/SuperscriptConverter.js b/packages/jats/superscript/SuperscriptConverter.js index 51a1d369a..d4490cb94 100644 --- a/packages/jats/superscript/SuperscriptConverter.js +++ b/packages/jats/superscript/SuperscriptConverter.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports = { +export default { type: 'superscript', tagName: 'sup' }; diff --git a/packages/jats/superscript/package.js b/packages/jats/superscript/package.js index 148407320..07f2c887d 100644 --- a/packages/jats/superscript/package.js +++ b/packages/jats/superscript/package.js @@ -1,9 +1,9 @@ 'use strict'; -var Superscript = require('./Superscript'); -var SuperscriptConverter = require('./SuperscriptConverter'); +import Superscript from './Superscript' +import SuperscriptConverter from './SuperscriptConverter' -module.exports = { +export default { name: 'superscript', configure: function(config) { config.addNode(Superscript); diff --git a/packages/jats/table-wrap/TableWrap.js b/packages/jats/table-wrap/TableWrap.js index c16e60850..94f594386 100644 --- a/packages/jats/table-wrap/TableWrap.js +++ b/packages/jats/table-wrap/TableWrap.js @@ -1,6 +1,6 @@ 'use strict'; -var Figure = require('../figure/Figure'); +import Figure from '../figure/Figure' function TableWrap() { TableWrap.super.apply(this, arguments); @@ -10,4 +10,4 @@ Figure.extend(TableWrap); TableWrap.type = 'table-wrap'; -module.exports = TableWrap; \ No newline at end of file +export default TableWrap; \ No newline at end of file diff --git a/packages/jats/table-wrap/TableWrapComponent.js b/packages/jats/table-wrap/TableWrapComponent.js index 59b65920a..2ef33a794 100644 --- a/packages/jats/table-wrap/TableWrapComponent.js +++ b/packages/jats/table-wrap/TableWrapComponent.js @@ -1,6 +1,6 @@ 'use strict'; -var FigureComponent = require('../figure/FigureComponent'); +import FigureComponent from '../figure/FigureComponent' function TableWrapComponent() { TableWrapComponent.super.apply(this, arguments); @@ -8,4 +8,4 @@ function TableWrapComponent() { FigureComponent.extend(TableWrapComponent); -module.exports = TableWrapComponent; \ No newline at end of file +export default TableWrapComponent; \ No newline at end of file diff --git a/packages/jats/table-wrap/TableWrapConverter.js b/packages/jats/table-wrap/TableWrapConverter.js index f8737ec55..c58b10e6e 100644 --- a/packages/jats/table-wrap/TableWrapConverter.js +++ b/packages/jats/table-wrap/TableWrapConverter.js @@ -1,8 +1,8 @@ 'use strict'; -var FigureConverter = require('../figure/FigureConverter'); +import FigureConverter from '../figure/FigureConverter' -module.exports = { +export default { type: 'table-wrap', tagName: 'table-wrap', diff --git a/packages/jats/table-wrap/package.js b/packages/jats/table-wrap/package.js index cf94dcdf9..4750a03ae 100644 --- a/packages/jats/table-wrap/package.js +++ b/packages/jats/table-wrap/package.js @@ -1,10 +1,10 @@ 'use strict'; -var TableWrap = require('./TableWrap'); -var TableWrapConverter = require('./TableWrapConverter'); -var TableWrapComponent = require('./TableWrapComponent'); +import TableWrap from './TableWrap' +import TableWrapConverter from './TableWrapConverter' +import TableWrapComponent from './TableWrapComponent' -module.exports = { +export default { name: 'table-wrap', configure: function(config) { config.addNode(TableWrap); diff --git a/packages/jats/table/Table.js b/packages/jats/table/Table.js index 3ac261dd6..68b878e5c 100644 --- a/packages/jats/table/Table.js +++ b/packages/jats/table/Table.js @@ -1,8 +1,6 @@ 'use strict'; -// TODO: we should be able to inherit from JATSNode to share properties. - -var BlockNode = require('substance/model/BlockNode'); +import { BlockNode } from 'substance' function Table() { Table.super.apply(this, arguments); @@ -16,4 +14,4 @@ Table.define({ htmlContent: {type: 'string'} }); -module.exports = Table; \ No newline at end of file +export default Table; \ No newline at end of file diff --git a/packages/jats/table/TableComponent.js b/packages/jats/table/TableComponent.js index 60d8db34f..dd79a590d 100644 --- a/packages/jats/table/TableComponent.js +++ b/packages/jats/table/TableComponent.js @@ -1,6 +1,6 @@ 'use strict'; -var Component = require('substance/ui/Component'); +import { Component } from 'substance' function TableComponent() { Component.apply(this, arguments); @@ -20,4 +20,4 @@ TableComponent.Prototype = function() { Component.extend(TableComponent); -module.exports = TableComponent; \ No newline at end of file +export default TableComponent; \ No newline at end of file diff --git a/packages/jats/table/TableConverter.js b/packages/jats/table/TableConverter.js index e600dc4ee..f4d7203cc 100644 --- a/packages/jats/table/TableConverter.js +++ b/packages/jats/table/TableConverter.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports = { +export default { type: 'table', // Substance node model tagName: 'table', // Used as a matcher diff --git a/packages/jats/table/package.js b/packages/jats/table/package.js index ec855814f..68f9a1242 100644 --- a/packages/jats/table/package.js +++ b/packages/jats/table/package.js @@ -1,10 +1,10 @@ 'use strict'; -var Table = require('./Table'); -var TableComponent = require('./TableComponent'); -var TableConverter = require('./TableConverter'); +import Table from './Table' +import TableComponent from './TableComponent' +import TableConverter from './TableConverter' -module.exports = { +export default { name: 'table', configure: function(config) { config.addNode(Table); diff --git a/packages/jats/title-group/TitleGroup.js b/packages/jats/title-group/TitleGroup.js index 28bbb51f6..435bd6e7d 100644 --- a/packages/jats/title-group/TitleGroup.js +++ b/packages/jats/title-group/TitleGroup.js @@ -1,6 +1,6 @@ 'use strict'; -var Container = require('substance/model/Container'); +import { Container } from 'substance' function TitleGroup() { TitleGroup.super.apply(this, arguments); @@ -22,4 +22,4 @@ TitleGroup.define({ }); -module.exports = TitleGroup; +export default TitleGroup; diff --git a/packages/jats/title-group/TitleGroupComponent.js b/packages/jats/title-group/TitleGroupComponent.js index ba6eed6eb..6bc5b26a9 100644 --- a/packages/jats/title-group/TitleGroupComponent.js +++ b/packages/jats/title-group/TitleGroupComponent.js @@ -1,7 +1,7 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var renderNodeComponent = require('../../../util/renderNodeComponent'); +import { Component } from 'substance' +import renderNodeComponent from '../../../util/renderNodeComponent' function TitleGroupComponent() { Component.apply(this, arguments); @@ -34,4 +34,4 @@ TitleGroupComponent.Prototype = function() { Component.extend(TitleGroupComponent); -module.exports = TitleGroupComponent; \ No newline at end of file +export default TitleGroupComponent; \ No newline at end of file diff --git a/packages/jats/title-group/TitleGroupConverter.js b/packages/jats/title-group/TitleGroupConverter.js index 7cc42edae..df34bfeff 100644 --- a/packages/jats/title-group/TitleGroupConverter.js +++ b/packages/jats/title-group/TitleGroupConverter.js @@ -1,9 +1,9 @@ 'use strict'; -var JATS = require('../JATS'); -var XMLIterator = require('../../../util/XMLIterator'); +import JATS from '../JATS' +import XMLIterator from '../../../util/XMLIterator' -module.exports = { +export default { type: 'title-group', tagName: 'title-group', diff --git a/packages/jats/title-group/package.js b/packages/jats/title-group/package.js index 5e3c8735c..5e46dc34b 100644 --- a/packages/jats/title-group/package.js +++ b/packages/jats/title-group/package.js @@ -1,10 +1,10 @@ 'use strict'; -var TitleGroup = require('./TitleGroup'); -var TitleGroupConverter = require('./TitleGroupConverter'); -var TitleGroupComponent = require('./TitleGroupComponent'); +import TitleGroup from './TitleGroup' +import TitleGroupConverter from './TitleGroupConverter' +import TitleGroupComponent from './TitleGroupComponent' -module.exports = { +export default { name: 'title-group', configure: function(config) { config.addNode(TitleGroup); diff --git a/packages/jats/title/Title.js b/packages/jats/title/Title.js index 297f711d5..6da1f87e8 100644 --- a/packages/jats/title/Title.js +++ b/packages/jats/title/Title.js @@ -1,6 +1,6 @@ 'use strict'; -var TextNode = require('substance/model/TextNode'); +import { TextNode } from 'substance' function Title() { Title.super.apply(this, arguments); @@ -14,4 +14,4 @@ Title.define({ attributes: { type: 'object', default: {} }, }); -module.exports = Title; \ No newline at end of file +export default Title; \ No newline at end of file diff --git a/packages/jats/title/TitleComponent.js b/packages/jats/title/TitleComponent.js index 49a36023d..ab7c9adf9 100644 --- a/packages/jats/title/TitleComponent.js +++ b/packages/jats/title/TitleComponent.js @@ -1,7 +1,6 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var TextPropertyEditor = require('substance/ui/TextPropertyEditor'); +import { Component, TextPropertyEditor } from 'substance' function TitleComponent() { TitleComponent.super.apply(this, arguments); @@ -23,4 +22,4 @@ TitleComponent.Prototype = function() { Component.extend(TitleComponent); -module.exports = TitleComponent; \ No newline at end of file +export default TitleComponent; \ No newline at end of file diff --git a/packages/jats/title/TitleConverter.js b/packages/jats/title/TitleConverter.js index a8ce8276a..567e52784 100644 --- a/packages/jats/title/TitleConverter.js +++ b/packages/jats/title/TitleConverter.js @@ -1,8 +1,8 @@ 'use strict'; -var TextNodeConverter = require('../TextNodeConverter'); +import TextNodeConverter from '../TextNodeConverter' -module.exports = TextNodeConverter.extend({ +export default TextNodeConverter.extend({ type: 'title', tagName: 'title', }); diff --git a/packages/jats/title/package.js b/packages/jats/title/package.js index 34604c052..a4c3f9529 100644 --- a/packages/jats/title/package.js +++ b/packages/jats/title/package.js @@ -1,10 +1,10 @@ 'use strict'; -var Title = require('./Title'); -var TitleConverter = require('./TitleConverter'); -var TitleComponent = require('./TitleComponent'); +import Title from './Title' +import TitleConverter from './TitleConverter' +import TitleComponent from './TitleComponent' -module.exports = { +export default { name: 'title', configure: function(config) { config.addNode(Title); diff --git a/packages/jats/xref/XRef.js b/packages/jats/xref/XRef.js index bfc51e063..6aae350b0 100644 --- a/packages/jats/xref/XRef.js +++ b/packages/jats/xref/XRef.js @@ -1,7 +1,6 @@ 'use strict'; -var InlineNode = require('substance/model/InlineNode'); -var Fragmenter = require('substance/model/Fragmenter'); +import { Fragmenter, InlineNode } from 'substance' function XRef() { XRef.super.apply(this, arguments); @@ -31,4 +30,4 @@ Object.defineProperties(XRef.prototype, { // In presence of overlapping annotations will try to render this as one element XRef.fragmentation = Fragmenter.SHOULD_NOT_SPLIT; -module.exports = XRef; +export default XRef; diff --git a/packages/jats/xref/XRefCommand.js b/packages/jats/xref/XRefCommand.js index 039af43ca..455eb807c 100644 --- a/packages/jats/xref/XRefCommand.js +++ b/packages/jats/xref/XRefCommand.js @@ -1,6 +1,6 @@ 'use strict'; -var InlineNodeCommand = require('substance/ui/InlineNodeCommand'); +import { InlineNodeCommand } from 'substance' function XRefCommand() { XRefCommand.super.apply(this, arguments); @@ -8,4 +8,4 @@ function XRefCommand() { InlineNodeCommand.extend(XRefCommand); -module.exports = XRefCommand; \ No newline at end of file +export default XRefCommand; \ No newline at end of file diff --git a/packages/jats/xref/XRefComponent.js b/packages/jats/xref/XRefComponent.js index 483fcded5..f83475f55 100644 --- a/packages/jats/xref/XRefComponent.js +++ b/packages/jats/xref/XRefComponent.js @@ -1,7 +1,6 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var TextPropertyEditor = require('substance/ui/TextPropertyEditor'); +import { Component, TextPropertyEditor } from 'substance' function XRefComponent() { XRefComponent.super.apply(this, arguments); @@ -28,4 +27,4 @@ XRefComponent.Prototype = function() { Component.extend(XRefComponent); -module.exports = XRefComponent; \ No newline at end of file +export default XRefComponent; \ No newline at end of file diff --git a/packages/jats/xref/XRefConverter.js b/packages/jats/xref/XRefConverter.js index 6cbf1ba3f..3ab48ad0c 100644 --- a/packages/jats/xref/XRefConverter.js +++ b/packages/jats/xref/XRefConverter.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports = { +export default { type: "xref", tagName: "xref", diff --git a/packages/jats/xref/XRefTargets.js b/packages/jats/xref/XRefTargets.js index ce184984b..248ec50ad 100644 --- a/packages/jats/xref/XRefTargets.js +++ b/packages/jats/xref/XRefTargets.js @@ -1,10 +1,10 @@ 'use strict'; -var clone = require('lodash/clone'); -var find = require('lodash/find'); -var without = require('lodash/without'); -var Component = require('substance/ui/Component'); -var getXRefTargets = require('./getXRefTargets'); +import clone from 'lodash/clone' +import find from 'lodash/find' +import without from 'lodash/without' +import { Component } from 'substance' +import getXRefTargets from './getXRefTargets' /* Editing of XRefTargets @@ -84,4 +84,4 @@ XRefTargets.Prototype = function() { Component.extend(XRefTargets); -module.exports = XRefTargets; \ No newline at end of file +export default XRefTargets; \ No newline at end of file diff --git a/packages/jats/xref/XRefTool.js b/packages/jats/xref/XRefTool.js index 863f61d1c..3bfa73b2f 100644 --- a/packages/jats/xref/XRefTool.js +++ b/packages/jats/xref/XRefTool.js @@ -1,11 +1,8 @@ 'use strict'; -var Tool = require('substance/ui/Tool'); -var clone = require('lodash/clone'); -var Modal = require('substance/ui/Modal'); -var XRefTargets = require('./XRefTargets'); -var Prompt = require('substance/ui/Prompt'); -var deleteSelection = require('substance/model/transform/deleteSelection'); +import clone from 'lodash/clone' +import { deleteSelection, Modal, Prompt, Tool } from 'substance' +import XRefTargets from './XRefTargets' /* Edit a reference in a prompt. @@ -81,4 +78,4 @@ XRefTool.getProps = function(commandStates) { } }; -module.exports = XRefTool; +export default XRefTool; diff --git a/packages/jats/xref/getXRefTargets.js b/packages/jats/xref/getXRefTargets.js index 4f001b5aa..14aac3347 100644 --- a/packages/jats/xref/getXRefTargets.js +++ b/packages/jats/xref/getXRefTargets.js @@ -1,8 +1,8 @@ 'use strict'; -var includes = require('lodash/includes'); -var map = require('lodash/map'); -var orderBy = require('lodash/orderBy'); +import includes from 'lodash/includes' +import map from 'lodash/map' +import orderBy from 'lodash/orderBy' var TARGET_TYPES = { 'fig': ['figure', 'fig-group'], @@ -47,4 +47,4 @@ function getXRefTargets(node) { return targets; } -module.exports = getXRefTargets; \ No newline at end of file +export default getXRefTargets; \ No newline at end of file diff --git a/packages/jats/xref/package.js b/packages/jats/xref/package.js index 6cbe09bab..ebcc1b530 100644 --- a/packages/jats/xref/package.js +++ b/packages/jats/xref/package.js @@ -1,14 +1,12 @@ -'use strict'; +import XRef from './XRef' +import XRefComponent from './XRefComponent' +import XRefConverter from './XRefConverter' +import XRefCommand from './XRefCommand' +import XRefTool from './XRefTool' +import AddXRefCommand from './AddXRefCommand' +import AddXRefTool from './AddXRefTool' -var XRef = require('./XRef'); -var XRefComponent = require('./XRefComponent'); -var XRefConverter = require('./XRefConverter'); -var XRefCommand = require('./XRefCommand'); -var XRefTool = require('./XRefTool'); -var AddXRefCommand = require('./AddXRefCommand'); -var AddXRefTool = require('./AddXRefTool'); - -module.exports = { +export default { name: 'xref', configure: function(config) { config.addNode(XRef); diff --git a/packages/publisher/Publisher.js b/packages/publisher/Publisher.js index 230166477..2f78a5d3d 100644 --- a/packages/publisher/Publisher.js +++ b/packages/publisher/Publisher.js @@ -1,12 +1,6 @@ -'use strict'; - -var AbstractWriter = require('../common/AbstractWriter'); -var SplitPane = require('substance/ui/SplitPane'); -var ScrollPane = require('substance/ui/ScrollPane'); -var Layout = require('substance/ui/Layout'); -var Overlay = require('substance/ui/DefaultOverlay'); -var PublisherTOCProvider = require('./PublisherTOCProvider'); -var TOC = require('substance/ui/TOC'); +import { SplitPane, ScrollPane, Layout, Overlay, TOC } from 'substance' +import AbstractWriter from '../common/AbstractWriter' +import PublisherTOCProvider from './PublisherTOCProvider' function PublisherWriter() { PublisherWriter.super.apply(this, arguments); @@ -87,4 +81,4 @@ PublisherWriter.Prototype = function() { AbstractWriter.extend(PublisherWriter); -module.exports = PublisherWriter; +export default PublisherWriter; diff --git a/packages/publisher/PublisherTOCProvider.js b/packages/publisher/PublisherTOCProvider.js index 3b31ae20e..1238b608a 100644 --- a/packages/publisher/PublisherTOCProvider.js +++ b/packages/publisher/PublisherTOCProvider.js @@ -1,7 +1,4 @@ -"use strict"; - -var EventEmitter = require('substance/util/EventEmitter'); -var TOCProvider = require('substance/ui/TOCProvider'); +import { EventEmitter, TOCProvider } from 'substance' /* Manages a table of content for Publisher. @@ -85,4 +82,4 @@ PublisherTOCProvider.Prototype = function() { EventEmitter.extend(PublisherTOCProvider); -module.exports = PublisherTOCProvider; +export default PublisherTOCProvider; diff --git a/packages/publisher/package.js b/packages/publisher/package.js index c813d8af7..5b43e962c 100644 --- a/packages/publisher/package.js +++ b/packages/publisher/package.js @@ -1,23 +1,26 @@ -'use strict'; +import { Overlay, Toolbar, BasePackage, PersistencePackage } from 'substance' +import JATSPackage from '../jats/package' +import CommonPackage from '../common/package' +import InlineWrapperPackage from '../inline-wrapper/InlineWrapperPackage' +import UnsupportedNodePackage from '../unsupported/UnsupportedNodePackage' -var Overlay = require('substance/ui/Overlay'); -var Toolbar = require('substance/ui/Toolbar'); - -module.exports = { +export default { name: 'publisher', configure: function(config) { - // Now import base packages - config.import(require('substance/packages/base/BasePackage')); - config.import(require('substance/packages/persistence/PersistencePackage')); + config.import(BasePackage); + config.import(PersistencePackage); + // TODO: see substance#712 config.addComponent('overlay', Overlay); // TODO: this should be used as default, too config.setToolbarClass(Toolbar); - config.import(require('../jats/package')); - config.import(require('../common/package')); + + config.import(JATSPackage); + config.import(CommonPackage); + // support inline wrappers, for all hybrid types that can be // block-level but also inline. - config.import(require('../inline-wrapper/InlineWrapperPackage')); + config.import(InlineWrapperPackage); // catch all converters - config.import(require('../unsupported/UnsupportedNodePackage')); + config.import(UnsupportedNodePackage); } -}; \ No newline at end of file +} \ No newline at end of file diff --git a/packages/texture/Texture.js b/packages/texture/Texture.js index e4627a8fb..b33f35ff8 100644 --- a/packages/texture/Texture.js +++ b/packages/texture/Texture.js @@ -1,9 +1,6 @@ -'use strict'; - -var Component = require('substance/ui/Component'); -var DocumentSession = require('substance/model/DocumentSession'); -var Publisher = require('../../packages/publisher/Publisher'); -var Author = require('../../packages/author/Author'); +import { Component, DocumentSession } from 'substance' +import Publisher from '../../packages/publisher/Publisher' +import Author from '../../packages/author/Author' /* JATSEditor Component @@ -122,4 +119,4 @@ Texture.Prototype = function() { Component.extend(Texture); -module.exports = Texture; +export default Texture; diff --git a/packages/texture/TextureConfigurator.js b/packages/texture/TextureConfigurator.js index f2d24eab4..e42674113 100644 --- a/packages/texture/TextureConfigurator.js +++ b/packages/texture/TextureConfigurator.js @@ -1,8 +1,6 @@ -'use strict'; - -var Configurator = require('substance/util/Configurator'); -var forEach = require('lodash/forEach'); -var uniq = require('lodash/uniq'); +import forEach from 'lodash/forEach' +import uniq from 'lodash/uniq' +import { Configurator } from 'substance' /* Top-level configurator for scientist. Has sub-configurators for @@ -54,4 +52,4 @@ TextureConfigurator.Prototype = function() { Configurator.extend(TextureConfigurator); -module.exports = TextureConfigurator; \ No newline at end of file +export default TextureConfigurator diff --git a/packages/texture/package.js b/packages/texture/package.js index e5efabdba..25f2cbaec 100644 --- a/packages/texture/package.js +++ b/packages/texture/package.js @@ -1,15 +1,15 @@ 'use strict'; -var ProseEditorConfigurator = require('substance/packages/prose-editor/ProseEditorConfigurator'); +import { ProseEditorPackage } from 'substance' +import AuthorPackage from '../author/package' +import PublisherPackage from '../publisher/package' -var AuthorPackage = require('../author/package'); -var PublisherPackage = require('../publisher/package'); - -module.exports = { +export default { name: 'scientist', configure: function(config) { + var Configurator = ProseEditorPackage.Configurator // Default configuration for available scientist modes - config.addConfigurator('author', new ProseEditorConfigurator().import(AuthorPackage)); - config.addConfigurator('publisher', new ProseEditorConfigurator().import(PublisherPackage)); + config.addConfigurator('author', new Configurator().import(AuthorPackage)); + config.addConfigurator('publisher', new Configurator().import(PublisherPackage)); } }; diff --git a/packages/unsupported/UnsupportedInlineNode.js b/packages/unsupported/UnsupportedInlineNode.js index f4fd275a2..7fd382233 100644 --- a/packages/unsupported/UnsupportedInlineNode.js +++ b/packages/unsupported/UnsupportedInlineNode.js @@ -1,6 +1,4 @@ -'use strict'; - -var InlineNode = require('substance/model/InlineNode'); +import { InlineNode } from 'substance' function UnsupportedInlineNode() { UnsupportedInlineNode.super.apply(this, arguments); @@ -16,4 +14,4 @@ UnsupportedInlineNode.define({ tagName: 'string' }); -module.exports = UnsupportedInlineNode; +export default UnsupportedInlineNode; diff --git a/packages/unsupported/UnsupportedInlineNodeCommand.js b/packages/unsupported/UnsupportedInlineNodeCommand.js index 86d98862f..499280519 100644 --- a/packages/unsupported/UnsupportedInlineNodeCommand.js +++ b/packages/unsupported/UnsupportedInlineNodeCommand.js @@ -1,6 +1,4 @@ -'use strict'; - -var InlineNodeCommand = require('substance/ui/InlineNodeCommand'); +import { InlineNodeCommand } from 'substance' function UnsupportedInlineNodeCommand() { UnsupportedInlineNodeCommand.super.apply(this, arguments); @@ -10,4 +8,4 @@ InlineNodeCommand.extend(UnsupportedInlineNodeCommand); UnsupportedInlineNodeCommand.type = 'unsupported-inline'; -module.exports = UnsupportedInlineNodeCommand; +export default UnsupportedInlineNodeCommand; diff --git a/packages/unsupported/UnsupportedInlineNodeComponent.js b/packages/unsupported/UnsupportedInlineNodeComponent.js index 0996e626f..078ee376b 100644 --- a/packages/unsupported/UnsupportedInlineNodeComponent.js +++ b/packages/unsupported/UnsupportedInlineNodeComponent.js @@ -1,6 +1,4 @@ -'use strict'; - -var Component = require('substance/ui/Component'); +import { Component } from 'substance' function UnsupportedInlineNodeComponent() { Component.apply(this, arguments); @@ -22,4 +20,4 @@ UnsupportedInlineNodeComponent.Prototype = function() { Component.extend(UnsupportedInlineNodeComponent); -module.exports = UnsupportedInlineNodeComponent; \ No newline at end of file +export default UnsupportedInlineNodeComponent; \ No newline at end of file diff --git a/packages/unsupported/UnsupportedInlineNodeJATSConverter.js b/packages/unsupported/UnsupportedInlineNodeJATSConverter.js index 3ccda0147..4044cae83 100644 --- a/packages/unsupported/UnsupportedInlineNodeJATSConverter.js +++ b/packages/unsupported/UnsupportedInlineNodeJATSConverter.js @@ -1,8 +1,6 @@ -'use strict'; +import UnsupportedNodeJATSConverter from './UnsupportedNodeJATSConverter' -var UnsupportedNodeJATSConverter = require('./UnsupportedNodeJATSConverter'); - -module.exports = { +export default { type: 'unsupported-inline', @@ -12,4 +10,5 @@ module.exports = { import: UnsupportedNodeJATSConverter.import, export: UnsupportedNodeJATSConverter.export -}; + +} diff --git a/packages/unsupported/UnsupportedInlineNodeTool.js b/packages/unsupported/UnsupportedInlineNodeTool.js index 6ede37980..a4998a1f3 100644 --- a/packages/unsupported/UnsupportedInlineNodeTool.js +++ b/packages/unsupported/UnsupportedInlineNodeTool.js @@ -1,11 +1,6 @@ -'use strict'; - -var Tool = require('substance/ui/Tool'); -var clone = require('lodash/clone'); -var Modal = require('substance/ui/Modal'); -var Prompt = require('substance/ui/Prompt'); -var EditXML = require('../common/EditXML'); -var deleteSelection = require('substance/model/transform/deleteSelection'); +import clone from 'lodash/clone' +import { Modal, Prompt, Tool, deleteSelection } from 'substance' +import EditXML from '../common/EditXML' /* Prompt shown when an unsupported node is selected. @@ -80,4 +75,4 @@ UnsupportedInlineNodeTool.getProps = function(commandStates) { } }; -module.exports = UnsupportedInlineNodeTool; \ No newline at end of file +export default UnsupportedInlineNodeTool; diff --git a/packages/unsupported/UnsupportedNode.js b/packages/unsupported/UnsupportedNode.js index ee4206ba4..203e28e31 100644 --- a/packages/unsupported/UnsupportedNode.js +++ b/packages/unsupported/UnsupportedNode.js @@ -1,6 +1,4 @@ -'use strict'; - -var BlockNode = require('substance/model/BlockNode'); +import { BlockNode } from 'substance' function UnsupportedNode() { UnsupportedNode.super.apply(this, arguments); @@ -16,4 +14,4 @@ UnsupportedNode.define({ tagName: 'string' }); -module.exports = UnsupportedNode; +export default UnsupportedNode; diff --git a/packages/unsupported/UnsupportedNodeComponent.js b/packages/unsupported/UnsupportedNodeComponent.js index 25360af10..bdce4612c 100644 --- a/packages/unsupported/UnsupportedNodeComponent.js +++ b/packages/unsupported/UnsupportedNodeComponent.js @@ -1,6 +1,6 @@ 'use strict'; -var Component = require('substance/ui/Component'); +import { Component } from 'substance' function UnsupportedNodeComponent() { Component.apply(this, arguments); @@ -31,4 +31,4 @@ Component.extend(UnsupportedNodeComponent); UnsupportedNodeComponent.fullWidth = true; UnsupportedNodeComponent.noStyle = true; -module.exports = UnsupportedNodeComponent; \ No newline at end of file +export default UnsupportedNodeComponent; \ No newline at end of file diff --git a/packages/unsupported/UnsupportedNodeJATSConverter.js b/packages/unsupported/UnsupportedNodeJATSConverter.js index 1ab4f43fe..5a127faf3 100644 --- a/packages/unsupported/UnsupportedNodeJATSConverter.js +++ b/packages/unsupported/UnsupportedNodeJATSConverter.js @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = { +export default { type: 'unsupported', diff --git a/packages/unsupported/UnsupportedNodePackage.js b/packages/unsupported/UnsupportedNodePackage.js index 4ff302a3f..1d15701cb 100644 --- a/packages/unsupported/UnsupportedNodePackage.js +++ b/packages/unsupported/UnsupportedNodePackage.js @@ -1,15 +1,15 @@ 'use strict'; -var UnsupportedNode = require('./UnsupportedNode'); -var UnsupportedInlineNode = require('./UnsupportedInlineNode'); -var UnsupportedNodeComponent = require('./UnsupportedNodeComponent'); -var UnsupportedInlineNodeComponent = require('./UnsupportedInlineNodeComponent'); -var UnsupportedNodeJATSConverter = require('./UnsupportedNodeJATSConverter'); -var UnsupportedInlineNodeJATSConverter = require('./UnsupportedInlineNodeJATSConverter'); -var UnsupportedInlineNodeCommand = require('./UnsupportedInlineNodeCommand'); -var UnsupportedInlineNodeTool = require('./UnsupportedInlineNodeTool'); +import UnsupportedNode from './UnsupportedNode' +import UnsupportedInlineNode from './UnsupportedInlineNode' +import UnsupportedNodeComponent from './UnsupportedNodeComponent' +import UnsupportedInlineNodeComponent from './UnsupportedInlineNodeComponent' +import UnsupportedNodeJATSConverter from './UnsupportedNodeJATSConverter' +import UnsupportedInlineNodeJATSConverter from './UnsupportedInlineNodeJATSConverter' +import UnsupportedInlineNodeCommand from './UnsupportedInlineNodeCommand' +import UnsupportedInlineNodeTool from './UnsupportedInlineNodeTool' -module.exports = { +export default { name: 'unsupported', configure: function(config) { config.addNode(UnsupportedNode); diff --git a/test/jats/JATSExporter.test.js b/test/jats/JATSExporter.test.js index 3504d8b95..9b1318640 100644 --- a/test/jats/JATSExporter.test.js +++ b/test/jats/JATSExporter.test.js @@ -2,7 +2,7 @@ var test = require('./test').module('jats/JATSExporter'); -var createJATSConfigurator = require('./createJATSConfigurator'); +import createJATSConfigurator from './createJATSConfigurator' test('Exporting a node via id', function(t) { var configurator = createJATSConfigurator(); diff --git a/test/jats/createJATSConfigurator.js b/test/jats/createJATSConfigurator.js index 7e0ea70d4..458313c58 100644 --- a/test/jats/createJATSConfigurator.js +++ b/test/jats/createJATSConfigurator.js @@ -1,11 +1,11 @@ 'use strict'; -var Configurator = require('substance/util/Configurator'); -var JATSPackage = require('../../packages/jats/package'); -var InlineWrapperPackage = require('../../packages/inline-wrapper/InlineWrapperPackage'); -var UnsupportedNodePackage = require('../../packages/unsupported/UnsupportedNodePackage'); +import Configurator from 'substance/util/Configurator' +import JATSPackage from '../../packages/jats/package' +import InlineWrapperPackage from '../../packages/inline-wrapper/InlineWrapperPackage' +import UnsupportedNodePackage from '../../packages/unsupported/UnsupportedNodePackage' -module.exports = function createJATSConfigurator() { +export default function createJATSConfigurator() { var configurator = new Configurator(); configurator.import(JATSPackage); // support inline wrappers, for all hybrid types that can be diff --git a/test/jats/inline-wrapper.test.js b/test/jats/inline-wrapper.test.js index 66b64dfc4..053372608 100644 --- a/test/jats/inline-wrapper.test.js +++ b/test/jats/inline-wrapper.test.js @@ -2,7 +2,7 @@ var test = require('./test').module('jats/inline-wrapper'); -var createJATSConfigurator = require('./createJATSConfigurator'); +import createJATSConfigurator from './createJATSConfigurator' test('Exporting a wrapped jats node', function(t) { var configurator = createJATSConfigurator(); diff --git a/test/jats/label.test.js b/test/jats/label.test.js index ad3f2e89b..4b484171c 100644 --- a/test/jats/label.test.js +++ b/test/jats/label.test.js @@ -1,7 +1,7 @@ 'use strict'; var test = require('./test').module('jats/label'); -var testTextNode = require('./testTextNode'); +import testTextNode from './testTextNode' var withAttributes = ''; diff --git a/test/jats/paragraph.test.js b/test/jats/paragraph.test.js index 47425ecec..3b2261339 100644 --- a/test/jats/paragraph.test.js +++ b/test/jats/paragraph.test.js @@ -2,7 +2,7 @@ var test = require('./test').module('jats/paragraph'); -var testTextNode = require('./testTextNode'); +import testTextNode from './testTextNode' var withAttributes = '

      abcdefghi'; test.withFixture(fixture, 'Importing/exporting <'+tagName+'>', function(t) { diff --git a/test/jats/title.test.js b/test/jats/title.test.js index 93857f7ec..ea131bbfd 100644 --- a/test/jats/title.test.js +++ b/test/jats/title.test.js @@ -1,7 +1,7 @@ 'use strict'; var test = require('./test').module('jats/title'); -var testTextNode = require('./testTextNode'); +import testTextNode from './testTextNode' var withAttributes = 'Introduction'; diff --git a/util/XMLIterator.js b/util/XMLIterator.js index 089e19a67..3b18f0f8d 100644 --- a/util/XMLIterator.js +++ b/util/XMLIterator.js @@ -1,25 +1,20 @@ -'use strict'; +import isString from 'lodash/isString' +import { ArrayIterator, makeMap } from 'substance' -var isString = require('lodash/isString'); -var oo = require('substance/util/oo'); -var ArrayIterator = require('substance/util/ArrayIterator'); -var makeMap = require('substance/util/makeMap'); +export default class XMLIterator { + constructor(elements) { + this.it = new ArrayIterator(elements); + } -function XMLIterator(elements) { - this.it = new ArrayIterator(elements); -} - -XMLIterator.Prototype = function() { - - this.optional = function(tagName, cb) { + optional(tagName, cb) { this._one(tagName, true, cb); - }; + } - this.required = function(tagName, cb) { + required(tagName, cb) { this._one(tagName, false, cb); - }; + } - this._one = function(tagName, optional, cb) { + _one(tagName, optional, cb) { if (this.it.hasNext()) { var el = this.it.next(); if (el.tagName === tagName) { @@ -29,9 +24,9 @@ XMLIterator.Prototype = function() { } } if (!optional) throw new Error("Expecting element '"+ tagName +"'."); - }; + } - this._manyOf = function(tagNames, cb) { + _manyOf(tagNames, cb) { if (isString(tagNames)) tagNames = [tagNames]; var count = 0; tagNames = makeMap(tagNames); @@ -46,26 +41,22 @@ XMLIterator.Prototype = function() { } } return count; - }; + } - this.manyOf = function(tagNames, cb) { + manyOf(tagNames, cb) { return this._manyOf(tagNames, cb); - }; + } - this.oneOrMoreOf = function(tagNames, cb) { + oneOrMoreOf(tagNames, cb) { var count = this._manyOf(tagNames, cb); if (count === 0) { throw new Error('Expecting at least one element of ' + String(tagNames)); } return count; - }; + } - this.hasNext = function() { + hasNext() { return this.it.hasNext(); - }; + } -}; - -oo.initClass(XMLIterator); - -module.exports = XMLIterator; \ No newline at end of file +} diff --git a/util/renderNodeComponent.js b/util/renderNodeComponent.js index 93985afb2..1e2338716 100644 --- a/util/renderNodeComponent.js +++ b/util/renderNodeComponent.js @@ -1,8 +1,8 @@ 'use strict'; -var extend = require('lodash/extend'); +import extend from 'lodash/extend' -module.exports = function renderNodeComponent(self, $$, node, props) { +export default function renderNodeComponent(self, $$, node, props) { props = props || {}; var componentRegistry = self.props.componentRegistry || self.context.componentRegistry; var ComponentClass = componentRegistry.get(node.type); diff --git a/util/toDOM.js b/util/toDOM.js index e5e7d7d10..8a02132bf 100644 --- a/util/toDOM.js +++ b/util/toDOM.js @@ -1,13 +1,11 @@ -'use strict'; - -var DOMElement = require('substance/ui/DefaultDOMElement'); +import { DefaultDOMElement as DOMElement } from 'substance' /* Converts a node into its DOM representation @return {substance/ui/DOMElement} A wrapped DOM element */ -module.exports = function toDOM(node) { +export default function toDOM(node) { var tagName = node.constructor.tagName || node.constructor.type; var el = DOMElement.parseXML('<'+tagName+'>'+node.xmlContent+''); el.attr(node.attributes); From 9ea6bd09cd08c5dfaade330a2986e4419d7ea5d8 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 8 Sep 2016 20:14:15 +0200 Subject: [PATCH 064/167] Initial bundler --- examples/author/index.html | 3 ++- examples/publisher/index.html | 3 ++- make.js | 39 +++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 make.js diff --git a/examples/author/index.html b/examples/author/index.html index 472bca7cf..5469401e3 100644 --- a/examples/author/index.html +++ b/examples/author/index.html @@ -2,7 +2,8 @@ Texture Author - + + diff --git a/examples/publisher/index.html b/examples/publisher/index.html index c3f5ee657..319d09b64 100644 --- a/examples/publisher/index.html +++ b/examples/publisher/index.html @@ -2,7 +2,8 @@ Texture Publisher - + + diff --git a/make.js b/make.js new file mode 100644 index 000000000..29554b260 --- /dev/null +++ b/make.js @@ -0,0 +1,39 @@ +var b = require('substance-bundler'); + +b.task('clean', function() { + b.rm('./dist') +}) + +// this optional task makes it easier to work on Substance core +b.task('substance', function() { + b.make('substance') +}) + +// copy assets +b.task('assets', function() { + b.copy('examples/data', './dist/') + b.copy('node_modules/font-awesome/fonts', './dist/') +}) + +var examples = ['author', 'publisher'] +// options for js bundling +examples.forEach(function(example) { + b.task(example, function() { + b.copy('examples/'+example+'/index.html', './dist/'+example+'/') + b.js('examples/'+example+'/app.js', { + dest: './dist/'+example+'/app.js', + format: 'umd', + moduleName: example + }) + }) +}) + +b.task('examples', examples) + +b.task('minify_examples', function() { + examples.forEach(function(folder) { + b.minify('./dist/'+folder+'/app.js') + }) +}) + +b.task('default', ['clean', 'assets', 'examples', 'minify_examples']) From 7c02d023839a3b70bf41904e7e04155c049b9077 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 8 Sep 2016 21:23:52 +0200 Subject: [PATCH 065/167] Use es6 modules --- packages/jats/article/TextureArticle.js | 6 ++---- packages/jats/contrib/TagContribCommand.js | 11 +++-------- packages/jats/contrib/TagContribTool.js | 6 ++---- packages/jats/ref/TagRefCommand.js | 8 ++------ packages/jats/ref/TagRefTool.js | 11 +++-------- packages/jats/xref/AddXRefCommand.js | 6 ++---- packages/jats/xref/AddXRefTool.js | 6 ++---- 7 files changed, 16 insertions(+), 38 deletions(-) diff --git a/packages/jats/article/TextureArticle.js b/packages/jats/article/TextureArticle.js index 75e554068..ce0685f3a 100644 --- a/packages/jats/article/TextureArticle.js +++ b/packages/jats/article/TextureArticle.js @@ -1,6 +1,4 @@ -'use strict'; - -var Document = require('substance/model/Document'); +import { Document } from 'substance' class TextureArticle extends Document { /* @@ -22,4 +20,4 @@ class TextureArticle extends Document { } } -module.exports = TextureArticle; +export default TextureArticle diff --git a/packages/jats/contrib/TagContribCommand.js b/packages/jats/contrib/TagContribCommand.js index 63b3299b4..c9e843fde 100644 --- a/packages/jats/contrib/TagContribCommand.js +++ b/packages/jats/contrib/TagContribCommand.js @@ -1,10 +1,4 @@ -'use strict'; - -var Command = require('substance/ui/Command'); -var uuid = require('substance/util/uuid'); -var documentHelpers = require('substance/model/documentHelpers'); -var deleteSelection = require('substance/model/transform/deleteSelection'); - +import { Command, uuid, documentHelpers, deleteSelection } from 'substance' class TagContribCommand extends Command { @@ -54,4 +48,5 @@ class TagContribCommand extends Command { } } -module.exports = TagContribCommand; + +export default TagContribCommand diff --git a/packages/jats/contrib/TagContribTool.js b/packages/jats/contrib/TagContribTool.js index ca85ca090..93d453a80 100644 --- a/packages/jats/contrib/TagContribTool.js +++ b/packages/jats/contrib/TagContribTool.js @@ -1,7 +1,5 @@ -'use strict'; - -var Tool = require('substance/ui/Tool'); +import { Tool } from 'substance' class TagContribTool extends Tool {} -module.exports = TagContribTool; +export default TagContribTool diff --git a/packages/jats/ref/TagRefCommand.js b/packages/jats/ref/TagRefCommand.js index bd97d16fb..fcb1a7038 100644 --- a/packages/jats/ref/TagRefCommand.js +++ b/packages/jats/ref/TagRefCommand.js @@ -1,8 +1,4 @@ -'use strict'; - -var Command = require('substance/ui/Command'); -var uuid = require('substance/util/uuid'); -var Selection = require('substance/model/Selection'); +import { Command, uuid, Selection } from 'substance' class TagRefCommand extends Command { @@ -80,4 +76,4 @@ class TagRefCommand extends Command { } } -module.exports = TagRefCommand; +export default TagRefCommand diff --git a/packages/jats/ref/TagRefTool.js b/packages/jats/ref/TagRefTool.js index 279417b9f..144901dc8 100644 --- a/packages/jats/ref/TagRefTool.js +++ b/packages/jats/ref/TagRefTool.js @@ -1,10 +1,5 @@ -'use strict'; +import { Tool } from 'substance' -var Tool = require('substance/ui/Tool'); +class TagRefTool extends Tool {} -function TagRefTool() { - TagRefTool.super.apply(this, arguments); -} -Tool.extend(TagRefTool); - -module.exports = TagRefTool; +export default TagRefTool diff --git a/packages/jats/xref/AddXRefCommand.js b/packages/jats/xref/AddXRefCommand.js index 704d9e8d1..4338dd67c 100644 --- a/packages/jats/xref/AddXRefCommand.js +++ b/packages/jats/xref/AddXRefCommand.js @@ -1,6 +1,4 @@ -'use strict'; - -var InlineNodeCommand = require('substance/ui/InlineNodeCommand'); +import { InlineNodeCommand } from 'substance' function AddXRefCommand() { AddXRefCommand.super.apply(this, arguments); @@ -19,4 +17,4 @@ AddXRefCommand.Prototype = function() { InlineNodeCommand.extend(AddXRefCommand); -module.exports = AddXRefCommand; \ No newline at end of file +export default AddXRefCommand diff --git a/packages/jats/xref/AddXRefTool.js b/packages/jats/xref/AddXRefTool.js index 418bf9c60..cb183298f 100644 --- a/packages/jats/xref/AddXRefTool.js +++ b/packages/jats/xref/AddXRefTool.js @@ -1,6 +1,4 @@ -'use strict'; - -var AnnotationTool = require('substance/ui/AnnotationTool'); +import { AnnotationTool } from 'substance' function AddXRefTool() { AddXRefTool.super.apply(this, arguments); @@ -8,4 +6,4 @@ function AddXRefTool() { AnnotationTool.extend(AddXRefTool); -module.exports = AddXRefTool; \ No newline at end of file +export default AddXRefTool \ No newline at end of file From b95cdb9ec8d8c9585f29aa3bc1c64fe15d237917 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 9 Sep 2016 15:48:51 +0200 Subject: [PATCH 066/167] Fix bundling --- examples/author/index.html | 2 +- examples/publisher/index.html | 2 +- make.js | 14 +++++++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/examples/author/index.html b/examples/author/index.html index 5469401e3..6f4321aa9 100644 --- a/examples/author/index.html +++ b/examples/author/index.html @@ -2,7 +2,7 @@ Texture Author - + diff --git a/examples/publisher/index.html b/examples/publisher/index.html index 319d09b64..8e0654481 100644 --- a/examples/publisher/index.html +++ b/examples/publisher/index.html @@ -2,7 +2,7 @@ Texture Publisher - + diff --git a/make.js b/make.js index 29554b260..569cbbf48 100644 --- a/make.js +++ b/make.js @@ -11,8 +11,11 @@ b.task('substance', function() { // copy assets b.task('assets', function() { - b.copy('examples/data', './dist/') - b.copy('node_modules/font-awesome/fonts', './dist/') + b.copy('texture.css', './dist/') + b.copy('packages/**/*.css', './dist/') + b.copy('examples/data', './dist/data') + b.copy('node_modules/font-awesome', './dist/font-awesome') + b.copy('node_modules/substance/dist', './dist/substance') }) var examples = ['author', 'publisher'] @@ -20,7 +23,11 @@ var examples = ['author', 'publisher'] examples.forEach(function(example) { b.task(example, function() { b.copy('examples/'+example+'/index.html', './dist/'+example+'/') + b.copy('examples/'+example+'/*.css', './dist/'+example+'/', { root: 'examples/'+example }) b.js('examples/'+example+'/app.js', { + external: ['substance'], + nodeResolve: { include: ['node_modules/lodash/**'] }, + commonjs: { include: ['node_modules/lodash/**'] }, dest: './dist/'+example+'/app.js', format: 'umd', moduleName: example @@ -36,4 +43,5 @@ b.task('minify_examples', function() { }) }) -b.task('default', ['clean', 'assets', 'examples', 'minify_examples']) +//b.task('default', ['clean', 'assets', 'examples', 'minify_examples']) +b.task('default', ['clean', 'assets', 'examples']) From 54303f09aa36c0c44f2e7dae84d1873e249d76db Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 9 Sep 2016 15:49:19 +0200 Subject: [PATCH 067/167] Add dev server configuration --- make.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/make.js b/make.js index 569cbbf48..87be0f0c2 100644 --- a/make.js +++ b/make.js @@ -11,6 +11,7 @@ b.task('substance', function() { // copy assets b.task('assets', function() { + b.copy('examples/index.html', './dist/') b.copy('texture.css', './dist/') b.copy('packages/**/*.css', './dist/') b.copy('examples/data', './dist/data') @@ -45,3 +46,9 @@ b.task('minify_examples', function() { //b.task('default', ['clean', 'assets', 'examples', 'minify_examples']) b.task('default', ['clean', 'assets', 'examples']) + +// starts a server when CLI argument '-s' is set +b.setServerPort(5555) +b.serve({ + static: true, route: '/', folder: 'dist' +}) From ed90704a2dc6532ac5c47589947a51e2d92329e7 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 9 Sep 2016 20:42:13 +0200 Subject: [PATCH 068/167] Updated make --- make.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/make.js b/make.js index 87be0f0c2..ecd907ea9 100644 --- a/make.js +++ b/make.js @@ -6,7 +6,7 @@ b.task('clean', function() { // this optional task makes it easier to work on Substance core b.task('substance', function() { - b.make('substance') + b.make('substance', 'clean', 'css', 'browser:umd') }) // copy assets @@ -27,7 +27,6 @@ examples.forEach(function(example) { b.copy('examples/'+example+'/*.css', './dist/'+example+'/', { root: 'examples/'+example }) b.js('examples/'+example+'/app.js', { external: ['substance'], - nodeResolve: { include: ['node_modules/lodash/**'] }, commonjs: { include: ['node_modules/lodash/**'] }, dest: './dist/'+example+'/app.js', format: 'umd', @@ -44,8 +43,9 @@ b.task('minify_examples', function() { }) }) -//b.task('default', ['clean', 'assets', 'examples', 'minify_examples']) -b.task('default', ['clean', 'assets', 'examples']) +b.task('default', ['clean', 'assets', 'examples', 'minify_examples']) + +b.task('dev', ['substance', 'clean', 'assets', 'examples']) // starts a server when CLI argument '-s' is set b.setServerPort(5555) From faa8bcde2d990c67512d193ce6e055f3c2634266 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 12 Sep 2016 09:33:21 +0200 Subject: [PATCH 069/167] es6ifications --- packages/jats/aff/Aff.js | 6 +++--- packages/jats/aff/AffComponent.js | 8 +++----- packages/jats/aff/AffConverter.js | 6 ++---- packages/jats/aff/TagAffCommand.js | 8 ++------ packages/jats/aff/TagAffTool.js | 4 ++-- packages/jats/aff/affUtils.js | 9 ++------- packages/jats/aff/package.js | 16 ++++++++-------- packages/jats/contrib/ContribComponent.js | 1 - packages/jats/contrib/EditContrib.js | 8 +++----- packages/jats/contrib/contribUtils.js | 12 ++++-------- util/getFullName.js | 6 ++---- 11 files changed, 31 insertions(+), 53 deletions(-) diff --git a/packages/jats/aff/Aff.js b/packages/jats/aff/Aff.js index e03a429cb..f34e11d5d 100644 --- a/packages/jats/aff/Aff.js +++ b/packages/jats/aff/Aff.js @@ -1,7 +1,7 @@ 'use strict'; -var DocumentNode = require('substance/model/DocumentNode'); -var toDOM = require('../../../util/toDOM'); +import { DocumentNode } from 'substance' +import toDOM from '../../../util/toDOM' class Aff extends DocumentNode { } @@ -26,4 +26,4 @@ Aff.define({ xmlContent: { type: 'string', default: ''} }); -module.exports = Aff; +export default Aff diff --git a/packages/jats/aff/AffComponent.js b/packages/jats/aff/AffComponent.js index cd804342a..d971bb135 100644 --- a/packages/jats/aff/AffComponent.js +++ b/packages/jats/aff/AffComponent.js @@ -1,9 +1,7 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var Icon = require('substance/ui/FontAwesomeIcon'); - -var getAdapter = require('./affUtils').getAdapter; +import { Component, FontAwesomeIcon as Icon } from 'substance' +import { getAdapter } from './affUtils' class AffComponent extends Component { constructor(...args) { @@ -19,4 +17,4 @@ class AffComponent extends Component { } } -module.exports = AffComponent; +export default AffComponent diff --git a/packages/jats/aff/AffConverter.js b/packages/jats/aff/AffConverter.js index ab27f4f39..58fd8b333 100644 --- a/packages/jats/aff/AffConverter.js +++ b/packages/jats/aff/AffConverter.js @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = { +export default { type: 'aff', tagName: 'aff', @@ -12,4 +10,4 @@ module.exports = { export: function(node, el, converter) { // eslint-disable-line el.innerHTML = node.xmlContent; } -}; +} diff --git a/packages/jats/aff/TagAffCommand.js b/packages/jats/aff/TagAffCommand.js index 2f01e92c3..79f1cbc6a 100644 --- a/packages/jats/aff/TagAffCommand.js +++ b/packages/jats/aff/TagAffCommand.js @@ -1,10 +1,6 @@ 'use strict'; -var Command = require('substance/ui/Command'); -var uuid = require('substance/util/uuid'); -var documentHelpers = require('substance/model/documentHelpers'); -var deleteSelection = require('substance/model/transform/deleteSelection'); - +import { Command, uuid, documentHelpers, deleteSelection } from 'substance' class TagAffCommand extends Command { @@ -54,4 +50,4 @@ class TagAffCommand extends Command { } } -module.exports = TagAffCommand; +export default TagAffCommand diff --git a/packages/jats/aff/TagAffTool.js b/packages/jats/aff/TagAffTool.js index 2074bc670..acfda0bec 100644 --- a/packages/jats/aff/TagAffTool.js +++ b/packages/jats/aff/TagAffTool.js @@ -1,7 +1,7 @@ 'use strict'; -var Tool = require('substance/ui/Tool'); +import { Tool } from 'substance' class TagAffTool extends Tool {} -module.exports = TagAffTool; +export default TagAffTool diff --git a/packages/jats/aff/affUtils.js b/packages/jats/aff/affUtils.js index 53295d855..d78716e4f 100644 --- a/packages/jats/aff/affUtils.js +++ b/packages/jats/aff/affUtils.js @@ -1,6 +1,4 @@ -'use strict'; - -var toDOM = require('../../../util/toDOM'); +import toDOM from '../../../util/toDOM' /* Get all affiliations for a doc @@ -24,7 +22,4 @@ function getAdapter(node) { }; } -module.exports = { - getAffs: getAffs, - getAdapter: getAdapter -}; \ No newline at end of file +export { getAffs, getAdapter } diff --git a/packages/jats/aff/package.js b/packages/jats/aff/package.js index 2e25c0862..809cc5990 100644 --- a/packages/jats/aff/package.js +++ b/packages/jats/aff/package.js @@ -1,19 +1,19 @@ 'use strict'; -var Aff = require('./Aff'); -var AffComponent = require('./AffComponent'); -var AffConverter = require('./AffConverter'); -var TagAffCommand = require('./TagAffCommand'); -var TagAffTool = require('./TagAffTool'); +import Aff from './Aff' +import AffComponent from './AffComponent' +import AffConverter from './AffConverter' +import TagAffCommand from './TagAffCommand' +import TagAffTool from './TagAffTool' -module.exports = { +export default { name: 'aff', configure: function(config) { - config.addNode(Aff); + config.addNode(Aff) config.addComponent(Aff.type, AffComponent); config.addConverter('jats', AffConverter); config.addCommand('tag-aff', TagAffCommand); config.addTool('tag-aff', TagAffTool); config.addIcon('tag-aff', { 'fontawesome': 'fa-bullseye' }); } -}; \ No newline at end of file +} diff --git a/packages/jats/contrib/ContribComponent.js b/packages/jats/contrib/ContribComponent.js index 18ed34e77..00a767d00 100644 --- a/packages/jats/contrib/ContribComponent.js +++ b/packages/jats/contrib/ContribComponent.js @@ -2,7 +2,6 @@ import { Component, Modal } from 'substance' import EditXML from '../../common/EditXML' -import contribToHTML from './contribToHTML' import EditContrib from './EditContrib' import { getAdapter } from './contribUtils' diff --git a/packages/jats/contrib/EditContrib.js b/packages/jats/contrib/EditContrib.js index dfc0399d0..2c1c67fbe 100644 --- a/packages/jats/contrib/EditContrib.js +++ b/packages/jats/contrib/EditContrib.js @@ -1,9 +1,7 @@ 'use strict'; -var Component = require('substance/ui/Component'); -var Input = require('substance/ui/Input'); -var Button = require('substance/ui/Button'); -var saveContrib = require('./contribUtils').saveContrib; +import { Component, Input, Button } from 'substance' +import { saveContrib } from './contribUtils' class EditContrib extends Component { @@ -93,4 +91,4 @@ function getSelectedOptions(sel, fn) { return opts; } -module.exports = EditContrib; +export default EditContrib diff --git a/packages/jats/contrib/contribUtils.js b/packages/jats/contrib/contribUtils.js index 15ed1f4e2..466008fc1 100644 --- a/packages/jats/contrib/contribUtils.js +++ b/packages/jats/contrib/contribUtils.js @@ -1,6 +1,6 @@ -var toDOM = require('../../../util/toDOM'); -var getFullName = require('../../../util/getFullName'); -var getAffs = require('../aff/affUtils').getAffs; +import toDOM from '../../../util/toDOM' +import getFullName from '../../../util/getFullName' +import { getAffs } from '../aff/affUtils' /* For given contrib node get the assigned affiliation ids as an object @@ -55,8 +55,4 @@ function saveContrib(documentSession, contribData) { }); } -module.exports = { - affsForContrib: affsForContrib, - getAdapter: getAdapter, - saveContrib: saveContrib -}; \ No newline at end of file +export { affsForContrib, getAdapter, saveContrib} diff --git a/util/getFullName.js b/util/getFullName.js index 27026c6bc..d2a106be9 100644 --- a/util/getFullName.js +++ b/util/getFullName.js @@ -1,6 +1,4 @@ -'use strict'; - -var toDOM = require('./toDOM'); +import toDOM from './toDOM' /* Extract name from elements that contain @@ -20,4 +18,4 @@ function getFullName(node) { } } -module.exports = getFullName; \ No newline at end of file +export default getFullName From 508fef5d9239b33c37cd749330391ed3a99b8f85 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 12 Sep 2016 11:20:10 +0200 Subject: [PATCH 070/167] Updated make --- make.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/make.js b/make.js index ecd907ea9..a26b1b7e0 100644 --- a/make.js +++ b/make.js @@ -26,6 +26,8 @@ examples.forEach(function(example) { b.copy('examples/'+example+'/index.html', './dist/'+example+'/') b.copy('examples/'+example+'/*.css', './dist/'+example+'/', { root: 'examples/'+example }) b.js('examples/'+example+'/app.js', { + // need buble if we want to minify later + buble: true, external: ['substance'], commonjs: { include: ['node_modules/lodash/**'] }, dest: './dist/'+example+'/app.js', @@ -37,13 +39,15 @@ examples.forEach(function(example) { b.task('examples', examples) -b.task('minify_examples', function() { +b.task('minify:examples', function() { examples.forEach(function(folder) { b.minify('./dist/'+folder+'/app.js') }) }) -b.task('default', ['clean', 'assets', 'examples', 'minify_examples']) +b.task('minify', ['minify:examples']) + +b.task('default', ['clean', 'assets', 'examples', 'minify']) b.task('dev', ['substance', 'clean', 'assets', 'examples']) From a3438f0fc199037f9c77d3a3364299f902c49b61 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 12 Sep 2016 12:56:35 +0200 Subject: [PATCH 071/167] Updated package.json --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index fe8fcef24..595c7a976 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "A scientific editor and reader for JATS files.", "dependencies": { "lodash": "^4.14.1", - "substance": "substance/substance#develop" + "substance": "substance/substance#jsnext" }, "devDependencies": { "eslint": "^3.2.2", @@ -12,7 +12,7 @@ "substance-bundler": "*", "tap-spec": "4.1.1", "tape": "4.5.1", - "yargs": "^4.8.1" + "uglify-js": "^2.7.3" }, "scripts": { "bundle": "node make", From 1734620e72ac560287885f059285eb2d8f7b454c Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 12 Sep 2016 14:53:30 +0200 Subject: [PATCH 072/167] Updated make --- make.js | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/make.js b/make.js index a26b1b7e0..033bc0254 100644 --- a/make.js +++ b/make.js @@ -4,11 +4,6 @@ b.task('clean', function() { b.rm('./dist') }) -// this optional task makes it easier to work on Substance core -b.task('substance', function() { - b.make('substance', 'clean', 'css', 'browser:umd') -}) - // copy assets b.task('assets', function() { b.copy('examples/index.html', './dist/') @@ -16,13 +11,18 @@ b.task('assets', function() { b.copy('packages/**/*.css', './dist/') b.copy('examples/data', './dist/data') b.copy('node_modules/font-awesome', './dist/font-awesome') +}) + +// this optional task makes it easier to work on Substance core +b.task('substance', function() { + b.make('substance', 'clean', 'css', 'browser:umd') b.copy('node_modules/substance/dist', './dist/substance') }) var examples = ['author', 'publisher'] // options for js bundling examples.forEach(function(example) { - b.task(example, function() { + b.task("example:"+example, function() { b.copy('examples/'+example+'/index.html', './dist/'+example+'/') b.copy('examples/'+example+'/*.css', './dist/'+example+'/', { root: 'examples/'+example }) b.js('examples/'+example+'/app.js', { @@ -37,7 +37,9 @@ examples.forEach(function(example) { }) }) -b.task('examples', examples) +b.task('examples', examples.map(function(example) { + return "example:"+example +})) b.task('minify:examples', function() { examples.forEach(function(folder) { @@ -47,9 +49,14 @@ b.task('minify:examples', function() { b.task('minify', ['minify:examples']) -b.task('default', ['clean', 'assets', 'examples', 'minify']) +var basics = ['clean', 'assets', 'substance'] + +// build all +b.task('default', basics.concat(['examples', 'minify'])) -b.task('dev', ['substance', 'clean', 'assets', 'examples']) +// for dev purpose build only author relevant stuff +b.task('author', basics.concat('example:author')) +b.task('publisher', basics.concat('example:publisher')) // starts a server when CLI argument '-s' is set b.setServerPort(5555) From 257d81917e0bef0b9c578391c61ea576e94634ae Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 12 Sep 2016 19:30:02 +0200 Subject: [PATCH 073/167] Updated make --- make.js | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/make.js b/make.js index 033bc0254..9ed9fccc3 100644 --- a/make.js +++ b/make.js @@ -22,7 +22,7 @@ b.task('substance', function() { var examples = ['author', 'publisher'] // options for js bundling examples.forEach(function(example) { - b.task("example:"+example, function() { + b.task(example, function() { b.copy('examples/'+example+'/index.html', './dist/'+example+'/') b.copy('examples/'+example+'/*.css', './dist/'+example+'/', { root: 'examples/'+example }) b.js('examples/'+example+'/app.js', { @@ -37,9 +37,7 @@ examples.forEach(function(example) { }) }) -b.task('examples', examples.map(function(example) { - return "example:"+example -})) +b.task('examples', examples) b.task('minify:examples', function() { examples.forEach(function(folder) { @@ -49,14 +47,8 @@ b.task('minify:examples', function() { b.task('minify', ['minify:examples']) -var basics = ['clean', 'assets', 'substance'] - // build all -b.task('default', basics.concat(['examples', 'minify'])) - -// for dev purpose build only author relevant stuff -b.task('author', basics.concat('example:author')) -b.task('publisher', basics.concat('example:publisher')) +b.task('default', (['clean', 'assets', 'substance', 'examples' /*, 'minify'*/])) // starts a server when CLI argument '-s' is set b.setServerPort(5555) From 0ff2c704995c97bb02e8189f27dee126982a3626 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 12 Sep 2016 19:31:01 +0200 Subject: [PATCH 074/167] Refactored author example --- examples/author/app.js | 41 ++++++--- examples/author/package.js | 6 +- packages/author/package.js | 2 - packages/texture/Texture.js | 115 +++++++++--------------- packages/texture/TextureConfigurator.js | 58 +++--------- 5 files changed, 87 insertions(+), 135 deletions(-) diff --git a/examples/author/app.js b/examples/author/app.js index 2cb4d81fc..3959abde7 100644 --- a/examples/author/app.js +++ b/examples/author/app.js @@ -1,21 +1,42 @@ import { substanceGlobals } from 'substance' import Package from './package' -import TextureConfigurator from '../../packages/texture/TextureConfigurator' import Texture from '../../packages/texture/Texture' +import TextureConfigurator from '../../packages/texture/TextureConfigurator' +import Author from '../../packages/author/Author' substanceGlobals.DEBUG_RENDERING = true; -var config = new TextureConfigurator().import(Package); + +class App extends Texture { + + render($$) { + let el = $$('div').addClass('sc-author-example') + + if (this.state.error) { + el.append(this.state.error) + } + + if (this.state.documentSession) { + el.append($$(Author, { + documentId: this.props.documentId, + documentSession: this.state.documentSession, + configurator: this.getConfigurator() + })) + } + + return el + } +} if (typeof window !== 'undefined') { window.onload = function() { - window.app = Texture.mount({ - mode: 'author', - documentId: 'kitchen-sink-author', - configurator: config - }, document.body); + let configurator = new TextureConfigurator() + configurator.import(Package) + var app = App.mount({ + configurator: configurator, + documentId: 'elife-00007' + }, document.body) + window.app = app }; } -export default { - config: config -} +export default App diff --git a/examples/author/package.js b/examples/author/package.js index f370f0bcb..61ba25937 100644 --- a/examples/author/package.js +++ b/examples/author/package.js @@ -1,12 +1,10 @@ -import TexturePackage from '../../packages/texture/package' +import AuthorPackage from '../../packages/author/package' import ExampleXMLStore from '../ExampleXMLStore' export default { name: 'author-example', configure: function(config) { - // Use the default Texture package - config.import(TexturePackage); - // Define XML Store + config.import(AuthorPackage) config.setXMLStore(ExampleXMLStore); } }; diff --git a/packages/author/package.js b/packages/author/package.js index c9eed9284..be9289055 100644 --- a/packages/author/package.js +++ b/packages/author/package.js @@ -13,8 +13,6 @@ export default { // Now import base packages config.import(BasePackage); config.import(PersistencePackage); - // TODO: this should be used as default, too - config.setToolbarClass(Toolbar); config.import(JATSPackage); config.import(HeadingPackage); diff --git a/packages/texture/Texture.js b/packages/texture/Texture.js index b33f35ff8..ea4c8b85d 100644 --- a/packages/texture/Texture.js +++ b/packages/texture/Texture.js @@ -1,60 +1,72 @@ import { Component, DocumentSession } from 'substance' -import Publisher from '../../packages/publisher/Publisher' -import Author from '../../packages/author/Author' /* JATSEditor Component Based on given mode prop, displays the Publisher, Author or Reader component */ -function Texture() { - Component.apply(this, arguments); +class Texture extends Component { - var configurator = this.props.configurator; - this.xmlStore = configurator.getXMLStore(); -} + constructor(parent, props) { + super(parent, props) -Texture.Prototype = function() { + if (!props.configurator) { + throw new Error("'configurator' is required") + } + this.configurator = props.configurator + this.xmlStore = this.configurator.getXMLStore() + } - this.getChildContext = function() { + getChildContext() { return { xmlStore: this.xmlStore - }; - }; + } + } - this.getInitialState = function() { + getInitialState() { return { documentSession: null, error: null - }; - }; + } + } - this.didMount = function() { + didMount() { // load the document after mounting this._loadDocument(this.props.documentId); - }; + } - this.willReceiveProps = function(newProps) { + willReceiveProps(newProps) { if (newProps.documentId !== this.props.documentId) { this.dispose(); this.state = this.getInitialState(); this._loadDocument(newProps.documentId); } - }; + } - this.dispose = function() { - this._dispose(); - }; - - this._dispose = function() { + dispose() { // Note: we need to clear everything, as the childContext // changes which is immutable this.empty(); - }; + } - this._loadDocument = function() { - var configurator = this.getChildConfigurator(); + render($$) { + var el = $$('div').addClass('sc-texture'); + if (this.state.error) { + el.append(this.state.error) + } + return el; + } + + getConfigurator() { + return this.configurator + } + createDocumentSession(doc) { + return new DocumentSession(doc) + } + + _loadDocument() { + const configurator = this.getConfigurator(); this.xmlStore.readXML(this.props.documentId, function(err, xml) { if (err) { console.error(err); @@ -63,60 +75,15 @@ Texture.Prototype = function() { }); return; } - var importer = configurator.createImporter('jats'); var doc = importer.importDocument(xml); // HACK: For debug purposes window.doc = doc; - var documentSession = new DocumentSession(doc); - this.setState({ - documentSession: documentSession + documentSession: this.createDocumentSession(doc) }); }.bind(this)); - }; - - this.getChildConfigurator = function() { - var scientistConfigurator = this.props.configurator; - return scientistConfigurator.getConfigurator(this.props.mode); - }; - - // Rendering - // ------------------------------------ - - this.render = function($$) { - var el = $$('div').addClass('sc-texture'); - - if (this.state.error) { - el.append('ERROR: ', this.state.error.message); - return el; - } - - if (!this.state.documentSession) { - return el; - } - - // Depending on the chosen mode, instantiate - var ActiveModeClass; - var configurator = this.getChildConfigurator(); - - if (this.props.mode === 'publisher') { - ActiveModeClass = Publisher; - } else if (this.props.mode === 'author') { - ActiveModeClass = Author; - } - - el.append( - $$(ActiveModeClass, { - documentId: this.props.documentId, - documentSession: this.state.documentSession, - configurator: configurator - }).ref(this.props.mode) - ); - return el; - }; -}; - -Component.extend(Texture); + } +} export default Texture; diff --git a/packages/texture/TextureConfigurator.js b/packages/texture/TextureConfigurator.js index e42674113..d16954aa8 100644 --- a/packages/texture/TextureConfigurator.js +++ b/packages/texture/TextureConfigurator.js @@ -1,55 +1,23 @@ -import forEach from 'lodash/forEach' -import uniq from 'lodash/uniq' -import { Configurator } from 'substance' +import { ProseEditorPackage } from 'substance' +// TODO: we should have a better base Configurator in core +const Configurator = ProseEditorPackage.Configurator -/* - Top-level configurator for scientist. Has sub-configurators for - all available modules (author, publisher, reader). -*/ -function TextureConfigurator() { - TextureConfigurator.super.apply(this, arguments); +class TextureConfigurator extends Configurator { - // Extend config - this.config.configurators = {}; - this.config.XMLStoreClass = null; -} - -TextureConfigurator.Prototype = function() { - - /* - Provision of sub configurators (e.g. Author, Publisher, Reader - receive their own configurator) - */ - this.addConfigurator = function(name, configurator) { - this.config.configurators[name] = configurator; - }; - - this.getConfigurator = function(name) { - return this.config.configurators[name]; - }; + constructor(...args) { + super(...args) + this.config.XMLStoreClass = null + } - this.setXMLStore = function(XMLStoreClass) { + setXMLStore(XMLStoreClass) { this.config.XMLStoreClass = XMLStoreClass; - }; + } - this.getXMLStore = function() { + getXMLStore() { var XMLStoreClass = this.config.XMLStoreClass; return new XMLStoreClass(); - }; + } - this.getStyles = function() { - var styles = [].concat(this.config.styles); - - forEach(this.config.configurators, function(configurator) { - styles = styles.concat(configurator.getStyles()); - }); - - // Remove duplicates with _.uniq, since publisher, author, - // reader use a lot of shared styles - return uniq(styles); - }; -}; - -Configurator.extend(TextureConfigurator); +} export default TextureConfigurator From dc866004cff0468595ae2aea02cc05b9e32717aa Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 12 Sep 2016 20:45:34 +0200 Subject: [PATCH 075/167] Extracted tagging example --- examples/author/app.js | 2 ++ examples/index.html | 1 + examples/tagging/README.md | 7 +++++ examples/tagging/TaggingPackage.js | 30 +++++++++++++++++++ .../tagging}/aff/TagAffCommand.js | 2 -- .../tagging}/aff/TagAffTool.js | 2 -- examples/tagging/app.css | 11 +++++++ examples/tagging/app.js | 14 +++++++++ .../tagging}/contrib/TagContribCommand.js | 0 .../tagging}/contrib/TagContribTool.js | 0 examples/tagging/index.html | 11 +++++++ .../tagging}/ref/TagRefCommand.js | 0 .../tagging}/ref/TagRefTool.js | 0 packages/jats/aff/package.js | 7 ----- packages/jats/contrib/package.js | 5 ---- packages/jats/ref/Ref.js | 2 -- packages/jats/ref/RefComponent.js | 3 -- packages/jats/ref/RefConverter.js | 5 ++-- packages/jats/ref/RefTarget.js | 2 -- packages/jats/ref/package.js | 5 ---- packages/jats/ref/refToHTML.js | 2 -- 21 files changed, 78 insertions(+), 33 deletions(-) create mode 100644 examples/tagging/README.md create mode 100644 examples/tagging/TaggingPackage.js rename {packages/jats => examples/tagging}/aff/TagAffCommand.js (98%) rename {packages/jats => examples/tagging}/aff/TagAffTool.js (86%) create mode 100644 examples/tagging/app.css create mode 100644 examples/tagging/app.js rename {packages/jats => examples/tagging}/contrib/TagContribCommand.js (100%) rename {packages/jats => examples/tagging}/contrib/TagContribTool.js (100%) create mode 100644 examples/tagging/index.html rename {packages/jats => examples/tagging}/ref/TagRefCommand.js (100%) rename {packages/jats => examples/tagging}/ref/TagRefTool.js (100%) diff --git a/examples/author/app.js b/examples/author/app.js index 3959abde7..84293f0f7 100644 --- a/examples/author/app.js +++ b/examples/author/app.js @@ -27,6 +27,8 @@ class App extends Texture { } } +App.Configurator = TextureConfigurator + if (typeof window !== 'undefined') { window.onload = function() { let configurator = new TextureConfigurator() diff --git a/examples/index.html b/examples/index.html index 112fb518d..d2f8e273a 100644 --- a/examples/index.html +++ b/examples/index.html @@ -3,4 +3,5 @@

      Texture Examples

      • Author - word-like editing interface
      • Publisher - QC-interface for publishers
      • +
      • Tagging - Experiment for post-conversion tagging UI
      diff --git a/examples/tagging/README.md b/examples/tagging/README.md new file mode 100644 index 000000000..45c820a7f --- /dev/null +++ b/examples/tagging/README.md @@ -0,0 +1,7 @@ +# Experimental UX for tagging + +The considered use-case is to start from a generated JATS file +e.g. from a DOCX converter. +The JATS content has structural issues, e.g., wrong section levels, detached figure captions, etc., which need to be corrected. + +The proposed UI let's the user select such content and apply certain tools that help to get from unstructured or wrong structured to well structured content. diff --git a/examples/tagging/TaggingPackage.js b/examples/tagging/TaggingPackage.js new file mode 100644 index 000000000..f016211ae --- /dev/null +++ b/examples/tagging/TaggingPackage.js @@ -0,0 +1,30 @@ +import AuthorExamplePackage from '../author/package' + +import TagAffCommand from './aff/TagAffCommand' +import TagAffTool from './aff/TagAffTool' +import TagRefCommand from './ref/TagRefCommand' +import TagRefTool from './ref/TagRefTool' +import TagContribCommand from './contrib/TagContribCommand' +import TagContribTool from './contrib/TagContribTool' + +export default { + name: 'tagging-example', + configure: function(config) { + config.import(AuthorExamplePackage) + + // Tagging + // ------- + // aff + config.addCommand('tag-aff', TagAffCommand); + config.addTool('tag-aff', TagAffTool); + config.addIcon('tag-aff', { 'fontawesome': 'fa-bullseye' }); + // ref + config.addCommand('tag-ref', TagRefCommand); + config.addTool('tag-ref', TagRefTool); + config.addIcon('tag-ref', { 'fontawesome': 'fa-bullseye' }); + //contrib + config.addCommand('tag-contrib', TagContribCommand); + config.addTool('tag-contrib', TagContribTool); + config.addIcon('tag-contrib', { 'fontawesome': 'fa-bullseye' }); + } +}; diff --git a/packages/jats/aff/TagAffCommand.js b/examples/tagging/aff/TagAffCommand.js similarity index 98% rename from packages/jats/aff/TagAffCommand.js rename to examples/tagging/aff/TagAffCommand.js index 79f1cbc6a..334634491 100644 --- a/packages/jats/aff/TagAffCommand.js +++ b/examples/tagging/aff/TagAffCommand.js @@ -1,5 +1,3 @@ -'use strict'; - import { Command, uuid, documentHelpers, deleteSelection } from 'substance' class TagAffCommand extends Command { diff --git a/packages/jats/aff/TagAffTool.js b/examples/tagging/aff/TagAffTool.js similarity index 86% rename from packages/jats/aff/TagAffTool.js rename to examples/tagging/aff/TagAffTool.js index acfda0bec..7e01a2de3 100644 --- a/packages/jats/aff/TagAffTool.js +++ b/examples/tagging/aff/TagAffTool.js @@ -1,5 +1,3 @@ -'use strict'; - import { Tool } from 'substance' class TagAffTool extends Tool {} diff --git a/examples/tagging/app.css b/examples/tagging/app.css new file mode 100644 index 000000000..d994158d6 --- /dev/null +++ b/examples/tagging/app.css @@ -0,0 +1,11 @@ +/* Substance Component styles */ +@import '../substance/substance.css'; +/* Texture Component styles */ +@import '../texture.css'; +/* You may want to use your own reset and pagestyle */ +@import '../substance/substance-reset.css'; +@import '../substance/substance-pagestyle.css'; +/* Using url here, so font-awesome does not get bundled. */ +@import url('../font-awesome/css/font-awesome.min.css'); +body { overflow: hidden; } +.sc-author { position: absolute; left: 0px; right: 0px; bottom: 0px; top: 0px; } \ No newline at end of file diff --git a/examples/tagging/app.js b/examples/tagging/app.js new file mode 100644 index 000000000..c39c953bb --- /dev/null +++ b/examples/tagging/app.js @@ -0,0 +1,14 @@ +import App from '../author/app' +import TaggingPackage from './TaggingPackage' + +if (typeof window !== 'undefined') { + window.onload = function() { + let configurator = new App.Configurator() + configurator.import(TaggingPackage) + var app = App.mount({ + configurator: configurator, + documentId: 'elife-00007' + }, document.body) + window.app = app + }; +} diff --git a/packages/jats/contrib/TagContribCommand.js b/examples/tagging/contrib/TagContribCommand.js similarity index 100% rename from packages/jats/contrib/TagContribCommand.js rename to examples/tagging/contrib/TagContribCommand.js diff --git a/packages/jats/contrib/TagContribTool.js b/examples/tagging/contrib/TagContribTool.js similarity index 100% rename from packages/jats/contrib/TagContribTool.js rename to examples/tagging/contrib/TagContribTool.js diff --git a/examples/tagging/index.html b/examples/tagging/index.html new file mode 100644 index 000000000..23acde600 --- /dev/null +++ b/examples/tagging/index.html @@ -0,0 +1,11 @@ + + + Texture -- Tagging + + + + + + + + diff --git a/packages/jats/ref/TagRefCommand.js b/examples/tagging/ref/TagRefCommand.js similarity index 100% rename from packages/jats/ref/TagRefCommand.js rename to examples/tagging/ref/TagRefCommand.js diff --git a/packages/jats/ref/TagRefTool.js b/examples/tagging/ref/TagRefTool.js similarity index 100% rename from packages/jats/ref/TagRefTool.js rename to examples/tagging/ref/TagRefTool.js diff --git a/packages/jats/aff/package.js b/packages/jats/aff/package.js index 809cc5990..6766cd3fa 100644 --- a/packages/jats/aff/package.js +++ b/packages/jats/aff/package.js @@ -1,10 +1,6 @@ -'use strict'; - import Aff from './Aff' import AffComponent from './AffComponent' import AffConverter from './AffConverter' -import TagAffCommand from './TagAffCommand' -import TagAffTool from './TagAffTool' export default { name: 'aff', @@ -12,8 +8,5 @@ export default { config.addNode(Aff) config.addComponent(Aff.type, AffComponent); config.addConverter('jats', AffConverter); - config.addCommand('tag-aff', TagAffCommand); - config.addTool('tag-aff', TagAffTool); - config.addIcon('tag-aff', { 'fontawesome': 'fa-bullseye' }); } } diff --git a/packages/jats/contrib/package.js b/packages/jats/contrib/package.js index 22c18af65..c38368ab5 100644 --- a/packages/jats/contrib/package.js +++ b/packages/jats/contrib/package.js @@ -1,8 +1,6 @@ import Contrib from './Contrib' import ContribComponent from './ContribComponent' import ContribConverter from './ContribConverter' -import TagContribCommand from './TagContribCommand' -import TagContribTool from './TagContribTool' export default { name: 'contrib', @@ -10,8 +8,5 @@ export default { config.addNode(Contrib); config.addComponent(Contrib.type, ContribComponent); config.addConverter('jats', ContribConverter); - config.addCommand('tag-contrib', TagContribCommand); - config.addTool('tag-contrib', TagContribTool); - config.addIcon('tag-contrib', { 'fontawesome': 'fa-bullseye' }); } } diff --git a/packages/jats/ref/Ref.js b/packages/jats/ref/Ref.js index 529a2bd3d..79a946410 100644 --- a/packages/jats/ref/Ref.js +++ b/packages/jats/ref/Ref.js @@ -1,5 +1,3 @@ -'use strict'; - import { DocumentNode, DefaultDOMElement as DOMElement } from 'substance' /* diff --git a/packages/jats/ref/RefComponent.js b/packages/jats/ref/RefComponent.js index 85ffc66fb..54f64aede 100644 --- a/packages/jats/ref/RefComponent.js +++ b/packages/jats/ref/RefComponent.js @@ -1,9 +1,6 @@ -'use strict'; - import { Component } from 'substance' import refToHTML from './refToHTML' - function RefComponent() { RefComponent.super.apply(this, arguments); } diff --git a/packages/jats/ref/RefConverter.js b/packages/jats/ref/RefConverter.js index 190f61ac9..5efee6346 100644 --- a/packages/jats/ref/RefConverter.js +++ b/packages/jats/ref/RefConverter.js @@ -1,5 +1,3 @@ -'use strict'; - export default { type: 'ref', @@ -16,4 +14,5 @@ export default { el.innerHTML = node.xmlContent; } -}; +} + diff --git a/packages/jats/ref/RefTarget.js b/packages/jats/ref/RefTarget.js index 7fd7278be..f4db38984 100644 --- a/packages/jats/ref/RefTarget.js +++ b/packages/jats/ref/RefTarget.js @@ -1,5 +1,3 @@ -'use strict'; - import { Component } from 'substance' import refToHTML from './refToHTML' diff --git a/packages/jats/ref/package.js b/packages/jats/ref/package.js index 91b74694f..0e84125f5 100644 --- a/packages/jats/ref/package.js +++ b/packages/jats/ref/package.js @@ -2,8 +2,6 @@ import Ref from './Ref' import RefComponent from './RefComponent' import RefTarget from './RefTarget' import RefConverter from './RefConverter' -import TagRefCommand from './TagRefCommand' -import TagRefTool from './TagRefTool' export default { name: 'ref', @@ -12,8 +10,5 @@ export default { config.addComponent(Ref.type, RefComponent); config.addComponent(Ref.type+'-target', RefTarget); config.addConverter('jats', RefConverter); - config.addCommand('tag-ref', TagRefCommand); - config.addTool('tag-ref', TagRefTool); - config.addIcon('tag-ref', { 'fontawesome': 'fa-bullseye' }); } } diff --git a/packages/jats/ref/refToHTML.js b/packages/jats/ref/refToHTML.js index a9ffe4322..d935dd383 100644 --- a/packages/jats/ref/refToHTML.js +++ b/packages/jats/ref/refToHTML.js @@ -1,5 +1,3 @@ -'use strict'; - import { DefaultDOMElement as DOMElement } from 'substance' /* From 87976d5888634e4814d099a9d0f9837b529e516b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 12 Sep 2016 20:45:42 +0200 Subject: [PATCH 076/167] Updated make --- make.js | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/make.js b/make.js index 9ed9fccc3..04463d621 100644 --- a/make.js +++ b/make.js @@ -19,10 +19,8 @@ b.task('substance', function() { b.copy('node_modules/substance/dist', './dist/substance') }) -var examples = ['author', 'publisher'] -// options for js bundling -examples.forEach(function(example) { - b.task(example, function() { +function buildExample(example) { + return function() { b.copy('examples/'+example+'/index.html', './dist/'+example+'/') b.copy('examples/'+example+'/*.css', './dist/'+example+'/', { root: 'examples/'+example }) b.js('examples/'+example+'/app.js', { @@ -34,21 +32,17 @@ examples.forEach(function(example) { format: 'umd', moduleName: example }) - }) -}) - -b.task('examples', examples) + } +} -b.task('minify:examples', function() { - examples.forEach(function(folder) { - b.minify('./dist/'+folder+'/app.js') - }) -}) +b.task('author', ['clean', 'substance', 'assets'], buildExample('author')) +b.task('publisher', ['clean', 'substance', 'assets'], buildExample('publisher')) +b.task('tagging', ['author'], buildExample('tagging')) -b.task('minify', ['minify:examples']) +b.task('examples', ['author', 'publisher', 'tagging']) // build all -b.task('default', (['clean', 'assets', 'substance', 'examples' /*, 'minify'*/])) +b.task('default', ['examples']) // starts a server when CLI argument '-s' is set b.setServerPort(5555) From 31183615362ec0815e93ca85838ea801427be740 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 12 Sep 2016 21:31:45 +0200 Subject: [PATCH 077/167] Get rid of express. --- examples/tagging/app.js | 2 +- index.js | 5 ----- package.json | 1 - server.js | 39 --------------------------------------- 4 files changed, 1 insertion(+), 46 deletions(-) delete mode 100644 index.js delete mode 100644 server.js diff --git a/examples/tagging/app.js b/examples/tagging/app.js index c39c953bb..8f04bbb2b 100644 --- a/examples/tagging/app.js +++ b/examples/tagging/app.js @@ -7,7 +7,7 @@ if (typeof window !== 'undefined') { configurator.import(TaggingPackage) var app = App.mount({ configurator: configurator, - documentId: 'elife-00007' + documentId: 'kitchen-sink-author' }, document.body) window.app = app }; diff --git a/index.js b/index.js deleted file mode 100644 index 7b10c3159..000000000 --- a/index.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -var Scientist = require('./packages/scientist/Scientist'); - -module.exports = Scientist; \ No newline at end of file diff --git a/package.json b/package.json index 595c7a976..06e5731d4 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ }, "devDependencies": { "eslint": "^3.2.2", - "express": "4.13.4", "font-awesome": "4.5.0", "substance-bundler": "*", "tap-spec": "4.1.1", diff --git a/server.js b/server.js deleted file mode 100644 index 4982e30c7..000000000 --- a/server.js +++ /dev/null @@ -1,39 +0,0 @@ -'use strict'; - -/* eslint-disable no-console */ -var express = require('express'); -var path = require('path'); -var PORT = process.env.PORT || 5001; -var serverUtils = require('substance/util/server'); -var app = express(); - -var browserifyConfig = { - debug: true -}; - -serverUtils.serveJS(app, '/publisher/app.js', { - sourcePath: path.join(__dirname, 'examples/publisher', 'app.js'), - browserify: browserifyConfig, -}); -serverUtils.serveHTML(app, '/publisher', path.join(__dirname, 'examples/publisher', 'index.html'), {}); - -serverUtils.serveJS(app, '/author/app.js', { - sourcePath: path.join(__dirname, 'examples/author', 'app.js'), - browserify: browserifyConfig, -}); -serverUtils.serveHTML(app, '/author', path.join(__dirname, 'examples/author', 'index.html'), {}); - -// static served data -app.use('/data', express.static(path.join(__dirname, 'examples/data'))); -app.use(express.static(path.join(__dirname, 'examples'))); -app.use('/fonts', express.static(path.join(__dirname, 'node_modules/font-awesome/fonts'))); - -app.use(express.static(__dirname)); -app.use('/substance', express.static(path.join(__dirname, 'node_modules/substance'))); -app.use('/font-awesome', express.static(path.join(__dirname, 'node_modules/font-awesome'))); - -serverUtils.serveTestSuite(app, "test/**/*.test.js"); - -app.listen(PORT); -console.log('Server is listening on %s', PORT); -console.log('To view the docs go to http://localhost:%s', PORT); From 33f72c2aed161a279feefb661fcdf60bb7cc6603 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 12 Sep 2016 21:47:32 +0200 Subject: [PATCH 078/167] Switch to substance#develop. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 06e5731d4..9d8385179 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "A scientific editor and reader for JATS files.", "dependencies": { "lodash": "^4.14.1", - "substance": "substance/substance#jsnext" + "substance": "substance/substance#develop" }, "devDependencies": { "eslint": "^3.2.2", From 25af297c68b565cdaa299c043ed16bf7fe3377ce Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Mon, 12 Sep 2016 21:51:57 +0200 Subject: [PATCH 079/167] Specify start script. --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 9d8385179..ec3daaaa4 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ }, "scripts": { "bundle": "node make", + "start": "node make -s -w", "test": "gulp test" }, "version": "1.0.0-alpha.2" From b299cb96a3c75620700b0ca43911e4afa53e3be0 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 13 Sep 2016 15:45:44 +0200 Subject: [PATCH 080/167] Updated package.json - bumped substance-bundler - removed uglify-js --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index ec3daaaa4..d22d2d8d5 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,9 @@ "devDependencies": { "eslint": "^3.2.2", "font-awesome": "4.5.0", - "substance-bundler": "*", + "substance-bundler": "^0.4.12", "tap-spec": "4.1.1", - "tape": "4.5.1", - "uglify-js": "^2.7.3" + "tape": "4.5.1" }, "scripts": { "bundle": "node make", From e4ac3f217091b8e57907deedc6c583cd0cb9d4d8 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 14 Sep 2016 10:45:54 +0200 Subject: [PATCH 081/167] Add support for tool targets. --- .eslintrc.js | 3 +- examples/data/kitchen-sink-author.xml | 4 +- examples/tagging/TaggingPackage.js | 16 ++++++-- make.js | 2 +- packages/author/package.js | 2 +- packages/common/TextureToolbar.js | 53 +++++++++++++++++++++++++ packages/common/package.js | 6 ++- packages/publisher/package.js | 4 +- packages/texture/TextureConfigurator.js | 8 ++-- 9 files changed, 81 insertions(+), 17 deletions(-) create mode 100644 packages/common/TextureToolbar.js diff --git a/.eslintrc.js b/.eslintrc.js index 7bb3185a7..10a9af88f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -10,7 +10,8 @@ module.exports = { }, "extends": "eslint:recommended", "globals": { - "Promise": true + "Promise": true, + "Map": true }, "rules": { // 0 - off, 1 - warning, 2 - error diff --git a/examples/data/kitchen-sink-author.xml b/examples/data/kitchen-sink-author.xml index 7742bea5a..b88037101 100644 --- a/examples/data/kitchen-sink-author.xml +++ b/examples/data/kitchen-sink-author.xml @@ -29,8 +29,8 @@ Introduction -

      Texture is a tool for publishers for creating structured JATS documents based on Word or InDesign submissions.

      -

      The original document is imported with annotations preserved. Then the user starts tagging semantic entities in the document, such as marking up the reference list, the authors, affiliations etc. Saving the document produces valid JATS 1.1 XML.

      +

      Texture is a tool for publishers to creating structured JATS documents based on Word or InDesign submissions.

      +

      The original document is imported with annotations preserved. Then the user starts tagging semantic entities in the document, such as marking up the reference list, the authors, affiliations etc. Saving the document produces valid JATS 1.1 XML ([1]).

      Create a bibliography diff --git a/examples/tagging/TaggingPackage.js b/examples/tagging/TaggingPackage.js index f016211ae..d1f5e3b8b 100644 --- a/examples/tagging/TaggingPackage.js +++ b/examples/tagging/TaggingPackage.js @@ -1,5 +1,5 @@ import AuthorExamplePackage from '../author/package' - +import { ToolDropdown } from 'substance' import TagAffCommand from './aff/TagAffCommand' import TagAffTool from './aff/TagAffTool' import TagRefCommand from './ref/TagRefCommand' @@ -14,17 +14,25 @@ export default { // Tagging // ------- + + // Needed by TextureToolbar (lookup via tool-target-{targetname}) + config.addComponent('tool-target-tag', ToolDropdown); + config.addIcon('tool-target-tag', { 'fontawesome': 'fa-bullseye' }); + // aff config.addCommand('tag-aff', TagAffCommand); - config.addTool('tag-aff', TagAffTool); + config.addTool('tag-aff', TagAffTool, {target: 'tag'}); config.addIcon('tag-aff', { 'fontawesome': 'fa-bullseye' }); // ref config.addCommand('tag-ref', TagRefCommand); - config.addTool('tag-ref', TagRefTool); + config.addTool('tag-ref', TagRefTool, {target: 'tag'}); + config.addIcon('tag-ref', { 'fontawesome': 'fa-bullseye' }); + config.addLabel('tag-ref', 'Reference'); //contrib config.addCommand('tag-contrib', TagContribCommand); - config.addTool('tag-contrib', TagContribTool); + config.addTool('tag-contrib', TagContribTool, {target: 'tag'}); config.addIcon('tag-contrib', { 'fontawesome': 'fa-bullseye' }); } }; + diff --git a/make.js b/make.js index 04463d621..c1929a1c9 100644 --- a/make.js +++ b/make.js @@ -25,7 +25,7 @@ function buildExample(example) { b.copy('examples/'+example+'/*.css', './dist/'+example+'/', { root: 'examples/'+example }) b.js('examples/'+example+'/app.js', { // need buble if we want to minify later - buble: true, + // buble: true, external: ['substance'], commonjs: { include: ['node_modules/lodash/**'] }, dest: './dist/'+example+'/app.js', diff --git a/packages/author/package.js b/packages/author/package.js index be9289055..c3926ab45 100644 --- a/packages/author/package.js +++ b/packages/author/package.js @@ -1,4 +1,4 @@ -import { Toolbar, BasePackage, PersistencePackage } from 'substance' +import { BasePackage, PersistencePackage } from 'substance' import AuthorImporter from './AuthorImporter' import AuthorExporter from './AuthorExporter' import JATSPackage from '../jats/package' diff --git a/packages/common/TextureToolbar.js b/packages/common/TextureToolbar.js new file mode 100644 index 000000000..aa6eec11d --- /dev/null +++ b/packages/common/TextureToolbar.js @@ -0,0 +1,53 @@ +import { Component, ToolGroup } from 'substance' + +class TextureToolbar extends Component { + render($$) { + var el = $$("div").addClass(this.getClassNames()) + var commandStates = this.props.commandStates + var componentRegistry = this.context.componentRegistry + var toolTargets = this.context.tools + var toolEls = [] + + toolTargets.forEach(function(tools, target) { + if (target === 'overlay') return; + + var TargetWrapperClass = componentRegistry.get('tool-target-'+target) + if (TargetWrapperClass) { + // If target wrapper component found (e.g. ToolDropDown) tools + // get wrapped in it + var wrapperEl = $$(TargetWrapperClass, { + name: 'tool-target-'+target + }) + tools.forEach(function(tool, name) { + var toolProps = commandStates[name] + // HACK: Also always include tool name which is equal to command name + toolProps.name = name + wrapperEl.append( + $$(tool.Class, toolProps) + ) + }) + toolEls.push(wrapperEl) + } else { + // Default: Render tool target flat + tools.forEach(function(tool, name) { + var toolProps = commandStates[name] + // HACK: Also always include tool name which is equal to command name + toolProps.name = name + toolEls.push( + $$(tool.Class, toolProps) + ) + }) + } + }) + el.append( + $$(ToolGroup).append(toolEls) + ) + return el + } + + getClassNames() { + return 'sc-toolbar'; + } +} + +export default TextureToolbar; diff --git a/packages/common/package.js b/packages/common/package.js index 9d5c08079..344579db0 100644 --- a/packages/common/package.js +++ b/packages/common/package.js @@ -1,4 +1,8 @@ +import TextureToolbar from './TextureToolbar' + export default { name: 'common', - configure: function() {} + configure: function(config) { + config.setToolbarClass(TextureToolbar) + } } diff --git a/packages/publisher/package.js b/packages/publisher/package.js index 5b43e962c..9a3a2390f 100644 --- a/packages/publisher/package.js +++ b/packages/publisher/package.js @@ -1,4 +1,4 @@ -import { Overlay, Toolbar, BasePackage, PersistencePackage } from 'substance' +import { Overlay, BasePackage, PersistencePackage } from 'substance' import JATSPackage from '../jats/package' import CommonPackage from '../common/package' import InlineWrapperPackage from '../inline-wrapper/InlineWrapperPackage' @@ -11,8 +11,6 @@ export default { config.import(PersistencePackage); // TODO: see substance#712 config.addComponent('overlay', Overlay); - // TODO: this should be used as default, too - config.setToolbarClass(Toolbar); config.import(JATSPackage); config.import(CommonPackage); diff --git a/packages/texture/TextureConfigurator.js b/packages/texture/TextureConfigurator.js index d16954aa8..1b5e80e0f 100644 --- a/packages/texture/TextureConfigurator.js +++ b/packages/texture/TextureConfigurator.js @@ -10,14 +10,14 @@ class TextureConfigurator extends Configurator { } setXMLStore(XMLStoreClass) { - this.config.XMLStoreClass = XMLStoreClass; + this.config.XMLStoreClass = XMLStoreClass } getXMLStore() { - var XMLStoreClass = this.config.XMLStoreClass; - return new XMLStoreClass(); + var XMLStoreClass = this.config.XMLStoreClass + return new XMLStoreClass() } } -export default TextureConfigurator +export default TextureConfigurator \ No newline at end of file From e8c98ca372e4d3804800daead0507f8a668551d7 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 14 Sep 2016 11:32:33 +0200 Subject: [PATCH 082/167] Updated package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d22d2d8d5..bf696d88c 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "devDependencies": { "eslint": "^3.2.2", "font-awesome": "4.5.0", - "substance-bundler": "^0.4.12", + "substance-bundler": "^0.4.16", "tap-spec": "4.1.1", "tape": "4.5.1" }, From 7ff5af9ccf84bb74bbdaaa976f98507cf14be737 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sat, 17 Sep 2016 19:37:58 +0200 Subject: [PATCH 083/167] Make use of new tool target support. --- examples/tagging/TaggingPackage.js | 31 ++++++++------- packages/common/TextureToolbar.js | 53 -------------------------- packages/common/_index.css | 3 +- packages/common/_toolbar.css | 4 ++ packages/common/package.js | 5 ++- packages/jats/article-title/package.js | 1 + packages/jats/article/_index.css | 2 + packages/jats/bold/package.js | 2 +- packages/jats/ext-link/package.js | 4 +- packages/jats/italic/ItalicCommand.js | 5 +++ packages/jats/italic/ItalicTool.js | 5 +++ packages/jats/italic/package.js | 15 ++++++-- packages/jats/package.js | 2 +- packages/jats/xref/package.js | 19 ++++----- 14 files changed, 66 insertions(+), 85 deletions(-) delete mode 100644 packages/common/TextureToolbar.js create mode 100644 packages/common/_toolbar.css create mode 100644 packages/jats/italic/ItalicCommand.js create mode 100644 packages/jats/italic/ItalicTool.js diff --git a/examples/tagging/TaggingPackage.js b/examples/tagging/TaggingPackage.js index d1f5e3b8b..be780c335 100644 --- a/examples/tagging/TaggingPackage.js +++ b/examples/tagging/TaggingPackage.js @@ -16,23 +16,28 @@ export default { // ------- // Needed by TextureToolbar (lookup via tool-target-{targetname}) - config.addComponent('tool-target-tag', ToolDropdown); - config.addIcon('tool-target-tag', { 'fontawesome': 'fa-bullseye' }); + config.addComponent('tool-target-tag', ToolDropdown) + config.addIcon('tool-target-tag', { 'fontawesome': 'fa-bullseye' }) + config.addLabel('tag', 'Tag') // aff - config.addCommand('tag-aff', TagAffCommand); - config.addTool('tag-aff', TagAffTool, {target: 'tag'}); - config.addIcon('tag-aff', { 'fontawesome': 'fa-bullseye' }); + config.addCommand('tag-aff', TagAffCommand) + config.addTool('tag-aff', TagAffTool, {target: 'tag'}) + config.addIcon('tag-aff', { 'fontawesome': 'fa-bullseye' }) + config.addLabel('tag-aff', 'Affiliation') + // ref - config.addCommand('tag-ref', TagRefCommand); - config.addTool('tag-ref', TagRefTool, {target: 'tag'}); + config.addCommand('tag-ref', TagRefCommand) + config.addTool('tag-ref', TagRefTool, {target: 'tag'}) + + config.addIcon('tag-ref', { 'fontawesome': 'fa-bullseye' }) + config.addLabel('tag-ref', 'Reference') - config.addIcon('tag-ref', { 'fontawesome': 'fa-bullseye' }); - config.addLabel('tag-ref', 'Reference'); //contrib - config.addCommand('tag-contrib', TagContribCommand); - config.addTool('tag-contrib', TagContribTool, {target: 'tag'}); - config.addIcon('tag-contrib', { 'fontawesome': 'fa-bullseye' }); + config.addCommand('tag-contrib', TagContribCommand) + config.addTool('tag-contrib', TagContribTool, {target: 'tag'}) + config.addIcon('tag-contrib', { 'fontawesome': 'fa-bullseye' }) + config.addLabel('tag-contrib', 'Author') } -}; +} diff --git a/packages/common/TextureToolbar.js b/packages/common/TextureToolbar.js deleted file mode 100644 index aa6eec11d..000000000 --- a/packages/common/TextureToolbar.js +++ /dev/null @@ -1,53 +0,0 @@ -import { Component, ToolGroup } from 'substance' - -class TextureToolbar extends Component { - render($$) { - var el = $$("div").addClass(this.getClassNames()) - var commandStates = this.props.commandStates - var componentRegistry = this.context.componentRegistry - var toolTargets = this.context.tools - var toolEls = [] - - toolTargets.forEach(function(tools, target) { - if (target === 'overlay') return; - - var TargetWrapperClass = componentRegistry.get('tool-target-'+target) - if (TargetWrapperClass) { - // If target wrapper component found (e.g. ToolDropDown) tools - // get wrapped in it - var wrapperEl = $$(TargetWrapperClass, { - name: 'tool-target-'+target - }) - tools.forEach(function(tool, name) { - var toolProps = commandStates[name] - // HACK: Also always include tool name which is equal to command name - toolProps.name = name - wrapperEl.append( - $$(tool.Class, toolProps) - ) - }) - toolEls.push(wrapperEl) - } else { - // Default: Render tool target flat - tools.forEach(function(tool, name) { - var toolProps = commandStates[name] - // HACK: Also always include tool name which is equal to command name - toolProps.name = name - toolEls.push( - $$(tool.Class, toolProps) - ) - }) - } - }) - el.append( - $$(ToolGroup).append(toolEls) - ) - return el - } - - getClassNames() { - return 'sc-toolbar'; - } -} - -export default TextureToolbar; diff --git a/packages/common/_index.css b/packages/common/_index.css index 255ec51b9..f0ef5fcd6 100644 --- a/packages/common/_index.css +++ b/packages/common/_index.css @@ -1,2 +1,3 @@ @import './_edit-xml.css'; -@import './_isolated-node.css'; \ No newline at end of file +@import './_isolated-node.css'; +@import './_toolbar.css'; \ No newline at end of file diff --git a/packages/common/_toolbar.css b/packages/common/_toolbar.css new file mode 100644 index 000000000..777e5cbf2 --- /dev/null +++ b/packages/common/_toolbar.css @@ -0,0 +1,4 @@ +/* Toolbar style overrides */ +.sc-toolbar { + +} \ No newline at end of file diff --git a/packages/common/package.js b/packages/common/package.js index 344579db0..36d5961ea 100644 --- a/packages/common/package.js +++ b/packages/common/package.js @@ -1,8 +1,9 @@ -import TextureToolbar from './TextureToolbar' +import { ToolDropdown } from 'substance' export default { name: 'common', configure: function(config) { - config.setToolbarClass(TextureToolbar) + config.addComponent('tool-target-insert', ToolDropdown) + config.addLabel('insert', 'Insert'); } } diff --git a/packages/jats/article-title/package.js b/packages/jats/article-title/package.js index fb19279e4..ec61c4d90 100644 --- a/packages/jats/article-title/package.js +++ b/packages/jats/article-title/package.js @@ -10,5 +10,6 @@ export default { config.addNode(ArticleTitle); config.addConverter('jats', ArticleTitleConverter); config.addComponent(ArticleTitle.type, ArticleTitleComponent); + config.addLabel('article-title.content', 'Title'); } } diff --git a/packages/jats/article/_index.css b/packages/jats/article/_index.css index d81d4bedf..2ddc7b823 100644 --- a/packages/jats/article/_index.css +++ b/packages/jats/article/_index.css @@ -1,4 +1,6 @@ .sc-article { + padding-top: 20px; + padding-bottom: 20px; padding-left: 20px; padding-right: 20px; } \ No newline at end of file diff --git a/packages/jats/bold/package.js b/packages/jats/bold/package.js index 7db830e53..8ee9fc245 100644 --- a/packages/jats/bold/package.js +++ b/packages/jats/bold/package.js @@ -11,7 +11,7 @@ export default { config.addNode(Bold); config.addConverter('jats', BoldConverter); config.addCommand(Bold.type, BoldCommand, { nodeType: Bold.type }); - config.addTool(Bold.type, BoldTool); + config.addTool(Bold.type, BoldTool, {target: 'annotations'}); config.addIcon(Bold.type, { 'fontawesome': 'fa-bold' }); config.addLabel(Bold.type, { en: 'Bold' diff --git a/packages/jats/ext-link/package.js b/packages/jats/ext-link/package.js index 94be87aac..be9973660 100644 --- a/packages/jats/ext-link/package.js +++ b/packages/jats/ext-link/package.js @@ -15,8 +15,8 @@ export default { config.addComponent(ExtLink.type, ExtLinkComponent); config.addCommand(ExtLink.type, ExtLinkCommand, {nodeType: ExtLink.type}); - config.addTool(ExtLink.type, ExtLinkTool); - config.addTool('edit-ext-link', EditExtLinkTool, { overlay: true }); + config.addTool(ExtLink.type, ExtLinkTool, {target: 'annotations'}); + config.addTool('edit-ext-link', EditExtLinkTool, { target: 'overlay' }); config.addIcon(ExtLink.type, { 'fontawesome': 'fa-link'}); config.addIcon('open-link', { 'fontawesome': 'fa-external-link' }); config.addLabel(ExtLink.type, { diff --git a/packages/jats/italic/ItalicCommand.js b/packages/jats/italic/ItalicCommand.js new file mode 100644 index 000000000..f2f815a0f --- /dev/null +++ b/packages/jats/italic/ItalicCommand.js @@ -0,0 +1,5 @@ +import { AnnotationCommand } from 'substance' + +class ItalicCommand extends AnnotationCommand {} + +export default ItalicCommand; \ No newline at end of file diff --git a/packages/jats/italic/ItalicTool.js b/packages/jats/italic/ItalicTool.js new file mode 100644 index 000000000..ab13e5735 --- /dev/null +++ b/packages/jats/italic/ItalicTool.js @@ -0,0 +1,5 @@ +import { AnnotationTool } from 'substance' + +class ItalicTool extends AnnotationTool {} + +export default ItalicTool; \ No newline at end of file diff --git a/packages/jats/italic/package.js b/packages/jats/italic/package.js index 242af3831..32d2dbe3c 100644 --- a/packages/jats/italic/package.js +++ b/packages/jats/italic/package.js @@ -2,11 +2,20 @@ import Italic from './Italic' import ItalicConverter from './ItalicConverter' +import ItalicTool from './ItalicTool' +import ItalicCommand from './ItalicCommand' export default { name: 'italic', configure: function(config) { - config.addNode(Italic); - config.addConverter('jats', ItalicConverter); + config.addNode(Italic) + config.addConverter('jats', ItalicConverter) + + config.addCommand(Italic.type, ItalicCommand, { nodeType: Italic.type }) + config.addTool(Italic.type, ItalicTool, {target: 'annotations'}) + config.addIcon(Italic.type, { 'fontawesome': 'fa-italic' }) + config.addLabel(Italic.type, { + en: 'Italic' + }) } -}; +} diff --git a/packages/jats/package.js b/packages/jats/package.js index 58658141f..d880b4fb3 100644 --- a/packages/jats/package.js +++ b/packages/jats/package.js @@ -43,13 +43,13 @@ export default { config.import(BackPackage) config.import(BodyPackage) config.import(BoldPackage) + config.import(ItalicPackage) config.import(CaptionPackage) config.import(ExtLinkPackage) config.import(FigurePackage) config.import(FootnotePackage) config.import(FrontPackage) config.import(GraphicPackage) - config.import(ItalicPackage) config.import(LabelPackage) config.import(MonospacePackage) config.import(ParagraphPackage) diff --git a/packages/jats/xref/package.js b/packages/jats/xref/package.js index ebcc1b530..1527c2390 100644 --- a/packages/jats/xref/package.js +++ b/packages/jats/xref/package.js @@ -14,20 +14,21 @@ export default { config.addConverter('jats', XRefConverter); // TODO: is there a way to use only one command for the two different tools - config.addCommand(XRef.type, XRefCommand, {nodeType: XRef.type}); - config.addCommand('add-xref', AddXRefCommand, {nodeType: XRef.type}); - config.addTool('add-xref', AddXRefTool); - config.addTool(XRef.type, XRefTool, { overlay: true }); + config.addCommand(XRef.type, XRefCommand, {nodeType: XRef.type}) + config.addCommand('add-xref', AddXRefCommand, {nodeType: XRef.type}) + config.addTool('add-xref', AddXRefTool, {target: 'insert'}) + config.addTool(XRef.type, XRefTool, { overlay: true }) + config.addLabel('add-xref', 'Cross Reference') - config.addIcon('add-xref', { 'fontawesome': 'fa-external-link' }); + config.addIcon('add-xref', { 'fontawesome': 'fa-external-link' }) config.addLabel(XRef.type, { en: 'Cross Reference' - }); + }) config.addLabel('edit-xref', { en: 'Edit Reference' - }); + }) config.addLabel('delete-xref', { en: 'Delete Reference' - }); + }) } -}; +} From 0febb2188b0bcc41785b56a1890dd32e4964f387 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sat, 17 Sep 2016 19:53:22 +0200 Subject: [PATCH 084/167] Add some separators to Texture toolbar. --- packages/common/_toolbar.css | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/common/_toolbar.css b/packages/common/_toolbar.css index 777e5cbf2..74d732536 100644 --- a/packages/common/_toolbar.css +++ b/packages/common/_toolbar.css @@ -1,4 +1,16 @@ /* Toolbar style overrides */ -.sc-toolbar { +.sc-toolbar .sc-tool-group.sm-target-document { + /*background: blue;*/ + padding-right: 5px; + border-right: 1px solid var(--border-color); +} +.sc-toolbar .sc-tool-group.sm-target-text { + border-right: 1px solid var(--border-color); +} + +.sc-toolbar .sm-target-insert { + padding-left: 7px; + margin-left: 5px; + border-left: 1px solid var(--border-color); } \ No newline at end of file From 3690a881a357aa31cd3e7ebf8e03121bb281953d Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sun, 18 Sep 2016 19:47:18 +0200 Subject: [PATCH 085/167] Get Modal, Prompt, etc. from componentRegistry. --- packages/jats/contrib/ContribComponent.js | 3 ++- packages/jats/contrib/EditContrib.js | 5 ++++- packages/jats/xref/XRefTool.js | 5 ++++- packages/publisher/Publisher.js | 6 +++++- packages/unsupported/UnsupportedInlineNodeTool.js | 4 +++- 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/jats/contrib/ContribComponent.js b/packages/jats/contrib/ContribComponent.js index 00a767d00..6e9c98e97 100644 --- a/packages/jats/contrib/ContribComponent.js +++ b/packages/jats/contrib/ContribComponent.js @@ -1,6 +1,6 @@ 'use strict'; -import { Component, Modal } from 'substance' +import { Component } from 'substance' import EditXML from '../../common/EditXML' import EditContrib from './EditContrib' import { getAdapter } from './contribUtils' @@ -19,6 +19,7 @@ function ContribComponent() { ContribComponent.Prototype = function() { this.render = function($$) { + var Modal = this.getComponent('modal'); var contrib = getAdapter(this.props.node); var el = $$('div').addClass('sc-contrib') .append( diff --git a/packages/jats/contrib/EditContrib.js b/packages/jats/contrib/EditContrib.js index 2c1c67fbe..be553cd77 100644 --- a/packages/jats/contrib/EditContrib.js +++ b/packages/jats/contrib/EditContrib.js @@ -1,6 +1,6 @@ 'use strict'; -import { Component, Input, Button } from 'substance' +import { Component } from 'substance' import { saveContrib } from './contribUtils' class EditContrib extends Component { @@ -10,6 +10,9 @@ class EditContrib extends Component { } render($$) { + var Input = this.getComponent('input'); + var Button = this.getComponent('button'); + var el = $$('div').addClass('sc-edit-contrib'); var affs = this.props.affs; var fullName = this.props.fullName; diff --git a/packages/jats/xref/XRefTool.js b/packages/jats/xref/XRefTool.js index 3bfa73b2f..5c89394e3 100644 --- a/packages/jats/xref/XRefTool.js +++ b/packages/jats/xref/XRefTool.js @@ -1,7 +1,7 @@ 'use strict'; import clone from 'lodash/clone' -import { deleteSelection, Modal, Prompt, Tool } from 'substance' +import { deleteSelection, Tool } from 'substance' import XRefTargets from './XRefTargets' /* @@ -19,6 +19,9 @@ function XRefTool() { XRefTool.Prototype = function() { this.render = function($$) { + var Modal = this.getComponent('modal'); + var Prompt = this.getComponent('prompt'); + // if ($$.capturing) console.log("Rendering XRefTool, state=", this.state); var node = this.props.node; var el = $$('div').addClass('sc-xref-tool'); diff --git a/packages/publisher/Publisher.js b/packages/publisher/Publisher.js index 2f78a5d3d..b47786006 100644 --- a/packages/publisher/Publisher.js +++ b/packages/publisher/Publisher.js @@ -1,4 +1,4 @@ -import { SplitPane, ScrollPane, Layout, Overlay, TOC } from 'substance' +import { Overlay, TOC } from 'substance' import AbstractWriter from '../common/AbstractWriter' import PublisherTOCProvider from './PublisherTOCProvider' @@ -9,6 +9,7 @@ function PublisherWriter() { PublisherWriter.Prototype = function() { this.render = function($$) { + var SplitPane = this.getComponent('split-pane'); var el = $$('div').addClass('sc-publisher'); el.append( $$(SplitPane, {splitType: 'vertical', sizeB: '400px'}).append( @@ -26,6 +27,7 @@ PublisherWriter.Prototype = function() { }; this._renderMainSection = function($$) { + var SplitPane = this.getComponent('split-pane'); var mainSection = $$('div').addClass('se-main-section'); var splitPane = $$(SplitPane, {splitType: 'horizontal'}).append( this._renderToolbar($$), @@ -37,6 +39,8 @@ PublisherWriter.Prototype = function() { this._renderContentPanel = function($$) { var doc = this.documentSession.getDocument(); + var Layout = this.getComponent('layout'); + var ScrollPane = this.getComponent('scroll-pane'); var contentPanel = $$(ScrollPane, { tocProvider: this.tocProvider, diff --git a/packages/unsupported/UnsupportedInlineNodeTool.js b/packages/unsupported/UnsupportedInlineNodeTool.js index a4998a1f3..3e0a9f508 100644 --- a/packages/unsupported/UnsupportedInlineNodeTool.js +++ b/packages/unsupported/UnsupportedInlineNodeTool.js @@ -1,5 +1,5 @@ +import { Tool, deleteSelection } from 'substance' import clone from 'lodash/clone' -import { Modal, Prompt, Tool, deleteSelection } from 'substance' import EditXML from '../common/EditXML' /* @@ -38,6 +38,8 @@ UnsupportedInlineNodeTool.Prototype = function() { this.render = function($$) { var el = $$('div').addClass('sc-unsupported-node-tool'); var node = this.props.node; + var Modal = this.getComponent('modal'); + var Prompt = this.getComponent('prompt'); el.append( $$(Prompt).append( From 8316cb60a0847c1cc66143dc2c93190ac546e989 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Mon, 19 Sep 2016 22:36:16 +0300 Subject: [PATCH 086/167] ES6 AnnotationCommand. --- packages/jats/bold/BoldCommand.js | 8 ++------ packages/jats/ext-link/ExtLinkCommand.js | 17 ++++++----------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/packages/jats/bold/BoldCommand.js b/packages/jats/bold/BoldCommand.js index 674309f5a..f7b663890 100644 --- a/packages/jats/bold/BoldCommand.js +++ b/packages/jats/bold/BoldCommand.js @@ -2,10 +2,6 @@ import { AnnotationCommand } from 'substance' -function BoldCommand() { - BoldCommand.super.apply(this, arguments); -} +class BoldCommand extends AnnotationCommand {} -AnnotationCommand.extend(BoldCommand); - -export default BoldCommand; \ No newline at end of file +export default BoldCommand diff --git a/packages/jats/ext-link/ExtLinkCommand.js b/packages/jats/ext-link/ExtLinkCommand.js index c32c094fd..5a5de3f3f 100644 --- a/packages/jats/ext-link/ExtLinkCommand.js +++ b/packages/jats/ext-link/ExtLinkCommand.js @@ -2,20 +2,15 @@ import { LinkPackage } from 'substance' -function ExtLinkCommand() { - ExtLinkCommand.super.apply(this, arguments); -} +class ExtLinkCommand extends LinkPackage.LinkCommand { -ExtLinkCommand.Prototype = function() { - this.getAnnotationData = function() { + getAnnotationData() { return { attributes: { 'xlink:href': '' } - }; - }; -}; - -LinkPackage.LinkCommand.extend(ExtLinkCommand); + } + } +} -export default ExtLinkCommand; \ No newline at end of file +export default ExtLinkCommand \ No newline at end of file From 6c83b052c06fe9df18eecc682fe5b79cae632540 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Mon, 19 Sep 2016 23:27:28 +0300 Subject: [PATCH 087/167] ES6 ProseEditor. --- packages/common/AbstractWriter.js | 111 ++++++++++++++---------------- 1 file changed, 53 insertions(+), 58 deletions(-) diff --git a/packages/common/AbstractWriter.js b/packages/common/AbstractWriter.js index 4787f290e..7796f38b2 100644 --- a/packages/common/AbstractWriter.js +++ b/packages/common/AbstractWriter.js @@ -5,67 +5,62 @@ const ProseEditor = ProseEditorPackage.ProseEditor // TODO: we need to think if it is really a good idea to // derive from ProseEditor here // There would be a lot of code redundancy -function AbstractWriter() { - AbstractWriter.super.apply(this, arguments); - - this.handleActions({ - 'tocEntrySelected': this.tocEntrySelected - }); -} - -AbstractWriter.Prototype = function() { - - var _super = AbstractWriter.super.prototype; - - this._initialize = function() { - _super._initialize.apply(this, arguments); - - this.exporter = this._getExporter(); - this.tocProvider = this._getTOCProvider(); - this.saveHandler = this._getSaveHandler(); - this.documentSession.setSaveHandler(this.saveHandler); - }; - - this.getChildContext = function() { - var childContext = _super.getChildContext.apply(this, arguments); - childContext.tocProvider = this.tocProvider; - return childContext; - }; - - this._renderToolbar = function($$) { // eslint-disable-line - return _super._renderToolbar.apply(this, arguments); - }; - - this._renderContentPanel = function($$) { // eslint-disable-line - throw new Error("This method is abstract."); - }; - - this.tocEntrySelected = function(nodeId) { - return this._scrollTo(nodeId); - }; - - this._scrollTo = function(nodeId) { // eslint-disable-line - throw new Error("This method is abstract."); - }; - - this._getExporter = function() { - throw new Error("This method is abstract."); - }; - - this._getTOCProvider = function() { - throw new Error("This method is abstract."); - }; - - this._getSaveHandler = function() { +class AbstractWriter extends ProseEditor { + constructor(...args) { + super(...args) + + this.handleActions({ + 'tocEntrySelected': this.tocEntrySelected + }) + } + + _initialize() { + super._initialize.apply(this, arguments); + + this.exporter = this._getExporter() + this.tocProvider = this._getTOCProvider() + this.saveHandler = this._getSaveHandler() + this.documentSession.setSaveHandler(this.saveHandler) + } + + getChildContext() { + let childContext = super.getChildContext.apply(this, arguments) + childContext.tocProvider = this.tocProvider + return childContext + } + + _renderToolbar($$) { // eslint-disable-line + return super._renderToolbar.apply(this, arguments) + } + + _renderContentPanel($$) { // eslint-disable-line + throw new Error("This method is abstract.") + } + + tocEntrySelected(nodeId) { + return this._scrollTo(nodeId) + } + + _scrollTo(nodeId) { // eslint-disable-line + throw new Error("This method is abstract.") + } + + _getExporter() { + throw new Error("This method is abstract.") + } + + _getTOCProvider() { + throw new Error("This method is abstract.") + } + + _getSaveHandler() { return new SaveHandler({ documentId: this.props.documentId, xmlStore: this.context.xmlStore, exporter: this.exporter - }); - }; + }) + } -}; - -ProseEditor.extend(AbstractWriter); +} -export default AbstractWriter; +export default AbstractWriter From c3b08fc53e0d71fd17bbde88d3e041d88a14986e Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Mon, 19 Sep 2016 23:38:11 +0300 Subject: [PATCH 088/167] ES6 AnnotationTool. --- packages/jats/bold/BoldTool.js | 9 ++------- packages/jats/ext-link/ExtLinkTool.js | 10 ++-------- packages/jats/xref/AddXRefTool.js | 6 +----- 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/packages/jats/bold/BoldTool.js b/packages/jats/bold/BoldTool.js index 4e65354d0..4e08b567d 100644 --- a/packages/jats/bold/BoldTool.js +++ b/packages/jats/bold/BoldTool.js @@ -1,10 +1,5 @@ -'use strict'; - import { AnnotationTool } from 'substance' -function BoldTool() { - BoldTool.super.apply(this, arguments); -} -AnnotationTool.extend(BoldTool); +class BoldTool extends AnnotationTool {} -export default BoldTool; \ No newline at end of file +export default BoldTool \ No newline at end of file diff --git a/packages/jats/ext-link/ExtLinkTool.js b/packages/jats/ext-link/ExtLinkTool.js index 15a744021..cf601eaba 100644 --- a/packages/jats/ext-link/ExtLinkTool.js +++ b/packages/jats/ext-link/ExtLinkTool.js @@ -1,11 +1,5 @@ -'use strict'; - import { AnnotationTool } from 'substance' -function ExtLinkTool() { - ExtLinkTool.super.apply(this, arguments); -} - -AnnotationTool.extend(ExtLinkTool); +class ExtLinkTool extends AnnotationTool {} -export default ExtLinkTool; \ No newline at end of file +export default ExtLinkTool \ No newline at end of file diff --git a/packages/jats/xref/AddXRefTool.js b/packages/jats/xref/AddXRefTool.js index cb183298f..b15ca4ef7 100644 --- a/packages/jats/xref/AddXRefTool.js +++ b/packages/jats/xref/AddXRefTool.js @@ -1,9 +1,5 @@ import { AnnotationTool } from 'substance' -function AddXRefTool() { - AddXRefTool.super.apply(this, arguments); -} - -AnnotationTool.extend(AddXRefTool); +class AddXRefTool extends AnnotationTool {} export default AddXRefTool \ No newline at end of file From cf87b8a5d954747c2e49a74984b79ebe46c94391 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Tue, 20 Sep 2016 00:52:43 +0300 Subject: [PATCH 089/167] ES6 InlineNodeCommand. --- packages/jats/xref/AddXRefCommand.js | 16 +++++----------- packages/jats/xref/XRefCommand.js | 8 ++------ .../unsupported/UnsupportedInlineNodeCommand.js | 10 +++------- 3 files changed, 10 insertions(+), 24 deletions(-) diff --git a/packages/jats/xref/AddXRefCommand.js b/packages/jats/xref/AddXRefCommand.js index 4338dd67c..cda0aeba4 100644 --- a/packages/jats/xref/AddXRefCommand.js +++ b/packages/jats/xref/AddXRefCommand.js @@ -1,20 +1,14 @@ import { InlineNodeCommand } from 'substance' -function AddXRefCommand() { - AddXRefCommand.super.apply(this, arguments); -} - -AddXRefCommand.Prototype = function() { - this.createNodeData = function() { +class AddXRefCommand extends InlineNodeCommand { + createNodeData() { return { attributes: {'ref-type': 'bibr'}, targets: [], label: '???', type: 'xref' - }; - }; -}; - -InlineNodeCommand.extend(AddXRefCommand); + } + } +} export default AddXRefCommand diff --git a/packages/jats/xref/XRefCommand.js b/packages/jats/xref/XRefCommand.js index 455eb807c..972261dfb 100644 --- a/packages/jats/xref/XRefCommand.js +++ b/packages/jats/xref/XRefCommand.js @@ -2,10 +2,6 @@ import { InlineNodeCommand } from 'substance' -function XRefCommand() { - XRefCommand.super.apply(this, arguments); -} +class XRefCommand extends InlineNodeCommand {} -InlineNodeCommand.extend(XRefCommand); - -export default XRefCommand; \ No newline at end of file +export default XRefCommand \ No newline at end of file diff --git a/packages/unsupported/UnsupportedInlineNodeCommand.js b/packages/unsupported/UnsupportedInlineNodeCommand.js index 499280519..b0f1c8ba6 100644 --- a/packages/unsupported/UnsupportedInlineNodeCommand.js +++ b/packages/unsupported/UnsupportedInlineNodeCommand.js @@ -1,11 +1,7 @@ import { InlineNodeCommand } from 'substance' -function UnsupportedInlineNodeCommand() { - UnsupportedInlineNodeCommand.super.apply(this, arguments); -} +class UnsupportedInlineNodeCommand extends InlineNodeCommand {} -InlineNodeCommand.extend(UnsupportedInlineNodeCommand); +UnsupportedInlineNodeCommand.type = 'unsupported-inline' -UnsupportedInlineNodeCommand.type = 'unsupported-inline'; - -export default UnsupportedInlineNodeCommand; +export default UnsupportedInlineNodeCommand From 302767fc09a26332cfaf38ef54acb0cf71dd97b2 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Tue, 20 Sep 2016 00:54:20 +0300 Subject: [PATCH 090/167] Change substance branch. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bf696d88c..0da38de31 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "A scientific editor and reader for JATS files.", "dependencies": { "lodash": "^4.14.1", - "substance": "substance/substance#develop" + "substance": "substance/substance#es6-syntax" }, "devDependencies": { "eslint": "^3.2.2", From e63388bd5f0a191aed5c08042a06f65a5002c076 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Wed, 21 Sep 2016 00:48:10 +0300 Subject: [PATCH 091/167] ES6 AnnotationComponent. --- packages/jats/ext-link/ExtLinkComponent.js | 46 +++++++++------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/packages/jats/ext-link/ExtLinkComponent.js b/packages/jats/ext-link/ExtLinkComponent.js index 0ba0588aa..bf7419662 100644 --- a/packages/jats/ext-link/ExtLinkComponent.js +++ b/packages/jats/ext-link/ExtLinkComponent.js @@ -2,40 +2,32 @@ import { AnnotationComponent } from 'substance' -function ExtLinkComponent() { - ExtLinkComponent.super.apply(this, arguments); -} - -ExtLinkComponent.Prototype = function() { +class ExtLinkComponent extends AnnotationComponent { - var _super = ExtLinkComponent.super.prototype; + didMount() { + super.didMount.apply(this, arguments) - this.didMount = function() { - _super.didMount.apply(this, arguments); + var node = this.props.node + node.on('properties:changed', this.rerender, this) + } - var node = this.props.node; - node.on('properties:changed', this.rerender, this); - }; + dispose() { + super.dispose.apply(this, arguments) - this.dispose = function() { - _super.dispose.apply(this, arguments); + var node = this.props.node + node.off(this) + } + render($$) { // eslint-disable-line var node = this.props.node; - node.off(this); - }; + var el = super.render.apply(this, arguments) - this.render = function($$) { // eslint-disable-line - var node = this.props.node; - var el = _super.render.apply(this, arguments); + el.tagName = 'a' + el.attr('href', node.attributes['xlink:href']) - el.tagName = 'a'; - el.attr('href', node.attributes['xlink:href']); + return el + } - return el; - }; - -}; - -AnnotationComponent.extend(ExtLinkComponent); +} -export default ExtLinkComponent; +export default ExtLinkComponent From e284f37e26c92d6f767cf8319a8ef6df224f4b39 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 22 Sep 2016 21:09:30 +0300 Subject: [PATCH 092/167] ES6 TextBlockComponent. --- packages/author/heading/HeadingComponent.js | 6 +++--- packages/jats/paragraph/ParagraphComponent.js | 18 ++++++------------ 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/packages/author/heading/HeadingComponent.js b/packages/author/heading/HeadingComponent.js index f77e805d0..2e73e49db 100644 --- a/packages/author/heading/HeadingComponent.js +++ b/packages/author/heading/HeadingComponent.js @@ -3,10 +3,10 @@ import { TextBlockComponent } from 'substance' class HeadingComponent extends TextBlockComponent { render($$) { - var el = super.render($$); - return el.addClass("sc-heading sm-level-"+this.props.node.level); + let el = super.render($$) + return el.addClass("sc-heading sm-level-"+this.props.node.level) } } -export default HeadingComponent; +export default HeadingComponent diff --git a/packages/jats/paragraph/ParagraphComponent.js b/packages/jats/paragraph/ParagraphComponent.js index f8643db78..cb98bec68 100644 --- a/packages/jats/paragraph/ParagraphComponent.js +++ b/packages/jats/paragraph/ParagraphComponent.js @@ -2,18 +2,12 @@ import { TextBlockComponent } from 'substance' -function ParagraphComponent() { - ParagraphComponent.super.apply(this, arguments); -} - -ParagraphComponent.Prototype = function() { +class ParagraphComponent extends TextBlockComponent { - this.getClassNames = function() { - return 'sc-paragraph'; - }; + getClassNames() { + return 'sc-paragraph' + } -}; - -TextBlockComponent.extend(ParagraphComponent); +} -export default ParagraphComponent; +export default ParagraphComponent From 91e5e7b8453148c1ae0f65fd82b17d929e8cd673 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 22 Sep 2016 21:25:43 +0300 Subject: [PATCH 093/167] ES6 TOCProvider. --- packages/author/AuthorTOCProvider.js | 14 ++-- packages/publisher/PublisherTOCProvider.js | 92 +++++++++++----------- 2 files changed, 52 insertions(+), 54 deletions(-) diff --git a/packages/author/AuthorTOCProvider.js b/packages/author/AuthorTOCProvider.js index 770bf0589..286c8eb0e 100644 --- a/packages/author/AuthorTOCProvider.js +++ b/packages/author/AuthorTOCProvider.js @@ -1,11 +1,11 @@ import { TOCProvider } from 'substance' -function AuthorTOCProvider(documentSession) { - TOCProvider.call(this, documentSession.getDocument(), { - containerId: 'bodyFlat' - }); +class AuthorTOCProvider extends TOCProvider { + constructor(documentSession) { + super(documentSession.getDocument(), { + containerId: 'bodyFlat' + }) + } } -TOCProvider.extend(AuthorTOCProvider); - -export default AuthorTOCProvider; +export default AuthorTOCProvider diff --git a/packages/publisher/PublisherTOCProvider.js b/packages/publisher/PublisherTOCProvider.js index 1238b608a..38568c01c 100644 --- a/packages/publisher/PublisherTOCProvider.js +++ b/packages/publisher/PublisherTOCProvider.js @@ -10,76 +10,74 @@ import { EventEmitter, TOCProvider } from 'substance' @prop {model/DocumentSession} */ -function PublisherTOCProvider(documentSession) { - EventEmitter.apply(this, arguments); - - this.documentSession = documentSession; - this.entries = this.computeEntries(); - if (this.entries.length > 0) { - this.activeEntry = this.entries[0].id; - } else { - this.activeEntry = null; +class PublisherTOCProvider extends EventEmitter { + constructor(documentSession) { + super(documentSession) + + this.documentSession = documentSession + this.entries = this.computeEntries() + if (this.entries.length > 0) { + this.activeEntry = this.entries[0].id + } else { + this.activeEntry = null; + } + this.documentSession.on('update', this.handleDocumentChange, this) } - this.documentSession.on('update', this.handleDocumentChange, this); -} -PublisherTOCProvider.Prototype = function() { - - this.dispose = function() { - this.documentSession.disconnect(this); - }; + dispose() { + this.documentSession.disconnect(this) + } - this.getDocument = function() { - return this.documentSession.getDocument(); - }; + getDocument() { + return this.documentSession.getDocument() + } // Inspects a document change and recomputes the // entries if necessary - this.handleDocumentChange = function(change) { // eslint-disable-line - var needsUpdate = false; + handleDocumentChange(change) { // eslint-disable-line + let needsUpdate = false if (needsUpdate) { - this.entries = this.computeEntries(); - this.emit('toc:updated'); + this.entries = this.computeEntries() + this.emit('toc:updated') } - }; + } - this._computeEntriesForContainer = function(container, level) { - var doc = this.getDocument(); - var entries = []; + _computeEntriesForContainer(container, level) { + let doc = this.getDocument() + let entries = [] container.nodes.forEach(function(nodeId) { - var node = doc.get(nodeId); + let node = doc.get(nodeId) if (node.type === 'section') { entries.push({ id: node.id, name: node.getTitle(), level: level, node: node - }); + }) // Sections may contain subsections entries = entries.concat( this._computeEntriesForContainer(node, level + 1) - ); + ) } - }.bind(this)); - return entries; - }; + }.bind(this)) + return entries + } - this.computeEntries = function() { - var doc = this.getDocument(); - var body = doc.get('body'); - var level = 1; - var entries = this._computeEntriesForContainer(body, level); - return entries; - }; + computeEntries() { + let doc = this.getDocument() + let body = doc.get('body') + let level = 1 + let entries = this._computeEntriesForContainer(body, level) + return entries + } - this.getEntries = function() { - return this.entries; - }; + getEntries() { + return this.entries + } - this.markActiveEntry = TOCProvider.prototype.markActiveEntry; -}; +} -EventEmitter.extend(PublisherTOCProvider); +PublisherTOCProvider.prototype.markActiveEntry = TOCProvider.prototype.markActiveEntry -export default PublisherTOCProvider; +export default PublisherTOCProvider From ba3298e5c6c1be1bb5c75a24622c5607b600855f Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 23 Sep 2016 01:07:24 +0200 Subject: [PATCH 094/167] Use more consistent overlay APIs. --- packages/author/Author.js | 4 ++-- packages/jats/ext-link/EditExtLinkCommand.js | 9 +++++++++ packages/jats/ext-link/EditExtLinkTool.js | 16 +++------------- packages/jats/ext-link/ExtLinkCommand.js | 4 ++-- packages/jats/ext-link/package.js | 2 ++ packages/jats/xref/XRefTool.js | 7 ------- .../unsupported/UnsupportedInlineNodeTool.js | 7 ------- 7 files changed, 18 insertions(+), 31 deletions(-) create mode 100644 packages/jats/ext-link/EditExtLinkCommand.js diff --git a/packages/author/Author.js b/packages/author/Author.js index 620a29d7f..7569f1a17 100644 --- a/packages/author/Author.js +++ b/packages/author/Author.js @@ -1,4 +1,4 @@ -import { SplitPane, ScrollPane, Layout, Overlay, TOC } from 'substance' +import { SplitPane, ScrollPane, Layout, ProseEditorOverlayTools, TOC } from 'substance' import AbstractWriter from '../common/AbstractWriter' import AuthorTOCProvider from './AuthorTOCProvider' @@ -41,7 +41,7 @@ class Author extends AbstractWriter { tocProvider: this.tocProvider, scrollbarType: 'substance', scrollbarPosition: 'left', - overlay: Overlay, + overlay: ProseEditorOverlayTools, }).ref('contentPanel') let layout = $$(Layout, { diff --git a/packages/jats/ext-link/EditExtLinkCommand.js b/packages/jats/ext-link/EditExtLinkCommand.js new file mode 100644 index 000000000..4627cd05d --- /dev/null +++ b/packages/jats/ext-link/EditExtLinkCommand.js @@ -0,0 +1,9 @@ +'use strict'; + +import { EditLinkCommand } from 'substance' + +class EditExtLinkCommand extends EditLinkCommand { + +} + +export default EditExtLinkCommand \ No newline at end of file diff --git a/packages/jats/ext-link/EditExtLinkTool.js b/packages/jats/ext-link/EditExtLinkTool.js index 3893ea41c..166ab54fd 100644 --- a/packages/jats/ext-link/EditExtLinkTool.js +++ b/packages/jats/ext-link/EditExtLinkTool.js @@ -1,22 +1,12 @@ 'use strict'; -import { LinkPackage } from 'substance' +import { EditLinkTool } from 'substance' import clone from 'lodash/clone' -function EditExtLinkTool() { - EditExtLinkTool.super.apply(this, arguments); -} +class EditExtLinkTool extends EditLinkTool { -LinkPackage.EditLinkTool.extend(EditExtLinkTool); +} EditExtLinkTool.urlPropertyPath = ['attributes', 'xlink:href']; -EditExtLinkTool.getProps = function(commandStates) { - if (commandStates['ext-link'].mode === 'edit') { - return clone(commandStates['ext-link']); - } else { - return undefined; - } -}; - export default EditExtLinkTool; diff --git a/packages/jats/ext-link/ExtLinkCommand.js b/packages/jats/ext-link/ExtLinkCommand.js index 5a5de3f3f..aceb4cdba 100644 --- a/packages/jats/ext-link/ExtLinkCommand.js +++ b/packages/jats/ext-link/ExtLinkCommand.js @@ -1,8 +1,8 @@ 'use strict'; -import { LinkPackage } from 'substance' +import { LinkCommand } from 'substance' -class ExtLinkCommand extends LinkPackage.LinkCommand { +class ExtLinkCommand extends LinkCommand { getAnnotationData() { return { diff --git a/packages/jats/ext-link/package.js b/packages/jats/ext-link/package.js index be9973660..0b2649755 100644 --- a/packages/jats/ext-link/package.js +++ b/packages/jats/ext-link/package.js @@ -5,6 +5,7 @@ import ExtLinkConverter from './ExtLinkConverter' import ExtLinkComponent from './ExtLinkComponent' import ExtLinkTool from './ExtLinkTool' import ExtLinkCommand from './ExtLinkCommand' +import EditExtLinkCommand from './EditExtLinkCommand' import EditExtLinkTool from './EditExtLinkTool' export default { @@ -15,6 +16,7 @@ export default { config.addComponent(ExtLink.type, ExtLinkComponent); config.addCommand(ExtLink.type, ExtLinkCommand, {nodeType: ExtLink.type}); + config.addCommand('edit-ext-link', EditExtLinkCommand, {nodeType: ExtLink.type}); config.addTool(ExtLink.type, ExtLinkTool, {target: 'annotations'}); config.addTool('edit-ext-link', EditExtLinkTool, { target: 'overlay' }); config.addIcon(ExtLink.type, { 'fontawesome': 'fa-link'}); diff --git a/packages/jats/xref/XRefTool.js b/packages/jats/xref/XRefTool.js index 5c89394e3..d86c5b9ba 100644 --- a/packages/jats/xref/XRefTool.js +++ b/packages/jats/xref/XRefTool.js @@ -73,12 +73,5 @@ XRefTool.Prototype = function() { Tool.extend(XRefTool); -XRefTool.getProps = function(commandStates) { - if (commandStates['xref'].active) { - return clone(commandStates['xref']); - } else { - return undefined; - } -}; export default XRefTool; diff --git a/packages/unsupported/UnsupportedInlineNodeTool.js b/packages/unsupported/UnsupportedInlineNodeTool.js index 3e0a9f508..95c995727 100644 --- a/packages/unsupported/UnsupportedInlineNodeTool.js +++ b/packages/unsupported/UnsupportedInlineNodeTool.js @@ -69,12 +69,5 @@ UnsupportedInlineNodeTool.Prototype = function() { Tool.extend(UnsupportedInlineNodeTool); -UnsupportedInlineNodeTool.getProps = function(commandStates) { - if (commandStates['unsupported-inline'].active) { - return clone(commandStates['unsupported-inline']); - } else { - return undefined; - } -}; export default UnsupportedInlineNodeTool; From 3bf9fef6b39db693c339d7ec8cc90bbe40209a76 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 23 Sep 2016 23:33:00 +0200 Subject: [PATCH 095/167] Streamline tool APIs. --- examples/data/kitchen-sink-author.xml | 1 + packages/jats/xref/AddXRefCommand.js | 4 +- packages/jats/xref/EditXRefCommand.js | 7 ++ packages/jats/xref/EditXRefTool.js | 74 ++++++++++++++++++ packages/jats/xref/XRefCommand.js | 7 -- packages/jats/xref/XRefTool.js | 77 ------------------- packages/jats/xref/_edit-xref-tool.css | 4 + packages/jats/xref/_index.css | 28 +------ packages/jats/xref/_xref-targets.css | 4 + packages/jats/xref/_xref.css | 15 ++++ packages/jats/xref/package.js | 12 +-- .../UnsupportedInlineNodeCommand.js | 4 +- .../unsupported/UnsupportedInlineNodeTool.js | 76 +++++++++--------- packages/unsupported/_index.css | 5 ++ 14 files changed, 162 insertions(+), 156 deletions(-) create mode 100644 packages/jats/xref/EditXRefCommand.js create mode 100644 packages/jats/xref/EditXRefTool.js delete mode 100644 packages/jats/xref/XRefCommand.js delete mode 100644 packages/jats/xref/XRefTool.js create mode 100644 packages/jats/xref/_edit-xref-tool.css create mode 100644 packages/jats/xref/_xref-targets.css create mode 100644 packages/jats/xref/_xref.css diff --git a/examples/data/kitchen-sink-author.xml b/examples/data/kitchen-sink-author.xml index b88037101..18aab490e 100644 --- a/examples/data/kitchen-sink-author.xml +++ b/examples/data/kitchen-sink-author.xml @@ -31,6 +31,7 @@ Introduction

      Texture is a tool for publishers to creating structured JATS documents based on Word or InDesign submissions.

      The original document is imported with annotations preserved. Then the user starts tagging semantic entities in the document, such as marking up the reference list, the authors, affiliations etc. Saving the document produces valid JATS 1.1 XML ([1]).

      +

      This is an Unsupported element.

      Create a bibliography diff --git a/packages/jats/xref/AddXRefCommand.js b/packages/jats/xref/AddXRefCommand.js index cda0aeba4..351a1bc26 100644 --- a/packages/jats/xref/AddXRefCommand.js +++ b/packages/jats/xref/AddXRefCommand.js @@ -1,6 +1,6 @@ -import { InlineNodeCommand } from 'substance' +import { InsertInlineNodeCommand } from 'substance' -class AddXRefCommand extends InlineNodeCommand { +class AddXRefCommand extends InsertInlineNodeCommand { createNodeData() { return { attributes: {'ref-type': 'bibr'}, diff --git a/packages/jats/xref/EditXRefCommand.js b/packages/jats/xref/EditXRefCommand.js new file mode 100644 index 000000000..280d2bcd5 --- /dev/null +++ b/packages/jats/xref/EditXRefCommand.js @@ -0,0 +1,7 @@ +'use strict'; + +import { EditInlineNodeCommand } from 'substance' + +class EditXRefCommand extends EditInlineNodeCommand {} + +export default EditXRefCommand \ No newline at end of file diff --git a/packages/jats/xref/EditXRefTool.js b/packages/jats/xref/EditXRefTool.js new file mode 100644 index 000000000..9e3826902 --- /dev/null +++ b/packages/jats/xref/EditXRefTool.js @@ -0,0 +1,74 @@ +'use strict'; + +import { deleteSelection, Tool } from 'substance' +import XRefTargets from './XRefTargets' + +/* + Shown in OverlayTools +*/ +class EditXRefTool extends Tool { + constructor(...args) { + super(...args) + this.handleActions({ + 'closeModal': this._doneEditing, + 'doneEditing': this._doneEditing + }) + } + + render($$) { + let Modal = this.getComponent('modal') + let Button = this.getComponent('button') + + let node = this.props.node + let el = $$('div').addClass('sc-edit-xref-tool') + + el.append( + $$(Button, { + icon: 'edit', + style: this.props.style + }) + .attr('title', this.getLabel('edit-xref')) + .on('click', this._onEdit), + $$(Button, { + icon: 'delete', + style: this.props.style + }) + .attr('title', this.getLabel('delete-xref')) + .on('click', this._onDelete) + ) + + if (this.state.edit) { + el.append( + $$(Modal, { + width: 'large' + }).append( + $$(XRefTargets, { + node: node + }).ref('targets') + ) + ) + } + return el; + } + + _onEdit() { + this.setState({ + edit: true + }) + } + + _doneEditing() { + this.setState({ + edit: false + }) + } + + _onDelete() { + var ds = this.context.documentSession; + ds.transaction(function(tx, args) { + return deleteSelection(tx, args) + }) + } +} + +export default EditXRefTool; diff --git a/packages/jats/xref/XRefCommand.js b/packages/jats/xref/XRefCommand.js deleted file mode 100644 index 972261dfb..000000000 --- a/packages/jats/xref/XRefCommand.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -import { InlineNodeCommand } from 'substance' - -class XRefCommand extends InlineNodeCommand {} - -export default XRefCommand \ No newline at end of file diff --git a/packages/jats/xref/XRefTool.js b/packages/jats/xref/XRefTool.js deleted file mode 100644 index d86c5b9ba..000000000 --- a/packages/jats/xref/XRefTool.js +++ /dev/null @@ -1,77 +0,0 @@ -'use strict'; - -import clone from 'lodash/clone' -import { deleteSelection, Tool } from 'substance' -import XRefTargets from './XRefTargets' - -/* - Edit a reference in a prompt. -*/ -function XRefTool() { - XRefTool.super.apply(this, arguments); - - this.handleActions({ - 'closeModal': this._doneEditing, - 'doneEditing': this._doneEditing - }); -} - -XRefTool.Prototype = function() { - - this.render = function($$) { - var Modal = this.getComponent('modal'); - var Prompt = this.getComponent('prompt'); - - // if ($$.capturing) console.log("Rendering XRefTool, state=", this.state); - var node = this.props.node; - var el = $$('div').addClass('sc-xref-tool'); - - el.append( - $$(Prompt).append( - $$(Prompt.Label, {label: this.getLabel('xref')}), - $$(Prompt.Separator), - $$(Prompt.Action, {name: 'edit', title: this.getLabel('edit-xref')}) - .on('click', this._onEdit), - $$(Prompt.Action, {name: 'delete', title: this.getLabel('delete-xref')}) - .on('click', this._onDelete) - ) - ); - - if (this.state.edit) { - el.append( - $$(Modal, { - width: 'large' - }).append( - $$(XRefTargets, { - node: node - }).ref('targets') - ) - ); - } - return el; - }; - - this._onEdit = function() { - this.setState({ - edit: true - }); - }; - - this._doneEditing = function() { - this.setState({ - edit: false - }); - }; - - this._onDelete = function() { - var ds = this.context.documentSession; - ds.transaction(function(tx, args) { - return deleteSelection(tx, args); - }); - }; -}; - -Tool.extend(XRefTool); - - -export default XRefTool; diff --git a/packages/jats/xref/_edit-xref-tool.css b/packages/jats/xref/_edit-xref-tool.css new file mode 100644 index 000000000..581e6cc2e --- /dev/null +++ b/packages/jats/xref/_edit-xref-tool.css @@ -0,0 +1,4 @@ +.sc-edit-xref-tool > * { + display: inline-block; + margin-right: 5px; +} \ No newline at end of file diff --git a/packages/jats/xref/_index.css b/packages/jats/xref/_index.css index b13a077a1..f1635f21c 100644 --- a/packages/jats/xref/_index.css +++ b/packages/jats/xref/_index.css @@ -1,25 +1,3 @@ -.sc-xref { - background: rgba(0, 0, 0, 0.075); - border-bottom: 1px solid rgba(0, 0, 0, 0.3); - white-space: nowrap; -} -.sc-xref.sm-bibr { - background: rgba(11, 157, 217, 0.075); - color: #1B6685; - border-bottom: 1px solid rgba(11, 157, 217, 0.4); -} -.sc-xref.sm-fig { - background: rgba(145, 187, 4, 0.15); - border-bottom: 1px solid rgba(145, 187, 4, 0.6); - color: #495A11; -} - -.sc-xref-targets { - max-height: 600px; - overflow: auto; -} - -.sc-xref-tool > .se-actions > button { - padding: 5px; - font-size: var(--small-font-size); -} +@import './_xref.css'; +@import './_xref-targets.css'; +@import './_edit-xref-tool.css'; diff --git a/packages/jats/xref/_xref-targets.css b/packages/jats/xref/_xref-targets.css new file mode 100644 index 000000000..583a481bd --- /dev/null +++ b/packages/jats/xref/_xref-targets.css @@ -0,0 +1,4 @@ +.sc-xref-targets { + max-height: 600px; + overflow: auto; +} \ No newline at end of file diff --git a/packages/jats/xref/_xref.css b/packages/jats/xref/_xref.css new file mode 100644 index 000000000..131413dc5 --- /dev/null +++ b/packages/jats/xref/_xref.css @@ -0,0 +1,15 @@ +.sc-xref { + background: rgba(0, 0, 0, 0.075); + border-bottom: 1px solid rgba(0, 0, 0, 0.3); + white-space: nowrap; +} +.sc-xref.sm-bibr { + background: rgba(11, 157, 217, 0.075); + color: #1B6685; + border-bottom: 1px solid rgba(11, 157, 217, 0.4); +} +.sc-xref.sm-fig { + background: rgba(145, 187, 4, 0.15); + border-bottom: 1px solid rgba(145, 187, 4, 0.6); + color: #495A11; +} diff --git a/packages/jats/xref/package.js b/packages/jats/xref/package.js index 1527c2390..cf7d27c59 100644 --- a/packages/jats/xref/package.js +++ b/packages/jats/xref/package.js @@ -1,8 +1,8 @@ import XRef from './XRef' import XRefComponent from './XRefComponent' import XRefConverter from './XRefConverter' -import XRefCommand from './XRefCommand' -import XRefTool from './XRefTool' +import EditXRefCommand from './EditXRefCommand' +import EditXRefTool from './EditXRefTool' import AddXRefCommand from './AddXRefCommand' import AddXRefTool from './AddXRefTool' @@ -13,13 +13,13 @@ export default { config.addComponent(XRef.type, XRefComponent); config.addConverter('jats', XRefConverter); - // TODO: is there a way to use only one command for the two different tools - config.addCommand(XRef.type, XRefCommand, {nodeType: XRef.type}) + config.addCommand('edit-xref', EditXRefCommand, {nodeType: XRef.type}) config.addCommand('add-xref', AddXRefCommand, {nodeType: XRef.type}) + config.addTool('add-xref', AddXRefTool, {target: 'insert'}) - config.addTool(XRef.type, XRefTool, { overlay: true }) - config.addLabel('add-xref', 'Cross Reference') + config.addTool('edit-xref', EditXRefTool, { target: 'overlay' }) + config.addLabel('add-xref', 'Cross Reference') config.addIcon('add-xref', { 'fontawesome': 'fa-external-link' }) config.addLabel(XRef.type, { en: 'Cross Reference' diff --git a/packages/unsupported/UnsupportedInlineNodeCommand.js b/packages/unsupported/UnsupportedInlineNodeCommand.js index b0f1c8ba6..94e35802b 100644 --- a/packages/unsupported/UnsupportedInlineNodeCommand.js +++ b/packages/unsupported/UnsupportedInlineNodeCommand.js @@ -1,6 +1,6 @@ -import { InlineNodeCommand } from 'substance' +import { EditInlineNodeCommand } from 'substance' -class UnsupportedInlineNodeCommand extends InlineNodeCommand {} +class UnsupportedInlineNodeCommand extends EditInlineNodeCommand {} UnsupportedInlineNodeCommand.type = 'unsupported-inline' diff --git a/packages/unsupported/UnsupportedInlineNodeTool.js b/packages/unsupported/UnsupportedInlineNodeTool.js index 95c995727..e31efd0e4 100644 --- a/packages/unsupported/UnsupportedInlineNodeTool.js +++ b/packages/unsupported/UnsupportedInlineNodeTool.js @@ -1,56 +1,59 @@ import { Tool, deleteSelection } from 'substance' -import clone from 'lodash/clone' import EditXML from '../common/EditXML' /* Prompt shown when an unsupported node is selected. */ -function UnsupportedInlineNodeTool() { - UnsupportedInlineNodeTool.super.apply(this, arguments); - this.handleActions({ - 'closeModal': this._closeModal, - 'xmlSaved': this._closeModal - }); -} +class UnsupportedInlineNodeTool extends Tool { + constructor(...args) { + super(...args) + this.handleActions({ + 'closeModal': this._closeModal, + 'xmlSaved': this._closeModal + }) + } -UnsupportedInlineNodeTool.Prototype = function() { - this._closeModal = function() { + _closeModal() { this.setState({ editXML: false - }); - }; + }) + } - this._onEdit = function() { + _onEdit() { this.setState({ editXML: true - }); - }; + }) + } - this._onDelete = function() { - var ds = this.context.documentSession; + _onDelete() { + let ds = this.context.documentSession ds.transaction(function(tx, args) { - return deleteSelection(tx, args); - }); - }; + return deleteSelection(tx, args) + }) + } - this.render = function($$) { - var el = $$('div').addClass('sc-unsupported-node-tool'); - var node = this.props.node; - var Modal = this.getComponent('modal'); - var Prompt = this.getComponent('prompt'); + render($$) { + let el = $$('div').addClass('sc-unsupported-node-tool') + let node = this.props.node + let Modal = this.getComponent('modal') + let Button = this.getComponent('button') el.append( - $$(Prompt).append( - $$(Prompt.Label, {label: 'Unsupported Element'}), - $$(Prompt.Separator), - $$(Prompt.Action, {name: 'edit', title: 'Edit XML'}) - .on('click', this._onEdit), - $$(Prompt.Action, {name: 'delete', title: 'Delete Element'}) - .on('click', this._onDelete) - ) - ); + $$(Button, { + icon: 'edit', + style: this.props.style + }) + .attr('title', 'Edit XML') + .on('click', this._onEdit), + $$(Button, { + icon: 'delete', + style: this.props.style + }) + .attr('title', 'Delete Element') + .on('click', this._onDelete) + ) if (this.state.editXML) { el.append( @@ -64,10 +67,9 @@ UnsupportedInlineNodeTool.Prototype = function() { ); } return el; - }; -}; + } -Tool.extend(UnsupportedInlineNodeTool); +} export default UnsupportedInlineNodeTool; diff --git a/packages/unsupported/_index.css b/packages/unsupported/_index.css index 222fd0ff5..9ae3c60fc 100644 --- a/packages/unsupported/_index.css +++ b/packages/unsupported/_index.css @@ -17,4 +17,9 @@ .sc-edit-xml textarea { width: 100%; height: 400px; +} + +.sc-unsupported-node-tool > * { + display: inline-block; + margin-right: 5px; } \ No newline at end of file From 399859e0a16993ce1cba51d66f7a91a129fa479b Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sat, 24 Sep 2016 15:45:32 +0200 Subject: [PATCH 096/167] Switch to substance#develop. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0da38de31..bf696d88c 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "A scientific editor and reader for JATS files.", "dependencies": { "lodash": "^4.14.1", - "substance": "substance/substance#es6-syntax" + "substance": "substance/substance#develop" }, "devDependencies": { "eslint": "^3.2.2", From 7549b10a67673ce61cecea0262bb413379f94cdb Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Sat, 24 Sep 2016 20:17:25 +0200 Subject: [PATCH 097/167] Activate highlights for the scrollbar. --- packages/author/Author.js | 1 + packages/common/AbstractWriter.js | 31 ++++++++++++++++++-- packages/jats/ext-link/package.js | 8 +++++ packages/jats/figure/FigureComponent.js | 1 - packages/jats/figure/FigureConverter.js | 1 - packages/jats/ref/RefComponent.js | 19 +++++------- packages/jats/xref/_index.css | 1 + packages/jats/xref/_scrollbar-highlights.css | 8 +++++ packages/publisher/Publisher.js | 1 + packages/texture/Texture.js | 2 ++ 10 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 packages/jats/xref/_scrollbar-highlights.css diff --git a/packages/author/Author.js b/packages/author/Author.js index 7569f1a17..8f0e4d6e6 100644 --- a/packages/author/Author.js +++ b/packages/author/Author.js @@ -42,6 +42,7 @@ class Author extends AbstractWriter { scrollbarType: 'substance', scrollbarPosition: 'left', overlay: ProseEditorOverlayTools, + highlights: this.contentHighlights }).ref('contentPanel') let layout = $$(Layout, { diff --git a/packages/common/AbstractWriter.js b/packages/common/AbstractWriter.js index 7796f38b2..e4f379321 100644 --- a/packages/common/AbstractWriter.js +++ b/packages/common/AbstractWriter.js @@ -1,6 +1,5 @@ -import { ProseEditorPackage } from 'substance' +import { ProseEditor, Highlights } from 'substance' import SaveHandler from './SaveHandler' -const ProseEditor = ProseEditorPackage.ProseEditor // TODO: we need to think if it is really a good idea to // derive from ProseEditor here @@ -21,6 +20,9 @@ class AbstractWriter extends ProseEditor { this.tocProvider = this._getTOCProvider() this.saveHandler = this._getSaveHandler() this.documentSession.setSaveHandler(this.saveHandler) + + let doc = this.props.documentSession.getDocument() + this.contentHighlights = new Highlights(doc) } getChildContext() { @@ -61,6 +63,31 @@ class AbstractWriter extends ProseEditor { }) } + /* + TODO: this should live in the xref package with the ability + for other packages to manage their own highlights. + */ + documentSessionUpdated() { + super.documentSessionUpdated() + let documentSession = this.documentSession + let sel = documentSession.getSelection() + let selectionState = documentSession.getSelectionState() + + let xrefs = selectionState.getAnnotationsForType('xref') + let highlights = { + 'fig': [], + 'bibr': [] + } + + if (xrefs.length === 1 && xrefs[0].getSelection().equals(sel) ) { + let xref = xrefs[0] + // highlights.xref = [ xref.id ] + highlights[xref.referenceType] = xref.targets.concat([xref.id]) + } + + this.contentHighlights.set(highlights) + } + } export default AbstractWriter diff --git a/packages/jats/ext-link/package.js b/packages/jats/ext-link/package.js index 0b2649755..d33c32653 100644 --- a/packages/jats/ext-link/package.js +++ b/packages/jats/ext-link/package.js @@ -24,5 +24,13 @@ export default { config.addLabel(ExtLink.type, { en: 'Link' }); + config.addLabel('open-link', { + en: 'Open Link', + de: 'Link öffnen' + }); + config.addLabel('delete-link', { + en: 'Remove Link', + de: 'Link löschen' + }); } } diff --git a/packages/jats/figure/FigureComponent.js b/packages/jats/figure/FigureComponent.js index e58f13566..22f04e026 100644 --- a/packages/jats/figure/FigureComponent.js +++ b/packages/jats/figure/FigureComponent.js @@ -12,7 +12,6 @@ FigureComponent.Prototype = function() { this.render = function($$) { var node = this.props.node; var doc = node.getDocument(); - var el = $$('div') .addClass('sc-figure') .attr('data-id', this.props.node.id); diff --git a/packages/jats/figure/FigureConverter.js b/packages/jats/figure/FigureConverter.js index 9e18acd0e..04f5ad6f8 100644 --- a/packages/jats/figure/FigureConverter.js +++ b/packages/jats/figure/FigureConverter.js @@ -42,7 +42,6 @@ export default { */ import: function(el, node, converter) { - var iterator = new XMLIterator(el.getChildren()); iterator.manyOf('object-id', function(child) { node.objectIds.push(child.textContent); diff --git a/packages/jats/ref/RefComponent.js b/packages/jats/ref/RefComponent.js index 54f64aede..a529a17ab 100644 --- a/packages/jats/ref/RefComponent.js +++ b/packages/jats/ref/RefComponent.js @@ -1,20 +1,15 @@ import { Component } from 'substance' import refToHTML from './refToHTML' -function RefComponent() { - RefComponent.super.apply(this, arguments); +class RefComponent extends Component { + render($$) { + var el = $$('div').addClass('sc-ref') + el.attr('data-id', this.props.node.id) + el.html(refToHTML(this.props.node)) + return el + } } -RefComponent.Prototype = function() { - this.render = function($$) { - var el = $$('div').addClass('sc-ref'); - el.html(refToHTML(this.props.node)); - return el; - }; -}; - -Component.extend(RefComponent); - // Isolated Nodes config RefComponent.fullWidth = true; RefComponent.noStyle = true; diff --git a/packages/jats/xref/_index.css b/packages/jats/xref/_index.css index f1635f21c..2ccc6fde1 100644 --- a/packages/jats/xref/_index.css +++ b/packages/jats/xref/_index.css @@ -1,3 +1,4 @@ @import './_xref.css'; @import './_xref-targets.css'; @import './_edit-xref-tool.css'; +@import './_scrollbar-highlights.css'; \ No newline at end of file diff --git a/packages/jats/xref/_scrollbar-highlights.css b/packages/jats/xref/_scrollbar-highlights.css new file mode 100644 index 000000000..651074674 --- /dev/null +++ b/packages/jats/xref/_scrollbar-highlights.css @@ -0,0 +1,8 @@ +/* Scrollbar overrides for highlights */ +.sc-scrollbar .se-highlight.sm-fig { + background-color: #91bb04; +} + +.sc-scrollbar .se-highlight.sm-bibr { + background-color: #0b9dd9; +} \ No newline at end of file diff --git a/packages/publisher/Publisher.js b/packages/publisher/Publisher.js index b47786006..9e61f2f28 100644 --- a/packages/publisher/Publisher.js +++ b/packages/publisher/Publisher.js @@ -47,6 +47,7 @@ PublisherWriter.Prototype = function() { scrollbarType: 'substance', scrollbarPosition: 'left', overlay: Overlay, + highlights: this.contentHighlights }).ref('contentPanel'); var layout = $$(Layout, { diff --git a/packages/texture/Texture.js b/packages/texture/Texture.js index ea4c8b85d..36d65ef22 100644 --- a/packages/texture/Texture.js +++ b/packages/texture/Texture.js @@ -10,6 +10,7 @@ class Texture extends Component { constructor(parent, props) { super(parent, props) + if (!props.configurator) { throw new Error("'configurator' is required") } @@ -77,6 +78,7 @@ class Texture extends Component { } var importer = configurator.createImporter('jats'); var doc = importer.importDocument(xml); + // HACK: For debug purposes window.doc = doc; this.setState({ From 997235e8a1406e8f3302cf5f2751c1752b281d53 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 27 Sep 2016 15:08:17 +0200 Subject: [PATCH 098/167] Substance bundle target has changed. --- make.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/make.js b/make.js index c1929a1c9..dd11fca14 100644 --- a/make.js +++ b/make.js @@ -15,7 +15,7 @@ b.task('assets', function() { // this optional task makes it easier to work on Substance core b.task('substance', function() { - b.make('substance', 'clean', 'css', 'browser:umd') + b.make('substance', 'clean', 'css', 'browser') b.copy('node_modules/substance/dist', './dist/substance') }) @@ -38,7 +38,6 @@ function buildExample(example) { b.task('author', ['clean', 'substance', 'assets'], buildExample('author')) b.task('publisher', ['clean', 'substance', 'assets'], buildExample('publisher')) b.task('tagging', ['author'], buildExample('tagging')) - b.task('examples', ['author', 'publisher', 'tagging']) // build all From 5b52ed7d42fe34c8992a3a20e98231680ff3e1f6 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 27 Sep 2016 15:08:53 +0200 Subject: [PATCH 099/167] Getting rid of ProseEditor dependencies. --- packages/author/Author.js | 2 +- packages/texture/FileClientStub.js | 27 +++++++++++++++++++++++++ packages/texture/SaveHandlerStub.js | 9 +++++++++ packages/texture/TextureConfigurator.js | 25 ++++++++++++++++++++--- 4 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 packages/texture/FileClientStub.js create mode 100644 packages/texture/SaveHandlerStub.js diff --git a/packages/author/Author.js b/packages/author/Author.js index 8f0e4d6e6..4e1b066a5 100644 --- a/packages/author/Author.js +++ b/packages/author/Author.js @@ -22,7 +22,7 @@ class Author extends AbstractWriter { } _renderMainSection($$) { - let mainSection = $$('div').addClass('se-main-sectin') + let mainSection = $$('div').addClass('se-main-section') let splitPane = $$(SplitPane, {splitType: 'horizontal'}).append( // inherited from ProseEditor this._renderToolbar($$), diff --git a/packages/texture/FileClientStub.js b/packages/texture/FileClientStub.js new file mode 100644 index 000000000..a7883069e --- /dev/null +++ b/packages/texture/FileClientStub.js @@ -0,0 +1,27 @@ +import { EventEmitter } from 'substance' + +class FileClientStub { + + uploadFile(file, cb) { + let delay = 50 + let steps = (file.size / 500000) * (1000 / delay) + let i = 0 + let channel = new EventEmitter() + let _step = function() { + if (i++ < steps) { + channel.emit('progress', (i-1)/(steps)) + window.setTimeout(_step, delay) + } else { + // Default file upload implementation + // We just return a temporary objectUrl + let fileUrl = window.URL.createObjectURL(file) + cb(null, fileUrl) + } + } + _step() + return channel + } +} + + +export default FileClientStub diff --git a/packages/texture/SaveHandlerStub.js b/packages/texture/SaveHandlerStub.js new file mode 100644 index 000000000..1f57f7b06 --- /dev/null +++ b/packages/texture/SaveHandlerStub.js @@ -0,0 +1,9 @@ +class SaveHandlerStub { + + saveDocument(doc, changes, cb) { + console.warn('No SaveHandler provided. Using Stub.') + cb(null) + } +} + +export default SaveHandlerStub diff --git a/packages/texture/TextureConfigurator.js b/packages/texture/TextureConfigurator.js index 1b5e80e0f..1929ef3cd 100644 --- a/packages/texture/TextureConfigurator.js +++ b/packages/texture/TextureConfigurator.js @@ -1,14 +1,33 @@ -import { ProseEditorPackage } from 'substance' -// TODO: we should have a better base Configurator in core -const Configurator = ProseEditorPackage.Configurator +import { Configurator } from 'substance' +import SaveHandlerStub from './SaveHandlerStub' +import FileClientStub from './FileClientStub' class TextureConfigurator extends Configurator { constructor(...args) { super(...args) + + this.config.saveHandler = new SaveHandlerStub() + this.config.fileClient = new FileClientStub() this.config.XMLStoreClass = null } + setSaveHandler(saveHandler) { + this.config.saveHandler = saveHandler + } + + setFileClient(fileClient) { + this.config.fileClient = fileClient + } + + getFileClient() { + return this.config.fileClient + } + + getSaveHandler() { + return this.config.saveHandler + } + setXMLStore(XMLStoreClass) { this.config.XMLStoreClass = XMLStoreClass } From d5cef4195384db6f9abe3731b65c273ad1a2efae Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 28 Sep 2016 02:48:42 +0200 Subject: [PATCH 100/167] Revive Publisher interface. --- examples/publisher/app.js | 47 ++++++++++++++---- examples/publisher/package.js | 5 +- packages/author/Author.js | 1 - packages/common/AbstractWriter.js | 26 ++++++---- packages/publisher/Publisher.js | 80 ++++++++++++++----------------- packages/publisher/package.js | 5 +- 6 files changed, 93 insertions(+), 71 deletions(-) diff --git a/examples/publisher/app.js b/examples/publisher/app.js index da1d92107..02b63aa7e 100644 --- a/examples/publisher/app.js +++ b/examples/publisher/app.js @@ -2,14 +2,43 @@ import { substanceGlobals } from 'substance' import Package from './package' import Texture from '../../packages/texture/Texture' import TextureConfigurator from '../../packages/texture/TextureConfigurator' +import Publisher from '../../packages/publisher/Publisher' substanceGlobals.DEBUG_RENDERING = true; -var configurator = new TextureConfigurator().import(Package); - -window.onload = function() { - window.app = Texture.mount({ - mode: 'publisher', - documentId: 'elife-00007', - configurator: configurator - }, document.body); -}; + +class App extends Texture { + + render($$) { + let el = $$('div').addClass('sc-publisher-example') + + if (this.state.error) { + el.append(this.state.error) + } + + if (this.state.documentSession) { + el.append($$(Publisher, { + documentId: this.props.documentId, + documentSession: this.state.documentSession, + configurator: this.getConfigurator() + })) + } + + return el + } +} + +App.Configurator = TextureConfigurator + +if (typeof window !== 'undefined') { + window.onload = function() { + let configurator = new TextureConfigurator() + configurator.import(Package) + var app = App.mount({ + configurator: configurator, + documentId: 'elife-00007' + }, document.body) + window.app = app + }; +} + +export default App diff --git a/examples/publisher/package.js b/examples/publisher/package.js index 7464ef87c..5afda4fd8 100644 --- a/examples/publisher/package.js +++ b/examples/publisher/package.js @@ -1,11 +1,10 @@ -import TexturePackage from '../../packages/texture/package' +import PublisherPackage from '../../packages/publisher/package' import ExampleXMLStore from '../ExampleXMLStore' export default { name: 'publisher-example', configure: function(config) { - config.import(TexturePackage); - // Define XML Store + config.import(PublisherPackage) config.setXMLStore(ExampleXMLStore); } } diff --git a/packages/author/Author.js b/packages/author/Author.js index 4e1b066a5..40a82c725 100644 --- a/packages/author/Author.js +++ b/packages/author/Author.js @@ -24,7 +24,6 @@ class Author extends AbstractWriter { _renderMainSection($$) { let mainSection = $$('div').addClass('se-main-section') let splitPane = $$(SplitPane, {splitType: 'horizontal'}).append( - // inherited from ProseEditor this._renderToolbar($$), this._renderContentPanel($$) ) diff --git a/packages/common/AbstractWriter.js b/packages/common/AbstractWriter.js index e4f379321..043f12c35 100644 --- a/packages/common/AbstractWriter.js +++ b/packages/common/AbstractWriter.js @@ -1,10 +1,10 @@ -import { ProseEditor, Highlights } from 'substance' +import { ProseEditor, Highlights, Toolbar, AbstractEditor } from 'substance' import SaveHandler from './SaveHandler' // TODO: we need to think if it is really a good idea to // derive from ProseEditor here // There would be a lot of code redundancy -class AbstractWriter extends ProseEditor { +class AbstractWriter extends AbstractEditor { constructor(...args) { super(...args) @@ -31,8 +31,11 @@ class AbstractWriter extends ProseEditor { return childContext } - _renderToolbar($$) { // eslint-disable-line - return super._renderToolbar.apply(this, arguments) + _renderToolbar($$) { + let commandStates = this.commandManager.getCommandStates() + return $$(Toolbar, { + commandStates: commandStates + }).ref('toolbar') } _renderContentPanel($$) { // eslint-disable-line @@ -63,12 +66,16 @@ class AbstractWriter extends ProseEditor { }) } - /* - TODO: this should live in the xref package with the ability - for other packages to manage their own highlights. - */ + documentSessionUpdated() { - super.documentSessionUpdated() + let toolbar = this.refs.toolbar + if (toolbar) { + let commandStates = this.commandManager.getCommandStates() + toolbar.setProps({ + commandStates: commandStates + }) + } + let documentSession = this.documentSession let sel = documentSession.getSelection() let selectionState = documentSession.getSelectionState() @@ -81,7 +88,6 @@ class AbstractWriter extends ProseEditor { if (xrefs.length === 1 && xrefs[0].getSelection().equals(sel) ) { let xref = xrefs[0] - // highlights.xref = [ xref.id ] highlights[xref.referenceType] = xref.targets.concat([xref.id]) } diff --git a/packages/publisher/Publisher.js b/packages/publisher/Publisher.js index 9e61f2f28..68c126788 100644 --- a/packages/publisher/Publisher.js +++ b/packages/publisher/Publisher.js @@ -2,45 +2,40 @@ import { Overlay, TOC } from 'substance' import AbstractWriter from '../common/AbstractWriter' import PublisherTOCProvider from './PublisherTOCProvider' -function PublisherWriter() { - PublisherWriter.super.apply(this, arguments); -} - -PublisherWriter.Prototype = function() { - - this.render = function($$) { - var SplitPane = this.getComponent('split-pane'); - var el = $$('div').addClass('sc-publisher'); +class Publisher extends AbstractWriter { + render($$) { + var SplitPane = this.componentRegistry.get('split-pane') + var el = $$('div').addClass('sc-publisher') el.append( $$(SplitPane, {splitType: 'vertical', sizeB: '400px'}).append( this._renderMainSection($$), this._renderContextSection($$) ) - ); - return el; - }; + ) + return el + } - this._renderContextSection = function($$) { + _renderContextSection($$) { return $$('div').addClass('se-context-section').append( $$(TOC) - ); - }; + ) + } - this._renderMainSection = function($$) { - var SplitPane = this.getComponent('split-pane'); - var mainSection = $$('div').addClass('se-main-section'); + _renderMainSection($$) { + var SplitPane = this.componentRegistry.get('split-pane') + var mainSection = $$('div').addClass('se-main-section') var splitPane = $$(SplitPane, {splitType: 'horizontal'}).append( this._renderToolbar($$), this._renderContentPanel($$) ); - mainSection.append(splitPane); - return mainSection; - }; + mainSection.append(splitPane) + return mainSection + } - this._renderContentPanel = function($$) { - var doc = this.documentSession.getDocument(); - var Layout = this.getComponent('layout'); - var ScrollPane = this.getComponent('scroll-pane'); + _renderContentPanel($$) { + var doc = this.documentSession.getDocument() + var Layout = this.componentRegistry.get('layout') + var ScrollPane = this.componentRegistry.get('scroll-pane') var contentPanel = $$(ScrollPane, { tocProvider: this.tocProvider, @@ -54,9 +49,9 @@ PublisherWriter.Prototype = function() { width: 'large' }); - var ArticleComponent = this.componentRegistry.get('article'); + var ArticleComponent = this.componentRegistry.get('article') - var article = doc.get('article'); + var article = doc.get('article') layout.append( $$(ArticleComponent, { node: article, @@ -65,25 +60,22 @@ PublisherWriter.Prototype = function() { configurator: this.props.configurator }) ); + contentPanel.append(layout) + return contentPanel + } - contentPanel.append(layout); - return contentPanel; - }; - - this._scrollTo = function(nodeId) { - this.refs.contentPanel.scrollTo(nodeId); - }; + _scrollTo(nodeId) { + this.refs.contentPanel.scrollTo(nodeId) + } - this._getExporter = function() { - return this.props.configurator.createExporter('jats'); - }; + _getExporter() { + return this.props.configurator.createExporter('jats') + } - this._getTOCProvider = function() { - return new PublisherTOCProvider(this.documentSession); - }; - -}; + _getTOCProvider() { + return new PublisherTOCProvider(this.documentSession) + } +} -AbstractWriter.extend(PublisherWriter); -export default PublisherWriter; +export default Publisher; diff --git a/packages/publisher/package.js b/packages/publisher/package.js index 9a3a2390f..24474fcbd 100644 --- a/packages/publisher/package.js +++ b/packages/publisher/package.js @@ -1,4 +1,4 @@ -import { Overlay, BasePackage, PersistencePackage } from 'substance' +import { BasePackage, PersistencePackage } from 'substance' import JATSPackage from '../jats/package' import CommonPackage from '../common/package' import InlineWrapperPackage from '../inline-wrapper/InlineWrapperPackage' @@ -9,9 +9,6 @@ export default { configure: function(config) { config.import(BasePackage); config.import(PersistencePackage); - // TODO: see substance#712 - config.addComponent('overlay', Overlay); - config.import(JATSPackage); config.import(CommonPackage); From 3827601f54aaa953a9d2aacbb9229af0fa5dc7b1 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 28 Sep 2016 11:37:03 +0200 Subject: [PATCH 101/167] Reactivate overlay tools for Publisher. --- packages/publisher/Publisher.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/publisher/Publisher.js b/packages/publisher/Publisher.js index 68c126788..450614d6d 100644 --- a/packages/publisher/Publisher.js +++ b/packages/publisher/Publisher.js @@ -1,4 +1,4 @@ -import { Overlay, TOC } from 'substance' +import { ProseEditorOverlayTools, TOC } from 'substance' import AbstractWriter from '../common/AbstractWriter' import PublisherTOCProvider from './PublisherTOCProvider' @@ -41,7 +41,7 @@ class Publisher extends AbstractWriter { tocProvider: this.tocProvider, scrollbarType: 'substance', scrollbarPosition: 'left', - overlay: Overlay, + overlay: ProseEditorOverlayTools, highlights: this.contentHighlights }).ref('contentPanel'); From 4d7dd323e2b44233ab3a736a8288c3d545337700 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 28 Sep 2016 12:34:25 +0200 Subject: [PATCH 102/167] Use example with more content variation. --- examples/author/app.js | 3 +- examples/data/elife-00007.xml | 1 - examples/data/elife-15278.xml | 1 + examples/data/example.xml | 135 +++++++++++++++++++++++++++ examples/publisher/app.js | 2 +- packages/jats/xref/getXRefTargets.js | 3 +- packages/publisher/Publisher.js | 2 +- 7 files changed, 141 insertions(+), 6 deletions(-) delete mode 100644 examples/data/elife-00007.xml create mode 100644 examples/data/elife-15278.xml create mode 100644 examples/data/example.xml diff --git a/examples/author/app.js b/examples/author/app.js index 84293f0f7..f96cc63b9 100644 --- a/examples/author/app.js +++ b/examples/author/app.js @@ -22,7 +22,6 @@ class App extends Texture { configurator: this.getConfigurator() })) } - return el } } @@ -35,7 +34,7 @@ if (typeof window !== 'undefined') { configurator.import(Package) var app = App.mount({ configurator: configurator, - documentId: 'elife-00007' + documentId: 'elife-15278' }, document.body) window.app = app }; diff --git a/examples/data/elife-00007.xml b/examples/data/elife-00007.xml deleted file mode 100644 index 0a71a84c3..000000000 --- a/examples/data/elife-00007.xml +++ /dev/null @@ -1 +0,0 @@ -
      eLifeelifeeLifeeLife2050-084XeLife Sciences Publications, Ltd0000710.7554/eLife.00007Research ArticleGenomics and Evolutionary BiologyPlant BiologyHerbivory-induced volatiles function as defenses increasing fitness of the native plant Nicotiana attenuata in natureSchumanMeredith CBarthelKathleenBaldwinIan T*Department of Molecular Ecology, Max Planck Institute for Chemical Ecology, Jena, GermanyWeigelDetlefReviewing editorMax Planck Institute for Developmental Biology, GermanyFor correspondence: baldwin@ice.mpg.de

      Federal Research Center for Cultivated Plants Institute for Breeding Research on Horticultural And Fruit Crops, Julius Kühn Institute, Dresden, Germany

      1510201220121e000070705201211072012© 2012, Schuman et al2012Schuman et alThis article is distributed under the terms of the Creative Commons Attribution License, which permits unrestricted use and redistribution provided that the original author and source are credited.10.7554/eLife.00007.001

      From an herbivore's first bite, plants release herbivory-induced plant volatiles (HIPVs) which can attract enemies of herbivores. However, other animals and competing plants can intercept HIPVs for their own use, and it remains unclear whether HIPVs serve as an indirect defense by increasing fitness for the emitting plant. In a 2-year field study, HIPV-emitting N. attenuata plants produced twice as many buds and flowers as HIPV-silenced plants, but only when native Geocoris spp. predators reduced herbivore loads (by 50%) on HIPV-emitters. In concert with HIPVs, plants also employ antidigestive trypsin protease inhibitors (TPIs), but TPI-producing plants were not fitter than TPI-silenced plants. TPIs weakened a specialist herbivore's behavioral evasive responses to simulated Geocoris spp. attack, indicating that TPIs function against specialists by enhancing indirect defense.

      DOI: http://dx.doi.org/10.7554/eLife.00007.001

      10.7554/eLife.00007.002eLife digest

      As the population of the world continues to increase beyond 7 billion, and agricultural pests continue to rapidly evolve resistance to pesticides, it is becoming ever more important to cultivate arable land in a way that is sustainable for both humans and the environment. A better understanding of the different mechanisms used by wild plants to deter herbivores will help to increase crop production without harming the environment.

      Plants use both direct and indirect methods to fend off herbivores. Direct defense methods include the production of chemicals that are toxic to herbivores or give them indigestion, and the growth of sticky prickles and spines that can injure or kill the herbivore. Indirect defense methods, on the other hand, generally rely on the plant attracting organisms that are either predators or parasites of the herbivore.

      Plants produce odors known as herbivory-induced plant volatiles (HIPVs) that are thought to offer indirect defense against herbivores by betraying their location to predators and parasites. However, HIPVs also influence other members of the ecological community, sometimes in ways that are detrimental to plants. Moreover, despite 30 years of research, no study has demonstrated that HIPVs increase the fitness of a plant, so it is unclear what they have evolved to do.

      Now, a 2-year field study by Schuman et al. has shown plants that emit green leaf volatiles (which are a type of HIPV) produce twice as many buds and flowers—a measure of fitness—as plants that have been genetically engineered not to emit green leaf volatiles. This study was conducted with Nicotiana attenuata, which is a wild tobacco plant that is often targeted by Manduca sexta, a type of moth that is also known as the tobacco hornworm. Green leaf volatiles only increased plants' fitness when various species of Geocoris—a bug that preys on Manduca sexta—reduced the number of herbivores by a factor of two. This is the first evidence that HIPVs offer indirect defense against herbivores.

      Schuman et al. also studied the effects of molecules called protease inhibitors that are thought to function as direct defenses by making it difficult for herbivores to digest plants. They found that the ability to produce protease inhibitors did not increase the fitness of plants under herbivore attack; however, tobacco hornworms that had been fed plants containing protease inhibitors were found to be more sluggish in response to attack, which suggests that protease inhibitors can enhance the indirect defenses of plants. The results suggest that employing both direct and indirect defenses—such as a combination of biological pesticides and genetic engineering to produce both HIPVs and protease inhibitors—is the best approach for defending agricultural plants against pests.

      DOI: http://dx.doi.org/10.7554/eLife.00007.002

      Author keywordsNicotiana attenuataherbivory-induced plant volatileplant-predator interactiongreen leaf volatiletrypsin protease inhibitorindirect defenseResearch organismOtherMax Planck SocietySchumanMeredith CBarthelKathleenBaldwinIanThe funder had no role in study design, data collection and interpretation, or the decision to submit the work for publication.elife-xml-version2Author impact statementA 2-year field study has demonstrated that volatile compounds produced by plants when they are attacked by herbivores act as defenses by attracting predators to the herbivores and increasing the reproduction of the plants.
      Introduction

      Plant indirect defenses are traits that disable or remove herbivores by manipulating tri-trophic interactions to the advantage of the plant (Price et al., 1980). They attract and inform the third trophic level, predators or parasitoids, resulting in increased attacks on herbivores (Turlings and Wäckers, 2004). Indirect defenses are widespread and include domatia, extrafloral nectar, and food bodies which provide shelter and nutrition for predators and parasitoids, as well as herbivory-induced plant volatiles (HIPVs) which convey information about feeding herbivores (Heil, 2008). Field studies with the native tobacco Nicotiana attenuata, a desert annual, and with maize have shown that HIPVs can reduce herbivore loads by 24% to more than 90%, by increasing both predation and parasitization of herbivores (Kessler and Baldwin, 2001; Rasmann et al., 2005; Halitschke et al., 2008; Degenhardt et al., 2009; Allmann and Baldwin, 2010) and deterring herbivore oviposition (Kessler and Baldwin, 2001).

      If HIPVs really function as defenses, they should increase Darwinian fitness, defined as successful reproduction, for plants under herbivore attack (Karban and Baldwin, 1997). But because HIPVs can be perceived by many other members of the ecological community—from herbivores, pollinators, predators and parasitoids to competing or parasitic plants—it is not clear whether HIPVs increase plant fitness in nature (Dicke and Baldwin, 2010; Kessler and Heil, 2011). The field studies described above have either spanned too short a time to reveal Darwinian fitness benefits, or have not reported fitness data at all (Kessler and Baldwin, 2001; Rasmann et al., 2005; Halitschke et al., 2008; Degenhardt et al., 2009; Allmann and Baldwin, 2010). Two laboratory studies showed that parasitization of herbivores can increase plant reproduction (van Loon et al., 2000; Hoballah and Turlings, 2001), but the parasitization in these studies was not mediated by HIPVs. Hence three decades after their description, it remains unclear whether HIPVs are really indirect defenses.

      Long-term field studies comparing HIPV-emitting vs -deficient plants are required in order to demonstrate a defensive function for HIPVs. Experimental additions of pure volatiles or mixes to plants growing in nature has worked well to test short-term effects of specific compounds (Kessler and Baldwin, 2001; Allmann and Baldwin, 2010), but only endogenously produced HIPV emissions can ensure specific, lasting and consistent differences under field conditions. Most evidence for the utility of HIPVs comes from studies in which predators and parasitoids learn to associate HIPVs with prey; naïve predators and parasitoids are just as likely to respond to HIPVs as not to respond (Allison and Hare, 2009). Thus the inducibility of HIPV emission, which ensures association with herbivore feeding, is likely essential for HIPV function, but it is difficult to engineer (Kos et al., 2009). Engineered constitutive HIPV emissions have been used, either on predators and parasitoids trained to associate target volatiles with prey in short-term laboratory experiments (Kappers et al., 2005; Schnee et al., 2006), or in set-ups in which target volatiles are always associated with prey (Rasmann et al., 2005; Degenhardt et al., 2009). When plants are engineered constitutively to emit HIPVs, they no longer provide accurate information about the location of feeding herbivores, and predators will not associate these signals with prey in nature. Genetically silencing the biosynthesis of HIPVs, however, permits naturally inducible wild-type (WT) plants to serve as HIPV emitters, for comparison with transformed lines lacking specific volatile components (Halitschke et al., 2008; Skibbe et al., 2008). Furthermore, field experiments that manipulate the production of HIPVs which not only attract the third trophic level, but also influence the second trophic level (e.g., as feeding stimulants and host location cues), require additional experimental manipulations to preserve the plant-herbivore part of the tritrophic interaction.

      When HIPVs do attract the third trophic level, how can herbivores adapt? Many herbivores can outgrow their vulnerability to predators and parasitoids, but plant direct defenses can slow herbivore growth and prolong vulnerability as postulated by the slow growth-high mortality hypothesis (Benrey and Denno, 1997; Williams, 1999; Kessler and Baldwin, 2001, 2004; Kaplan and Thaler, 2011). The solanaceous specialists Manduca sexta and M. quinquemaculata (Lepidoptera, Sphingidae) are resistant to the potent alkaloid toxin nicotine (Wink and Theile, 2002), but sensitive to the nutritional value of plant tissue (Zavala and Baldwin, 2004). Non-toxic protease inhibitor (PI) proteins, which inhibit protein digestion and thus decrease the availability of organic nitrogen in the form of amino acids (Zavala et al., 2008), are widespread in flowering plants (Hartl et al., 2011), and trypsin protease inhibitors (TPIs) slow the growth of M. sexta on N. attenuata (Zavala et al., 2008). However, herbivores can overcome PIs by producing insensitive or desensitized proteases, inactivating or degrading PIs, eating more plant tissue, and eating more nutritious young tissue (Winterer and Bergelson, 2001; Steppuhn and Baldwin, 2007; Zavala et al., 2008). In the latter two cases, PIs could reduce plant fitness. Although TPI-producing N. attenuata plants produce more seeds than TPI-deficient plants when attacked by M. sexta under controlled glasshouse conditions (Zavala and Baldwin, 2004), whether TPIs function as a direct defense in nature is unknown.

      We tested the hypotheses that HIPVs and TPIs defend plants in nature by increasing herbivore predation and thereby plant Darwinian fitness. To do so, we monitored the performance, predation and mortality of Manduca spp. (M. sexta and M. quinquemaculata) on wild-type N. attenuata plants and RNAi transformed lines silenced for the production either of a specific group of HIPVs, or of TPIs, and compared the resulting plant reproductive output in terms of bud and flower production (we are not permitted to allow transgenic plants to disperse ripe seed). Because N. attenuata is an annual, opportunistic out-crosser, seeds are produced within one growing season, mostly from fertilization via self-pollen (Sime and Baldwin, 2003), and we can relate bud and flower production to lifetime seed production, which is commonly accepted as a measure of Darwinian fitness (Baldwin, 1998; van Loon et al., 2000; Hoballah and Turlings, 2001).We hypothesized that HIPVs would increase plant reproduction by increasing predation of herbivores, and that TPIs alone would not increase reproduction under herbivore attack, but would either increase predation or increase herbivores' susceptibility to predators. We then assembled a toolbox of wild-type and transgenic lines chosen to test these hypotheses.

      We chose a genotype of N. attenuata native to the Great Basin Desert of southwestern Utah. In many years, Manduca spp. larvae cause the most defoliation of N. attenuata plants in this area (Kessler and Baldwin, 2001) and thus the N. attenuata 'UT' genotype is likely adapted to defend against Manduca spp. Eggs and young larvae of Manduca spp. are predated by Geocoris spp. (big-eyed bugs) which occur naturally in the Utah habitat and are attracted to components of N. attenuata's HIPV bouquet (Kessler and Baldwin, 2001; Halitschke et al., 2008; Skibbe et al., 2008). Specifically, Utah Geocoris spp. predators are attracted to the sesquiterpene (E)-α-bergamotene as well as green leaf volatiles (fatty acid-derived C6 aldehydes, alcohols and esters) (Kessler and Baldwin, 2001; Halitschke et al., 2008; Schuman et al., 2009). Green leaf volatiles, or GLVs, can be silenced via a single upstream 13-lipoxygenase, NaLOX2, which specifically supplies lipid hydroperoxides for their production (Allmann et al., 2010). Although GLVs are released upon mechanical damage, the oral secretions (OS) of M. sexta convert 3-(Z)-GLVs to the 2-(E)-structures, resulting in greater Geocoris spp. predation than the damage-induced (Z):(E) ratio (Allmann and Baldwin, 2010). GLVs are released immediately upon damage (Allmann and Baldwin, 2010) and may therefore be a 'first line of defense'.

      Like GLVs, many other HIPVs are also released after mechanical damage, but change in amount or ratio upon herbivory, and thus GLVs mirror the functional complexity of the total HIPV blend. Furthermore, GLVs prime or directly regulate responses in neighboring plants (Kessler et al., 2006; Paschold et al., 2006), attract herbivores as well as predators (Halitschke et al., 2008), and are important cues for pollinating and ovipositing moths (Kessler and Baldwin, 2001, 2006; De Moraes et al., 2001; Fraser et al., 2003), thus performing several roles which may harm or benefit plant fitness in addition to their role in attracting predators. Perhaps most significantly, GLVs also stimulate Manduca spp. feeding, and silencing plant GLV production results in reduced herbivore damage (Halitschke et al., 2004; Meldau et al., 2009). All these qualities made the manipulation of GLV emissions an ideal means to test rigorously the fitness consequences of HIPV emissions and to evaluate whether these emissions can truly be considered defensive.

      ResultsGLV and TPI production are reduced or eliminated in transformed lines

      We chose a line of irPI plants with no detectable TPI activity (Steppuhn and Baldwin, 2007), and a line of irLOX2 plants with GLV emissions <20% of WT (Allmann et al., 2010); non-target defense metabolites are not affected in either line (Steppuhn and Baldwin, 2007; Allmann and Baldwin, 2010), including emission of (E)-α-bergamotene measured in a glasshouse characterization of all lines prior to field release (see 'Non-target metabolites are not affected in irLOX2, hemi-irLOX2 or irPI plants'). Because of the importance of GLVs for the plant-herbivore interaction, we used both homozygous (Allmann et al., 2010) and hemizygous irLOX2 plants to provide different levels of GLV silencing. Hemizygous (hemi-) irLOX2 plants were created by crossing homozygous irLOX2 and irPI plants, but the irPI construct was not active in this cross (Figure 1 see 'Discussion').10.7554/eLife.00007.003

      Trypsin protease inhibitor (TPI) activity and transcripts in transformed lines; graphs show means+SEM. (A) TPI activity measured in systemic leaves of field-grown (top two panels, 2011, N=11–14 for panel 1 and N=21 for panel 2) or glasshouse-grown plants (bottom panel, N=10) attacked by Manduca spp. larvae. Only WT, irPI and hemi-irLOX2 plants were used in M4. For a timeline of Manduca spp. infestations M1–M4 see Figure 4A. For raw data, see F2A_SchumanBarthelBaldwin2012TPIactivity.xlsx (Dryad: Schuman et al., 2012). (B) Transcripts of PI in unelicited leaf tissue (control), and at the point of maximum accumulation in W+OS-elicited leaf tissue in glasshouse-grown plants (N=5). For raw data, see F2B_SchumanBarthelBaldwin2012PItranscripts.xlsx (Dryad: Schuman et al., 2012). *W+OS treatment had a significant effect on PI (p<0.001) transcript accumulation. a, b Different letters indicate significant differences between genotypes (p<0.001) in Scheffe post hoc tests following a two-way ANOVA on log2-transformed data with factors treatment and genotype (genotype F3,29=174.077, p<0.001; treatment F1,29=75.909, p<0.001). L.O.D.: below limit of detection for measurement.

      DOI: http://dx.doi.org/10.7554/eLife.00007.003

      The irPI plants (Steppuhn and Baldwin, 2007) had no detectable TPI activity in the glasshouse or throughout the field experiment in 2011, and PI transcripts accumulated to only 0.3% of WT levels in irPI (transcripts, N=5, p<0.001 in Scheffe post hoc tests following two-way ANOVAs on log2-transformed data with factors W+OS treatment and genotype: treatment F1,29=75.909, p<0.001; genotype F3,29=174.077, p<0.001); in contrast, TPI activity and PI transcripts were similar to WT plants in irLOX2 and hemi-irLOX2 (transcripts, N=5, p>0.2 in Scheffe post hoc tests following two-way ANOVAs on log2-transformed data with factors W+OS treatment and genotype; activity, N=10–17, p>0.05 in one-way ANOVAs with factor genotype) (Figure 1).

      We assessed GLV production by hexane extraction of GLVs from frozen leaf tissue, and GLV emission by GC analyses of leaf headspaces. GLVs in hemi-irLOX2 plants were reduced to levels similar to those in irLOX2 plants, but hemi-irLOX2 plants still produced detectable amounts of (Z)-3-hexenol (Figures 2 and 3). The dominant GLV in hexane tissue extracts was (E)-hex-2-enal, and (Z)-hex-3-en-1-ol was additionally quantifiable as a minor component. Only (E)-hex-2-enal was quantifiable in extracts from field-grown plants on May 28, 2011, and was below quantifiable levels in irLOX2 and hemi-irLOX2 plants, but detectable in pooled samples from hemi-irLOX2 (Figures 2 and 3). Extracts from later in the season also contained quantifiable amounts of (Z)-hex-3-en-1-ol and hemi-irLOX2 extracts contained up to 50% as much of this alcohol as WT and irPI extracts (N=10, p<0.05 in Scheffe post hoc tests following one-way ANOVAs with factor genotype: June 14, 2011, F2,26=9.556, p=0.001; June 22, 2011, F2,26=12.196, p<0.001; p>0.6 for irPI vs WT in a t-test for May 28 and in Scheffe post hoc tests for June 14 and 22) (Figure 3). Headspace measurements from field- and glasshouse-grown plants detected a similar 80–100% reduction in GLV emissions from irLOX2 and hemi-irLOX2 plants compared to WT and irPI (field, N=3, p=0.024 for hemi-irLOX2 v irPI, p>0.05 for hemi-irLOX2 vs WT and irLOX2 vs irPI and WT, but p=0.939 for irPI vs WT in Scheffe post hoc tests following one-way ANOVA: F3,8=7.346, p=0.011; glasshouse, N=4: irLOX2 and hemi-irLOX2 below limit of detection, p=0.834 for t-test irPI vs WT) (Figure 3), and transcript accumulation of LOX2 was 2% of WT levels in irLOX2 and hemi-irLOX2 (N=5, p<0.001 in Scheffe post hoc tests following two-way ANOVAs on log2-transformed data with factors W+OS treatment and genotype: treatment F1,32=0.021, p=0.887; genotype F3,32=635.477, p<0.001) but unaffected in irPI (p>0.9 in Scheffe post hoc test vs WT) (Figure 3).10.7554/eLife.00007.004

      Hexane extracts of leaves from field-grown plants. (A) Hexane extracts from pooled leaf samples of field-grown plants for a qualitative assessment of green leaf volatile (GLV) pools, analyzed by GC-MS with a split ratio of 1/100 onto a nonpolar column; only (E)-hex-2-enal was identified due to poor resolution of (E)-hex-2-enal and (Z)-hex-3-en-1-ol on the nonpolar column; no ester peaks were detected. For raw data, see F3A_SchumanBarthelBaldwin2012chromatograms.xlsx (Dryad: Schuman et al., 2012). (B) Example chromatograms from hexane extracts of individual leaf samples from field-grown plants, analyzed by GC-FID on a wax column. The dominant compound was (E)-hex-2-enal; (Z)-hex-3-en-1-ol was also present in quantifiable amounts. (Z)-3-hexenyl acetate was chosen as an internal standard because no esters were detectable in the preliminary qualitative GC-MS analysis (1A), and because its chemical similarity to (E)-hex-2-enal and (Z)-hex-3-en-1-ol made it a good choice of internal standard for normalization and calculation of yield from extracts. For raw data, see F3B_SchumanBarthelBaldwin2012chromatograms.xlsx (Dryad: Schuman et al., 2012). IS: internal standard.

      DOI: http://dx.doi.org/10.7554/eLife.00007.004

      10.7554/eLife.00007.005

      GLV production and emission in transformed lines; graphs show means+SEM. (A) GLVs extracted with hexane from leaf tissue of field-grown WT, irPI, and hemi-irLOX2 plants grouped in triplets for infestation M4 in 2011(Figure 4A). Leaves were harvested from every plant at the beginning (June 14) and in the middle of M4 (June 22) and leaves from plants in 10 randomly chosen triplets were analyzed. Only (E)-hex-2-enal and (Z)-hex-3-en-1-ol were quantifiable in leaf extracts. Different letters (a and b) indicate significant differences (p≤0.05) in Scheffe post hoc tests following one-way ANOVAs for (Z)-hex-3-en-1-ol (top panel, F2,26=9.556, p=0.001; bottom panel, F2,26=12.196, p<0.001). For raw data, see F4A_SchumanBarthelBaldwin2012GLVpools.xlsx (Dryad: Schuman et al., 2012). (B) GLVs measured in headspace samples of leaves from field-grown (top panel, N=3) or glasshouse-grown plants (bottom panel, N=4). For field-grown plants, leaves were harvested and measured on May 21 (just before M3). Intact leaves were kept fresh by placing petioles in water. Immediately before each measurement, one leaf was treated with wounding and M. sexta oral secretions (W+OS); a 1-cm2 disc was stamped out and placed in a 4-mL GC vial. After 15 min the headspace in the vial was measured with a Z-Nose 4200 and total alcohols and aldehydes were quantified. Different letters (a and b) indicate significant differences (p<0.05) in Scheffe post hoc tests following one-way ANOVA (F3,8=7.346, p=0.011). For glasshouse-grown plants, leaves were left on plants, treated with W+OS, and enclosed in padded, 50 mL food-quality plastic containers for 3 hr while the headspace was pulled over a Poropak Q filter. Filter eluents were measured by GC-MS. Three-hour headspace samples contained (Z)-hex-3-en-1-ol, (E)-hex-2-en-1-ol (forms from (E)-hex-2-enal on filters over trapping periods longer than 20 min), (Z)-hex-3-enyl acetate, (Z)-hex-3-enyl butanoate, (Z)-hex-3-enyl isobutyrate, and (Z)-hex-3-enyl propanoate, all of which showed the pattern shown for the total amount. For raw data, see F4B_SchumanBarthelBaldwin2012GLVheadspace.xlsx (Dryad: Schuman et al., 2012). (C) Transcripts of LOX2 in unelicited leaf tissue (control), and at the point of maximum accumulation in W+OS-elicited leaf tissue in glasshouse-grown plants (N=5). For raw data, see F4C_SchumanBarthelBaldwin2012LOX2transcripts.xlsx (Dryad: Schuman et al., 2012). a, b Different letters indicate significant differences between genotypes (p<0.001) in Scheffe post hoc tests following a two-way ANOVA on log2-transformed data with factors treatment and genotype (genotype F3,32=635.477, p<0.001, treatment F1,32=0.021, p=0.887). L.O.D.: below limit of detection for measurement.

      DOI: http://dx.doi.org/10.7554/eLife.00007.005

      Non-target metabolites are not affected in transformed lines

      For the ‘UT’ genotype of N. attenuata used in our experiments, the induction of all HIPVs except GLVs is mediated by jasmonate signaling (Halitschke and Baldwin, 2003; Kessler et al., 2004). The irPI line A-04-186-1 (Steppuhn and Baldwin, 2007) and irLOX2 line A-04-52-2 (Allmann et al., 2010) have been characterized previously, and neither is affected in jasmonate signaling. Particularly, the emission of (E)-α-bergamotene, the best-characterized HIPV in N. attenuata apart from GLVs (Halitschke et al., 2000; Kessler et al., 2004; Halitschke et al., 2008; Skibbe et al., 2008), does not differ significantly among the lines used (N=4 measured 24–32 hr after W+OS treatment as according to Halitschke et al. (2000) and normalized as a percentage of the internal standard peak: WT, 67.9±17.1%; irPI, 30.2±13.2%; irLOX2, 26.6±5.8%; hemi-irLOX2, 42.7±23.3%; ANOVA: F3,12=1.338, p=0.308). The transformation process itself does not affect plant fitness or competitive ability (Schwachtje et al., 2008), TPI production or volatile emission (Figures 1–3).

      <italic>Geocoris</italic> spp. consistently prefer to predate from GLV-perfumed or -emitting plants

      We monitored the predation of Manduca spp. larvae and eggs daily, and counted Geocoris spp. individuals around plants every 2–3 days (Geocoris spp. counts, Figure 4). In 2010, we planted into a first-year plot. Although plants were infested with laboratory strain M. sexta larvae (N=51) and baited with M. sexta eggs (N=50) over a 2-week period in 2010 (Figure 4), no Geocoris spp. individuals were observed on this plot through May. There were also no Geocoris spp. observed through May on a nearby, older plot: Geocoris spp. first arrived and began to predate Manduca spp. eggs on the older plot on June 9. In 2011, we planted into the older plot, where we observed Geocoris spp. in May prior to the first infestation (M2, Figure 4).10.7554/eLife.00007.006

      Experimental timeline and layout. (A) Timeline of field experiments in 2010 and 2011. Different assays and measurements are represented by individual arrows, and rectangles span the time frame of each assay or measurement; narrow rectangles represent single days. Four experimental Manduca infestations (M1–M4) structure the overall experimental design: M1–M3, with laboratory Manduca, and M4, with wild Manduca larvae. (B and C) Layouts of field plots in (B) 2010 and (C) 2011. Thick lines denote the borders of the experiment, thin lines denote irrigation lines (vertical borders of plot were also irrigation lines in [B] 2010), and R# denotes row number (used for identifying replicates during the experiment). The genotype key in (B) applies to both (B) and (C).

      DOI: http://dx.doi.org/10.7554/eLife.00007.006

      During infestation M2 (Figure 4), we allowed Geocoris spp. to associate all four plant genotypes with the presence of prey: we infested half of all plants with equal numbers of first-instar M. sexta larvae from the laboratory strain and, because Geocoris spp. predate more from GLV-emitting or-perfumed plants (Kessler and Baldwin, 2001; Halitschke et al., 2008; Allmann and Baldwin, 2010), we supplemented GLV emission from irLOX2 and hemi-irLOX2 plants by placing cotton swabs with lanolin paste containing GLVs representative of the M. sexta-fed N. attenuata headspace (Table 1 Allmann and Baldwin, 2010) adjacent to M. sexta-infested leaves. Swabs containing lanolin with solvent were placed next to irPI and WT as a control. M. sexta larvae were predated at a rate of 12–37% over two 2- to 3-day trials. Geocoris spp. tended to predate more larvae from GLV-supplemented plants (Fisher's exact tests, 35–37% vs 22–27% May 5–6, N=59–60 larvae, p=0.066; 17–21% vs 12% May 13–15, N=92–100 larvae, p=0.069; combined trials, Bonferroni-corrected p=0.0063) (Figure 5).10.7554/eLife.00007.007

      GLV mix used to externally supplement plant GLV emission in M2 (see Figure 4) (Allmann and Baldwin, 2010)

      DOI: http://dx.doi.org/10.7554/eLife.00007.007

      ComponentNanogram/20 μL lanolin
      (Z)-hex-3-enal3530
      (E)-hex-2-enal2690
      (Z)-hex-3-en-1-ol1780
      (E)-hex-2-en-1-ol2440
      (Z)-hex-3-enyl acetate46.6
      (E)-hex-2-enyl acetate35.5
      (Z)-hex-3-enyl propanoate9.00
      (E)-hex-2-enyl propanoate8.08
      (Z)-hex-3-enyl butanoate97.0
      (E)-hex-2-enyl butanoate35.6

      Pure GLVs were diluted in 1 mL of hexane and mixed into 14 mL of lanolin to yield the amount shown per 20 μL, representing the emission per g leaf material within the first 20 minutes of W+OS elicitation. Lanolin containing an equivalent amount of hexane was used as a control.

      10.7554/eLife.00007.008

      Predation of M. sexta larvae and eggs by Geocoris spp. (A) Examples of predated M. sexta larva (left panel) and egg (right panel). Left, the carcass of a predated first-instar M. sexta larva and typical feeding damage from early-instar Manduca spp. larvae. Right, an intact (lower left) and a predated (upper right) Manduca spp. egg. In this case, the predated egg collapsed during predation. (B) Total predation of M. sexta larvae per trial over two trials during infestation M2. GLVs were supplemented externally by placing cotton swabs next to Manduca-infested leaves (1 per plant). Cotton swabs next to irLOX2 and hemi-irLOX2 plants received 20 μL of a GLV mixture in lanolin paste (Table 1); those next to WT and irPI plants received lanolin with hexane as a control because hexane was used to dissolve GLVs before mixing with lanolin. N=59–60 larvae on May 5–6 and 92–100 larvae on May 13–15. Geocoris spp. tended to predate more larvae from GLV-supplemented plants (Fisher's exact tests, 35–37% vs 22–27% May 5–6, p=0.066; 17–21% vs 12% May 13–15, p=0.069; combined trials, Bonferroni-corrected p=0.0063). (C) Total percentage of M. sexta larvae (left panel, N=30 larvae) and eggs (right panel, N=88 eggs) predated in two separate trials during infestation M3 in 2011 (Figure 4). There was no predation of larvae or eggs by Geocoris spp. in 2010. Raw data for (B) and (C) is in F5BC_SchumanBarthelBaldwin2012predation.xlsx (Dryad: Schuman et al., 2012). Pictures are of a G. pallens adult predating a first-instar Manduca spp. larva (left) and a fifth-instar G. pallens nymph predating a Manduca spp. egg (right picture, S. Allmann). *p<0.05, ***p<0.001 in Fisher's exact tests against WT (irLOX2) or irPI (hemi-irLOX2, which also contains the irPI construct).

      DOI: http://dx.doi.org/10.7554/eLife.00007.008

      We removed the cotton swabs and the remaining larvae. We then monitored predation of newly-infested larvae and eggs without GLV supplementation during infestation M3 (Figure 4). We staggered infestation to accommodate differences in plant growth: WT and irPI seedlings were initially larger and therefore were planted into the field on average 3 days earlier than irLOX2 and hemi-irLOX2 plants, so that all plants were planted at a similar size, which is important for even establishment. We therefore re-infested WT and irPI plants earlier after M2, to allow irLOX2 and hemi-irLOX2 plants to catch up in their growth to WT and irPI before re-infestation, so as not to bias further assays. However, we left M. sexta larvae on irLOX2 and hemi-irLOX2 as long as on WT and irPI, and we made several control measurements to ensure that differences in Geocoris spp. predation were not due to our staggering of infestation: we counted Geocoris spp. populations around all genotypes over this period (Table 2) and saw that they were not different (p>0.05 in Fisher's exact tests), indicating that Geocoris spp. continued to explore irLOX2 and hemi-irLOX2 plants but not to predate from them over a week of infestation followed by 5 days of M. sexta egg predation assays (during which M. sexta eggs were simultaneously applied to all genotypes); and we followed predation of M. sexta larvae from all four genotypes in parallel over 1 week, during which irLOX2 and hemi-irLOX2 were infested with more larvae than WT and irPI due to sustained higher predation rates on WT and irPI; but predation remained higher on WT and irPI.10.7554/eLife.00007.009

      Numbers (N) of Geocoris spp. individuals (nymphs and adults) within 5 cm radii around plants used for predation experiments, counted within half an hour during the main period of Geocoris spp. activity

      DOI: http://dx.doi.org/10.7554/eLife.00007.009

      ExperimentGenotypeGeocoris spp. per day (n)Plants (n)
      Larval predationDatesMay2122
      May 21–23, 2011WT3419
      irPI6624
      irLOX26420
      hemi-irLOX28220
      Total231683
      Egg predationDatesJune3457
      June 2–6, 2011WT252118
      irPI371521
      irLOX2420321
      hemi-irLOX2112224
      Total101551184

      Numbers are shown as subtotals for each plant genotype and grand totals per day (in bold).

      Predation of both larvae and eggs without GLV supplementation was two to four times as great on GLV-emitting WT and irPI plants: 43%/60% (WT/irPI) for larvae and 34%/39% for eggs, vs 17%/33% (irLOX2/hemi-irLOX2) for larvae and 9%/20% for eggs (Fisher's exact tests: N=30 larvae, p=0.047 for irLOX2 vs WT, p=0.069 for hemi-irLOX2 vs irPI; N=88 eggs, p<0.001 for irLOX2 vs WT, p=0.013 for hemi-irLOX2 vs irPI) (Figure 5). Predation was associated with a steady Geocoris spp. population of 16–23 individuals per day within a 5 cm radius around plants (Table 2). However, there was no difference among plant genotypes in the number of Geocoris spp. individuals (p>0.05 in Fisher's exact tests), indicating that Geocoris spp. regularly survey all plants and use GLVs as a short-distance cue to determine which plants harbor prey. Figure 5 shows larval predation rates at the beginning of the assay, when the M. sexta load was comparable across plant genotypes. Over the following week, Geocoris spp. predated a total of 80% of these larvae from WT and irPI vs 47% from irLOX2 (Fisher's exact test, p=0.015 vs WT) and 67% from hemi-irLOX2 (p=0.382 vs irPI).

      In summary, Geocoris spp. had the same opportunity to locate M. sexta larvae and eggs on all genotypes, but consistently preferred to predate from GLV-supplemented or -emitting plants.

      <italic>Manduca</italic> spp. damage reduces plant growth and reproduction

      We took the different number of ‘days in field’ for each plant into account in our comparison of growth and reproduction among genotypes and therefore the staggered planting did not affect this comparison (Figure 6, statistics Table 3). The irLOX2 and hemi-irLOX2 plants suffered, in total, a similar amount of M. sexta damage to WT plants in trials M2 and M3 (Figure 4), and only irPI plants suffered significantly less M. sexta damage (Figure 7).10.7554/eLife.00007.010

      Growth and reproduction of plants during the 2010 and 2011 field seasons; graphs show means±SEM. (A) Final growth measurements for M. sexta-infested and uninfested control plants of each genotype in 2011 (left, 44–45 days after planting, N=11–17) or M. sexta-infested plants in 2010 (right, June 6, 2 days after the removal of fifth-instar M. sexta larvae). *p<0.05 for Wilks' Lambda test of the effect of M. sexta feeding on growth and reproduction in 2011, day 44–45, in a two-way MANOVA with factors genotype and treatment (F6,52=2.287, p=0.049). *p-values above individual graphs denote the significance of M. sexta feeding over all genotypes in 2011 for the measurement shown in the MANOVA, or in a separate Mann-Whitney U-test for side branches (stem F1,57=9.155; side branches, U = 270; buds F1,57=4.572); values for individual genotypes are in Table 3. a, b, c Different letters denote significant (p<0.05) differences between genotypes in 2011 for Scheffe post hoc tests (rosette diameter F3,57=8.791, p<0.001, stem length F3,57=4.192, p=0.009, number of buds F3,57=9.876, p<0.001) or Bonferroni-corrected p-values for Mann-Whitney U-tests following a Kruskal-Wallis test (side branches χ2 = 10.958). In 2010, in the absence of Geocoris spp. activity, there were no significant differences between genotypes in the parameters shown with or without M. sexta infestation (Table 3). Bud numbers from 2010 are also shown in Figure 9. (B and C) Flower production for M. sexta-infested and uninfested control plants from the beginning of flowering in (B) 2011 and (C) 2010. Flowers were counted and removed at the time points shown: each time point represents new flower production. Insets in (C) show the first two time points for irPI and hemi-irLOX2. *p<0.05 for the main effect of M. sexta infestation in a repeated-measures ANOVA with log2-transformed data (Table 3). Raw data for 2011 is in F6AB_SchumanBarthelBaldwin2012growth_reproduction2011.xlsx and T4_SchumanBarthelBaldwin2012growth_reproduction2011.xlsx, and data for 2010 is in F6AC_SchumanBarthelBaldwin2012growth_reproduction2010.xlsx (Dryad: Schuman et al., 2012).

      DOI: http://dx.doi.org/10.7554/eLife.00007.010

      10.7554/eLife.00007.011

      Results of Mann–Whitney U-tests, Kruskal–Wallis tests, and ANOVAs for control vs M. sexta-infested plants of each genotype grown in the field in 2010 and 2011 (Figures 6 and 9)

      DOI: http://dx.doi.org/10.7554/eLife.00007.011

      2010BranchesStem, buds, flowers
      Mann–Whitney, Kruskal–WallisMANOVA, Wilks' lambda
      ComparisonGenotypedfχ2p*dfFp
      TreatmentAll10.0221.0003, 1480.4630.709
      GenotypeAll32.9090.8029, 360.3441.1860.303
      Branches (n)Rosette diameter (cm)Stem length (cm)Buds (n)Flowers (n)
      2011Student's t-testStudent's t-testMANOVA, Wilks' lambdaMANOVA, Wilks' lambdaMANOVA, Wilks' lambda
      ComparisonGenotypedftpdftpdfFpdfFpdfFp
      Treatment×timeWT261.6960.10226−0.8700.9325, 223.8710.0115, 223.1880.0263, 241.2130.326
      irPI261.0240.31526−0.1610.8735, 220.9910.4465, 220.6560.6605, 220.5250.755
      irLOX2251.1120.27725−0.0580.9545, 210.6060.6965, 210.5350.7485, 210.5400.744
      hemi-irLOX2221.7530.094221.1400.2675, 181.1180.3865, 183.0010.0384, 190.7230.587

      2010: Numbers of side branches (Mann–Whitney, Kruskal–Wallis), stem length, and final numbers of buds and flowers (MANOVA) were recorded in a single measurement at the end of M1 (Figure 4). Numbers of newly produced flowers were counted repeatedly upon flower removal, and Wilks' Lambda F values for the main effect of M. sexta feeding are shown from repeated-measures ANOVAs across all measurements; Wilks' F values for the M. sexta-by-time interaction were not significant. * Bonferroni-corrected p-values.

      2011: Because many plants had few or no side branches before the final measurement, and rosette diameters did not change over the period that plants were measured, t-tests are shown for the final measurement of these parameters in M3 (Figure 4). For stem lengths, numbers (n) of buds, and numbers of flowers, Wilks' lambda F values for the M. sexta-by-time interaction are shown from repeated-measures ANOVAs across all measurements. Significant p-values are given in bold.

      10.7554/eLife.00007.012

      Herbivore damage to plants during the 2010 and 2011 field seasons (means+SEM). For a timeline of Manduca infestations M1–M4, see Figure 4A. (A) Total canopy damage due to naturally occurring herbivores before the start of infestation M1 in 2010, N=17. For raw data, see F7A_SchumanBarthelBaldwin2012herbivoreDamage2010.xlsx (Dryad: Schuman et al., 2012). (B) Total canopy damage due to naturally occurring herbivores before infestation M2 (May 5) and near the end of M3 (May 27) in 2011, N=24–28. a, b Different letters denote significant (p<0.05) differences between genotypes in Scheffe post hoc tests following one-way ANOVAs for arcsine-transformed data at each timepoint (mirids May 27 F3,103=5.291, p=0.002; noctuids May 27 F3,103=3.503, p=0.018); n.s.: not significantly different. #p<0.05 for the main effect of genotype on noctuid damage in a Bonferroni-corrected Kruskal-Wallis test, May 5 (χ2=11.239, p=0.027). (C) Damage in 2011 from M. sexta larvae used in the predation assays in M2 (left panel) and M3 (right panel). GLVs were externally supplemented to plants in infestation M2 and not in M3. Total canopy damage was estimated, using the index, by an independent observer without knowledge of plant identity (N=11–17). *p<0.05 in a Mann-Whitney U-test between irPI and WT on May 28 (U=54, p=0.046); the difference on May 15 was not significant (p>0.1). Note that scales differ. Raw data for (B) and (C) is in F7BC_SchumanBarthelBaldwin2012herbivoreDamage2011.xlsx (Dryad: Schuman et al., 2012).

      DOI: http://dx.doi.org/10.7554/eLife.00007.012

      Reduced predation of M. sexta from irLOX2 and hemi-irLOX2 in trials M2 and M3 in 2011 (Figure 4) correlated with the reduced growth and reproduction of both genotypes, by 30–50% for irLOX2 and 20–30% for hemi-irLOX2 vs WT, although this reduction was also apparent in plants not infested with M. sexta. (Figures 4 and 6, statistics Table 3). In 2010 however, in the absence of predation, there was no difference in stem growth, branching, or bud and flower production among genotypes irrespective of M. sexta infestation (Figure 6, statistics Table 3). Although M. sexta feeding significantly affected growth and reproduction of plants overall, the effect was not significant for irLOX2 or irPI plants in either year (Figure 6, statistics Table 3), possibly due to reduced feeding damage resulting from a lack of TPI-induced compensatory feeding in irPI (Steppuhn and Baldwin, 2007) (Mann-Whitney U-test between irPI and WT on May 28, U=54, p=0.046, Figure 7). Although GLVs are feeding stimulants (Halitschke et al., 2004), we could not measure reduced M. sexta feeding damage in hemi-irLOX2 or irLOX2 (Figure 7). Yet hemi-irLOX2 plants, despite strongly reduced GLVs, still suffered reduced growth and reproduction from Manduca spp. feeding: M. sexta feeding reduced flower production rates by about 50% in WT and by about 30% in hemi-irLOX2 plants in 2010, although the overall reduction was only significant in WT; and reduced bud production significantly for both WT and hemi-irLOX2 by 25–30% in 2011 (Figure 6, statistics Table 3).

      Damage from naturally occurring herbivores other than <italic>Manduca</italic> spp. cannot explain differences in plant fitness

      We monitored herbivore attack to determine whether GLV-silenced plants suffered different amounts of damage from naturally occurring herbivores, which could also cause differences in their growth and reproduction. All genotypes were attacked by mirid (Tupiocoris notatus) and noctuid herbivores which caused similar amounts of damage across genotypes and years (ca. 15% and 3% of total canopy area, respectively) although irLOX2 plants suffered 60% less mirid and noctuid damage by the end of M3 in 2011 (N=24–28; Bonferroni-corrected Kruskal-Wallis test, noctuids May 5, p=0.027, all pairwise tests Bonferroni-corrected p>0.05; one-way ANOVAs with factor genotype on arcsine-transformed data: mirids May 27, F3,103=5.291, p=0.002, p<0.05 for irLOX2 vs hemi-irLOX2 and irPI in Scheffe post hoc tests, noctuids May 27, F3,103=3.503, p=0.018, all post hoc tests p>0.05; all other comparisons p>0.05; Figures 4 and 7). Reduced herbivore damage on irLOX2 in 2011 could have increased the growth and reproduction of irLOX2 plants relative to WT, but cannot explain why irLOX2 plants instead displayed reduced growth and reproduction. Plants in 2011 were also damaged by flea beetles and grasshoppers (<3% of canopy area, Kruskal-Wallis tests, N=24–28, all comparisons p>0.05, Figure 7).

      We cannot exclude the possibility that reduced growth and reproduction of uninfested irLOX2 and hemi-irLOX2 plants in 2011 (Figure 6, statistics Table 3) might have been due to non-herbivory-related factors (e.g., differences in root health corresponding to GLV antimicrobial properties) which did not play a role in 2010. Because of this uncertainty, we conducted assay M4 (Figure 4) in which plants were carefully matched for size and prior reproduction (Figure 8), and this experiment is the more robust basis for our argument that GLV-mediated indirect defense increases plant reproduction.10.7554/eLife.00007.013

      Comparison of plants used in triplets for infestation M4 in 2011 (see Figure 4A); graphs show means+SEM (N=21 plants). (A) Parameters used to match plants in triplets. Measurements and assessments are from the first day of M4. (B) Final measurement of prior growth and reproduction for plants used for triplets; data are from the final two measurements during infestation M3 (see Figure 4A). a, bDifferent letters denote significant differences (p<0.001) for flower number in Scheffe post hoc tests following a MANOVA with all measurements and genotype as the factor (F2,60=8.668, p<0.001). (C) Health index used in (A). For raw data, see F8_SchumanBarthelBaldwin2012triplets.xlsx (Dryad: Schuman et al., 2012).

      DOI: http://dx.doi.org/10.7554/eLife.00007.013

      GLV-mediated <italic>Manduca</italic> spp. mortality positively correlates to plant reproduction

      To ensure that the correlated differences we observed in plant reproduction and M. sexta mortality were due to plant GLV emission and not to different timing and amounts of M. sexta damage, and to avoid the influence of non-herbivory-related factors, we conducted a Manduca spp. predation and plant performance assay during infestations M1 in 2010, and M4 in 2011 (Figure 4) for which all plants used were matched for size, as well as former damage and reproduction as necessary (Figure 8), and infested simultaneously with Manduca spp. neonates. We hypothesized that the 50% lower predation rates of Manduca spp. from GLV-deficient plants (Figure 5), combined with Manduca spp.'s negative effect on growth and reproduction (Figure 6), would result in reduced reproduction for GLV-deficient versus matched GLV-producing plants if Geocoris spp. were present. Homozygous irLOX2 plants were excluded from these 'matched' experiments because they did not suffer reduced growth or reproduction from M. sexta feeding, and because they were too small in comparison to other lines in 2011 (Figure 6).

      In both 2010 and 2011, we selected triplets of WT, irPI and hemi-irLOX2 plants similar in size, reproductive output, apparent health, and prior damage; damage from naturally occurring herbivores did not differ among these genotypes (Figure 7). In 2010, matched plants were part of infestation M1 (Figure 4) and thus it was not necessary to control for prior reproduction or M. sexta damage. Plants in 2010 received three lab strain M. sexta larvae per plant to a lower stem leaf. We recorded the mortality of M. sexta larvae and the reproductive output of plants until they began to set unripe seed. No reproductive meristems were removed, but flowers were removed and counted periodically over the first 10 days, as was done during infestation M3 in 2011 (Figures 4 and 6, statistics Table 3), to track plant reproduction while avoiding ripe seed capsules: the distribution of ripe seed is not permitted for genetically modified plants. In the absence of Geocoris spp. in 2010, genotypes did not differ in M. sexta mortality (N=51 larvae)—which in every observed case was due to a failure of the larva to feed—or plant reproduction (N=17 plants) (Figure 9). This, and the fact that flower production did not differ among genotypes in 2011 through infestation M3 despite flower removal (Figure 6), indicates that flower removal itself does not cause a difference among genotypes, and suggests that the other differences among genotypes in growth and reproduction seen in 2011 (Figure 6, statistics Table 3) are real.

      In 2011, hemi-irLOX2, irPI and WT plants were matched prior to infestation M4 to exclude differences in growth, reproduction and Manduca spp. damage arising during M. sexta infestations M2 and M3 and from caged Manduca spp. during the egg predation assay (Figures 4, 7, and 8). Instead of regularly removing flowers, we removed all reproductive meristems from matched plants in 2011 by cutting inflorescences at their base. This allowed us to follow a new set of reproductive meristems through to seed set without incurring ripe seed. Because plants were matched prior to the assay, a similar number of reproductive meristems were cut from all plants, and thus all plants were similarly affected by this cutting (Figure 8, see 'Discussion').

      Because oviposition by native Manduca spp. moths provided sufficient eggs prior to the beginning of M4 (Figure 4), we decided to conduct this infestation with wild larvae and thereby demonstrate that native larvae, like larvae of the lab strain, are susceptible to GLV-mediated predation. To make M4 a realistic test, we placed one wild Manduca spp. neonate per plant on a lower stem leaf to mimic natural oviposition rates (Kessler and Baldwin, 2001). We again recorded the mortality of Manduca spp. larvae and the new reproductive output of plants until they began to set unripe seed. During the first to third larval instars in which larvae are vulnerable to Geocoris spp. predation (Kessler and Baldwin, 2001), wild Manduca spp. mortality was 38% on hemi-irLOX2 plants vs 62–76% on matched WT and irPI plants; the overall mortality of larvae on all three lines was significantly different (N=21 larvae, Bonferroni-corrected pairwise comparisons by Friedman tests, p<0.01) (Figure 9). Although Manduca spp. mortality on hemi-irLOX2 jumped to 70% in the fourth and semi-final larval instar, this was likely due to predation by whiptail lizards (Cnemidophorus spp.) which were present on the field plot: these lizards predate late-instar Manduca and are attracted to short-chain fatty-acid volatiles produced by the larvae due to ingestion of acyl sugars in plant trichomes (Stork et al., 2011; Weinhold and Baldwin, 2011).10.7554/eLife.00007.014

      Cumulative mortality of Manduca spp. larvae and numbers of reproductive units produced by infested plants in 2010, in the absence of Geocoris spp. predation, and in 2011, when Geocoris spp. were active predators of Manduca spp. (A) In 2010, flowering plants matched for size (N=17) were each infested with three M. sexta neonates from a laboratory culture (N=51 larvae), which were allowed to reach the final instar on plants. The upper panel shows larva mortality over time, which reached a maximum of 40% by the fifth instar, after 12 days. Flower production (lower panel) did not differ, nor did any other parameters of plant size and reproduction (Figure 6, Table 3) including number of buds produced by June 6, which was day 19 after infestation and day 49 after planting in the field. For raw data, see F9A_SchumanBarthelBaldwin2012data2010.xlsx (Dryad: Schuman et al., 2012). (B) In 2011, plants (N=21) were matched for size, prior reproduction, health, and previous damage by Manduca spp. and other herbivores (Figures 7 and 8) following the end of infestation M3 (Figure 4), and reproductive meristems were removed. Matched plants were infested with one wild Manduca spp. neonate each (M4 in Figure 4), and Manduca spp. larvae were allowed to reach the fourth (penultimate) instar. Larval mortality (upper panel) reached a maximum of 76% after larvae transitioned from the second to third instar (days 9 and 10), at which time larval mortality on hemi-irLOX2 was only half as great as on WT or irPI; larvae beyond this stage are not susceptible to Geocoris spp. (Kessler and Baldwin, 2001). Flower and bud production (lower panel) was twice as great in WT and irPI as in hemi-irLOX2, and numbers of flowers and buds correspond to numbers of seed capsules: hemi-irLOX2 plants also produced fewer unripe seed capsules than WT or irPI plants. For raw data, see F9B_SchumanBarthelBaldwin2012data2011.xlsx (Dryad: Schuman et al., 2012). a, b, c Different letters indicate significant differences (p<0.01) in Bonferroni-corrected pairwise Friedman tests (Manduca spp. mortality), or Scheffe post hoc tests of hemi-irLOX2 versus WT and irPI flowers and buds following a repeated-measures MANOVA over all flower and bud counts shown (results of Greenhouse-Geisser-corrected univariate tests for the interaction of line and day: buds, F4.988,149.653=5.297, p<0.001; flowers, F3.722,111.657=4.403, p=0.003), or significant differences (p<0.05) in Scheffe post hoc tests following an ANOVA for unripe seed capsules at day 15 with genotype as the factor (F2,60=4.142, P=0.021).

      DOI: http://dx.doi.org/10.7554/eLife.00007.014

      The plants used in M4 had not previously differed in their reproduction except that hemi-irLOX2 plants had produced more flowers than WT, but not irPI plants (Figure 8). By the end of the assay, the hemi-irLOX2 plants had produced 40–50% fewer buds and flowers than matched WT and irPI plants (N=21 plants, p<0.05 in Scheffe post hoc tests for hemi-irLOX2 vs WT and irPI flowers and buds following a repeated-measures MANOVA over all flower and bud counts, Wilks' Lambda for the interaction of line and day: F12,110=2.835, p=0.002) (Figure 9). This reduced bud and flower production was not due to accelerated seed set: unripe seed capsules on hemi-irLOX2 plants were also reduced by 50% (N=21 plants, p=0.021 for hemi-irLOX2 vs irPI in a Scheffe post hoc test following an ANOVA with genotype as the factor, F2,60=4.142, p=0.021) (Figure 9). These data demonstrate that herbivore-induced GLV emissions function as indirect defenses by increasing predation of Manduca spp. larvae twofold, resulting in a twofold increase in bud and flower production for N. attenuata in its native habitat.

      <italic>M. sexta</italic> and <italic>M. quinquemaculata</italic> perform similarly on plants

      To ensure that our results were not biased by the use of wild Manduca spp. larvae, which comprised both M. sexta and M. quinquemaculata, we analyzed the growth (length over time) and instar change of larvae on plants in M4 by larval species. M. sexta and M. quinquemaculata did not differ in their growth or instar progression (N=11–13, repeated measures ANOVA for days 4–11, Wilks' Lambda for the interaction of day and species: F11,12=1.356, p=0.311). Because larvae of the two species cannot be distinguished before the third instar, we could not test whether mortality was equal for both species in the first three instars; however, because other collections of wild eggs around the same time as the collection for our experiment yielded a 1:1 ratio of species, and because our ratio of the species remained 1:1 after larvae reached the third instar, it is likely that mortality of the two species was equal prior to the third instar.

      <italic>Manduca</italic> spp. response to mock predator attack is altered by TPI consumption

      TPIs had a less consistent and, contrary to our expectations, negative effect on Manduca spp. predation (Figure 5); furthermore, there was no positive effect of TPIs on plant growth and reproduction (Figure 6, statistics Table 3) and only a marginal effect of TPIs on Manduca spp. growth under natural conditions (N=13–26 second instar larvae during M2, one-way ANOVAs with genotype as the factor, F3,77=2.792, p=0.046, all post hoc tests p>0.05, Figure 10; N=8 second instar larvae during M4, paired t-test between matched WT and irPI, p=0.052). We hypothesized that the reduced access to protein for larvae feeding on TPI-producing plants might nevertheless affect Manduca spp. behavior independently of larval size. Indeed, wild Manduca spp. larvae feeding on WT plants (infestation M4, Figure 4) reacted more sluggishly to experimental provocation than size-matched larvae on irPI plants: they were 75% less likely to attack when lifted off of the leaf (N=5 second-instar larvae matched for size, p=0.035 in paired t-test) (Figure 10, Videos 1 and 2).10.7554/eLife.00007.015

      Mock Geocoris spp. predation assays with Manduca spp. larvae fed on WT or irPI plants. (A) Response of wild Manduca spp. (Figure 4A) on plants in the field to poking with a toothpick and lifting with a featherweight forceps (N=5 second-instar larvae matched for size). We first poked larvae below the horn three times, 3 s apart, with the end of a toothpick and counted how often they attacked the toothpick, defined as the larva whipping its head around toward the toothpick and making contact. We then lifted larvae from the plant using the forceps and counted how often they attempted to attack, or succeeded in attacking the forceps over 15 s. In an attempted attack, the larvae moved from hanging at a 180° angle below the forceps vertically toward the forceps; and in a successful attack, the front end of the larva made contact with the forceps, before returning to its original position. All individuals were recorded and responses were counted from videos (see Videos 1 and 2). *p<0.05 in a paired t-test. (B) Left, response of M. sexta from a laboratory strain raised for 48 hr in boxes on either WT or irPI leaf tissue (N=20 first-instar larvae matched for size) to being poked, pierced and lifted with an insect pin. Right, growth of larvae in the following 24 hr. The procedure was identical to that for the on-plant assay described above, except that larvae were poked with an insect pin rather than a toothpick, and then pierced in the rear flank and lifted with the same insect pin (see Videos 3 and 4). *p<0.05 in a paired t-test. The length of each larva was measured prior to poking and lifting. Afterward, larvae were placed in individual cups, each with a moist paper towel round and fresh WT or irPI leaf tissue, and length of the larvae in millimeters was again measured after 24 hr; mortality did not differ between WT- and irPI-fed larvae. *p<0.05 in a Student's t-test. (C) Upper panel, length of first instar larvae fed for 2 days on WT or irPI tissue and size-matched for use in the off-plant behavioral assay mimicking Geocoris attack (B); lower panel, mortality of first instar larvae 24 hr after mock Geocoris attack as described in (B). Mortality was not significantly different in a Fisher's exact test. (D) Larval length in the first instar after 2 days on plants in the field: larvae on irPI were not significantly larger. Length of surviving larvae was measured in a predation assay during infestation M3 (Figures 4 and 5C), N=13–26 larvae. Length was not significantly different for larvae feeding on irPI in a one-way ANOVA with genotype as the factor (F3,77=2.792, p=0.046, all post-hoc tests p>0.05). For raw data, see F10_SchumanBarthelBaldwin2012Manduca.xlsx (Dryad: Schuman et al., 2012).

      DOI: http://dx.doi.org/10.7554/eLife.00007.015

      10.7554/eLife.00007.016

      On-plant assay, plant 7u, WT, June 18, 2011.

      DOI: http://dx.doi.org/10.7554/eLife.00007.016

      10.7554/eLife.00007.017

      On-plant assay, plant 2o, irPI, June 18, 2011.

      DOI: http://dx.doi.org/10.7554/eLife.00007.017

      We were careful not to harm wild larvae so that we could monitor their natural mortality and consequences for plant reproduction (Figure 9). To more accurately imitate Geocoris spp. attack, we developed an off-plant assay with larvae from the laboratory M. sexta strain feeding on detached leaves from field-grown plants, in which size-matched larvae were poked, pierced and lifted using an insect pin to mimic the Geocoris spp. beak (Figure 10, Videos 3 and 4). Similarly to the on-plant assay, larvae fed on WT leaves were 50% less likely to successfully attack the insect pin, either when initially poked, or poked and lifted with the pin (N=20 first-instar larvae matched for size, p<0.05 in paired t-tests) (Figure 10). We also monitored recovery post-trial and found that WT-fed larvae ceased to grow for at least 24 hr after simulated attack, while irPI-fed larvae continued to grow (p=0.016 in Student's t-test); mortality did not differ (p=0.527 in Fisher's exact test) (Figure 10).10.7554/eLife.00007.018

      Off-plant assay, replicate 3, WT, June 24, 2011.

      DOI: http://dx.doi.org/10.7554/eLife.00007.018

      10.7554/eLife.00007.019

      Off-plant assay, replicate 3, irPI, June 24, 2011.

      DOI: http://dx.doi.org/10.7554/eLife.00007.019

      Thus TPIs did not increase plant reproduction under attack from Manduca spp. in nature, but may support indirect defense by weakening the response of larvae to predator attack. The contradictory higher predation rates of Manduca spp. larvae from irPI than from WT plants (Figure 5) might reflect Geocoris spp.'s feeding preference, if irPI-fed larvae are more nutritious than WT-fed larvae (Kaplan and Thaler, 2011).

      Discussion

      Our data demonstrate that herbivore-induced GLV emissions function as indirect defenses by increasing predation of Manduca spp. twofold, resulting in a twofold increase in bud and flower production for N. attenuata in its native habitat. In contrast, there was no positive effect of TPIs on plant growth and reproduction and no significant effect of TPIs on Manduca spp. growth under natural conditions; however, TPIs may support indirect defense by weakening the response of larvae to predator attack. Although this indicates that predation rates from irPI plants should be reduced, we observed a tendency towards higher predation rates from irPI than from WT plants; this could reflect Geocoris spp.'s preference if irPI-fed larvae are more nutritious than WT-fed larvae (Kaplan and Thaler, 2011).

      WT levels of TPIs in hemi-ir<italic>LOX2</italic> plants are likely due to gene dosage effects

      The hemi-irLOX2 plants used in this study were created by crossing homozygous irPI and irLOX2 plants, but the irPI construct was not active in the hemizygous state (Figure 1). We continued to use this cross for its less severely reduced GLV production in comparison to homozygous irLOX2 plants (Figures 2 and 3), which likely permitted growth and reproduction comparable to irPI and WT in 2011 that was essential for plant matching prior to the final assays of Manduca spp. mortality and plant reproduction (M4, Figures 4 and 9). It is common molecular biology knowledge that functional RNAi constructs may be rendered ineffective as a result of insufficient gene dosage, for example, Travella et al. (2006) and references therein, which may occur when an RNAi construct is present in the hemizygous state (García-Pérez et al., 2004). The 35S promoter which drives the transcription of the RNAi construct may also be methylated: an epigenetic effect which can reduce the dose of RNAi in individual plants within a single transformed line (A Weinhold, unpublished data). This may have occurred in the irPI parent used for the creation of the hemi-irLOX2 line, although loss of activity of the irPI construct was not observed in the homozygous irPI line over the lifetime of plants in the field (Figure 1).

      Our best measures of reproduction for transgenic plants in the field demonstrate the positive effect of GLV-mediated indirect defense

      Although the production of viable offspring is the accepted definition of Darwinian fitness, we are not permitted to allow transgenic plants to disperse ripe seed in the field, and measures to prevent seed dispersal, such as bagging meristems, strongly affect production of buds and flowers and can also affect seed viability by increasing temperature, and decreasing respiration and photosynthesis of reproductive tissue and associated green tissue.

      For field-grown N. attenuata plants, fewer than 5% of buds and flowers (in total) are aborted by healthy (not diseased) plants, and abortion seems always to be due to damage by insects (M C Schuman and I T Baldwin, personal observation, June 2010). Plants are self-compatible and more than 70% of seed set from plants in native populations results from fertilization via self-pollen (Sime and Baldwin, 2003). Thus numbers of buds and flowers correlate to lifetime seed capsule production, which in turn correlates to lifetime seed production, which has been used as a proxy measure of Darwinian fitness (Baldwin, 1998; van Loon et al., 2000; Hoballah and Turlings, 2001). The transgenic lines used do not vary in seed mass or their seedling viability under laboratory conditions.

      Meristem removal from plants before infestation M4 was necessary despite matching, and affected all plants similarly

      During the 2011 experiment, we saw a large and reproducible difference in predation from GLV-emitting versus GLV-deficient plant genotypes, which was not observed in 2010 due to an absence of Geocoris spp. predators in that year. This difference in predation rate correlated to a difference in plant growth and reproduction which was also not observed in 2010. To rigorously test the consequences of GLV-mediated predation of Manduca spp. on plant reproduction, we selected triplets of WT, irPI and hemi-irLOX2 plants similar in size, previous reproductive output, apparent health, and prior damage to carry out Manduca spp. mortality and plant reproduction assays (M1 in 2010, M4 in 2011, Figure 4). We removed all reproductive meristems from matched plants in 2011 to allow us to follow plant reproduction over full Manduca spp. larval development without incurring ripe transgenic seed capsules. In 2010 (and during infestation M3 in 2011, Figure 4), we had removed and counted flowers regularly to track reproduction while avoiding ripe seed; this did not cause a difference in reproduction among genotypes (Figure 6), but we elected to avoid flower removal during infestation M4 by removing reproductive meristems prior to the beginning of the assay.

      The hemi-irLOX2 plants chosen in 2011 had produced more flowers than WT – but not more than irPI—prior to the start of infestation M4 (Figures 4 and 8). This did not correspond to more cuts on average for hemi-irLOX2 when removing reproductive meristems: meristems were cut at the bases of inflorescences which contained mostly buds, and the number of these did not differ for the plants chosen, nor did the number of side branches (Figure 8) which bore most reproductive meristems. Therefore, in the absence of additional effects during infestation M4, the reproduction of the matched hemi-irLOX2 plants should have been similar to that of WT and irPI.

      Conclusions and outlook

      By indicating the long-sought indirect defensive function of HIPVs, these data set the stage for the use of HIPVs as part of integrated pest management strategies (IPM), which rely in part on recruiting biological control agents to reduce pesticide use (Horne and Page, 2008). These agents are usually naturally occurring generalist parasitoids and predators, such as Geocoris spp. (Eubanks and Denno, 1999, 2000; Allison and Hare, 2009; Allmann and Baldwin, 2010). HIPVs are produced by genotypes of most, if not all crop plants and IPM would benefit from selective breeding or engineering of HIPV emission (Kos et al., 2009) rather than relying on alternatives such as controlled release dispensers, which have mixed success and require large amounts of synthetic HIPVs (Kaplan, 2012). PIs may be employed to enhance the efficiency of indirect defense, especially combined with toxins like Bt that directly target herbivores and are safe for biological control agents. With growing concerns about field-evolved Bt resistance (Liu et al., 2010), indirect defenses promise an effective 'first line of defense' against agricultural pests, to which not even specialist herbivores are likely to rapidly evolve resistance.

      Materials and methodsPlants, growth conditions and field plantations

      Seed germination, glasshouse growth conditions, and the Agrobacterium tumefaciens (strain LBA 4404)–mediated transformation procedure have been described previously (Krügel et al., 2002). Seeds of the 31st generation of the inbred 'UT' line of Nicotiana attenuata (Torr. ex S. Wats.) were used as the wild-type plant in all experiments. For the field experiment, seedlings were transferred to 50 mm peat pellets (Jiffy) 15 days after germination and gradually hardened to the environmental conditions of high sunlight and low relative humidity over 10 days. Small, adapted, size-matched rosette-stage plants were transplanted into a field plot in a native habitat in Utah and watered thoroughly once at planting and as needed over the first 2 weeks until roots were established; all plants received the same watering regime in each year. WT, irPI, irLOX2 and hemi-irLOX2 plants were arranged in quadruplets (N=40–50) of one plant per genotype, with individuals 0.5 m apart, a distance sufficient to allow predators and herbivores to distinguish volatiles from neighboring plants (Kessler and Baldwin, 2001). Quadruplets were arranged so that no two adjacent plants were of the same genotype (Figure 4). In 2010, the field plot was a first-year plot located at latitude 37.141, longitude 114.027; in 2011, plants were planted at a second, older field site across a river from the first, located at latitude 37.146, longitude 114.020. Field plantations were conducted under APHIS permission numbers 06-242-3r-a3 (2010 and 2011) and 10-349-102r (2011).

      We used previously characterized, homozygous, inverted-repeat (ir) RNAi transformed lines of the second transformed generation (T2) to silence GLV biosynthesis: irLOX2 line number A-04-52-2 (Allmann et al., 2010), and TPI activity: irPI line number A-04-186-1 (Steppuhn and Baldwin, 2007). Vector construction and the pSOL3 plasmid have been described previously (Bubner et al., 2006). A cross was created between irLOX2 and irPI homozygous lines; however, the hemizygous irPI construct did not silence TPI activity or transcripts, and these plants therefor served as vector controls for comparison with irPI and had slightly greater residual GLV production than irLOX2 (see 'Results'). They are thus referred to as hemizygous (hemi-)irLOX2 plants.

      <italic>Manduca</italic> spp. eggs and larvae

      Wild Manduca spp. eggs were collected for field assays when available from natural ovipositions. M. sexta and M. quinquemaculata (hereafter Manduca spp.) were both ovipositing at the time experiments were conducted; the species of larvae was identified at the third instar and recorded (earlier instars of these two species cannot be distinguished morphologically). M. sexta and M. quinquemaculata oral secretions (OS) are highly similar in their composition (Halitschke et al., 2001) and elicit similar volatiles (Halitschke et al., 2001; Kessler and Baldwin, 2001) and defense genes (Schittko et al., 2001) in N. attenuata. Eggs from laboratory-reared M. sexta, kindly provided by Dr. Carol Miles at SUNY Binghampton, were used in the field when wild Manduca spp. eggs were not sufficiently abundant. Eggs were allowed to hatch in well-aerated boxes on fresh N. attenuata leaf tissue over a moistened paper towel. M. sexta larvae used to elicit glasshouse-grown plants, or to collect oral secretions (OS) for plant treatments, were taken from an in-house colony at the Max Planck Institute for Chemical Ecology in Jena, Germany.

      <italic>Manduca</italic> spp. infestation and W+OS treatment of plants

      Because GLVs influence Manduca spp. oviposition (De Moraes et al., 2001; Kessler and Baldwin, 2001; Fraser et al., 2003), and the timing and extent of Manduca spp. oviposition varies from year to year, we created even, synchronous oviposition events by infesting plants with Manduca spp. larvae, either from a lab-reared culture or from wild collections (see Manduca spp. eggs and larvae). Larvae used for plant infestations were placed as neonates on a rosette or lower stem leaf at a standardized position for each assay, and monitored mornings and evenings, during times outside of the main period of Geocoris spp. activity that occurs at midday. Plants in field experiments were either infested with Manduca spp. larvae as described above, or left uninfested (control). There were four infestations over both years of the experiment, denoted M1-M4 in Figure 4.

      For measuring headspace GLVs in the field and for glasshouse assays, plants were treated with wounding and M. sexta OS (W+OS) as a standardized method to mimic Manduca spp. feeding. Pure OS collected from fourth to fifth instar M. sexta larvae from the Jena colony fed on WT plants was diluted 1:5 with distilled water before use; even 1000-fold diluted OS is still sufficient to cause most OS-elicited responses (Schittko et al., 2000). For field-grown plants, a similar, mature, non-senescent leaf was chosen from each plant; for glasshouse-grown plants, the two adjacent older leaves (nodes +1, +2) to the leaf undergoing a source-sink transition (node 0) on rosette-stage plants were used for PI and LOX2 transcript quantification, and the +2 node of a separate set of bolting plants was used for measuring headspace volatiles. The leaf chosen for treatment was wounded by using a fabric pattern wheel run over the adaxial surface to make six rows of holes in the lamina, three rows on either side of the midvein. 20 µL of 1:5 diluted OS were deposited on the adaxial surface and gently rubbed over the holes with a gloved finger. Control plants were left untreated.

      Plant tissue harvests and sample handling

      For field-grown plants and glasshouse-grown M. sexta-fed plants, a similar, mature, non-senescent systemic (undamaged) leaf was chosen from each plant; for glasshouse-grown plants used to measure PI and LOX2 transcripts, the leaves at nodes +1 and +2 (treated leaf positions) were harvested. Leaves were cut at the petiole and wrapped in a double layer of aluminum foil. In the field, harvested leaves were immediately frozen on dry ice insulated with ice packs frozen at −20°C; samples were stored at −20°C until transport to Jena on dry ice, where they were kept at −80°C until analysis. Leaves harvested from glasshouse-grown plants were flash-frozen in liquid nitrogen and kept at −80°C until analysis. All sample processing was carried out over liquid nitrogen until the addition of the extraction solvents. Prior to analysis, entire leaves were ground with a mortar and pestle and transferred to a 2 mL microcentrifuge tube for storage. For specific measurements, aliquots were weighed into microcentrifuge tubes containing two steel balls and finely ground in a GenoGrinder (SPEX Certi Prep) prior to extraction.

      Quantification of TPI activity

      TPI activity was quantified in 100 mg of tissue from systemic leaves on Manduca spp.-infested plants using a radial diffusion assay as previously described (van Dam et al., 2001).

      Quantification of <italic>PI</italic> and <italic>LOX2</italic> transcripts

      Leaf samples were from control plants or plants treated with W+OS. Treated leaf positions were harvested at the peak of transcript accumulation for PI, 12 hr (Wu et al., 2006) and LOX2, 14 hr (Allmann et al., 2010). Total RNA was extracted from leaves using the TRIzol reagent (Invitrogen), and a 0.5 μg aliquot of total RNA of each sample was reverse-transcribed using oligo(dT)18 and RevertAid H Minus reverse transcriptase (Fermentas) following the manufacturer's instructions. Quantitative real-time PCR (qPCR) was performed with a Mx3005P Multiplex qPCR system (Stratagene) and the qPCR Core kit for SYBR Green I (Eurogentec). Transcripts were quantified using external standard curves for each gene. Elongation factor 1A (EF1A) transcript abundance in each sample was used to normalize total cDNA concentration variations. Samples of RNA used to make cDNA were pooled to the same dilution as in cDNA samples and run alongside cDNA in all qPCRs to control for gDNA contamination; no contamination was detected. The sequences of primers used for qPCR (Kallenbach et al., 2010; Fragoso et al., 2011) are provided in Table 4.10.7554/eLife.00007.020

      Primers used for quantitative PCR (SYBR Green)

      DOI: http://dx.doi.org/10.7554/eLife.00007.020

      GeneForward primer sequence (5′-3′)Reverse primer sequence (5′-3′)Citation
      PITCAGGAGATAGTAAATATGGATCTGCATGTTCCACATTGCFragoso et al. (2011)
      LOX2TTGCACTTGGTGTTTGAGATGGTTTAGTAGAAAATGAGCACCACAAKallenbach et al. (2010)

      Quantification of GLV pools in tissue

      To assess qualitatively the GLV pools in leaf tissue from field-grown plants, and to determine appropriate amounts of leaf tissue and internal standard (IS) for GLV extraction, we extracted pooled samples from leaves collected June 6, 2011, from M. sexta-infested plants during infestation M3 (Figure 4). Each sample was pooled from all leaves collected from one genotype. Hexane (300 µL) was added to 100 mg tissue spiked with 3 µg tetralin as an internal standard (IS) and incubated by rotating at RT overnight. Samples were allowed to settle and 100 µL of water- and tissue-free hexane was transferred to a GC vial containing a 250 µL microinsert. Individual analytes were analyzed by a Varian CP-3800 GC-Saturn 4000 ion trap MS connected to a ZB5 column (30 m×0.25 mm i.d., 0.25 μm film thickness; Phenomenex). 1 μL of samples was injected by a CP-8400 autoinjector (Varian) onto the column with a 1:10 split ratio; the injector was returned to a 1:70 split ratio from 2 min after injection through the end of each run. The GC was programmed as follows: injector held at 250°C, initial column temperature at 40°C held for 5 min, then ramped at 5°C/min to 185°C and finally at 30°C/min to 300°C, held for 0.17 min. Helium carrier gas was used and the column flow set to 1 mL/min. Compounds eluted from the GC column were transferred to the MS for analysis. The MS was programmed as follows: transfer line at 250°C, trap temperature 110°C, manifold temperature 50°C, source heater 200°C and scan range from 40 to 399 m/z at 1.33 spectra per second as previously described (Schuman et al., 2009). The identification of compounds was conducted by GC retention time compared to pure standards and mass spectra compared to standards and mass spectra databases, Wiley version 6 (Wiley) and NIST (National Institute of Standards and Technology) spectral libraries.

      For the quantification of GLV pools in leaf tissue from field-grown plants, the hexane extraction protocol was adjusted based on GC-MS results from pooled samples (described above), and a GC-FID with a wax column was used for the quantitative analysis of extracts. Hexane (300 µL) were added to 50 mg tissue (N=10) spiked with 15 µg (Z)-hex-3-enyl acetate, a GLV not found in GC-MS samples, as an IS. The extraction proceeded as described above. Analytes were separated by Varian CP-3800 GC-FID connected to a ZB-Wax column (30 m×0.25 mm i.d., 0.25 μm film thickness; Phenomenex). 1 μL of samples was injected by a CP-8400 autoinjector (Varian) onto the column in a splitless mode; the injector was returned to a 1:70 split ratio 2 min after injection through the end of each run. The GC was programmed as follows: injector held at 230°C, initial column temperature at 40°C held for 7 min, then ramped at 5°C/min to 115°C and finally at 30°C/min to 250°C, held for 0.5 min. Helium carrier gas was used and the column flow set to 1 mL/min. Compounds eluted from the GC column were transferred to a Varian FID set at 250°C for analysis (airflow 300 mL/min, hydrogen 30 mL/min, nitrogen make-up gas 5 mL/min). Individual volatile compound peaks were quantified by peak areas using MS Work Station Method Builder and Batch Report software (Varian) and normalized to the peak area of the IS (Z)-hex-3-enyl acetate in each sample. Peak identification and quantification was done by comparison to standard curves of pure compounds in hexane. Compounds present in quantifiable amounts were (Z)-hex-3-en-1-ol, (E)-hex-2-enal and the IS (Z)-hex-3-enyl acetate.

      Relative quantification of GLVs and (<italic>E</italic>)-α-bergamotene in the plant headspace

      For measurement of GLVs in the headspace of field-grown plants, intact leaves were harvested (N=3) and kept fresh by placing the petioles in microcentrifuge tubes filled with water. Immediately before each measurement, one leaf was treated with W+OS, and a 1 cm2 disc was stamped out and placed in a 4 mL GC vial. After 15 min, the headspace in the vial was measured with a ZNose 4200 portable gas chromatograph with a 1 m DB5 column (Electronic Sensor Technology, Newbury Park, CA, USA) by inserting the ZNose inlet needle through the septum of the GC vial into the headspace. The program was as follows: valve set at 165°C, inlet at 200°C, trap at 250°C; 30 s sampling time, column ramped from 30°C to 190°C at 4°C/s, data collection for 20 s. Genotypes were analyzed in an alternating order within each replicate: first replicate 1 of all genotypes, then replicate 2, then replicate 3. Retention times of GLV aldehydes and alcohols, the most abundant GLV headspace components, were determined using pure standards.

      For the analysis of GLVs in the headspace of glasshouse-grown plants, the +2 leaf was enclosed immediately after W+OS elicitation in a food-quality 50 mL plastic container (Huhtamaki) with an activated charcoal filter attached to one side for incoming air, and connected to self-packed Poropak Q filters containing 20 mg of Poropak (Sigma-Aldrich) packed with silanized glass wool and Teflon tubing in the column bodies (ARS, Inc.) as previously described (Halitschke et al., 2000; Schuman et al., 2009). Ambient air was pulled by vacuum pump for 3 hr through an activated charcoal filter, over the leaf in the trapping container, and through a Poropak Q filter connected by PVC tubing (Rotabilo) to a custom-made valve manifold, as previously described (Schuman et al., 2009); the manifold was adjusted such that flow rates through traps were ca. 300 mL/min. After trapping, sampled leaves were excised at the base of the petiole, scanned, and the leaf area was measured in comparison to a 1 cm2 standard (SigmaScan 5.0; Systat Software Inc.) for normalization of volatile emission to cm2 leaf area. Poropak Q filters were wrapped in aluminum foil and stored at −20°C until elution of volatiles with 250 μL dichloromethane (Sigma-Aldrich).

      Immediately prior to elution, each filter was spiked with 320 ng of tetralin internal standard (IS) in hexane (Sigma-Aldrich). Filters were eluted into a GC vial containing a 250 μL glass insert. Samples were analyzed by a CP-3800 GC Varian Saturn 2000 ion trap MS (Varian) connected to a polar ZB-wax column (30 m×0.25 mm i.d., 0.25 μm film thickness; Phenomenex). 1 μL of samples was injected by a CP-8200 autoinjector (Varian) onto the column in a splitless mode; the injector was returned to a 1:70 split ratio from 2 min after injection through the end of each run. The GC was programmed as follows: injector held at 230°C, initial column temperature at 40°C held for 3 min, then ramped at 5°C/min to 180°C and finally at 10°C/min to 240°C, held for 1 min. Helium carrier gas was used and the column flow set to 1 mL/min. Eluted compounds from the GC column were transferred to the MS for analysis. The MS was programmed as follows: transfer line at 230°C, trap temperature 150°C, manifold temperature 80°C and scan range from 40 to 399 m/z at 1.33 spectra per second as previously described (Schuman et al., 2009). Individual volatile compound peaks were quantified by peak areas of two specific and abundant ion traces per compound using MS Work Station Data Analysis software (Varian) and normalized by the 104+132 ion trace peak area of the IS (tetralin) in each sample. The identification of compounds was conducted by GC retention time compared to pure standards and mass spectra compared to standards and mass spectra databases, Wiley version 6 (Wiley) and NIST (National Institute of Standards and Technology) spectral libraries. In 3 hr headspace samples we detected (Z)-hex-3-en-1-ol, (Z)-hex-3-en-1-ol, (E)-hex-2-en-1-ol (forms from (E)-hex-2-enal on filters over trapping periods longer than 20 min), (Z)-hex-3-enyl acetate, (Z)-hex-3-enyl butanoate, (Z)-hex-3-enyl isobutyrate, and (Z)-hex-3-enyl propanoate.

      The collection of (E)-α-bergamotene from the headspace of glasshouse-grown plants and its extraction from Poropak Q filters was carried out as for GLVs, except that (E)-α-bergamotene was collected 24–32 hr after W+OS treatment of the leaf. Eluted samples were analyzed by an HP 6890 GC-5973 quadropole MS (Hewlett-Packard) connected to a nonpolar DB-5ms column (30 m×0.25 mm i.d., 0.25 μm film thickness; Agilent). 1 μL of samples was injected by a HP 7683 autoinjector (Hewlett-Packard) onto column in a splitless mode; the injector was purged at 50 mL/min 1.5 min after injection and switched to gas saver mode (20 mL/min) from 10 min through the end of each run. The GC was programmed as follows: injector held at 230°C, initial column temperature at 40°C held for 2 min, then ramped at 5°C/min to 165°C and finally at 60°C/min to 300°C, held for 2 min. Helium carrier gas was used and the column flow set to 2 mL/min. Eluted compounds from GC column were transferred to the MS for analysis. The MS was programmed as follows: source at 230°C, quad temperature 150°C, and scan range from 33 to 350 m/z at 4.49 spectra per second. (E)-α-Bergamotene was quantified by peak area using the ion trace 119 m/z in Chemstation software (Agilent) and normalized by the 104 ion trace peak area of the IS (tetralin) in each sample. The identification of (E)-α-Bergamotene and tetralin IS was conducted by GC retention time and mass spectra compared to mass spectra of known standards as previously described (Schuman et al., 2009).

      <italic>Manduca</italic> spp. bioassays

      One or two larvae were placed on plants at a time for each assay, depending on the number available, and were equally distributed among plants as described under ‘Manduca spp. infestation and W+OS treatment of plants'. However, for infestation M3 (Figure 4), we staggered the infestation of different plant genotypes to accommodate differences in plant growth: WT and irPI plants were initially larger and therefore went into the field on average earlier than irLOX2 and hemi-irLOX2 plants, so that all plants were planted at a similar size, which is important for even establishment. We therefore re-infested WT and irPI plants earlier after M1, to allow irLOX2 and hemi-irLOX2 plants to catch up in their growth to WT and irPI before re-infestation. However, we then left M. sexta larvae on irLOX2 and hemi-irLOX2 as long as on WT and irPI, and we used a combination of Geocoris spp. counts and additional predation assays to make sure that differences in Geocoris spp. predation were not due to this staggering of infestation (see 'Results: Geocoris spp. preferentially predate from GLV-perfumed or -emitting plants').

      Manduca spp. behavior, predation, and growth assays were conducted with first- and second-instar larvae, except infestations M1 2010 and M4 in 2011, in which larvae were reared from the first through fifth instars on plants; and egg predation assays, in which M. sexta eggs were used.

      Larvae used in the off-plant mock predation assays were hatched on the appropriate N. attenuata genotype (WT or irPI) and hatching was monitored three times per day (morning, noon, evening) so that the mock predation assay could be timed to 48 hr after larvae hatched. A protocol of the mock predation assays is given in Figure 10, and Videos 1–4 depict on-plant (1 and 2) and off-plant (3 and 4) behavioral assays. Larvae for off-plant mock predation assays were kept in aerated plastic boxes on cut leaves over moist paper towels. Leaves were refreshed twice daily and were kept fresh by placing the petioles in water in 1.5 mL microcentrifuge tubes which were closed around the petiole with Parafilm (Pechiney Plastic Packaging Company). Larval growth was measured as increases in body length (in millimeters) using calipers or a small, flexible, transparent plastic ruler.

      Predation assays

      Predation rates were recorded for larvae placed on plants as described above, or for two eggs per plant fixed with droplets of α-cellulose glue (Kessler and Baldwin, 2001) to the underside of a rosette or lower stem leaf at a standardized position. For egg predation assays, a wild Manduca spp. larva was enclosed on a nearby leaf to ensure continual GLV emission: a clip cage was closed around the larva to make it inaccessible to Geocoris spp. predators. Predation was monitored mornings and evenings. Larvae were considered to be predated when either the larva was missing over multiple days, but clear Manduca spp. feeding damage was present, or when the predated larval carcass was found (Figure 5). Mortality was defined as the total number of missing larvae. Eggs were considered predated when the eggshell was empty but intact except for a small hole which characterizes the typical damage caused by Geocoris spp. feeding; eggs occasionally collapse during Geocoris spp. predation, but collapsed eggs were not counted unless the eggs were mostly or fully empty and with a visible hole (Figure 5).

      GLV supplementation

      During infestation M2, GLVs were added back to irLOX2 and hemi-irLOX2 headspaces by placing a cotton swab adjacent to the M. sexta-infested leaf and adding ca. 20 µL of lanolin paste, measured with a seed spoon, containing a mix of pure GLVs representative of the M. sexta-fed headspace and dissolved in hexane (Table 1) (Allmann and Baldwin, 2010) to the cotton swab. Cotton swabs bearing ca. 20 µL of lanolin paste with hexane as a control were placed next to M. sexta-infested leaves of WT and irPI plants. Lanolin pastes were regularly refreshed by adding 20 µL in the early afternoon and in the morning. Placing GLVs next to, rather than on the leaf ensured that the supplemented headspace would not be altered by plant metabolism, and that we could terminate the supplementation by removing the cotton swabs.

      <italic>Geocoris</italic> spp. counts

      Field plots were monitored daily for Geocoris spp. presence during the experiments in 2010 and 2011; both G. pallens and G. punctipes were present in 2011, but most individuals observed on and around plants were G. pallens. Soon after the first Geocoris spp. sightings in May 2011 (before the first infestation, M2), Geocoris spp. populations in the immediate vicinity of experimental plants were monitored every 2–3 days by counting individuals. Counts were conducted during the main period of Geocoris spp. activity in the early afternoon, by at least two observers in parallel, in order to complete the count around all Manduca spp.-infested and control plants within 20–30 min. Each observer proceeded by looking at a focal plant and its immediate vicinity for 15 s and then quickly inspecting the rosette leaves; all Geocoris spp. adults and nymphs seen on, under, or within 5 cm around the rosette of the plant during this time were counted. Observers moved in synchrony with each other from one end of the field plot to the other, in this way counting predators around plants which had not yet been disturbed.

      Plant growth and reproduction

      Plant size (rosette diameter, stem length and branching) was monitored at the end of infestation M1 in 2010 and from the beginning of infestation M2 in 2011 (Figure 4): rosette diameter was measured as the maximum diameter found by gently laying a ruler over the rosette; stem length was measured from the base of the stem to the tip of the apical inflorescence by placing a ruler beside the stem; and all side branches 5 cm or longer were counted. Reproductive output was monitored by counting the number of closed flowers removed every 2–3 days (before they opened) from the beginning of flowering, and by counting numbers of closed flowers and buds 2 mm or larger at the end of infestation M1 in 2010, and during all infestations in 2011. All growth and reproduction data were analyzed for differences in control versus M. sexta-infested plants within each genotype (statistics Table 3). Because size-matched plants had been planted over one week in 2011, growth and reproduction data from plants in 2011 were organized by the number of days since planting for comparison between genotypes (Figure 6).

      Removal of flowers during infestations M1 and M3, and of reproductive meristems prior to infestation M4

      Flowers were removed and counted periodically over the first 10 days of infestation M1 and during infestation M3 (Figures 4 and 6, statistics Table 3), in order to track plant reproduction while avoiding ripe seed capsules: the distribution of ripe seed is not permitted for genetically modified plants. For infestation M4 in 2011 (Figure 4), instead of regularly removing flowers, we removed all reproductive meristems by cutting inflorescences, which contained mostly buds, at their base, so that we would be able to follow a new set of reproductive meristems through to seed set without incurring ripe seed. Because plants were matched prior to M4 and had the same number of buds and of side branches (which usually terminate in inflorescences) (Figure 8, see 'Discussion'), all plants were similarly affected by the removal of reproductive meristems.

      Herbivore damage and plant health

      Photographs were taken of entire plants and M. sexta-damaged leaves during infestations M2 and M3 in 2011. Damage caused by M. sexta larvae was rated from photographs by an independent observer with no knowledge of plant identity. Total percent canopy damage due to M. sexta was rated as 1, 2, 3, or 4 using the damage index in Figure 7.

      We monitored herbivore attack to determine whether GLV-silenced plants suffered different amounts of herbivore damage, which could influence fitness measurements. The naturally occurring herbivore community on plants in 2010 and 2011 comprised mirids (Tupiocoris notatus) and noctuid larvae; in 2011 grasshoppers (Trimerotropis spp.) and flea beetles (Epitrix spp.) were also present. Total canopy damage due to herbivores occurring naturally on the field plot was quantified prior to the infestations in 2010 and 2011 and again during infestation M3 in 2011. Damage was calculated by identifying damage from specific herbivores according to their characteristic feeding patterns, counting the number of leaves per plant (small leaves were counted as 1/5 to 1/2 of a leaf based on leaf area and large leaves were counted as 1 leaf), estimating the total percentage of leaf area damage due to each herbivore, and dividing the total leaf area damage from each herbivore by the total number of leaves. Leaf area damage was estimated in categories of 1%, 5%, 10%, 15%, and so on, in steps of 5%. All such damage estimates were made by MCS or KB, who first practiced quantifying damage together until they consistently arrived at the same numbers.

      As part of matching plants prior to infestation M4 in 2011, plant health was rated on a scale of 1 (dead) to 5 (healthy) using the index in Figure 7.

      Statistical analyses

      Fisher's exact tests were conducted using a macro (J H Macdonald, http://udel.edu/~mcdonald/statfishers.html) for Excel (Microsoft). All other statistical analyses were conducted with SPSS 17.0 (IBM). Count data were analyzed either by Fisher's exact tests (independent values) or by Friedman tests (repeated measures). Levene's test for homogeneity of variance was performed prior to all t-tests and ANOVAs and when necessary, data were log2 transformed (volatile and transcript data), square root transformed (count data) or arcsin transformed (herbivore damage data) to meet requirements for homogeneity of variance. Parametric data were compared using ANOVAs, MANOVAs, or repeated-measure ANOVAs followed by Scheffe post hoc tests. If variance was not homogeneous following transformation, data were compared using Kruskal-Wallis tests (for multiple comparisons) or Mann-Whitney U-tests (for two-way comparisons) and Bonferroni p-value corrections were used to correct for nonparametric multiple comparisons. For Kruskal-Wallis tests and Mann-Whitney U-tests, a Monte Carlo algorithm was used with 10,000 permutations and a 95% confidence level.

      Acknowledgements

      We thank S Allmann for conducting egg predation assays in 2010; C Diezel, M Erb, M Kallenbach, D Kessler, D Marciniak, M Stanton, and A Steppke for help with field work; S Weigl for rating M. sexta damage levels; J Gershenzon for the use of the HP GC-MS; M Erb, J Gershenzon, D Heckel, M Kallenbach, A Kessler, A Steppke, and A Weinhold for comments on the manuscript; Brigham Young University for the use of their Lytle Preserve field station; and APHIS for constructive regulatory oversight.

      Additional informationCompeting interests

      ITB: Senior Editor, eLife.

      The other authors have declared that no competing interests exist.

      Author contributions

      MCS: Conception and design, acquisition of data, analysis and interpretation of data, and drafting or revising the article

      KB: Conception and design, acquisition of data, analysis and interpretation of data, and drafting or revising the article

      ITB: Conception and design, acquisition of data, analysis and interpretation of data, and drafting or revising the article

      Additional filesMajor datasets

      The following datasets were generated

      SchumanMC, BarthelK, BaldwinIT, 2012, Herbivory-induced volatiles function as defenses increasing fitness of the native plant Nicotiana attenuata in nature, http://dx.doi.org/10.5061/dryad.gs45f, Available at Dryad Digital Repository under a CC0 Public Domain Dedication

      ReferencesAllisonJDHareJD2009Learned and naïve natural enemy responses and the interpretation of volatile organic compounds as cues or signalsNew Phytol18476878210.1111/j.1469-8137.2009.03046.xAllmannSBaldwinIT2010Insects betray themselves in nature to predators by rapid isomerization of green leaf volatilesScience3291075107810.1126/science.1191634AllmannSHalitschkeRSchuurinkRCBaldwinIT2010Oxylipin channelling in Nicotiana attenuata: Lipoxygenase 2 supplies substrates for green leaf volatile productionPlant Cell Environ332028204010.1111/j.1365-3040.2010.02203.xBaldwinIT1998Jasmonate-induced responses are costly but benefit plants under attack in native populationsProc Natl Acad Sci U S A9581138118BenreyBDennoRF1997The slow-growth-high mortality hypothesis: A test using the cabbage butterflyEcology7898799910.2307/2265852BubnerBGaseKBergerBLinkDBaldwinIT2006Occurrence of tetraploidy in Nicotiana attenuata plants after Agrobacterium-mediated transformation is genotype specific but independent of polysomaty of explant tissuePlant Cell Rep2566867510.1007/s00299-005-0111-4De MoraesCMMescherMCTumlinsonJH2001Caterpillar-induced nocturnal plant volatiles repel conspecific femalesNature41057758010.1038/35069058DegenhardtJHiltpoldIKöllnerTGFreyMGierlAGershenzonJ2009Restoring a maize root signal that attracts insect-killing nematodes to control a major pestProc Natl Acad Sci U S A106132131321810.1073/pnas.0906365106DickeMBaldwinIT2010The evolutionary context for herbivore-induced plant volatiles: Beyond the ‘cry for help’Trends Plant Sci1516717510.1016/j.tplants.2009.12.002EubanksMDDennoRF1999The ecological consequences of variation in plants and prey for an omnivorous insectEcology801253126610.2307/177072EubanksMDDennoRF2000Host plants mediate omnivore-herbivore interactions and influence prey suppressionEcology8193694710.2307/177168FragosoVGoddardHBaldwinITKimS-G2011A simple and efficient micrografting method for stably transformed Nicotiana attenuata plants to examine shoot-root signalingPlant Methods73410.1186/1746-4811-7-34FraserAMMechaberWLHildebrandJG2003Electroantennographic and behavioral responses of the sphinx moth Manduca sexta to host plant headspace volatilesJ Chem Ecol291813183310.1023/A:1024898127549García-PérezRDHoudtHVDepickerA2004Spreading of post-transcriptional gene silencing along the target gene promotes systemic silencingPlant J3859460210.1111/j.1365-313X.2004.02067.xHalitschkeRBaldwinIT2003Antisense LOX expression increases herbivore performance by decreasing defense responses and inhibiting growth-related transcriptional reorganization in Nicotiana attenuataPlant J3679480710.1046/j.1365-313X.2003.01921.xHalitschkeRKesslerA.KahlJLorenzABaldwinIT2000Ecophysiological comparison of direct and indirect defenses in Nicotiana attenuataOecologia12440841710.1007/s004420000389HalitschkeRSchittkoUPohnertGBolandWBaldwinIT2001Molecular interactions between the specialist herbivore Manduca sexta (Lepidoptera, Sphingidae) and its natural host Nicotiana attenuata. III. Fatty acid-amino acid conjugates in herbivore oral secretions are necessary and sufficient for herbivore-specific plant responsesPlant Physiol12571171710.1104/pp.125.2.711HalitschkeRZieglerJKeinänenMBaldwinIT2004Silencing of hydroperoxide lyase and allene oxide synthase reveals substrate and defense signaling crosstalk in Nicotiana attenuataPlant J40354610.1111/j.1365-313X.2004.02185.xHalitschkeRStenbergJAKesslerDKesslerABaldwinIT2008Shared signals—‘alarm calls’ from plants increase apparency to herbivores and their enemies in natureEcol Lett11243410.1111/j.1461-0248.2007.01123.xHartlMGiriAPKaurHBaldwinIT2011The multiple functions of plant serine protease inhibitors: Defense against herbivores and beyondPlant Signal Behav61009101110.4161/psb.6.7.15504HeilM2008Indirect defence via tritrophic interactionsNew Phytol178416110.1111/j.1469-8137.2007.02330.xHoballahMEFTurlingsTCJ2001Experimental evidence that plants under caterpillar attack may benefit from attracting parasitoidsEvol Ecol Res3553565HorneP.PageJ2008Integrated pest management for crops and pasturesLandlinks PressVictoriaKallenbachMAlagnaFBaldwinITBonaventureG2010Nicotiana attenuata SIPK, WIPK, NPR1, and fatty acid-amino acid conjugates participate in the induction of jasmonic acid biosynthesis by affecting early enzymatic steps in the pathwayPlant Physiol1529610610.1104/pp.109.149013KaplanI2012Attracting carnivorous arthropods with plant volatiles: The future of biocontrol or playing with fire?Biol Control60778910.1016/j.biocontrol.2011.10.017KaplanIThalerJS2011Do plant defenses enhance or diminish prey suppression by omnivorous Heteroptera?Biol Control59536010.1016/j.biocontrol.2010.12.005KappersIFAharoniAvan HerpenTWJMLuckerhoffLLPDickeMBouwmeesterHJ2005Genetic engineering of terpenoid metabolism attracts bodyguards to ArabidopsisScience3092070207210.1126/science.1116232KarbanRBaldwinIT1997Induced responses to herbivoryUniversity of Chicago PressChicagoKesslerABaldwinIT2001Defensive function of herbivore-induced plant volatile emissions in natureScience2912141214410.1126/science.291.5511.2141KesslerABaldwinIT2004Herbivore-induced plant vaccination. Part I. The orchestration of plant defenses in nature and their fitness consequences in the wild tobacco Nicotiana attenuataPlant J3863964910.1111/j.1365-313X.2004.02076.xKesslerDBaldwinIT2006Making sense of nectar scents: The effects of nectar secondary metabolites on floral visitors of Nicotiana attenuataPlant J4984085410.1111/j.1365-313X.2006.02995.xKesslerAHeilM2011The multiple faces of indirect defences and their agents of natural selectionFunct Ecol2534835710.1111/j.1365-2435.2010.01818.xKesslerAHalitschkeRBaldwinIT2004Silencing the jasmonate cascade: Induced plant defenses and insect populationsScience30566566810.1126/science.291.5511.2141KesslerAHalitschkeRDiezelCBaldwinIT2006Priming of plant defense responses in nature by airborne signaling between Artemisia tridentata and Nicotiana attenuataOecologia14828029210.1007/s00442-006-0365-8KosMvan LoonJJADickeMVetLEM2009Transgenic plants as vital components of integrated pest managementTrends Biotechnol2762162710.1016/j.tibtech.2009.08.002KrügelTLimMGaseKHalitschkeRBaldwinIT2002Agrobacterium-mediated transformation of Nicotiana attenuata, a model ecological expression systemChemoecology1217718310.1007/PL00012666LiuFXuZZhuYCHuangFWangYLiH2010Evidence of field-evolved resistance to Cry1Ac-expressing Bt cotton in Helicoverpa armigera (Lepidoptera: Noctuidae) in northern ChinaPest Manag Sci6615516110.1002/ps.1849MeldauSWuJBaldwinIT2009Silencing two herbivory-activated MAP kinases, SIPK and WIPK, does not increase Nicotiana attenuata's susceptibility to herbivores in the glasshouse and in natureNew Phytol18116117310.1111/j.1469-8137.2008.02645.xPascholdAHalitschkeRBaldwinIT2006Using ‘mute’ plants to translate volatile signalsPlant J4527529110.1111/j.1365-313X.2005.02623.xPricePWBoutonCEGrossPMcPheronBAThompsonJNWeisAE1980Interactions among three trophic levels: Influence of plants on interactions between insect herbivores and natural enemiesAnn Rev Ecol Syst11416510.1146/annurev.es.11.110180.000353RasmannSKöllnerTGDegenhardtJHiltpoldIToepferSKuhlmannU2005Recruitment of entomopathogenic nematodes by insect-damaged maize rootsNature43473273710.1038/nature03451SchittkoUPrestonCABaldwinIT2000Eating the evidence? Manduca sexta larvae can not disrupt specific jasmonate induction in Nicotiana attenuata by rapid consumptionPlanta21034334610.1007/PL00008143SchittkoUHermsmeierDBaldwinIT2001Molecular interactions between the specialist herbivore Manduca sexta (Lepidoptera, Sphingidae) and its natural host Nicotiana attenuata. II. Accumulation of plant mRNAs in response to insect-derived cuesPlant Physiol12570171010.1104/pp.125.2.701SchneeCKöllnerTGHeldMTurlingsTCJGershenzonJDegenhardtJ2006The products of a single maize sesquiterpene synthase form a volatile defense signal that attracts natural enemies of maize herbivoresProc Natl Acad Sci U S A1031129113410.1073/pnas.0508027103SchumanMHeinzelNGaquerelESvatosABaldwinIT2009Polymorphism in jasmonate signaling partially accounts for the variety of volatiles produced by Nicotiana attenuata plants in a native populationNew Phytol1831134114810.1111/j.1469-8137.2009.02894.xSchumanMBarthelKBaldwinIT2012Data from: Herbivory-induced volatiles function as defenses increasing fitness of the native plant Nicotiana attenuata in nature. Dryad Digital Repository.http://dx.doi.org/10.5061/dryad.gs45fSchwachtjeJKutschbachSBaldwinIT2008Reverse genetics in ecological researchPLoS One3e154310.1371/journal.pone.0001543SimeKRBaldwinIT2003Opportunistic out-crossing in Nicotiana attenuata (Solanaceae), a predominantly self-fertilizing native tobaccoBMC Ecol3610.1186/1472-6785-3-6SkibbeMQuNGalisIBaldwinIT2008Induced plant defenses in the natural environment: Nicotiana attenuata WRKY3 and WRKY6 coordinate responses to herbivoryPlant Cell201984200010.1105/tpc.108.058594SteppuhnABaldwinIT2007Resistance management in a native plant: Nicotine prevents herbivores from compensating for plant protease inhibitorsEcol Lett1049951110.1111/j.1461-0248.2007.01045.xStorkWFJWeinholdABaldwinIT2011Trichomes as dangerous lollipops: Do lizards also use caterpillar body and frass odor to optimize their foraging?Plant Signal Behav61893189610.4161/psb.6.12.18028TravellaSKlimmTE.KellerB2006RNA interference-based gene silencing as an efficient tool for functional genomics in hexaploid bread wheatPlant Physiol14262010.1104/pp.106.084517TurlingsTCJWäckersFL2004Recruitment of predators and parasitoids by herbivore-injured plantsAdvances in insect chemical ecologyCardéRTMillarJG2175Cambridge University PressCambridgevan DamNMHornMMaresMBaldwinIT2001Ontogeny constrains systemic protease inhibitor response in Nicotiana attenuataJ Chem Ecol2754756810.1023/A:1010341022761van LoonJJAde BoerJGDickeM2000Parasitoid-plant mutualism: Parasitoid attack of herbivore increases plant reproductionEntomologia Experimentalis et Applicata9721922710.1046/j.1570-7458.2000.00733.xWeinholdABaldwinIT2011Trichome-derived O-acyl sugars are a first meal for caterpillars that tags them for predationProc Natl Acad Sci U S A1087855785910.1073/pnas.1101306108WilliamsIS1999Slow-growth, high-mortality—a general hypothesis, or is it?Ecol Entomol2449049510.1046/j.1365-2311.1999.00217.xWinkMTheileV2002Alkaloid tolerance in Manduca sexta and phylogenetically related sphingids (Lepidoptera: Sphingidae)Chemoecology46294610.1007/s00049-002-8324-2WintererJ.BergelsonJ2001Diamondback moth compensatory consumption of protease inhibitor-transformed plantsMol Ecol101069107410.1046/j.1365-294X.2001.01239.xWuJHettenhausenCBaldwinIT2006Evolution of proteinase inhibitor defenses in North American allopolyploid species of NicotianaPlanta22475076010.1007/s00425-006-0256-6ZavalaJABaldwinIT2004Fitness benefits of trypsin proteinase inhibitor expression in Nicotiana attenuata are greater than their costs when plants are attackedBMC Ecol41110.1186/1472-6785-4-11ZavalaJAGiriAPJongsmaMABaldwinIT2008Digestive duet: Midgut digestive proteinases of Manduca sexta ingesting Nicotiana attenuata with manipulated trypsin proteinase inhibitor expressionPLoS One3293110.1371/journal.pone.0002008
      10.7554/eLife.00007.021Decision letterWeigelDetlefReviewing editorMax Planck Institute for Developmental Biology, Germany

      eLife posts the editorial decision letter and author response on a selection of the published articles (subject to the approval of the authors). An edited version of the letter sent to the authors after peer review is shown, indicating the substantive concerns or comments; minor concerns are not usually shown. Reviewers have the opportunity to discuss the decision before the letter is sent (see review process). Similarly, the author response typically shows only responses to the major concerns raised by the reviewers.

      Your manuscript “Herbivory-induced volatiles function as defenses increasing plant fitness in nature” has been reviewed. The following individual(s) responsible for the peer review of your submission want(s) their identity to be known: Detlef Weigel (reviewing editor); Joerg Bohlmann (reviewer).

      We are happy to tell you that a revised manuscript shall be acceptable for eLife. Here are the comments:

      The hypothesis outlined in the title of this paper, that indirect defences in the form of herbivory-induced volatiles increase plant fitness, is being continuously discussed in the literature, without there being much definitive evidence for this phenomenon occurring in nature. It is a difficult hypothesis to test, but the authors of this work make a big step toward providing an answer.

      In field studies over two seasons (with both wild and lab-reared predators) complemented with lab experiments, the authors examined how emission of volatile organic compounds (VOCs) and a protease inhibitor (TPI) that reduces digestibility of plant tissue affect herbivore growth and plant fitness, as measured by flower buds and seed set in tobacco. The experimental approach was to reduce VOCs by silencing the LOX2 gene, and TPI activity by silencing the PI gene.

      The authors clearly show that plants that emit less VOCs attract fewer Geocoris predators to Manduca herbivores (Fig. 2), and that Manduca mortality is reduced in the presence of Geocoris (Fig. 3A). The result is that fewer flowers and flower buds are produced, but only in the presence of Geocoris (Fig. 3B).

      The authors are to be commended for reporting a comprehensive set of measurements, including ones that are not easily explained or fit the hypotheses examined. This makes unfortunately in several places for difficult reading. In addition, the paper is extremely densely written and difficult to follow for those unfamiliar with the research program of the authors. To make the content of the work more accessible, the paper should be presented with separate sections for introduction, results, and discussion, and subsections for the results. In addition, the supplementary figures as well as the supplementary narrative should be integrated into the main text, and the data should be better and more consistently presented in the figures. For example, the colour code for different genotypes in Fig. S1-3 and 6A,B should also be applied in all other figures.

      Some essential information is only mentioned in passing, e.g., that homozygous irLOX2 lines “… did not suffer reduced growth or reproduction from Manduca sexta feeding … and that they were too small …”. This must be explained, and better justification must be provided for focussing on the hemizygous lines, especially because it is not entirely clear how the effects on VOCs compare between hemi- and homozygous plants.

      Other important points: (i) The statement in the Introduction (beginning “Although GLVs are released upon mechanical damage…”) must be at least changed to: “… the oral secretions of Manduca convert 3-(Z)-GLVs to the 2-(E)-structures, …” (This is because this is a rearrangement, not an isomerisation). (ii) The authors should consider whether the experiments in Fig. 4 regarding the effects of TPI on M. sexta behaviour, though interesting, distract from the rest of the work. Perhaps they could be omitted from this manuscript?

      A final remark: it is a pity that, because of global attitudes to genetically modified plants, the authors could not evaluate ripe seeds.

      10.7554/eLife.00007.022Author response

      Reviewer comments are in italics.

      The authors are to be commended for reporting a comprehensive set of measurements, including ones that are not easily explained or fit the hypotheses examined. This makes unfortunately in several places for difficult reading. In addition, the paper is extremely densely written and difficult to follow for those unfamiliar with the research program of the authors. To make the content of the work more accessible, the paper should be presented with separate sections for introduction, results, and discussion, and subsections for the results. In addition, the supplementary figures as well as the supplementary narrative should be integrated into the main text, and the data should be better and more consistently presented in the figures. For example, the colour code for different genotypes in Fig. S1-3 and 6A,B should also be applied in all other figures.

      We have now organized the manuscript into an introduction, Materials and Methods, results, and discussion, with subsections in the Methods, Results, and Discussion sections following the order of the figures and tables. In particular, we have expanded the explanation of the data behind new Figures 8 and 9 (infestations M1 and M4).

      We have also implemented consistent color codes for the genotypes, and consistent pattern codes for control vs Manduca spp.-infested or W+OS-treated plants, and a more consistent format for the figures. We have also merged some figures which were formerly separate but described the same results or sets of assays.

      A note: in the interest of clarity, we now include reports of statistical analyses in the text and not only in figure captions or tables. Perhaps it could be considered to convert these in-text statistical reports to mouse-over hypertext in the online version of the paper, since the long parantheticals interrupt the flow of the text.

      Some essential information is only mentioned in passing, e.g., that homozygous irLOX2 lines “… did not suffer reduced growth or reproduction from Manduca sexta feeding … and that they were too small …”. This must be explained, and better justification must be provided for focussing on the hemizygous lines, especially because it is not entirely clear how the effects on VOCs compare between hemi- and homozygous plants (see minor comments below).

      We have tried to clarify our description of the GLV pools and emissions from the irLOX2 and hemi-irLOX2 plants. It is clearly stated in the Materials and Methods and in the Results that the hemi-irLOX2 plants contain an inactive irPI construct, and the possible explanations for this construct's inactivity are discussed in a new section of the discussion, “WT levels of TPIs in hemi-irLOX2 plants are likely due to gene dosage effects”.

      Other important points: (i) The statement in the Introduction (beginning “Although GLVs are released upon mechanical damage…”) must be at least changed to: “… the oral secretions of Manduca convert 3-(Z)-GLVs to the 2-(E)-structures, …” (This is because this is a rearrangement, not an isomerisation).

      We have changed this sentence to “Although GLVs are released upon mechanical damage, the oral secretions (OS) of M. sexta convert 3-(Z)-GLVs to the 2-(E)-structures, resulting in greater Geocoris spp. predation than the damage-induced (Z):(E) ratio”.

      (ii) The authors should consider whether the experiments in Fig. 4 regarding the effects of TPI on M. sexta behaviour, though interesting, distract from the rest of the work. Perhaps they could be omitted from this manuscript?

      We recognize that this is a long, complex, and data-heavy manuscript. However, we feel that the behavior data is essential to the story, because it is the only effect we found of TPIs, and it is a novel effect which is highly relevant for the efficiency of indirect defense. Both because of the experimental designs presented in the paper, and because of the implications of these results, we feel they belong as part of this story. Also, if these data were not included, we would have to re-analyze all experiments without the irPI line, which we feel is artificial. The removal of these data would only save one figure and 3.5 paragraphs of text.

      A final remark: it is a pity that, because of global attitudes to genetically modified plants, the authors could not evaluate ripe seeds.

      We appreciate the reviewers' sympathy on this point!

      \ No newline at end of file diff --git a/examples/data/elife-15278.xml b/examples/data/elife-15278.xml new file mode 100644 index 000000000..9582f0d94 --- /dev/null +++ b/examples/data/elife-15278.xml @@ -0,0 +1 @@ +
      elifeeLifeeLifeeLife2050-084XeLife Sciences Publications, Ltd1527810.7554/eLife.15278NeuroscienceResearch ArticleObject vision to hand action in macaque parietal, premotor, and motor corticesSchaffelhoferStefanhttp://orcid.org/0000-0002-1006-971X12ScherbergerHansjörghttp://orcid.org/0000-0001-6593-280013*Neurobiology Laboratory, German Primate Center GmbH, Göttingen, GermanyLaboratory of Neural Systems, The Rockefeller University, New York, United StatesDepartment of Biology, University of Göttingen, Göttingen, GermanyKastnerSabineReviewing editorPrinceton University, United Stateshscherb@gwdg.de

      Competing Interest

      2607201620165e152781602201613062016© 2016, Schaffelhofer et al2016Schaffelhofer et alThis article is distributed under the terms of the Creative Commons Attribution License, which permits unrestricted use and redistribution provided that the original author and source are credited.10.7554/eLife.15278.001

      Grasping requires translating object geometries into appropriate hand shapes. How the brain computes these transformations is currently unclear. We investigated three key areas of the macaque cortical grasping circuit with microelectrode arrays and found cooperative but anatomically separated visual and motor processes. The parietal area AIP operated primarily in a visual mode. Its neuronal population revealed a specialization for shape processing, even for abstract geometries, and processed object features ultimately important for grasping. Premotor area F5 acted as a hub that shared the visual coding of AIP only temporarily and switched to highly dominant motor signals towards movement planning and execution. We visualize these non-discrete premotor signals that drive the primary motor cortex M1 to reflect the movement of the grasping hand. Our results reveal visual and motor features encoded in the grasping circuit and their communication to achieve transformation for grasping.

      DOI: http://dx.doi.org/10.7554/eLife.15278.001

      10.7554/eLife.15278.002eLife digest

      In order to grasp and manipulate objects, our brains have to transform information about an object (such as its size, shape and position) into commands about movement that are sent to our hands. Previous work suggests that in primates (including humans and monkeys), this transformation is coordinated in three key brain areas: the parietal cortex, the premotor cortex and the motor cortex. But exactly how these transformations are computed is still not clear.

      Schaffelhofer and Scherberger attempted to find out how this transformation happens by recording the electrical activity from different brain areas as monkeys reached out to grasp different objects. The specific brain areas studied were the anterior intraparietal (AIP) area of the parietal cortex, a part of the premotor cortex known as F5, and the region of the motor cortex that controls hand movements. The exact movement made by the monkeys’ hands was also recorded.

      Analysing the recorded brain activity revealed that the three brain regions worked together to transform information about an object into commands for the hand, although each region also had its own specific, separate role in this process. Neurons in the AIP area of the parietal cortex mostly dealt with visual information about the object. These neurons specialized in processing information about the shape of an object, including information that was ultimately important for grasping it. In contrast, the premotor area F5 represented visual information about the object only briefly, quickly switching to representing information about the upcoming movement as it was planned and carried out. Finally, the neurons in the primary motor cortex were only active during the actual hand movement, and their activity strongly reflected the action of hand as it grasped the object.

      Overall, the results presented by Schaffelhofer and Scherberger suggest that grasping movements are generated from visual information about the object via AIP and F5 neurons communicating with each other. The strong links between the premotor and motor cortex also suggest that a common network related to movement executes and refines the prepared plan of movement. Further investigations are now needed to reveal how such networks process the information they receive.

      DOI: http://dx.doi.org/10.7554/eLife.15278.002

      Author Keywordsparietal cortexpremotor cortexmotor cortexsensorimotor transformationparallel recordinghand graspingResearch OrganismRhesus macaquehttp://dx.doi.org/10.13039/100005156Alexander von Humboldt-StiftungPostdoctoral FellowshipSchaffelhoferStefanhttp://dx.doi.org/10.13039/501100001659Deutsche ForschungsgemeinschaftSCHE 1575/3-1ScherbergerHansjörghttp://dx.doi.org/10.13039/501100002347Bundesministerium für Bildung und ForschungBCCN-II, 01GQ1005CScherbergerHansjörghttp://dx.doi.org/10.13039/501100000780European CommissionFP7-611687 (NEBIAS)ScherbergerHansjörgThe funders had no role in study design, data collection and interpretation, or the decision to submit the work for publication.elife-xml-version2.5Author impact statementThe cortical grasping circuit separates but shares visual and motor processes to transform object attributes into appropriate hand movements.
      Introduction

      Grasping objects of different shapes and sizes appears trivial in daily life. We can distinguish between thousands of objects (Biederman, 1987) and shape our hands according to their geometry in order to hold and manipulate them (Napier, 1956; Smeets and Brenner, 1999). Although such operations seem to be effortless, their underlying neuronal mechanisms are highly complex and require extensive computational resources (Fagg and Arbib, 1998; Felleman and Van Essen, 1991). The cortical grasping network needs to translate high-dimensional visual information of an object into multidimensional motor signals that control the complex biomechanics of the hand.

      In the primate brain, these processes are linked to the anterior intraparietal (AIP), the ventral premotor (F5), and the primary motor cortex (M1) (Brochier and Umilta, 2007; Castiello, 2005; Davare et al., 2011; Nelissen and Vanduffel, 2011). Within this network, AIP provides access to the dorsal visual stream that processes vision for action (Culham et al., 2003; Goodale et al., 1994). In fact, neurons in AIP were shown to strongly respond to the presentation of graspable objects or 3D contours (Murata et al., 2000; Taira et al., 1990; Theys et al., 2012b), but could also encode specific grip types (Baumann et al., 2009). This grasp-relevant information processed in AIP is exchanged with F5 via dense reciprocal connections (Borra et al., 2008; Gerbella et al., 2011; Luppino et al., 1999). Accordingly, deactivation of AIP or F5 causes severe deficits in pre-shaping the hand while approaching an object (Fogassi et al., 2001; Gallese et al., 1994). In contrast to AIP, concurrent electrophysiological studies suggest that F5 is primarily encoding objects in motor terms and is storing context-specific grip type information (Fluet et al., 2010; Raos et al., 2006). Connections of the dorsal subdivision of F5 (F5p) to the spinal cord and to M1 provide further evidence for the important role of F5 for grasp movement preparation (Borra et al., 2010; Dum and Strick, 2005).

      These electrophysiological and anatomical observations lead to our current understanding of the fronto-parietal network as the main circuitry for translating object attributes into motor commands (Jeannerod et al., 1995; Rizzolatti and Luppino, 2001). In detail, it has been suggested that visual features extracted in AIP activate motor prototypes in F5, which store hand configurations according to an object’s geometry (Rizzolatti and Luppino, 2001). However, the detailed neural mechanisms of these processes remained unclear.

      To create a deeper understanding of how visual information is transformed into motor commands, a precise identification and differentiation of visual and motor processes within the grasping network is required. Previous important grasping studies classified visual-dominant, visual-motor or motor-dominant neurons primarily on the phase of their activation [for AIP see Murata et al. (2000) and Sakata et al. (1995), for F5 see Raos et al. (2006); Theys et al. (2012a)], but they could not discriminate between neural coding of visual features of objects or motor features of the hand.

      A differentiation between visual and motor coding is challenging for multiple reasons. First, the fronto-parietal network is multimodal and can reflect sensory and motor signals simultaneously. Second, visual and motor descriptions of objects and the hand are multidimensional due to the complexity of object geometry and hand physiology. Investigations at the neural level therefore necessitate multidimensional observations from many neurons. Third, the visual and motor spaces are highly linked to each other since the form of an object often defines the shape of the grasping hand. Disassociating both neuronal representations therefore requires highly variable visual stimuli and motor responses.

      In this study, we took a multidimensional approach to identify and separate visual and motor processes in the grasping network of AIP, F5, and M1. We recorded large populations of neurons simultaneously from the entire network and compared their modulation patters to the visual attributes of highly diverse objects and the kinematic features recorded from the grasping hand. Our data revealed distinct roles of the grasping network in translating visual object attributes (AIP) into planning (F5) and execution signals (M1) and allowed visualizing the propagation of these features for grasping.

      Results

      Two macaque monkeys grasped a large set of 49 objects causing highly variable visual stimuli and motor responses (Figure 1a–b, Video 1). During the experiments we recorded hand and arm kinematics from an instrumented glove (Schaffelhofer and Scherberger, 2012) (see Figure 1c, Video 2) in conjunction with neuronal activity from 6 cortical microelectrode arrays (6 x 32 channels) (Figure 1e–g).10.7554/eLife.15278.003Behavioural design and implantation details.

      (a–b) Two monkeys were trained to grasp a total of 48 objects presented on a PC-controlled turntable. In addition, monkeys were instructed to perform either precision or power grips on a handle. Each of the 50 grasping conditions was denoted with a double-digit number (ID1, ID2), a colour code, and a symbol to allow easy identification throughout this manuscript. (c) An instrumented glove equipped with electro-magnetic sensors allowed monitoring and recording the monkeys’ hand and arm kinematics in 27 DOF. (d) All grasping actions were performed as a delayed grasp-and-hold task consisting of eye-fixation, cue, planning, grasping and hold epochs. (e–g) Neural activity was recorded simultaneously from six floating microelectrode arrays implanted in the cortical areas AIP, F5, and M1. (f) Electrode placement in monkey Z (right hemisphere). Each array consisted of 2 ground and 2 reference electrodes (black), as well as 32 recording channels (white) aligned in a 4x9 matrix. Electrode length for each row increased towards the sulcus from 1.5–7.1 mm. (g) Same for monkey M (left hemisphere). Two arrays were implanted in each area. AIP: toward the lateral end of the intraparietal sulcus (IPS); F5: on the posterior bank of the arcuate sulcus (AS); hand area of M1: on the anterior bank of the central sulcus (CS).

      DOI: http://dx.doi.org/10.7554/eLife.15278.003

      10.7554/eLife.15278.004Experimental task.

      A monkey grasped and held highly variable objects presented on a PC-controlled turntable. Note: For presentation purposes, the video was captured in the light.

      DOI: http://dx.doi.org/10.7554/eLife.15278.004

      10.7554/eLife.15278.005Hand and arm tracking.

      18 joints of the primate hand were tracked with electromagnetic sensors and used to drive a 3-D primate-specific musculoskeletal model to extract 27 joint angles. Thumb, index, wrist, elbow, and shoulder angles are shown while the monkey is grasping a ring, a ball and a cylinder. The video runs at half speed.

      DOI: http://dx.doi.org/10.7554/eLife.15278.005

      Training the monkeys to perform grasping movements in a delayed grasp-to-hold paradigm allowed us to investigate neural activity at several key stages of the task. As shown in Figure 1d, visual responses (i.e., object presentation in cue epoch), planning activity (i.e., motor preparation in planning epoch), and motor execution signals (i.e., grasp and hold epoch) were temporarily distinct and could therefore be explored separately.

      We analysed data from 20 recording sessions of two macaque monkeys (10 sessions per animal). On average, spiking activity of 202 ± 7 and 355 ± 20 (mean ± s.d.) single and multiunits were collected in each session in monkey Z and M, respectively. Of these units, 29.2% and 25.2% were recorded from AIP, 37.3% and 32.3% from F5, and 33.5% and 42.5% from M1 (monkey Z and M, respectively).

      Vision for hand action

      Presenting 3D objects to the monkeys lead to vigorous discharge (Baumann et al., 2009; Murata et al., 2000) of AIP-neurons (Figure 2a–b). The modulated population was not only larger (sliding ANOVA, Figure 3), but also significantly faster appearing after stimulus onset than in F5 (49.7 ms and 54.9 ms, monkey M and Z respectively). Impressively, individual AIP cells were capable of differentiating object shapes at high precision (e.g., Figure 2a). To quantify this attribute, we computed a modulation depth analysis that determined the relative difference in firing rate between all pairs of conditions (objects) during the cue epoch (see Materials and methods). The example cell of Figure 2b revealed a chequered structure caused by the shape-wise order of object conditions 00–76 (for object id, see Figure 1b) and a maximum modulation depth (MD) of 62 Hz. Statistical analysis between all conditions (ANOVA and post-hoc Tukey-Kramer criterion, p<0.01; see Materials and methods) revealed a high encoding capacity of the example neuron that could significantly separate 71% of the 946 condition pairs (44 conditions). Interestingly, the neuron decreased its MD in darkness but maintained its encoding of shape (as also indicated in Figure 2a).10.7554/eLife.15278.006Visual object processing in area AIP.

      (a) Example neuron of AIP responding to the presentation of graspable objects (each curve represents one task condition). (b) Modulation depth plot illustrating the absolute firing rate difference in the cue epoch between all condition pairs (conditions 00 – 76 placed on axis in ascending order). Warm colours: high modulation depth, cool colours: low modulation depth. (c) Shape-wise clustering of objects in the AIP population during the cue epoch, as demonstrated by CDA. Arrows indicate a shift in position when big horizontal cylinders (red triangles) were grasped from below instead from above (black triangles). (d) Same as c, but during the grasp epoch. (e–f) Dendrograms illustrating the neural distance between object conditions in the simultaneously recorded AIP population in the cue and grasp epoch (N = 62). Symbols and colour code in a, c-f as in Figure 1b. Percentages in c and d describe how much variance of the data is explained by the shown components (1st, 2nd and 3rd). Note: Video 3 visualizes the N-space of AIP of an additional recording in the same animal (Z). See Figure 2—figure supplement 1–2 for the averaged population results of animal Z and animal M, respectively.

      DOI: http://dx.doi.org/10.7554/eLife.15278.006

      10.7554/eLife.15278.007Visual coding for hand action in AIP in animal Z across all sessions.

      Neural distance between each pair of group means was measured for each recording session, averaged across sessions, and visualized as dendrograms for the (a) cue and (b) hold epoch. Symbols and colours as in Figure 1b.

      DOI: http://dx.doi.org/10.7554/eLife.15278.007

      10.7554/eLife.15278.008Visual coding for hand action in AIP in animal M across all sessions.

      (a) Firing rate plot of AIP example unit. (b–c) N-space of AIP during cue and hold epoch of one recording session (simultaneously recorded, N = 90, first three components shown). (d–e) Neural distances between each pair of group means were measured for each recording session, then averaged across all sessions and visualized as dendrograms for the cue and hold epoch.

      DOI: http://dx.doi.org/10.7554/eLife.15278.008

      10.7554/eLife.15278.009Population coding in AIP.

      The first three canonical variables of the AIP population are shown in 3D and are animated for presentation purposes. Each symbol represents one trial. Symbols and colours as in Figure 1b.

      DOI: http://dx.doi.org/10.7554/eLife.15278.009

      10.7554/eLife.15278.010Visual processing of object shapes.

      (a) A set of six 'mixed' objects elicited different visual stimuli and different motor responses. (b) Percentage of tuned neurons of the AIP, F5, and M1 population express the significant modulation with respect to the mixed objects across time (sliding one-way ANOVA). (c) Tuned neurons (shades of red) were mapped to their recording location during the visual (t = 0.16 s after object presentation) and motor phase (t = 0.7 s after movement onset). (d) As a contrast and to elicit pure visual responses, 'abstract' objects caused different visual stimuli but the same grip. (e) Similar to b, but for the abstract objects set. (f) Similar to c, but showing the map of tuned neurons (shades of green) with respect to the abstract object set. For b, e: Data is doubly aligned on cue onset and on the grasp (go) signal. Sliding ANOVA was computed for each session individually and averaged across all 10 recording sessions per animal. Shades represent standard error from mean (s.e.m.) across recording sessions. For c, f: The number of tuned neurons per channel were averaged across all recording sessions and visualized in shades of green and red for the abstract and mixed objects, respectively. Channels without any identified neurons were highlighted in light grey. Map of monkey M is mirrored along vertical axis for better comparison of both animals.

      DOI: http://dx.doi.org/10.7554/eLife.15278.010

      To investigate this effect at the neuronal population level, we performed canonical discriminant analysis (CDA; see Materials and methods), which allowed reducing the neuronal state space (N-space) to its most informative dimensions. Figure 2c and 2d show the first three canonical variables during the cue and grasp epoch, respectively. In them, each marker represents the neuronal state of an individual trial in the AIP population (see Figure 1b for symbol and colour code). In this N-space of AIP, we found objects to be separated based on their shape. Independent of the way the objects were grasped, the neural space accurately differentiated horizontal cylinders (black), vertical cylinders (green), rings (magenta), spheres (orange), cubes (blue), and bars (black) (see Video 3 for an animated 3D view of a typical N-space).10.7554/eLife.15278.011Population coding in F5.

      Joint angles and the population activity of F5 were recorded together and for visual display reduced to their most informative dimensions (component 1 and 2). The video displays the evolving hand kinematics (top, left) and neuronal population activity (bottom, left) during three subsequent grasping actions. Arrows point at these trials in the J- (top, right) and N-space (bottom, right). The audio-track plays the spiking activity of an individual F5 neuron, which is highlighted in the raster plot in blue.

      DOI: http://dx.doi.org/10.7554/eLife.15278.011

      To further quantify these findings, we computed the Mahalanobis distance between all pairs of conditions in the complete N-space of AIP (see Materials and methods). Hierarchical cluster analysis (HCA) performed on these distance measures confirmed the findings of the CDA and revealed a clear clustering according to object shape during visual presentation of the object (Figure 2e) that widely persisted during movement execution, although with significantly shorter neural distances (Figure 2f). 100% and 91% of the objects shared their cluster with other objects of the same shape during the cue and grasp epoch, respectively. Importantly, consistent results were observed in both monkeys when performing HCA across all recording sessions (Figure 2—figure supplement 12, see Materials and methods).

      The large number of objects presented in one recording session required separating the 48 objects on different turntables (see Figure 1), often objects of similar shape. This separation created small offsets already in the fixation epoch, but at very low modulations. An extreme case is shown in Figure 2a. This might raise concerns on whether coding in AIP was really due to object shape, or rather to the object presentation order (different turntables presented sequentially). However, shape-wise clustering in AIP cannot be explained by the task design for the following reasons: (1) The offsets in the fixation epoch were very small in comparison to the visual modulations observed in AIP when the objects were presented (e.g., see Video 5). (2) The set of 'mixed' objects – presented and grasped in the same block – clustered with other objects of the same shape (e.g. ring in mixed block clusters with other ring objects). Together, this demonstrates clear shape processing in AIP.

      The AIP population also encoded the size of objects, but differentiated this geometrical feature at clearly lower neural modulations compared to object shape. As shown in Figure 2e–f and supplements, the majority of objects were located closest to objects of similar size, but with significantly shorter neural distances in comparison to shape features. The secondary role of size was surprising, since object size has significant influence on the aperture of the grasping hand (Jakobson and Goodale, 1991).

      To further test the specialisation for shape processing, we tested a mixed set of objects (Figure 3a), causing highly variable visual stimuli and motor responses, against an abstract object set (Figure 3d) that we have specifically designed to cause different visual stimuli but the same grip. In theory, a purely visual area should differentiate both sets of shapes, since they both provide different visual stimuli. In contrast, an exclusive motor area should not show modulations for the abstract objects because they require the same grip. Strikingly, the AIP population responded highly similar to the presentation (cue epoch) of mixed (Figure 3b) and abstract (Figure 3e) objects (t-test, p>0.05; 35% vs. 35% and 20% vs. 17% comparing mixed and abstract objects in monkey Z and M, respectively). Thus, the equal responses to both object sets strongly supports the specialisation of AIP in processing object shapes.

      Importantly, AIP remained the most tuned area when the monkeys planned and grasped the abstract objects, as shown in Figure 3e. However, the number of significantly tuned cells decreased during these epochs in comparison to the responses evoked by the mixed objects (Figure 3b). This reduced selectivity could indicate either motor or visual transformations that are both required for grasping: First, the abstract objects were grasped with the same hand configuration (see Figure 3d). Unmodulated activity could therefore reflect the same motor affordance across the six abstract objects (Fagg and Arbib, 1998; Rizzolatti and Luppino, 2001). Second, the abstract objects have different shapes, but have the graspable handle in common that shares the same geometrical dimensions across all six objects (see Figure 3d). A uniform modulation could therefore also represent visual processes that reduce the objects to its parts relevant for grasping (i.e. the same geometries of the handle across the six abstract objects). Considering that the same AIP population separated the complete object set primarily on their geometrical features (Figure 2e–f) would suggest visual rather than motor transformations explaining uniform modulations.

      We found further indicators for this hypothesis when focusing on objects that caused, in contrast to the abstract objects, equal visual stimuli but different motor responses. To create such a scenario, monkeys were trained to perform power or precision grips on the same object, the handle (condition 00 and 01). Although both conditions were located most distantly in the kinematic or joint-angle (J-) space in both monkeys (see Figure 4e and 5a), they were located closest to each other in the N-space of AIP (see Figure 2e–f), clearly implying a visual representation of the handle. Statistical analysis revealed, however, that both conditions (00, 01) slightly increased their neural distance (Figure 2d) towards planning and movement execution, as expressed by an average of 21% and 16% of significantly tuned AIP neurons in monkey Z and M (ANOVA tested in grasp epoch, p<0.01). These observations suggest a visual representation of the handle and a further differentiation of its parts that are relevant for grasping.10.7554/eLife.15278.012Motor planning and execution in F5.

      (a) Example neuron of F5, responding to all 50 task conditions (colour code as in Figure 1b). (b) Modulation depth plots (as in Figure 2b) in the planning and grasp epoch. (c) Recorded kinematics was used to drive a monkey-specific musculoskeletal model that allowed extracting 27 DOF. (d) A selection of DOFs is presented for three sequential grips: thumb and index finger, wrist, elbow, and shoulder. (e) PCA performed on the J-space during the hold epoch allowed visualizing the grip types of all conditions and trials of one recording session (showing 1st and 2nd PCA component). (f–g) Raster plot shows the spiking activity of F5-neurons recorded from a single FMA (F5-ventral). (h) Mean firing rates during the grasp epoch (N-space) were transformed with CDA to reduce and visualize the multidimensional representation of the complete F5 population (N = 119, simultaneously recorded). In d,g, example trials t1, t2 and t3 are highlighted in yellow (hold epoch in d, grasp epoch in g) and marked with arrows in e,h. (i) Neuronal state space evolution shows the course of the task determined by the CDA. e,h and i: For visual comparison the N-space was aligned to the J-space using PCRA; Symbols and colours as in Figure 1b, symbol size corresponds to object size.

      DOI: http://dx.doi.org/10.7554/eLife.15278.012

      10.7554/eLife.15278.013Hierarchical cluster analysis of the F5 population.

      (a) Dendrogram of J-space (27 DOF). (b–c) Dendrogram of F5’s complete N-space during the plan and the grasp epoch. Condition numbers as in Figure 1b. A selection of grip types and their corresponding objects are illustrated. In a-c, similar motor characteristics are highlighted with coloured boxes (see text). (b,c) is based on the complete F5 population (N = 119, simultaneously recorded neurons), in contrast to its illustration in the reduced neural space in Figure 4. See Figure 5—figure supplement 1–2 for the averaged population results across all sessions of animal M and animal Z, respectively.

      DOI: http://dx.doi.org/10.7554/eLife.15278.013

      10.7554/eLife.15278.014F5-Motor coding in animal M across all recording sessions.

      Neural distances between each pair of group means were measured for each session, averaged across sessions, and visualized as dendograms for the (a) plan and (b) grasp epoch.

      DOI: http://dx.doi.org/10.7554/eLife.15278.014

      10.7554/eLife.15278.015F5-Motor coding in animal Z across all sessions.

      (a) Firing rate plot of F5 example unit. (b) Modulation depth plot of example unit during grasp epoch. (c) Reduced J-space of one session recorded with instrumented glove and (d) reduced N-space of F5 during the grasp epoch of the same session (simultaneously recorded, N = 76, first two components shown). (e–f) Neural distances between each pair of group means were measured for each session, averaged across sessions, and visualized as dendograms for the plan and grasp epoch. For c–e: Symbols and colours as in Figure 1b.

      DOI: http://dx.doi.org/10.7554/eLife.15278.015

      Similarly, the AIP population coded all horizontal cylinders based on their shape and then differentiated the two biggest horizontal cylinders (55,56, see Figure 2), when they were grasped differently (either from top or from below). Both conditions (55, 56) required a focus on different parts of the object (top vs. bottom edge) as well as different hand configurations (pronation vs. supination). Importantly, the neural representation of both conditions originated from the very same shape cluster in N-space (Figure 2c,e) that subsequently drifted further apart (see arrows in Figure 2d,f). Together, these observations suggest a visual rather than motor representation in AIP.

      Motor planning and execution

      To generate grasping movements, visual attributes of objects need to be transformed into adequate motor commands before they get executed (Jeannerod et al., 1995; Rizzolatti and Luppino, 2001). Creating a motor plan and its execution is associated with areas F5 and M1 (Murata et al., 1997; Raos et al., 2006; Umilta et al., 2007).

      In a first analysis that compared neuronal population tuning for the mixed (Figure 3a) and abstract objects (Figure 3d), we found evidence for a primary motor role of F5 and M1. The F5 population was strongly activated in the motor epochs when the mixed objects were grasped differently (up to 47% and 45% tuned neurons in monkey Z and M resp., see Figure 3b), and it was strikingly unmodulated when the abstract objects were grasped similar (Figure 3e). Likewise, the M1 population responded uniformly for similar grips (Figure 3e), but it was modulated very strongly when different hand configurations were applied (up to 67% and 61% in monkey Z an M resp, see Figure 3b).

      During movement planning, M1 showed no or minimal preparation activity (Figure 3a–c), whereas F5 revealed a multimodal role: in the cue epoch, the tuned F5 population substantially decreased from 28% to 18% in monkey Z, and from 13% to 4% in monkey M, when comparing abstract with mixed objects. This is in strong contrast to AIP, which demonstrated equal population responses for both type of object sets. The reduced F5 modulation suggests early motor processes starting shortly after object presentation. However, 18% and 4% (Monkey Z and M resp.) of all F5 neurons remained their modulation when the monkeys observed the abstract geometries. Thus, at least some F5 cells coded objects in purely visual terms.

      It is notable, that we found significantly different contributions in motor preparation between the F5 recording sites. The visual (Figure 3e–f) and visuomotor modulations (Figure 3b–c) prior to movement primarily originated from the ventral recording array, corresponding to the F5a subdivision (Gerbella et al., 2011; Theys et al., 2012a). In fact, 76% of the visual (abstract objects) and 72% of visuomotor tuned neurons (mixed objects) recorded from F5 were detected on the ventral site (ANOVA p<0.01, all sessions, tested in cue epoch), in line with previously reported enhanced decoding capabilities of planning signals from ventral F5 (Schaffelhofer et al., 2015a). In contrast, the dorsal F5 array, corresponding to F5p, mainly contributed during movement execution by a four-fold increase of its tuned population with respect to the cue epoch.

      Feature coding in area F5

      The general population response of F5 was confirmed when extending our analysis to all 49 objects. Neurons were modulated by hand grasping actions and typically showed the strongest MD during motor execution. The example neuron shown in Figure 4a–b demonstrated a maximum MD of 39.8 Hz while grasping and allowed significantly separating 42% of all condition pairs in this epoch (Figure 4b, right). Importantly, the neuron showed similar motor coding already during the preparation epoch (r = 0.76, between plan and grasp MD-maps, as shown in Figure 4b). Using the planning activity of the example neuron alone, about 43% of the task conditions could be separated, thereby demonstrating the important role of F5 for hand movement planning.

      To evaluate the relationship between neural population activity and motor actions, we recorded spiking activity (Figure 4f–g) together with the kinematics of the primate hand (Figure 4c–d). Dimensionality reduction methods (PCA, CDA) were performed to express the high dimensional kinematic (J-space) and neural space (N-space) in a low dimensional fashion. Procrustes analysis (PCRA) was subsequently applied to align the N- to the J-space for their visual comparison (Figure 4e,h-i) (see Materials and methods)

      In detail, joint trajectories were recorded in 3-D space from an instrumented glove (Schaffelhofer and Scherberger, 2012) and translated to joint angles utilizing a primate-specific musculoskeletal model (Schaffelhofer et al., 2015b). The mean values of a total of 27 degrees of freedom were then extracted from the hold epoch to describe the hand shapes used for grasping the objects (J-space, Figure 4c–d). This provided accurate and stable, but highly variable hand configurations across the 49 tested objects. Performing PCA on this dataset allowed visualizing all correctly performed grips in a low-dimensional fashion. Thus, each marker in Figure 4e reflects one individual grip/trial.

      Similarly, spiking activity from a large population of neurons was recorded with the FMAs. Then, mean firing rates were extracted from epochs of interest (e.g., grasp) as illustrated in Figure 4f-g (N-space). On this dataset we performed CDA and PRCA to reduce and compare the multidimensional N-space and the J-space as shown in Figure 4h and Figure 4e, respectively. For an animation of Figure 4 see Video 4.

      The J-space demonstrated a high variability of hand configurations across conditions and closely reflected the hand’s wrist orientation (1st principal component) and hand aperture (2nd principal component). Furthermore, the reduced J-space allowed observing the most relevant kinematic observations with respect to the presented objects, as shown in Figure 4e and 5a: (1) Objects of small sizes such as the small rings (condition ID 21, 22), spheres (11,41,42) and cubes (31, 32) were grasped similarly (index finger and thumb) and thus were located close to each other in the reduced and the complete J-space. (2) Vertical cylinders and big rings (16, 23–26, 71–76) were enclosed with the digits and required 90° of wrist rotation. Therefore, these grips are located close to each other in J-space. (3) All abstract objects (91–96) shared a compact cluster and demonstrated their similarity in J-space. (4) Precision (00) and power grips (01) performed on the same handle required highly different hand configurations and were located distant in J-space. (5) The highest separation of hand configuration across objects of similar shape was evoked from the rings that were grasped with precision (21, 22) or power grips (23–26). Small rings and big rings are therefore separated in the J-space.10.7554/eLife.15278.016Motor execution in M1.

      (a) Example neuron of M1 in monkey M, curves show firing rates separately for all 50 task conditions (colour code as in Figure 1b). (b) Modulation depth plots (as in Figure 4b) for the planning and hold epoch of the example neuron in a. (c) Population activity from the reduced and (d) the complete kinematic space (J-space) is compared to (e) the reduced and (f) the complete neural population space (N-space) of M1 during the hold epoch of the task (N = 151, simultaneously recorded). In e, N-space was aligned to J-space with PCRA; symbols and colours as in Figure 1b; symbol size corresponds to object size. Arrows t1-t3 highlight the example trials of Figure 4d,g. See Figure 6—figure supplement 12 for the averaged population results of animal M and animal Z, respectively.

      DOI: http://dx.doi.org/10.7554/eLife.15278.016

      10.7554/eLife.15278.017M1-Motor coding in animal M across all sessions.

      Neural distances between each pair of group means were measured for each session, averaged across sessions, and visualized as dendograms during the hold epoch.

      DOI: http://dx.doi.org/10.7554/eLife.15278.017

      10.7554/eLife.15278.018M1-Motor coding in animal Z across all sessions.

      (a) Firing rate plot of M1 example unit. (b) Modulation depth plot of example unit in hold epoch. (cd) Reduced J-space of one session recorded with the instrumented glove and reduced N-space of M1 during hold epoch of the same session (simultaneously recorded, N = 62, first two components shown). (e) Neural distances between each pair of group means were measured for each session, averaged across all sessions, and visualized as dendograms. For c,d: Symbols and colours as in Figure 1b.

      DOI: http://dx.doi.org/10.7554/eLife.15278.018

      Importantly, the majority of kinematic observations were also found in the N-space of F5 during motor execution (Figure 4h). In contrast to AIP, conditions of different visual stimuli but equal grips were located close to each other in the neural space (observation 1–3), whereas conditions of similar visual stimuli but different motor responses caused a separation (observation 4–5). These results were further supported by the high similarity between the J- (Figure 4e) and N-space (Figure 4h) during movement execution (for quantification see section ‘Numerical comparison’ and Figure 7). The findings demonstrate clearly different coding properties with respect to AIP and reveal a primary motor role of F5 during movement execution. CDA and PRCA were further used to visualize the evolution of the F5 population during the task. Similar to observations at the single unit level (see Figure 4a–b), the F5 population demonstrated first modulations and expressions of the upcoming motor actions already during motor preparation.10.7554/eLife.15278.019Motor similarity measure.

      Boxplots illustrating similarity between the population coding of J-space and N-space during the hold epoch of the task, as provided by the PCRA analysis. Left: results in AIP, F5, and M1 across all 10 recording sessions for monkey Z. Right: same for monkey M. Red horizontal lines indicate median value, boxes show lower and upper quartile of data (25%–75%), and whiskers indicate maximum and minimal values.

      DOI: http://dx.doi.org/10.7554/eLife.15278.019

      To quantify the observations made on the reduced spaces, hierarchical cluster analysis (HCA) was performed with the complete population of F5 neurons (N-space) and joint kinematics (J-space). In accordance with the low-dimensional representation, abstract forms, small objects, as well as the big rings and cylinders created individual clusters in the J-space and were located close to each other. As shown in Figure 5b, these motor characteristics were rudimentarily marked in F5 already during motor preparation (see Figure 5b, coloured boxes). These clusters that emerged during motor planning persisted to a large extent during motor execution, but increased their relative distance to each other (Figure 5c), in line with the higher MD of single F5 neurons during grasp execution (Figure 4b). HCA performed on the averaged population response across all recording sessions (see Materials and methods) confirmed in both animals the motor characteristics of simultaneously recorded populations in single sessions (Figure 5—figure supplements 12).

      As discussed above, premotor preparation activity primarily originated from the ventral F5 array. Thus, the modulations observed prior to movement execution, such as observed in the CDA and hierarchical clustering, are mainly based on the ventral recording site. In contrast, both arrays significantly supported movement execution. The different modalities in both recording sites are in line with the architectonically (Belmalih et al., 2009) and connectionally (Borra et al., 2010; Gerbella et al., 2011) distinct subdivisions F5a and F5p, which largely correspond to the ventral and dorsal recording array, respectively. Distinct connections of F5a with SII, AIP and other subdivision of F5 (but not to M1) (Gerbella et al., 2011) suggest an integration of visual, motor and context specific information (Theys et al., 2013). On the other hand, connections of F5p to the hand area of M1 and to the spinal cord (Borra et al., 2010) suggest a rather direct contribution to hand movement control. Taken together, the multimodal preparation signals, including visual and motor contribution, and the distinct motor feature coding towards planning and execution, supports the key role of F5 for visuomotor transformation.

      Feature coding in area M1

      In agreement with the general population response (Figure 3b), single neurons of M1 were almost exclusively modulated during movement execution and showed minimal modulations during preparatory epochs (Umilta et al., 2007), as also indicated by the example neuron in Figure 6a–b. This neuron was capable of differentiating 52% of condition pairs when holding the object, but failed to separate any (0%) of the conditions when planning the movement. (ANOVA, Tukey-Kramer criterion, p<0.01), thereby highlighting its major difference to F5 neurons.

      Although the motor relevance of the hand area of M1 has been described extensively with electrophysiological (Schieber, 1991; Schieber and Poliakov, 1998; Spinks et al., 2008; Umilta et al., 2007) and anatomical methods (Dum and Strick, 2005; Rathelot and Strick, 2009), it has been unclear how versatile hand configurations are encoded at the population level. The high variability of objects and motor affordances in our task allowed such a description (Figure 6). Similar to the analysis performed on the F5 population, PCRA analysis compared the J-space with the N-space of M1 and revealed, highly important for the understanding of hand movement generation and as an important control, striking similarities between both representations, as demonstrated in Figure 6c,e.

      The similarity of J- and N-space of M1 was not only visible in the first two components, but was also quantified across all dimensions in the hierarchical cluster trees of the simultaneously recorded M1 population (Figure 6d,f) and when averaging the population response across all recording sessions (Figure 6—figure supplement 1–2 for monkey M and Z, respectively). The large majority of conditions were assigned to the same clusters in the J- and the M1-space (coloured boxes in Figure 6d,f, exceptions: conditions 42, 43). Furthermore, all of the motor characteristics (1–5) defined above were also observed and were even more strongly represented in M1 than in F5: again, the group of small objects (11, 21–22, 31–32, 41–42) and the group of abstract forms (91–96) created strong and individual clusters, whereas small (21–22) and big rings (16, 23–26) as well as precision (00) and power grips (01) were located distant from each other.

      Numerical comparison

      We also quantified motor similarities between the J-space and the N-space of area AIP, F5, and M1 across all recording sessions, similar to individual recording session analyses presented in Figures 46. For this, similarity measures were performed between the J-space and the N-space of AIP, F5 and M1 using PCRA (see Materials and methods). A similarity of '0' indicates a complete match between the distribution of trials (n > 500) in N-space and in J-space, whereas values close to '1' represent high divergences between the clustering in both spaces. In accordance with the previous analysis, M1 demonstrated the highest similarity to the J-space (averaged value across 10 recording sessions for monkey M: 0.48, for monkey Z: 0.59), followed by F5 (monkey M: 0.61; monkey Z: 0.65) and AIP (monkey M: 0.75; monkey Z: 0.75). These values were highly consistent across recording sessions and monkeys (Figure 7). Furthermore, differences between areas were significant (ANOVA and post-hoc Tukey-Kramer criterion, p<0.01). Together, these results highlight the different roles of the cortical areas AIP, F5, and M1 for the preparation and execution of grasping movements.

      Feature code correlation

      For visualizing the communication of features between areas, we correlated the dynamic modulations on a trial-basis (see Materials and methods). In this, the elicited modulation patterns of each neuronal population were correlated in a pair-wise fashion (AIP vs. F5, F5 vs. M1, AIP vs. M1) across time (Figure 8, Video 5).10.7554/eLife.15278.020Temporal feature correlation between areas.

      The distance (in firing rate) between all possible trial-pairs was computed separately in the N-space of area AIP, F5 and M1. The resulting distance maps thus represent the neuronal modulations of a population (e.g. AIP) for a specific time t. (Right) Example maps show the neural modulation patterns at key times t1 (object presentation) and t2 (during hold). Warm colours: long neural distances, cool colours: short neural distances. (Left) Correlating the neuronal patterns across time (Spearman’s r) allowed visualizing the similarity between the areas for animal Z (top row) and animal M (bottom row). For computation, spiking activity was aligned to the beginning of the cue and grasping onset. For an animation of the feature code correlation see Video 5.

      DOI: http://dx.doi.org/10.7554/eLife.15278.020

      10.7554/eLife.15278.021Temporal feature correlation between areas.

      The neural distance (in firing rate) between all pairs of trials within a neuronal population provided a modulation pattern between trials (top) for area AIP, F5, and M1. Correlating these neuronal patterns for each moment in the task allowed visualizing the coding similarity between pairs of areas across time (AIP-F5 in green, AIP-M1 in cyan, and F5-M1 in magenta). Feature correlations are based on all trials, whereas the presented object and corresponding grasp movement are shown for an example trial.

      DOI: http://dx.doi.org/10.7554/eLife.15278.021

      During object presentation, we found similar chequered patterns in area AIP in both animals (t1 in Figure 8), again confirming the coding of object shapes at the population level, but here on trial-by-trial basis. These visual feature patterns caused a significant correlation peak with area F5 in animal Z, suggesting the propagation of visual information; in animal M, however, only a minor correlation peak was observed (Figure 8). These results are consistent with the different proportion of F5 visual cells identified in animal Z and M (Figure 3), which only temporarily shared the visual coding with AIP. Interestingly, F5 and AIP demonstrated minimal similarities during movement planning, in support of the different encoding schemes of visual and motor features described at the population level (Figures 2,4 and 5).

      F5 modulations strongly increased before movement execution and were followed by M1 activity after movement onset (see Video 5), suggesting that premotor cortex drives M1. Signals did not only follow in time but also in modulation patterns, as expressed by the impressively high correlation coefficients in both animals (t2 in Figure 8), and in agreement with similar motor coding schemes observed with the population analysis. Together, these results expand the static feature coding found with CDA by demonstrating dynamical functional coupling of AIP, F5, and M1 during the course of the delayed grasp and hold task.

      Discussion

      In this study, we took advantage of a rich set of objects and parallel recording techniques to study visuomotor transformation. We show that the cortical grasping network differentiates visual from motor processes to achieve this transformation. Area AIP revealed a strong visual role and a specialisation for processing object shapes. In contrast, area F5 coded objects only partially and temporarily in visual terms and switched to dominant motor signals towards movement planning and execution. The encoded motor features of F5 showed striking similarities with M1 thereby suggesting a strong collaboration of both areas during hand and movement control.

      Recording sites and relation to anatomical connections

      We targeted the cortical grasping circuit with FMAs implanted under anatomical considerations. AIP, an end-stage area of the dorsal visual stream, receives input from parietal visual areas (e.g., LIP, CIP, and V6a) as well as from the inferior temporal cortex (e.g., areas TEa and TEm) (Borra et al., 2008; Nakamura et al., 2001). AIP further connects to pre-motor F5 via dense reciprocal projections (Borra et al., 2008; Gerbella et al., 2011; Luppino et al., 1999). In agreement with these known connections, we observed strong visuomotor responses in AIP and F5 (Figure 3).

      Another significant connection links F5 with the hand area of M1 (Dum and Strick, 2005; Kraskov et al., 2011). As described by Rathelot and Strick (2009), neurons of M1, in particular in the bank of the central sulcus, form direct connections to α-motor neurons in the spinal cord that drive the distal hand muscles. In line with these observations, the majority of M1-neurons demonstrated significant modulations during hand movement control despite highly constant reaching components (Figure 3b). Together, strong grasp modulations (Figure 3) and their intercommunication (Figure 8) confirmed the correct positioning of the electrode arrays and the importance of all areas for visuomotor processing.

      Visual processing for grasping

      While it is known that area AIP and F5 strongly respond to the presentation of objects and to the variation of their dimensions (e.g. shape, orientation) (Baumann et al., 2009; Fagg and Arbib, 1998; Murata et al., 1997; 2000; Taira et al., 1990) it was unclear whether these modulations reflect visual or motor processes. For example, responses to object presentation can either reflect object attributes or instant motor representations as we have shown here (Figure 3) and as suggested previously (Murata et al., 1997). By design, our task created associations as well as dissociations between objects and their afforded hand configurations (Figure 4e, 5a) in order to disentangle these normally highly linked parameters.

      The AIP population demonstrated a distinct visual separation of objects (Figure 2, 3e), which was largely unrelated to the observed motor characteristics (Figure 4e, 5a), even when grasping in complete darkness (Figure 7). The predominant criterion for object separation was object shape, even for abstract geometries that required the same grip (Figure 3d–f). These findings are in agreement with anatomical connections of AIP to the inferior temporal cortex (Borra et al., 2008) that codes perceived shapes (Logothetis et al., 1995; Tanaka, 1996). Object size was expressed in the population but played, surprisingly, only a secondary role in AIP (Figure 2). These smaller neural distances with respect to size are remarkable, in particular since this feature is highly relevant for controlling hand aperture (Jakobson and Goodale, 1991). A possible explanation for this effect could be the higher computational effort (more neurons) required for processing shape in comparison to size.

      AIP also widely maintained its coding for visual object properties during movement execution in the dark (Figure 2f), although with significantly smaller neural distances (Figure 2e–f). We hypothesize that AIP serves as working memory and not only extracts, but also maintains visual object information required for motor planning and execution (Rizzolatti and Luppino, 2001). We emphasize that visual coding at the population level does not preclude motor coding of some individual cells, as suggested previously (Murata et al., 1997). Rather, the evidence of bidirectional connections to F5 suggests that subpopulations exist in AIP that reflect feedback of motor signals.

      Despite AIP’s primary visual coding, we observed a distinctive coding in the N-space when the same objects were grasped differently (e.g., handle and cylinders in Figure 2c–d). These modulations could reflect either motor (Fagg and Arbib, 1998) or visual transformations required for grasping. In fact, when grasping an object, both processes are required: the visual selection of (focus on) object parts and the selection of a corresponding hand configuration. Several indicators in our data suggest visual rather than motor transformations in AIP: First, the population separated the entire set of objects in visual terms, but differentiated same objects when grasped differently. Second, the separation of the same object when grasped differently, originated from one object shape cluster. In line with these findings, Baumann et al. (2009) demonstrated that AIP planning activity depends on the previous visual knowledge of an object (see Figure 6 in their paper). Presenting an object (the same handle as we used) caused a strong visual activation in the AIP population that got separated when a grip type (precision or power grip) was instructed subsequently. In contrast, instructing the grip type before object presentation did not lead to a substantial population response and caused significant modulations only after the object was presented. These differentiation schemes support our hypothesis of visual rather than motor transformations in AIP.

      Motor planning and execution

      Grasping requires the transformation of visual descriptions of an object into adequate motor commands. F5 is densely connected to AIP (Borra et al., 2008; Gerbella et al., 2011; Luppino et al., 1999) and has been associated with these visuomotor processes (Fluet et al., 2010; Jeannerod et al., 1995; Rizzolatti and Luppino, 2001). Similar to AIP, neurons in F5 respond to the presentation of 3D objects (Fluet et al., 2010; Murata et al., 1997; Raos et al., 2006; Theys et al., 2012a; Vargas-Irwin et al., 2015). These modulations have been discussed to reflect object or motor representations (Fluet et al., 2010; Murata et al., 1997; Raos et al., 2006; Theys et al., 2013), however without measuring corresponding hand kinematics.

      With many more object conditions, precise hand kinematics, and a large neuronal dataset we were able to address this question and confirm a primary motor role of the F5 population for representing the joint (J-) space during motor execution (Figures 4, 5). Due to the large number of objects tested, we could demonstrate for the first time that the F5 population does not reflect stereotypical grip types (Rizzolatti and Luppino, 2001), but represents a continuum of many hand configurations (Figure 5), highly similar to M1 (Figure 8, Video 5).

      Importantly, motor characteristics in the N-Space of F5 could be observed not only in motor execution epochs, but also during motor preparation (Figure 4i, 5b). In contrast to AIP, the F5 population showed already in the cue epoch a reduced tuning for abstract objects requiring the same grip (Figure 3a–b vs. Figure 3d–e). This suggests a rapid appearance of grip features in F5 shortly after object presentation. However, F5 also contained a small subgroup of neurons that represented pure visual information during the cue epoch (Figure 3). The vast majority of these cells have been recorded from the ventral array, i.e., they originate from the F5a subdivision. In line, electrophysiological investigations of area F5a demonstrated selectivity for 3D shape (Theys et al., 2012a). We suggest that these neurons receive direct visual input from AIP and might be crucially involved in the activation of stored motor plans. Similar modulation patterns in AIP and F5 during object presentation suggest the communication of visual properties to premotor cortex (Figure 8 and Video 5). The presence of multimodal signals as well as the proximity of specialized sub areas for visual input and motor output suggest a central role of F5 for visuomotor transformation.

      In contrast to F5, the hand area of primary motor cortex (M1) showed an almost exclusive role for motor execution (Saleh et al., 2010; Umilta et al., 2007). We investigated, for the first time, the N-space of the hand area of M1 (Rathelot and Strick, 2009) for a large repertoire of grasping actions. As expected, the N-space of M1 was closely related to the J-space (Figure 6) and showed the highest motor similarity across all three areas (Figure 7).

      Correlating these M1 modulation patterns with F5 revealed that both areas are not only strongly interconnected (Dum and Strick, 2005; Kraskov et al., 2011), but they also heavily share motor features for grasping (Figure 8). The high similarity of the F5 and M1 population during movement execution (Figure 4h vs. Figure 6e, Figure 8, and Video 5) is in agreement with findings of similar coding schemes between both areas in spiking (Umilta et al., 2007) and beta-band LFP activity (Spinks et al., 2008). The earlier premotor (vs. motor) onset (Figure 3b) suggests that the movement is facilitated by F5, whereas the closer motor similarity of M1 might reflect its advanced finger control capacity due to more direct motor connections (Fogassi et al., 2001; Rathelot and Strick, 2009; Schieber and Poliakov, 1998).

      Conclusions

      Our findings demonstrate that the cortical grasping network transforms visual object attributes into motor plans and actions. We found highly different coding schemes between the frontoparietal circuits of AIP and F5, indicating widely separated processing of visual and motor features. These findings suggest that visuomotor transformation is achieved effectively by visual object descriptions that activate linked motor plans in the reciprocal network of AIP and F5. Strong feature communication between F5 and M1 further suggest a common motor network that executes and refines the prepared motor plan.

      Materials and methodsAnimal training and experimental setup

      Two rhesus monkeys (Macaca mulatta) participated in this study (animal Z: female, 7.0 kg body weight; animal M: male, 10.5 kg). Animal housing, care, and all experimental procedures were conducted in accordance with German and European laws governing animal welfare and were in agreement with the guidelines for the care and use of mammals in neuroscience and behavioural research (National Research Council, 2003; see also Ethics statement).

      We developed an experimental setup that allowed us to present a large number of graspable objects to the monkeys while monitoring their behaviour, neural activity and hand kinematics. During each recording session, monkeys grasped a total of 42–48 objects of equal weight that were placed on 8 interchangeable turntables (Figure 1a–b). Objects were of different shapes and sizes including rings (diameter of 15, 20, 25, 30, 35, and 40 mm), cubes (length of 15, 20, 25, 30, 35, and 40 mm), spheres (diameter of 15, 20, 25, 30, 35 and 40 mm), horizontal cylinders (diameter of 15, 20, 25, 30, 35, 40 mm, equal length), vertical cylinders (diameter: 15, 20, 25, 30, 35, 40 mm, equal height), and bars (depth of 15, 20, 25, 30, 35, and 40 mm, equal height and width). Furthermore, a mixed turntable held objects of different shapes of average size. Important for this study, a special turntable was holding objects of abstract forms, which differed largely visually but required identical hand configurations for grasping (Figure 1b). Both monkeys were also trained to grasp a single object, a handle, either with a precision grip or a power grip. This extended our task by two more conditions (to a total of 50) that evoked similar visual, but different motor responses. In 20 recording sessions (10 per animal), each condition was repeated at least 10 times.

      Precision and power grips applied on the handle as well as grasping and lifting the 3D-objects were detected with photoelectric barriers (Schaffelhofer et al., 2015a). The turntable position was controlled with a step motor. Furthermore, the monkey’s eye position was monitored with an optical eye tracking system (model AA-EL-200; ISCAN Inc.). All behavioural and task-relevant parameters were controlled using a custom-written control software implemented in LabVIEW Realtime (National Instruments, Austin, TX).

      Task paradigm

      Monkeys were trained to grasp 49 objects (Figure 1b) in a delayed grasp-and-hold task (Figure 1d). While sitting in the dark the monkeys could initiate a trial (self-paced) by placing their grasping hand (left hand in monkey Z, right hand in monkey M) onto a rest sensor that enabled a fixation LED close to the object. Looking at (fixating) this spot for a variable time (fixation epoch, duration: 500–800 ms) activated a spot light that illuminated the graspable object (cue epoch: 700 ms). After the light was turned off the monkeys had to withhold movement execution (planning epoch: 600–1000 ms) until the fixation LED blinked for 100 ms. After this, the monkeys released the rest sensor, reached for and grasped the object (movement epoch), and briefly lifted it up (hold epoch: 500 ms). The monkeys had to fixate the LED throughout the task (max. deviation: ~5 deg of visual angle). In trials where the handle was grasped, one of two additional LEDs was presented during the cue epoch, which indicated to perform either a precision grip (yellow LED) or a power grip (green LED). All correctly executed trials were rewarded with a liquid reward (juice) and monkeys could initiate the next trial after a short delay. Error trials were immediately aborted without reward and excluded from analysis.

      Kinematics recording

      Finger, hand, and arm kinematics of the acting hand were tracked with an instrumented glove for small primates (Figure 1a,c). Seven magnetic sensor coils (model WAVE, Northern Digital) were placed onto the fingernails, the hand’s dorsum as well as the wrist to compute the centres of 18 individual joints in 3D space, including thumb, digits, wrist, elbow and shoulder. The method and its underlying computational model have been described previously (Schaffelhofer and Scherberger, 2012).

      Recorded joint trajectories were then used to drive a 3D-musculoskeletal model (Schaffelhofer et al., 2015b), which was adjusted to the specific anatomy of each monkey. The model was implemented in OpenSim (Delp et al., 2007) and allowed extracting a total of 27 DOF [see Schaffelhofer et al. (2015b) for detailed list of DOF]. All extracted joint angles from the model were low-pass filtered (Kaiser window, finite impulse response filter, passband cutoff: 5–20 Hz), downsampled to 50 Hz and used to describe the hand configuration in a 27-dimensional joint space (J-space).

      Electrophysiological recordings

      Single and multiunit activity was recorded simultaneously using floating microelectrode arrays (FMA, Microprobe Inc., Gaithersburg, MD, USA). In each monkey we recorded from in total 192 channels of 6 individual arrays implanted into the cortical areas AIP, F5, and M1 (see Figure 1e–g). In each array, the lengths of the electrodes increased towards the sulcus and ranged from 1.5 (1st row) to 7.1 mm (4th row). In area F5, one array was placed in the posterior bank of the inferior arcuate sulcus approximately targeting F5a (longer electrodes) (Theys et al., 2012a) and approaching the F5 convexity (F5c; shorter electrodes). The second and more dorsally located array was positioned to target F5p. In AIP, the arrays were implanted into the end of the posterior intraparietal sulcus at the level of area PF and more dorsally at the level of area PFG. In M1, both arrays were placed into the hand area of M1 into the anterior bank of the central sulcus at the level of the spur of the arcuate sulcus (Rathelot and Strick, 2009). See Schaffelhofer et al. (2015a) for details on surgical procedures. Neural activity was recorded at full bandwidth with a sampling frequency of 24 kHz and a resolution of 16 bits (model: RZ2 Biosignal Processor; Tucker Davis Technologies, FL, USA). Neural data was synchronously stored to disk together with the behavioural and kinematic data. Raw recordings were filtered offline (bandpass cutoff: 0.3––7 kHz) before spikes were detected (threshold: 3.5x std) and extracted. Spike sorting was processed in two steps: First, we applied super-paramagnetic clustering (Quiroga et al., 2004) and then revised the results by visual inspection using Offline sorter (Plexon, TX, USA) to detect and remove neuronal drift and artefacts. No other pre-selection was applied and single and multiunit activity have been analysed together.

      Data analysisFiring rate and modulation depth

      Firing rate plots were created in order to visualize the activity of example neurons across time. For this, spike rates were smoothed with a Gaussian Kernel (σ = 50 ms) over time and then averaged across trials of the same condition (Baumann et al., 2009). To illustrate the response of a specific condition we used the colour code as introduced in Figure 1b. Furthermore, we visualized the modulation depth (MD) of example neurons in specific epochs of interest. The MD between two conditions was defined as their absolute difference in average firing rate. This measure was computed for all possible pairs of conditions and visualized as a colour-map. In addition, we performed multi-comparison tests to check whether the differences in firing rate between conditions were significant (ANOVA, Tukey-Kramer criterion, p<0.01; ≥10 trials/condition, ≥500 trials/session, Matlab functions: anova1, multcompare).

      Sliding ANOVA population analysis

      To investigate the population activity during the course of the trial, we tested for significant tuning at multiple time points t using a 1-way ANOVA. Similar to the visualization of firing rates, we first smoothed all spike trains with a Gaussian kernel (σ = 50 ms) and then performed a sliding ANOVA in time steps of 1 ms (p<0.01; no multi-comparison correction, ≥10 trials/condition). Sliding ANOVA results were then averaged across all recording sessions to visualize results (Figure 3). Due to the variable length of the planning epoch, trials were first aligned to the cue-onset and then to the grasp-onset event. Abstract shapes were introduced at a later stage of the project (included in 12 recording sessions, Figure 3e), whereas all other conditions were tested in all 20 recording sessions (Figure 3b). Please note: Irregular grips were detected in the J-space and excluded for the sliding ANOVA analysis of the abstract shapes (Figure 3b). Only 17 trials in 12 recording sessions were excluded to guarantee equal hand configurations for statistical analysis.

      To calculate the visual response times of an area of interest (i.e. AIP and F5) we measured the time between cue onset and 75% of the population’s peak activity. Response times were averaged across recording sessions for each animal and tested for significant differences.

      Dimensionality reduction

      To compare and visualize the simultaneously recorded high-dimensional data (J- and N-space), we applied dimensionality reduction methods. We used principal component analysis (PCA) to express the data variability of the J-space in a compact, lower-dimensional fashion. This approach was demonstrated to be optimal for describing hand shapes (Pesyna et al., 2011). As an input for PCA, we computed for each trial and DOF the mean joint angle during the hold epoch (in degrees). This let for each trial to a 27-dimensional joint position vector in J-space that robustly described the monkey’s average hand configuration during the hold epoch, and across all trials to an input matrix of dimension: trials x DOF.

      For exploring the N-space (neuronal population space), we applied canonical discriminant analysis (CDA). Similar to PCA, CDA creates a new transform of the original dataset spanned by linear combinations of the original variables. Whereas PCA creates the new coordinate system in a way that maximizes the total variance, CDA transforms the data in order to maximize the separation of groups (here: task conditions). The first axis in the new transform (first canonical variable) therefore reflects the linear combination of original variables that show the most significant F-statistic in a one-way analysis of variance. The second canonical variable is orthogonal to the first one and has maximum separation within the remaining dimensions.

      We performed CDA based on the population's mean firing rates of a specific task epoch of interest (e.g., grasp epoch) relative to baseline activity. This means, a population matrix consists of entries that correspond to the mean firing rate of individual neurons for all trials in a certain time interval (dimensions: trials x number of neurons). In contrast to other dimensionality reduction methods, CDA considers only variances of the signal related to conditional differences. Due to this advantage, noise or condition-irrelevant modulations get suppressed.

      For a fair comparison, all dimensionality reduction results presented for the individual areas originated from the same recording session per monkey (e.g. AIP, F5 and M1 populations shown from monkey Z or M) and were therefore recorded simultaneously.

      Procrustes analysis

      Procrustes analysis (PCRA) can be used to test similarities or differences between multidimensional datasets of different measures and scales. In the context of this study, PCRA was used to evaluate the resemblance between the J- and the N-space (firing rates). For this, we reduced both representations to their highest common dimension (i.e., 27 DOF of hand and arm) using the dimensionality reduction methods explained above (i.e., CDA for N-space). This produced datasets of identical number of trials (e.g., 600) and dimensions (e.g., 27). Then PCRA was used to translate and rotate the space of interest (e.g., N-space of M1, F5, or AIP) in a way that minimized the sum of squared distances (SSD) to the corresponding points in the reference space (e.g., J-space) (Matlab function: procrustes). The resulting transform was used to visualize and quantify the amount of similarity to the reference space (J-space). As a numerical measure of similarity, the sum of squared distances between the new transform and the reference frame was computed and normalized by the sum of squared distances between points of the reference space to their dimensional means (Matlab function: procrustes). This similarity measure is a non-negative number with values near 0 implying a high similarity between the multidimensional spaces and values approaching (or exceeding) 1 implying strong dissimilarity.

      Hierarchical cluster analysis

      To illustrate and compare the many conditions of our task in an untransformed, full-dimensional way, we performed hierarchical cluster analysis (HCA). We first computed the Mahalanobis distances between the population activities (N-space) of all possible pairs of task conditions in an epoch of interest (Matlab function: manova1). This resulting distance matrix (e.g., for 50 x 50 conditions) was used to create an agglomerative hierarchical cluster tree based on the average linkage criterion (Matlab function: manovacluster), presenting the cluster solutions of an individual recording session as dendrograms (e.g. Figure 2e–f for AIP of animal Z). Additionally, we averaged the Mahalanobis distance matrices of all individual session to build dendrograms expressing the N-space of an animal across all recording sessions (e.g. Figure 2—figure supplement 1 for AIP of animal Z).

      Feature code correlation

      For correlating the dynamic feature communicated within the grasping network we (1) binned the spiking activity of each individual neuron (bin width = 10 ms), (2) smoothed the firing rates with a Gaussian kernel (σ = 300 ms) and (3) aligned the firing vectors to both cue and grasp onset. Within each of the resulting bins we then (4) computed the Euclidean distance between all possible pairs of trials in the N-space. This leads, separately for each area AIP, F5 and M1, to a distance matrix of the size m2, where m is the number of trials that represents the neural population difference across different trials and trial conditions. Pairs of such matrices from AIP, F5, and M1 were then (5) correlated for every time bin (Spearman’s correlation coefficient), which led to a correlation function across time for each pair of areas (AIP-F5, AIP-M1, and F5-M1). This correlation function represents for every time in the task the similarity of the encoded features between both areas. Figure 8 and Video 5 visualizes these distance matrices and the resulting correlation function over the time.

      Acknowledgements

      The authors thank M Sartori, M Dörge, K Menz, R Ahlert, N Nazarenus, and L Burchardt for assistance and MM Fabiszak, M Hepp-Reymond, and W Freiwald for helpful comments on an earlier version of the manuscript. This work was supported by the Federal Ministry of Education and Research (Bernstein Center for Computational Neuroscience II Grant DPZ-01GQ1005C, the German Research Foundation (SCHE 1575/3-1), the European Union Grant FP7– 611687 (NEBIAS), and the Humboldt Foundation.

      Additional informationCompeting interests

      The authors declare that no competing interests exist.

      Author contributions

      SS, Designed experiments, Developed the experimental setup, Trained the animals, Recorded and analysed the data, Wrote the manuscript, Acquisition of data

      HS, Designed experiments, Performed the surgeries, Edited the manuscript, Provided supervision at all stages of the project, Analysis and interpretation of data

      Ethics

      Animal experimentation: All procedures and animal were conducted in accordance with the guidelines for the care and use of mammals in neuroscience and behavioral research (National Research Council, 2003), and were in agreement with German and European laws governing animal care. Authorization for conducting this study has been granted by the regional government office, the Animal Welfare Division of the Office for Consumer Protection and Food Safety of the State of Lower Saxony, Germany (permit no. 032/09). Monkey handling also followed the recommendations of the Weatherall Report of good animal practice. Animals were pairhoused in a spacious cage (well exceeding legal requirements) and were maintained on a 12-hour on/off lighting schedule. Housing procedures included an environmental enrichment program with access to toys, swings, and hidden treats (e.g., seeds in sawdust). Monkeys had visual and auditory contact to other monkeys. They were fed on a diet of enriched biscuits and fruits. Daily access to fluids was controlled during training and experimental periods to promote behavioral motivation. All surgical procedures were performed under anesthesia, and all efforts were made to minimize post-surgical pain or suffering. Institutional veterinarians continually monitored animal health and well-being.

      ReferencesBaumannMAFluetMCScherbergerH2009Context-specific grasp movement representation in the macaque anterior intraparietal areaJournal of Neuroscience296436644810.1523/JNEUROSCI.5479-08.2009BelmalihABorraEContiniMGerbellaMRozziSLuppinoG2009Multimodal architectonic subdivision of the rostral part (area F5) of the macaque ventral premotor cortexJournal of Comparative Neurology51218321710.1002/cne.21892BiedermanI1987Recognition-by-components: a theory of human image understandingPsychological Review9411514710.1037/0033-295X.94.2.115BorraEBelmalihACalzavaraRGerbellaMMurataARozziSLuppinoG2008Cortical connections of the macaque anterior intraparietal (AIP) areaCerebral Cortex181094111110.1093/cercor/bhm146BorraEBelmalihAGerbellaMRozziSLuppinoG2010Projections of the hand field of the macaque ventral premotor area F5 to the brainstem and spinal cordThe Journal of Comparative Neurology5182570259110.1002/cne.22353BrochierTUmiltàMA2007Cortical control of grasp in non-human primatesCurrent Opinion in Neurobiology1763764310.1016/j.conb.2007.12.002CastielloU2005The neuroscience of graspingNature Reviews. Neuroscience672673610.1038/nrn1744CulhamJCDanckertSLDeSouzaJFGatiJSMenonRSGoodaleMA2003Visually guided grasping produces fMRI activation in dorsal but not ventral stream brain areasExperimental Brain Research15318018910.1007/s00221-003-1591-5DavareMKraskovARothwellJCLemonRN2011Interactions between areas of the cortical grasping networkCurrent Opinion in Neurobiology2156557010.1016/j.conb.2011.05.021DelpSLAndersonFCArnoldASLoanPHabibAJohnCTGuendelmanEThelenDG2007OpenSim: open-source software to create and analyze dynamic simulations of movementIEEET Biomed Eng541940195010.1109/TBME.2007.901024DumRPStrickPL2005Frontal lobe inputs to the digit representations of the motor areas on the lateral surface of the hemisphereJournal of Neuroscience251375138610.1523/JNEUROSCI.3902-04.2005FaggAHArbibMA1998Modeling parietal-premotor interactions in primate control of graspingNeural Networks111277130310.1016/S0893-6080(98)00047-1FellemanDJVan EssenDC1991Distributed hierarchical processing in the primate cerebral cortexCerebral Cortex114710.1093/cercor/1.1.1FluetMCBaumannMAScherbergerH2010Context-specific grasp movement representation in macaque ventral premotor cortexJournal of Neuroscience30151751518410.1523/JNEUROSCI.3343-10.2010FogassiLGalleseVBuccinoGCraigheroLFadigaLRizzolattiG2001Cortical mechanism for the visual guidance of hand grasping movements in the monkey: A reversible inactivation studyBrain 12457158610.1093/brain/124.3.571GalleseVMurataAKasedaMNikiNSakataH1994Deficit of hand preshaping after muscimol injection in monkey parietal cortexNeuroreport51525152910.1097/00001756-199407000-00029GerbellaMBelmalihABorraERozziSLuppinoG2011Cortical connections of the anterior (F5a) subdivision of the macaque ventral premotor area F5Brain Structure & Function216436510.1007/s00429-010-0293-6GoodaleMAMeenanJPBülthoffHHNicolleDAMurphyKJRacicotCI1994Separate neural pathways for the visual analysis of object shape in perception and prehensionCurrent Biology460461010.1016/S0960-9822(00)00132-9JakobsonLSGoodaleMA1991Factors affecting higher-order movement planning: a kinematic analysis of human prehensionExperimental Brain Research8619920810.1007/BF00231054JeannerodMArbibMARizzolattiGSakataH1995Grasping objects: the cortical mechanisms of visuomotor transformationTrends in Neurosciences1831432010.1016/0166-2236(95)93921-JKraskovAPrabhuGQualloMMLemonRNBrochierT2011Ventral premotor-motor cortex interactions in the macaque monkey during grasp: response of single neurons to intracortical microstimulationJournal of Neuroscience318812882110.1523/JNEUROSCI.0525-11.2011LogothetisNKPaulsJPoggioT1995Shape representation in the inferior temporal cortex of monkeysCurrent Biology555256310.1016/S0960-9822(95)00108-4LuppinoGMurataAGovoniPMatelliM1999Largely segregated parietofrontal connections linking rostral intraparietal cortex (areas AIP and VIP) and the ventral premotor cortex (areas F5 and F4)Experimental Brain Research12818118710.1007/s002210050833MurataAFadigaLFogassiLGalleseVRaosVRizzolattiG1997Object representation in the ventral premotor cortex (area F5) of the monkeyJournal of Neurophysiology7822262230MurataAGalleseVLuppinoGKasedaMSakataH2000Selectivity for the shape, size, and orientation of objects for grasping in neurons of monkey parietal area AIPJournal of Neurophysiology8325802601NakamuraHKurodaTWakitaMKusunokiMKatoAMikamiASakataHItohK2001From three-dimensional space vision to prehensile hand movements: the lateral intraparietal area links the area V3A and the anterior intraparietal area in macaquesJournal of Neuroscience2181748187NapierJR1956The prehensile movements of the human handJournal of Bone and Joint Surgery. British Volume38-B902913National Research Council2003Guidelines for the Care and Use of Mammals in Neuroscience and Behavioral ResearchWashington, D.CNational Academies Press10.17226/10732NelissenKVanduffelW2011Grasping-related functional magnetic resonance imaging brain responses in the macaque monkeyJournal of Neuroscience318220822910.1523/JNEUROSCI.0623-11.2011PesynaCPundiKFlandersM2011Coordination of hand shapeJournal of Neuroscience313757376510.1523/JNEUROSCI.5158-10.2011QuirogaRQNadasdyZBen-ShaulY2004Unsupervised spike detection and sorting with wavelets and superparamagnetic clusteringNeural Computation161661168710.1162/089976604774201631RaosVUmiltáMAMurataAFogassiLGalleseV2006Functional properties of grasping-related neurons in the ventral premotor area F5 of the macaque monkeyJournal of Neurophysiology9570972910.1152/jn.00463.2005RathelotJAStrickPL2009Subdivisions of primary motor cortex based on cortico-motoneuronal cellsProceedings of the National Academy of Sciences of the United States of America10691892310.1073/pnas.0808362106RizzolattiGLuppinoG2001The cortical motor systemNeuron3188990110.1016/S0896-6273(01)00423-8SakataHTairaMMurataAMineS1995Neural mechanisms of visual guidance of hand action in the parietal cortex of the monkeyCerebral Cortex542943810.1093/cercor/5.5.429SalehMTakahashiKAmitYHatsopoulosNG2010Encoding of coordinated grasp trajectories in primary motor cortexJournal of Neuroscience30170791709010.1523/JNEUROSCI.2558-10.2010SchaffelhoferSScherbergerH2012A new method of accurate hand- and arm-tracking for small primatesJournal of Neural Engineering902602510.1088/1741-2560/9/2/026025SchaffelhoferSAgudelo-ToroAScherbergerH2015aDecoding a wide range of hand configurations from macaque motor, premotor, and parietal corticesJournal of Neuroscience351068108110.1523/JNEUROSCI.3594-14.2015SchaffelhoferSSartoriMScherbergerHFarinaD2015bMusculoskeletal representation of a large repertoire of hand grasping actions in primatesIEEE Transactions on Neural Systems and Rehabilitation Engineering2321022010.1109/TNSRE.2014.2364776SchieberMH1991Individuated finger movements of rhesus monkeys: a means of quantifying the independence of the digitsJournal of Neurophysiology6513811391SchieberMHPoliakovAV1998Partial inactivation of the primary motor cortex hand area: effects on individuated finger movementsJournal of Neuroscience1890389054SmeetsJBBrennerE1999A new view on graspingMotor Control3237271SpinksRLKraskovABrochierTUmiltaMALemonRN2008Selectivity for grasp in local field potential and single neuron activity recorded simultaneously from M1 and F5 in the awake macaque monkeyJournal of Neuroscience28109611097110.1523/JNEUROSCI.1956-08.2008TairaMMineSGeorgopoulosAPMurataASakataH1990Parietal cortex neurons of the monkey related to the visual guidance of hand movementExperimental Brain Research83293610.1007/BF00232190TanakaK1996Inferotemporal cortex and object visionAnnual Review of Neuroscience1910913910.1146/annurev.ne.19.030196.000545TheysTPaniPvan LoonJGoffinJJanssenP2012aSelectivity for three-dimensional shape and grasping-related activity in the macaque ventral premotor cortexJournal of Neuroscience32120381205010.1523/JNEUROSCI.1790-12.2012TheysTSrivastavaSvan LoonJGoffinJJanssenP2012bSelectivity for three-dimensional contours and surfaces in the anterior intraparietal areaJournal of Neurophysiology107995100810.1152/jn.00248.2011TheysTPaniPvan LoonJGoffinJJanssenP2013Three-dimensional shape coding in grasping circuits: a comparison between the anterior intraparietal area and ventral premotor area F5aJournal of Cognitive Neuroscience2535236410.1162/jocn_a_00332UmiltaMABrochierTSpinksRLLemonRN2007Simultaneous recording of macaque premotor and primary motor cortex neuronal populations reveals different functional contributions to visuomotor graspJournal of Neurophysiology9848850110.1152/jn.01094.2006Vargas-IrwinCEFranquemontLBlackMJDonoghueJP2015Linking Objects to Actions: Encoding of Target Object and Grasping Strategy in Primate Ventral Premotor CortexJournal of Neuroscience35108881089710.1523/JNEUROSCI.1574-15.2015
      10.7554/eLife.15278.023Decision letterKastnerSabineReviewing editorPrinceton University, United States

      In the interests of transparency, eLife includes the editorial decision letter and accompanying author responses. A lightly edited version of the letter sent to the authors after peer review is shown, indicating the most substantive concerns; minor comments are not usually included.

      Thank you for submitting your article "Object vision to hand action in macaque parietal, motor, and premotor cortices" for consideration by eLife. Your article has been reviewed by three peer reviewers. The following individuals involved in the review of your submission have agreed to reveal their identity: Kenneth Valyear (peer reviewer) and Sabine Kastner (Senior Editor and peer reviewer).

      The reviewers have discussed the reviews with one another and the Editor has drafted this decision to help you prepare a revised submission.

      Summary:

      All three reviewers felt that this was an exceptionally strong study providing fundamental insight into visuo-motor transformations during grasping actions.

      Essential revisions:

      The reviewers thought that all comments deserve consideration by the authors. Particularly, the reviewers felt that analyzing the data as a function of the F5 subdivisions would strengthen the study further, particularly since the authors have followed such a strategy in previous work, and we'd hope that such analysis will be straightforward. In addition, the reviewers felt that there were interpretational issues with the role of area AIP that will deserve careful attention.

      Reviewer #1:

      The study by Schaffelhofer and Scherberger on "Object vision to hand action in macaque parietal, motor, and premotor cortices" reports novel findings on the roles of areas AiP, F5 and M1 in the transformation of visual information to motor action. Simultaneous recordings in these areas from arrays of electrodes were performed. The animals were trained on an excellent grasping task that used a variety of 3D objects and dissociated the different parts of a grasping task into its component parts (e.g. visual, motor planning, motor action). In addition to the use of sophisticated behavioral and recording protocols, the authors also used a glove to quantitatively measure kinematic aspects of grasping movements. The complex data from multiple areas and recording channels as well as movement parameters were analyzed in sophisticated ways to permit novel insight into the transformation of visual signals in areas AIP and F5 to motor planning and action in F5 and M1. I'll leave the detailed critique to the expert reviewer. In focusing on a larger picture in this particular area, I found this paper outstanding in all respects.

      Reviewer #2:

      1) The main limit of this beautiful work is the assumption that area F5 is anatomo-functionally unitary. Recent literature not considered in this work shows that F5 is neither architectonically (Belmalih et al. 2009) nor connectionally (Gerbella et al. 2011) homogeneous: the ventral and anterior part of F5 (called F5a, where the most lateral arrays in the present study have been implanted), hosts 3D-shape-selective and "visual-dominant" neurons (Theys et al. 2012), commonly found also in AIP (Theys et al. 2013) but not in the dorsal part of F5 (i.e. F5p, see Bonini et al. 2014). Furthermore, while in the introduction the authors generally talk about "connections of F5 to the spinal cord and M1", this is true virtually only for F5p (Borra et al. 2010). Considering altogether data recorded from different F5 subdivisions was acceptable in the authors' previous paper (Schaffelhofer et al. 2015, J Neurosci), as its goal was to decode hand configurations, but not here, where the authors want to elucidate the functioning of the cortical grasping network.

      2) Strictly related to this issue, the electrodes length is unknown. From the authors' previous works (Schaffelhoefer et al. 2015a and Townsend et al. 2011) I infer that "electrode length ranged from 1.5 to 7.1 mm", with the longest electrodes toward the sulcus. Thus, the more superficial electrodes of the lateral arrays certainly sampled F5c motor activity, likely related to mouth and hand movements, (see Graziano et al. 1997 and Maranesi et al. 2012), while the deepest electrodes most likely sampled F5p/a visuomotor activity. Please clarify.

      3) "Data have been analysed from 20 recording sessions (10 per animal)…". I don't understand how many (single and multi) units have been used for the analyses. It seems that a total of about 202 (units)*10 (sessions)=2020 and 355*10=3550 "units" have been considered in the two animals, respectively: with chronic recording this approach would certainly imply some resampling of the same "units" across sessions, increasing their number but reducing the variability of their discharge. At the same time, the authors stated in the Materials and methods section that "all dimensionality reduction results presented for the individual areas originated from the same recording session per monkey", which actually sounds fair, but in contrast with the previous consideration. Please clarify.

      4) I recommend using the same y-axis scales for plots in Figure 3 (b and d). Nevertheless, it is clear that the tuning profile of AIP does not change when abstract or mixed sets of objects are used (see Figure 3b and d): I totally understand the authors' reasoning, but they will acknowledge that all the abstract objects share an elongated shape, while those of the mixed set are much more variable. Thus, the lack of difference in the AIP tuning profile between the two sets is strange and should be better explained/discussed. For example, could it be due to receptive fields properties of AIP neurons (see Romero et al. 2014; Romero and Janssen 2016)?

      Reviewer #3:

      Altogether, I consider the work exceptional. The data make new and important contributions to understanding the cortical mechanisms underlying grasp control. By concurrently recording and characterising the relationships between limb kinematics and neural activity from AIP, F5, and M1 while monkeys viewed and grasped a wide range of objects, the scope of the current investigation is unparalleled in the current primate neurophysiological literature. Also outstanding are the beautiful data visualisation methods that the authors advance here.

      I have a few suggestions, however, detailed below. My hope is that the authors will find these comments constructive.

      A) Main concerns:

      (A-1) The role of AIP

      I'm having some difficulty understanding the authors’ stance on the role of AIP. I believe they are arguing that their data suggest that AIP is encoding object properties in visual terms, and not in motoric terms. They suggest that the results of their CDA show that AIP encodes objects according to shape in visual space, independent of the way they are grasped.

      My interpretation of their stance is that AIP activity does not reflect action possibilities in sensorimotor terms – but rather reflects the 'flagging' of visual features relevant for actions, but NOT (yet) represented as spatiomotor plans.

      If this is indeed their stance, I see this as a significant departure from prior conceptualizations (Jeannerod et al., 1995).

      However, I remain confused about this argument, both (1) conceptually, and (2) with respect to how some aspects of their data can be viewed as consistent these claims.

      1) Conceptually. The authors talk about "object affordances" as different from "motor affordances".

      To me, affordances = action possibilities; they are sensory representations of the external environment that are inseparably linked to the motor apparatus and capabilities of the perceiving animal. In other words, affordances are, according to my understanding, inextricably motor.

      What does it mean to "extract object affordances relevant for grasping", but to not at the same time encode those same objects according to the spatiomotor properties required for their manual interaction?

      They state: "…suggest encoding of object affordances rather than motor affordances".

      I urge the authors to better clarify what is meant by object vs. motor affordances.

      2) Data. Some aspects of AIP data suggest encoding related to motoric features.

      a) Shift for same object – big horizontal cylinders – when grasped from below vs. above.

      b) Significant differentiation of conditions 00 vs. 01.

      c) Motor similarity measures – Figure 7 – presumably a measure of.75 for AIP is different than a measure of "1" – and thus, does suggest some correspondence between N- and J-space encoding in AIP

      d) Also, there interpretation of Figure 3b vs. d – "…observed encoding of abstract objects in AIP can be explained exclusively by object shape."

      Is it not possible that these data may reflect the fact that abstract versus mixed object set have more graspable parts – a greater number of possible actions –, and AIP encoding is sensitive to these differences?

      This account could be considered consistent with the authors’ interpretations regarding the evidence for reduced tuning in AIP over time for abstract shapes: "…reduction of 3D shapes to the relevant parts for grasping…".

      Summary:

      While the authors seem to argue for a strict separation in roles between AIP and F5 – visual vs. motor, respectively – I see the data as more likely evidence for a continuum – a graded difference – visual prevalence in AIP, with motor encoding vs. motoric prevalence in F5, with visual encoding.

      I suggest that the authors clarify their stance, and/or temper their arguments.

      B) Intermediate concerns

      B-1) in the Introduction, the authors state that prior work did not dissociate between visual and motor features. At first, I thought this was inconsistent with the work of Sakata and colleagues – describing visual dominant, visuomotor, and motor dominant cell types. I think some discussion of this work upfront, including how the current approach critically differs, would be helpful.

      B-2) Introduction – last paragraph – it isn't clear to me what the authors mean to say here, without first reading the rest of the paper. I think this section could be made clearer.

      B-3) I'm not sure I understand their explanation of the shape-specificity prior to fixation. Please try to make this clearer.

      B-4) At first I thought I missed something – it seemed as though AIP was not looked at in terms of J- and N-space encoding in the same way that F5 and M1 were. However, later it is clear that they did analyse AIP in the same way. Why not also show these data, as they do for F5 (Figure 4, 5) and M1 (Figure 6)?

      B-5) Figure 4 – it is unclear to me why they plot J-space for the hold epoch and N-space for the grasp epoch; why not show results from the same epochs?

      B-6) Figure 8 – and the authors' discussion of the driving influence of F5 on M1 activity – how do these findings relate to (Umilta et al., 2007; Spinks et al., 2008)? I think these studies should be explicitly discussed.

      Also, is it not surprising to find so little evidence for correspondence between AIP and F5 during planning?

      How does the relationship between AIP and F5 that the authors suggest according to their new results compare with prior accounts – e.g. Jeannerod et al., 1995; Fagg and Arbib, 1998?

      How do the authors interpret the increased AIP-M1 correspondence during grasp and hold?

      B-7) What do the authors mean by the statement regarding M1 on p.26 "…its neuronal population has never been studied explicitly"? What about, for e.g., the work of Umilta et al., 2007; Spinks et al., 2008?

      References:

      Fagg AH, Arbib MA (1998) Modeling parietal-premotor interactions in primate control of grasping. Neural Netw 11:1277-1303.

      Jeannerod M, Arbib MA, Rizzolatti G, Sakata H (1995) Grasping objects: the cortical mechanisms of visuomotor transformation. Trends Neurosci 18:314-320.

      Spinks RL, Kraskov A, Brochier T, Umilta MA, Lemon RN (2008) Selectivity for grasp in local field potential and single neuron activity recorded simultaneously from M1 and F5 in the awake macaque monkey. J Neurosci 28:10961-10971.

      Umilta MA, Brochier T, Spinks RL, Lemon RN (2007) Simultaneous recording of macaque premotor and primary motor cortex neuronal populations reveals different functional contributions to visuomotor grasp. J Neurophysiol 98:488-501.

      10.7554/eLife.15278.024Author response

      Essential revisions:

      The reviewers thought that all comments deserve consideration by the authors. Particularly, the reviewers felt that analyzing the data as a function of the F5 subdivisions would strengthen the study further, particularly since the authors have followed such a strategy in previous work, and we'd hope that such analysis will be straightforward. In addition, the reviewers felt that there were interpretational issues with the role of area AIP that will deserve careful attention.

      Reviewer #1:

      The study by Schaffelhofer and Scherberger on "Object vision to hand action in macaque parietal, motor, and premotor cortices" reports novel findings on the roles of areas AiP, F5 and M1 in the transformation of visual information to motor action. Simultaneous recordings in these areas from arrays of electrodes were performed. The animals were trained on an excellent grasping task that used a variety of 3D objects and dissociated the different parts of a grasping task into its component parts (e.g. visual, motor planning, motor action). In addition to the use of sophisticated behavioral and recording protocols, the authors also used a glove to quantitatively measure kinematic aspects of grasping movements. The complex data from multiple areas and recording channels as well as movement parameters were analyzed in sophisticated ways to permit novel insight into the transformation of visual signals in areas AIP and F5 to motor planning and action in F5 and M1. I'll leave the detailed critique to the expert reviewer. In focusing on a larger picture in this particular area, I found this paper outstanding in all respects.

      Thank you for your extremely favorable evaluation of our paper in particular regarding the larger picture of this research topic.

      Reviewer #2:

      1) The main limit of this beautiful work is the assumption that area F5 is anatomo-functionally unitary. Recent literature not considered in this work shows that F5 is neither architectonically (Belmalih et al. 2009) nor connectionally (Gerbella et al. 2011) homogeneous: the ventral and anterior part of F5 (called F5a, where the most lateral arrays in the present study have been implanted), hosts 3D-shape-selective and "visual-dominant" neurons (Theys et al. 2012), commonly found also in AIP (Theys et al. 2013) but not in the dorsal part of F5 (i.e. F5p, see Bonini et al. 2014). Furthermore, while in the introduction the authors generally talk about "connections of F5 to the spinal cord and M1", this is true virtually only for F5p (Borra et al. 2010). Considering altogether data recorded from different F5 subdivisions was acceptable in the authors' previous paper (Schaffelhofer et al. 2015, J Neurosci), as its goal was to decode hand configurations, but not here, where the authors want to elucidate the functioning of the cortical grasping network.

      Floating micro-electrode arrays have the advantage of analyzing simultaneously recorded populations on the identical time-line, thereby creating new possibilities of analyzing neural data (e.g. trial-based analysis as shown in Figure 6, Figure 7, Figure 8). However, the technique has the disadvantage of static electrode positions (non-moveable). In other words, a large number of channels are required for acquiring a sufficient sample size of modulated neurons. Primarily for this reason, we have merged the recording sites within area F5 (F5p and F5a). However, we agree of course that F5 consists of specialized sub regions that we have now analyzed and visualized separately (see Figure 3 c,f). Specifically, we mapped all identified visual and visuomotor neurons in each of the six electrode arrays. As expected, we found significant differences between the F5 subdivisions consistent with the current literature and your comments. In contrast to F5a, F5p did not (monkey M) or only minimally (monkey Z) contribute to movement planning, but instead was modulated during movement execution.

      Beside the new Figure 3c,f, we changed the following parts of the manuscript:

      Introduction, second paragraph:

      “Connections of the dorsal subdivision of F5 (F5p) to the spinal cord and to M1 provide further evidence of the area’s important role in grasp movement preparation (Borra et al., 2010; Dum and Strick, 2005).“

      Motor planning and execution, last paragraph:

      “It is notable, that we found significantly different contributions in motor preparation between the F5 recording sites. The visual (Figure 3e-f) and visuomotor modulations (Figure 3b-c) prior to movement primarily originated from the ventral recording array, corresponding to the F5a subdivision (Gerbella et al., 2011; Theys et al., 2012a). In fact, 76% of the visual (abstract objects) and 72% of visuomotor tuned neurons (mixed objects) recorded from F5 were detected on the ventral site (ANOVA p<0.01, all sessions, tested in cue epoch), in line with previously reported enhanced decoding capabilities of planning signals from ventral F5 (Schaffelhofer et al., 2015a). In contrast, the dorsal F5 array, corresponding to F5p, mainly contributed during movement execution by a four-fold increase of its tuned population with respect to the cue epoch.”

      Feature coding in area F5, last paragraph:

      “As discussed above, premotor preparation activity primarily originated from the ventral F5 array. Thus, the modulations observed prior to movement execution, such as observed in the CDA and hierarchical clustering, mainly based on the ventral recording site. In contrast, both arrays significantly supported movement execution. The different modalities in both recording sites are in line with the architectonical (Belmalih et al., 2009) and connectionally (Borra et al., 2010; Gerbella et al., 2011) distinct subdivisions F5a and F5p, which largely correspond to the ventral and dorsal recording array, respectively. Distinct connections of F5a with SII, AIP and other subdivision of F5 (but not to M1) (Gerbella et al., 2011) suggest an integration of visual, motor and context specific information (Theys et al., 2013). On the other hand, connections of F5p to the hand area of M1 and to the spinal cord (Borra et al., 2010) suggest a rather direct contribution to hand movement control. Taken together, the multimodal preparation signals with visual and motor contribution and the distinct motor feature coding towards planning and execution supports the important role of F5 in visuomotor transformation.”

      2) Strictly related to this issue, the electrodes length is unknown. From the authors' previous works (Schaffelhoefer et al. 2015a and Townsend et al. 2011) I infer that "electrode length ranged from 1.5 to 7.1 mm", with the longest electrodes toward the sulcus. Thus, the more superficial electrodes of the lateral arrays certainly sampled F5c motor activity, likely related to mouth and hand movements, (see Graziano et al. 1997 and Maranesi et al. 2012), while the deepest electrodes most likely sampled F5p/a visuomotor activity. Please clarify.

      Thank you for reading the manuscript so carefully. We have now added the electrode length in the following sections:

      Legend of Figure 1: “…(f) Electrode placement in monkey Z (right hemisphere). Each array consisted of 2 ground and 2 reference electrodes (black), as well as 32 recording channels (white) aligned in a 4x9 matrix. Electrode length for each row increased towards the sulcus from 1.5 – 7.1 mm. (g) Same for monkey M (left hemisphere)…”.

      [Please note that Figure 1f-g has been adapted accordingly to illustrate individual channels]

      Chapter “Electrophysiological recordings”:

      “In each array, the lengths of the electrodes increased towards the sulcus and ranged from 1.5 (1st row) to 7.1mm (4th row). In area F5, one array was placed in the posterior bank of the inferior arcuate sulcus approximately targeting F5a (longer electrodes)(Theys et al., 2012) and approaching the F5 convexity (F5c; shorter electrodes). The second and more dorsally located array was positioned to target F5p. In AIP, the arrays were implanted into the end of the posterior intraparietal sulcus at the level of area PF and more dorsally at the level of area PFG. In M1, both arrays were placed into the hand area of M1 into the anterior bank of the central sulcus at the level of the spur of the arcuate sulcus (Rathelot and Strick, 2009)”.

      We believe that the updated Figure 12 and the corresponding updates in the text now provide full details of the location of the implanted electrodes.

      3) "Data have been analysed from 20 recording sessions (10 per animal)…". I don't understand how many (single and multi) units have been used for the analyses. It seems that a total of about 202 (units)*10 (sessions)=2020 and 355*10=3550 "units" have been considered in the two animals, respectively: with chronic recording this approach would certainly imply some resampling of the same "units" across sessions, increasing their number but reducing the variability of their discharge. At the same time, the authors stated in the Materials and methods section that "all dimensionality reduction results presented for the individual areas originated from the same recording session per monkey", which actually sounds fair, but in contrast with the previous consideration. Please clarify.

      Yes, we recorded in average 202 and 355 neurons from monkey Z and M, respectively (10 sessions per animal, see Results, paragraph 3). The reason we have not stated the summed number of neurons across sessions is exactly because of the resampling of neurons (due to the day-to-day stability of electrodes with respect to their position). The high unit counts you mentioned are correct (591 AIP + 677 M1 + 753 F5 cells = 2021 cells in animal Z, and 892 AIP, 1507 M1 and 1146 F5 cells = 3545 in animal M) but could potentially give the reader the incorrect impression about the sum of uniqueneurons and we therefore avoided them. Thus, to provide the fairest unit counts, we stated the average cell count per session and averaged analysis results accordingly (see Figure. 3, Figure 7, Figure 8).

      For results that reflect individual sessions, we have added the number of included cells to each individual Figure (please see Figure 2, 4, 5, and 6 and their corresponding supplements). For the single session analysis, we have explicitly mentioned “all dimensionality reduction results are from the same recording session” to make clear that we did not select the “best” representations we could find within 10 sessions for each of the individual areas (AIP, F5 and M1), but instead presented populations from the same recording session. This step should increase the comparability of results between individual areas.

      Moreover, we have made clear that single and multi-units have been analyzed together. See chapter “Electrophysiological recordings”, last sentence: “No other pre-selection was applied and single and multiunit activity have been analysed together.”

      The manuscript now provides detailed information for each analysis with respect to unit count.

      Somewhat related to your comment, we also solved a question that has been important to us. We added a variation of the hierarchical cluster analysis (HCA) in order to express the coding of task conditions across recording sessions (in addition to individual sessions). For this, we measured the Mahalanobis distance between each pair of group means (e.g., between condition 00 and 11) resulting in a 50 x 50 distance matrix. These matrices, observed from each individual session, were averaged across all recording sessions and then used as a basis for an across-session HCA. The resulting dendrograms are now shown as supplemental figures in addition to the results of individual example sessions (Figure 2 —figure supplement 12; Figure 5 —figure supplement 12, Figure 6 —figure supplement 12). The following sections of the manuscript were altered:

      Chapter “Hierarchical Cluster Analysis”, end of chapter:

      “Additionally, we averaged the Mahalanobis distance matrices of all individual session to build dendrograms expressing the N-space of an animal across all recording sessions (e.g. Figure 2 —figure supplement 1 for AIP of animal Z).”

      Chapter “Vision for hand action”, end of paragraph 3:

      “Importantly, consistent results were observed in both monkeys when performing HCA across all recording sessions (Figure 2 —figure supplement 12, see Materials and methods).”

      Chapter “Feature coding in area F5”, end of paragraph 7:

      “HCA performed on the averaged population response across all recording sessions (see Materials and methods) confirmed in both animals the motor characteristics of simultaneously recorded populations in single sessions (Figure 5 —figure supplements 12).

      Chapter “Feature coding in area M1”, last paragraph:

      “The similarity of J- and N-space of M1 was not only visible in the first two components, but was also quantified across all dimensions in the hierarchical cluster trees of the simultaneously recorded M1 population (Figure 6 d,f) and when averaging the population response across all recording sessions (Figure 6 —figure supplement 1-2 for monkey M and Z, resp.).”

      4) I recommend using the same y-axis scales for plots in figure 3 (b and d). Nevertheless, it is clear that the tuning profile of AIP does not change when abstract or mixed sets of objects are used (see Figure 3b and d): I totally understand the authors' reasoning, but they will acknowledge that all the abstract objects share an elongated shape, while those of the mixed set are much more variable. Thus, the lack of difference in the AIP tuning profile between the two sets is strange and should be better explained/discussed. For example, could it be due to receptive fields properties of AIP neurons (see Romero et al. 2014; Romero and Janssen 2016)?

      Thank you for pointing this out. We updated the y-axis scales according to your suggestion.

      The similar quantitative responses (in terms of percentage of significantly tuned neurons) for the abstract and mixed shapes, in our opinion, are not strange but strikingly extend our findings from the complete object set. We understand that a higher variation in object shape could have affected the number of tuned cells, in stark contrast to the observed minor differences presented in Figure 3. However, monkeys viewed the objects from the side, which substantially reduced the apparent visual uniformity of the abstract object set (less elongated profiles). Furthermore, we report in Figure 3 the percentage of significantly tuned neurons, and not, for example, the average tuning strength (e.g., the difference between the strongest and weakest response in each object set), which might have been a more sensitive measure for detecting absolute tuning differences between both object sets.

      Reviewer #3:

      Altogether, I consider the work exceptional. The data make new and important contributions to understanding the cortical mechanisms underlying grasp control. By concurrently recording and characterising the relationships between limb kinematics and neural activity from AIP, F5, and M1 while monkeys viewed and grasped a wide range of objects, the scope of the current investigation is unparalleled in the current primate neurophysiological literature. Also outstanding are the beautiful data visualisation methods that the authors advance here.

      I have a few suggestions, however, detailed below. My hope is that the authors will find these comments constructive.

      A) Main concerns:

      (A-1) The role of AIP

      I'm having some difficulty understanding the authors’ stance on the role of AIP. I believe they are arguing that their data suggest that AIP is encoding object properties in visual terms, and not in motoric terms. They suggest that the results of their CDA show that AIP encodes objects according to shape in visual space, independent of the way they are grasped.

      My interpretation of their stance is that AIP activity does not reflect action possibilities in sensorimotor terms – but rather reflects the 'flagging' of visual features relevant for actions, but NOT (yet) represented as spatiomotor plans.

      If this is indeed their stance, I see this as a significant departure from prior conceptualizations (Jeannerod et al., 1995).

      However, I remain confused about this argument, both (1) conceptually, and (2) with respect to how some aspects of their data can be viewed as consistent these claims.

      Thank you for your detailed thoughts that we found very constructive. Following your comments, we have clarified the interpretation/summary of AIP throughout the manuscript and highlighted the corresponding sections in green (see section “Vision for action”, paragraph 3 and 6, “Discussion”, paragraph 5-7). We hope that these revisions improve the general understanding of the AIP results and their interpretation. Here we first summarize our stance and then address point-by point your questions regarding concept and data:

      Grasping an object in different ways does not only require different motor plans, but also differentiated visual descriptions of the object. For example, when grasping a coffee cup, we need to create a geometrical description of the cup and an additional visual selection of its object parts (e.g., the handle) that we intend to grasp (e.g., perform a hook grip). Our data suggests that AIP is a dynamical visual area that might be responsible for differentiating and selecting these objects parts in a visual (geometrical) rather than in a motor space.

      1) Conceptually. The authors talk about "object affordances" as different from "motor affordances".

      To me, affordances = action possibilities; they are sensory representations of the external environment that are inseparably linked to the motor apparatus and capabilities of the perceiving animal. In other words, affordances are, according to my understanding, inextricably motor.

      What does it mean to "extract object affordances relevant for grasping", but to not at the same time encode those same objects according to the spatiomotor properties required for their manual interaction?

      They state: "…suggest encoding of object affordances rather than motor affordances".

      I urge the authors to better clarify what is meant by object vs. motor affordances.

      Your comment is directly related to comment (d) of Reviewer #2. With object affordances we intended to express the visual extraction of object features of an object part relevant for grasping. To avoid confusion, we replaced “object affordances” with “object features” throughout the manuscript.

      2) Data. Some aspects of AIP data suggest encoding related to motoric features.

      a) Shift for same object – big horizontal cylinders – when grasped from below vs. above.

      b) Significant differentiation of conditions 00 vs. 01.

      c) Motor similarity measures – Figure 7 – presumably a measure of.75 for AIP is different than a measure of "1" – and thus, does suggest some correspondence between N- and J-space encoding in AIP

      d) Also, there interpretation of Figure 3b vs. d – "…observed encoding of abstract objects in AIP can be explained exclusively by object shape."

      Is it not possible that these data may reflect the fact that abstract versus mixed object set have more graspable parts – a greater number of possible actions –, and AIP encoding is sensitive to these differences?

      This account could be considered consistent with the authors’ interpretations regarding the evidence for reduced tuning in AIP over time for abstract shapes: "…reduction of 3D shapes to the relevant parts for grasping…".

      Summary:

      While the authors seem to argue for a strict separation in roles between AIP and F5 – visual vs. motor, respectively – I see the data as more likely evidence for a continuum – a graded difference – visual prevalence in AIP, with motor encoding vs. motoric prevalence in F5, with visual encoding.

      I suggest that the authors clarify their stance, and/or temper their arguments.

      Describing the neural differentiation in cases a-b as motor features would be seductive and in agreement with current literature. However, in our opinion, this standpoint does not reflect the global view on our data. For the following reasons we interpret the observed modulations in AIP as a visual rather than a motoric differentiation:

      In both animals, the AIP population separated objects primarily on visual object attributes at the session- (Figure 2) and multi-session level (Figure 2 —figure supplement 12): objects clustered primarily based on visual attributes, such as shape and size, although they were grasped in highly different fashions. In contrast, motor attributes were rarely found.

      Differences with respect to the selected grip type were only apparent when the same object was grasped differently (e.g., handle box, horizontal cylinder), whereas all other objects maintained their shape clusters. In contrast, motor feature coding, as observed in F5 and M1, would separate all objects in motor terms (not only those that offer different object parts). This could indicate visual rather than motor processes for grasping.

      The separation of such conditions (handle, cylinder) originated from the same shape cluster (see Figure 2c and Author response image 1) also suggesting visual rather than motor transformations.

      10.7554/eLife.15278.022Visualization of (<bold>a</bold>) reduced and (<bold>b</bold>) complete population show perfectly overlapping clusters of small (black triangles, 51-54) and large cylinders (red triangles, 55-56) in the early cue phase (100 ms after cue onset).

      These conditions start separating over time as shown in Figure 2c,d and Figure 2e,f.

      DOI: http://dx.doi.org/10.7554/eLife.15278.022

      In d), the reviewer suggested that abstract objects might have more graspable parts, and hence a larger number of possible actions, than objects of the mixed set. However, we regard this as rather unlikely. Neither the grasp variability of both animals nor the visual aspect of the objects justifies the conclusion that abstract objects have more graspable parts. In fact, we specifically designed the abstract set such that objects have many different visual parts, but only one graspable part, which both animals also uniformly selected.

      However, we agree with Reviewer #3 that the visual and motor space cannot be separated completely, as we have discussed previously (Schaffelhofer et al. 2015). For example, coming from the motor side, Figure 6c-d shows the separation of objects based on the recorded hand kinematics. Although this is a pure motor representation of objects, some shapes tend to cluster together, such as the vertical cylinders or the cubes, due to the design of the objects that shape the hand. In other words, even a pure motor representation creates similarities with the visual space and vice versa.

      Taken together, and in agreement with reviewer #3, the differences between AIP and F5 can only be described as graded ones, with visual prevalence in AIP and motoric prevalence in F5. While we maintain our general interpretation of the AIP results, we tempered our arguments, as suggested. Both, visual and motor separation of objects is now discussed in the Results and Discussion section (we highlighted all text edits in the manuscript with respect to this comment in green).

      “Vision for hand action”, paragraph 3:

      “Hierarchical cluster analysis (HCA) performed on these distance measures confirmed the findings of the CDA and revealed a clear clustering according to object shape during visual presentation of the object (Figure 2e) that widely remained during movement execution, although with significantly shorter neural distances (Figure 2f).”

      “Vision for hand action”, paragraph 7:

      “This reduced selectivity could indicate either motor or visual transformations that are both required for grasping: First, the abstract objects were grasped with the same hand configuration (see Figure 3d). […] Together, these observations suggest a visual rather than motor representation in AIP.”

      “Discussion – Visual processing for grasping”, paragraph 3 and 4:

      “We emphasize that visual coding at the population level does not preclude motor coding of some individual cells, as suggested previously (Murata et al., 1997). Rather, the evidence of bidirectional connections to F5 suggests that subpopulations in AIP exist that reflect feedback motor signals from F5.”

      “These modulations could reflect either motor (Fagg and Arbib, 1998) or visual transformations required for grasping. […] These differentiation schemes support our hypothesis of visual rather than motor transformations in AIP.”

      B) Intermediate concerns

      B-1) in the Introduction, the authors state that prior work did not dissociate between visual and motor features. At first, I thought this was inconsistent with the work of Sakata and colleagues – describing visual dominant, visuomotor, and motor dominant cell types. I think some discussion of this work upfront, including how the current approach critically differs, would be helpful.

      Previous approaches separated neurons into visual, visuomotor and motor cells primarily based on their responses to objects in light or dark condition (activation or no activation). According to Sakata and co-workers, Motor dominant cells become activated during grasping and holding in both light and dark. They do not fire during object fixation. Visual-motor neurons discharge stronger during grasping in light than in the dark. Visual-dominant neurons discharge during object fixation and when grasping in light. Thus, the epoch of activation has been the main criteria for classification.

      Our work took a significantly different approach by comparing the coding (modulation patterns) of neurons and of neuronal populations with respect to highly variable objects and the measured hand kinematics in order to separate visual from motor processes. Our work demonstrated that activations in visual epochs can reflect motor processing, whereas grasp modulation can reflect object geometries.

      We followed your suggestion and entirely revised paragraph 4-6 of the Introduction:

      “To create a deeper understanding of how visual information is transformed into motor commands, a precise identification and differentiation of visual and motor processes within the grasping network is required. […] Our data revealed distinct roles of the grasping network in translating visual object attributes (AIP) into planning (F5) and execution signals (M1) and allowed visualizing the propagation of these features for grasping. “

      B-2) Introduction – last paragraph – it isn't clear to me what the authors mean to say here, without first reading the rest of the paper. I think this section could be made clearer.

      We revised the last paragraph accordingly (see above). We believe, that the concept and intention of our experiments are now better explained.

      B-3) I'm not sure I understand their explanation of the shape-specificity prior to fixation. Please try to make this clearer.

      Shape-specificity during the fixation epoch is likely due to our block design, in which we presented objects of similar shape on the same turntable. This fact is a small detail, however it could raise concerns on whether coding in AIP was really due to object shape, or rather to the object presentation order (different turntables presented sequentially). We revised our arguments to make this clearer:

      “The large number of objects presented in one recording session required separating the 48 objects on different turntables (see Figure 1), often objects of similar shape. This separation created small offsets already in the fixation epoch, but at very low modulations. An extreme case is shown in Figure 2a. This might raise concerns on whether coding in AIP was really due to object shape, or rather to the object presentation order (different turntables presented sequentially). However, shape-wise clustering in AIP cannot be explained by the task design for the following reasons: (1) The offsets in the fixation epoch were very small in comparison to the visual modulations observed in AIP when the objects were presented (e.g., see Video 5). (2) The set of “mixed” objects – presented and grasped in the same block – clustered with other objects of the same shape (e.g. ring in mixed block clusters with other ring objects). Together, this demonstrates clear shape processing in AIP.”

      B-4) At first I thought I missed something – it seemed as though AIP was not looked at in terms of J- and N-space encoding in the same way that F5 and M1 were. However, later it is clear that they did analyse AIP in the same way. Why not also show these data, as they do for F5 (Figure 4, 5) and M1 (Figure 6)?

      For the complete N-space the AIP, F5, and M1 populations were analyzed and visualized in the same way. In the reduced space the areas were visualized differently to represent the full dimensional space (hierarchical clustering) best. That is, showing the object separation of AIP in 3D to reveal the object-shape clusters best, whereas F5 and M1 populations were shown in 2D and aligned (rotated) to the J-space (with PCRA) to allow direct comparison of both representations next to each other. We believe that this kind of visualization reflects and explains the full-dimensional results best.

      B-5) Figure 4 – it is unclear to me why they plot J-space for the hold epoch and N-space for the grasp epoch; why not show results from the same epochs?

      Premotor area F5 provided higher modulations (separation of conditions) in the grasping epoch, when the hand was approaching the object. This is also shown and discussed in video 5, where you can see F5 expressions earlier than in M1. We therefore selected this epoch in area F5 to represent motor execution. However, all epochs, including the hold epoch, are shown below in Figure 4i.

      B-6) Figure 8 – and the authors' discussion of the driving influence of F5 on M1 activity – how do these findings relate to (Umilta et al., 2007; Spinks et al., 2008)? I think these studies should be explicitly discussed.

      We find both studies most helpful. Umilta et al. and Spinks et al. report similarity between F5 and AIP with respect to grasp coding at the LFP and single unit level in support of our feature code correlation results. We now discuss and reference their work in the following sections:

      Chapter “Feature coding in area M1”, first paragraph:

      “In agreement with the general population response (Figure 3b), single neurons of M1 were almost exclusively modulated during movement execution and showed minimal modulations during preparatory epochs (Umilita et al. 2007), as also indicated by the example neuron in Figure 6a-b.”

      “Discussion”, last paragraph:

      “The high similarity of the F5 and M1 population during movement execution (Figure 4h vs. 6e, Figure 8, and Video 5) is in agreement with findings of similar coding schemes between both areas in spiking (Umilta et al., 2007) and β-band LFP activity (Spinks et al., 2008).”

      Also, is it not surprising to find so little evidence for correspondence between AIP and F5 during planning?

      The applied analysis reflects the coding similarity between both areas, not their physical connectivity. In other words, when two areas share the same feature coding with respect to the 50 conditions the correlation coefficient increases. In fact, the correlation analysis results, although exploring the data with an entirely different method, match the identified visual and motor coding (and their proportion) from the population analysis. In detail, only an F5 subpopulation coded objects in visual terms, and therefore similar with respect to AIP (see Figure 3). This explains the relatively low feature-communication peaks between both areas, and demonstrates that the coding of objects is represented strongly differently in AIP and F5 during large parts of the task, although both areas are highly modulated by these objects. Please note that we would expect significantly higher feature communication between AIP and F5 when precisely targeting the F5a subdivision, which holds predominantly visual-dominant neurons, in comparison to F5p (Theys et al. 2012), and directly receives information from AIP (Gerbella et al. 2010).

      In response to your comment, we added the following sentences to chapter “Results/Feature code correlation”:

      “These results are consistent with the proportion of F5 visual cells identified in animal Z and M (Figure 3), which only temporarily shared the visual coding with AIP. Interestingly, F5 and AIP demonstrated minimal similarities during movement planning, which could support the different encoding of visual and motor features described on the population level (Figure 2, Figure 4,5).”

      How does the relationship between AIP and F5 that the authors suggest according to their new results compare with prior accounts – e.g. Jeannerod et al., 1995; Fagg and Arbib, 1998?

      Existing models of the grasping network share the same basic interpretation of the F5-AIP network as the main circuit for visuomotor transformation (Jeannerod et al., 1995, Fagg and Arbib, 1998, Rizzolati et Luppino, 2001). In support, our data provides important electrophysiological evidence that object features are indeed transformed into motor representations between both areas.

      Previous models were, however, uncertain on how and where visual information is exactly translated into motor commands and whether both areas perform both visual and motor computations. Fagg et Arbib (1998) and Rizzolatti et Luppino (2001) consider grasp transforms already in AIP. They propose that AIP is using the visual input to generate multiple affordances passed to F5, which selects the final grip type.

      Our data suggest a slightly different information flow in which visual and motor processes are organized more separately. In this understanding, AIP is responsible for providing object properties to F5 (F5a) thereby activating motor solutions that, in return to AIP, help further extracting geometrical features relevant for grasping. F5 with its connection to visual input (F5a) and motor output (F5p), could be the main hub for coordinating visual feature extraction with AIP and motor planning and subsequent execution with M1.

      We believe that our edits in response to this reviewer’s comment a) (see above) addresses this question.

      How do the authors interpret the increased AIP-M1 correspondence during grasp and hold?

      This comment is related to comment (1b)-d. As discussed above, visual representations of objects and motor features of the hand cannot be entirely disassociated, because the object geometries define the shape of the grasping hand. Even pure motor representations, such as the recorded hand kinematics, can therefore share similarities with an object space. When M1 changes from a mostly unmodulated (planning) to a highly modulated state (grasp epoch) the similarity to an object space increases. In other words, we interpret the increase of similarity as a result of the highly increased modulations in M1.

      B-7) What do the authors mean by the statement regarding M1 on p.26 "…its neuronal population has never been studied explicitly"? What about, for e.g., the work of Umilta et al., 2007; Spinks et al., 2008?

      We tempered this statement: “Although the motor relevance of the hand area of M1 has been described extensively with electrophysiological (Schieber, 1991; Schieber and Poliakov, 1998; Spinks et al., 2008; Umilta et al., 2007) and anatomical methods (Dum and Strick, 2005; Rathelot and Strick, 2009), it has been unclear how versatile hand configurations are encoded at the population level.”

      \ No newline at end of file diff --git a/examples/data/example.xml b/examples/data/example.xml new file mode 100644 index 000000000..3f6883901 --- /dev/null +++ b/examples/data/example.xml @@ -0,0 +1,135 @@ + + +
      + + + + + ORIGINAL RESEARCH ARTICLE Survival of Sami and non Sami cancer patients in Finnish Lapland + + + + Leena Soininen + leena.soininen@fimnet.fi + 2 + + + Arun Pokhrel + 1 + + + Tadek Dyba + 1 + + + Eero Pukkala + 0 + 1 + + + Timo Hakulinen + 1 + + + + School of Health Sciences, University of Tampere + , + Tampere + , + Finland + + + + Finnish Cancer Registry, Institute for Statistical and Epidemiological Cancer Research + , + Helsinki + , + Finland + + + + University of Helsinki + , + Helsinki + , + Finland + + + + + 25 + 5 + 2012 + + + 20 + 12 + 2011 + + + 25 + 4 + 2012 + + + + + + +

      ABSTRACT

      +

      Objectives. The incidence of cancer among the indigenous Sami people of Northern Finland is lower than among the Finnish general population. The survival of Sami cancer patients is not known, and therefore it is the object of this study.

      +

      Study design. The cohort consisted of 2,091 Sami and 4,161 non-Sami who lived on 31 December 1978 in the two Sami municipalities of Inari and Utsjoki, which are located in Northern Finland and are 300-500 km away from the nearest central hospital. The survival experience of Sami and non-Sami cancer patients diagnosed in this cohort during 1979-2009 was compared with that of the Finnish patients outside the cohort.

      +

      Methods. The Sami and non-Sami cancer patients were matched to other Finnish cancer patients for gender, age and year of diagnosis and for the site of cancer. An additional matching was done for the stage at diagnosis. Cancer-specific survival analyses were made using the Kaplan-Meier method and Cox regression modeling.

      +

      Results. There were 204 Sami and 391 non-Sami cancer cases in the cohort, 20,181 matched controls without matching with stage, and 7,874 stage-matched controls. In the cancer–specific analysis without stage variable, the hazard ratio for Sami was 1.05 (95% confidence interval 0.85–1.30) and for non-Sami 1.02 (0.86–1.20), indicating no difference between the survival of those groups and other patients in Finland. Likewise, when the same was done by also matching the stage, there was no difference in cancer survival.

      +

      Conclusion. Long distances to medical care or Sami ethnicity have no influence on the cancer patient survival in Northern Finland.

      +

      + (Int J Circumpolar Health 2012) +

      +

      Keywords: Sami, cancer, cancer survival, arctic population

      +

      INTRODUCTION

      +

      The Sami are the indigenous people of Northern Finland, Sweden, Norway and Russia. Today there are about 70,000 Sami in these countries. In Finland, there were about 10,000 Sami in the year 2011, when they were counted for the election of the Sami Parliament. More than 65% of them were living outside of their traditional homeland, which consists of the three northernmost municipalities of Finland - Inari, Utsjoki, Enontekiö, and the northern part of the Sodankylä municipality. In the Inari municipality, there are three Sami groups - Inari Sami, Skolt Sami and Northern Sami - all with cultural, linguistic and health differences. In the same area, there are also non-Sami, some families have been there already for several generations. Utsjoki is the only municipality in Finland with a Sami majority. The living habits of the Sami nowadays are rather similar to those of the non-Sami, because both of them have been influenced from the other. The Sami are genetically different from the rest of the Finnish population. Until about 1960s, the Finnish Sami were rather isolated and did not get many stimuli and influences from outside (1).

      +

      The disease pattern of the Sami differs from that of the general population in their countries and from the non-Sami in the same area (1-10). The mortality and cancer incidence of the Sami groups have been studied previously, and hence it is known that the Finnish Sami groups have cancer incidence patterns that are different from each other and from the non-Sami population (4,10). The cancer incidence of the Sami was significantly lower (SIR 0.64) than that of the Finnish general population and also lower than that of the non-Sami population in the same region (4). On the other hand, the total mortality of the Sami was higher due to non-disease mortality (10). It is not known if the survival of the Sami cancer patients differs from that of the general population. The survival of the non-Sami cancer patients from the same area has not been studied, either.

      +

      Until the 1990s the nearest oncologist worked in Oulu University Hospital and consulted from time to time in the main hospital of Lapland (Lapland Central Hospital) in Rovaniemi. The most remote village in “Samiland” is Nuorgam, about 500 km from Rovaniemi and 700 km from Oulu.

      +

      The aim of the study is to assess cancer patient survival among the Sami and non-Sami living hundreds of kilometers north from the nearest central hospital, and to compare it with the survival experience of average Finnish cancer patients. This setting allows estimation of the impacts of long distance, and of factors related to genetic background and/or lifestyle of the Sami to the survival of the cancer patients.

      +

      MATERIAL AND METHODS

      +
      + + The cohort +

      All persons living in two Sami municipalities in northernmost Finland (Inari and Utsjoki) on 31 December 1978 were identified from the Finnish Population Information System. The Sami were identified by using the material of the Finnish International Biological Program, Human Adaptability section. Those data were produced by interviewing the Sami themselves and by genealogical sources (1,11). In the current study, a person representing at least 75% of any ethnic subgroup of Sami was classified as a Sami. A non-Sami is a person without any Sami ethnicity. The mixed group with 1-25% of Sami ethnicity was excluded. Because of historical computational reasons, the non-Sami were restricted to those born between the 1st and 24th day of any month of any year. The final cohort consisted of 2,091 Sami and 4,161 non-Sami people.

      +

      All persons in this cohort had personal identity codes given to all residents who have lived in Finland in 1967 or later and used in all person registers in Finland. The cohort was updated from Statistics Finland with information on dates and causes of death up to 31 December 2009. Dates of emigration were obtained from the National Population Register. The cohort was also linked with the Finnish Cancer Registry including incident cancer cases diagnosed during 1979-2009.

      +
      + + Statistical analyses +

      Cancer-specific survival analysis was employed. The outcome is a net survival measure representing survival from a specified cause of death, in this case the patient`s cancer, in the absence of other causes of death. The survival times of individuals who died from causes other than those specified are considered to be censored.

      +

      The cancer-specific survival experience of patients classified as Sami and non-Sami was compared with that of the Finns outside the cohort. The 5-year cancer-specific survival was estimated only for all cancers combined because of the small numbers of individual cancers.

      +

      To produce comparative cancer-specific survival figures, the Sami cancer patients were matched to other Finnish cancer patients obtained from the Finnish Cancer Registry with respect to site, gender, age at diagnosis and year of diagnosis, and in a separate analysis also with respect to the stage. The stage was analyzed in five categories: (i) localized; (ii) regional; (iii) distant; (iv) non-localized, not known whether regional or distant; and (v) unknown. All available controls were accepted into the analyses. A similar matching was also made for non-Sami cancer patients.

      +

      Cancer-specific analyses were conducted using the matched Cox regression model (12). Weighted survival analyses were made separately for Sami and Non-Sami cancer patients using the Kaplan-Meier method. The weight for each matched control was calculated as the inverse of the number of controls for each case (i.e., weight = 1/number of controls for each case). The statistical software STATA was used to calculate 5-year cumulative weighted cause-specific survival figures.

      +

      In addition to the cancer-specific analyses, regular matched overall or all-cause survival analyses were also performed, disregarding the cause of death information.

      +

       RESULTS

      +

      There were 204 cancer cases in the Sami cohort, 391 in the non-Sami cohort. The number of controls was 20,181 when cancer patients were matched with respect to site, gender, age at diagnosis and year of diagnosis and 7,874 when also matched with respect to stage. Survival until 5 years after diagnosis was first compared without considering the stage and later also matching for stage.

      +

      In the cancer-specific analysis without stage variable, the hazard ratio for Sami was 1.05 (95% CI 0.85–1.30) and for non-Sami 1.02 (0.86–1.20). When the Sami cancer patients were also matched according to the stage of the cancer, the cancer-specific analyses gave a hazard ratio for the Sami 1.02 (0.78–1.33) and for the non-Sami 1.10 (0.91–1.33).

      +

      The hazard ratios in the all-cause observed 5-year survival analysis were 1.13 (0.94–1.37) for the Sami and 0.97 (0.84–1.12) for the non-Sami.

      +

      In the survival curves (Figure 1.) a small difference can be seen between survival of the Sami and matched controls. This difference, however, is not statistically significant as the numbers above show. The survival curves for the non-Sami and matched controls are practically identical. The curves of Sami and non-Sami and their matched controls run at different levels in the figures.

      +
      + + [Place Figure 1 about here] +

      DISCUSSION

      +

      This is the first assessment of the cancer survival of the Sami. Only the survival of all sites of cancer could be assessed because of the low number of cancer cases. Because the different Sami groups could only be assessed together due to the small numbers of cancer cases in each of them, the possible survival differences between the Sami categories could not be assessed.

      +

      The starting assumption of this study was that both genetic or lifestyle features of the Sami, and long distances to the medical care and to hospitals could have an influence on the survival of cancer. The results, however, do not support these hypotheses.

      +

      About half of the Sami people in this cohort were born before 1950, and hence have been living according to the traditional Sami culture. The main livelihoods were reindeer herding, fishing and hunting. The quality of food was healthy, including reindeer meat, fish and berries. Before the era of cars and other motor vehicles, the Sami had to do a lot of exercise. The increased communication between the Sami area and other districts brought along more smoking, alcohol drinking, and unhealthy eating habits, but also a higher living standard, better health care and facilities, making life easier. Finnish legislation since 1969 has made it possible to get a 75% subsidy for the costs for building new reindeer farms, and in that way affecting the well-being and health of reindeer herders. The Skolt Sami have their own legislation, which helps their living conditions. From the 1970s, the ways of life of the Sami and the non-Sami have been very much alike, also with regard to how they seek health services.

      +

      There is very little cancer survival data concerning arctic indigenous populations. A publication from the USA describes and compares cancer-specific survival ratios of patients of six major racial or ethnic groups during the years 1975-1997 in the USA (13). In 1975-1987, the cancer survival ratio of American Indian and Alaskan Native patients was the lowest; 25% in males and 36% in females (13). The respective ratios for the non-Hispanic Whites were 35% and 46%. Although the 5-year survival ratios of cancer patients during 1988-1997 in any group were more favorable than in 1975-1987, the differences between ethnic groups persisted. An 11 percent-unit lower all-site cancer survival ratio was reported in a comparison between the Alaska Natives and the USA Caucasian cancer patients in 1984-1994 (14). There are no data on the survival of Sami cancer patients before 1979. However, the mortality/incidence ratios in the Northernmost Finland in the 1950s suggest that the survival of cancer patients in that area was worse than in the rest of Finland, but the difference disappeared before the 1970s, thanks to a more rapid decrease in the mortality/incidence ratio in the North (15). It is likely that the survival of patients with cancer (and other diseases) improves when the living standard increases and the living conditions get better. They are rather good today in Finnish Lapland. One has to remember that the living circumstances such as distances, living standards, and social situations of Indians and Alaskan natives are quite different from those of the Sami in Finland.

      +

      The explanation for the similar cancer survival of Sami and non-Sami and the Finnish population might be the similar possibilities to get physician consultations and care everywhere in Finland. When the sickness insurance act came into force 1964, it recognized the need for travelling to the medical doctor. From that time on it was possible to get reimbursement for travelling costs. For those who lived far from services (health center, shops, banks etc.), it was practical to also manage other things such as shopping when coming to visit the doctor. Hence, the threshold to visit the doctor was rather low, similarly for the Sami and non-Sami from the Northernmost Finland.

      +

      In the past, language has been a problem, because all the three Sami groups in Finnish Lapland speak different Sami languages, and it is clear that physicians and public health nurses, who came from the South did not speak Sami at all, and Sami nurses spoke only their own Sami language. The Utsjoki municipality later got Northern-Sami speaking general practitioners (GP) and nurses. Today all Sami are bilingual; they understand and speak Finnish. Inari has three official Sami languages and Utsjoki one. Health care workers receive a salary increment if they speak a Sami language.

      +

      When the Public Health Act came into force in 1972, it was a big step towards better health care, especially in the sparsely populated rural areas. New health centers, often with beds, were built, more posts for medical doctors and other staff were established, and especially, the health education and early detection of diseases was prioritized. The equality in health care should have been realized, providing the same system and same rules for everybody. In the Inari health center during the time of this study, there were 6 GP posts and 35 beds. The health center in Utsjoki has 1.5 GP posts and 15 beds. A local deviation or application from the Public Health Act was that the doctors met patients not only in health centers but also in remote Sami villages. The patients did not need to travel, because the GP travelled. When travelling to the remote villages, the GP also made home visits on the way.

      +

      In the Inari municipality and partly also in Utsjoki, there were the same GPs working from the beginning of the 1970s until they gradually retired from 2005. These GPs knew well the population and circumstances, which benefits the early diagnosing of diseases, also cancer. There was not a high threshold to contact the GP in case of symptoms. The Sami and non-Sami in Utsjoki and Inari had all possibilities for early detection, which is an important reason for better survival. From the present study we see that there was no difference between the results with and without adjustment for the stage.

      +

      When the nearest central hospital in Rovaniemi got its own oncologist in the beginning of 1990s, most cancer patients no longer needed to travel to Oulu (another 200 km further), unless a specialized treatment such as radiotherapy was required. Because of the experienced GPs and good cooperation with the central hospital oncologist, it was possible to follow the treatment plan in the local health center and carry out such cancer treatments (e.g. chemotherapy), which normally are implemented in central hospitals. Special investigations such as tomography, MRI and ultrasound were done in the central hospital.

      +

      The survival curves of the Sami cancer patients and their control cancer patients - matched according to sex, age and cancer type - were on a lower level than the respective curves for the non-Sami and their controls (Figure). The reason for this difference is the different cancer type distribution of the Sami and non-Sami. The Sami have a lower incidence of cancers with high survival (cancers of the skin, breast, prostate, testis, kidney, bladder and thyroid, and Hodgkin lymphoma) than the non-Sami, while the incidence of more lethal common cancer types such as stomach cancer or lung cancer is not lower (4). The Sami persons were also older than the non-Sami, and older cancer patients tend to have lower relative survival rates than young ones.

      +

      There was no difference between the all-cause survival of Sami and non-Sami and other patients in Finland. The higher mortality hazard in the Sami patients may well also reflect a higher mortality from the other causes of death (10), which may as well be partly due to the higher age of the Sami compared to the non-Sami.

      +

      During the study period (1979-2009), the survival of cancer patients in the far north has been the same as in Finland generally. That concerns both Sami and non-Sami patients, which means that neither long distances in Finland nor ethnic background have an effect on surviving. These results might also tell something about good and persistent patient-physician relationships (early detection), which are known to advance the surviving of all diseases.

      +

      Figure 1. Cumulative cancer-specific survival curves of all cancer sites combined for the Sami and non-Sami cancer patients in Inari and Utsjoki compared with controls of Finnish population, matched with respect to site, gender, age at diagnosis and year of diagnosis.

      +
      + + + HasslerSvenSjĂślanderPerBarnekow-BergkvistMargaretaKadesjĂśAndersEuropean Journal of Epidemiology2001969976SoininenLeenaJärvinenSariPukkalaEeroCancer incidence among Sami in Northern Finland, 1979-1998International Journal of Cancer2002-may342346HaldorsenTTynesTCancer in the Sami population of North Norway, 1970–1997European Journal of Cancer Prevention2005-feb6368HasslerSvenSoininenLeenaSjĂślanderPerPukkalaEeroCancer among the Sami–a review on the Norwegian, Swedish and Finnish Sami populationsInternational Journal of Circumpolar Health2008-decHasslerSvenSjĂślanderPerGrĂśnbergHenrikJohanssonRobertDamberLenaCancer in the Sami population of Sweden in relation to lifestyle and genetic factorsEur J Epidemiol2008-mar273280HasslerSvenSjĂślanderPerGrĂśnbergHenrikJohanssonRobertDamberLenaCancer in the Sami population of Sweden in relation to lifestyle and genetic factorsEur J Epidemiol2008-mar273280TynesToreHaldorsenTorMortality in the Sami population of North Norway, 1970-98Scandinavian Journal of Public Health2007306312SoininenLeenaPukkalaEeroMortality of the Sami in northern Finland 1979-2005International Journal of Circumpolar Health2008-marPrenticeRossLIntroduction to Cox (1972) Regression Models and Life-TablesSpringer Series in StatisticsSpringer Science $\mathplus$ Business Media1992519526CleggLiminXLiFrederickPHankeyBenjaminFChuKennethEdwardsBrendaKCancer Survival Among US Whites and MinoritiesArch Intern Med2002-sepAWErikssonAnthropology and health in Lapps. Coll Antropol 1988:2(12):197-235.1. Eriksson AW. Anthropology and health in LappsColl Antropol19882WiklundKLEHolmEklundGMortality among Swedish reindeer breeding Lapps in 1961–85. Arctic Med Res 1991;50(1):3-7.2. Wiklund1991NickulESuomen saamelaiset vuonna 1962 [The Sami of Finland in the year 1962]. Master’s graduate study. Helsinki:Finnish].11. Nickul E. Suomen saamelaiset vuonna 1962 [The Sami of Finland in the year 1962]. Master’s graduate study1968PukkalaEPatamaTSmall-area based map animations of cancer incidence in the Finland, 1953-2008. Helsinki: Finnish Cancer Registry;2010HGWelchLMSchwartzVoloshinSAre increasing 5-year survival rates evidence of success against cancer? JAMA 2000;283(22):2975-2978. [Author: Is this reference cited in the text?Please check]Leena SoininenUniversity of HelsinkiVyökatu 2 B 35FI-00160 HelsinkiFINLANDEmail: leena.soininen@fimnet.fi + +
      diff --git a/examples/publisher/app.js b/examples/publisher/app.js index 02b63aa7e..2f05b2756 100644 --- a/examples/publisher/app.js +++ b/examples/publisher/app.js @@ -35,7 +35,7 @@ if (typeof window !== 'undefined') { configurator.import(Package) var app = App.mount({ configurator: configurator, - documentId: 'elife-00007' + documentId: 'elife-15278' }, document.body) window.app = app }; diff --git a/packages/jats/xref/getXRefTargets.js b/packages/jats/xref/getXRefTargets.js index 14aac3347..cee0e6d39 100644 --- a/packages/jats/xref/getXRefTargets.js +++ b/packages/jats/xref/getXRefTargets.js @@ -7,7 +7,8 @@ import orderBy from 'lodash/orderBy' var TARGET_TYPES = { 'fig': ['figure', 'fig-group'], 'bibr': ['ref'], - 'table': ['table-wrap'] + 'table': ['table-wrap'], + 'other': ['figure'] }; /* diff --git a/packages/publisher/Publisher.js b/packages/publisher/Publisher.js index 450614d6d..df1807419 100644 --- a/packages/publisher/Publisher.js +++ b/packages/publisher/Publisher.js @@ -47,7 +47,7 @@ class Publisher extends AbstractWriter { var layout = $$(Layout, { width: 'large' - }); + }) var ArticleComponent = this.componentRegistry.get('article') From 2f94424ad8757b70a8c6422128c731e854374449 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 28 Sep 2016 12:36:24 +0200 Subject: [PATCH 103/167] Improve fullName extraction. --- util/getFullName.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/util/getFullName.js b/util/getFullName.js index d2a106be9..41e296102 100644 --- a/util/getFullName.js +++ b/util/getFullName.js @@ -5,16 +5,16 @@ import toDOM from './toDOM' name or string-name nodes (e.g. contrib, mixed-citation, element-citation) */ function getFullName(node) { - var el = toDOM(node); - var name = el.find('name'); - var stringName = el.find('string-name'); + var el = toDOM(node) + var name = el.find('name') + var stringName = el.find('string-name') if (name) { - var surname = name.find('surname').text(); - var givenNames = name.find('given-names').text(); - return [givenNames, surname]; + var surname = name.find('surname').text() + var givenNames = name.find('given-names').text() + return [givenNames, surname].join(' ') } else if (stringName) { - return stringName.text(); + return stringName.text() } } From 06cf0f267509b5477da2588173f9e5ab1a60184f Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 28 Sep 2016 13:00:00 +0200 Subject: [PATCH 104/167] Fix button styles for EditXML. --- packages/common/_edit-xml.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/_edit-xml.css b/packages/common/_edit-xml.css index 8c32cec6d..8bf9c0696 100644 --- a/packages/common/_edit-xml.css +++ b/packages/common/_edit-xml.css @@ -8,6 +8,6 @@ } .sc-edit-xml .se-tag { opacity: 0.5; } .sc-edit-xml .se-actions { padding-top: 20px; } -.sc-edit-xml .se-actions .sc-button { margin-right: 20px; } +.sc-edit-xml .se-actions .sc-button { margin-right: 20px; display: inline-block; } .sc-xml-attribute-editor textarea { width: 100%; height: 100px; } .sc-xml-editor textarea { width: 100%; height: 270px; } From afdcbbf967c088f6467d42da0268d3ee1398778e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 28 Sep 2016 20:01:23 +0200 Subject: [PATCH 105/167] Updated linter config. --- .eslintrc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index 10a9af88f..79b4a65ca 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -127,6 +127,6 @@ module.exports = { "no-undef-init": 2, "no-undefined": 0, "no-unused-vars": 2, - "no-use-before-define": [2, { "functions": false }] + "no-use-before-define": [2, { "functions": false, "classes": false }] } }; \ No newline at end of file From f71069293f36e041539336cac185003e1a0b74a9 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 28 Sep 2016 20:01:53 +0200 Subject: [PATCH 106/167] ES6ified tests. --- test/jats/JATSExporter.test.js | 7 +- test/jats/article.test.js | 4 +- test/jats/back.test.js | 4 +- test/jats/body.test.js | 4 +- test/jats/bold.test.js | 4 +- test/jats/caption.test.js | 4 +- test/jats/contrib.test.js | 4 +- test/jats/createJATSConfigurator.js | 5 +- test/jats/ext-link.test.js | 4 +- test/jats/figure.test.js | 4 +- test/jats/footnote.test.js | 4 +- test/jats/front.test.js | 4 +- test/jats/graphic.test.js | 4 +- test/jats/inline-wrapper.test.js | 7 +- test/jats/italic.test.js | 4 +- test/jats/label.test.js | 6 +- test/jats/monospace.test.js | 4 +- test/jats/paragraph.test.js | 7 +- test/jats/ref-list.test.js | 4 +- test/jats/ref.test.js | 4 +- test/jats/section.test.js | 4 +- test/jats/subscript.test.js | 4 +- test/jats/superscript.test.js | 4 +- ...table-wrap.test_.js => table-wrap.test.js} | 4 +- test/jats/table.test.js | 4 +- test/jats/test.js | 100 +++++++++--------- test/jats/testTextNode.js | 28 +++-- test/jats/title.test.js | 6 +- test/jats/unsupported.test.js | 4 +- test/jats/xref.test.js | 4 +- 30 files changed, 122 insertions(+), 132 deletions(-) rename test/jats/{table-wrap.test_.js => table-wrap.test.js} (79%) diff --git a/test/jats/JATSExporter.test.js b/test/jats/JATSExporter.test.js index 9b1318640..0b40d8c65 100644 --- a/test/jats/JATSExporter.test.js +++ b/test/jats/JATSExporter.test.js @@ -1,9 +1,8 @@ -'use strict'; - -var test = require('./test').module('jats/JATSExporter'); - +import { module } from './test' import createJATSConfigurator from './createJATSConfigurator' +const test = module('jats/JATSExporter') + test('Exporting a node via id', function(t) { var configurator = createJATSConfigurator(); var doc = configurator.createArticle(function(doc) { diff --git a/test/jats/article.test.js b/test/jats/article.test.js index 4827726fa..dc93a1371 100644 --- a/test/jats/article.test.js +++ b/test/jats/article.test.js @@ -1,6 +1,6 @@ -'use strict'; +import { module } from './test' -var test = require('./test').module('jats/article'); +const test = module('jats/article') // attributes should be preserved var withAttributes = diff --git a/test/jats/back.test.js b/test/jats/back.test.js index 4a6082ee0..7d2a605b7 100644 --- a/test/jats/back.test.js +++ b/test/jats/back.test.js @@ -1,6 +1,6 @@ -'use strict'; +import { module } from './test' -var test = require('./test').module('jats/back'); +const test = module('jats/back') // attributes should be preserved var withAttributes = diff --git a/test/jats/body.test.js b/test/jats/body.test.js index 666801203..26fdac6c0 100644 --- a/test/jats/body.test.js +++ b/test/jats/body.test.js @@ -1,6 +1,6 @@ -'use strict'; +import { module } from './test' -var test = require('./test').module('jats/body'); +const test = module('jats/body') // attributes should be preserved var withAttributes = diff --git a/test/jats/bold.test.js b/test/jats/bold.test.js index 4919eb291..94141c6df 100644 --- a/test/jats/bold.test.js +++ b/test/jats/bold.test.js @@ -1,6 +1,6 @@ -'use strict'; +import { module } from './test' -var test = require('./test').module('jats/bold'); +const test = module('jats/bold') var withAttributes = ' 1) { - whiteList = Array.prototype.slice.call(arguments, 0); + whiteList = Array.prototype.slice.call(arguments, 0) } else if (!isArray(whiteList)) { - whiteList = [whiteList]; + whiteList = [whiteList] } - whiteList.push('unsupported'); + whiteList.push('unsupported') converters = converters.filter(function(entry, name) { - return includes(whiteList, name); - }); + return includes(whiteList, name) + }) } - config.converters = converters; - var importer = new JATSImporter(config); - importer.createDocument(); - return importer; - }; - - this.createExporter = function() { - return this.configurator.createExporter('jats'); - }; + config.converters = converters + var importer = new JATSImporter(config) + importer.createDocument() + return importer + } -}; + createExporter() { + return this.configurator.createExporter('jats') + } -oo.initClass(JATSFixture); +} -export default test; diff --git a/test/jats/testTextNode.js b/test/jats/testTextNode.js index be9538dd0..2efc43a50 100644 --- a/test/jats/testTextNode.js +++ b/test/jats/testTextNode.js @@ -1,21 +1,19 @@ -'use strict'; - export default function(test, tagName, type) { - type = type || tagName; - var fixture = '<'+tagName+'>abcdefghi'; + type = type || tagName + var fixture = '<'+tagName+'>abcdefghi' test.withFixture(fixture, 'Importing/exporting <'+tagName+'>', function(t) { // import - var importer = t.fixture.createImporter([type, 'bold']); - var node = importer.convertElement(t.fixture.xmlElement); + var importer = t.fixture.createImporter([type, 'bold']) + var node = importer.convertElement(t.fixture.xmlElement) // HACK: still we need to call this, otherwise annotations // are not created - importer._createInlineNodes(); - t.equal(node.getText(), 'abcdefghi', 'text content should have been imported correctly'); + importer._createInlineNodes() + t.equal(node.getText(), 'abcdefghi', 'text content should have been imported correctly') // export - var exporter = t.fixture.createExporter(); - var el = exporter.convertNode(node); - t.ok(el.is(tagName), 'exported element should be a <'+tagName+'> element'); - t.equal(el.innerHTML, 'abcdefghi', 'nodes content should be exported'); - t.end(); - }); -}; \ No newline at end of file + var exporter = t.fixture.createExporter() + var el = exporter.convertNode(node) + t.ok(el.is(tagName), 'exported element should be a <'+tagName+'> element') + t.equal(el.innerHTML, 'abcdefghi', 'nodes content should be exported') + t.end() + }) +} diff --git a/test/jats/title.test.js b/test/jats/title.test.js index ea131bbfd..95decb4ce 100644 --- a/test/jats/title.test.js +++ b/test/jats/title.test.js @@ -1,8 +1,8 @@ -'use strict'; - -var test = require('./test').module('jats/title'); +import { module } from './test' import testTextNode from './testTextNode' +const test = module('jats/title') + var withAttributes = 'Introduction'; diff --git a/test/jats/unsupported.test.js b/test/jats/unsupported.test.js index dc0085532..523f8ba11 100644 --- a/test/jats/unsupported.test.js +++ b/test/jats/unsupported.test.js @@ -1,6 +1,6 @@ -'use strict'; +import { module } from './test' -var test = require('./test').module('jats/unsupported'); +const test = module('jats/unsupported') // attributes should be preserved var withAttributes = diff --git a/test/jats/xref.test.js b/test/jats/xref.test.js index a60aede9f..82a2c68d7 100644 --- a/test/jats/xref.test.js +++ b/test/jats/xref.test.js @@ -1,6 +1,6 @@ -'use strict'; +import { module } from './test' -var test = require('./test').module('jats/xref'); +const test = module('jats/xref') // attributes should be preserved var withAttributes = From d4225c60f20ddb12649d566ca715088118e7af11 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 28 Sep 2016 20:02:07 +0200 Subject: [PATCH 107/167] Added test index file --- test/index.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 test/index.js diff --git a/test/index.js b/test/index.js new file mode 100644 index 000000000..5394d1e0e --- /dev/null +++ b/test/index.js @@ -0,0 +1,27 @@ +import "./jats/article.test.js" +import "./jats/back.test.js" +import "./jats/body.test.js" +import "./jats/bold.test.js" +import "./jats/caption.test.js" +import "./jats/contrib.test.js" +import "./jats/ext-link.test.js" +import "./jats/figure.test.js" +import "./jats/footnote.test.js" +import "./jats/front.test.js" +import "./jats/graphic.test.js" +import "./jats/inline-wrapper.test.js" +import "./jats/italic.test.js" +import "./jats/JATSExporter.test.js" +import "./jats/label.test.js" +import "./jats/monospace.test.js" +import "./jats/paragraph.test.js" +import "./jats/ref-list.test.js" +import "./jats/ref.test.js" +import "./jats/section.test.js" +import "./jats/subscript.test.js" +import "./jats/superscript.test.js" +import "./jats/table.test.js" +// import "./jats/table-wrap.test.js" +import "./jats/title.test.js" +import "./jats/unsupported.test.js" +import "./jats/xref.test.js" From a35be8ae71e30169af65497b228b23211f947c5c Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 28 Sep 2016 20:02:38 +0200 Subject: [PATCH 108/167] Extended makefile for building tests --- .travis.yml | 2 +- make.js | 42 ++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +++-- test.js | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 test.js diff --git a/.travis.yml b/.travis.yml index 0a6525d2b..2473ccc3e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,6 @@ cache: directories: - node_modules node_js: - - "4" + - "6" before_script: - 'npm install' diff --git a/make.js b/make.js index dd11fca14..d7c60461c 100644 --- a/make.js +++ b/make.js @@ -43,6 +43,48 @@ b.task('examples', ['author', 'publisher', 'tagging']) // build all b.task('default', ['examples']) + +b.task('test:clean', function() { + b.rm('dist/test') +}) + +b.task('test:assets', function() { + b.copy('./node_modules/substance-test/dist/*', './dist/test', { root: './node_modules/substance-test/dist' }) +}) + +b.task('test:browser', function() { + b.js('./test/index.js', { + // buble necessary here, as travis has old browser versions + buble: true, + ignore: ['substance-cheerio'], + external: ['substance-test', 'substance'], + commonjs: { include: ['node_modules/lodash/**'] }, + targets: [ + { dest: './dist/test/tests.js', format: 'umd', moduleName: 'tests' } + ] + }); +}) + +b.task('test:server', function() { + b.js('./test/index.js', { + // buble necessary here, for nodejs + buble: true, + external: ['substance-test', 'substance'], + commonjs: { + include: [ + 'node_modules/lodash/**', + 'node_modules/substance-cheerio/**' + ] + }, + targets: [ + { dest: './dist/test/run-tests.js', format: 'cjs' }, + ] + }); +}) + +b.task('test', ['test:clean', 'test:assets', 'test:browser', 'test:server']) + + // starts a server when CLI argument '-s' is set b.setServerPort(5555) b.serve({ diff --git a/package.json b/package.json index bf696d88c..486a87d1d 100644 --- a/package.json +++ b/package.json @@ -8,14 +8,15 @@ "devDependencies": { "eslint": "^3.2.2", "font-awesome": "4.5.0", - "substance-bundler": "^0.4.16", + "substance-bundler": "^0.4.20", + "substance-test": "^0.2.2", "tap-spec": "4.1.1", "tape": "4.5.1" }, "scripts": { "bundle": "node make", "start": "node make -s -w", - "test": "gulp test" + "test": "node test" }, "version": "1.0.0-alpha.2" } diff --git a/test.js b/test.js new file mode 100644 index 000000000..1a15572b4 --- /dev/null +++ b/test.js @@ -0,0 +1,32 @@ +var path = require('path') +var cp = require('child_process') +var b = require('substance-bundler') + +b.task('build', function() { + b.make(require.resolve('./make.js'), 'test') +}) + +// TODO: tape is exiting the process when done :( +// so this task must be called at last +b.task('server', function() { + b.custom('Running nodejs tests...', { + execute: function() { + return new Promise(function(resolve, reject) { + const child = cp.fork(path.join(__dirname, 'dist/test/run-tests.js')) + child.on('message', function(msg) { + if (msg === 'done') { resolve() } + }) + child.on('error', function(error) { + reject(new Error(error)) + }) + child.on('close', function(exitCode) { + if (exitCode !== 0) { + process.exit(exitCode) + } + }) + }); + } + }) +}) + +b.task('default', ['build', 'server']) From 336681b6ce1f23ded34664c926be8d13504d840e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 28 Sep 2016 20:08:50 +0200 Subject: [PATCH 109/167] Build substance for tests. --- make.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/make.js b/make.js index d7c60461c..e7b95f2e4 100644 --- a/make.js +++ b/make.js @@ -19,6 +19,10 @@ b.task('substance', function() { b.copy('node_modules/substance/dist', './dist/substance') }) +b.task('substance:all', function() { + b.make('substance') +}) + function buildExample(example) { return function() { b.copy('examples/'+example+'/index.html', './dist/'+example+'/') @@ -82,7 +86,7 @@ b.task('test:server', function() { }); }) -b.task('test', ['test:clean', 'test:assets', 'test:browser', 'test:server']) +b.task('test', ['substance:all', 'test:clean', 'test:assets', 'test:browser', 'test:server']) // starts a server when CLI argument '-s' is set From f1d23a54c7e69f7fdcc40774b662107ae3764893 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 28 Sep 2016 20:18:00 +0200 Subject: [PATCH 110/167] Removed obsolete dependencies --- package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/package.json b/package.json index 486a87d1d..4f1c10a5d 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,7 @@ "eslint": "^3.2.2", "font-awesome": "4.5.0", "substance-bundler": "^0.4.20", - "substance-test": "^0.2.2", - "tap-spec": "4.1.1", - "tape": "4.5.1" + "substance-test": "^0.2.2" }, "scripts": { "bundle": "node make", From c3f8d0960ebd0ee0b0d324a51296936d5ac06aab Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 28 Sep 2016 20:18:12 +0200 Subject: [PATCH 111/167] Run tests in node 4 and 6. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 2473ccc3e..5d622b29d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ cache: directories: - node_modules node_js: + - "4" - "6" before_script: - 'npm install' From 27a8b40a051a5eb2464cd95228d9dc82365c6ea4 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Wed, 28 Sep 2016 21:29:11 +0200 Subject: [PATCH 112/167] Simplified usage / configuration of Texture. --- CHANGELOG.md | 11 +++ README.md | 74 ++++++------------- examples/author/app.js | 36 ++------- examples/author/package.js | 10 --- examples/publisher/app.js | 39 +++------- examples/publisher/package.js | 11 --- examples/tagging/app.js | 25 +++++-- .../author/{package.js => AuthorPackage.js} | 21 +++--- .../{package.js => PublisherPackage.js} | 15 ++-- packages/tagging/README.md | 7 ++ .../tagging/TaggingPackage.js | 2 - .../tagging/aff/TagAffCommand.js | 0 .../tagging/aff/TagAffTool.js | 0 .../tagging/contrib/TagContribCommand.js | 0 .../tagging/contrib/TagContribTool.js | 0 .../tagging/ref/TagRefCommand.js | 0 .../tagging/ref/TagRefTool.js | 0 packages/texture/Texture.js | 50 ++++++++----- packages/texture/TextureConfigurator.js | 13 ++++ packages/texture/package.js | 13 ++-- 20 files changed, 146 insertions(+), 181 deletions(-) create mode 100644 CHANGELOG.md delete mode 100644 examples/author/package.js delete mode 100644 examples/publisher/package.js rename packages/author/{package.js => AuthorPackage.js} (62%) rename packages/publisher/{package.js => PublisherPackage.js} (62%) create mode 100644 packages/tagging/README.md rename {examples => packages}/tagging/TaggingPackage.js (93%) rename {examples => packages}/tagging/aff/TagAffCommand.js (100%) rename {examples => packages}/tagging/aff/TagAffTool.js (100%) rename {examples => packages}/tagging/contrib/TagContribCommand.js (100%) rename {examples => packages}/tagging/contrib/TagContribTool.js (100%) rename {examples => packages}/tagging/ref/TagRefCommand.js (100%) rename {examples => packages}/tagging/ref/TagRefTool.js (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..423928d05 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,11 @@ + +## Alpha 2 + +- Update to Substance Beta 5 +- Front matter editing for title + abstract (JATS ``) +- Editing of authors (create, update and delete contrib elements) +- Create and edit xref elements + +## Alpha + +Initial release \ No newline at end of file diff --git a/README.md b/README.md index bc0c1bda6..ced7185d5 100644 --- a/README.md +++ b/README.md @@ -53,66 +53,43 @@ Here's how you can integrate Texture into your web app. ```js // app.js -var Texture = require('substance-texture'); -var myTexturePackage = require('./myTexturePackage'); -var configurator = new Texture.Configurator(myTexturePackage); +import { Texture, TextureConfigurator, AuthorPackage } from 'substance-texture' +import MyXMLStore from './MyXMLStore' + +let configurator = new TextureConfigurator() +configurator + .import(AuthorPackage) + .setXMLStore(MyXMLStore) window.onload = function() { window.app = Texture.mount({ - mode: 'publisher', // or 'author' or 'reader' documentId: 'doc-1', configurator: configurator - }, document.body); -}; + }, document.body) +} ``` -Texture is fully configurable. So you need to supply a custom configuration via a package defintion. - -```js -// myTexturePackage.js -var MyXMLStore = require('../MyXMLStore'); -var texturePackage = require('substance-texture/packages/texture/package'); -var path = require('path'); - -module.exports = { - name: 'my-texture', - configure: function(config) { - // Use the default Texture package - config.import(texturePackage); - - // Define XML Store - config.setXMLStore(MyXMLStore); - } -}; -``` +Texture is fully configurable. So you need to supply a custom configuration by importing packages. In order to connect Texture to a backend you need to define an XML Store: ```js // MyXMLStore.js -var oo = require('substance/util/oo'); -var request = require('substance/util/request'); - -function MyXMLStore() {} +import { request } from 'substance' -MyXMLStore.Prototype = function() { - this.readXML = function(documentId, cb) { - request('GET', 'https://myserver.com/documents/'+documentId+'.xml', null, cb); - }; +export default class MyXMLStore { + readXML(documentId, cb) { + request('GET', 'https://myserver.com/documents/'+documentId+'.xml', null, cb) + } - this.writeXML = function(documentId, xml, cb) { - var data = {content: xml}; + writeXML(documentId, xml, cb) { + var data = { content: xml } var url = 'https://myserver.com/documents/'+documentId+'.xml' - request('PUT', url, data, cb); - }; -}; - -oo.initClass(MyXMLStore); - -module.exports = MyXMLStore; + request('PUT', url, data, cb) + } +} ``` - ## Bundle examples ```bash @@ -125,18 +102,9 @@ See [CONTRIBUTING.md](CONTRIBUTING.md). ## Roadmap -### Alpha 2 - -*ETA: September 2016* - -- Update to Substance Beta 5 -- Front matter editing for title + abstract (JATS ``) -- Editing of authors (create, update and delete contrib elements) -- Create and edit xref elements - ### Alpha 3 -*ETA: October 2016* +*ETA: November 2016* Goal is to provide proof of concepts for the discussed tagging workflow (get from unstructured text to structured JATS). For example: diff --git a/examples/author/app.js b/examples/author/app.js index f96cc63b9..c404b1fab 100644 --- a/examples/author/app.js +++ b/examples/author/app.js @@ -1,43 +1,23 @@ import { substanceGlobals } from 'substance' -import Package from './package' import Texture from '../../packages/texture/Texture' import TextureConfigurator from '../../packages/texture/TextureConfigurator' -import Author from '../../packages/author/Author' +import AuthorPackage from '../../packages/author/AuthorPackage' +import ExampleXMLStore from '../ExampleXMLStore' substanceGlobals.DEBUG_RENDERING = true; -class App extends Texture { - - render($$) { - let el = $$('div').addClass('sc-author-example') - - if (this.state.error) { - el.append(this.state.error) - } - - if (this.state.documentSession) { - el.append($$(Author, { - documentId: this.props.documentId, - documentSession: this.state.documentSession, - configurator: this.getConfigurator() - })) - } - return el - } -} - -App.Configurator = TextureConfigurator +/* Example Configuration */ +let configurator = new TextureConfigurator() + .import(AuthorPackage) + .setXMLStore(ExampleXMLStore) if (typeof window !== 'undefined') { window.onload = function() { - let configurator = new TextureConfigurator() - configurator.import(Package) - var app = App.mount({ + var app = Texture.mount({ configurator: configurator, documentId: 'elife-15278' }, document.body) window.app = app - }; + } } -export default App diff --git a/examples/author/package.js b/examples/author/package.js deleted file mode 100644 index 61ba25937..000000000 --- a/examples/author/package.js +++ /dev/null @@ -1,10 +0,0 @@ -import AuthorPackage from '../../packages/author/package' -import ExampleXMLStore from '../ExampleXMLStore' - -export default { - name: 'author-example', - configure: function(config) { - config.import(AuthorPackage) - config.setXMLStore(ExampleXMLStore); - } -}; diff --git a/examples/publisher/app.js b/examples/publisher/app.js index 2f05b2756..0cf375f95 100644 --- a/examples/publisher/app.js +++ b/examples/publisher/app.js @@ -1,44 +1,23 @@ import { substanceGlobals } from 'substance' -import Package from './package' import Texture from '../../packages/texture/Texture' import TextureConfigurator from '../../packages/texture/TextureConfigurator' -import Publisher from '../../packages/publisher/Publisher' +import PublisherPackage from '../../packages/publisher/PublisherPackage' +import ExampleXMLStore from '../ExampleXMLStore' -substanceGlobals.DEBUG_RENDERING = true; +substanceGlobals.DEBUG_RENDERING = true -class App extends Texture { - - render($$) { - let el = $$('div').addClass('sc-publisher-example') - - if (this.state.error) { - el.append(this.state.error) - } - - if (this.state.documentSession) { - el.append($$(Publisher, { - documentId: this.props.documentId, - documentSession: this.state.documentSession, - configurator: this.getConfigurator() - })) - } - - return el - } -} - -App.Configurator = TextureConfigurator +/* Configure example */ +let configurator = new TextureConfigurator() + .import(PublisherPackage) + .setXMLStore(ExampleXMLStore) if (typeof window !== 'undefined') { window.onload = function() { - let configurator = new TextureConfigurator() - configurator.import(Package) - var app = App.mount({ + var app = Texture.mount({ configurator: configurator, documentId: 'elife-15278' }, document.body) window.app = app - }; + } } -export default App diff --git a/examples/publisher/package.js b/examples/publisher/package.js deleted file mode 100644 index 5afda4fd8..000000000 --- a/examples/publisher/package.js +++ /dev/null @@ -1,11 +0,0 @@ -import PublisherPackage from '../../packages/publisher/package' -import ExampleXMLStore from '../ExampleXMLStore' - -export default { - name: 'publisher-example', - configure: function(config) { - config.import(PublisherPackage) - config.setXMLStore(ExampleXMLStore); - } -} - diff --git a/examples/tagging/app.js b/examples/tagging/app.js index 8f04bbb2b..70953a3ab 100644 --- a/examples/tagging/app.js +++ b/examples/tagging/app.js @@ -1,14 +1,25 @@ -import App from '../author/app' -import TaggingPackage from './TaggingPackage' +import { substanceGlobals } from 'substance' +import Texture from '../../packages/texture/Texture' +import TextureConfigurator from '../../packages/texture/TextureConfigurator' +import AuthorPackage from '../../packages/author/AuthorPackage' +import TaggingPackage from '../../packages/tagging/TaggingPackage' +import ExampleXMLStore from '../ExampleXMLStore' + +substanceGlobals.DEBUG_RENDERING = true + +/* Configure example */ +let configurator = new TextureConfigurator() + .import(AuthorPackage) + // enable tagging abilities + .import(TaggingPackage) + .setXMLStore(ExampleXMLStore) if (typeof window !== 'undefined') { window.onload = function() { - let configurator = new App.Configurator() - configurator.import(TaggingPackage) - var app = App.mount({ + var app = Texture.mount({ configurator: configurator, - documentId: 'kitchen-sink-author' + documentId: 'elife-15278' }, document.body) window.app = app - }; + } } diff --git a/packages/author/package.js b/packages/author/AuthorPackage.js similarity index 62% rename from packages/author/package.js rename to packages/author/AuthorPackage.js index c3926ab45..da16e833a 100644 --- a/packages/author/package.js +++ b/packages/author/AuthorPackage.js @@ -6,26 +6,29 @@ import HeadingPackage from './heading/package' import CommonPackage from '../common/package' import InlineWrapperPackage from '../inline-wrapper/InlineWrapperPackage' import UnsupportedNodePackage from '../unsupported/UnsupportedNodePackage' +import Author from './Author' export default { name: 'author', configure: function(config) { + config.setInterfaceComponentClass(Author) + // Now import base packages - config.import(BasePackage); - config.import(PersistencePackage); + config.import(BasePackage) + config.import(PersistencePackage) - config.import(JATSPackage); - config.import(HeadingPackage); - config.import(CommonPackage); + config.import(JATSPackage) + config.import(HeadingPackage) + config.import(CommonPackage) // support inline wrappers, for all hybrid types that can be // block-level but also inline. - config.import(InlineWrapperPackage); + config.import(InlineWrapperPackage) // catch all converters - config.import(UnsupportedNodePackage); + config.import(UnsupportedNodePackage) // Override Importer/Exporter - config.addImporter('jats', AuthorImporter); - config.addExporter('jats', AuthorExporter); + config.addImporter('jats', AuthorImporter) + config.addExporter('jats', AuthorExporter) } } diff --git a/packages/publisher/package.js b/packages/publisher/PublisherPackage.js similarity index 62% rename from packages/publisher/package.js rename to packages/publisher/PublisherPackage.js index 24474fcbd..0d733471c 100644 --- a/packages/publisher/package.js +++ b/packages/publisher/PublisherPackage.js @@ -3,19 +3,22 @@ import JATSPackage from '../jats/package' import CommonPackage from '../common/package' import InlineWrapperPackage from '../inline-wrapper/InlineWrapperPackage' import UnsupportedNodePackage from '../unsupported/UnsupportedNodePackage' +import Publisher from './Publisher' export default { name: 'publisher', configure: function(config) { - config.import(BasePackage); - config.import(PersistencePackage); - config.import(JATSPackage); - config.import(CommonPackage); + config.setInterfaceComponentClass(Publisher) + + config.import(BasePackage) + config.import(PersistencePackage) + config.import(JATSPackage) + config.import(CommonPackage) // support inline wrappers, for all hybrid types that can be // block-level but also inline. - config.import(InlineWrapperPackage); + config.import(InlineWrapperPackage) // catch all converters - config.import(UnsupportedNodePackage); + config.import(UnsupportedNodePackage) } } \ No newline at end of file diff --git a/packages/tagging/README.md b/packages/tagging/README.md new file mode 100644 index 000000000..45c820a7f --- /dev/null +++ b/packages/tagging/README.md @@ -0,0 +1,7 @@ +# Experimental UX for tagging + +The considered use-case is to start from a generated JATS file +e.g. from a DOCX converter. +The JATS content has structural issues, e.g., wrong section levels, detached figure captions, etc., which need to be corrected. + +The proposed UI let's the user select such content and apply certain tools that help to get from unstructured or wrong structured to well structured content. diff --git a/examples/tagging/TaggingPackage.js b/packages/tagging/TaggingPackage.js similarity index 93% rename from examples/tagging/TaggingPackage.js rename to packages/tagging/TaggingPackage.js index be780c335..0a7b9ac56 100644 --- a/examples/tagging/TaggingPackage.js +++ b/packages/tagging/TaggingPackage.js @@ -1,4 +1,3 @@ -import AuthorExamplePackage from '../author/package' import { ToolDropdown } from 'substance' import TagAffCommand from './aff/TagAffCommand' import TagAffTool from './aff/TagAffTool' @@ -10,7 +9,6 @@ import TagContribTool from './contrib/TagContribTool' export default { name: 'tagging-example', configure: function(config) { - config.import(AuthorExamplePackage) // Tagging // ------- diff --git a/examples/tagging/aff/TagAffCommand.js b/packages/tagging/aff/TagAffCommand.js similarity index 100% rename from examples/tagging/aff/TagAffCommand.js rename to packages/tagging/aff/TagAffCommand.js diff --git a/examples/tagging/aff/TagAffTool.js b/packages/tagging/aff/TagAffTool.js similarity index 100% rename from examples/tagging/aff/TagAffTool.js rename to packages/tagging/aff/TagAffTool.js diff --git a/examples/tagging/contrib/TagContribCommand.js b/packages/tagging/contrib/TagContribCommand.js similarity index 100% rename from examples/tagging/contrib/TagContribCommand.js rename to packages/tagging/contrib/TagContribCommand.js diff --git a/examples/tagging/contrib/TagContribTool.js b/packages/tagging/contrib/TagContribTool.js similarity index 100% rename from examples/tagging/contrib/TagContribTool.js rename to packages/tagging/contrib/TagContribTool.js diff --git a/examples/tagging/ref/TagRefCommand.js b/packages/tagging/ref/TagRefCommand.js similarity index 100% rename from examples/tagging/ref/TagRefCommand.js rename to packages/tagging/ref/TagRefCommand.js diff --git a/examples/tagging/ref/TagRefTool.js b/packages/tagging/ref/TagRefTool.js similarity index 100% rename from examples/tagging/ref/TagRefTool.js rename to packages/tagging/ref/TagRefTool.js diff --git a/packages/texture/Texture.js b/packages/texture/Texture.js index 36d65ef22..10b84809b 100644 --- a/packages/texture/Texture.js +++ b/packages/texture/Texture.js @@ -1,7 +1,9 @@ import { Component, DocumentSession } from 'substance' +import Author from '../author/Author' +import Publisher from '../publisher/Publisher' /* - JATSEditor Component + Texture Component Based on given mode prop, displays the Publisher, Author or Reader component */ @@ -10,7 +12,6 @@ class Texture extends Component { constructor(parent, props) { super(parent, props) - if (!props.configurator) { throw new Error("'configurator' is required") } @@ -33,29 +34,40 @@ class Texture extends Component { didMount() { // load the document after mounting - this._loadDocument(this.props.documentId); + this._loadDocument(this.props.documentId) } willReceiveProps(newProps) { if (newProps.documentId !== this.props.documentId) { - this.dispose(); - this.state = this.getInitialState(); - this._loadDocument(newProps.documentId); + this.dispose() + this.state = this.getInitialState() + this._loadDocument(newProps.documentId) } } dispose() { // Note: we need to clear everything, as the childContext // changes which is immutable - this.empty(); + this.empty() } render($$) { - var el = $$('div').addClass('sc-texture'); + let el = $$('div').addClass('sc-texture') + if (this.state.error) { el.append(this.state.error) } - return el; + + if (this.state.documentSession) { + let ComponentClass = this.configurator.getInterfaceComponentClass() + + el.append($$(ComponentClass, { + documentId: this.props.documentId, + documentSession: this.state.documentSession, + configurator: this.getConfigurator() + })) + } + return el } getConfigurator() { @@ -67,25 +79,25 @@ class Texture extends Component { } _loadDocument() { - const configurator = this.getConfigurator(); + const configurator = this.getConfigurator() this.xmlStore.readXML(this.props.documentId, function(err, xml) { if (err) { - console.error(err); + console.error(err) this.setState({ error: new Error('Loading failed') - }); - return; + }) + return } - var importer = configurator.createImporter('jats'); - var doc = importer.importDocument(xml); + var importer = configurator.createImporter('jats') + var doc = importer.importDocument(xml) // HACK: For debug purposes - window.doc = doc; + window.doc = doc this.setState({ documentSession: this.createDocumentSession(doc) - }); - }.bind(this)); + }) + }.bind(this)) } } -export default Texture; +export default Texture diff --git a/packages/texture/TextureConfigurator.js b/packages/texture/TextureConfigurator.js index 1929ef3cd..b280d4716 100644 --- a/packages/texture/TextureConfigurator.js +++ b/packages/texture/TextureConfigurator.js @@ -10,6 +10,18 @@ class TextureConfigurator extends Configurator { this.config.saveHandler = new SaveHandlerStub() this.config.fileClient = new FileClientStub() this.config.XMLStoreClass = null + this.config.InterfaceComponentClass = null + } + + setInterfaceComponentClass(Class) { + if (this.config.InterfaceComponentClass) { + throw new Error("InterfaceComponetClass can't be set twice") + } + this.config.InterfaceComponentClass = Class + } + + getInterfaceComponentClass() { + return this.config.InterfaceComponentClass } setSaveHandler(saveHandler) { @@ -30,6 +42,7 @@ class TextureConfigurator extends Configurator { setXMLStore(XMLStoreClass) { this.config.XMLStoreClass = XMLStoreClass + return this } getXMLStore() { diff --git a/packages/texture/package.js b/packages/texture/package.js index 25f2cbaec..67cadcfcf 100644 --- a/packages/texture/package.js +++ b/packages/texture/package.js @@ -5,11 +5,12 @@ import AuthorPackage from '../author/package' import PublisherPackage from '../publisher/package' export default { - name: 'scientist', - configure: function(config) { - var Configurator = ProseEditorPackage.Configurator - // Default configuration for available scientist modes - config.addConfigurator('author', new Configurator().import(AuthorPackage)); - config.addConfigurator('publisher', new Configurator().import(PublisherPackage)); + name: 'texture', + configure: function(config, options) { + if (options.mode === 'publisher') { + config.import(AuthorPackage) + } else { + config.import(PublisherPackage) + } } }; From c1548d4d984464f635b68131eb50d34792040181 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 00:03:32 +0300 Subject: [PATCH 113/167] ES6 Heading. --- packages/author/heading/Heading.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/author/heading/Heading.js b/packages/author/heading/Heading.js index 3cc352e0f..911e2a41f 100644 --- a/packages/author/heading/Heading.js +++ b/packages/author/heading/Heading.js @@ -1,18 +1,14 @@ import { TextBlock } from 'substance' -function HeadingNode() { - HeadingNode.super.apply(this, arguments); -} +class HeadingNode extends TextBlock {} -TextBlock.extend(HeadingNode); - -HeadingNode.type = "heading"; +HeadingNode.type = "heading" HeadingNode.define({ // just a reference to the original node // which will be used to retain XML attributes sectionId: { type: 'id', optional: true }, - level: { type: "number", default: 1 }, -}); + level: { type: "number", default: 1 } +}) -export default HeadingNode; +export default HeadingNode From 20b697a996dd6263b0f20efb8223b84464278e73 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 00:28:39 +0300 Subject: [PATCH 114/167] ES6 Exporters. --- packages/author/AuthorExporter.js | 22 +++++-------- packages/jats/JATSExporter.js | 52 +++++++++++++------------------ 2 files changed, 30 insertions(+), 44 deletions(-) diff --git a/packages/author/AuthorExporter.js b/packages/author/AuthorExporter.js index a5a3667ab..968946574 100644 --- a/packages/author/AuthorExporter.js +++ b/packages/author/AuthorExporter.js @@ -1,20 +1,14 @@ import JATSExporter from '../jats/JATSExporter' import JATSTransformer from './JATSTransformer' -function AuthorExporter() { - AuthorExporter.super.apply(this, arguments); -} - -AuthorExporter.Prototype = function() { - var _super = AuthorExporter.super.prototype; +class AuthorExporter extends JATSExporter { - this.exportDocument = function(doc) { - var trafo = new JATSTransformer(); - doc = trafo.toJATS(doc); - return _super.exportDocument.call(this, doc); - }; -}; + exportDocument(doc) { + let trafo = new JATSTransformer() + doc = trafo.toJATS(doc) + return super.exportDocument(doc) + } -JATSExporter.extend(AuthorExporter); +} -export default AuthorExporter; +export default AuthorExporter diff --git a/packages/jats/JATSExporter.js b/packages/jats/JATSExporter.js index 026e619e9..862c5a199 100644 --- a/packages/jats/JATSExporter.js +++ b/packages/jats/JATSExporter.js @@ -3,46 +3,38 @@ import isString from 'lodash/isString' import { XMLExporter } from 'substance' -function JATSExporter(config) { - JATSExporter.super.call(this, config); -} - -JATSExporter.Prototype = function() { - - var _super = JATSExporter.super.prototype; +class JATSExporter extends XMLExporter { - this.exportDocument = function(doc) { - this.state.doc = doc; + exportDocument(doc) { + this.state.doc = doc - var articleEl = this.convertNode(doc.get('article')); - return articleEl.outerHTML; - }; + let articleEl = this.convertNode(doc.get('article')) + return articleEl.outerHTML + } - this.convertNode = function(node) { - var el = _super.convertNode.apply(this, arguments); + convertNode(node) { + let el = super.convertNode(node) if (isString(node)) { - node = this.state.doc.get(node); + node = this.state.doc.get(node) } - el.attr(node.attributes); - return el; - }; + el.attr(node.attributes) + return el + } - this.convertNodes = function(nodes) { - var els = []; - var converter = this; + convertNodes(nodes) { + let els = [] + let converter = this if (nodes._isArrayIterator) { while(nodes.hasNext()) { - els.push(converter.convertNode(nodes.next())); + els.push(converter.convertNode(nodes.next())) } } else { nodes.forEach(function(node) { - els.push(converter.convertNode(node)); - }); + els.push(converter.convertNode(node)) + }) } - return els; - }; -}; - -XMLExporter.extend(JATSExporter); + return els + } +} -export default JATSExporter; +export default JATSExporter From 609de7af93a083fb8e2ad308ebf53248077770ef Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 00:28:52 +0300 Subject: [PATCH 115/167] ES6 Importers. --- packages/author/AuthorImporter.js | 24 ++-- packages/jats/JATSImporter.js | 136 ++++++++---------- .../UnsupportedNodeJATSConverter.js | 14 +- 3 files changed, 78 insertions(+), 96 deletions(-) diff --git a/packages/author/AuthorImporter.js b/packages/author/AuthorImporter.js index f038dc9a5..d18733044 100644 --- a/packages/author/AuthorImporter.js +++ b/packages/author/AuthorImporter.js @@ -1,21 +1,15 @@ import JATSImporter from '../jats/JATSImporter' import JATSTransformer from './JATSTransformer' -function AuthorImporter() { - AuthorImporter.super.apply(this, arguments); -} - -AuthorImporter.Prototype = function() { - var _super = AuthorImporter.super.prototype; +class AuthorImporter extends JATSImporter { - this.importDocument = function() { - var doc = _super.importDocument.apply(this, arguments); - var trafo = new JATSTransformer(); - doc = trafo.fromJATS(doc); - return doc; - }; -}; + importDocument(...args) { + let doc = super.importDocument(...args) + let trafo = new JATSTransformer() + doc = trafo.fromJATS(doc) + return doc + } -JATSImporter.extend(AuthorImporter); +} -export default AuthorImporter; \ No newline at end of file +export default AuthorImporter \ No newline at end of file diff --git a/packages/jats/JATSImporter.js b/packages/jats/JATSImporter.js index 4a744ab50..ee799780a 100644 --- a/packages/jats/JATSImporter.js +++ b/packages/jats/JATSImporter.js @@ -2,106 +2,94 @@ import last from 'lodash/last' import { DefaultDOMElement, DOMImporter, XMLImporter, inBrowser } from 'substance' import UnsupportedNodeJATSConverter from '../unsupported/UnsupportedNodeJATSConverter' -function JATSImporter(config) { - config.enableInlineWrapper = true; - JATSImporter.super.call(this, config); - this.state = new JATSImporter.State(); -} - -JATSImporter.Prototype = function() { - - var _super = JATSImporter.super.prototype; - - this.importDocument = function(xmlString) { - this.reset(); - var xmlDoc = DefaultDOMElement.parseXML(xmlString, 'fullDoc'); +class JATSImporter extends XMLImporter { + constructor(config) { + super(config) + config.enableInlineWrapper = true + this.state = new JATSImporter.State() + } + + importDocument(xmlString) { + this.reset() + let xmlDoc = DefaultDOMElement.parseXML(xmlString, 'fullDoc') // HACK: server side impl gives an array - var articleEl; + let articleEl if (inBrowser) { - articleEl = xmlDoc.find('article'); + articleEl = xmlDoc.find('article') } else { // HACK: this should be more convenient - for (var idx = 0; idx < xmlDoc.length; idx++) { + for (let idx = 0; idx < xmlDoc.length; idx++) { if (xmlDoc[idx].tagName === 'article') { - articleEl = xmlDoc[idx]; + articleEl = xmlDoc[idx] } } } - this.convertDocument(articleEl); - var doc = this.generateDocument(); - return doc; - }; + this.convertDocument(articleEl) + let doc = this.generateDocument() + return doc + } - this.convertDocument = function(articleElement) { - this.convertElement(articleElement); - }; + convertDocument(articleElement) { + this.convertElement(articleElement) + } - this.convertElements = function(elements, startIdx, endIdx) { + convertElements(elements, startIdx, endIdx) { if (arguments.length < 2) { - startIdx = 0; + startIdx = 0 } if(arguments.length < 3) { - endIdx = elements.length; + endIdx = elements.length } - var nodes = []; - for (var i = startIdx; i < endIdx; i++) { - nodes.push(this.convertElement(elements[i])); + let nodes = [] + for (let i = startIdx; i < endIdx; i++) { + nodes.push(this.convertElement(elements[i])) } - return nodes; - }; - - this._converterCanBeApplied = function(converter, el) { - return converter.matchElement(el, this); - }; + return nodes + } - this._getUnsupportedNodeConverter = function() { - return UnsupportedNodeJATSConverter; - }; + _converterCanBeApplied(converter, el) { + return converter.matchElement(el, this) + } - this._nodeData = function(el) { - var nodeData = _super._nodeData.apply(this, arguments); - nodeData.attributes = el.getAttributes(); - return nodeData; - }; + _getUnsupportedNodeConverter() { + return UnsupportedNodeJATSConverter + } + _nodeData(el, schema) { + let nodeData = super._nodeData(el, schema) + nodeData.attributes = el.getAttributes() + return nodeData + } -}; - -XMLImporter.extend(JATSImporter); - -JATSImporter.State = function() { - JATSImporter.State.super.call(this); -}; - -JATSImporter.State.Prototype = function() { +} - var _super = JATSImporter.State.super.prototype; +class State extends DOMImporter.State { - this.reset = function() { - _super.reset.call(this); + reset(...args) { + super.reset(...args) // stack for list types - this.lists = []; - this.listItemLevel = 1; - }; + this.lists = [] + this.listItemLevel = 1 + } - this.getCurrentListItemLevel = function() { - return this.listItemLevel; - }; + getCurrentListItemLevel() { + return this.listItemLevel + } - this.increaseListItemLevel = function() { - return this.listItemLevel++; - }; + increaseListItemLevel() { + return this.listItemLevel++ + } - this.decreaseListItemLevel = function() { - return this.listItemLevel--; - }; + decreaseListItemLevel() { + return this.listItemLevel-- + } - this.getCurrentList = function() { - return last(this.lists); - }; + getCurrentList() { + return last(this.lists) + } -}; +} -DOMImporter.State.extend(JATSImporter.State); +JATSImporter.State = State -export default JATSImporter; +export default JATSImporter diff --git a/packages/unsupported/UnsupportedNodeJATSConverter.js b/packages/unsupported/UnsupportedNodeJATSConverter.js index 5a127faf3..32de2b239 100644 --- a/packages/unsupported/UnsupportedNodeJATSConverter.js +++ b/packages/unsupported/UnsupportedNodeJATSConverter.js @@ -3,18 +3,18 @@ export default { type: 'unsupported', matchElement: function() { - return true; + return true }, import: function(el, node) { - node.xmlContent = el.innerHTML; - node.tagName = el.tagName; + node.xmlContent = el.innerHTML + node.tagName = el.tagName }, export: function(node, el) { - el.tagName = node.tagName; - el.innerHTML = node.xmlContent; - return el; + el.tagName = node.tagName + el.innerHTML = node.xmlContent + return el } -}; +} From 4082d38717ecb9f3fd3765613d1580fbb45c5362 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 00:39:44 +0300 Subject: [PATCH 116/167] ES6 syntax fixes. --- packages/jats/JATS.js | 17 ++++++----------- packages/jats/TextNodeConverter.js | 10 ++++------ packages/jats/package.js | 4 ++-- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/packages/jats/JATS.js b/packages/jats/JATS.js index 351559f32..6a2e69d43 100644 --- a/packages/jats/JATS.js +++ b/packages/jats/JATS.js @@ -1,9 +1,7 @@ -'use strict'; - // Helpers to define strict converters // everything here is taken from JATS 1.1 green http://jats.nlm.nih.gov/archiving/tag-library/1.1/ -var JATS = { +let JATS = { ABSTRACT: ['abstract'], ACCESS: ['alt-text','long-desc'], ADDRESS_LINK: ['email','ext-link','uri'], @@ -39,9 +37,9 @@ var JATS = { SUBSUP: ['sub','sup'], TITLE_GROUP: ['article-title', 'subtitle', 'trans-title-group', 'alt-title', 'fn-group'], X: ['x'], -}; +} -JATS.ARTICLE_LINK = ['inline-supplementary-material'].concat(JATS.RELATED_ARTICLE); +JATS.ARTICLE_LINK = ['inline-supplementary-material'].concat(JATS.RELATED_ARTICLE) JATS.ALL_PHRASE = JATS.ADDRESS_LINK .concat(JATS.ARTICLE_LINK) .concat(JATS.APPEARANCE) @@ -52,7 +50,7 @@ JATS.ALL_PHRASE = JATS.ADDRESS_LINK .concat(JATS.PHRASE) .concat(JATS.SIMPLE_LINK) .concat(JATS.SUBSUP) - .concat(JATS.X); + .concat(JATS.X) JATS.PARA_LEVEL = JATS.BLOCK_DISPLAY .concat(JATS.BLOCK_MATH) .concat(JATS.LIST) @@ -60,9 +58,6 @@ JATS.PARA_LEVEL = JATS.BLOCK_DISPLAY .concat(JATS.NOTHING_BUT_PARA) .concat(JATS.RELATED_ARTICLE) .concat(JATS.REST_OF_PARA) - .concat(JATS.X); - -export default JATS; - - + .concat(JATS.X) +export default JATS diff --git a/packages/jats/TextNodeConverter.js b/packages/jats/TextNodeConverter.js index e81516db0..2693fe519 100644 --- a/packages/jats/TextNodeConverter.js +++ b/packages/jats/TextNodeConverter.js @@ -1,16 +1,14 @@ -'use strict'; - import extend from 'lodash/extend' export default { import: function(el, node, converter) { - node.content = converter.annotatedText(el, [node.id, 'content']); + node.content = converter.annotatedText(el, [node.id, 'content']) }, export: function(node, el, converter) { - el.append(converter.annotatedText([node.id, 'content'])); + el.append(converter.annotatedText([node.id, 'content'])) }, // used by text node converters to reduce code redundancy extend: function(converter) { - return extend({}, this, converter); + return extend({}, this, converter) } -}; +} diff --git a/packages/jats/package.js b/packages/jats/package.js index d880b4fb3..7f22a268e 100644 --- a/packages/jats/package.js +++ b/packages/jats/package.js @@ -63,7 +63,7 @@ export default { config.import(TitleGroupPackage) config.import(XrefPackage) - config.addImporter('jats', JATSImporter); - config.addExporter('jats', JATSExporter); + config.addImporter('jats', JATSImporter) + config.addExporter('jats', JATSExporter) } } From c252a3e2d5aa80560e22ba8b4605aa6046471135 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 00:40:00 +0300 Subject: [PATCH 117/167] ES6 xref package. --- packages/jats/xref/XRef.js | 18 +++---- packages/jats/xref/XRefComponent.js | 30 +++++------- packages/jats/xref/XRefConverter.js | 13 ++--- packages/jats/xref/XRefTargets.js | 73 ++++++++++++---------------- packages/jats/xref/getXRefTargets.js | 34 ++++++------- packages/jats/xref/package.js | 6 +-- 6 files changed, 75 insertions(+), 99 deletions(-) diff --git a/packages/jats/xref/XRef.js b/packages/jats/xref/XRef.js index 6aae350b0..8b169c539 100644 --- a/packages/jats/xref/XRef.js +++ b/packages/jats/xref/XRef.js @@ -2,11 +2,7 @@ import { Fragmenter, InlineNode } from 'substance' -function XRef() { - XRef.super.apply(this, arguments); -} - -InlineNode.extend(XRef); +class XRef extends InlineNode {} XRef.type = 'xref'; @@ -14,20 +10,20 @@ XRef.define({ attributes: { type: 'object', default: {} }, targets: {type: ['id'], default: []}, label: { type: 'text', optional: true } -}); +}) Object.defineProperties(XRef.prototype, { referenceType: { get: function() { - return this.attributes['ref-type']; + return this.attributes['ref-type'] }, set: function(refType) { - this.attributes['ref-type'] = refType; + this.attributes['ref-type'] = refType } } -}); +}) // In presence of overlapping annotations will try to render this as one element -XRef.fragmentation = Fragmenter.SHOULD_NOT_SPLIT; +XRef.fragmentation = Fragmenter.SHOULD_NOT_SPLIT -export default XRef; +export default XRef diff --git a/packages/jats/xref/XRefComponent.js b/packages/jats/xref/XRefComponent.js index f83475f55..f05feb656 100644 --- a/packages/jats/xref/XRefComponent.js +++ b/packages/jats/xref/XRefComponent.js @@ -2,29 +2,23 @@ import { Component, TextPropertyEditor } from 'substance' -function XRefComponent() { - XRefComponent.super.apply(this, arguments); -} - -XRefComponent.Prototype = function() { +class XRefComponent extends Component { - this.render = function($$) { // eslint-disable-line - var node = this.props.node; - var el = $$('span').addClass('sc-xref'); + render($$) { // eslint-disable-line + let node = this.props.node + let el = $$('span').addClass('sc-xref') - var labelEditor = $$(TextPropertyEditor, { + let labelEditor = $$(TextPropertyEditor, { disabled: this.props.disabled, tagName: 'span', path: [node.id, 'label'], withoutBreak: true - }).ref('labelEditor'); - el.append(labelEditor); + }).ref('labelEditor') + el.append(labelEditor) - el.addClass('sm-'+node.referenceType); - return el; - }; -}; - -Component.extend(XRefComponent); + el.addClass('sm-'+node.referenceType) + return el + } +} -export default XRefComponent; \ No newline at end of file +export default XRefComponent diff --git a/packages/jats/xref/XRefConverter.js b/packages/jats/xref/XRefConverter.js index 3ab48ad0c..8b2076cdb 100644 --- a/packages/jats/xref/XRefConverter.js +++ b/packages/jats/xref/XRefConverter.js @@ -1,5 +1,3 @@ -'use strict'; - export default { type: "xref", @@ -13,18 +11,17 @@ export default { /* Steppuhn and Baldwin, 2007 */ import: function(el, node, converter) { - node.targets = el.attr('rid').split(' '); - node.label = converter.annotatedText(el, [node.id, 'label']); + node.targets = el.attr('rid').split(' ') + node.label = converter.annotatedText(el, [node.id, 'label']) }, export: function(node, el, converter) { // eslint-disable-line el.attr({ 'rid': node.targets.join(' '), 'ref-type': node.referenceType - }); + }) el.append( converter.annotatedText([node.id, 'label']) - ); + ) } -}; - +} \ No newline at end of file diff --git a/packages/jats/xref/XRefTargets.js b/packages/jats/xref/XRefTargets.js index 248ec50ad..78be55a02 100644 --- a/packages/jats/xref/XRefTargets.js +++ b/packages/jats/xref/XRefTargets.js @@ -1,5 +1,3 @@ -'use strict'; - import clone from 'lodash/clone' import find from 'lodash/find' import without from 'lodash/without' @@ -9,18 +7,13 @@ import getXRefTargets from './getXRefTargets' /* Editing of XRefTargets */ -function XRefTargets() { - XRefTargets.super.apply(this, arguments); - // console.log('Created XRefTargets', this.__id__); -} +class XRefTargets extends Component { -XRefTargets.Prototype = function() { - - this.getInitialState = function() { + getInitialState() { return { targets: getXRefTargets(this.props.node) - }; - }; + } + } // this.willReceiveProps = function() { // console.log('XRefTargets.willReceiveProps', this.__id__); @@ -30,58 +23,56 @@ XRefTargets.Prototype = function() { // console.log('XRefTargets.dispose', this.__id__); // }; - this.render = function($$) { - var el = $$('div').addClass('sc-xref-targets'); - var componentRegistry = this.context.componentRegistry; + render($$) { + let el = $$('div').addClass('sc-xref-targets') + let componentRegistry = this.context.componentRegistry this.state.targets.forEach(function(target) { - var TargetComponent = componentRegistry.get(target.node.type+'-target'); - var props = clone(target); + let TargetComponent = componentRegistry.get(target.node.type+'-target') + let props = clone(target) // disable editing in TargetComponent - props.disabled = true; + props.disabled = true el.append( $$(TargetComponent, props) .on('click', this._toggleTarget.bind(this, target.node)) - ); - }.bind(this)); - return el; - }; - - this._toggleTarget = function(targetNode) { - var node = this.props.node; - var surface = this.context.surfaceManager.getFocusedSurface(); + ) + }.bind(this)) + return el + } + + _toggleTarget(targetNode) { + let node = this.props.node + let surface = this.context.surfaceManager.getFocusedSurface() // console.log('XRefTargets: toggling target of ', node.id); // Update model - var newTargets = node.targets; + let newTargets = node.targets if (newTargets.indexOf(targetNode.id) > 0) { - newTargets = without(newTargets, targetNode.id); + newTargets = without(newTargets, targetNode.id) } else { - newTargets.push(targetNode.id); + newTargets.push(targetNode.id) } // Compute visual feedback - var targets = this.state.targets; - var target = find(this.state.targets, function(t) { - return t.node === targetNode; - }); + let targets = this.state.targets; + let target = find(this.state.targets, function(t) { + return t.node === targetNode + }) // Flip the selected flag - target.selected = !target.selected; + target.selected = !target.selected // Triggers a rerender this.setState({ targets: targets - }); + }) // console.log('XRefTargets: setting targets of ', node.id, 'to', newTargets); // ATTENTION: still we need to use surface.transaction() surface.transaction(function(tx) { - tx.set([node.id, 'targets'], newTargets); - }); - }; -}; - -Component.extend(XRefTargets); + tx.set([node.id, 'targets'], newTargets) + }) + } +} -export default XRefTargets; \ No newline at end of file +export default XRefTargets diff --git a/packages/jats/xref/getXRefTargets.js b/packages/jats/xref/getXRefTargets.js index cee0e6d39..fd9013773 100644 --- a/packages/jats/xref/getXRefTargets.js +++ b/packages/jats/xref/getXRefTargets.js @@ -1,15 +1,13 @@ -'use strict'; - import includes from 'lodash/includes' import map from 'lodash/map' import orderBy from 'lodash/orderBy' -var TARGET_TYPES = { +let TARGET_TYPES = { 'fig': ['figure', 'fig-group'], 'bibr': ['ref'], 'table': ['table-wrap'], 'other': ['figure'] -}; +} /* Computes available targets for a given reference node @@ -24,28 +22,28 @@ var TARGET_TYPES = { ] */ function getXRefTargets(node) { - var doc = node.getDocument(); - var selectedTargets = node.targets; - var nodesByType = doc.getIndex('type'); - var refType = node.referenceType; - var targetTypes = TARGET_TYPES[refType]; - var targets = []; + let doc = node.getDocument() + let selectedTargets = node.targets + let nodesByType = doc.getIndex('type') + let refType = node.referenceType + let targetTypes = TARGET_TYPES[refType] + let targets = [] targetTypes.forEach(function(targetType) { - var nodesForType = map(nodesByType.get(targetType)); + let nodesForType = map(nodesByType.get(targetType)) nodesForType.forEach(function(node) { - var isSelected = includes(selectedTargets, node.id); + let isSelected = includes(selectedTargets, node.id) targets.push({ selected: isSelected, node: node - }); - }); - }); + }) + }) + }) // Makes the selected targets go to top - targets = orderBy(targets, ['selected'], ['desc']); - return targets; + targets = orderBy(targets, ['selected'], ['desc']) + return targets } -export default getXRefTargets; \ No newline at end of file +export default getXRefTargets diff --git a/packages/jats/xref/package.js b/packages/jats/xref/package.js index cf7d27c59..ad7209a36 100644 --- a/packages/jats/xref/package.js +++ b/packages/jats/xref/package.js @@ -9,9 +9,9 @@ import AddXRefTool from './AddXRefTool' export default { name: 'xref', configure: function(config) { - config.addNode(XRef); - config.addComponent(XRef.type, XRefComponent); - config.addConverter('jats', XRefConverter); + config.addNode(XRef) + config.addComponent(XRef.type, XRefComponent) + config.addConverter('jats', XRefConverter) config.addCommand('edit-xref', EditXRefCommand, {nodeType: XRef.type}) config.addCommand('add-xref', AddXRefCommand, {nodeType: XRef.type}) From f95378146b4a3b8d340aea0cfb3a68f5c2f6c2b9 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 01:29:28 +0300 Subject: [PATCH 118/167] ES6 Title group package. --- packages/jats/title-group/TitleGroup.js | 13 ++----- .../jats/title-group/TitleGroupComponent.js | 36 ++++++++----------- .../jats/title-group/TitleGroupConverter.js | 20 +++++------ packages/jats/title-group/package.js | 10 +++--- 4 files changed, 30 insertions(+), 49 deletions(-) diff --git a/packages/jats/title-group/TitleGroup.js b/packages/jats/title-group/TitleGroup.js index 435bd6e7d..4bb7aed4b 100644 --- a/packages/jats/title-group/TitleGroup.js +++ b/packages/jats/title-group/TitleGroup.js @@ -1,14 +1,8 @@ -'use strict'; - import { Container } from 'substance' -function TitleGroup() { - TitleGroup.super.apply(this, arguments); -} - -Container.extend(TitleGroup); +class TitleGroup extends Container {} -TitleGroup.type = "title-group"; +TitleGroup.type = "title-group" /* Content @@ -21,5 +15,4 @@ TitleGroup.define({ nodes: { type: ['id'], default: [] } }); - -export default TitleGroup; +export default TitleGroup diff --git a/packages/jats/title-group/TitleGroupComponent.js b/packages/jats/title-group/TitleGroupComponent.js index 6bc5b26a9..4d4aed110 100644 --- a/packages/jats/title-group/TitleGroupComponent.js +++ b/packages/jats/title-group/TitleGroupComponent.js @@ -1,37 +1,29 @@ -'use strict'; - import { Component } from 'substance' import renderNodeComponent from '../../../util/renderNodeComponent' -function TitleGroupComponent() { - Component.apply(this, arguments); -} - -TitleGroupComponent.Prototype = function() { +class TitleGroupComponent extends Component { - this.render = function($$) { - var node = this.props.node; - var doc = node.getDocument(); + render($$) { + let node = this.props.node + let doc = node.getDocument() - var el = $$('div') + let el = $$('div') .addClass('sc-title-group') - .attr('data-id', this.props.node.id); + .attr('data-id', this.props.node.id) - var children = node.nodes; + let children = node.nodes children.forEach(function(nodeId) { - var childNode = doc.get(nodeId); + let childNode = doc.get(nodeId) if (childNode.type !== 'unsupported') { el.append( renderNodeComponent(this, $$, childNode, { disabled: this.props.disabled }) - ); + ) } - }.bind(this)); - return el; - }; -}; - -Component.extend(TitleGroupComponent); + }.bind(this)) + return el + } +} -export default TitleGroupComponent; \ No newline at end of file +export default TitleGroupComponent diff --git a/packages/jats/title-group/TitleGroupConverter.js b/packages/jats/title-group/TitleGroupConverter.js index df34bfeff..b193222c8 100644 --- a/packages/jats/title-group/TitleGroupConverter.js +++ b/packages/jats/title-group/TitleGroupConverter.js @@ -1,5 +1,3 @@ -'use strict'; - import JATS from '../JATS' import XMLIterator from '../../../util/XMLIterator' @@ -20,27 +18,27 @@ export default { import: function(el, node, converter) { node.id = 'title-group'; // there is only be one body element - node.xmlAttributes = el.getAttributes(); + node.xmlAttributes = el.getAttributes() - var children = el.getChildren(); - var iterator = new XMLIterator(children); + var children = el.getChildren() + var iterator = new XMLIterator(children) // TODO: This is not strict enough. We want to check for the // element cardinalities: // (article-title, subtitle*, trans-title-group*, alt-title*, fn-group?) // We may want to use a helper for this (see #64) iterator.manyOf(JATS.TITLE_GROUP, function(child) { - node.nodes.push(converter.convertElement(child).id); + node.nodes.push(converter.convertElement(child).id) }); - if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML); + if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML) }, export: function(node, el, converter) { - el.attr(node.xmlAttributes); - el.append(converter.convertNodes(node.nodes)); + el.attr(node.xmlAttributes) + el.append(converter.convertNodes(node.nodes)) if (node.sigBlock) { - el.append(converter.convertNode(node.sigBlock)); + el.append(converter.convertNode(node.sigBlock)) } } -}; +} diff --git a/packages/jats/title-group/package.js b/packages/jats/title-group/package.js index 5e46dc34b..767e32e43 100644 --- a/packages/jats/title-group/package.js +++ b/packages/jats/title-group/package.js @@ -1,5 +1,3 @@ -'use strict'; - import TitleGroup from './TitleGroup' import TitleGroupConverter from './TitleGroupConverter' import TitleGroupComponent from './TitleGroupComponent' @@ -7,8 +5,8 @@ import TitleGroupComponent from './TitleGroupComponent' export default { name: 'title-group', configure: function(config) { - config.addNode(TitleGroup); - config.addConverter('jats', TitleGroupConverter); - config.addComponent(TitleGroup.type, TitleGroupComponent); + config.addNode(TitleGroup) + config.addConverter('jats', TitleGroupConverter) + config.addComponent(TitleGroup.type, TitleGroupComponent) } -}; +} \ No newline at end of file From 802fbae45892075dc46a88bea89179ca7a2b21c2 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 11:06:03 +0300 Subject: [PATCH 119/167] ES6 Aff package. --- packages/jats/aff/Aff.js | 10 +++------- packages/jats/aff/AffComponent.js | 6 ++---- packages/jats/aff/AffConverter.js | 4 ++-- packages/jats/aff/affUtils.js | 6 +++--- packages/jats/aff/package.js | 4 ++-- 5 files changed, 12 insertions(+), 18 deletions(-) diff --git a/packages/jats/aff/Aff.js b/packages/jats/aff/Aff.js index f34e11d5d..041c99002 100644 --- a/packages/jats/aff/Aff.js +++ b/packages/jats/aff/Aff.js @@ -1,12 +1,8 @@ -'use strict'; - import { DocumentNode } from 'substance' -import toDOM from '../../../util/toDOM' -class Aff extends DocumentNode { -} +class Aff extends DocumentNode {} -Aff.type = 'aff'; +Aff.type = 'aff' /* Content @@ -24,6 +20,6 @@ Aff.type = 'aff'; Aff.define({ attributes: { type: 'object', default: {} }, xmlContent: { type: 'string', default: ''} -}); +}) export default Aff diff --git a/packages/jats/aff/AffComponent.js b/packages/jats/aff/AffComponent.js index d971bb135..d625b7047 100644 --- a/packages/jats/aff/AffComponent.js +++ b/packages/jats/aff/AffComponent.js @@ -1,18 +1,16 @@ -'use strict'; - import { Component, FontAwesomeIcon as Icon } from 'substance' import { getAdapter } from './affUtils' class AffComponent extends Component { constructor(...args) { - super(...args); + super(...args) } render($$) { var aff = getAdapter(this.props.node); var el = $$('div').addClass('sc-aff') .append($$(Icon, {icon: 'fa-building-o'})) - .append(' '+aff.name); + .append(' '+aff.name) return el; } } diff --git a/packages/jats/aff/AffConverter.js b/packages/jats/aff/AffConverter.js index 58fd8b333..114266f1d 100644 --- a/packages/jats/aff/AffConverter.js +++ b/packages/jats/aff/AffConverter.js @@ -4,10 +4,10 @@ export default { tagName: 'aff', import: function(el, node, converter) { // eslint-disable-line - node.xmlContent = el.innerHTML; + node.xmlContent = el.innerHTML }, export: function(node, el, converter) { // eslint-disable-line - el.innerHTML = node.xmlContent; + el.innerHTML = node.xmlContent } } diff --git a/packages/jats/aff/affUtils.js b/packages/jats/aff/affUtils.js index d78716e4f..432bc5199 100644 --- a/packages/jats/aff/affUtils.js +++ b/packages/jats/aff/affUtils.js @@ -4,10 +4,10 @@ import toDOM from '../../../util/toDOM' Get all affiliations for a doc */ function getAffs(doc) { - var affs = doc.getIndex('type').get('aff'); + var affs = doc.getIndex('type').get('aff') // Convert to array and get the view for the node - affs = Object.keys(affs).map(affId => getAdapter(affs[affId])); - return affs; + affs = Object.keys(affs).map(affId => getAdapter(affs[affId])) + return affs } /* diff --git a/packages/jats/aff/package.js b/packages/jats/aff/package.js index 6766cd3fa..416284435 100644 --- a/packages/jats/aff/package.js +++ b/packages/jats/aff/package.js @@ -6,7 +6,7 @@ export default { name: 'aff', configure: function(config) { config.addNode(Aff) - config.addComponent(Aff.type, AffComponent); - config.addConverter('jats', AffConverter); + config.addComponent(Aff.type, AffComponent) + config.addConverter('jats', AffConverter) } } From 6b9982eeebd229040eb17c38b00574a8b4d7ddb0 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 11:08:54 +0300 Subject: [PATCH 120/167] ES6 Aff package. --- packages/jats/aff/AffComponent.js | 6 +++--- packages/jats/aff/affUtils.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/jats/aff/AffComponent.js b/packages/jats/aff/AffComponent.js index d625b7047..dfd3367cb 100644 --- a/packages/jats/aff/AffComponent.js +++ b/packages/jats/aff/AffComponent.js @@ -7,11 +7,11 @@ class AffComponent extends Component { } render($$) { - var aff = getAdapter(this.props.node); - var el = $$('div').addClass('sc-aff') + let aff = getAdapter(this.props.node) + let el = $$('div').addClass('sc-aff') .append($$(Icon, {icon: 'fa-building-o'})) .append(' '+aff.name) - return el; + return el } } diff --git a/packages/jats/aff/affUtils.js b/packages/jats/aff/affUtils.js index 432bc5199..50caefc13 100644 --- a/packages/jats/aff/affUtils.js +++ b/packages/jats/aff/affUtils.js @@ -4,7 +4,7 @@ import toDOM from '../../../util/toDOM' Get all affiliations for a doc */ function getAffs(doc) { - var affs = doc.getIndex('type').get('aff') + let affs = doc.getIndex('type').get('aff') // Convert to array and get the view for the node affs = Object.keys(affs).map(affId => getAdapter(affs[affId])) return affs @@ -15,7 +15,7 @@ function getAffs(doc) { rendered by the component. */ function getAdapter(node) { - var el = toDOM(node); + let el = toDOM(node); return { node: node, name: el.textContent From f0add1d988d27721b588cc56b75bc794fb658ee1 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 11:12:32 +0300 Subject: [PATCH 121/167] ES6 jats article package. --- packages/jats/article/ArticleComponent.js | 49 ++++++++++------------ packages/jats/article/ArticleConverter.js | 50 +++++++++++------------ packages/jats/article/ArticleNode.js | 14 +++---- packages/jats/article/TextureArticle.js | 12 +++--- packages/jats/article/package.js | 8 ++-- 5 files changed, 62 insertions(+), 71 deletions(-) diff --git a/packages/jats/article/ArticleComponent.js b/packages/jats/article/ArticleComponent.js index 3c73b6616..310876454 100644 --- a/packages/jats/article/ArticleComponent.js +++ b/packages/jats/article/ArticleComponent.js @@ -1,54 +1,49 @@ import { Component } from 'substance' import renderNodeComponent from '../../../util/renderNodeComponent' -function ArticleComponent() { - Component.apply(this, arguments); -} - -ArticleComponent.Prototype = function() { +class ArticleComponent extends Component { - this.render = function($$) { - var node = this.props.node; - var doc = node.getDocument(); - var configurator = this.props.configurator; - var el = $$('div') + render($$) { + let node = this.props.node + let doc = node.getDocument() + let configurator = this.props.configurator + let el = $$('div') .addClass('sc-article') - .attr('data-id', this.props.node.id); + .attr('data-id', this.props.node.id) // Render front - var front = doc.get('front'); + let front = doc.get('front') if (front) { - var frontEl = renderNodeComponent(this, $$, front, { + let frontEl = renderNodeComponent(this, $$, front, { disabled: this.props.disabled, configurator: configurator - }); - el.append(frontEl); + }) + el.append(frontEl) } // Render body - var body = doc.get(this.props.bodyId); + let body = doc.get(this.props.bodyId) if (body) { - var bodyEl = renderNodeComponent(this, $$, body, { + let bodyEl = renderNodeComponent(this, $$, body, { disabled: this.props.disabled, configurator: configurator - }); - el.append(bodyEl); + }) + el.append(bodyEl) } // Render back matter - var back = doc.get('back'); + let back = doc.get('back') if (back) { - var backEl = renderNodeComponent(this, $$, back, { + let backEl = renderNodeComponent(this, $$, back, { disabled: this.props.disabled, configurator: configurator }); - el.append(backEl); + el.append(backEl) } - return el; - }; -}; + return el + } -Component.extend(ArticleComponent); +} -export default ArticleComponent; \ No newline at end of file +export default ArticleComponent diff --git a/packages/jats/article/ArticleConverter.js b/packages/jats/article/ArticleConverter.js index d2e9b00a9..39952592e 100644 --- a/packages/jats/article/ArticleConverter.js +++ b/packages/jats/article/ArticleConverter.js @@ -23,51 +23,51 @@ export default { */ import: function(el, node, converter) { - node.id = 'article'; // there is only be one article element + node.id = 'article' // there is only be one article element - var children = el.getChildren(); - var iterator = new XMLIterator(children); + let children = el.getChildren() + let iterator = new XMLIterator(children) iterator.required('front', function(child) { - node.front = converter.convertElement(child).id; - }); + node.front = converter.convertElement(child).id + }) iterator.optional('body', function(child) { - node.body = converter.convertElement(child).id; - }); + node.body = converter.convertElement(child).id + }) iterator.optional('back', function(child) { - node.back = converter.convertElement(child).id; - }); + node.back = converter.convertElement(child).id + }) iterator.optional('floats-group', function(child) { - node.floatsGroup = converter.convertElement(child).id; - }); + node.floatsGroup = converter.convertElement(child).id + }) iterator.manyOf('sub-article', function(child) { - if (!node.subArticles) node.subArticles = []; - node.subArticles.push(converter.convertElement(child).id); - }); + if (!node.subArticles) node.subArticles = [] + node.subArticles.push(converter.convertElement(child).id) + }) iterator.manyOf('response', function(child) { - if (!node.responses) node.responses = []; - node.responses.push(converter.convertElement(child).id); - }); + if (!node.responses) node.responses = [] + node.responses.push(converter.convertElement(child).id) + }) if (iterator.hasNext()) { - throw new Error('Illegal JATS: ' + el.outerHTML); + throw new Error('Illegal JATS: ' + el.outerHTML) } }, export: function(node, el, converter) { - el.append(converter.convertNode(node.front)); + el.append(converter.convertNode(node.front)) if (node.body) { - el.append(converter.convertNode(node.body)); + el.append(converter.convertNode(node.body)) } if (node.back) { - el.append(converter.convertNode(node.back)); + el.append(converter.convertNode(node.back)) } if (node.floatsGroup) { - el.append(converter.convertNode(node.floatsGroup)); + el.append(converter.convertNode(node.floatsGroup)) } if (node.subArticles) { - el.append(converter.convertNodes(node.subArticles)); + el.append(converter.convertNodes(node.subArticles)) } if (node.responses) { - el.append(converter.convertNodes(node.responses)); + el.append(converter.convertNodes(node.responses)) } } -}; +} diff --git a/packages/jats/article/ArticleNode.js b/packages/jats/article/ArticleNode.js index 9b22a95c4..8a0e46d7e 100644 --- a/packages/jats/article/ArticleNode.js +++ b/packages/jats/article/ArticleNode.js @@ -1,12 +1,8 @@ import { DocumentNode } from 'substance' -function ArticleNode() { - ArticleNode.super.apply(this, arguments); -} +class ArticleNode extends DocumentNode {} -DocumentNode.extend(ArticleNode); - -ArticleNode.type = 'article'; +ArticleNode.type = 'article' /* Attributes @@ -32,7 +28,7 @@ ArticleNode.define({ back: { type: 'id', optional: true }, floatsGroup: { type: 'id', optional: true }, subArticles: { type: ['id'], optional: true }, - responses: { type: ['id'], optional: true }, -}); + responses: { type: ['id'], optional: true } +}) -export default ArticleNode; +export default ArticleNode diff --git a/packages/jats/article/TextureArticle.js b/packages/jats/article/TextureArticle.js index ce0685f3a..058668fc6 100644 --- a/packages/jats/article/TextureArticle.js +++ b/packages/jats/article/TextureArticle.js @@ -5,18 +5,18 @@ class TextureArticle extends Document { Get first RefList */ getRefList() { - var refLists = this.getIndex('type').get('ref-list'); - var refListId = Object.keys(refLists)[0]; - return refListId ? this.get(refListId) : undefined; + var refLists = this.getIndex('type').get('ref-list') + var refListId = Object.keys(refLists)[0] + return refListId ? this.get(refListId) : undefined } /* Get first ContribGroup */ getContribGroup() { - var contribGroups = this.getIndex('type').get('contrib-group'); - var contribGroupId = Object.keys(contribGroups)[0]; - return contribGroupId ? this.get(contribGroupId) : undefined; + var contribGroups = this.getIndex('type').get('contrib-group') + var contribGroupId = Object.keys(contribGroups)[0] + return contribGroupId ? this.get(contribGroupId) : undefined } } diff --git a/packages/jats/article/package.js b/packages/jats/article/package.js index 79dd14901..c50ff36b1 100644 --- a/packages/jats/article/package.js +++ b/packages/jats/article/package.js @@ -10,9 +10,9 @@ export default { name: 'texture-article', ArticleClass: TextureArticle, defaultTextType: 'paragraph' - }); - config.addNode(ArticleNode); - config.addConverter('jats', ArticleConverter); - config.addComponent(ArticleNode.type, ArticleComponent); + }) + config.addNode(ArticleNode) + config.addConverter('jats', ArticleConverter) + config.addComponent(ArticleNode.type, ArticleComponent) } } From a9156809879815142f707006c5906c3be547cf77 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 11:13:45 +0300 Subject: [PATCH 122/167] ES6 jats article. --- packages/jats/article/TextureArticle.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/jats/article/TextureArticle.js b/packages/jats/article/TextureArticle.js index 058668fc6..bd57116a8 100644 --- a/packages/jats/article/TextureArticle.js +++ b/packages/jats/article/TextureArticle.js @@ -5,8 +5,8 @@ class TextureArticle extends Document { Get first RefList */ getRefList() { - var refLists = this.getIndex('type').get('ref-list') - var refListId = Object.keys(refLists)[0] + let refLists = this.getIndex('type').get('ref-list') + let refListId = Object.keys(refLists)[0] return refListId ? this.get(refListId) : undefined } @@ -14,8 +14,8 @@ class TextureArticle extends Document { Get first ContribGroup */ getContribGroup() { - var contribGroups = this.getIndex('type').get('contrib-group') - var contribGroupId = Object.keys(contribGroups)[0] + let contribGroups = this.getIndex('type').get('contrib-group') + let contribGroupId = Object.keys(contribGroups)[0] return contribGroupId ? this.get(contribGroupId) : undefined } } From b749b64d9153b6f4dc5da3d5ca4d4dca4c603a70 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 11:19:19 +0300 Subject: [PATCH 123/167] ES6 jats article meta. --- packages/jats/article-meta/ArticleMeta.js | 12 +-- .../jats/article-meta/ArticleMetaComponent.js | 35 +++---- .../jats/article-meta/ArticleMetaConverter.js | 91 +++++++++---------- packages/jats/article-meta/package.js | 10 +- 4 files changed, 64 insertions(+), 84 deletions(-) diff --git a/packages/jats/article-meta/ArticleMeta.js b/packages/jats/article-meta/ArticleMeta.js index f5f9b1ddc..d7ff213a3 100644 --- a/packages/jats/article-meta/ArticleMeta.js +++ b/packages/jats/article-meta/ArticleMeta.js @@ -1,16 +1,12 @@ import { DocumentNode } from 'substance' -function ArticleMeta() { - ArticleMeta.super.apply(this, arguments); -} +class ArticleMeta extends DocumentNode {} -DocumentNode.extend(ArticleMeta); - -ArticleMeta.type = 'article-meta'; +ArticleMeta.type = 'article-meta' ArticleMeta.define({ attributes: { type: 'object', default: {} }, nodes: { type: ['id'], default: [] } -}); +}) -export default ArticleMeta; +export default ArticleMeta diff --git a/packages/jats/article-meta/ArticleMetaComponent.js b/packages/jats/article-meta/ArticleMetaComponent.js index 78df501e3..ec7a71e2a 100644 --- a/packages/jats/article-meta/ArticleMetaComponent.js +++ b/packages/jats/article-meta/ArticleMetaComponent.js @@ -1,25 +1,18 @@ -'use strict'; - import { Component } from 'substance' import renderNodeComponent from '../../../util/renderNodeComponent' -function ArticleMetaComponent() { - Component.apply(this, arguments); -} - -ArticleMetaComponent.Prototype = function() { +class ArticleMetaComponent extends Component { + render($$) { + let node = this.props.node + let doc = node.getDocument() - this.render = function($$) { - var node = this.props.node; - var doc = node.getDocument(); - - var el = $$('div') + let el = $$('div') .addClass('sc-article-meta') - .attr('data-id', this.props.node.id); + .attr('data-id', this.props.node.id) - var children = node.nodes; + let children = node.nodes children.forEach(function(nodeId) { - var childNode = doc.get(nodeId); + let childNode = doc.get(nodeId) if (childNode.type !== 'unsupported') { el.append( renderNodeComponent(this, $$, childNode, { @@ -27,11 +20,9 @@ ArticleMetaComponent.Prototype = function() { }) ); } - }.bind(this)); - return el; - }; -}; - -Component.extend(ArticleMetaComponent); + }.bind(this)) + return el + } +} -export default ArticleMetaComponent; \ No newline at end of file +export default ArticleMetaComponent diff --git a/packages/jats/article-meta/ArticleMetaConverter.js b/packages/jats/article-meta/ArticleMetaConverter.js index 7e126f3db..5bfcc923a 100644 --- a/packages/jats/article-meta/ArticleMetaConverter.js +++ b/packages/jats/article-meta/ArticleMetaConverter.js @@ -1,7 +1,4 @@ -'use strict'; - import XMLIterator from '../../../util/XMLIterator' - import JATS from '../JATS' export default { @@ -36,87 +33,85 @@ export default { */ import: function(el, node, converter) { node.id = 'article-meta'; // there is only one element - var iterator = new XMLIterator(el.getChildren()); - var elements; + let iterator = new XMLIterator(el.getChildren()) + let elements iterator.manyOf(['article-id'], function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.optional('article-categories', function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.optional('title-group', function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) // %contrib-group.class; | %aff-alternatives.class; | %x.class; elements = JATS.CONTRIB_GROUP .concat(JATS.AFF_ALTERNATIVES) - .concat(JATS.X); + .concat(JATS.X) iterator.manyOf(elements, function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.optional('author-notes', function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) // pub-date*, volume*, volume-id* iterator.manyOf(['pub-date', 'volume', 'volume-id'], function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.optional('volume-series', function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.manyOf(['issue', 'issue-id', 'issue-title', 'issue-sponsor'], function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.optional('issue-part', function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.manyOf(['volume-issue-group', 'isbn'], function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.optional('supplement', function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) // ( ( (fpage, lpage?)?, page-range?) | // elocation-id )?, // // TODO: XMLIterator can't handle such complex optionals atm iterator.manyOf(['fpage', 'lpage', 'page-range', 'elocation-id'], function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) // (%address-link.class; | product | // supplementary-material)*, elements = JATS.ADDRESS_LINK.concat(['product', 'supplementary-material']); iterator.manyOf(elements, function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.optional('history', function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.optional('permissions', function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) elements = ['self-uri'] .concat(JATS.RELATED_ARTICLE) .concat(JATS.ABSTRACT) .concat(['trans-abstract']) .concat(JATS.KWD_GROUP) - .concat(['funding-group', 'conference']); + .concat(['funding-group', 'conference']) iterator.manyOf(elements, function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.optional('counts', function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.optional('custom-meta-group', function(child) { - node.nodes.push(converter.convertElement(child).id); - }); - if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML); + node.nodes.push(converter.convertElement(child).id) + }) + if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML) }, export: function(node, el, converter) { - el.append(converter.convertNodes(node.nodes)); + el.append(converter.convertNodes(node.nodes)) } -}; - - +} diff --git a/packages/jats/article-meta/package.js b/packages/jats/article-meta/package.js index 611e22d81..0a3f2a9e9 100644 --- a/packages/jats/article-meta/package.js +++ b/packages/jats/article-meta/package.js @@ -1,5 +1,3 @@ -'use strict'; - import ArticleMeta from './ArticleMeta' import ArticleMetaConverter from './ArticleMetaConverter' import ArticleMetaComponent from './ArticleMetaComponent' @@ -7,8 +5,8 @@ import ArticleMetaComponent from './ArticleMetaComponent' export default { name: 'article-meta', configure: function(config) { - config.addNode(ArticleMeta); - config.addConverter('jats', ArticleMetaConverter); - config.addComponent(ArticleMeta.type, ArticleMetaComponent); + config.addNode(ArticleMeta) + config.addConverter('jats', ArticleMetaConverter) + config.addComponent(ArticleMeta.type, ArticleMetaComponent) } -}; +} From 62af3f5ad23286800c01228551df4869125ed672 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 11:24:39 +0300 Subject: [PATCH 124/167] ES6 jats article title package. --- packages/jats/article-title/ArticleTitle.js | 16 ++++------- .../article-title/ArticleTitleComponent.js | 28 ++++++------------- .../article-title/ArticleTitleConverter.js | 6 ++-- packages/jats/article-title/package.js | 10 +++---- 4 files changed, 20 insertions(+), 40 deletions(-) diff --git a/packages/jats/article-title/ArticleTitle.js b/packages/jats/article-title/ArticleTitle.js index 94e180fda..107893152 100644 --- a/packages/jats/article-title/ArticleTitle.js +++ b/packages/jats/article-title/ArticleTitle.js @@ -1,17 +1,11 @@ -'use strict'; - import { TextNode } from 'substance' -function ArticleTitle() { - ArticleTitle.super.apply(this, arguments); -} - -TextNode.extend(ArticleTitle); +class ArticleTitle extends TextNode {} -ArticleTitle.type = 'article-title'; +ArticleTitle.type = 'article-title' ArticleTitle.define({ - attributes: { type: 'object', default: {} }, -}); + attributes: { type: 'object', default: {} } +}) -export default ArticleTitle; \ No newline at end of file +export default ArticleTitle diff --git a/packages/jats/article-title/ArticleTitleComponent.js b/packages/jats/article-title/ArticleTitleComponent.js index 3167837c4..59aaec1f4 100644 --- a/packages/jats/article-title/ArticleTitleComponent.js +++ b/packages/jats/article-title/ArticleTitleComponent.js @@ -1,23 +1,13 @@ -'use strict'; - import TitleComponent from '../title/TitleComponent' -function ArticleTitleComponent() { - ArticleTitleComponent.super.apply(this, arguments); - +class ArticleTitleComponent extends TitleComponent { + + render(...args) { + let el = super.render(...args) + el.removeClass('sc-title') + el.addClass('sc-article-title') + return el + } } -ArticleTitleComponent.Prototype = function() { - var _super = ArticleTitleComponent.super.prototype; - - this.render = function() { - var el = _super.render.apply(this, arguments); - el.removeClass('sc-title'); - el.addClass('sc-article-title'); - return el; - }; -}; - -TitleComponent.extend(ArticleTitleComponent); - -export default ArticleTitleComponent; \ No newline at end of file +export default ArticleTitleComponent diff --git a/packages/jats/article-title/ArticleTitleConverter.js b/packages/jats/article-title/ArticleTitleConverter.js index c95dfac75..ba856f3c0 100644 --- a/packages/jats/article-title/ArticleTitleConverter.js +++ b/packages/jats/article-title/ArticleTitleConverter.js @@ -1,8 +1,6 @@ -'use strict'; - import TextNodeConverter from '../TextNodeConverter' export default TextNodeConverter.extend({ type: 'article-title', - tagName: 'article-title', -}); + tagName: 'article-title' +}) diff --git a/packages/jats/article-title/package.js b/packages/jats/article-title/package.js index ec61c4d90..d29ebf26e 100644 --- a/packages/jats/article-title/package.js +++ b/packages/jats/article-title/package.js @@ -1,5 +1,3 @@ -'use strict'; - import ArticleTitle from './ArticleTitle' import ArticleTitleConverter from './ArticleTitleConverter' import ArticleTitleComponent from './ArticleTitleComponent' @@ -7,9 +5,9 @@ import ArticleTitleComponent from './ArticleTitleComponent' export default { name: 'article-title', configure: function(config) { - config.addNode(ArticleTitle); - config.addConverter('jats', ArticleTitleConverter); - config.addComponent(ArticleTitle.type, ArticleTitleComponent); - config.addLabel('article-title.content', 'Title'); + config.addNode(ArticleTitle) + config.addConverter('jats', ArticleTitleConverter) + config.addComponent(ArticleTitle.type, ArticleTitleComponent) + config.addLabel('article-title.content', 'Title') } } From 12794a7797e85f635e5c3d578363702025e8089e Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 11:24:47 +0300 Subject: [PATCH 125/167] ES6 jats back package. --- packages/jats/back/Back.js | 16 ++++--------- packages/jats/back/BackComponent.js | 36 +++++++++++------------------ packages/jats/back/BackConverter.js | 24 +++++++++---------- packages/jats/back/package.js | 10 ++++---- 4 files changed, 34 insertions(+), 52 deletions(-) diff --git a/packages/jats/back/Back.js b/packages/jats/back/Back.js index b872a3425..48be6bfb3 100644 --- a/packages/jats/back/Back.js +++ b/packages/jats/back/Back.js @@ -1,5 +1,3 @@ -'use strict'; - import { Container } from 'substance' /* @@ -7,13 +5,9 @@ import { Container } from 'substance' Material published with an article but following the narrative flow. */ -function Back() { - Back.super.apply(this, arguments); -} - -Container.extend(Back); +class Back extends Container {} -Back.type = 'back'; +Back.type = 'back' /* Attributes @@ -28,7 +22,7 @@ Back.define({ attributes: { type: 'object', default: {} }, label: { type: 'label', optional:true }, titles: { type: ['title'], default: [] }, - nodes: { type: ['id'], default: [] }, -}); + nodes: { type: ['id'], default: [] } +}) -export default Back; +export default Back diff --git a/packages/jats/back/BackComponent.js b/packages/jats/back/BackComponent.js index ca8929a0b..6a0d234a3 100644 --- a/packages/jats/back/BackComponent.js +++ b/packages/jats/back/BackComponent.js @@ -1,26 +1,20 @@ -'use strict'; - import { Component } from 'substance' import renderNodeComponent from '../../../util/renderNodeComponent' -function BackComponent() { - Component.apply(this, arguments); -} - -BackComponent.Prototype = function() { +class BackComponent extends Component { - this.render = function($$) { - var node = this.props.node; - var doc = node.getDocument(); + render($$) { + let node = this.props.node + let doc = node.getDocument() - var el = $$('div') + let el = $$('div') .addClass('sc-back') - .attr('data-id', this.props.node.id); + .attr('data-id', this.props.node.id) // Ref elements - var children = node.nodes; + let children = node.nodes children.forEach(function(nodeId) { - var childNode = doc.get(nodeId); + let childNode = doc.get(nodeId) if (childNode.type !== 'unsupported') { el.append( renderNodeComponent(this, $$, childNode, { @@ -28,14 +22,12 @@ BackComponent.Prototype = function() { }) ); } else { - console.info(childNode.type+ ' inside currently not supported by the editor.'); + console.info(childNode.type+ ' inside currently not supported by the editor.') } - }.bind(this)); + }.bind(this)) - return el; - }; -}; - -Component.extend(BackComponent); + return el + } +} -export default BackComponent; \ No newline at end of file +export default BackComponent diff --git a/packages/jats/back/BackConverter.js b/packages/jats/back/BackConverter.js index 000cc2bcb..c7d584692 100644 --- a/packages/jats/back/BackConverter.js +++ b/packages/jats/back/BackConverter.js @@ -1,7 +1,5 @@ -'use strict'; - import XMLIterator from '../../../util/XMLIterator' -var BACK_CONTENT = ["ack", "app-group", "bio", "fn-group", "glossary", "ref-list", "notes", "sec"]; +let BACK_CONTENT = ["ack", "app-group", "bio", "fn-group", "glossary", "ref-list", "notes", "sec"] export default { @@ -15,29 +13,29 @@ export default { */ import: function(el, node, converter) { - node.id = 'back'; // There can only be one back item - var iterator = new XMLIterator(el.getChildren()); + node.id = 'back' // There can only be one back item + let iterator = new XMLIterator(el.getChildren()) iterator.optional('label', function(child) { - node.label = converter.convertElement(child).id; + node.label = converter.convertElement(child).id }); iterator.manyOf('title', function(child) { - node.titles.push(converter.convertElement(child).id); + node.titles.push(converter.convertElement(child).id) }); iterator.manyOf(BACK_CONTENT, function(child) { - node.nodes.push(converter.convertElement(child).id); + node.nodes.push(converter.convertElement(child).id) }); - if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML); + if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML) }, export: function(node, el, converter) { if(node.label) { - el.append(converter.convertNode(node.label)); + el.append(converter.convertNode(node.label)) } node.titles.forEach(function(nodeId) { - el.append(converter.convertNode(nodeId)); + el.append(converter.convertNode(nodeId)) }); node.nodes.forEach(function(nodeId) { - el.append(converter.convertNode(nodeId)); + el.append(converter.convertNode(nodeId)) }); } -}; +} diff --git a/packages/jats/back/package.js b/packages/jats/back/package.js index 7a06c2cd2..d289a4571 100644 --- a/packages/jats/back/package.js +++ b/packages/jats/back/package.js @@ -1,5 +1,3 @@ -'use strict'; - import Back from './Back' import BackConverter from './BackConverter' import BackComponent from './BackComponent' @@ -7,8 +5,8 @@ import BackComponent from './BackComponent' export default { name: 'back', configure: function(config) { - config.addNode(Back); - config.addConverter('jats', BackConverter); - config.addComponent(Back.type, BackComponent); + config.addNode(Back) + config.addConverter('jats', BackConverter) + config.addComponent(Back.type, BackComponent) } -}; \ No newline at end of file +} \ No newline at end of file From 1ac818784346f29de981217f3670a603a1465c15 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 11:27:30 +0300 Subject: [PATCH 126/167] ES6 jats body package. --- packages/jats/body/Body.js | 15 ++++---------- packages/jats/body/BodyComponent.js | 31 ++++++++++------------------ packages/jats/body/BodyConverter.js | 32 ++++++++++++++--------------- packages/jats/body/package.js | 10 ++++----- 4 files changed, 34 insertions(+), 54 deletions(-) diff --git a/packages/jats/body/Body.js b/packages/jats/body/Body.js index 08e46aacc..45b4649f3 100644 --- a/packages/jats/body/Body.js +++ b/packages/jats/body/Body.js @@ -1,14 +1,8 @@ -'use strict'; - import { Container } from 'substance' -function Body() { - Body.super.apply(this, arguments); -} - -Container.extend(Body); +class Body extends Container {} -Body.type = "body"; +Body.type = "body" /* Content @@ -21,7 +15,6 @@ Body.define({ attributes: { type: 'object', default: {} }, nodes: { type: ['id'], default: [] }, sigBlock: { type: ['sig-block'], optional: true } -}); - +}) -export default Body; +export default Body diff --git a/packages/jats/body/BodyComponent.js b/packages/jats/body/BodyComponent.js index 61d9f06d4..dcf68079f 100644 --- a/packages/jats/body/BodyComponent.js +++ b/packages/jats/body/BodyComponent.js @@ -1,19 +1,13 @@ -'use strict'; - import { Component, ContainerEditor } from 'substance' -function BodyComponent() { - Component.apply(this, arguments); -} - -BodyComponent.Prototype = function() { +class BodyComponent extends Component { - this.render = function($$) { - var node = this.props.node; - var configurator = this.props.configurator; - var el = $$('div') + render($$) { + let node = this.props.node + let configurator = this.props.configurator + let el = $$('div') .addClass('sc-body') - .attr('data-id', this.props.node.id); + .attr('data-id', this.props.node.id) el.append( $$(ContainerEditor, { @@ -22,12 +16,9 @@ BodyComponent.Prototype = function() { commands: configurator.getSurfaceCommandNames(), textTypes: configurator.getTextTypes() }).ref('body') - ); - return el; - }; -}; - - -Component.extend(BodyComponent); + ) + return el + } +} -export default BodyComponent; \ No newline at end of file +export default BodyComponent diff --git a/packages/jats/body/BodyConverter.js b/packages/jats/body/BodyConverter.js index a0d08c046..f8c0cad26 100644 --- a/packages/jats/body/BodyConverter.js +++ b/packages/jats/body/BodyConverter.js @@ -1,5 +1,3 @@ -'use strict'; - import JATS from '../JATS' import XMLIterator from '../../../util/XMLIterator' @@ -21,29 +19,29 @@ export default { */ import: function(el, node, converter) { - node.id = 'body'; // there is only be one body element - node.xmlAttributes = el.getAttributes(); + node.id = 'body' // there is only be one body element + node.xmlAttributes = el.getAttributes() - var children = el.getChildren(); - var iterator = new XMLIterator(children); + let children = el.getChildren() + let iterator = new XMLIterator(children) iterator.manyOf(JATS.PARA_LEVEL, function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.manyOf('sec', function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.optional('sig-block', function(child) { - node.sigBlock = converter.convertElement(child).id; - }); - if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML); + node.sigBlock = converter.convertElement(child).id + }) + if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML) }, export: function(node, el, converter) { - el.attr(node.xmlAttributes); - el.append(converter.convertNodes(node.nodes)); + el.attr(node.xmlAttributes) + el.append(converter.convertNodes(node.nodes)) if (node.sigBlock) { - el.append(converter.convertNode(node.sigBlock)); + el.append(converter.convertNode(node.sigBlock)) } } -}; +} diff --git a/packages/jats/body/package.js b/packages/jats/body/package.js index be3ea8b1c..1f0c6491f 100644 --- a/packages/jats/body/package.js +++ b/packages/jats/body/package.js @@ -1,5 +1,3 @@ -'use strict'; - import Body from './Body' import BodyConverter from './BodyConverter' import BodyComponent from './BodyComponent' @@ -7,8 +5,8 @@ import BodyComponent from './BodyComponent' export default { name: 'body', configure: function(config) { - config.addNode(Body); - config.addConverter('jats', BodyConverter); - config.addComponent(Body.type, BodyComponent); + config.addNode(Body) + config.addConverter('jats', BodyConverter) + config.addComponent(Body.type, BodyComponent) } -}; \ No newline at end of file +} \ No newline at end of file From fab68794ae00ea0dcac1df4c273d9ff7a15b806f Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 11:29:25 +0300 Subject: [PATCH 127/167] ES6 jats bold package. --- packages/jats/bold/Bold.js | 16 +++++----------- packages/jats/bold/BoldCommand.js | 2 -- packages/jats/bold/BoldConverter.js | 4 +--- packages/jats/bold/BoldTool.js | 2 +- packages/jats/bold/package.js | 16 +++++++--------- 5 files changed, 14 insertions(+), 26 deletions(-) diff --git a/packages/jats/bold/Bold.js b/packages/jats/bold/Bold.js index 1d37e09cb..5553f61b0 100644 --- a/packages/jats/bold/Bold.js +++ b/packages/jats/bold/Bold.js @@ -1,17 +1,11 @@ -'use strict'; - import { Annotation } from 'substance' -function Bold() { - Bold.super.apply(this, arguments); -} - -Annotation.extend(Bold); +class Bold extends Annotation {} -Bold.type = 'bold'; +Bold.type = 'bold' Bold.define({ - attributes: { type: 'object', default: {} }, -}); + attributes: { type: 'object', default: {} } +}) -export default Bold; +export default Bold diff --git a/packages/jats/bold/BoldCommand.js b/packages/jats/bold/BoldCommand.js index f7b663890..4fb74b6e2 100644 --- a/packages/jats/bold/BoldCommand.js +++ b/packages/jats/bold/BoldCommand.js @@ -1,5 +1,3 @@ -'use strict'; - import { AnnotationCommand } from 'substance' class BoldCommand extends AnnotationCommand {} diff --git a/packages/jats/bold/BoldConverter.js b/packages/jats/bold/BoldConverter.js index b51bc0d89..c3b7a5bba 100644 --- a/packages/jats/bold/BoldConverter.js +++ b/packages/jats/bold/BoldConverter.js @@ -1,6 +1,4 @@ -'use strict'; - export default { type: 'bold', tagName: 'bold' -}; +} diff --git a/packages/jats/bold/BoldTool.js b/packages/jats/bold/BoldTool.js index 4e08b567d..ca513c44d 100644 --- a/packages/jats/bold/BoldTool.js +++ b/packages/jats/bold/BoldTool.js @@ -2,4 +2,4 @@ import { AnnotationTool } from 'substance' class BoldTool extends AnnotationTool {} -export default BoldTool \ No newline at end of file +export default BoldTool diff --git a/packages/jats/bold/package.js b/packages/jats/bold/package.js index 8ee9fc245..a546315bd 100644 --- a/packages/jats/bold/package.js +++ b/packages/jats/bold/package.js @@ -1,5 +1,3 @@ -'use strict'; - import Bold from './Bold' import BoldConverter from './BoldConverter' import BoldTool from './BoldTool' @@ -8,13 +6,13 @@ import BoldCommand from './BoldCommand' export default { name: 'bold', configure: function(config) { - config.addNode(Bold); - config.addConverter('jats', BoldConverter); - config.addCommand(Bold.type, BoldCommand, { nodeType: Bold.type }); - config.addTool(Bold.type, BoldTool, {target: 'annotations'}); - config.addIcon(Bold.type, { 'fontawesome': 'fa-bold' }); + config.addNode(Bold) + config.addConverter('jats', BoldConverter) + config.addCommand(Bold.type, BoldCommand, { nodeType: Bold.type }) + config.addTool(Bold.type, BoldTool, {target: 'annotations'}) + config.addIcon(Bold.type, { 'fontawesome': 'fa-bold' }) config.addLabel(Bold.type, { en: 'Bold' - }); + }) } -}; +} From e0e5b883fc544cc9d392af7d0fdff15ad005ee73 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 11:31:24 +0300 Subject: [PATCH 128/167] ES6 jats caption package. --- packages/jats/caption/Caption.js | 22 ++++-------- packages/jats/caption/CaptionComponent.js | 42 +++++++++-------------- packages/jats/caption/CaptionConverter.js | 26 +++++++------- packages/jats/caption/package.js | 10 +++--- 4 files changed, 40 insertions(+), 60 deletions(-) diff --git a/packages/jats/caption/Caption.js b/packages/jats/caption/Caption.js index c423c53b5..e9ebb93b4 100644 --- a/packages/jats/caption/Caption.js +++ b/packages/jats/caption/Caption.js @@ -1,25 +1,17 @@ -'use strict'; - import { Container } from 'substance' -function Caption() { - Caption.super.apply(this, arguments); -} - -Caption.Prototype = function() { +class Caption extends Container { - this.getTitle = function() { + getTitle() { var doc = this.getDocument(); if (doc) { return doc.get(this.title); } - }; + } -}; - -Container.extend(Caption); +} -Caption.type = 'caption'; +Caption.type = 'caption' /* Attributes @@ -37,6 +29,6 @@ Caption.define({ attributes: { type: 'object', default: {} }, title: { type: 'title', optional: true }, nodes: { type: ['p'], default: [] } -}); +}) -export default Caption; \ No newline at end of file +export default Caption diff --git a/packages/jats/caption/CaptionComponent.js b/packages/jats/caption/CaptionComponent.js index 0933626ac..17fe20623 100644 --- a/packages/jats/caption/CaptionComponent.js +++ b/packages/jats/caption/CaptionComponent.js @@ -1,41 +1,33 @@ -'use strict'; - import { Component, ContainerEditor, TextPropertyEditor } from 'substance' -function CaptionComponent() { - Component.apply(this, arguments); -} - -CaptionComponent.Prototype = function() { +class CaptionComponent extends Component { - this.render = function($$) { - var node = this.props.node; - var doc = node.getDocument(); + render($$) { + let node = this.props.node + let doc = node.getDocument() - var el = $$('div') + let el = $$('div') .addClass('sc-caption') - .attr('data-id', node.id); + .attr('data-id', node.id) if (node.title) { - var title = doc.get(node.title); + let title = doc.get(node.title); el.append($$(TextPropertyEditor, { disabled: this.props.disabled, path: title.getTextPath() - })).ref('title'); + })).ref('title') } - var contentEl = $$('div').addClass('se-content'); - var contentEditor = $$(ContainerEditor, { + let contentEl = $$('div').addClass('se-content') + let contentEditor = $$(ContainerEditor, { disabled: this.props.disabled, node: node - }).ref('content'); - contentEl.append(contentEditor); - el.append(contentEl); + }).ref('content') + contentEl.append(contentEditor) + el.append(contentEl) - return el; - }; -}; - -Component.extend(CaptionComponent); + return el + } +} -export default CaptionComponent; +export default CaptionComponent diff --git a/packages/jats/caption/CaptionConverter.js b/packages/jats/caption/CaptionConverter.js index 43917820d..bbab175bb 100644 --- a/packages/jats/caption/CaptionConverter.js +++ b/packages/jats/caption/CaptionConverter.js @@ -1,5 +1,3 @@ -'use strict'; - import XMLIterator from '../../../util/XMLIterator' export default { @@ -21,26 +19,26 @@ export default { */ import: function(el, node, converter) { - node.xmlAttributes = el.getAttributes(); + node.xmlAttributes = el.getAttributes() - var children = el.getChildren(); - var iterator = new XMLIterator(children); + let children = el.getChildren() + let iterator = new XMLIterator(children) // title is just annotated text iterator.optional('title', function(childEl) { - node.title = converter.convertElement(childEl).id; - }); + node.title = converter.convertElement(childEl).id + }) iterator.manyOf('p', function(childEl) { - node.nodes.push(converter.convertElement(childEl).id); - }); + node.nodes.push(converter.convertElement(childEl).id) + }) if (iterator.hasNext()) { - throw new Error('Invalid JATS:' + el.outerHTML); + throw new Error('Invalid JATS:' + el.outerHTML) } }, export: function(node, el, converter) { - el.attr(node.xmlAttributes); - if (node.title) el.append(converter.convertNode(node.title)); - el.append(converter.convertNodes(node.nodes)); + el.attr(node.xmlAttributes) + if (node.title) el.append(converter.convertNode(node.title)) + el.append(converter.convertNodes(node.nodes)) } -}; +} diff --git a/packages/jats/caption/package.js b/packages/jats/caption/package.js index 8e1229d0b..bb232c06e 100644 --- a/packages/jats/caption/package.js +++ b/packages/jats/caption/package.js @@ -1,5 +1,3 @@ -'use strict'; - import Caption from './Caption' import CaptionComponent from './CaptionComponent' import CaptionConverter from './CaptionConverter' @@ -7,8 +5,8 @@ import CaptionConverter from './CaptionConverter' export default { name: 'caption', configure: function(config) { - config.addNode(Caption); - config.addComponent(Caption.type, CaptionComponent); - config.addConverter('jats', CaptionConverter); + config.addNode(Caption) + config.addComponent(Caption.type, CaptionComponent) + config.addConverter('jats', CaptionConverter) } -}; \ No newline at end of file +} From 0cb9bd9fd434ef8be6307ce6fd66061a0091da9e Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 12:10:11 +0300 Subject: [PATCH 129/167] ES6 jats contrib package. --- packages/jats/contrib/Contrib.js | 10 ++-- packages/jats/contrib/ContribComponent.js | 61 +++++++++++------------ packages/jats/contrib/ContribConverter.js | 8 ++- packages/jats/contrib/EditContrib.js | 58 +++++++++++---------- packages/jats/contrib/contribUtils.js | 38 +++++++------- packages/jats/contrib/package.js | 6 +-- 6 files changed, 84 insertions(+), 97 deletions(-) diff --git a/packages/jats/contrib/Contrib.js b/packages/jats/contrib/Contrib.js index 6fc7ddd9d..a7f615ec1 100644 --- a/packages/jats/contrib/Contrib.js +++ b/packages/jats/contrib/Contrib.js @@ -1,10 +1,6 @@ -'use strict'; - import { DocumentNode } from 'substance' -class Contrib extends DocumentNode { - -} +class Contrib extends DocumentNode {} Contrib.type = 'contrib'; @@ -21,6 +17,6 @@ Contrib.type = 'contrib'; Contrib.define({ attributes: { type: 'object', default: {} }, xmlContent: { type: 'string', default: ''} -}); +}) -export default Contrib; +export default Contrib diff --git a/packages/jats/contrib/ContribComponent.js b/packages/jats/contrib/ContribComponent.js index 6e9c98e97..f004f5458 100644 --- a/packages/jats/contrib/ContribComponent.js +++ b/packages/jats/contrib/ContribComponent.js @@ -1,41 +1,38 @@ -'use strict'; - import { Component } from 'substance' import EditXML from '../../common/EditXML' import EditContrib from './EditContrib' import { getAdapter } from './contribUtils' -function ContribComponent() { - ContribComponent.super.apply(this, arguments); - - this.handleActions({ - 'closeModal': this._closeModal, - 'xmlSaved': this._closeModal - }); +class ContribComponent extends Component { + constructor(...args) { + super(...args) - this.props.node.on('properties:changed', this.rerender, this); -} + this.handleActions({ + 'closeModal': this._closeModal, + 'xmlSaved': this._closeModal + }) -ContribComponent.Prototype = function() { + this.props.node.on('properties:changed', this.rerender, this) + } - this.render = function($$) { - var Modal = this.getComponent('modal'); - var contrib = getAdapter(this.props.node); - var el = $$('div').addClass('sc-contrib') + render($$) { + let Modal = this.getComponent('modal') + let contrib = getAdapter(this.props.node) + let el = $$('div').addClass('sc-contrib') .append( $$('div').addClass('se-name') .append(contrib.fullName) .on('click', this._toggleEditor) - ); + ) if (this.state.editXML) { // Conforms to strict markup enforced by texture // for visual editing - var EditorClass; + let EditorClass if (contrib.strict) { - EditorClass = EditContrib; + EditorClass = EditContrib } else { - EditorClass = EditXML; + EditorClass = EditXML } el.append( @@ -44,25 +41,23 @@ ContribComponent.Prototype = function() { }).append( $$(EditorClass, contrib) ) - ); + ) } - return el; - }; + return el + } - this._closeModal = function() { + _closeModal() { this.setState({ editXML: false - }); - }; + }) + } - this._toggleEditor = function() { + _toggleEditor() { this.setState({ editXML: true - }); - }; + }) + } -}; - -Component.extend(ContribComponent); +} -export default ContribComponent; +export default ContribComponent diff --git a/packages/jats/contrib/ContribConverter.js b/packages/jats/contrib/ContribConverter.js index db83fa9d7..f5273d5e2 100644 --- a/packages/jats/contrib/ContribConverter.js +++ b/packages/jats/contrib/ContribConverter.js @@ -1,5 +1,3 @@ -'use strict'; - export default { type: 'contrib', @@ -9,10 +7,10 @@ export default { (label?, (citation-alternatives | element-citation | mixed-citation | nlm-citation | note | x)+) */ import: function(el, node, converter) { // eslint-disable-line - node.xmlContent = el.innerHTML; + node.xmlContent = el.innerHTML }, export: function(node, el, converter) { // eslint-disable-line - el.innerHTML = node.xmlContent; + el.innerHTML = node.xmlContent } -}; +} diff --git a/packages/jats/contrib/EditContrib.js b/packages/jats/contrib/EditContrib.js index be553cd77..23f0d7ea8 100644 --- a/packages/jats/contrib/EditContrib.js +++ b/packages/jats/contrib/EditContrib.js @@ -1,35 +1,33 @@ -'use strict'; - import { Component } from 'substance' import { saveContrib } from './contribUtils' class EditContrib extends Component { getXML() { - return this.refs.xml.val(); + return this.refs.xml.val() } render($$) { - var Input = this.getComponent('input'); - var Button = this.getComponent('button'); + let Input = this.getComponent('input') + let Button = this.getComponent('button') - var el = $$('div').addClass('sc-edit-contrib'); - var affs = this.props.affs; - var fullName = this.props.fullName; - var selectedAffs = this.props.selectedAffs; + let el = $$('div').addClass('sc-edit-contrib') + let affs = this.props.affs + let fullName = this.props.fullName + let selectedAffs = this.props.selectedAffs - var affSel = $$('select').attr({multiple: 'multiple'}).ref('affSel'); + let affSel = $$('select').attr({multiple: 'multiple'}).ref('affSel') affs.forEach(function(a) { - var opt = $$('option') + let opt = $$('option') .attr({value: a.node.id}) - .append(a.name); + .append(a.name) if (selectedAffs[a.node.id]) { - opt.attr('selected', 'selected'); + opt.attr('selected', 'selected') } - affSel.append(opt); - }); + affSel.append(opt) + }) el.append( $$('div').addClass('se-label').append('Name:'), @@ -42,56 +40,56 @@ class EditContrib extends Component { ), $$('div').addClass('se-label').append('Affiliations:'), affSel - ); + ) el.append( $$('div').addClass('se-actions').append( $$(Button).append('Save').on('click', this._save), $$(Button).addClass('se-cancel').append('Cancel').on('click', this._cancel) ) - ); - return el; + ) + return el } _save() { - var contribData = { + let contribData = { id: this.props.node.id, selectedAffs: getSelectedOptions(this.refs.affSel.el.el), fullName: this.refs.fullName.val() - }; + } - var documentSession = this.context.documentSession; - saveContrib(documentSession, contribData); - this.send('closeModal'); + let documentSession = this.context.documentSession + saveContrib(documentSession, contribData) + this.send('closeModal') } _cancel() { - this.send('closeModal'); + this.send('closeModal') } } // arguments: reference to select list, callback function (optional) function getSelectedOptions(sel, fn) { - var opts = [], opt; + let opts = [], opt // loop through options in select list - for (var i=0, len=sel.options.length; i Date: Thu, 29 Sep 2016 12:12:42 +0300 Subject: [PATCH 130/167] ES6 jats contrib group package. --- packages/jats/contrib-group/ContribGroup.js | 14 +++----- .../contrib-group/ContribGroupComponent.js | 34 +++++++++---------- .../contrib-group/ContribGroupConverter.js | 24 ++++++------- packages/jats/contrib-group/package.js | 10 +++--- 4 files changed, 35 insertions(+), 47 deletions(-) diff --git a/packages/jats/contrib-group/ContribGroup.js b/packages/jats/contrib-group/ContribGroup.js index 4a4c460c5..e16c79316 100644 --- a/packages/jats/contrib-group/ContribGroup.js +++ b/packages/jats/contrib-group/ContribGroup.js @@ -1,18 +1,12 @@ -'use strict'; - import { Container } from 'substance' -function ContribGroup() { - ContribGroup.super.apply(this, arguments); -} - -Container.extend(ContribGroup); +class ContribGroup extends Container {} -ContribGroup.type = "contrib-group"; +ContribGroup.type = "contrib-group" ContribGroup.define({ attributes: { type: 'object', default: {} }, nodes: { type: ['id'], default: [] } -}); +}) -export default ContribGroup; +export default ContribGroup diff --git a/packages/jats/contrib-group/ContribGroupComponent.js b/packages/jats/contrib-group/ContribGroupComponent.js index 1b1439c4d..309470aac 100644 --- a/packages/jats/contrib-group/ContribGroupComponent.js +++ b/packages/jats/contrib-group/ContribGroupComponent.js @@ -1,45 +1,43 @@ -'use strict'; - import { Component } from 'substance' import renderNodeComponent from '../../../util/renderNodeComponent' class ContribGroupComponent extends Component { didMount() { - super.didMount(); - var node = this.props.node; - node.on('nodes:changed', this.rerender, this); + super.didMount() + let node = this.props.node + node.on('nodes:changed', this.rerender, this) } dispose() { - super.dispose(); - var node = this.props.node; - node.off(this); + super.dispose() + let node = this.props.node + node.off(this) } render($$) { - var node = this.props.node; - var doc = node.getDocument(); + let node = this.props.node + let doc = node.getDocument() - var el = $$('div') + let el = $$('div') .addClass('sc-contrib-group') - .attr('data-id', this.props.node.id); + .attr('data-id', this.props.node.id) - var children = node.nodes; + let children = node.nodes children.forEach(function(nodeId) { - var childNode = doc.get(nodeId); + let childNode = doc.get(nodeId) if (childNode.type !== 'unsupported') { el.append( renderNodeComponent(this, $$, childNode, { disabled: this.props.disabled }) - ); + ) } - }.bind(this)); + }.bind(this)) // el.append($$('button').addClass('se-add-author').append('Add Author')); - return el; + return el } } -export default ContribGroupComponent; \ No newline at end of file +export default ContribGroupComponent diff --git a/packages/jats/contrib-group/ContribGroupConverter.js b/packages/jats/contrib-group/ContribGroupConverter.js index 850d076b2..2cd421ce2 100644 --- a/packages/jats/contrib-group/ContribGroupConverter.js +++ b/packages/jats/contrib-group/ContribGroupConverter.js @@ -1,8 +1,6 @@ -'use strict'; - import XMLIterator from '../../../util/XMLIterator' -var CONTRIB_GROUP = ['contrib', 'address', 'aff', 'aff-alternatives', 'author-comment', 'bio', 'email', 'etal', 'ext-link', 'fn', 'on-behalf-of', 'role', 'uri', 'xref', 'x']; +let CONTRIB_GROUP = ['contrib', 'address', 'aff', 'aff-alternatives', 'author-comment', 'bio', 'email', 'etal', 'ext-link', 'fn', 'on-behalf-of', 'role', 'uri', 'xref', 'x'] export default { @@ -11,23 +9,23 @@ export default { import: function(el, node, converter) { // node.id = 'contrib-group'; // there is only be one body element - node.xmlAttributes = el.getAttributes(); + node.xmlAttributes = el.getAttributes() - var children = el.getChildren(); - var iterator = new XMLIterator(children); + let children = el.getChildren() + let iterator = new XMLIterator(children) iterator.oneOrMoreOf(CONTRIB_GROUP, function(child) { - node.nodes.push(converter.convertElement(child).id); - }); - if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML); + node.nodes.push(converter.convertElement(child).id) + }) + if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML) }, export: function(node, el, converter) { - el.attr(node.xmlAttributes); - el.append(converter.convertNodes(node.nodes)); + el.attr(node.xmlAttributes) + el.append(converter.convertNodes(node.nodes)) if (node.sigBlock) { - el.append(converter.convertNode(node.sigBlock)); + el.append(converter.convertNode(node.sigBlock)) } } -}; +} diff --git a/packages/jats/contrib-group/package.js b/packages/jats/contrib-group/package.js index 2bde9a4c3..3859de922 100644 --- a/packages/jats/contrib-group/package.js +++ b/packages/jats/contrib-group/package.js @@ -1,5 +1,3 @@ -'use strict'; - import ContribGroup from './ContribGroup' import ContribGroupConverter from './ContribGroupConverter' import ContribGroupComponent from './ContribGroupComponent' @@ -7,8 +5,8 @@ import ContribGroupComponent from './ContribGroupComponent' export default { name: 'contrib-group', configure: function(config) { - config.addNode(ContribGroup); - config.addConverter('jats', ContribGroupConverter); - config.addComponent(ContribGroup.type, ContribGroupComponent); + config.addNode(ContribGroup) + config.addConverter('jats', ContribGroupConverter) + config.addComponent(ContribGroup.type, ContribGroupComponent) } -}; +} From 09625b273280b28db269b518871c30950133cedc Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 12:20:47 +0300 Subject: [PATCH 131/167] ES6 jats ext-link package. --- packages/jats/ext-link/EditExtLinkCommand.js | 8 ++---- packages/jats/ext-link/EditExtLinkTool.js | 11 +++------ packages/jats/ext-link/ExtLink.js | 19 +++++--------- packages/jats/ext-link/ExtLinkCommand.js | 4 +-- packages/jats/ext-link/ExtLinkComponent.js | 10 +++----- packages/jats/ext-link/ExtLinkConverter.js | 4 +-- packages/jats/ext-link/ExtLinkTool.js | 2 +- packages/jats/ext-link/package.js | 26 +++++++++----------- 8 files changed, 31 insertions(+), 53 deletions(-) diff --git a/packages/jats/ext-link/EditExtLinkCommand.js b/packages/jats/ext-link/EditExtLinkCommand.js index 4627cd05d..9ac2b9be4 100644 --- a/packages/jats/ext-link/EditExtLinkCommand.js +++ b/packages/jats/ext-link/EditExtLinkCommand.js @@ -1,9 +1,5 @@ -'use strict'; - import { EditLinkCommand } from 'substance' -class EditExtLinkCommand extends EditLinkCommand { - -} +class EditExtLinkCommand extends EditLinkCommand {} -export default EditExtLinkCommand \ No newline at end of file +export default EditExtLinkCommand diff --git a/packages/jats/ext-link/EditExtLinkTool.js b/packages/jats/ext-link/EditExtLinkTool.js index 166ab54fd..ba92dfe34 100644 --- a/packages/jats/ext-link/EditExtLinkTool.js +++ b/packages/jats/ext-link/EditExtLinkTool.js @@ -1,12 +1,7 @@ -'use strict'; - import { EditLinkTool } from 'substance' -import clone from 'lodash/clone' - -class EditExtLinkTool extends EditLinkTool { -} +class EditExtLinkTool extends EditLinkTool {} -EditExtLinkTool.urlPropertyPath = ['attributes', 'xlink:href']; +EditExtLinkTool.urlPropertyPath = ['attributes', 'xlink:href'] -export default EditExtLinkTool; +export default EditExtLinkTool diff --git a/packages/jats/ext-link/ExtLink.js b/packages/jats/ext-link/ExtLink.js index 30a9deb4b..2e82a6560 100644 --- a/packages/jats/ext-link/ExtLink.js +++ b/packages/jats/ext-link/ExtLink.js @@ -1,21 +1,14 @@ -'use strict'; - import { Annotation, Fragmenter } from 'substance' -function ExtLink() { - ExtLink.super.apply(this, arguments); -} - -Annotation.extend(ExtLink); +class ExtLink extends Annotation {} -ExtLink.type = "ext-link"; +ExtLink.type = "ext-link" ExtLink.define({ - attributes: { type: 'object', default: {} }, -}); - + attributes: { type: 'object', default: {} } +}) // in presence of overlapping annotations will try to render this as one element -ExtLink.fragmentation = Fragmenter.SHOULD_NOT_SPLIT; +ExtLink.fragmentation = Fragmenter.SHOULD_NOT_SPLIT -export default ExtLink; +export default ExtLink diff --git a/packages/jats/ext-link/ExtLinkCommand.js b/packages/jats/ext-link/ExtLinkCommand.js index aceb4cdba..dbc54ae58 100644 --- a/packages/jats/ext-link/ExtLinkCommand.js +++ b/packages/jats/ext-link/ExtLinkCommand.js @@ -1,5 +1,3 @@ -'use strict'; - import { LinkCommand } from 'substance' class ExtLinkCommand extends LinkCommand { @@ -13,4 +11,4 @@ class ExtLinkCommand extends LinkCommand { } } -export default ExtLinkCommand \ No newline at end of file +export default ExtLinkCommand diff --git a/packages/jats/ext-link/ExtLinkComponent.js b/packages/jats/ext-link/ExtLinkComponent.js index bf7419662..cbb7daba8 100644 --- a/packages/jats/ext-link/ExtLinkComponent.js +++ b/packages/jats/ext-link/ExtLinkComponent.js @@ -1,5 +1,3 @@ -'use strict'; - import { AnnotationComponent } from 'substance' class ExtLinkComponent extends AnnotationComponent { @@ -7,20 +5,20 @@ class ExtLinkComponent extends AnnotationComponent { didMount() { super.didMount.apply(this, arguments) - var node = this.props.node + let node = this.props.node node.on('properties:changed', this.rerender, this) } dispose() { super.dispose.apply(this, arguments) - var node = this.props.node + let node = this.props.node node.off(this) } render($$) { // eslint-disable-line - var node = this.props.node; - var el = super.render.apply(this, arguments) + let node = this.props.node; + let el = super.render.apply(this, arguments) el.tagName = 'a' el.attr('href', node.attributes['xlink:href']) diff --git a/packages/jats/ext-link/ExtLinkConverter.js b/packages/jats/ext-link/ExtLinkConverter.js index 7eaed83ba..a2a6c7dbd 100644 --- a/packages/jats/ext-link/ExtLinkConverter.js +++ b/packages/jats/ext-link/ExtLinkConverter.js @@ -1,4 +1,4 @@ -'use strict'; +'use strict' export default { @@ -30,4 +30,4 @@ export default { tex-math | mml:math | abbrev | milestone-end | milestone-start | named-content | styled-content | fn | target | xref | sub | sup | x)* */ -}; +} diff --git a/packages/jats/ext-link/ExtLinkTool.js b/packages/jats/ext-link/ExtLinkTool.js index cf601eaba..c1cba0f95 100644 --- a/packages/jats/ext-link/ExtLinkTool.js +++ b/packages/jats/ext-link/ExtLinkTool.js @@ -2,4 +2,4 @@ import { AnnotationTool } from 'substance' class ExtLinkTool extends AnnotationTool {} -export default ExtLinkTool \ No newline at end of file +export default ExtLinkTool diff --git a/packages/jats/ext-link/package.js b/packages/jats/ext-link/package.js index d33c32653..6e729931a 100644 --- a/packages/jats/ext-link/package.js +++ b/packages/jats/ext-link/package.js @@ -1,5 +1,3 @@ -'use strict'; - import ExtLink from './ExtLink' import ExtLinkConverter from './ExtLinkConverter' import ExtLinkComponent from './ExtLinkComponent' @@ -11,26 +9,26 @@ import EditExtLinkTool from './EditExtLinkTool' export default { name: 'ext-link', configure: function(config) { - config.addNode(ExtLink); - config.addConverter('jats', ExtLinkConverter); - config.addComponent(ExtLink.type, ExtLinkComponent); + config.addNode(ExtLink) + config.addConverter('jats', ExtLinkConverter) + config.addComponent(ExtLink.type, ExtLinkComponent) - config.addCommand(ExtLink.type, ExtLinkCommand, {nodeType: ExtLink.type}); - config.addCommand('edit-ext-link', EditExtLinkCommand, {nodeType: ExtLink.type}); - config.addTool(ExtLink.type, ExtLinkTool, {target: 'annotations'}); - config.addTool('edit-ext-link', EditExtLinkTool, { target: 'overlay' }); - config.addIcon(ExtLink.type, { 'fontawesome': 'fa-link'}); - config.addIcon('open-link', { 'fontawesome': 'fa-external-link' }); + config.addCommand(ExtLink.type, ExtLinkCommand, {nodeType: ExtLink.type}) + config.addCommand('edit-ext-link', EditExtLinkCommand, {nodeType: ExtLink.type}) + config.addTool(ExtLink.type, ExtLinkTool, {target: 'annotations'}) + config.addTool('edit-ext-link', EditExtLinkTool, { target: 'overlay' }) + config.addIcon(ExtLink.type, { 'fontawesome': 'fa-link'}) + config.addIcon('open-link', { 'fontawesome': 'fa-external-link' }) config.addLabel(ExtLink.type, { en: 'Link' - }); + }) config.addLabel('open-link', { en: 'Open Link', de: 'Link öffnen' - }); + }) config.addLabel('delete-link', { en: 'Remove Link', de: 'Link löschen' - }); + }) } } From af6ceb97381f0061570151491659cc6b75dd4692 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 12:21:01 +0300 Subject: [PATCH 132/167] ES6 jats figure package. --- packages/jats/figure/Figure.js | 16 ++-- packages/jats/figure/FigureComponent.js | 44 ++++------ packages/jats/figure/FigureConverter.js | 104 ++++++++++++------------ packages/jats/figure/FigureTarget.js | 62 ++++++-------- packages/jats/figure/package.js | 12 ++- 5 files changed, 106 insertions(+), 132 deletions(-) diff --git a/packages/jats/figure/Figure.js b/packages/jats/figure/Figure.js index 8f85d5c26..1b377b0cd 100644 --- a/packages/jats/figure/Figure.js +++ b/packages/jats/figure/Figure.js @@ -1,14 +1,8 @@ -'use strict'; - import { DocumentNode } from 'substance' -function Figure() { - Figure.super.apply(this, arguments); -} - -DocumentNode.extend(Figure); +class Figure extends DocumentNode {} -Figure.type = 'figure'; +Figure.type = 'figure' /* Attribute @@ -45,7 +39,7 @@ Figure.define({ uris: { type: ['uri'], default: [] }, contentNodes: { type: ['id'], default: [] }, attribs: { type: ['attrib'], default: [] }, - permissions: { type: ['permissions'], default: [] }, -}); + permissions: { type: ['permissions'], default: [] } +}) -export default Figure; +export default Figure diff --git a/packages/jats/figure/FigureComponent.js b/packages/jats/figure/FigureComponent.js index 22f04e026..bdfd878bc 100644 --- a/packages/jats/figure/FigureComponent.js +++ b/packages/jats/figure/FigureComponent.js @@ -1,56 +1,48 @@ -'use strict'; - import { Component } from 'substance' import renderNodeComponent from '../../../util/renderNodeComponent' -function FigureComponent() { - Component.apply(this, arguments); -} - -FigureComponent.Prototype = function() { +class FigureComponent extends Component { - this.render = function($$) { - var node = this.props.node; - var doc = node.getDocument(); - var el = $$('div') + render($$) { + let node = this.props.node + let doc = node.getDocument() + let el = $$('div') .addClass('sc-figure') - .attr('data-id', this.props.node.id); + .attr('data-id', this.props.node.id) if (node.label) { - var label = doc.get(node.label); + let label = doc.get(node.label) el.append( renderNodeComponent(this, $$, label, { disabled: this.props.disabled }).ref('label') - ); + ) } // Display figure content node.contentNodes.forEach(function(nodeId) { - var childNode = doc.get(nodeId); + let childNode = doc.get(nodeId) el.append( renderNodeComponent(this, $$, childNode, { disabled: this.props.disabled }) - ); - }.bind(this)); + ) + }.bind(this)) // Display Captions node.captions.forEach(function(nodeId) { - var captionNode = doc.get(nodeId); + let captionNode = doc.get(nodeId) el.append( renderNodeComponent(this, $$, captionNode, { disabled: this.props.disabled }).ref('caption') - ); - }.bind(this)); + ) + }.bind(this)) // TODO: we should provide a UI to the rest of the node's content // in an overlay - return el; - }; -}; - -Component.extend(FigureComponent); + return el + } +} -export default FigureComponent; \ No newline at end of file +export default FigureComponent diff --git a/packages/jats/figure/FigureConverter.js b/packages/jats/figure/FigureConverter.js index 04f5ad6f8..958236298 100644 --- a/packages/jats/figure/FigureConverter.js +++ b/packages/jats/figure/FigureConverter.js @@ -1,16 +1,14 @@ -'use strict'; - import JATS from '../JATS' import XMLIterator from '../../../util/XMLIterator' -var ACCESS_OR_LINK = JATS.ACCESS.concat(JATS.ADDRESS_LINK); -var FIGURE_CONTENT = JATS.BLOCK_MATH +let ACCESS_OR_LINK = JATS.ACCESS.concat(JATS.ADDRESS_LINK) +let FIGURE_CONTENT = JATS.BLOCK_MATH .concat(JATS.CHEM_STRUCT) .concat(JATS.INTABLE_PARA) .concat(JATS.JUST_TABLE) .concat(JATS.JUST_PARA) .concat(JATS.LIST) - .concat(JATS.SIMPLE_DISPLAY); + .concat(JATS.SIMPLE_DISPLAY) export default { @@ -42,93 +40,93 @@ export default { */ import: function(el, node, converter) { - var iterator = new XMLIterator(el.getChildren()); + let iterator = new XMLIterator(el.getChildren()) iterator.manyOf('object-id', function(child) { - node.objectIds.push(child.textContent); - }); + node.objectIds.push(child.textContent) + }) iterator.optional('label', function(child) { - node.label = converter.convertElement(child).id; - }); + node.label = converter.convertElement(child).id + }) iterator.manyOf('caption', function(child) { - node.captions.push(converter.convertElement(child).id); - }); + node.captions.push(converter.convertElement(child).id) + }) iterator.manyOf('abstract', function(child) { - node.abstracts.push(converter.convertElement(child).id); - }); + node.abstracts.push(converter.convertElement(child).id) + }) iterator.manyOf('kwd-group', function(child) { - node.kwdGroups.push(converter.convertElement(child).id); - }); + node.kwdGroups.push(converter.convertElement(child).id) + }) iterator.manyOf(ACCESS_OR_LINK, function(child) { - var childNode = converter.convertElement(child); + let childNode = converter.convertElement(child) switch(child.tagName) { case "alt-text": - node.altTexts.push(childNode.id); - break; + node.altTexts.push(childNode.id) + break case "long-desc": - node.longDescs.push(childNode.id); - break; + node.longDescs.push(childNode.id) + break case "ext-link": - node.extLinks.push(childNode.id); - break; + node.extLinks.push(childNode.id) + break case "uri": - node.uris.push(childNode.id); - break; + node.uris.push(childNode.id) + break case "email": - node.emails.push(childNode.id); - break; + node.emails.push(childNode.id) + break default: //nothing } - }); + }) iterator.manyOf(FIGURE_CONTENT, function(child) { - node.contentNodes.push(converter.convertElement(child).id); - }); + node.contentNodes.push(converter.convertElement(child).id) + }) iterator.manyOf(JATS.DISLAY_BACK_MATTER, function(child) { - var childNode = converter.convertElement(child); + var childNode = converter.convertElement(child) switch(child.tagName) { case "attrib": - node.attribs.push(childNode.id); - break; + node.attribs.push(childNode.id) + break case "permissions": - node.permissions.push(childNode.id); - break; + node.permissions.push(childNode.id) + break default: //nothing } - }); + }) if (iterator.hasNext()) { - throw new Error('Illegal JATS: ' + el.outerHTML); + throw new Error('Illegal JATS: ' + el.outerHTML) } }, export: function(node, el, converter) { - var $$ = converter.$$; + let $$ = converter.$$ node.objectIds.forEach(function(objectId) { - el.append($$('object-id').text(objectId)); - }); + el.append($$('object-id').text(objectId)) + }) if (node.label) { - el.append(converter.convertNode(node.label)); + el.append(converter.convertNode(node.label)) } - el.append(converter.convertNodes(node.captions)); - el.append(converter.convertNodes(node.abstracts)); - el.append(converter.convertNodes(node.kwdGroups)); + el.append(converter.convertNodes(node.captions)) + el.append(converter.convertNodes(node.abstracts)) + el.append(converter.convertNodes(node.kwdGroups)) if (node.altTexts) { - el.append(converter.convertNodes(node.altTexts)); + el.append(converter.convertNodes(node.altTexts)) } if (node.longDescs) { - el.append(converter.convertNodes(node.longDescs)); + el.append(converter.convertNodes(node.longDescs)) } if (node.extLinks) { - el.append(converter.convertNodes(node.extLinks)); + el.append(converter.convertNodes(node.extLinks)) } if (node.uris) { - el.append(converter.convertNodes(node.uris)); + el.append(converter.convertNodes(node.uris)) } if (node.emails) { - el.append(converter.convertNodes(node.emails)); + el.append(converter.convertNodes(node.emails)) } - el.append(converter.convertNodes(node.contentNodes)); - el.append(converter.convertNodes(node.attribs)); - el.append(converter.convertNodes(node.permissions)); + el.append(converter.convertNodes(node.contentNodes)) + el.append(converter.convertNodes(node.attribs)) + el.append(converter.convertNodes(node.permissions)) } -}; +} diff --git a/packages/jats/figure/FigureTarget.js b/packages/jats/figure/FigureTarget.js index 25011584a..f005d10ba 100644 --- a/packages/jats/figure/FigureTarget.js +++ b/packages/jats/figure/FigureTarget.js @@ -1,77 +1,69 @@ -'use strict'; - import { Component } from 'substance' import renderNodeComponent from '../../../util/renderNodeComponent' /* Renders a keyboard-selectable figure target item */ -function FigureTarget() { - FigureTarget.super.apply(this, arguments); -} - -FigureTarget.Prototype = function() { +class FigureTarget extends Component { - this.render = function($$) { - var node = this.props.node; - var doc = node.getDocument(); - var el = $$('div') + render($$) { + let node = this.props.node + let doc = node.getDocument() + let el = $$('div') .addClass('sc-figure-target') - .attr({'data-id': node.id}); + .attr({'data-id': node.id}) if (this.props.selected) { - el.addClass('sm-selected'); + el.addClass('sm-selected') } // Render thumbnail el.append( this._renderThumb($$) - ); + ) if (node.label) { - var label = doc.get(node.label); + let label = doc.get(node.label) el.append( renderNodeComponent(this, $$, label, { disabled: this.props.disabled }) - ); + ) } // Render first caption // TODO: Is there a way to cut off the caption to have a more compact view? - var firstCaption = node.captions[0]; + let firstCaption = node.captions[0] if (firstCaption) { - firstCaption = doc.get(firstCaption); + firstCaption = doc.get(firstCaption) el.append( renderNodeComponent(this, $$, firstCaption, { disabled: this.props.disabled }) - ); + ) } - return el; - }; + return el + } /* Render thumbnail based on the contents of the figure */ - this._renderThumb = function($$) { + _renderThumb($$) { // For now we just pick the first content node (e.g. a graphic or a table) - var node = this.props.node; - var doc = node.getDocument(); - var firstContentNode = node.contentNodes[0]; - var el = $$('div').addClass('se-thumbnail'); + let node = this.props.node + let doc = node.getDocument() + let firstContentNode = node.contentNodes[0] + let el = $$('div').addClass('se-thumbnail') if (firstContentNode) { - firstContentNode = doc.get(firstContentNode); - el.append(renderNodeComponent(this, $$, firstContentNode)); + firstContentNode = doc.get(firstContentNode) + el.append(renderNodeComponent(this, $$, firstContentNode)) } else { - el.append('No thumb'); + el.append('No thumb') } - return el; - }; -}; - -Component.extend(FigureTarget); + return el + } +} -export default FigureTarget; \ No newline at end of file +export default FigureTarget diff --git a/packages/jats/figure/package.js b/packages/jats/figure/package.js index b2eb2c834..88000ef71 100644 --- a/packages/jats/figure/package.js +++ b/packages/jats/figure/package.js @@ -1,5 +1,3 @@ -'use strict'; - import Figure from './Figure' import FigureComponent from './FigureComponent' import FigureTarget from './FigureTarget' @@ -8,9 +6,9 @@ import FigureConverter from './FigureConverter' export default { name: 'figure', configure: function(config) { - config.addNode(Figure); - config.addComponent(Figure.type, FigureComponent); - config.addComponent(Figure.type+'-target', FigureTarget); - config.addConverter('jats', FigureConverter); + config.addNode(Figure) + config.addComponent(Figure.type, FigureComponent) + config.addComponent(Figure.type+'-target', FigureTarget) + config.addConverter('jats', FigureConverter) } -}; +} From 7042dedc6ddc90751d96772ae5463ecf2e58cc78 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 13:53:57 +0300 Subject: [PATCH 133/167] ES6 jats footnote package. --- packages/jats/footnote/Footnote.js | 14 +++----- packages/jats/footnote/FootnoteComponent.js | 36 ++++++++------------- packages/jats/footnote/FootnoteConverter.js | 20 ++++++------ packages/jats/footnote/package.js | 8 ++--- 4 files changed, 30 insertions(+), 48 deletions(-) diff --git a/packages/jats/footnote/Footnote.js b/packages/jats/footnote/Footnote.js index db05a46c7..4556556dd 100644 --- a/packages/jats/footnote/Footnote.js +++ b/packages/jats/footnote/Footnote.js @@ -1,14 +1,8 @@ -'use strict'; - import { Container } from 'substance' -function Footnote() { - Footnote.super.apply(this, arguments); -} - -Container.extend(Footnote); +class Footnote extends Container {} -Footnote.type = 'footnote'; +Footnote.type = 'footnote' /* Content @@ -18,6 +12,6 @@ Footnote.define({ attributes: { type: 'object', default: {} }, label: { type: 'label', optional: true }, nodes: { type: ['p'], default: [] } -}); +}) -export default Footnote; +export default Footnote diff --git a/packages/jats/footnote/FootnoteComponent.js b/packages/jats/footnote/FootnoteComponent.js index 2735ed11a..bef24087a 100644 --- a/packages/jats/footnote/FootnoteComponent.js +++ b/packages/jats/footnote/FootnoteComponent.js @@ -1,43 +1,35 @@ -'use strict'; - import { Component, TextPropertyComponent } from 'substance' import renderNodeComponent from '../../../util/renderNodeComponent' -function FootnoteComponent() { - Component.apply(this, arguments); -} - -FootnoteComponent.Prototype = function() { +class FootnoteComponent extends Component { - this.render = function($$) { - var node = this.props.node; - var doc = node.getDocument(); + render($$) { + let node = this.props.node + let doc = node.getDocument() - var el = $$('div') + let el = $$('div') .addClass('sc-footnote') - .attr('data-id', this.props.node.id); + .attr('data-id', this.props.node.id) if (node.label) { - var label = doc.get(node.label); + let label = doc.get(node.label) el.append($$(TextPropertyComponent, { path: label.getTextPath() - })); + })) } // TODO: what if no label is present? this.props.node.nodes.forEach(function(nodeId) { - var childNode = doc.get(nodeId); + let childNode = doc.get(nodeId) el.append( renderNodeComponent(this, $$, childNode, { disabled: this.props.disabled }) ); - }.bind(this)); + }.bind(this)) - return el; - }; -}; - -Component.extend(FootnoteComponent); + return el + } +} -export default FootnoteComponent; \ No newline at end of file +export default FootnoteComponent diff --git a/packages/jats/footnote/FootnoteConverter.js b/packages/jats/footnote/FootnoteConverter.js index 490dce6cd..6194bf3ec 100644 --- a/packages/jats/footnote/FootnoteConverter.js +++ b/packages/jats/footnote/FootnoteConverter.js @@ -1,5 +1,3 @@ -'use strict'; - import XMLIterator from '../../../util/XMLIterator' export default { @@ -20,21 +18,21 @@ export default { */ import: function(el, node, converter) { - var iterator = new XMLIterator(el.getChildren()); + var iterator = new XMLIterator(el.getChildren()) iterator.optional('label', function(child) { - node.label = converter.convertElement(child).id; - }); + node.label = converter.convertElement(child).id + }) iterator.oneOrMoreOf('p', function(child) { - node.nodes.push(converter.convertElement(child).id); - }); - if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML); + node.nodes.push(converter.convertElement(child).id) + }) + if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML) }, export: function(node, el, converter) { if (node.label) { - el.append(converter.convertNode(node.label)); + el.append(converter.convertNode(node.label)) } - el.append(converter.convertNodes(node.nodes)); + el.append(converter.convertNodes(node.nodes)) } -}; +} diff --git a/packages/jats/footnote/package.js b/packages/jats/footnote/package.js index ba0a41496..3889d383e 100644 --- a/packages/jats/footnote/package.js +++ b/packages/jats/footnote/package.js @@ -1,5 +1,3 @@ -'use strict'; - import Footnote from './Footnote' import FootnoteComponent from './FootnoteComponent' import FootnoteConverter from './FootnoteConverter' @@ -8,7 +6,7 @@ export default { name: 'footnote', configure: function(config) { config.addNode(Footnote); - config.addComponent(Footnote.type, FootnoteComponent); - config.addConverter('jats', FootnoteConverter); + config.addComponent(Footnote.type, FootnoteComponent) + config.addConverter('jats', FootnoteConverter) } -}; \ No newline at end of file +} \ No newline at end of file From 8adbc528bd3868e508bd6600e50ac57f2f3477fb Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 13:54:03 +0300 Subject: [PATCH 134/167] ES6 jats front package. --- packages/jats/front/Front.js | 14 ++++-------- packages/jats/front/FrontComponent.js | 32 ++++++++++----------------- packages/jats/front/FrontConverter.js | 28 +++++++++++------------ packages/jats/front/package.js | 10 ++++----- 4 files changed, 33 insertions(+), 51 deletions(-) diff --git a/packages/jats/front/Front.js b/packages/jats/front/Front.js index 7db1df702..f6b3bebf8 100644 --- a/packages/jats/front/Front.js +++ b/packages/jats/front/Front.js @@ -1,14 +1,8 @@ -'use strict'; - import { Container } from 'substance' -function Front() { - Front.super.apply(this, arguments); -} - -Container.extend(Front); +class Front extends Container {} -Front.type = "front"; +Front.type = "front" /* Content @@ -23,6 +17,6 @@ Front.define({ journalMeta: { type: 'journal-meta', optional: true }, articleMeta: { type: 'article-meta' }, nodes: { type: ['id'], default: [] } -}); +}) -export default Front; +export default Front diff --git a/packages/jats/front/FrontComponent.js b/packages/jats/front/FrontComponent.js index a89ad5563..4cf9abb65 100644 --- a/packages/jats/front/FrontComponent.js +++ b/packages/jats/front/FrontComponent.js @@ -1,35 +1,27 @@ -'use strict'; - import { Component } from 'substance' import renderNodeComponent from '../../../util/renderNodeComponent' -function FrontComponent() { - Component.apply(this, arguments); -} - -FrontComponent.Prototype = function() { +class FrontComponent extends Component { - this.render = function($$) { - var node = this.props.node; - var doc = node.getDocument(); + render($$) { + let node = this.props.node + let doc = node.getDocument() - var el = $$('div') + let el = $$('div') .addClass('sc-front') - .attr('data-id', this.props.node.id); + .attr('data-id', this.props.node.id) // Render articlemeta - var articleMeta = doc.get(node.articleMeta); + let articleMeta = doc.get(node.articleMeta) el.append( renderNodeComponent(this, $$, articleMeta, { disabled: this.props.disabled }) - ); + ) - return el; - }; -}; - -Component.extend(FrontComponent); + return el + } +} -export default FrontComponent; \ No newline at end of file +export default FrontComponent diff --git a/packages/jats/front/FrontConverter.js b/packages/jats/front/FrontConverter.js index d8f058ac4..f3587a934 100644 --- a/packages/jats/front/FrontConverter.js +++ b/packages/jats/front/FrontConverter.js @@ -1,8 +1,6 @@ -'use strict'; - import XMLIterator from '../../../util/XMLIterator' -var FRONT_CONTENT = ['def-list', 'list', 'ack', 'bio', 'fn-group', 'glossary', 'notes']; +let FRONT_CONTENT = ['def-list', 'list', 'ack', 'bio', 'fn-group', 'glossary', 'notes'] export default { @@ -22,24 +20,24 @@ export default { import: function(el, node, converter) { node.id = 'front'; // there is only one element - var iterator = new XMLIterator(el.getChildren()); + let iterator = new XMLIterator(el.getChildren()) iterator.optional('journal-meta', function(child) { - node.journalMeta = converter.convertElement(child).id; - }); + node.journalMeta = converter.convertElement(child).id + }) iterator.required('article-meta', function(child) { - node.articleMeta = converter.convertElement(child).id; - }); + node.articleMeta = converter.convertElement(child).id + }) iterator.manyOf(FRONT_CONTENT, function(child) { - node.nodes.push(converter.convertElement(child).id); - }); - if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML); + node.nodes.push(converter.convertElement(child).id) + }) + if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML) }, export: function(node, el, converter) { if (node.journalMeta) { - el.append(converter.convertNode(node.journalMeta)); + el.append(converter.convertNode(node.journalMeta)) } - el.append(converter.convertNode(node.articleMeta)); - el.append(converter.convertNodes(node.nodes)); + el.append(converter.convertNode(node.articleMeta)) + el.append(converter.convertNodes(node.nodes)) } -}; +} diff --git a/packages/jats/front/package.js b/packages/jats/front/package.js index e01eaa4bc..9f09080d3 100644 --- a/packages/jats/front/package.js +++ b/packages/jats/front/package.js @@ -1,5 +1,3 @@ -'use strict'; - import Front from './Front' import FrontConverter from './FrontConverter' import FrontComponent from './FrontComponent' @@ -7,8 +5,8 @@ import FrontComponent from './FrontComponent' export default { name: 'front', configure: function(config) { - config.addNode(Front); - config.addConverter('jats', FrontConverter); - config.addComponent(Front.type, FrontComponent); + config.addNode(Front) + config.addConverter('jats', FrontConverter) + config.addComponent(Front.type, FrontComponent) } -}; \ No newline at end of file +} \ No newline at end of file From f07b910b9aff1b5e747282f8c1a70b8cf215f9ce Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 13:57:18 +0300 Subject: [PATCH 135/167] ES6 jats graphic package. --- packages/jats/graphic/Graphic.js | 26 ++++++++------------- packages/jats/graphic/GraphicComponent.js | 28 ++++++++--------------- packages/jats/graphic/GraphicConverter.js | 18 +++++++-------- packages/jats/graphic/package.js | 10 ++++---- 4 files changed, 31 insertions(+), 51 deletions(-) diff --git a/packages/jats/graphic/Graphic.js b/packages/jats/graphic/Graphic.js index 40925b161..9f8fa314c 100644 --- a/packages/jats/graphic/Graphic.js +++ b/packages/jats/graphic/Graphic.js @@ -1,25 +1,17 @@ -'use strict'; - import { Container } from 'substance' -function Graphic() { - Graphic.super.apply(this, arguments); -} - -Graphic.Prototype = function() { +class Graphic extends Container { - this.getHref = function() { - return this.attributes['xlink:href']; - }; + getHref() { + return this.attributes['xlink:href'] + } -}; - -Container.extend(Graphic); +} -Graphic.type= 'graphic'; +Graphic.type = 'graphic' Graphic.define({ - attributes: { type: 'object', default: {} }, -}); + attributes: { type: 'object', default: {} } +}) -export default Graphic; \ No newline at end of file +export default Graphic diff --git a/packages/jats/graphic/GraphicComponent.js b/packages/jats/graphic/GraphicComponent.js index c5f5ce869..5831ee91b 100644 --- a/packages/jats/graphic/GraphicComponent.js +++ b/packages/jats/graphic/GraphicComponent.js @@ -1,27 +1,19 @@ -'use strict'; - import { Component } from 'substance' -function GraphicComponent() { - Component.apply(this, arguments); -} - -GraphicComponent.Prototype = function() { +class GraphicComponent extends Component { - this.render = function($$) { - var node = this.props.node; - var el = $$('div') + render($$) { + let node = this.props.node + let el = $$('div') .addClass('sc-graphic') - .attr('data-id', node.id); + .attr('data-id', node.id) el.append( $$('img').attr({ src: node.getHref() }) - ); - return el; - }; -}; - -Component.extend(GraphicComponent); + ) + return el + } +} -export default GraphicComponent; \ No newline at end of file +export default GraphicComponent diff --git a/packages/jats/graphic/GraphicConverter.js b/packages/jats/graphic/GraphicConverter.js index 343b97dc3..5e04245ed 100644 --- a/packages/jats/graphic/GraphicConverter.js +++ b/packages/jats/graphic/GraphicConverter.js @@ -1,12 +1,10 @@ -'use strict'; - import JATS from '../JATS' import XMLIterator from '../../../util/XMLIterator' -var GRAPHIC_ELEMENTS = JATS.ACCESS +let GRAPHIC_ELEMENTS = JATS.ACCESS .concat(JATS.ADDRESS_LINK) .concat(['caption', 'object-id', 'kwd-group', 'label']) - .concat(JATS.DISPLAY_BACK_MATTER); + .concat(JATS.DISPLAY_BACK_MATTER) export default { @@ -41,15 +39,15 @@ export default { */ import: function(el, node, converter) { - var iterator = new XMLIterator(el.getChildren()); + let iterator = new XMLIterator(el.getChildren()) iterator.manyOf(GRAPHIC_ELEMENTS, function(child) { - node.nodes.push(converter.convertElement(child).id); - }); - if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML); + node.nodes.push(converter.convertElement(child).id) + }) + if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML) }, export: function(node, el, converter) { - el.append(converter.convertNodes(node.nodes)); + el.append(converter.convertNodes(node.nodes)) } -}; +} diff --git a/packages/jats/graphic/package.js b/packages/jats/graphic/package.js index d3d156619..cc8890e8b 100644 --- a/packages/jats/graphic/package.js +++ b/packages/jats/graphic/package.js @@ -1,5 +1,3 @@ -'use strict'; - import Graphic from './Graphic' import GraphicComponent from './GraphicComponent' import GraphicConverter from './GraphicConverter' @@ -7,8 +5,8 @@ import GraphicConverter from './GraphicConverter' export default { name: 'graphic', configure: function(config) { - config.addNode(Graphic); - config.addComponent(Graphic.type, GraphicComponent); - config.addConverter('jats', GraphicConverter); + config.addNode(Graphic) + config.addComponent(Graphic.type, GraphicComponent) + config.addConverter('jats', GraphicConverter) } -}; \ No newline at end of file +} \ No newline at end of file From 62090dae8184f889c8dc866c572e95b7634ea836 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 13:58:32 +0300 Subject: [PATCH 136/167] ES6 jats italic package. --- packages/jats/italic/Italic.js | 16 +++++----------- packages/jats/italic/ItalicCommand.js | 2 +- packages/jats/italic/ItalicConverter.js | 4 +--- packages/jats/italic/ItalicTool.js | 2 +- packages/jats/italic/package.js | 2 -- 5 files changed, 8 insertions(+), 18 deletions(-) diff --git a/packages/jats/italic/Italic.js b/packages/jats/italic/Italic.js index dc6822ed9..e5fc6d5c6 100644 --- a/packages/jats/italic/Italic.js +++ b/packages/jats/italic/Italic.js @@ -1,17 +1,11 @@ -'use strict'; - import { Annotation } from 'substance' -function Italic() { - Italic.super.apply(this, arguments); -} - -Annotation.extend(Italic); +class Italic extends Annotation {} -Italic.type = 'italic'; +Italic.type = 'italic' Italic.define({ - attributes: { type: 'object', default: {} }, -}); + attributes: { type: 'object', default: {} } +}) -export default Italic; +export default Italic diff --git a/packages/jats/italic/ItalicCommand.js b/packages/jats/italic/ItalicCommand.js index f2f815a0f..4a9e0df9b 100644 --- a/packages/jats/italic/ItalicCommand.js +++ b/packages/jats/italic/ItalicCommand.js @@ -2,4 +2,4 @@ import { AnnotationCommand } from 'substance' class ItalicCommand extends AnnotationCommand {} -export default ItalicCommand; \ No newline at end of file +export default ItalicCommand diff --git a/packages/jats/italic/ItalicConverter.js b/packages/jats/italic/ItalicConverter.js index 612174da1..7b5bb3c14 100644 --- a/packages/jats/italic/ItalicConverter.js +++ b/packages/jats/italic/ItalicConverter.js @@ -1,6 +1,4 @@ -'use strict'; - export default { type: 'italic', tagName: 'italic' -}; +} diff --git a/packages/jats/italic/ItalicTool.js b/packages/jats/italic/ItalicTool.js index ab13e5735..b85150350 100644 --- a/packages/jats/italic/ItalicTool.js +++ b/packages/jats/italic/ItalicTool.js @@ -2,4 +2,4 @@ import { AnnotationTool } from 'substance' class ItalicTool extends AnnotationTool {} -export default ItalicTool; \ No newline at end of file +export default ItalicTool diff --git a/packages/jats/italic/package.js b/packages/jats/italic/package.js index 32d2dbe3c..382559ac4 100644 --- a/packages/jats/italic/package.js +++ b/packages/jats/italic/package.js @@ -1,5 +1,3 @@ -'use strict'; - import Italic from './Italic' import ItalicConverter from './ItalicConverter' import ItalicTool from './ItalicTool' From e18adbfa6ff38c42ed6ca883f8d5a0548f064848 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 14:31:29 +0300 Subject: [PATCH 137/167] ES6 jats label package. --- packages/jats/label/Label.js | 16 +++++--------- packages/jats/label/LabelComponent.js | 30 ++++++++++----------------- packages/jats/label/LabelConverter.js | 6 ++---- packages/jats/label/package.js | 10 ++++----- 4 files changed, 22 insertions(+), 40 deletions(-) diff --git a/packages/jats/label/Label.js b/packages/jats/label/Label.js index 8ef816ffb..9bfcb861b 100644 --- a/packages/jats/label/Label.js +++ b/packages/jats/label/Label.js @@ -1,17 +1,11 @@ -'use strict'; - import { TextNode } from 'substance' -function Label() { - Label.super.apply(this, arguments); -} - -TextNode.extend(Label); +class Label extends TextNode {} -Label.type = 'label'; +Label.type = 'label' Label.define({ - attributes: { type: 'object', default: {} }, -}); + attributes: { type: 'object', default: {} } +}) -export default Label; \ No newline at end of file +export default Label diff --git a/packages/jats/label/LabelComponent.js b/packages/jats/label/LabelComponent.js index 0e0d919e5..d7cc14adb 100644 --- a/packages/jats/label/LabelComponent.js +++ b/packages/jats/label/LabelComponent.js @@ -1,25 +1,17 @@ -'use strict'; - import { Component, TextPropertyEditor } from 'substance' -function LabelComponent() { - LabelComponent.super.apply(this, arguments); -} - -LabelComponent.Prototype = function() { +class LabelComponent extends Component { - this.render = function($$) { - var el = $$('div').addClass('sc-label'); - var node = this.props.node; - var labelEditor = $$(TextPropertyEditor, { + render($$) { + let el = $$('div').addClass('sc-label') + let node = this.props.node + let labelEditor = $$(TextPropertyEditor, { disabled: this.props.disabled, path: node.getTextPath() - }).ref('labelEditor'); - el.append(labelEditor); - return el; - }; -}; - -Component.extend(LabelComponent); + }).ref('labelEditor') + el.append(labelEditor) + return el + } +} -export default LabelComponent; \ No newline at end of file +export default LabelComponent diff --git a/packages/jats/label/LabelConverter.js b/packages/jats/label/LabelConverter.js index 7db7aac5f..6d306c70c 100644 --- a/packages/jats/label/LabelConverter.js +++ b/packages/jats/label/LabelConverter.js @@ -1,8 +1,6 @@ -'use strict'; - import TextNodeConverter from '../TextNodeConverter' export default TextNodeConverter.extend({ type: 'label', - tagName: 'label', -}); + tagName: 'label' +}) diff --git a/packages/jats/label/package.js b/packages/jats/label/package.js index 889029c12..aad7d2e75 100644 --- a/packages/jats/label/package.js +++ b/packages/jats/label/package.js @@ -1,5 +1,3 @@ -'use strict'; - import Label from './Label' import LabelConverter from './LabelConverter' import LabelComponent from './LabelComponent' @@ -7,8 +5,8 @@ import LabelComponent from './LabelComponent' export default { name: 'label', configure: function(config) { - config.addNode(Label); - config.addComponent(Label.type, LabelComponent); - config.addConverter('jats', LabelConverter); + config.addNode(Label) + config.addComponent(Label.type, LabelComponent) + config.addConverter('jats', LabelConverter) } -}; +} From 3f6b9ab0e18cb6696f3f9fba856d011d62e2b890 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 14:31:38 +0300 Subject: [PATCH 138/167] ES6 jats monospace package. --- packages/jats/monospace/Monospace.js | 16 +++++----------- packages/jats/monospace/MonospaceConverter.js | 4 +--- packages/jats/monospace/package.js | 8 +++----- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/packages/jats/monospace/Monospace.js b/packages/jats/monospace/Monospace.js index a966a9c9c..850da256d 100644 --- a/packages/jats/monospace/Monospace.js +++ b/packages/jats/monospace/Monospace.js @@ -1,17 +1,11 @@ -'use strict'; - import { Annotation } from 'substance' -function Monospace() { - Monospace.super.apply(this, arguments); -} - -Annotation.extend(Monospace); +class Monospace extends Annotation {} -Monospace.type = 'monospace'; +Monospace.type = 'monospace' Monospace.define({ - attributes: { type: 'object', default: {} }, -}); + attributes: { type: 'object', default: {} } +}) -export default Monospace; +export default Monospace diff --git a/packages/jats/monospace/MonospaceConverter.js b/packages/jats/monospace/MonospaceConverter.js index 052d6673b..a46ece3f6 100644 --- a/packages/jats/monospace/MonospaceConverter.js +++ b/packages/jats/monospace/MonospaceConverter.js @@ -1,6 +1,4 @@ -'use strict'; - export default { type: 'monospace', tagName: 'monospace' -}; +} diff --git a/packages/jats/monospace/package.js b/packages/jats/monospace/package.js index 5d02251ff..1eceb465f 100644 --- a/packages/jats/monospace/package.js +++ b/packages/jats/monospace/package.js @@ -1,12 +1,10 @@ -'use strict'; - import Monospace from './Monospace' import MonospaceConverter from './MonospaceConverter' export default { name: 'monospace', configure: function(config) { - config.addNode(Monospace); - config.addConverter('jats', MonospaceConverter); + config.addNode(Monospace) + config.addConverter('jats', MonospaceConverter) } -}; +} From 477ddaa9a78045733371e2bb730a6ff933a4fdc4 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 14:31:50 +0300 Subject: [PATCH 139/167] ES6 jats paragraph package. --- packages/jats/paragraph/Paragraph.js | 16 +++++----------- packages/jats/paragraph/ParagraphComponent.js | 3 --- packages/jats/paragraph/ParagraphConverter.js | 6 ++---- packages/jats/paragraph/package.js | 16 +++++++--------- 4 files changed, 14 insertions(+), 27 deletions(-) diff --git a/packages/jats/paragraph/Paragraph.js b/packages/jats/paragraph/Paragraph.js index 6394d9012..85e8858e3 100644 --- a/packages/jats/paragraph/Paragraph.js +++ b/packages/jats/paragraph/Paragraph.js @@ -1,17 +1,11 @@ -'use strict'; - import { TextBlock } from 'substance' -function ParagraphNode() { - ParagraphNode.super.apply(this, arguments); -} - -TextBlock.extend(ParagraphNode); +class ParagraphNode extends TextBlock {} -ParagraphNode.type = "paragraph"; +ParagraphNode.type = "paragraph" ParagraphNode.define({ - attributes: { type: 'object', default: {} }, -}); + attributes: { type: 'object', default: {} } +}) -export default ParagraphNode; +export default ParagraphNode diff --git a/packages/jats/paragraph/ParagraphComponent.js b/packages/jats/paragraph/ParagraphComponent.js index cb98bec68..a94bb30bb 100644 --- a/packages/jats/paragraph/ParagraphComponent.js +++ b/packages/jats/paragraph/ParagraphComponent.js @@ -1,5 +1,3 @@ -'use strict'; - import { TextBlockComponent } from 'substance' class ParagraphComponent extends TextBlockComponent { @@ -7,7 +5,6 @@ class ParagraphComponent extends TextBlockComponent { getClassNames() { return 'sc-paragraph' } - } export default ParagraphComponent diff --git a/packages/jats/paragraph/ParagraphConverter.js b/packages/jats/paragraph/ParagraphConverter.js index 2332ae698..1d89993ea 100644 --- a/packages/jats/paragraph/ParagraphConverter.js +++ b/packages/jats/paragraph/ParagraphConverter.js @@ -1,8 +1,6 @@ -'use strict'; - import TextNodeConverter from '../TextNodeConverter' export default TextNodeConverter.extend({ type: 'paragraph', - tagName: 'p', -}); + tagName: 'p' +}) diff --git a/packages/jats/paragraph/package.js b/packages/jats/paragraph/package.js index c0ff2c74d..a67dc8968 100644 --- a/packages/jats/paragraph/package.js +++ b/packages/jats/paragraph/package.js @@ -1,5 +1,3 @@ -'use strict'; - import Paragraph from './Paragraph' import ParagraphComponent from './ParagraphComponent' import ParagraphConverter from './ParagraphConverter' @@ -9,20 +7,20 @@ export default { name: 'paragraph', configure: function(config) { - config.addNode(Paragraph); - config.addComponent(Paragraph.type, ParagraphComponent); - config.addConverter('jats', ParagraphConverter); + config.addNode(Paragraph) + config.addComponent(Paragraph.type, ParagraphComponent) + config.addConverter('jats', ParagraphConverter) config.addTextType({ name: Paragraph.type, data: {type: Paragraph.type} - }); + }) config.addLabel(Paragraph.type, { en: 'Paragraph', de: 'Paragraph' - }); + }) config.addLabel('paragraph.content', { en: 'Paragraph', de: 'Paragraph' - }); + }) } -}; +} From f6ac0eac3abec5348e8de385f86565d915e3c8d3 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 14:43:46 +0300 Subject: [PATCH 140/167] ES6 jats ref-list package. --- packages/jats/ref-list/RefList.js | 16 +++------ packages/jats/ref-list/RefListComponent.js | 42 +++++++++++----------- packages/jats/ref-list/RefListConverter.js | 28 +++++++-------- packages/jats/ref-list/package.js | 10 +++--- 4 files changed, 42 insertions(+), 54 deletions(-) diff --git a/packages/jats/ref-list/RefList.js b/packages/jats/ref-list/RefList.js index 6bd63c7e0..d1afb90f2 100644 --- a/packages/jats/ref-list/RefList.js +++ b/packages/jats/ref-list/RefList.js @@ -1,5 +1,3 @@ -'use strict'; - import { Container } from 'substance' /* @@ -7,13 +5,9 @@ import { Container } from 'substance' List of bibliographic references for a document or document component. */ -function RefList() { - RefList.super.apply(this, arguments); -} - -Container.extend(RefList); +class RefList extends Container {} -RefList.type = 'ref-list'; +RefList.type = 'ref-list' /* ( @@ -33,7 +27,7 @@ RefList.define({ attributes: { type: 'object', default: {} }, label: { type: 'label', optional: true }, title: { type: 'title', optional: true }, - nodes: { type: ['id'], default: [] }, -}); + nodes: { type: ['id'], default: [] } +}) -export default RefList; +export default RefList diff --git a/packages/jats/ref-list/RefListComponent.js b/packages/jats/ref-list/RefListComponent.js index c6aca6e10..a9a709aa7 100644 --- a/packages/jats/ref-list/RefListComponent.js +++ b/packages/jats/ref-list/RefListComponent.js @@ -1,57 +1,55 @@ -'use strict'; - import { Component } from 'substance' import renderNodeComponent from '../../../util/renderNodeComponent' class RefListComponent extends Component { didMount() { - super.didMount(); - var node = this.props.node; - node.on('nodes:changed', this.rerender, this); + super.didMount() + let node = this.props.node + node.on('nodes:changed', this.rerender, this) } dispose() { - super.dispose(); - var node = this.props.node; - node.off(this); + super.dispose() + let node = this.props.node + node.off(this) } render($$) { - var node = this.props.node; - var doc = node.getDocument(); - var el = $$('div').addClass('sc-ref-list'); + let node = this.props.node + let doc = node.getDocument() + let el = $$('div').addClass('sc-ref-list') // NOTE: We don't yet expose RefList.label to the editor if (node.title) { - var titleNode = doc.get(node.title); + let titleNode = doc.get(node.title) el.append( renderNodeComponent(this, $$, titleNode, { disabled: this.props.disabled }) - ); + ) } // Ref elements - var children = node.nodes; + let children = node.nodes children.forEach(function(nodeId) { - var childNode = doc.get(nodeId); + let childNode = doc.get(nodeId) if (childNode.type !== 'unsupported') { el.append( renderNodeComponent(this, $$, childNode, { disabled: this.props.disabled }) - ); + ) } else { - console.info(childNode.type+ ' inside currently not supported by the editor.'); + console.info(childNode.type+ ' inside currently not supported by the editor.') } - }.bind(this)); + }.bind(this)) - return el; + return el } } // Isolated Nodes config -RefListComponent.fullWidth = true; -RefListComponent.noStyle = true; +RefListComponent.fullWidth = true +RefListComponent.noStyle = true -export default RefListComponent; \ No newline at end of file +export default RefListComponent diff --git a/packages/jats/ref-list/RefListConverter.js b/packages/jats/ref-list/RefListConverter.js index 4565df720..89120d15c 100644 --- a/packages/jats/ref-list/RefListConverter.js +++ b/packages/jats/ref-list/RefListConverter.js @@ -1,9 +1,7 @@ -'use strict'; - import JATS from '../JATS' import XMLIterator from '../../../util/XMLIterator' -var REFLIST_CONTENT = ['ref', 'ref-list'].concat(JATS.PARA_LEVEL); +let REFLIST_CONTENT = ['ref', 'ref-list'].concat(JATS.PARA_LEVEL) export default { @@ -25,27 +23,27 @@ export default { ) */ import: function(el, node, converter) { - var iterator = new XMLIterator(el.getChildren()); + let iterator = new XMLIterator(el.getChildren()) iterator.optional('label', function(child) { - node.label = converter.convertElement(child).id; - }); + node.label = converter.convertElement(child).id + }) iterator.optional('title', function(child) { - node.title = converter.convertElement(child).id; - }); + node.title = converter.convertElement(child).id + }) iterator.manyOf(REFLIST_CONTENT, function(child) { - node.nodes.push(converter.convertElement(child).id); - }); - if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML); + node.nodes.push(converter.convertElement(child).id) + }) + if (iterator.hasNext()) throw new Error('Illegal JATS: ' + el.outerHTML) }, export: function(node, el, converter) { if(node.label) { - el.append(converter.convertNode(node.label)); + el.append(converter.convertNode(node.label)) } if(node.title) { - el.append(converter.convertNode(node.title)); + el.append(converter.convertNode(node.title)) } - el.append(converter.convertNodes(node.nodes)); + el.append(converter.convertNodes(node.nodes)) } -}; +} diff --git a/packages/jats/ref-list/package.js b/packages/jats/ref-list/package.js index 6523bdfb9..228f77b1e 100644 --- a/packages/jats/ref-list/package.js +++ b/packages/jats/ref-list/package.js @@ -1,5 +1,3 @@ -'use strict'; - import RefList from './RefList' import RefListConverter from './RefListConverter' import RefListComponent from './RefListComponent' @@ -7,8 +5,8 @@ import RefListComponent from './RefListComponent' export default { name: 'ref-list', configure: function(config) { - config.addNode(RefList); - config.addComponent(RefList.type, RefListComponent); - config.addConverter('jats', RefListConverter); + config.addNode(RefList) + config.addComponent(RefList.type, RefListComponent) + config.addConverter('jats', RefListConverter) } -}; \ No newline at end of file +} From afb5e01d80bb239d441ce1d827f8bba008734088 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 14:43:57 +0300 Subject: [PATCH 141/167] ES6 jats ref package. --- packages/jats/ref/Ref.js | 26 +++--- packages/jats/ref/RefComponent.js | 6 +- packages/jats/ref/RefConverter.js | 5 +- packages/jats/ref/RefTarget.js | 28 +++---- packages/jats/ref/package.js | 8 +- packages/jats/ref/refToHTML.js | 130 +++++++++++++++--------------- 6 files changed, 95 insertions(+), 108 deletions(-) diff --git a/packages/jats/ref/Ref.js b/packages/jats/ref/Ref.js index 79a946410..35a8c833d 100644 --- a/packages/jats/ref/Ref.js +++ b/packages/jats/ref/Ref.js @@ -5,31 +5,25 @@ import { DocumentNode, DefaultDOMElement as DOMElement } from 'substance' One item in a bibliographic list. */ -function Ref() { - Ref.super.apply(this, arguments); -} +class Ref extends DocumentNode { -Ref.Prototype = function() { /* Checks if ref is a plain text citation, with no formatting / tagging etc. */ - this.isPlain = function() { + isPlain() { // TODO: - }; + } /* Get parsed DOM version of XML content */ - this.getDOM = function() { - return DOMElement.parseXML(this.xmlContent); - }; - -}; + getDOM() { + return DOMElement.parseXML(this.xmlContent) + } +} -DocumentNode.extend(Ref); - -Ref.type = 'ref'; +Ref.type = 'ref' /* Content @@ -38,6 +32,6 @@ Ref.type = 'ref'; Ref.define({ attributes: { type: 'object', default: {} }, xmlContent: {type: 'string', default: ''} -}); +}) -export default Ref; +export default Ref diff --git a/packages/jats/ref/RefComponent.js b/packages/jats/ref/RefComponent.js index a529a17ab..6345711a1 100644 --- a/packages/jats/ref/RefComponent.js +++ b/packages/jats/ref/RefComponent.js @@ -11,7 +11,7 @@ class RefComponent extends Component { } // Isolated Nodes config -RefComponent.fullWidth = true; -RefComponent.noStyle = true; +RefComponent.fullWidth = true +RefComponent.noStyle = true -export default RefComponent; +export default RefComponent diff --git a/packages/jats/ref/RefConverter.js b/packages/jats/ref/RefConverter.js index 5efee6346..56f3fc8fc 100644 --- a/packages/jats/ref/RefConverter.js +++ b/packages/jats/ref/RefConverter.js @@ -7,12 +7,11 @@ export default { (label?, (citation-alternatives | element-citation | mixed-citation | nlm-citation | note | x)+) */ import: function(el, node, converter) { // eslint-disable-line - node.xmlContent = el.innerHTML; + node.xmlContent = el.innerHTML }, export: function(node, el, converter) { // eslint-disable-line - el.innerHTML = node.xmlContent; + el.innerHTML = node.xmlContent } } - diff --git a/packages/jats/ref/RefTarget.js b/packages/jats/ref/RefTarget.js index f4db38984..d9151b0cd 100644 --- a/packages/jats/ref/RefTarget.js +++ b/packages/jats/ref/RefTarget.js @@ -4,26 +4,20 @@ import refToHTML from './refToHTML' /* Renders a keyboard-selectable ref target item */ -function RefTarget() { - RefTarget.super.apply(this, arguments); -} - -RefTarget.Prototype = function() { +class RefTarget extends Component { - this.render = function($$) { - var el = $$('div') + render($$) { + let el = $$('div') .addClass('sc-ref-target') - .attr({'data-id': this.props.node.id}); + .attr({'data-id': this.props.node.id}) if (this.props.selected) { - el.addClass('sm-selected'); + el.addClass('sm-selected') } - var node = this.props.node; - el.html(refToHTML(node)); - return el; - }; -}; - -Component.extend(RefTarget); + let node = this.props.node + el.html(refToHTML(node)) + return el + } +} -export default RefTarget; \ No newline at end of file +export default RefTarget diff --git a/packages/jats/ref/package.js b/packages/jats/ref/package.js index 0e84125f5..b53f5876a 100644 --- a/packages/jats/ref/package.js +++ b/packages/jats/ref/package.js @@ -6,9 +6,9 @@ import RefConverter from './RefConverter' export default { name: 'ref', configure: function(config) { - config.addNode(Ref); - config.addComponent(Ref.type, RefComponent); - config.addComponent(Ref.type+'-target', RefTarget); - config.addConverter('jats', RefConverter); + config.addNode(Ref) + config.addComponent(Ref.type, RefComponent) + config.addComponent(Ref.type+'-target', RefTarget) + config.addConverter('jats', RefConverter) } } diff --git a/packages/jats/ref/refToHTML.js b/packages/jats/ref/refToHTML.js index d935dd383..d5668deae 100644 --- a/packages/jats/ref/refToHTML.js +++ b/packages/jats/ref/refToHTML.js @@ -4,87 +4,87 @@ import { DefaultDOMElement as DOMElement } from 'substance' TODO: Get rid of HTML renderer. Instead extract data as JSON and then pass it to a component for rendering */ -var namesToHTML = function(ref) { - var nameElements = ref.findAll('name'); - var nameEls = []; - for (var i = 0; i < nameElements.length; i++) { - var name = nameElements[i]; - var nameEl = DOMElement.createElement('span'); - nameEl.addClass('name'); - nameEl.text(name.find('surname').text() + ' ' + name.find('given-names').text()); +let namesToHTML = function(ref) { + let nameElements = ref.findAll('name') + let nameEls = [] + for (let i = 0; i < nameElements.length; i++) { + let name = nameElements[i] + let nameEl = DOMElement.createElement('span') + nameEl.addClass('name') + nameEl.text(name.find('surname').text() + ' ' + name.find('given-names').text()) if (i > 0 && i < nameElements.length) { - var comma = DOMElement.createElement('span'); - comma.text(', '); - nameEls.push(comma); + let comma = DOMElement.createElement('span') + comma.text(', ') + nameEls.push(comma) } - nameEls.push(nameEl); + nameEls.push(nameEl) } - return nameEls; -}; + return nameEls +} -var titleToHTML = function (ref) { - var articleTitle = ref.find('article-title'); - var title = DOMElement.createElement('div'); - title.addClass('title'); +let titleToHTML = function (ref) { + let articleTitle = ref.find('article-title') + let title = DOMElement.createElement('div') + title.addClass('title') if (articleTitle) { - title.text(articleTitle.text() + '. '); + title.text(articleTitle.text() + '. ') } else { - title.text('Untitled. '); + title.text('Untitled. ') } - return title; -}; + return title +} -var metaToHTML = function (ref) { +let metaToHTML = function (ref) { // Example: "Cellular and Molecular Life Sciences, 70: 2657-2675, 2013" - var meta = DOMElement.createElement('div'); + let meta = DOMElement.createElement('div') - meta.addClass('meta'); + meta.addClass('meta') - var metaText = ''; + let metaText = '' - var source = ref.find('source'); - if (source) metaText += source.text() + ', '; + let source = ref.find('source') + if (source) metaText += source.text() + ', ' - var volume = ref.find('volume'); - if (volume) metaText += volume.text() + ': '; + let volume = ref.find('volume') + if (volume) metaText += volume.text() + ': ' - var fpage = ref.find('fpage'); - if (fpage) metaText += fpage.text() + '-'; + let fpage = ref.find('fpage') + if (fpage) metaText += fpage.text() + '-' - var lpage = ref.find('lpage'); - if (lpage) metaText += lpage.text() + ', '; + let lpage = ref.find('lpage') + if (lpage) metaText += lpage.text() + ', ' - var year = ref.find("year"); - if (year) metaText += year.text(); + let year = ref.find("year"); + if (year) metaText += year.text() - meta.text(metaText); - return meta; -}; + meta.text(metaText) + return meta +} -var URItoHTML = function (ref) { - var el = DOMElement.createElement('div'); - el.addClass('doi'); +let URItoHTML = function (ref) { + let el = DOMElement.createElement('div') + el.addClass('doi') - var doi = ref.find("pub-id[pub-id-type='doi'], ext-link[ext-link-type='doi']"); - var uri = ref.find("ext-link[ext-link-type='uri']"); + let doi = ref.find("pub-id[pub-id-type='doi'], ext-link[ext-link-type='doi']") + let uri = ref.find("ext-link[ext-link-type='uri']") - var url; + let url if (doi) { - url = 'http://dx.doi.org/' + doi.text(); + url = 'http://dx.doi.org/' + doi.text() } else if (uri) { - url = uri.getAttribute('xlink:href'); + url = uri.getAttribute('xlink:href') } - el.appendChild(DOMElement.createElement('a').setAttribute('href', url).text(url)); - return el; -}; + el.appendChild(DOMElement.createElement('a').setAttribute('href', url).text(url)) + return el +} -var refToHTML = function (ref) { +let refToHTML = function (ref) { // ref element to HTML - https://jats.nlm.nih.gov/archiving/tag-library/0.4/n-ac60.html // ------------------ @@ -135,29 +135,29 @@ var refToHTML = function (ref) { // // - ref = ref.getDOM(); + ref = ref.getDOM() // TODO: remove safeguard for multiple citation elements if(Array.isArray(ref)) { - ref = ref[0]; + ref = ref[0] } - var el = DOMElement.createElement('div'); + let el = DOMElement.createElement('div') if (ref.is('mixed-citation')) { - el.appendChild(ref.textContent); + el.appendChild(ref.textContent) } else if (ref.is('element-citation')) { - el.appendChild(titleToHTML(ref)); - var names = namesToHTML(ref); - for (var i = 0; i < names.length; i++) { - el.appendChild(names[i]); + el.appendChild(titleToHTML(ref)) + let names = namesToHTML(ref) + for (let i = 0; i < names.length; i++) { + el.appendChild(names[i]) } - el.appendChild(metaToHTML(ref)); - el.appendChild(URItoHTML(ref)); + el.appendChild(metaToHTML(ref)) + el.appendChild(URItoHTML(ref)) } else { - el.text('Citation type is unsupported'); + el.text('Citation type is unsupported') } - return el.outerHTML; + return el.outerHTML -}; +} -export default refToHTML; \ No newline at end of file +export default refToHTML From cac8e744098cd2cfeceff656eab261ded78dcad7 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 14:46:52 +0300 Subject: [PATCH 142/167] ES6 jats section package. --- packages/jats/section/Section.js | 27 ++++-------- packages/jats/section/SectionComponent.js | 37 ++++++---------- packages/jats/section/SectionConverter.js | 52 +++++++++++------------ packages/jats/section/package.js | 10 ++--- 4 files changed, 52 insertions(+), 74 deletions(-) diff --git a/packages/jats/section/Section.js b/packages/jats/section/Section.js index 359bb683c..493da276d 100644 --- a/packages/jats/section/Section.js +++ b/packages/jats/section/Section.js @@ -1,24 +1,16 @@ -'use strict'; - import { Container } from 'substance' -function Section() { - Section.super.apply(this, arguments); -} - -Section.Prototype = function() { +class Section extends Container { - this.getTitle = function() { - var titleNode = this.getDocument().get(this.title); + getTitle() { + let titleNode = this.getDocument().get(this.title) if (titleNode) { - return titleNode.getText(); + return titleNode.getText() } - }; -}; - -Container.extend(Section); + } +} -Section.type = "section"; +Section.type = "section" /* Content Model @@ -40,7 +32,6 @@ Section.define({ title: { type: 'id', optional: true }, nodes: { type: ['id'], default: [] }, backMatter: { type: ['id'], default: [] } -}); - -export default Section; +}) +export default Section diff --git a/packages/jats/section/SectionComponent.js b/packages/jats/section/SectionComponent.js index 3828657b4..00a7210b2 100644 --- a/packages/jats/section/SectionComponent.js +++ b/packages/jats/section/SectionComponent.js @@ -1,36 +1,27 @@ -'use strict'; - import { Component, ContainerEditor, TextPropertyEditor } from 'substance' -function SectionComponent() { - SectionComponent.super.apply(this, arguments); -} - -SectionComponent.Prototype = function() { +class SectionComponent extends Component { - this.render = function($$) { - var node = this.props.node; - var doc = node.getDocument(); - var el = $$('div').addClass('sc-section'); + render($$) { + let node = this.props.node + let doc = node.getDocument() + let el = $$('div').addClass('sc-section') if (node.title) { - var title = doc.get(node.title); + let title = doc.get(node.title) el.append( $$(TextPropertyEditor, { path: title.getTextPath() }).addClass('se-title').ref('titleEditor') - ); + ) } el.append( $$(ContainerEditor, { node: node }).ref('contentEditor') .addClass('se-content') - ); - return el; - }; - -}; - -Component.extend(SectionComponent); + ) + return el + } +} -SectionComponent.fullWidth = true; -SectionComponent.noStyle = true; +SectionComponent.fullWidth = true +SectionComponent.noStyle = true -export default SectionComponent; +export default SectionComponent diff --git a/packages/jats/section/SectionConverter.js b/packages/jats/section/SectionConverter.js index 89a8e5b71..9607e0dfa 100644 --- a/packages/jats/section/SectionConverter.js +++ b/packages/jats/section/SectionConverter.js @@ -1,5 +1,3 @@ -'use strict'; - import JATS from '../JATS' import XMLIterator from '../../../util/XMLIterator' @@ -34,59 +32,59 @@ export default { import: function(el, node, converter) { - var children = el.getChildren(); - var iterator = new XMLIterator(children); + let children = el.getChildren() + let iterator = new XMLIterator(children) iterator.optional('sec-meta', function(child) { - node.meta = converter.convertElement(child).id; - }); + node.meta = converter.convertElement(child).id + }) iterator.optional('label', function(child) { - node.label = converter.convertElement(child).id; - }); + node.label = converter.convertElement(child).id + }) iterator.optional('title', function(child) { - node.title = converter.convertElement(child).id; - }); + node.title = converter.convertElement(child).id + }) iterator.manyOf(JATS.PARA_LEVEL, function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.manyOf(['sec'], function(child) { - node.nodes.push(converter.convertElement(child).id); - }); + node.nodes.push(converter.convertElement(child).id) + }) iterator.manyOf(["notes","fn-group","glossary","ref-list"], function(child) { - node.backMatter.push(converter.convertElement(child).id); - }); + node.backMatter.push(converter.convertElement(child).id) + }) if (iterator.hasNext()) { - throw new Error('Illegal JATS: ' + el.outerHTML); + throw new Error('Illegal JATS: ' + el.outerHTML) } }, export: function(node, el, converter) { - var $$ = converter.$$; + let $$ = converter.$$ - el.attr(node.xmlAttributes); + el.attr(node.xmlAttributes) if (node.meta) { el.append( $$('sec-meta').append( converter.convertNode(node.meta) ) - ); + ) } if(node.label) { - el.append(converter.convertNode(node.label)); + el.append(converter.convertNode(node.label)) } if(node.title) { - el.append(converter.convertNode(node.title)); + el.append(converter.convertNode(node.title)) } node.nodes.forEach(function(nodeId) { - el.append(converter.convertNode(nodeId)); - }); + el.append(converter.convertNode(nodeId)) + }) node.backMatter.forEach(function(nodeId) { - el.append(converter.convertNode(nodeId)); - }); + el.append(converter.convertNode(nodeId)) + }) } -}; +} diff --git a/packages/jats/section/package.js b/packages/jats/section/package.js index 9fb0eb2a2..52929e229 100644 --- a/packages/jats/section/package.js +++ b/packages/jats/section/package.js @@ -1,5 +1,3 @@ -'use strict'; - import Section from './Section' import SectionComponent from './SectionComponent' import SectionConverter from './SectionConverter' @@ -7,8 +5,8 @@ import SectionConverter from './SectionConverter' export default { name: 'section', configure: function(config) { - config.addNode(Section); - config.addComponent('section', SectionComponent); - config.addConverter('jats', SectionConverter); + config.addNode(Section) + config.addComponent('section', SectionComponent) + config.addConverter('jats', SectionConverter) } -}; +} From fb7f335a1230580f41b0eee8f0c0c6829e87b7f0 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 14:49:47 +0300 Subject: [PATCH 143/167] ES6 jats subscript package. --- packages/jats/subscript/Subscript.js | 16 +++++----------- packages/jats/subscript/SubscriptConverter.js | 4 +--- packages/jats/subscript/package.js | 8 +++----- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/packages/jats/subscript/Subscript.js b/packages/jats/subscript/Subscript.js index ed6b3a5a6..8bc54a507 100644 --- a/packages/jats/subscript/Subscript.js +++ b/packages/jats/subscript/Subscript.js @@ -1,17 +1,11 @@ -'use strict'; - import { Annotation } from 'substance' -function Subscript() { - Subscript.super.apply(this, arguments); -} - -Annotation.extend(Subscript); +class Subscript extends Annotation {} -Subscript.type = 'subscript'; +Subscript.type = 'subscript' Subscript.define({ - attributes: { type: 'object', default: {} }, -}); + attributes: { type: 'object', default: {} } +}) -export default Subscript; +export default Subscript diff --git a/packages/jats/subscript/SubscriptConverter.js b/packages/jats/subscript/SubscriptConverter.js index 691dbd572..d319e6620 100644 --- a/packages/jats/subscript/SubscriptConverter.js +++ b/packages/jats/subscript/SubscriptConverter.js @@ -1,6 +1,4 @@ -'use strict'; - export default { type: 'subscript', tagName: 'sub' -}; +} diff --git a/packages/jats/subscript/package.js b/packages/jats/subscript/package.js index 44dcbbf93..62859457c 100644 --- a/packages/jats/subscript/package.js +++ b/packages/jats/subscript/package.js @@ -1,12 +1,10 @@ -'use strict'; - import Subscript from './Subscript' import SubscriptConverter from './SubscriptConverter' export default { name: 'subscript', configure: function(config) { - config.addNode(Subscript); - config.addConverter('jats', SubscriptConverter); + config.addNode(Subscript) + config.addConverter('jats', SubscriptConverter) } -}; +} From da973933e79978c12075c89fa7069589fd3a681d Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 14:49:54 +0300 Subject: [PATCH 144/167] ES6 jats superscript package. --- packages/jats/superscript/Superscript.js | 16 +++++----------- .../jats/superscript/SuperscriptConverter.js | 4 +--- packages/jats/superscript/package.js | 8 +++----- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/packages/jats/superscript/Superscript.js b/packages/jats/superscript/Superscript.js index 2d54af3e6..e0a087636 100644 --- a/packages/jats/superscript/Superscript.js +++ b/packages/jats/superscript/Superscript.js @@ -1,17 +1,11 @@ -'use strict'; - import { Annotation } from 'substance' -function Superscript() { - Superscript.super.apply(this, arguments); -} - -Annotation.extend(Superscript); +class Superscript extends Annotation {} -Superscript.type = 'superscript'; +Superscript.type = 'superscript' Superscript.define({ - attributes: { type: 'object', default: {} }, -}); + attributes: { type: 'object', default: {} } +}) -export default Superscript; +export default Superscript diff --git a/packages/jats/superscript/SuperscriptConverter.js b/packages/jats/superscript/SuperscriptConverter.js index d4490cb94..a2d7bca8e 100644 --- a/packages/jats/superscript/SuperscriptConverter.js +++ b/packages/jats/superscript/SuperscriptConverter.js @@ -1,6 +1,4 @@ -'use strict'; - export default { type: 'superscript', tagName: 'sup' -}; +} diff --git a/packages/jats/superscript/package.js b/packages/jats/superscript/package.js index 07f2c887d..7f615e780 100644 --- a/packages/jats/superscript/package.js +++ b/packages/jats/superscript/package.js @@ -1,12 +1,10 @@ -'use strict'; - import Superscript from './Superscript' import SuperscriptConverter from './SuperscriptConverter' export default { name: 'superscript', configure: function(config) { - config.addNode(Superscript); - config.addConverter('jats', SuperscriptConverter); + config.addNode(Superscript) + config.addConverter('jats', SuperscriptConverter) } -}; +} From abd8592b6b14145029ac1c12da382b956c35105d Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 14:55:03 +0300 Subject: [PATCH 145/167] ES6 jats table-wrap package. --- packages/jats/table-wrap/TableWrap.js | 12 +++--------- packages/jats/table-wrap/TableWrapComponent.js | 10 ++-------- packages/jats/table-wrap/TableWrapConverter.js | 4 +--- packages/jats/table-wrap/package.js | 10 ++++------ 4 files changed, 10 insertions(+), 26 deletions(-) diff --git a/packages/jats/table-wrap/TableWrap.js b/packages/jats/table-wrap/TableWrap.js index 94f594386..367426794 100644 --- a/packages/jats/table-wrap/TableWrap.js +++ b/packages/jats/table-wrap/TableWrap.js @@ -1,13 +1,7 @@ -'use strict'; - import Figure from '../figure/Figure' -function TableWrap() { - TableWrap.super.apply(this, arguments); -} - -Figure.extend(TableWrap); +class TableWrap extends Figure {} -TableWrap.type = 'table-wrap'; +TableWrap.type = 'table-wrap' -export default TableWrap; \ No newline at end of file +export default TableWrap diff --git a/packages/jats/table-wrap/TableWrapComponent.js b/packages/jats/table-wrap/TableWrapComponent.js index 2ef33a794..5989bce0f 100644 --- a/packages/jats/table-wrap/TableWrapComponent.js +++ b/packages/jats/table-wrap/TableWrapComponent.js @@ -1,11 +1,5 @@ -'use strict'; - import FigureComponent from '../figure/FigureComponent' -function TableWrapComponent() { - TableWrapComponent.super.apply(this, arguments); -} - -FigureComponent.extend(TableWrapComponent); +class TableWrapComponent extends FigureComponent {} -export default TableWrapComponent; \ No newline at end of file +export default TableWrapComponent diff --git a/packages/jats/table-wrap/TableWrapConverter.js b/packages/jats/table-wrap/TableWrapConverter.js index c58b10e6e..c11d145da 100644 --- a/packages/jats/table-wrap/TableWrapConverter.js +++ b/packages/jats/table-wrap/TableWrapConverter.js @@ -1,5 +1,3 @@ -'use strict'; - import FigureConverter from '../figure/FigureConverter' export default { @@ -9,4 +7,4 @@ export default { import: FigureConverter.import, export: FigureConverter.export -}; \ No newline at end of file +} diff --git a/packages/jats/table-wrap/package.js b/packages/jats/table-wrap/package.js index 4750a03ae..05399b8f4 100644 --- a/packages/jats/table-wrap/package.js +++ b/packages/jats/table-wrap/package.js @@ -1,5 +1,3 @@ -'use strict'; - import TableWrap from './TableWrap' import TableWrapConverter from './TableWrapConverter' import TableWrapComponent from './TableWrapComponent' @@ -7,8 +5,8 @@ import TableWrapComponent from './TableWrapComponent' export default { name: 'table-wrap', configure: function(config) { - config.addNode(TableWrap); - config.addComponent(TableWrap.type, TableWrapComponent); - config.addConverter('jats', TableWrapConverter); + config.addNode(TableWrap) + config.addComponent(TableWrap.type, TableWrapComponent) + config.addConverter('jats', TableWrapConverter) } -}; \ No newline at end of file +} From 34b165b0639e45252c3d34f35ec9030bf6526c55 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 14:55:12 +0300 Subject: [PATCH 146/167] ES6 jats table package. --- packages/jats/table/Table.js | 13 ++++--------- packages/jats/table/TableComponent.js | 24 ++++++++---------------- packages/jats/table/TableConverter.js | 8 +++----- packages/jats/table/package.js | 10 ++++------ 4 files changed, 19 insertions(+), 36 deletions(-) diff --git a/packages/jats/table/Table.js b/packages/jats/table/Table.js index 68b878e5c..6344a0673 100644 --- a/packages/jats/table/Table.js +++ b/packages/jats/table/Table.js @@ -1,17 +1,12 @@ -'use strict'; - import { BlockNode } from 'substance' -function Table() { - Table.super.apply(this, arguments); -} +class Table extends BlockNode {} -BlockNode.extend(Table); +Table.type = 'table' -Table.type = 'table'; Table.define({ attributes: { type: 'object', default: {} }, htmlContent: {type: 'string'} -}); +}) -export default Table; \ No newline at end of file +export default Table diff --git a/packages/jats/table/TableComponent.js b/packages/jats/table/TableComponent.js index dd79a590d..781878828 100644 --- a/packages/jats/table/TableComponent.js +++ b/packages/jats/table/TableComponent.js @@ -1,23 +1,15 @@ -'use strict'; - import { Component } from 'substance' -function TableComponent() { - Component.apply(this, arguments); -} - -TableComponent.Prototype = function() { +class TableComponent extends Component { - this.render = function($$) { - var el = $$('table') + render($$) { + let el = $$('table') .addClass('sc-table') .attr('data-id', this.props.node.id) - .html(this.props.node.htmlContent); + .html(this.props.node.htmlContent) - return el; - }; -}; - -Component.extend(TableComponent); + return el + } +} -export default TableComponent; \ No newline at end of file +export default TableComponent diff --git a/packages/jats/table/TableConverter.js b/packages/jats/table/TableConverter.js index f4d7203cc..7780393a0 100644 --- a/packages/jats/table/TableConverter.js +++ b/packages/jats/table/TableConverter.js @@ -1,15 +1,13 @@ -'use strict'; - export default { type: 'table', // Substance node model tagName: 'table', // Used as a matcher import: function(el, node) { - node.htmlContent = el.innerHTML; + node.htmlContent = el.innerHTML }, export: function(node, el) { - el.html(node.htmlContent); + el.html(node.htmlContent) } -}; +} diff --git a/packages/jats/table/package.js b/packages/jats/table/package.js index 68f9a1242..9b7c50ad0 100644 --- a/packages/jats/table/package.js +++ b/packages/jats/table/package.js @@ -1,5 +1,3 @@ -'use strict'; - import Table from './Table' import TableComponent from './TableComponent' import TableConverter from './TableConverter' @@ -7,8 +5,8 @@ import TableConverter from './TableConverter' export default { name: 'table', configure: function(config) { - config.addNode(Table); - config.addComponent(Table.type, TableComponent); - config.addConverter('jats', TableConverter); + config.addNode(Table) + config.addComponent(Table.type, TableComponent) + config.addConverter('jats', TableConverter) } -}; \ No newline at end of file +} From 230a287bb6fc9ec50cef07eb5c7ec1ba7acea2c2 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 14:55:19 +0300 Subject: [PATCH 147/167] ES6 jats title package. --- packages/jats/title/Title.js | 16 +++++--------- packages/jats/title/TitleComponent.js | 30 ++++++++++----------------- packages/jats/title/TitleConverter.js | 6 ++---- packages/jats/title/package.js | 10 ++++----- 4 files changed, 22 insertions(+), 40 deletions(-) diff --git a/packages/jats/title/Title.js b/packages/jats/title/Title.js index 6da1f87e8..1158fa913 100644 --- a/packages/jats/title/Title.js +++ b/packages/jats/title/Title.js @@ -1,17 +1,11 @@ -'use strict'; - import { TextNode } from 'substance' -function Title() { - Title.super.apply(this, arguments); -} - -TextNode.extend(Title); +class Title extends TextNode {} -Title.type = 'title'; +Title.type = 'title' Title.define({ - attributes: { type: 'object', default: {} }, -}); + attributes: { type: 'object', default: {} } +}) -export default Title; \ No newline at end of file +export default Title diff --git a/packages/jats/title/TitleComponent.js b/packages/jats/title/TitleComponent.js index ab7c9adf9..1a568e2af 100644 --- a/packages/jats/title/TitleComponent.js +++ b/packages/jats/title/TitleComponent.js @@ -1,25 +1,17 @@ -'use strict'; - import { Component, TextPropertyEditor } from 'substance' -function TitleComponent() { - TitleComponent.super.apply(this, arguments); -} - -TitleComponent.Prototype = function() { +class TitleComponent extends Component { - this.render = function($$) { - var el = $$('div').addClass('sc-title'); - var node = this.props.node; - var titleEditor = $$(TextPropertyEditor, { + render($$) { + let el = $$('div').addClass('sc-title') + let node = this.props.node + let titleEditor = $$(TextPropertyEditor, { disabled: this.props.disabled, path: node.getTextPath() - }).ref('titleEditor'); - el.append(titleEditor); - return el; - }; -}; - -Component.extend(TitleComponent); + }).ref('titleEditor') + el.append(titleEditor) + return el + } +} -export default TitleComponent; \ No newline at end of file +export default TitleComponent diff --git a/packages/jats/title/TitleConverter.js b/packages/jats/title/TitleConverter.js index 567e52784..af022ab85 100644 --- a/packages/jats/title/TitleConverter.js +++ b/packages/jats/title/TitleConverter.js @@ -1,8 +1,6 @@ -'use strict'; - import TextNodeConverter from '../TextNodeConverter' export default TextNodeConverter.extend({ type: 'title', - tagName: 'title', -}); + tagName: 'title' +}) diff --git a/packages/jats/title/package.js b/packages/jats/title/package.js index a4c3f9529..ca2ca7350 100644 --- a/packages/jats/title/package.js +++ b/packages/jats/title/package.js @@ -1,5 +1,3 @@ -'use strict'; - import Title from './Title' import TitleConverter from './TitleConverter' import TitleComponent from './TitleComponent' @@ -7,8 +5,8 @@ import TitleComponent from './TitleComponent' export default { name: 'title', configure: function(config) { - config.addNode(Title); - config.addConverter('jats', TitleConverter); - config.addComponent(Title.type, TitleComponent); + config.addNode(Title) + config.addConverter('jats', TitleConverter) + config.addComponent(Title.type, TitleComponent) } -}; +} From df46fd5a667eb4b0ad4e01e80dda5d893e391e69 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 21:33:50 +0300 Subject: [PATCH 148/167] ES6 author package. --- packages/author/AuthorImporter.js | 2 +- packages/author/JATSTransformer.js | 206 ++++++++++---------- packages/author/heading/HeadingComponent.js | 1 - packages/author/heading/package.js | 18 +- 4 files changed, 111 insertions(+), 116 deletions(-) diff --git a/packages/author/AuthorImporter.js b/packages/author/AuthorImporter.js index d18733044..a527fdbdf 100644 --- a/packages/author/AuthorImporter.js +++ b/packages/author/AuthorImporter.js @@ -12,4 +12,4 @@ class AuthorImporter extends JATSImporter { } -export default AuthorImporter \ No newline at end of file +export default AuthorImporter diff --git a/packages/author/JATSTransformer.js b/packages/author/JATSTransformer.js index 08460582a..38df571d1 100644 --- a/packages/author/JATSTransformer.js +++ b/packages/author/JATSTransformer.js @@ -1,5 +1,5 @@ import last from 'lodash/last' -import { oo, JSONConverter, annotationHelpers } from 'substance' +import { JSONConverter, annotationHelpers } from 'substance' /* EXPERIMENTAL: @@ -24,129 +24,125 @@ import { oo, JSONConverter, annotationHelpers } from 'substance' is used at the same time with the JATS editing interface. */ -function JATSTransformer() {} +class JATSTransformer { -JATSTransformer.Prototype = function() { + fromJATS(doc) { + let jsonConverter = new JSONConverter() + let json = doc.toJSON() + let converted = doc.newInstance() + jsonConverter.importDocument(converted, json) - this.fromJATS = function(doc) { - var jsonConverter = new JSONConverter(); - var json = doc.toJSON(); - var converted = doc.newInstance(); - jsonConverter.importDocument(converted, json); + let body = doc.get('body') + let nodes = body.getNodes() - var body = doc.get('body'); - var nodes = body.getNodes(); - - var nodeIds = _flattenSections(converted, nodes, [], 1); + let nodeIds = _flattenSections(converted, nodes, [], 1) converted.create({ id: 'bodyFlat', type: 'body', nodes: nodeIds - }); - return converted; - }; - - function _flattenSections(doc, nodes, result, level) { - nodes.forEach(function(node) { - if (node.type === 'section') { - var id = 'h_' + node.id; - var titleId = node.title; - doc.create({ - id: id, - type: 'heading', - sectionId: node.id, - level: level, - content: node.getTitle(), - }); - if (titleId) { - annotationHelpers.transferAnnotations(doc, [titleId, 'content'], 0, [id, 'content'], 0); - } - result.push(id); - result = _flattenSections(doc, node.getNodes(), result, level+1); - result = result.concat(node.backMatter); - } else { - result.push(node.id); - } - }); - return result; + }) + return converted } - this.toJATS = function(doc) { - var jsonConverter = new JSONConverter(); - var json = doc.toJSON(); - var converted = doc.newInstance(); - jsonConverter.importDocument(converted, json); + toJATS(doc) { + let jsonConverter = new JSONConverter() + let json = doc.toJSON() + let converted = doc.newInstance() + jsonConverter.importDocument(converted, json) - var body = converted.get('bodyFlat'); - var nodeIds = _createSections(converted, body.getNodes()); + let body = converted.get('bodyFlat') + let nodeIds = _createSections(converted, body.getNodes()) if (converted.get('body')) { - converted.set(['body', 'nodes'], nodeIds); + converted.set(['body', 'nodes'], nodeIds) } else { converted.create({ id: 'body', type: 'body', nodes: nodeIds - }); - } - return converted; - }; - - var _isSectionBackMatter = { - "notes": true, - "fn-group": true, - "glossary": true, - "ref-list": true - }; - - function _createSections(doc, nodes) { - var stack = [{ - nodes: [], - backMatter: [] - }]; - - function _createSection(item) { - var title = doc.create({ - type: 'title', - content: item.node.getText(), - }); - annotationHelpers.transferAnnotations(doc, item.node.getTextPath(), 0, title.getTextPath(), 0); - return doc.create({ - type: 'section', - title: title.id, - nodes: item.nodes, - backMatter: item.backMatter - }); + }) } - var item, sec; - - for (var i=0; i < nodes.length; i++) { - var node = nodes[i]; - if (node.type === 'heading') { - while (stack.length >= node.level+1) { - item = stack.pop(); - sec = _createSection(item); - last(stack).nodes.push(sec.id); - } - stack.push({ - node: node, - nodes: [], - backMatter: [], - }); - } else if (_isSectionBackMatter[node.type]) { - last(stack).backMatter.push(node.id); - } else { - last(stack).nodes.push(node.id); + return converted + } +} + +let _isSectionBackMatter = { + "notes": true, + "fn-group": true, + "glossary": true, + "ref-list": true +} + +function _flattenSections(doc, nodes, result, level) { + nodes.forEach(function(node) { + if (node.type === 'section') { + let id = 'h_' + node.id; + let titleId = node.title; + doc.create({ + id: id, + type: 'heading', + sectionId: node.id, + level: level, + content: node.getTitle(), + }) + if (titleId) { + annotationHelpers.transferAnnotations(doc, [titleId, 'content'], 0, [id, 'content'], 0) } + result.push(id) + result = _flattenSections(doc, node.getNodes(), result, level+1) + result = result.concat(node.backMatter) + } else { + result.push(node.id) } - while (stack.length > 1) { - item = stack.pop(); - sec = _createSection(item); - last(stack).nodes.push(sec.id); + }) + return result +} + +function _createSections(doc, nodes) { + let stack = [{ + nodes: [], + backMatter: [] + }] + + function _createSection(item) { + let title = doc.create({ + type: 'title', + content: item.node.getText(), + }) + annotationHelpers.transferAnnotations(doc, item.node.getTextPath(), 0, title.getTextPath(), 0) + return doc.create({ + type: 'section', + title: title.id, + nodes: item.nodes, + backMatter: item.backMatter + }) + } + let item, sec + + for (let i=0; i < nodes.length; i++) { + let node = nodes[i] + if (node.type === 'heading') { + while (stack.length >= node.level+1) { + item = stack.pop() + sec = _createSection(item) + last(stack).nodes.push(sec.id) + } + stack.push({ + node: node, + nodes: [], + backMatter: [] + }) + } else if (_isSectionBackMatter[node.type]) { + last(stack).backMatter.push(node.id) + } else { + last(stack).nodes.push(node.id) } - return stack[0].nodes; } -}; - -oo.initClass(JATSTransformer); + while (stack.length > 1) { + item = stack.pop() + sec = _createSection(item) + last(stack).nodes.push(sec.id) + } + return stack[0].nodes +} -export default JATSTransformer; +export default JATSTransformer diff --git a/packages/author/heading/HeadingComponent.js b/packages/author/heading/HeadingComponent.js index 2e73e49db..d69a78d90 100644 --- a/packages/author/heading/HeadingComponent.js +++ b/packages/author/heading/HeadingComponent.js @@ -6,7 +6,6 @@ class HeadingComponent extends TextBlockComponent { let el = super.render($$) return el.addClass("sc-heading sm-level-"+this.props.node.level) } - } export default HeadingComponent diff --git a/packages/author/heading/package.js b/packages/author/heading/package.js index 33aff5bed..7cc59b169 100644 --- a/packages/author/heading/package.js +++ b/packages/author/heading/package.js @@ -5,32 +5,32 @@ import { HeadingPackage as CorePackage } from 'substance' export default { name: 'heading', configure: function(config) { - config.addNode(Heading); - config.addComponent(Heading.type, HeadingComponent); - config.addConverter('html', CorePackage.HeadingHTMLConverter); + config.addNode(Heading) + config.addComponent(Heading.type, HeadingComponent) + config.addConverter('html', CorePackage.HeadingHTMLConverter) config.addTextType({ name: 'heading1', data: {type: 'heading', level: 1} - }); + }) config.addTextType({ name: 'heading2', data: {type: 'heading', level: 2} - }); + }) config.addTextType({ name: 'heading3', data: {type: 'heading', level: 3} - }); + }) config.addLabel('heading1', { en: 'Heading 1', de: 'Überschrift 1' - }); + }) config.addLabel('heading2', { en: 'Heading 2', de: 'Überschrift 2' - }); + }) config.addLabel('heading3', { en: 'Heading 3', de: 'Überschrift 3' - }); + }) } } From 5e752e206528f297319864f9bda867be858441f1 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 21:34:02 +0300 Subject: [PATCH 149/167] ES6 common package. --- packages/common/AbstractWriter.js | 2 +- packages/common/EditXML.js | 63 ++++++++++++--------------- packages/common/SaveHandler.js | 8 ++-- packages/common/XMLAttributeEditor.js | 60 ++++++++++++------------- packages/common/XMLEditor.js | 28 +++++------- packages/common/package.js | 2 +- 6 files changed, 73 insertions(+), 90 deletions(-) diff --git a/packages/common/AbstractWriter.js b/packages/common/AbstractWriter.js index 043f12c35..90340a4c5 100644 --- a/packages/common/AbstractWriter.js +++ b/packages/common/AbstractWriter.js @@ -1,4 +1,4 @@ -import { ProseEditor, Highlights, Toolbar, AbstractEditor } from 'substance' +import { Highlights, Toolbar, AbstractEditor } from 'substance' import SaveHandler from './SaveHandler' // TODO: we need to think if it is really a good idea to diff --git a/packages/common/EditXML.js b/packages/common/EditXML.js index 6c37891ec..dc6bab56f 100644 --- a/packages/common/EditXML.js +++ b/packages/common/EditXML.js @@ -2,76 +2,71 @@ import { Button, Component } from 'substance' import XMLAttributeEditor from './XMLAttributeEditor' import XMLEditor from './XMLEditor' -function EditXML() { - EditXML.super.apply(this, arguments); -} +class EditXML extends Component { -EditXML.Prototype = function() { - this.render = function($$) { - var node = this.props.node; - var el = $$('div').addClass('sc-edit-xml'); - var tagName = node.tagName || node.constructor.type; + render($$) { + let node = this.props.node + let el = $$('div').addClass('sc-edit-xml') + let tagName = node.tagName || node.constructor.type el.append( $$('div').addClass('se-tag sm-open-tag-start').append('<'+tagName) - ); + ) el.append( $$(XMLAttributeEditor, { attributes: node.attributes }).ref('attributesEditor') - ); + ) el.append( $$('div').addClass('se-tag sm-open-tag-end').append('>') - ); + ) el.append( $$(XMLEditor, { xml: node.xmlContent }).ref('xmlEditor') - ); + ) el.append( $$('div').addClass('se-tag sm-end-tag').append('') - ); + ) el.append( $$('div').addClass('se-actions').append( $$(Button).append('Save').on('click', this._save), $$(Button).addClass('se-cancel').append('Cancel').on('click', this._cancel) ) - ); - return el; - }; + ) + return el + } - this._cancel = function() { + _cancel() { this.send('closeModal'); - }; + } - this._delete = function() { + _delete() { console.warn('Not yet implemented'); // TODO: this is actually not very trivial as we don't // know the node's context. E.g. when deleting // a contrib node we need to remove the id from - }; + } - this._save = function() { - var documentSession = this.context.documentSession; - var node = this.props.node; + _save() { + let documentSession = this.context.documentSession + let node = this.props.node - var newAttributes = this.refs.attributesEditor.getAttributes(); - var newXML = this.refs.xmlEditor.getXML(); + let newAttributes = this.refs.attributesEditor.getAttributes() + let newXML = this.refs.xmlEditor.getXML() // TODO: add validity checks. E.g. try to parse XML string documentSession.transaction(function(tx) { - tx.set([node.id, 'xmlContent'], newXML); - tx.set([node.id, 'attributes'], newAttributes); - }); - this.send('closeModal'); - }; -}; - -Component.extend(EditXML); + tx.set([node.id, 'xmlContent'], newXML) + tx.set([node.id, 'attributes'], newAttributes) + }) + this.send('closeModal') + } +} -export default EditXML; +export default EditXML diff --git a/packages/common/SaveHandler.js b/packages/common/SaveHandler.js index 984cea4ec..4abdd4d3d 100644 --- a/packages/common/SaveHandler.js +++ b/packages/common/SaveHandler.js @@ -1,14 +1,14 @@ export default class SaveHandler { constructor(context) { - this.context = context; + this.context = context } saveDocument(doc, changes, cb) { - var exporter = this.context.exporter; - var xml = exporter.exportDocument(doc); + let exporter = this.context.exporter + let xml = exporter.exportDocument(doc) // console.log('### SAVING XML', xml); - this.context.xmlStore.writeXML(this.context.documentId, xml, cb); + this.context.xmlStore.writeXML(this.context.documentId, xml, cb) } } diff --git a/packages/common/XMLAttributeEditor.js b/packages/common/XMLAttributeEditor.js index d02fd8e83..32514913f 100644 --- a/packages/common/XMLAttributeEditor.js +++ b/packages/common/XMLAttributeEditor.js @@ -1,48 +1,42 @@ import map from 'lodash/map' import { Component } from 'substance' -function XMLAttributeEditor() { - XMLAttributeEditor.super.apply(this, arguments); -} - -XMLAttributeEditor.Prototype = function() { +class XMLAttributeEditor extends Component { - this._getAttributeString = function() { + _getAttributeString() { return map(this.props.attributes, function(val, key) { - return key+'='+val; - }).join('\n'); - }; + return key+'='+val + }).join('\n') + } - this._parseAttributesFromString = function(newAttrs) { - newAttrs = newAttrs.split('\n'); - var res = {}; + _parseAttributesFromString(newAttrs) { + newAttrs = newAttrs.split('\n') + let res = {} newAttrs.forEach(function(attr) { - var parts = attr.split('='); - res[parts[0]] = parts[1]; - }); - return res; - }; + let parts = attr.split('=') + res[parts[0]] = parts[1] + }) + return res + } /* Returns the changed attributes */ - this.getAttributes = function() { - var attrStr = this.refs.attributesEditor.val(); - return this._parseAttributesFromString(attrStr); - }; - - this.render = function($$) { - var node = this.props.node; - var el = $$('div').addClass('sc-xml-attribute-editor'); - var attributeStr = this._getAttributeString(node); + getAttributes() { + let attrStr = this.refs.attributesEditor.val() + return this._parseAttributesFromString(attrStr) + } + + render($$) { + let node = this.props.node + let el = $$('div').addClass('sc-xml-attribute-editor') + let attributeStr = this._getAttributeString(node) el.append( $$('textarea') .ref('attributesEditor') .append(attributeStr) - ); - return el; - }; -}; - -Component.extend(XMLAttributeEditor); + ) + return el + } +} -export default XMLAttributeEditor; +export default XMLAttributeEditor diff --git a/packages/common/XMLEditor.js b/packages/common/XMLEditor.js index 2324f146e..930ef5b98 100644 --- a/packages/common/XMLEditor.js +++ b/packages/common/XMLEditor.js @@ -1,28 +1,22 @@ import { Component } from 'substance' -function XMLEditor() { - XMLEditor.super.apply(this, arguments); -} - -XMLEditor.Prototype = function() { +class XMLEditor extends Component { - this.getXML = function() { - return this.refs.xml.val(); - }; + getXML() { + return this.refs.xml.val() + } - this.render = function($$) { - var el = $$('div').addClass('sc-xml-editor'); + render($$) { + let el = $$('div').addClass('sc-xml-editor') el.append( $$('textarea') .ref('xml') .append(this.props.xml) - ); - return el; - }; + ) + return el + } -}; - -Component.extend(XMLEditor); +} -export default XMLEditor; +export default XMLEditor diff --git a/packages/common/package.js b/packages/common/package.js index 36d5961ea..f664a9cf3 100644 --- a/packages/common/package.js +++ b/packages/common/package.js @@ -4,6 +4,6 @@ export default { name: 'common', configure: function(config) { config.addComponent('tool-target-insert', ToolDropdown) - config.addLabel('insert', 'Insert'); + config.addLabel('insert', 'Insert') } } From 75512ff8c469c41a791dd87c00af34d454fea8f6 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 21:34:43 +0300 Subject: [PATCH 150/167] ES6 inline wrapper package. --- .../inline-wrapper/InlineWrapperJATSConverter.js | 14 ++++++-------- packages/inline-wrapper/InlineWrapperPackage.js | 4 ++-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/inline-wrapper/InlineWrapperJATSConverter.js b/packages/inline-wrapper/InlineWrapperJATSConverter.js index ce6aa984e..ab3c2d756 100644 --- a/packages/inline-wrapper/InlineWrapperJATSConverter.js +++ b/packages/inline-wrapper/InlineWrapperJATSConverter.js @@ -1,21 +1,19 @@ -'use strict'; - export default { type: 'inline-wrapper', matchElement: function(el, converter) { - var blockConverter = converter._getConverterForElement(el, 'block'); - return Boolean(blockConverter && blockConverter.type !== 'unsupported'); + var blockConverter = converter._getConverterForElement(el, 'block') + return Boolean(blockConverter && blockConverter.type !== 'unsupported') }, import: function(el, node, converter) { - node.id = converter.nextId('inline-wrapper'); - node.wrappedNode = converter.convertElement(el).id; + node.id = converter.nextId('inline-wrapper') + node.wrappedNode = converter.convertElement(el).id }, export: function(node, el, converter) { - return converter.convertNode(node.wrappedNode); + return converter.convertNode(node.wrappedNode) } -}; +} diff --git a/packages/inline-wrapper/InlineWrapperPackage.js b/packages/inline-wrapper/InlineWrapperPackage.js index f71fe3927..018afe524 100644 --- a/packages/inline-wrapper/InlineWrapperPackage.js +++ b/packages/inline-wrapper/InlineWrapperPackage.js @@ -4,7 +4,7 @@ import InlineWrapperJATSConverter from './InlineWrapperJATSConverter' export default { name: 'inline-wrapper', configure: function(config) { - config.import(InlineWrapperPackage); - config.addConverter('jats', InlineWrapperJATSConverter); + config.import(InlineWrapperPackage) + config.addConverter('jats', InlineWrapperJATSConverter) } } From e11faa4dbaee2cfe7d8a500e5ad8a3ce58976e7c Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 21:36:05 +0300 Subject: [PATCH 151/167] ES6 publisher package. --- packages/publisher/Publisher.js | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/publisher/Publisher.js b/packages/publisher/Publisher.js index df1807419..d173d383c 100644 --- a/packages/publisher/Publisher.js +++ b/packages/publisher/Publisher.js @@ -4,8 +4,8 @@ import PublisherTOCProvider from './PublisherTOCProvider' class Publisher extends AbstractWriter { render($$) { - var SplitPane = this.componentRegistry.get('split-pane') - var el = $$('div').addClass('sc-publisher') + let SplitPane = this.componentRegistry.get('split-pane') + let el = $$('div').addClass('sc-publisher') el.append( $$(SplitPane, {splitType: 'vertical', sizeB: '400px'}).append( this._renderMainSection($$), @@ -22,9 +22,9 @@ class Publisher extends AbstractWriter { } _renderMainSection($$) { - var SplitPane = this.componentRegistry.get('split-pane') - var mainSection = $$('div').addClass('se-main-section') - var splitPane = $$(SplitPane, {splitType: 'horizontal'}).append( + let SplitPane = this.componentRegistry.get('split-pane') + let mainSection = $$('div').addClass('se-main-section') + let splitPane = $$(SplitPane, {splitType: 'horizontal'}).append( this._renderToolbar($$), this._renderContentPanel($$) ); @@ -33,25 +33,25 @@ class Publisher extends AbstractWriter { } _renderContentPanel($$) { - var doc = this.documentSession.getDocument() - var Layout = this.componentRegistry.get('layout') - var ScrollPane = this.componentRegistry.get('scroll-pane') + let doc = this.documentSession.getDocument() + let Layout = this.componentRegistry.get('layout') + let ScrollPane = this.componentRegistry.get('scroll-pane') - var contentPanel = $$(ScrollPane, { + let contentPanel = $$(ScrollPane, { tocProvider: this.tocProvider, scrollbarType: 'substance', scrollbarPosition: 'left', overlay: ProseEditorOverlayTools, highlights: this.contentHighlights - }).ref('contentPanel'); + }).ref('contentPanel') - var layout = $$(Layout, { + let layout = $$(Layout, { width: 'large' }) - var ArticleComponent = this.componentRegistry.get('article') + let ArticleComponent = this.componentRegistry.get('article') - var article = doc.get('article') + let article = doc.get('article') layout.append( $$(ArticleComponent, { node: article, @@ -59,7 +59,7 @@ class Publisher extends AbstractWriter { disabled: this.props.disabled, configurator: this.props.configurator }) - ); + ) contentPanel.append(layout) return contentPanel } @@ -77,5 +77,4 @@ class Publisher extends AbstractWriter { } } - -export default Publisher; +export default Publisher From 7f6a56287e8ce98e7aec26979bd02eddd5b632e8 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 21:40:46 +0300 Subject: [PATCH 152/167] ES6 tagging package,. --- packages/tagging/TaggingPackage.js | 1 - packages/tagging/aff/TagAffCommand.js | 40 +++++------ packages/tagging/contrib/TagContribCommand.js | 40 +++++------ packages/tagging/ref/TagRefCommand.js | 66 +++++++++---------- 4 files changed, 73 insertions(+), 74 deletions(-) diff --git a/packages/tagging/TaggingPackage.js b/packages/tagging/TaggingPackage.js index 0a7b9ac56..025fc2a71 100644 --- a/packages/tagging/TaggingPackage.js +++ b/packages/tagging/TaggingPackage.js @@ -38,4 +38,3 @@ export default { config.addLabel('tag-contrib', 'Author') } } - diff --git a/packages/tagging/aff/TagAffCommand.js b/packages/tagging/aff/TagAffCommand.js index 334634491..95fede370 100644 --- a/packages/tagging/aff/TagAffCommand.js +++ b/packages/tagging/aff/TagAffCommand.js @@ -3,48 +3,48 @@ import { Command, uuid, documentHelpers, deleteSelection } from 'substance' class TagAffCommand extends Command { getCommandState(params, context) { - var documentSession = context.documentSession; - var doc = documentSession.getDocument(); + let documentSession = context.documentSession + let doc = documentSession.getDocument() - var sel = this._getSelection(params); - var disabled = true; - var stringName; // author name without components + let sel = this._getSelection(params) + let disabled = true + let stringName // author name without components if (sel.isPropertySelection() && !sel.isCollapsed()) { - disabled = false; - stringName = documentHelpers.getTextForSelection(doc, sel); + disabled = false + stringName = documentHelpers.getTextForSelection(doc, sel) } return { disabled: disabled, stringName: stringName, active: false - }; + } } execute(params, context) { - var stringName = params.stringName; - var documentSession = context.documentSession; + let stringName = params.stringName + let documentSession = context.documentSession documentSession.transaction(function(tx, args) { - var contribGroupNodeId = tx.document.getContribGroup().id; - var contribGroupNode = tx.get(contribGroupNodeId); - var newAff = { + let contribGroupNodeId = tx.document.getContribGroup().id + let contribGroupNode = tx.get(contribGroupNodeId) + let newAff = { id: uuid('aff'), type: 'aff', xmlContent: stringName, attributes: { generator: 'texture' } - }; + } - var affNode = tx.create(newAff); - contribGroupNode.show(affNode.id); - args = deleteSelection(tx, args); - return args; - }); + let affNode = tx.create(newAff) + contribGroupNode.show(affNode.id) + args = deleteSelection(tx, args) + return args + }) - return {status: 'ok'}; + return {status: 'ok'} } } diff --git a/packages/tagging/contrib/TagContribCommand.js b/packages/tagging/contrib/TagContribCommand.js index c9e843fde..6ab981567 100644 --- a/packages/tagging/contrib/TagContribCommand.js +++ b/packages/tagging/contrib/TagContribCommand.js @@ -3,48 +3,48 @@ import { Command, uuid, documentHelpers, deleteSelection } from 'substance' class TagContribCommand extends Command { getCommandState(params, context) { - var documentSession = context.documentSession; - var doc = documentSession.getDocument(); + let documentSession = context.documentSession + let doc = documentSession.getDocument() - var sel = this._getSelection(params); - var disabled = true; - var stringName; // author name without components + let sel = this._getSelection(params) + let disabled = true + let stringName // author name without components if (sel.isPropertySelection() && !sel.isCollapsed()) { - disabled = false; - stringName = documentHelpers.getTextForSelection(doc, sel); + disabled = false + stringName = documentHelpers.getTextForSelection(doc, sel) } return { disabled: disabled, stringName: stringName, active: false - }; + } } execute(params, context) { - var stringName = params.stringName; - var documentSession = context.documentSession; + let stringName = params.stringName + let documentSession = context.documentSession documentSession.transaction(function(tx, args) { - var contribGroupNodeId = tx.document.getContribGroup().id; - var contribGroupNode = tx.get(contribGroupNodeId); - var newContrib = { + let contribGroupNodeId = tx.document.getContribGroup().id + let contribGroupNode = tx.get(contribGroupNodeId) + let newContrib = { id: uuid('contrib'), type: 'contrib', xmlContent: ''+stringName+'', attributes: { generator: 'texture' } - }; + } - var contribNode = tx.create(newContrib); - contribGroupNode.show(contribNode.id); - args = deleteSelection(tx, args); - return args; - }); + let contribNode = tx.create(newContrib) + contribGroupNode.show(contribNode.id) + args = deleteSelection(tx, args) + return args + }) - return {status: 'ok'}; + return {status: 'ok'} } } diff --git a/packages/tagging/ref/TagRefCommand.js b/packages/tagging/ref/TagRefCommand.js index fcb1a7038..8699781e5 100644 --- a/packages/tagging/ref/TagRefCommand.js +++ b/packages/tagging/ref/TagRefCommand.js @@ -3,27 +3,27 @@ import { Command, uuid, Selection } from 'substance' class TagRefCommand extends Command { getCommandState(params, context) { - var documentSession = context.documentSession; - var doc = documentSession.getDocument(); + let documentSession = context.documentSession + let doc = documentSession.getDocument() - var sel = this._getSelection(params); - var disabled = true; - var nodeIds; // all nodes included in the selection + let sel = this._getSelection(params) + let disabled = true + let nodeIds // all nodes included in the selection if (sel.isPropertySelection()) { - disabled = false; - nodeIds = [ sel.path[0] ]; + disabled = false + nodeIds = [ sel.path[0] ] } else if (sel.isContainerSelection()) { - var fragments = sel.getFragments(); + let fragments = sel.getFragments() nodeIds = - fragments.map(frag => frag.path[0]); - var isParagraph = - nodeId => doc.get(nodeId).type === 'paragraph'; - var onlyParagraphs = - (nodeIds) => nodeIds.every(isParagraph); + fragments.map(frag => frag.path[0]) + let isParagraph = + nodeId => doc.get(nodeId).type === 'paragraph' + let onlyParagraphs = + (nodeIds) => nodeIds.every(isParagraph) if (onlyParagraphs(nodeIds)) { - disabled = false; + disabled = false } } @@ -31,48 +31,48 @@ class TagRefCommand extends Command { disabled: disabled, nodeIds: nodeIds, active: false - }; + } } execute(params, context) { - var nodeIds = params.nodeIds; - var documentSession = context.documentSession; - var focusedSurface = context.surfaceManager.getFocusedSurface(); + let nodeIds = params.nodeIds + let documentSession = context.documentSession + let focusedSurface = context.surfaceManager.getFocusedSurface() documentSession.transaction(function(tx) { - var refListId = tx.document.getRefList().id; - var refListNode = tx.get(refListId); + let refListId = tx.document.getRefList().id + let refListNode = tx.get(refListId) nodeIds.forEach(nodeId => { - var p = tx.get(nodeId); - var newRef = { + let p = tx.get(nodeId) + let newRef = { id: uuid('ref'), type: 'ref', xmlContent: ''+p.content+'', attributes: { generator: 'texture' } - }; - var refNode = tx.create(newRef); - refListNode.show(refNode.id); + } + let refNode = tx.create(newRef) + refListNode.show(refNode.id) // Remove original paragraphs from container // We need to look up the owning container // by inspecting the focused surface. - var containerId = focusedSurface.getContainerId(); + let containerId = focusedSurface.getContainerId() if (containerId) { - var container = tx.get(containerId); - container.hide(nodeId); - tx.delete(nodeId); + let container = tx.get(containerId) + container.hide(nodeId) + tx.delete(nodeId) } - }); + }) return { selection: Selection.nullSelection - }; - }); + } + }) - return {status: 'ok'}; + return {status: 'ok'} } } From 896f37562ad96a1160076c1fd1ad44fde504be31 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 21:43:24 +0300 Subject: [PATCH 153/167] ES6 texture package. --- packages/texture/FileClientStub.js | 1 - packages/texture/Texture.js | 6 ++---- packages/texture/TextureConfigurator.js | 4 ++-- packages/texture/package.js | 3 --- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/packages/texture/FileClientStub.js b/packages/texture/FileClientStub.js index a7883069e..71644371c 100644 --- a/packages/texture/FileClientStub.js +++ b/packages/texture/FileClientStub.js @@ -23,5 +23,4 @@ class FileClientStub { } } - export default FileClientStub diff --git a/packages/texture/Texture.js b/packages/texture/Texture.js index 10b84809b..a929dbe10 100644 --- a/packages/texture/Texture.js +++ b/packages/texture/Texture.js @@ -1,6 +1,4 @@ import { Component, DocumentSession } from 'substance' -import Author from '../author/Author' -import Publisher from '../publisher/Publisher' /* Texture Component @@ -88,8 +86,8 @@ class Texture extends Component { }) return } - var importer = configurator.createImporter('jats') - var doc = importer.importDocument(xml) + let importer = configurator.createImporter('jats') + let doc = importer.importDocument(xml) // HACK: For debug purposes window.doc = doc diff --git a/packages/texture/TextureConfigurator.js b/packages/texture/TextureConfigurator.js index b280d4716..98c480830 100644 --- a/packages/texture/TextureConfigurator.js +++ b/packages/texture/TextureConfigurator.js @@ -46,10 +46,10 @@ class TextureConfigurator extends Configurator { } getXMLStore() { - var XMLStoreClass = this.config.XMLStoreClass + let XMLStoreClass = this.config.XMLStoreClass return new XMLStoreClass() } } -export default TextureConfigurator \ No newline at end of file +export default TextureConfigurator diff --git a/packages/texture/package.js b/packages/texture/package.js index 67cadcfcf..ebc671cf1 100644 --- a/packages/texture/package.js +++ b/packages/texture/package.js @@ -1,6 +1,3 @@ -'use strict'; - -import { ProseEditorPackage } from 'substance' import AuthorPackage from '../author/package' import PublisherPackage from '../publisher/package' From c8e76a27a2fe8342d9d6cc8a1e86225da10ccf45 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 21:47:19 +0300 Subject: [PATCH 154/167] ES6 unsupported package. --- packages/unsupported/UnsupportedInlineNode.js | 12 +++----- .../UnsupportedInlineNodeComponent.js | 22 ++++++--------- .../unsupported/UnsupportedInlineNodeTool.js | 7 ++--- packages/unsupported/UnsupportedNode.js | 12 +++----- .../unsupported/UnsupportedNodeComponent.js | 28 +++++++------------ .../unsupported/UnsupportedNodePackage.js | 20 ++++++------- 6 files changed, 38 insertions(+), 63 deletions(-) diff --git a/packages/unsupported/UnsupportedInlineNode.js b/packages/unsupported/UnsupportedInlineNode.js index 7fd382233..db0cfc608 100644 --- a/packages/unsupported/UnsupportedInlineNode.js +++ b/packages/unsupported/UnsupportedInlineNode.js @@ -1,17 +1,13 @@ import { InlineNode } from 'substance' -function UnsupportedInlineNode() { - UnsupportedInlineNode.super.apply(this, arguments); -} +class UnsupportedInlineNode extends InlineNode {} -InlineNode.extend(UnsupportedInlineNode); - -UnsupportedInlineNode.type = 'unsupported-inline'; +UnsupportedInlineNode.type = 'unsupported-inline' UnsupportedInlineNode.define({ attributes: { type: 'object', default: {} }, xmlContent: {type: 'string', default: ''}, tagName: 'string' -}); +}) -export default UnsupportedInlineNode; +export default UnsupportedInlineNode diff --git a/packages/unsupported/UnsupportedInlineNodeComponent.js b/packages/unsupported/UnsupportedInlineNodeComponent.js index 078ee376b..2671e3310 100644 --- a/packages/unsupported/UnsupportedInlineNodeComponent.js +++ b/packages/unsupported/UnsupportedInlineNodeComponent.js @@ -1,23 +1,17 @@ import { Component } from 'substance' -function UnsupportedInlineNodeComponent() { - Component.apply(this, arguments); -} - -UnsupportedInlineNodeComponent.Prototype = function() { +class UnsupportedInlineNodeComponent extends Component { - this.render = function($$) { - var el = $$('span') + render($$) { + let el = $$('span') .addClass('sc-unsupported-inline-node') .attr('data-id', this.props.node.id) .attr('contenteditable', false) .append( '<'+this.props.node.tagName+'>' - ); - return el; - }; -}; - -Component.extend(UnsupportedInlineNodeComponent); + ) + return el + } +} -export default UnsupportedInlineNodeComponent; \ No newline at end of file +export default UnsupportedInlineNodeComponent diff --git a/packages/unsupported/UnsupportedInlineNodeTool.js b/packages/unsupported/UnsupportedInlineNodeTool.js index e31efd0e4..bd7590e68 100644 --- a/packages/unsupported/UnsupportedInlineNodeTool.js +++ b/packages/unsupported/UnsupportedInlineNodeTool.js @@ -64,12 +64,11 @@ class UnsupportedInlineNodeTool extends Tool { node: node }) ) - ); + ) } - return el; + return el } } - -export default UnsupportedInlineNodeTool; +export default UnsupportedInlineNodeTool diff --git a/packages/unsupported/UnsupportedNode.js b/packages/unsupported/UnsupportedNode.js index 203e28e31..0cbc1c3d3 100644 --- a/packages/unsupported/UnsupportedNode.js +++ b/packages/unsupported/UnsupportedNode.js @@ -1,17 +1,13 @@ import { BlockNode } from 'substance' -function UnsupportedNode() { - UnsupportedNode.super.apply(this, arguments); -} +class UnsupportedNode extends BlockNode {} -BlockNode.extend(UnsupportedNode); - -UnsupportedNode.type = 'unsupported'; +UnsupportedNode.type = 'unsupported' UnsupportedNode.define({ attributes: { type: 'object', default: {} }, xmlContent: {type: 'string', default: ''}, tagName: 'string' -}); +}) -export default UnsupportedNode; +export default UnsupportedNode diff --git a/packages/unsupported/UnsupportedNodeComponent.js b/packages/unsupported/UnsupportedNodeComponent.js index bdce4612c..99e336188 100644 --- a/packages/unsupported/UnsupportedNodeComponent.js +++ b/packages/unsupported/UnsupportedNodeComponent.js @@ -1,15 +1,9 @@ -'use strict'; - import { Component } from 'substance' -function UnsupportedNodeComponent() { - Component.apply(this, arguments); -} - -UnsupportedNodeComponent.Prototype = function() { +class UnsupportedNodeComponent extends Component { - this.render = function($$) { - var el = $$('span') + render($$) { + let el = $$('span') .addClass('sc-unsupported-inline-node') .attr('data-id', this.props.node.id) .attr('contenteditable', false) @@ -21,14 +15,12 @@ UnsupportedNodeComponent.Prototype = function() { ) ) ) - ); - return el; - }; -}; - -Component.extend(UnsupportedNodeComponent); + ) + return el + } +} -UnsupportedNodeComponent.fullWidth = true; -UnsupportedNodeComponent.noStyle = true; +UnsupportedNodeComponent.fullWidth = true +UnsupportedNodeComponent.noStyle = true -export default UnsupportedNodeComponent; \ No newline at end of file +export default UnsupportedNodeComponent diff --git a/packages/unsupported/UnsupportedNodePackage.js b/packages/unsupported/UnsupportedNodePackage.js index 1d15701cb..9d23a7dc5 100644 --- a/packages/unsupported/UnsupportedNodePackage.js +++ b/packages/unsupported/UnsupportedNodePackage.js @@ -1,5 +1,3 @@ -'use strict'; - import UnsupportedNode from './UnsupportedNode' import UnsupportedInlineNode from './UnsupportedInlineNode' import UnsupportedNodeComponent from './UnsupportedNodeComponent' @@ -12,13 +10,13 @@ import UnsupportedInlineNodeTool from './UnsupportedInlineNodeTool' export default { name: 'unsupported', configure: function(config) { - config.addNode(UnsupportedNode); - config.addNode(UnsupportedInlineNode); - config.addComponent(UnsupportedNode.type, UnsupportedNodeComponent); - config.addComponent(UnsupportedInlineNode.type, UnsupportedInlineNodeComponent); - config.addCommand(UnsupportedInlineNode.type, UnsupportedInlineNodeCommand, {nodeType: UnsupportedInlineNode.type}); - config.addTool(UnsupportedInlineNode.type, UnsupportedInlineNodeTool, { overlay: true }); - config.addConverter('jats', UnsupportedNodeJATSConverter); - config.addConverter('jats', UnsupportedInlineNodeJATSConverter); + config.addNode(UnsupportedNode) + config.addNode(UnsupportedInlineNode) + config.addComponent(UnsupportedNode.type, UnsupportedNodeComponent) + config.addComponent(UnsupportedInlineNode.type, UnsupportedInlineNodeComponent) + config.addCommand(UnsupportedInlineNode.type, UnsupportedInlineNodeCommand, {nodeType: UnsupportedInlineNode.type}) + config.addTool(UnsupportedInlineNode.type, UnsupportedInlineNodeTool, { overlay: true }) + config.addConverter('jats', UnsupportedNodeJATSConverter) + config.addConverter('jats', UnsupportedInlineNodeJATSConverter) } -}; +} From 402cc3e811c3aff80e8f5b2d64cf305bc421bd23 Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 21:50:13 +0300 Subject: [PATCH 155/167] ES6 utils. --- util/XMLIterator.js | 40 ++++++++++++++++++------------------- util/getFullName.js | 12 +++++------ util/renderNodeComponent.js | 16 +++++++-------- util/toDOM.js | 10 +++++----- 4 files changed, 38 insertions(+), 40 deletions(-) diff --git a/util/XMLIterator.js b/util/XMLIterator.js index 3b18f0f8d..8e5ba9773 100644 --- a/util/XMLIterator.js +++ b/util/XMLIterator.js @@ -3,60 +3,60 @@ import { ArrayIterator, makeMap } from 'substance' export default class XMLIterator { constructor(elements) { - this.it = new ArrayIterator(elements); + this.it = new ArrayIterator(elements) } optional(tagName, cb) { - this._one(tagName, true, cb); + this._one(tagName, true, cb) } required(tagName, cb) { - this._one(tagName, false, cb); + this._one(tagName, false, cb) } _one(tagName, optional, cb) { if (this.it.hasNext()) { - var el = this.it.next(); + let el = this.it.next() if (el.tagName === tagName) { - return cb(el); + return cb(el) } else { - this.it.back(); + this.it.back() } } - if (!optional) throw new Error("Expecting element '"+ tagName +"'."); + if (!optional) throw new Error("Expecting element '"+ tagName +"'.") } _manyOf(tagNames, cb) { - if (isString(tagNames)) tagNames = [tagNames]; - var count = 0; - tagNames = makeMap(tagNames); + if (isString(tagNames)) tagNames = [tagNames] + let count = 0 + tagNames = makeMap(tagNames) while(this.it.hasNext()) { - var el = this.it.next(); + let el = this.it.next() if (tagNames[el.tagName]) { - count++; - cb(el); + count++ + cb(el) } else { - this.it.back(); - break; + this.it.back() + break } } - return count; + return count } manyOf(tagNames, cb) { - return this._manyOf(tagNames, cb); + return this._manyOf(tagNames, cb) } oneOrMoreOf(tagNames, cb) { - var count = this._manyOf(tagNames, cb); + let count = this._manyOf(tagNames, cb) if (count === 0) { throw new Error('Expecting at least one element of ' + String(tagNames)); } - return count; + return count } hasNext() { - return this.it.hasNext(); + return this.it.hasNext() } } diff --git a/util/getFullName.js b/util/getFullName.js index 41e296102..ac5fd8b75 100644 --- a/util/getFullName.js +++ b/util/getFullName.js @@ -1,17 +1,17 @@ -import toDOM from './toDOM' +import toDOM from './toDOM' /* Extract name from elements that contain name or string-name nodes (e.g. contrib, mixed-citation, element-citation) */ function getFullName(node) { - var el = toDOM(node) - var name = el.find('name') - var stringName = el.find('string-name') + let el = toDOM(node) + let name = el.find('name') + let stringName = el.find('string-name') if (name) { - var surname = name.find('surname').text() - var givenNames = name.find('given-names').text() + let surname = name.find('surname').text() + let givenNames = name.find('given-names').text() return [givenNames, surname].join(' ') } else if (stringName) { return stringName.text() diff --git a/util/renderNodeComponent.js b/util/renderNodeComponent.js index 1e2338716..04360f626 100644 --- a/util/renderNodeComponent.js +++ b/util/renderNodeComponent.js @@ -1,16 +1,14 @@ -'use strict'; - import extend from 'lodash/extend' export default function renderNodeComponent(self, $$, node, props) { - props = props || {}; - var componentRegistry = self.props.componentRegistry || self.context.componentRegistry; - var ComponentClass = componentRegistry.get(node.type); + props = props || {} + let componentRegistry = self.props.componentRegistry || self.context.componentRegistry + let ComponentClass = componentRegistry.get(node.type) if (!ComponentClass) { - console.error('Could not resolve a component for node type ' + node.type); - ComponentClass = componentRegistry.get('unsupported'); + console.error('Could not resolve a component for node type ' + node.type) + ComponentClass = componentRegistry.get('unsupported') } return $$(ComponentClass, extend({ node: node - }, props)); -}; + }, props)) +} diff --git a/util/toDOM.js b/util/toDOM.js index 8a02132bf..0a3a36865 100644 --- a/util/toDOM.js +++ b/util/toDOM.js @@ -6,8 +6,8 @@ import { DefaultDOMElement as DOMElement } from 'substance' @return {substance/ui/DOMElement} A wrapped DOM element */ export default function toDOM(node) { - var tagName = node.constructor.tagName || node.constructor.type; - var el = DOMElement.parseXML('<'+tagName+'>'+node.xmlContent+''); - el.attr(node.attributes); - return el; -}; \ No newline at end of file + var tagName = node.constructor.tagName || node.constructor.type + var el = DOMElement.parseXML('<'+tagName+'>'+node.xmlContent+'') + el.attr(node.attributes) + return el +} From 80283585647537c5dd0088273981c543959779cb Mon Sep 17 00:00:00 2001 From: Daniel Beilinson Date: Thu, 29 Sep 2016 21:51:22 +0300 Subject: [PATCH 156/167] ES6 examples. --- examples/ExampleXMLStore.js | 12 ++++++------ examples/author/app.js | 2 +- examples/tagging/app.js | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/ExampleXMLStore.js b/examples/ExampleXMLStore.js index 3947ef5bf..25f03d700 100644 --- a/examples/ExampleXMLStore.js +++ b/examples/ExampleXMLStore.js @@ -3,19 +3,19 @@ import { request } from 'substance' class ExampleXMLStore { readXML(documentId, cb) { - var cached = localStorage.getItem(documentId); + let cached = localStorage.getItem(documentId) if (cached) { - return cb(null, cached); + return cb(null, cached) } - request('GET', '../data/'+documentId+'.xml', null, cb); + request('GET', '../data/'+documentId+'.xml', null, cb) } // TODO make functional writeXML(documentId, xml, cb) { - localStorage.setItem(documentId, xml); - cb(null); + localStorage.setItem(documentId, xml) + cb(null) } } -export default ExampleXMLStore; +export default ExampleXMLStore diff --git a/examples/author/app.js b/examples/author/app.js index c404b1fab..3398e849f 100644 --- a/examples/author/app.js +++ b/examples/author/app.js @@ -13,7 +13,7 @@ let configurator = new TextureConfigurator() if (typeof window !== 'undefined') { window.onload = function() { - var app = Texture.mount({ + let app = Texture.mount({ configurator: configurator, documentId: 'elife-15278' }, document.body) diff --git a/examples/tagging/app.js b/examples/tagging/app.js index 70953a3ab..2040f3744 100644 --- a/examples/tagging/app.js +++ b/examples/tagging/app.js @@ -16,7 +16,7 @@ let configurator = new TextureConfigurator() if (typeof window !== 'undefined') { window.onload = function() { - var app = Texture.mount({ + let app = Texture.mount({ configurator: configurator, documentId: 'elife-15278' }, document.body) From 9a928152d1a4224a5cdb454334a18d87fb9a44b7 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Thu, 29 Sep 2016 22:29:52 +0200 Subject: [PATCH 157/167] We don't need eslint dependency. --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 4f1c10a5d..3ba6f8ce6 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,6 @@ "substance": "substance/substance#develop" }, "devDependencies": { - "eslint": "^3.2.2", "font-awesome": "4.5.0", "substance-bundler": "^0.4.20", "substance-test": "^0.2.2" From 4678cd6c050e47ff65e5ab108bda8f7f1c13c14e Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 4 Oct 2016 12:18:50 +0200 Subject: [PATCH 158/167] Get rid of some unneeded commands. --- packages/jats/ext-link/EditExtLinkCommand.js | 5 ----- packages/jats/ext-link/ExtLink.js | 6 ++++-- packages/jats/ext-link/ExtLinkCommand.js | 14 -------------- packages/jats/ext-link/package.js | 9 +++++---- 4 files changed, 9 insertions(+), 25 deletions(-) delete mode 100644 packages/jats/ext-link/EditExtLinkCommand.js delete mode 100644 packages/jats/ext-link/ExtLinkCommand.js diff --git a/packages/jats/ext-link/EditExtLinkCommand.js b/packages/jats/ext-link/EditExtLinkCommand.js deleted file mode 100644 index 9ac2b9be4..000000000 --- a/packages/jats/ext-link/EditExtLinkCommand.js +++ /dev/null @@ -1,5 +0,0 @@ -import { EditLinkCommand } from 'substance' - -class EditExtLinkCommand extends EditLinkCommand {} - -export default EditExtLinkCommand diff --git a/packages/jats/ext-link/ExtLink.js b/packages/jats/ext-link/ExtLink.js index 2e82a6560..2a49bf9d6 100644 --- a/packages/jats/ext-link/ExtLink.js +++ b/packages/jats/ext-link/ExtLink.js @@ -2,10 +2,12 @@ import { Annotation, Fragmenter } from 'substance' class ExtLink extends Annotation {} -ExtLink.type = "ext-link" +ExtLink.type = 'ext-link' ExtLink.define({ - attributes: { type: 'object', default: {} } + attributes: { + type: 'object', default: {'xlink:href': ''} + } }) // in presence of overlapping annotations will try to render this as one element diff --git a/packages/jats/ext-link/ExtLinkCommand.js b/packages/jats/ext-link/ExtLinkCommand.js deleted file mode 100644 index dbc54ae58..000000000 --- a/packages/jats/ext-link/ExtLinkCommand.js +++ /dev/null @@ -1,14 +0,0 @@ -import { LinkCommand } from 'substance' - -class ExtLinkCommand extends LinkCommand { - - getAnnotationData() { - return { - attributes: { - 'xlink:href': '' - } - } - } -} - -export default ExtLinkCommand diff --git a/packages/jats/ext-link/package.js b/packages/jats/ext-link/package.js index 6e729931a..06b84ecd0 100644 --- a/packages/jats/ext-link/package.js +++ b/packages/jats/ext-link/package.js @@ -1,9 +1,10 @@ +import { LinkCommand, EditAnnotationCommand } from 'substance' import ExtLink from './ExtLink' import ExtLinkConverter from './ExtLinkConverter' import ExtLinkComponent from './ExtLinkComponent' import ExtLinkTool from './ExtLinkTool' -import ExtLinkCommand from './ExtLinkCommand' -import EditExtLinkCommand from './EditExtLinkCommand' + +// import EditExtLinkCommand from './EditExtLinkCommand' import EditExtLinkTool from './EditExtLinkTool' export default { @@ -13,8 +14,8 @@ export default { config.addConverter('jats', ExtLinkConverter) config.addComponent(ExtLink.type, ExtLinkComponent) - config.addCommand(ExtLink.type, ExtLinkCommand, {nodeType: ExtLink.type}) - config.addCommand('edit-ext-link', EditExtLinkCommand, {nodeType: ExtLink.type}) + config.addCommand(ExtLink.type, LinkCommand, {nodeType: ExtLink.type}) + config.addCommand('edit-ext-link', EditAnnotationCommand, {nodeType: ExtLink.type}) config.addTool(ExtLink.type, ExtLinkTool, {target: 'annotations'}) config.addTool('edit-ext-link', EditExtLinkTool, { target: 'overlay' }) config.addIcon(ExtLink.type, { 'fontawesome': 'fa-link'}) From 7ad181142d8e9ad932fcf2a86424a264e824d9de Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 4 Oct 2016 15:53:46 +0300 Subject: [PATCH 159/167] Fix make configuration. --- .gitignore | 1 + make.js | 16 +++++++++------- package.json | 4 ++-- test.js | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 2dbfcc9e4..30c02690e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ logs dist node_modules .lock-wscript +.test diff --git a/make.js b/make.js index e7b95f2e4..6daf801e3 100644 --- a/make.js +++ b/make.js @@ -47,13 +47,16 @@ b.task('examples', ['author', 'publisher', 'tagging']) // build all b.task('default', ['examples']) +var TEST ='.test/' b.task('test:clean', function() { - b.rm('dist/test') + b.rm(TEST) }) b.task('test:assets', function() { - b.copy('./node_modules/substance-test/dist/*', './dist/test', { root: './node_modules/substance-test/dist' }) + // TODO: it would be nice to treat such glob patterns + // differently, so that we do not need to specify glob root + b.copy('./node_modules/substance-test/dist/*', TEST, { root: './node_modules/substance-test/dist' }) }) b.task('test:browser', function() { @@ -64,7 +67,7 @@ b.task('test:browser', function() { external: ['substance-test', 'substance'], commonjs: { include: ['node_modules/lodash/**'] }, targets: [ - { dest: './dist/test/tests.js', format: 'umd', moduleName: 'tests' } + { dest: TEST+'tests.js', format: 'umd', moduleName: 'tests' } ] }); }) @@ -76,19 +79,18 @@ b.task('test:server', function() { external: ['substance-test', 'substance'], commonjs: { include: [ - 'node_modules/lodash/**', - 'node_modules/substance-cheerio/**' + '/**/lodash/**', + '/**/substance-cheerio/**' ] }, targets: [ - { dest: './dist/test/run-tests.js', format: 'cjs' }, + { dest: TEST+'tests.cjs.js', format: 'cjs' }, ] }); }) b.task('test', ['substance:all', 'test:clean', 'test:assets', 'test:browser', 'test:server']) - // starts a server when CLI argument '-s' is set b.setServerPort(5555) b.serve({ diff --git a/package.json b/package.json index 3ba6f8ce6..677d5fc5a 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ }, "devDependencies": { "font-awesome": "4.5.0", - "substance-bundler": "^0.4.20", - "substance-test": "^0.2.2" + "substance-bundler": "0.4.24", + "substance-test": "0.2.3" }, "scripts": { "bundle": "node make", diff --git a/test.js b/test.js index 1a15572b4..f8e09602c 100644 --- a/test.js +++ b/test.js @@ -12,7 +12,7 @@ b.task('server', function() { b.custom('Running nodejs tests...', { execute: function() { return new Promise(function(resolve, reject) { - const child = cp.fork(path.join(__dirname, 'dist/test/run-tests.js')) + const child = cp.fork(path.join(__dirname, '.test/run-tests.js')) child.on('message', function(msg) { if (msg === 'done') { resolve() } }) From f1f6a0b0e9c3d74e251e60cabb9c5d388c340f43 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 4 Oct 2016 17:25:08 +0300 Subject: [PATCH 160/167] Updated substance-test. Trying to fix issues unde node 6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 677d5fc5a..cb44a6e60 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "devDependencies": { "font-awesome": "4.5.0", "substance-bundler": "0.4.24", - "substance-test": "0.2.3" + "substance-test": "0.2.5" }, "scripts": { "bundle": "node make", From 14947a67971511ba2df10dce9669e5424fdce740 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 4 Oct 2016 18:21:24 +0200 Subject: [PATCH 161/167] Bump Substance. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cb44a6e60..7917a7c54 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "A scientific editor and reader for JATS files.", "dependencies": { "lodash": "^4.14.1", - "substance": "substance/substance#develop" + "substance": "substance/substance#ede6e10ecf1bd94c80504d85b23d5ee5bf4ada91" }, "devDependencies": { "font-awesome": "4.5.0", From 56e985a316b7c0eeaabdce32f6684e8c2c4ad182 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Tue, 4 Oct 2016 18:35:37 +0200 Subject: [PATCH 162/167] Old habits. --- make.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/make.js b/make.js index 6daf801e3..8f37b64e6 100644 --- a/make.js +++ b/make.js @@ -1,4 +1,4 @@ -var b = require('substance-bundler'); +var b = require('substance-bundler') b.task('clean', function() { b.rm('./dist') @@ -44,7 +44,7 @@ b.task('publisher', ['clean', 'substance', 'assets'], buildExample('publisher')) b.task('tagging', ['author'], buildExample('tagging')) b.task('examples', ['author', 'publisher', 'tagging']) -// build all +// build all examples b.task('default', ['examples']) var TEST ='.test/' @@ -69,7 +69,7 @@ b.task('test:browser', function() { targets: [ { dest: TEST+'tests.js', format: 'umd', moduleName: 'tests' } ] - }); + }) }) b.task('test:server', function() { @@ -86,11 +86,13 @@ b.task('test:server', function() { targets: [ { dest: TEST+'tests.cjs.js', format: 'cjs' }, ] - }); + }) }) b.task('test', ['substance:all', 'test:clean', 'test:assets', 'test:browser', 'test:server']) + + // starts a server when CLI argument '-s' is set b.setServerPort(5555) b.serve({ From 3514266d95fb902e730768787d4e990cf006acd6 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 7 Oct 2016 00:56:29 +0200 Subject: [PATCH 163/167] Bump versions. --- make.js | 11 ++++++----- package.json | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/make.js b/make.js index 8f37b64e6..e8bed56c4 100644 --- a/make.js +++ b/make.js @@ -29,12 +29,14 @@ function buildExample(example) { b.copy('examples/'+example+'/*.css', './dist/'+example+'/', { root: 'examples/'+example }) b.js('examples/'+example+'/app.js', { // need buble if we want to minify later - // buble: true, + buble: false, external: ['substance'], commonjs: { include: ['node_modules/lodash/**'] }, - dest: './dist/'+example+'/app.js', - format: 'umd', - moduleName: example + targets: [{ + // useStrict: false, // need for Safari 9 to work + dest: './dist/'+example+'/app.js', + format: 'umd', moduleName: example, + }] }) } } @@ -92,7 +94,6 @@ b.task('test:server', function() { b.task('test', ['substance:all', 'test:clean', 'test:assets', 'test:browser', 'test:server']) - // starts a server when CLI argument '-s' is set b.setServerPort(5555) b.serve({ diff --git a/package.json b/package.json index 7917a7c54..a20282419 100644 --- a/package.json +++ b/package.json @@ -3,11 +3,11 @@ "description": "A scientific editor and reader for JATS files.", "dependencies": { "lodash": "^4.14.1", - "substance": "substance/substance#ede6e10ecf1bd94c80504d85b23d5ee5bf4ada91" + "substance": "substance/substance#15a707669810e67f7bcaf17709fa1b79c5acee7c" }, "devDependencies": { "font-awesome": "4.5.0", - "substance-bundler": "0.4.24", + "substance-bundler": "0.4.26", "substance-test": "0.2.5" }, "scripts": { From f98bd116fda5bca7288b4265e7fbfab525023915 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 7 Oct 2016 00:59:13 +0200 Subject: [PATCH 164/167] No ES5 transpile for substance bundle. --- make.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make.js b/make.js index e8bed56c4..0fa02733d 100644 --- a/make.js +++ b/make.js @@ -15,7 +15,7 @@ b.task('assets', function() { // this optional task makes it easier to work on Substance core b.task('substance', function() { - b.make('substance', 'clean', 'css', 'browser') + b.make('substance', 'clean', 'css', 'browser:pure') b.copy('node_modules/substance/dist', './dist/substance') }) From 4b3cc230d4f90ed22abb1aadb6cefa6496d7cf5d Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 7 Oct 2016 04:21:24 +0200 Subject: [PATCH 165/167] Bump to Substance Beta 5. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a20282419..7853adc8b 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "A scientific editor and reader for JATS files.", "dependencies": { "lodash": "^4.14.1", - "substance": "substance/substance#15a707669810e67f7bcaf17709fa1b79c5acee7c" + "substance": "1.0.0-beta.5.4" }, "devDependencies": { "font-awesome": "4.5.0", From 904eb88ab666c84e7d36f13bd9e38e264713f86e Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 7 Oct 2016 17:40:12 +0200 Subject: [PATCH 166/167] Bundling for NPM. Much improved build process. Better file structure. --- {examples/data => data}/elife-15278.xml | 0 {examples/data => data}/example.xml | 0 .../data => data}/kitchen-sink-author.xml | 0 {examples/data => data}/vanilla.xml | 0 {examples/data => data}/with-xref.xml | 0 examples/author.html | 45 +++++ examples/author/app.css | 11 -- examples/author/index.html | 11 -- examples/config.js | 6 - examples/index.html | 7 - examples/publisher.html | 45 +++++ examples/publisher/app.css | 11 -- examples/publisher/app.js | 23 --- examples/publisher/index.html | 12 -- examples/tagging.html | 47 +++++ examples/tagging/app.css | 11 -- examples/tagging/app.js | 25 --- examples/tagging/index.html | 11 -- index.es.js | 16 ++ index.html | 7 + {packages => lib}/_index.css | 0 {packages => lib}/author/Author.js | 0 {packages => lib}/author/AuthorExporter.js | 0 {packages => lib}/author/AuthorImporter.js | 0 {packages => lib}/author/AuthorPackage.js | 0 {packages => lib}/author/AuthorTOCProvider.js | 0 {packages => lib}/author/JATSTransformer.js | 0 {packages => lib}/author/_index.css | 0 {examples => lib}/author/app.js | 6 +- {packages => lib}/author/heading/Heading.js | 0 .../author/heading/HeadingComponent.js | 0 {packages => lib}/author/heading/package.js | 0 {packages => lib}/common/AbstractWriter.js | 0 {packages => lib}/common/EditXML.js | 0 {packages => lib}/common/SaveHandler.js | 0 .../common/XMLAttributeEditor.js | 0 {packages => lib}/common/XMLEditor.js | 0 {packages => lib}/common/_edit-xml.css | 0 {packages => lib}/common/_index.css | 0 {packages => lib}/common/_isolated-node.css | 0 {packages => lib}/common/_toolbar.css | 0 {packages => lib}/common/package.js | 0 .../InlineWrapperJATSConverter.js | 0 .../inline-wrapper/InlineWrapperPackage.js | 0 {packages => lib}/jats/JATS.js | 0 {packages => lib}/jats/JATSExporter.js | 0 {packages => lib}/jats/JATSImporter.js | 0 {packages => lib}/jats/TextNodeConverter.js | 0 {packages => lib}/jats/_index.css | 0 {packages => lib}/jats/aff/Aff.js | 0 {packages => lib}/jats/aff/AffComponent.js | 0 {packages => lib}/jats/aff/AffConverter.js | 0 {packages => lib}/jats/aff/_aff.css | 0 {packages => lib}/jats/aff/_index.css | 0 {packages => lib}/jats/aff/affUtils.js | 2 +- {packages => lib}/jats/aff/package.js | 0 .../jats/article-meta/ArticleMeta.js | 0 .../jats/article-meta/ArticleMetaComponent.js | 2 +- .../jats/article-meta/ArticleMetaConverter.js | 2 +- .../jats/article-meta/package.js | 0 .../jats/article-title/ArticleTitle.js | 0 .../article-title/ArticleTitleComponent.js | 0 .../article-title/ArticleTitleConverter.js | 0 .../jats/article-title/_index.css | 0 .../jats/article-title/package.js | 0 .../jats/article/ArticleComponent.js | 2 +- .../jats/article/ArticleConverter.js | 2 +- {packages => lib}/jats/article/ArticleNode.js | 0 .../jats/article/TextureArticle.js | 0 {packages => lib}/jats/article/_index.css | 0 {packages => lib}/jats/article/package.js | 0 {packages => lib}/jats/back/Back.js | 0 {packages => lib}/jats/back/BackComponent.js | 2 +- {packages => lib}/jats/back/BackConverter.js | 2 +- {packages => lib}/jats/back/_index.css | 0 {packages => lib}/jats/back/package.js | 0 {packages => lib}/jats/body/Body.js | 0 {packages => lib}/jats/body/BodyComponent.js | 0 {packages => lib}/jats/body/BodyConverter.js | 2 +- {packages => lib}/jats/body/package.js | 0 {packages => lib}/jats/bold/Bold.js | 0 {packages => lib}/jats/bold/BoldCommand.js | 0 {packages => lib}/jats/bold/BoldConverter.js | 0 {packages => lib}/jats/bold/BoldTool.js | 0 {packages => lib}/jats/bold/_index.css | 0 {packages => lib}/jats/bold/package.js | 0 {packages => lib}/jats/caption/Caption.js | 0 .../jats/caption/CaptionComponent.js | 0 .../jats/caption/CaptionConverter.js | 2 +- {packages => lib}/jats/caption/package.js | 0 .../jats/contrib-group/ContribGroup.js | 0 .../contrib-group/ContribGroupComponent.js | 2 +- .../contrib-group/ContribGroupConverter.js | 2 +- .../jats/contrib-group/_index.css | 0 .../jats/contrib-group/package.js | 0 {packages => lib}/jats/contrib/Contrib.js | 0 .../jats/contrib/ContribComponent.js | 0 .../jats/contrib/ContribConverter.js | 0 {packages => lib}/jats/contrib/EditContrib.js | 0 {packages => lib}/jats/contrib/_contrib.css | 0 .../jats/contrib/_edit-contrib.css | 0 {packages => lib}/jats/contrib/_index.css | 0 .../jats/contrib/contribUtils.js | 4 +- {packages => lib}/jats/contrib/package.js | 0 .../jats/ext-link/EditExtLinkTool.js | 0 {packages => lib}/jats/ext-link/ExtLink.js | 0 .../jats/ext-link/ExtLinkComponent.js | 0 .../jats/ext-link/ExtLinkConverter.js | 0 .../jats/ext-link/ExtLinkTool.js | 0 {packages => lib}/jats/ext-link/_index.css | 0 {packages => lib}/jats/ext-link/package.js | 0 {packages => lib}/jats/figure/Figure.js | 0 .../jats/figure/FigureComponent.js | 2 +- .../jats/figure/FigureConverter.js | 2 +- {packages => lib}/jats/figure/FigureTarget.js | 2 +- .../jats/figure/_figure-target.css | 0 {packages => lib}/jats/figure/_index.css | 0 {packages => lib}/jats/figure/package.js | 0 {packages => lib}/jats/footnote/Footnote.js | 0 .../jats/footnote/FootnoteComponent.js | 2 +- .../jats/footnote/FootnoteConverter.js | 2 +- {packages => lib}/jats/footnote/_index.css | 0 {packages => lib}/jats/footnote/package.js | 0 {packages => lib}/jats/front/Front.js | 0 .../jats/front/FrontComponent.js | 2 +- .../jats/front/FrontConverter.js | 2 +- {packages => lib}/jats/front/package.js | 0 {packages => lib}/jats/graphic/Graphic.js | 0 .../jats/graphic/GraphicComponent.js | 0 .../jats/graphic/GraphicConverter.js | 2 +- {packages => lib}/jats/graphic/_index.css | 0 {packages => lib}/jats/graphic/package.js | 0 {packages => lib}/jats/italic/Italic.js | 0 .../jats/italic/ItalicCommand.js | 0 .../jats/italic/ItalicConverter.js | 0 {packages => lib}/jats/italic/ItalicTool.js | 0 {packages => lib}/jats/italic/_index.css | 0 {packages => lib}/jats/italic/package.js | 0 {packages => lib}/jats/label/Label.js | 0 .../jats/label/LabelComponent.js | 0 .../jats/label/LabelConverter.js | 0 {packages => lib}/jats/label/package.js | 0 {packages => lib}/jats/monospace/Monospace.js | 0 .../jats/monospace/MonospaceConverter.js | 0 {packages => lib}/jats/monospace/_index.css | 0 {packages => lib}/jats/monospace/package.js | 0 {packages => lib}/jats/package.js | 0 {packages => lib}/jats/paragraph/Paragraph.js | 0 .../jats/paragraph/ParagraphComponent.js | 0 .../jats/paragraph/ParagraphConverter.js | 0 {packages => lib}/jats/paragraph/package.js | 0 {packages => lib}/jats/ref-list/RefList.js | 0 .../jats/ref-list/RefListComponent.js | 2 +- .../jats/ref-list/RefListConverter.js | 2 +- {packages => lib}/jats/ref-list/_index.css | 0 {packages => lib}/jats/ref-list/package.js | 0 {packages => lib}/jats/ref/Ref.js | 0 {packages => lib}/jats/ref/RefComponent.js | 0 {packages => lib}/jats/ref/RefConverter.js | 0 {packages => lib}/jats/ref/RefTarget.js | 0 {packages => lib}/jats/ref/_index.css | 0 {packages => lib}/jats/ref/package.js | 0 {packages => lib}/jats/ref/refToHTML.js | 0 {packages => lib}/jats/section/Section.js | 0 .../jats/section/SectionComponent.js | 0 .../jats/section/SectionConverter.js | 2 +- {packages => lib}/jats/section/_index.css | 0 {packages => lib}/jats/section/package.js | 0 {packages => lib}/jats/subscript/Subscript.js | 0 .../jats/subscript/SubscriptConverter.js | 0 {packages => lib}/jats/subscript/_index.css | 0 {packages => lib}/jats/subscript/package.js | 0 .../jats/superscript/Superscript.js | 0 .../jats/superscript/SuperscriptConverter.js | 0 {packages => lib}/jats/superscript/_index.css | 0 {packages => lib}/jats/superscript/package.js | 0 .../jats/table-wrap/TableWrap.js | 0 .../jats/table-wrap/TableWrapComponent.js | 0 .../jats/table-wrap/TableWrapConverter.js | 0 {packages => lib}/jats/table-wrap/package.js | 0 {packages => lib}/jats/table/Table.js | 0 .../jats/table/TableComponent.js | 0 .../jats/table/TableConverter.js | 0 {packages => lib}/jats/table/package.js | 0 .../jats/title-group/TitleGroup.js | 0 .../jats/title-group/TitleGroupComponent.js | 2 +- .../jats/title-group/TitleGroupConverter.js | 2 +- {packages => lib}/jats/title-group/package.js | 0 {packages => lib}/jats/title/Title.js | 0 .../jats/title/TitleComponent.js | 0 .../jats/title/TitleConverter.js | 0 {packages => lib}/jats/title/_index.css | 0 {packages => lib}/jats/title/package.js | 0 {packages => lib}/jats/xref/AddXRefCommand.js | 0 {packages => lib}/jats/xref/AddXRefTool.js | 0 .../jats/xref/EditXRefCommand.js | 0 {packages => lib}/jats/xref/EditXRefTool.js | 0 {packages => lib}/jats/xref/XRef.js | 0 {packages => lib}/jats/xref/XRefComponent.js | 0 {packages => lib}/jats/xref/XRefConverter.js | 0 {packages => lib}/jats/xref/XRefTargets.js | 0 .../jats/xref/_edit-xref-tool.css | 0 {packages => lib}/jats/xref/_index.css | 0 .../jats/xref/_scrollbar-highlights.css | 0 {packages => lib}/jats/xref/_xref-targets.css | 0 {packages => lib}/jats/xref/_xref.css | 0 {packages => lib}/jats/xref/getXRefTargets.js | 0 {packages => lib}/jats/xref/package.js | 0 {packages => lib}/publisher/Publisher.js | 0 .../publisher/PublisherPackage.js | 0 .../publisher/PublisherTOCProvider.js | 0 {packages => lib}/publisher/_index.css | 0 {examples => lib}/tagging/README.md | 0 {packages => lib}/tagging/TaggingPackage.js | 0 .../tagging/aff/TagAffCommand.js | 0 {packages => lib}/tagging/aff/TagAffTool.js | 0 .../tagging/contrib/TagContribCommand.js | 0 .../tagging/contrib/TagContribTool.js | 0 .../tagging/ref/TagRefCommand.js | 0 {packages => lib}/tagging/ref/TagRefTool.js | 0 {examples => lib/texture}/ExampleXMLStore.js | 8 +- {packages => lib}/texture/FileClientStub.js | 0 {packages => lib}/texture/SaveHandlerStub.js | 0 {packages => lib}/texture/Texture.js | 0 .../texture/TextureConfigurator.js | 14 +- {packages => lib}/texture/package.js | 0 .../unsupported/UnsupportedInlineNode.js | 0 .../UnsupportedInlineNodeCommand.js | 0 .../UnsupportedInlineNodeComponent.js | 0 .../UnsupportedInlineNodeJATSConverter.js | 0 .../unsupported/UnsupportedInlineNodeTool.js | 0 .../unsupported/UnsupportedNode.js | 0 .../unsupported/UnsupportedNodeComponent.js | 0 .../UnsupportedNodeJATSConverter.js | 0 .../unsupported/UnsupportedNodePackage.js | 0 {packages => lib}/unsupported/_index.css | 0 {util => lib/util}/XMLIterator.js | 0 {util => lib/util}/diff.html | 0 {util => lib/util}/getFullName.js | 0 {util => lib/util}/renderNodeComponent.js | 0 {util => lib/util}/toDOM.js | 0 make.js | 178 +++++++++++------- package.json | 4 +- packages/tagging/README.md | 7 - test/jats/createJATSConfigurator.js | 6 +- test/jats/test.js | 2 +- texture.css | 2 +- 247 files changed, 321 insertions(+), 246 deletions(-) rename {examples/data => data}/elife-15278.xml (100%) rename {examples/data => data}/example.xml (100%) rename {examples/data => data}/kitchen-sink-author.xml (100%) rename {examples/data => data}/vanilla.xml (100%) rename {examples/data => data}/with-xref.xml (100%) create mode 100644 examples/author.html delete mode 100644 examples/author/app.css delete mode 100644 examples/author/index.html delete mode 100644 examples/config.js delete mode 100644 examples/index.html create mode 100644 examples/publisher.html delete mode 100644 examples/publisher/app.css delete mode 100644 examples/publisher/app.js delete mode 100644 examples/publisher/index.html create mode 100644 examples/tagging.html delete mode 100644 examples/tagging/app.css delete mode 100644 examples/tagging/app.js delete mode 100644 examples/tagging/index.html create mode 100644 index.es.js create mode 100644 index.html rename {packages => lib}/_index.css (100%) rename {packages => lib}/author/Author.js (100%) rename {packages => lib}/author/AuthorExporter.js (100%) rename {packages => lib}/author/AuthorImporter.js (100%) rename {packages => lib}/author/AuthorPackage.js (100%) rename {packages => lib}/author/AuthorTOCProvider.js (100%) rename {packages => lib}/author/JATSTransformer.js (100%) rename {packages => lib}/author/_index.css (100%) rename {examples => lib}/author/app.js (71%) rename {packages => lib}/author/heading/Heading.js (100%) rename {packages => lib}/author/heading/HeadingComponent.js (100%) rename {packages => lib}/author/heading/package.js (100%) rename {packages => lib}/common/AbstractWriter.js (100%) rename {packages => lib}/common/EditXML.js (100%) rename {packages => lib}/common/SaveHandler.js (100%) rename {packages => lib}/common/XMLAttributeEditor.js (100%) rename {packages => lib}/common/XMLEditor.js (100%) rename {packages => lib}/common/_edit-xml.css (100%) rename {packages => lib}/common/_index.css (100%) rename {packages => lib}/common/_isolated-node.css (100%) rename {packages => lib}/common/_toolbar.css (100%) rename {packages => lib}/common/package.js (100%) rename {packages => lib}/inline-wrapper/InlineWrapperJATSConverter.js (100%) rename {packages => lib}/inline-wrapper/InlineWrapperPackage.js (100%) rename {packages => lib}/jats/JATS.js (100%) rename {packages => lib}/jats/JATSExporter.js (100%) rename {packages => lib}/jats/JATSImporter.js (100%) rename {packages => lib}/jats/TextNodeConverter.js (100%) rename {packages => lib}/jats/_index.css (100%) rename {packages => lib}/jats/aff/Aff.js (100%) rename {packages => lib}/jats/aff/AffComponent.js (100%) rename {packages => lib}/jats/aff/AffConverter.js (100%) rename {packages => lib}/jats/aff/_aff.css (100%) rename {packages => lib}/jats/aff/_index.css (100%) rename {packages => lib}/jats/aff/affUtils.js (92%) rename {packages => lib}/jats/aff/package.js (100%) rename {packages => lib}/jats/article-meta/ArticleMeta.js (100%) rename {packages => lib}/jats/article-meta/ArticleMetaComponent.js (90%) rename {packages => lib}/jats/article-meta/ArticleMetaConverter.js (98%) rename {packages => lib}/jats/article-meta/package.js (100%) rename {packages => lib}/jats/article-title/ArticleTitle.js (100%) rename {packages => lib}/jats/article-title/ArticleTitleComponent.js (100%) rename {packages => lib}/jats/article-title/ArticleTitleConverter.js (100%) rename {packages => lib}/jats/article-title/_index.css (100%) rename {packages => lib}/jats/article-title/package.js (100%) rename {packages => lib}/jats/article/ArticleComponent.js (94%) rename {packages => lib}/jats/article/ArticleConverter.js (97%) rename {packages => lib}/jats/article/ArticleNode.js (100%) rename {packages => lib}/jats/article/TextureArticle.js (100%) rename {packages => lib}/jats/article/_index.css (100%) rename {packages => lib}/jats/article/package.js (100%) rename {packages => lib}/jats/back/Back.js (100%) rename {packages => lib}/jats/back/BackComponent.js (91%) rename {packages => lib}/jats/back/BackConverter.js (95%) rename {packages => lib}/jats/back/_index.css (100%) rename {packages => lib}/jats/back/package.js (100%) rename {packages => lib}/jats/body/Body.js (100%) rename {packages => lib}/jats/body/BodyComponent.js (100%) rename {packages => lib}/jats/body/BodyConverter.js (95%) rename {packages => lib}/jats/body/package.js (100%) rename {packages => lib}/jats/bold/Bold.js (100%) rename {packages => lib}/jats/bold/BoldCommand.js (100%) rename {packages => lib}/jats/bold/BoldConverter.js (100%) rename {packages => lib}/jats/bold/BoldTool.js (100%) rename {packages => lib}/jats/bold/_index.css (100%) rename {packages => lib}/jats/bold/package.js (100%) rename {packages => lib}/jats/caption/Caption.js (100%) rename {packages => lib}/jats/caption/CaptionComponent.js (100%) rename {packages => lib}/jats/caption/CaptionConverter.js (95%) rename {packages => lib}/jats/caption/package.js (100%) rename {packages => lib}/jats/contrib-group/ContribGroup.js (100%) rename {packages => lib}/jats/contrib-group/ContribGroupComponent.js (93%) rename {packages => lib}/jats/contrib-group/ContribGroupConverter.js (94%) rename {packages => lib}/jats/contrib-group/_index.css (100%) rename {packages => lib}/jats/contrib-group/package.js (100%) rename {packages => lib}/jats/contrib/Contrib.js (100%) rename {packages => lib}/jats/contrib/ContribComponent.js (100%) rename {packages => lib}/jats/contrib/ContribConverter.js (100%) rename {packages => lib}/jats/contrib/EditContrib.js (100%) rename {packages => lib}/jats/contrib/_contrib.css (100%) rename {packages => lib}/jats/contrib/_edit-contrib.css (100%) rename {packages => lib}/jats/contrib/_index.css (100%) rename {packages => lib}/jats/contrib/contribUtils.js (93%) rename {packages => lib}/jats/contrib/package.js (100%) rename {packages => lib}/jats/ext-link/EditExtLinkTool.js (100%) rename {packages => lib}/jats/ext-link/ExtLink.js (100%) rename {packages => lib}/jats/ext-link/ExtLinkComponent.js (100%) rename {packages => lib}/jats/ext-link/ExtLinkConverter.js (100%) rename {packages => lib}/jats/ext-link/ExtLinkTool.js (100%) rename {packages => lib}/jats/ext-link/_index.css (100%) rename {packages => lib}/jats/ext-link/package.js (100%) rename {packages => lib}/jats/figure/Figure.js (100%) rename {packages => lib}/jats/figure/FigureComponent.js (94%) rename {packages => lib}/jats/figure/FigureConverter.js (98%) rename {packages => lib}/jats/figure/FigureTarget.js (95%) rename {packages => lib}/jats/figure/_figure-target.css (100%) rename {packages => lib}/jats/figure/_index.css (100%) rename {packages => lib}/jats/figure/package.js (100%) rename {packages => lib}/jats/footnote/Footnote.js (100%) rename {packages => lib}/jats/footnote/FootnoteComponent.js (91%) rename {packages => lib}/jats/footnote/FootnoteConverter.js (94%) rename {packages => lib}/jats/footnote/_index.css (100%) rename {packages => lib}/jats/footnote/package.js (100%) rename {packages => lib}/jats/front/Front.js (100%) rename {packages => lib}/jats/front/FrontComponent.js (88%) rename {packages => lib}/jats/front/FrontConverter.js (95%) rename {packages => lib}/jats/front/package.js (100%) rename {packages => lib}/jats/graphic/Graphic.js (100%) rename {packages => lib}/jats/graphic/GraphicComponent.js (100%) rename {packages => lib}/jats/graphic/GraphicConverter.js (96%) rename {packages => lib}/jats/graphic/_index.css (100%) rename {packages => lib}/jats/graphic/package.js (100%) rename {packages => lib}/jats/italic/Italic.js (100%) rename {packages => lib}/jats/italic/ItalicCommand.js (100%) rename {packages => lib}/jats/italic/ItalicConverter.js (100%) rename {packages => lib}/jats/italic/ItalicTool.js (100%) rename {packages => lib}/jats/italic/_index.css (100%) rename {packages => lib}/jats/italic/package.js (100%) rename {packages => lib}/jats/label/Label.js (100%) rename {packages => lib}/jats/label/LabelComponent.js (100%) rename {packages => lib}/jats/label/LabelConverter.js (100%) rename {packages => lib}/jats/label/package.js (100%) rename {packages => lib}/jats/monospace/Monospace.js (100%) rename {packages => lib}/jats/monospace/MonospaceConverter.js (100%) rename {packages => lib}/jats/monospace/_index.css (100%) rename {packages => lib}/jats/monospace/package.js (100%) rename {packages => lib}/jats/package.js (100%) rename {packages => lib}/jats/paragraph/Paragraph.js (100%) rename {packages => lib}/jats/paragraph/ParagraphComponent.js (100%) rename {packages => lib}/jats/paragraph/ParagraphConverter.js (100%) rename {packages => lib}/jats/paragraph/package.js (100%) rename {packages => lib}/jats/ref-list/RefList.js (100%) rename {packages => lib}/jats/ref-list/RefListComponent.js (94%) rename {packages => lib}/jats/ref-list/RefListConverter.js (96%) rename {packages => lib}/jats/ref-list/_index.css (100%) rename {packages => lib}/jats/ref-list/package.js (100%) rename {packages => lib}/jats/ref/Ref.js (100%) rename {packages => lib}/jats/ref/RefComponent.js (100%) rename {packages => lib}/jats/ref/RefConverter.js (100%) rename {packages => lib}/jats/ref/RefTarget.js (100%) rename {packages => lib}/jats/ref/_index.css (100%) rename {packages => lib}/jats/ref/package.js (100%) rename {packages => lib}/jats/ref/refToHTML.js (100%) rename {packages => lib}/jats/section/Section.js (100%) rename {packages => lib}/jats/section/SectionComponent.js (100%) rename {packages => lib}/jats/section/SectionConverter.js (97%) rename {packages => lib}/jats/section/_index.css (100%) rename {packages => lib}/jats/section/package.js (100%) rename {packages => lib}/jats/subscript/Subscript.js (100%) rename {packages => lib}/jats/subscript/SubscriptConverter.js (100%) rename {packages => lib}/jats/subscript/_index.css (100%) rename {packages => lib}/jats/subscript/package.js (100%) rename {packages => lib}/jats/superscript/Superscript.js (100%) rename {packages => lib}/jats/superscript/SuperscriptConverter.js (100%) rename {packages => lib}/jats/superscript/_index.css (100%) rename {packages => lib}/jats/superscript/package.js (100%) rename {packages => lib}/jats/table-wrap/TableWrap.js (100%) rename {packages => lib}/jats/table-wrap/TableWrapComponent.js (100%) rename {packages => lib}/jats/table-wrap/TableWrapConverter.js (100%) rename {packages => lib}/jats/table-wrap/package.js (100%) rename {packages => lib}/jats/table/Table.js (100%) rename {packages => lib}/jats/table/TableComponent.js (100%) rename {packages => lib}/jats/table/TableConverter.js (100%) rename {packages => lib}/jats/table/package.js (100%) rename {packages => lib}/jats/title-group/TitleGroup.js (100%) rename {packages => lib}/jats/title-group/TitleGroupComponent.js (90%) rename {packages => lib}/jats/title-group/TitleGroupConverter.js (95%) rename {packages => lib}/jats/title-group/package.js (100%) rename {packages => lib}/jats/title/Title.js (100%) rename {packages => lib}/jats/title/TitleComponent.js (100%) rename {packages => lib}/jats/title/TitleConverter.js (100%) rename {packages => lib}/jats/title/_index.css (100%) rename {packages => lib}/jats/title/package.js (100%) rename {packages => lib}/jats/xref/AddXRefCommand.js (100%) rename {packages => lib}/jats/xref/AddXRefTool.js (100%) rename {packages => lib}/jats/xref/EditXRefCommand.js (100%) rename {packages => lib}/jats/xref/EditXRefTool.js (100%) rename {packages => lib}/jats/xref/XRef.js (100%) rename {packages => lib}/jats/xref/XRefComponent.js (100%) rename {packages => lib}/jats/xref/XRefConverter.js (100%) rename {packages => lib}/jats/xref/XRefTargets.js (100%) rename {packages => lib}/jats/xref/_edit-xref-tool.css (100%) rename {packages => lib}/jats/xref/_index.css (100%) rename {packages => lib}/jats/xref/_scrollbar-highlights.css (100%) rename {packages => lib}/jats/xref/_xref-targets.css (100%) rename {packages => lib}/jats/xref/_xref.css (100%) rename {packages => lib}/jats/xref/getXRefTargets.js (100%) rename {packages => lib}/jats/xref/package.js (100%) rename {packages => lib}/publisher/Publisher.js (100%) rename {packages => lib}/publisher/PublisherPackage.js (100%) rename {packages => lib}/publisher/PublisherTOCProvider.js (100%) rename {packages => lib}/publisher/_index.css (100%) rename {examples => lib}/tagging/README.md (100%) rename {packages => lib}/tagging/TaggingPackage.js (100%) rename {packages => lib}/tagging/aff/TagAffCommand.js (100%) rename {packages => lib}/tagging/aff/TagAffTool.js (100%) rename {packages => lib}/tagging/contrib/TagContribCommand.js (100%) rename {packages => lib}/tagging/contrib/TagContribTool.js (100%) rename {packages => lib}/tagging/ref/TagRefCommand.js (100%) rename {packages => lib}/tagging/ref/TagRefTool.js (100%) rename {examples => lib/texture}/ExampleXMLStore.js (79%) rename {packages => lib}/texture/FileClientStub.js (100%) rename {packages => lib}/texture/SaveHandlerStub.js (100%) rename {packages => lib}/texture/Texture.js (100%) rename {packages => lib}/texture/TextureConfigurator.js (77%) rename {packages => lib}/texture/package.js (100%) rename {packages => lib}/unsupported/UnsupportedInlineNode.js (100%) rename {packages => lib}/unsupported/UnsupportedInlineNodeCommand.js (100%) rename {packages => lib}/unsupported/UnsupportedInlineNodeComponent.js (100%) rename {packages => lib}/unsupported/UnsupportedInlineNodeJATSConverter.js (100%) rename {packages => lib}/unsupported/UnsupportedInlineNodeTool.js (100%) rename {packages => lib}/unsupported/UnsupportedNode.js (100%) rename {packages => lib}/unsupported/UnsupportedNodeComponent.js (100%) rename {packages => lib}/unsupported/UnsupportedNodeJATSConverter.js (100%) rename {packages => lib}/unsupported/UnsupportedNodePackage.js (100%) rename {packages => lib}/unsupported/_index.css (100%) rename {util => lib/util}/XMLIterator.js (100%) rename {util => lib/util}/diff.html (100%) rename {util => lib/util}/getFullName.js (100%) rename {util => lib/util}/renderNodeComponent.js (100%) rename {util => lib/util}/toDOM.js (100%) delete mode 100644 packages/tagging/README.md diff --git a/examples/data/elife-15278.xml b/data/elife-15278.xml similarity index 100% rename from examples/data/elife-15278.xml rename to data/elife-15278.xml diff --git a/examples/data/example.xml b/data/example.xml similarity index 100% rename from examples/data/example.xml rename to data/example.xml diff --git a/examples/data/kitchen-sink-author.xml b/data/kitchen-sink-author.xml similarity index 100% rename from examples/data/kitchen-sink-author.xml rename to data/kitchen-sink-author.xml diff --git a/examples/data/vanilla.xml b/data/vanilla.xml similarity index 100% rename from examples/data/vanilla.xml rename to data/vanilla.xml diff --git a/examples/data/with-xref.xml b/data/with-xref.xml similarity index 100% rename from examples/data/with-xref.xml rename to data/with-xref.xml diff --git a/examples/author.html b/examples/author.html new file mode 100644 index 000000000..47d3423cb --- /dev/null +++ b/examples/author.html @@ -0,0 +1,45 @@ + + + Texture Author + + + + + + + + + + + diff --git a/examples/author/app.css b/examples/author/app.css deleted file mode 100644 index d994158d6..000000000 --- a/examples/author/app.css +++ /dev/null @@ -1,11 +0,0 @@ -/* Substance Component styles */ -@import '../substance/substance.css'; -/* Texture Component styles */ -@import '../texture.css'; -/* You may want to use your own reset and pagestyle */ -@import '../substance/substance-reset.css'; -@import '../substance/substance-pagestyle.css'; -/* Using url here, so font-awesome does not get bundled. */ -@import url('../font-awesome/css/font-awesome.min.css'); -body { overflow: hidden; } -.sc-author { position: absolute; left: 0px; right: 0px; bottom: 0px; top: 0px; } \ No newline at end of file diff --git a/examples/author/index.html b/examples/author/index.html deleted file mode 100644 index 6f4321aa9..000000000 --- a/examples/author/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - Texture Author - - - - - - - - diff --git a/examples/config.js b/examples/config.js deleted file mode 100644 index 77a36d62e..000000000 --- a/examples/config.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict'; - -// this needs to stay commonjs as it is used only during build -module.exports = { - examples: ['author', 'publisher'] -}; diff --git a/examples/index.html b/examples/index.html deleted file mode 100644 index d2f8e273a..000000000 --- a/examples/index.html +++ /dev/null @@ -1,7 +0,0 @@ -

      Texture Examples

      - -
        -
      • Author - word-like editing interface
      • -
      • Publisher - QC-interface for publishers
      • -
      • Tagging - Experiment for post-conversion tagging UI
      • -
      diff --git a/examples/publisher.html b/examples/publisher.html new file mode 100644 index 000000000..9330d95c9 --- /dev/null +++ b/examples/publisher.html @@ -0,0 +1,45 @@ + + + Texture Publisher + + + + + + + + + + + diff --git a/examples/publisher/app.css b/examples/publisher/app.css deleted file mode 100644 index 52dc7c5d5..000000000 --- a/examples/publisher/app.css +++ /dev/null @@ -1,11 +0,0 @@ -/* Substance Component styles */ -@import '../substance/substance.css'; -/* Texture Component styles */ -@import '../texture.css'; -/* You may want to use your own reset and pagestyle */ -@import '../substance/substance-reset.css'; -@import '../substance/substance-pagestyle.css'; -/* Using url here, so font-awesome does not get bundled. */ -@import url('../font-awesome/css/font-awesome.min.css'); -body { overflow: hidden; } -.sc-publisher { position: absolute; left: 0px; right: 0px; bottom: 0px; top: 0px; } \ No newline at end of file diff --git a/examples/publisher/app.js b/examples/publisher/app.js deleted file mode 100644 index 0cf375f95..000000000 --- a/examples/publisher/app.js +++ /dev/null @@ -1,23 +0,0 @@ -import { substanceGlobals } from 'substance' -import Texture from '../../packages/texture/Texture' -import TextureConfigurator from '../../packages/texture/TextureConfigurator' -import PublisherPackage from '../../packages/publisher/PublisherPackage' -import ExampleXMLStore from '../ExampleXMLStore' - -substanceGlobals.DEBUG_RENDERING = true - -/* Configure example */ -let configurator = new TextureConfigurator() - .import(PublisherPackage) - .setXMLStore(ExampleXMLStore) - -if (typeof window !== 'undefined') { - window.onload = function() { - var app = Texture.mount({ - configurator: configurator, - documentId: 'elife-15278' - }, document.body) - window.app = app - } -} - diff --git a/examples/publisher/index.html b/examples/publisher/index.html deleted file mode 100644 index 8e0654481..000000000 --- a/examples/publisher/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - Texture Publisher - - - - - - - - - diff --git a/examples/tagging.html b/examples/tagging.html new file mode 100644 index 000000000..324129843 --- /dev/null +++ b/examples/tagging.html @@ -0,0 +1,47 @@ + + + Texture Publisher + + + + + + + + + + + diff --git a/examples/tagging/app.css b/examples/tagging/app.css deleted file mode 100644 index d994158d6..000000000 --- a/examples/tagging/app.css +++ /dev/null @@ -1,11 +0,0 @@ -/* Substance Component styles */ -@import '../substance/substance.css'; -/* Texture Component styles */ -@import '../texture.css'; -/* You may want to use your own reset and pagestyle */ -@import '../substance/substance-reset.css'; -@import '../substance/substance-pagestyle.css'; -/* Using url here, so font-awesome does not get bundled. */ -@import url('../font-awesome/css/font-awesome.min.css'); -body { overflow: hidden; } -.sc-author { position: absolute; left: 0px; right: 0px; bottom: 0px; top: 0px; } \ No newline at end of file diff --git a/examples/tagging/app.js b/examples/tagging/app.js deleted file mode 100644 index 2040f3744..000000000 --- a/examples/tagging/app.js +++ /dev/null @@ -1,25 +0,0 @@ -import { substanceGlobals } from 'substance' -import Texture from '../../packages/texture/Texture' -import TextureConfigurator from '../../packages/texture/TextureConfigurator' -import AuthorPackage from '../../packages/author/AuthorPackage' -import TaggingPackage from '../../packages/tagging/TaggingPackage' -import ExampleXMLStore from '../ExampleXMLStore' - -substanceGlobals.DEBUG_RENDERING = true - -/* Configure example */ -let configurator = new TextureConfigurator() - .import(AuthorPackage) - // enable tagging abilities - .import(TaggingPackage) - .setXMLStore(ExampleXMLStore) - -if (typeof window !== 'undefined') { - window.onload = function() { - let app = Texture.mount({ - configurator: configurator, - documentId: 'elife-15278' - }, document.body) - window.app = app - } -} diff --git a/examples/tagging/index.html b/examples/tagging/index.html deleted file mode 100644 index 23acde600..000000000 --- a/examples/tagging/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - Texture -- Tagging - - - - - - - - diff --git a/index.es.js b/index.es.js new file mode 100644 index 000000000..106a8a5b7 --- /dev/null +++ b/index.es.js @@ -0,0 +1,16 @@ +// texture +export { default as Texture } from './lib/texture/Texture' +export { default as TextureConfigurator } from './lib/texture/TextureConfigurator' +export { default as ExampleXMLStore } from './lib/texture/ExampleXMLStore' + +// author +export { default as Author } from './lib/author/Author' +export { default as AuthorPackage } from './lib/author/AuthorPackage' + +// publisher +export { default as Publisher } from './lib/publisher/Publisher' +export { default as PublisherPackage } from './lib/publisher/PublisherPackage' + +// tagging +export { default as TaggingPackage } from './lib/tagging/TaggingPackage' + diff --git a/index.html b/index.html new file mode 100644 index 000000000..97ee26db9 --- /dev/null +++ b/index.html @@ -0,0 +1,7 @@ +

      Texture Examples

      + +
        +
      • Author - word-like editing interface
      • +
      • Publisher - QC-interface for publishers
      • +
      • Tagging - Experiment for post-conversion tagging UI
      • +
      diff --git a/packages/_index.css b/lib/_index.css similarity index 100% rename from packages/_index.css rename to lib/_index.css diff --git a/packages/author/Author.js b/lib/author/Author.js similarity index 100% rename from packages/author/Author.js rename to lib/author/Author.js diff --git a/packages/author/AuthorExporter.js b/lib/author/AuthorExporter.js similarity index 100% rename from packages/author/AuthorExporter.js rename to lib/author/AuthorExporter.js diff --git a/packages/author/AuthorImporter.js b/lib/author/AuthorImporter.js similarity index 100% rename from packages/author/AuthorImporter.js rename to lib/author/AuthorImporter.js diff --git a/packages/author/AuthorPackage.js b/lib/author/AuthorPackage.js similarity index 100% rename from packages/author/AuthorPackage.js rename to lib/author/AuthorPackage.js diff --git a/packages/author/AuthorTOCProvider.js b/lib/author/AuthorTOCProvider.js similarity index 100% rename from packages/author/AuthorTOCProvider.js rename to lib/author/AuthorTOCProvider.js diff --git a/packages/author/JATSTransformer.js b/lib/author/JATSTransformer.js similarity index 100% rename from packages/author/JATSTransformer.js rename to lib/author/JATSTransformer.js diff --git a/packages/author/_index.css b/lib/author/_index.css similarity index 100% rename from packages/author/_index.css rename to lib/author/_index.css diff --git a/examples/author/app.js b/lib/author/app.js similarity index 71% rename from examples/author/app.js rename to lib/author/app.js index 3398e849f..c836b3d65 100644 --- a/examples/author/app.js +++ b/lib/author/app.js @@ -1,7 +1,7 @@ import { substanceGlobals } from 'substance' -import Texture from '../../packages/texture/Texture' -import TextureConfigurator from '../../packages/texture/TextureConfigurator' -import AuthorPackage from '../../packages/author/AuthorPackage' +import Texture from '../../lib/texture/Texture' +import TextureConfigurator from '../../lib/texture/TextureConfigurator' +import AuthorPackage from '../../lib/author/AuthorPackage' import ExampleXMLStore from '../ExampleXMLStore' substanceGlobals.DEBUG_RENDERING = true; diff --git a/packages/author/heading/Heading.js b/lib/author/heading/Heading.js similarity index 100% rename from packages/author/heading/Heading.js rename to lib/author/heading/Heading.js diff --git a/packages/author/heading/HeadingComponent.js b/lib/author/heading/HeadingComponent.js similarity index 100% rename from packages/author/heading/HeadingComponent.js rename to lib/author/heading/HeadingComponent.js diff --git a/packages/author/heading/package.js b/lib/author/heading/package.js similarity index 100% rename from packages/author/heading/package.js rename to lib/author/heading/package.js diff --git a/packages/common/AbstractWriter.js b/lib/common/AbstractWriter.js similarity index 100% rename from packages/common/AbstractWriter.js rename to lib/common/AbstractWriter.js diff --git a/packages/common/EditXML.js b/lib/common/EditXML.js similarity index 100% rename from packages/common/EditXML.js rename to lib/common/EditXML.js diff --git a/packages/common/SaveHandler.js b/lib/common/SaveHandler.js similarity index 100% rename from packages/common/SaveHandler.js rename to lib/common/SaveHandler.js diff --git a/packages/common/XMLAttributeEditor.js b/lib/common/XMLAttributeEditor.js similarity index 100% rename from packages/common/XMLAttributeEditor.js rename to lib/common/XMLAttributeEditor.js diff --git a/packages/common/XMLEditor.js b/lib/common/XMLEditor.js similarity index 100% rename from packages/common/XMLEditor.js rename to lib/common/XMLEditor.js diff --git a/packages/common/_edit-xml.css b/lib/common/_edit-xml.css similarity index 100% rename from packages/common/_edit-xml.css rename to lib/common/_edit-xml.css diff --git a/packages/common/_index.css b/lib/common/_index.css similarity index 100% rename from packages/common/_index.css rename to lib/common/_index.css diff --git a/packages/common/_isolated-node.css b/lib/common/_isolated-node.css similarity index 100% rename from packages/common/_isolated-node.css rename to lib/common/_isolated-node.css diff --git a/packages/common/_toolbar.css b/lib/common/_toolbar.css similarity index 100% rename from packages/common/_toolbar.css rename to lib/common/_toolbar.css diff --git a/packages/common/package.js b/lib/common/package.js similarity index 100% rename from packages/common/package.js rename to lib/common/package.js diff --git a/packages/inline-wrapper/InlineWrapperJATSConverter.js b/lib/inline-wrapper/InlineWrapperJATSConverter.js similarity index 100% rename from packages/inline-wrapper/InlineWrapperJATSConverter.js rename to lib/inline-wrapper/InlineWrapperJATSConverter.js diff --git a/packages/inline-wrapper/InlineWrapperPackage.js b/lib/inline-wrapper/InlineWrapperPackage.js similarity index 100% rename from packages/inline-wrapper/InlineWrapperPackage.js rename to lib/inline-wrapper/InlineWrapperPackage.js diff --git a/packages/jats/JATS.js b/lib/jats/JATS.js similarity index 100% rename from packages/jats/JATS.js rename to lib/jats/JATS.js diff --git a/packages/jats/JATSExporter.js b/lib/jats/JATSExporter.js similarity index 100% rename from packages/jats/JATSExporter.js rename to lib/jats/JATSExporter.js diff --git a/packages/jats/JATSImporter.js b/lib/jats/JATSImporter.js similarity index 100% rename from packages/jats/JATSImporter.js rename to lib/jats/JATSImporter.js diff --git a/packages/jats/TextNodeConverter.js b/lib/jats/TextNodeConverter.js similarity index 100% rename from packages/jats/TextNodeConverter.js rename to lib/jats/TextNodeConverter.js diff --git a/packages/jats/_index.css b/lib/jats/_index.css similarity index 100% rename from packages/jats/_index.css rename to lib/jats/_index.css diff --git a/packages/jats/aff/Aff.js b/lib/jats/aff/Aff.js similarity index 100% rename from packages/jats/aff/Aff.js rename to lib/jats/aff/Aff.js diff --git a/packages/jats/aff/AffComponent.js b/lib/jats/aff/AffComponent.js similarity index 100% rename from packages/jats/aff/AffComponent.js rename to lib/jats/aff/AffComponent.js diff --git a/packages/jats/aff/AffConverter.js b/lib/jats/aff/AffConverter.js similarity index 100% rename from packages/jats/aff/AffConverter.js rename to lib/jats/aff/AffConverter.js diff --git a/packages/jats/aff/_aff.css b/lib/jats/aff/_aff.css similarity index 100% rename from packages/jats/aff/_aff.css rename to lib/jats/aff/_aff.css diff --git a/packages/jats/aff/_index.css b/lib/jats/aff/_index.css similarity index 100% rename from packages/jats/aff/_index.css rename to lib/jats/aff/_index.css diff --git a/packages/jats/aff/affUtils.js b/lib/jats/aff/affUtils.js similarity index 92% rename from packages/jats/aff/affUtils.js rename to lib/jats/aff/affUtils.js index 50caefc13..823f6338e 100644 --- a/packages/jats/aff/affUtils.js +++ b/lib/jats/aff/affUtils.js @@ -1,4 +1,4 @@ -import toDOM from '../../../util/toDOM' +import toDOM from '../../util/toDOM' /* Get all affiliations for a doc diff --git a/packages/jats/aff/package.js b/lib/jats/aff/package.js similarity index 100% rename from packages/jats/aff/package.js rename to lib/jats/aff/package.js diff --git a/packages/jats/article-meta/ArticleMeta.js b/lib/jats/article-meta/ArticleMeta.js similarity index 100% rename from packages/jats/article-meta/ArticleMeta.js rename to lib/jats/article-meta/ArticleMeta.js diff --git a/packages/jats/article-meta/ArticleMetaComponent.js b/lib/jats/article-meta/ArticleMetaComponent.js similarity index 90% rename from packages/jats/article-meta/ArticleMetaComponent.js rename to lib/jats/article-meta/ArticleMetaComponent.js index ec7a71e2a..164a6b903 100644 --- a/packages/jats/article-meta/ArticleMetaComponent.js +++ b/lib/jats/article-meta/ArticleMetaComponent.js @@ -1,5 +1,5 @@ import { Component } from 'substance' -import renderNodeComponent from '../../../util/renderNodeComponent' +import renderNodeComponent from '../../util/renderNodeComponent' class ArticleMetaComponent extends Component { render($$) { diff --git a/packages/jats/article-meta/ArticleMetaConverter.js b/lib/jats/article-meta/ArticleMetaConverter.js similarity index 98% rename from packages/jats/article-meta/ArticleMetaConverter.js rename to lib/jats/article-meta/ArticleMetaConverter.js index 5bfcc923a..2ae0ca1e1 100644 --- a/packages/jats/article-meta/ArticleMetaConverter.js +++ b/lib/jats/article-meta/ArticleMetaConverter.js @@ -1,4 +1,4 @@ -import XMLIterator from '../../../util/XMLIterator' +import XMLIterator from '../../util/XMLIterator' import JATS from '../JATS' export default { diff --git a/packages/jats/article-meta/package.js b/lib/jats/article-meta/package.js similarity index 100% rename from packages/jats/article-meta/package.js rename to lib/jats/article-meta/package.js diff --git a/packages/jats/article-title/ArticleTitle.js b/lib/jats/article-title/ArticleTitle.js similarity index 100% rename from packages/jats/article-title/ArticleTitle.js rename to lib/jats/article-title/ArticleTitle.js diff --git a/packages/jats/article-title/ArticleTitleComponent.js b/lib/jats/article-title/ArticleTitleComponent.js similarity index 100% rename from packages/jats/article-title/ArticleTitleComponent.js rename to lib/jats/article-title/ArticleTitleComponent.js diff --git a/packages/jats/article-title/ArticleTitleConverter.js b/lib/jats/article-title/ArticleTitleConverter.js similarity index 100% rename from packages/jats/article-title/ArticleTitleConverter.js rename to lib/jats/article-title/ArticleTitleConverter.js diff --git a/packages/jats/article-title/_index.css b/lib/jats/article-title/_index.css similarity index 100% rename from packages/jats/article-title/_index.css rename to lib/jats/article-title/_index.css diff --git a/packages/jats/article-title/package.js b/lib/jats/article-title/package.js similarity index 100% rename from packages/jats/article-title/package.js rename to lib/jats/article-title/package.js diff --git a/packages/jats/article/ArticleComponent.js b/lib/jats/article/ArticleComponent.js similarity index 94% rename from packages/jats/article/ArticleComponent.js rename to lib/jats/article/ArticleComponent.js index 310876454..79a46960f 100644 --- a/packages/jats/article/ArticleComponent.js +++ b/lib/jats/article/ArticleComponent.js @@ -1,5 +1,5 @@ import { Component } from 'substance' -import renderNodeComponent from '../../../util/renderNodeComponent' +import renderNodeComponent from '../../util/renderNodeComponent' class ArticleComponent extends Component { diff --git a/packages/jats/article/ArticleConverter.js b/lib/jats/article/ArticleConverter.js similarity index 97% rename from packages/jats/article/ArticleConverter.js rename to lib/jats/article/ArticleConverter.js index 39952592e..563ad75bb 100644 --- a/packages/jats/article/ArticleConverter.js +++ b/lib/jats/article/ArticleConverter.js @@ -1,4 +1,4 @@ -import XMLIterator from '../../../util/XMLIterator' +import XMLIterator from '../../util/XMLIterator' export default { diff --git a/packages/jats/article/ArticleNode.js b/lib/jats/article/ArticleNode.js similarity index 100% rename from packages/jats/article/ArticleNode.js rename to lib/jats/article/ArticleNode.js diff --git a/packages/jats/article/TextureArticle.js b/lib/jats/article/TextureArticle.js similarity index 100% rename from packages/jats/article/TextureArticle.js rename to lib/jats/article/TextureArticle.js diff --git a/packages/jats/article/_index.css b/lib/jats/article/_index.css similarity index 100% rename from packages/jats/article/_index.css rename to lib/jats/article/_index.css diff --git a/packages/jats/article/package.js b/lib/jats/article/package.js similarity index 100% rename from packages/jats/article/package.js rename to lib/jats/article/package.js diff --git a/packages/jats/back/Back.js b/lib/jats/back/Back.js similarity index 100% rename from packages/jats/back/Back.js rename to lib/jats/back/Back.js diff --git a/packages/jats/back/BackComponent.js b/lib/jats/back/BackComponent.js similarity index 91% rename from packages/jats/back/BackComponent.js rename to lib/jats/back/BackComponent.js index 6a0d234a3..3eb513590 100644 --- a/packages/jats/back/BackComponent.js +++ b/lib/jats/back/BackComponent.js @@ -1,5 +1,5 @@ import { Component } from 'substance' -import renderNodeComponent from '../../../util/renderNodeComponent' +import renderNodeComponent from '../../util/renderNodeComponent' class BackComponent extends Component { diff --git a/packages/jats/back/BackConverter.js b/lib/jats/back/BackConverter.js similarity index 95% rename from packages/jats/back/BackConverter.js rename to lib/jats/back/BackConverter.js index c7d584692..0b054dfde 100644 --- a/packages/jats/back/BackConverter.js +++ b/lib/jats/back/BackConverter.js @@ -1,4 +1,4 @@ -import XMLIterator from '../../../util/XMLIterator' +import XMLIterator from '../../util/XMLIterator' let BACK_CONTENT = ["ack", "app-group", "bio", "fn-group", "glossary", "ref-list", "notes", "sec"] export default { diff --git a/packages/jats/back/_index.css b/lib/jats/back/_index.css similarity index 100% rename from packages/jats/back/_index.css rename to lib/jats/back/_index.css diff --git a/packages/jats/back/package.js b/lib/jats/back/package.js similarity index 100% rename from packages/jats/back/package.js rename to lib/jats/back/package.js diff --git a/packages/jats/body/Body.js b/lib/jats/body/Body.js similarity index 100% rename from packages/jats/body/Body.js rename to lib/jats/body/Body.js diff --git a/packages/jats/body/BodyComponent.js b/lib/jats/body/BodyComponent.js similarity index 100% rename from packages/jats/body/BodyComponent.js rename to lib/jats/body/BodyComponent.js diff --git a/packages/jats/body/BodyConverter.js b/lib/jats/body/BodyConverter.js similarity index 95% rename from packages/jats/body/BodyConverter.js rename to lib/jats/body/BodyConverter.js index f8c0cad26..0bf8c59fa 100644 --- a/packages/jats/body/BodyConverter.js +++ b/lib/jats/body/BodyConverter.js @@ -1,5 +1,5 @@ import JATS from '../JATS' -import XMLIterator from '../../../util/XMLIterator' +import XMLIterator from '../../util/XMLIterator' export default { diff --git a/packages/jats/body/package.js b/lib/jats/body/package.js similarity index 100% rename from packages/jats/body/package.js rename to lib/jats/body/package.js diff --git a/packages/jats/bold/Bold.js b/lib/jats/bold/Bold.js similarity index 100% rename from packages/jats/bold/Bold.js rename to lib/jats/bold/Bold.js diff --git a/packages/jats/bold/BoldCommand.js b/lib/jats/bold/BoldCommand.js similarity index 100% rename from packages/jats/bold/BoldCommand.js rename to lib/jats/bold/BoldCommand.js diff --git a/packages/jats/bold/BoldConverter.js b/lib/jats/bold/BoldConverter.js similarity index 100% rename from packages/jats/bold/BoldConverter.js rename to lib/jats/bold/BoldConverter.js diff --git a/packages/jats/bold/BoldTool.js b/lib/jats/bold/BoldTool.js similarity index 100% rename from packages/jats/bold/BoldTool.js rename to lib/jats/bold/BoldTool.js diff --git a/packages/jats/bold/_index.css b/lib/jats/bold/_index.css similarity index 100% rename from packages/jats/bold/_index.css rename to lib/jats/bold/_index.css diff --git a/packages/jats/bold/package.js b/lib/jats/bold/package.js similarity index 100% rename from packages/jats/bold/package.js rename to lib/jats/bold/package.js diff --git a/packages/jats/caption/Caption.js b/lib/jats/caption/Caption.js similarity index 100% rename from packages/jats/caption/Caption.js rename to lib/jats/caption/Caption.js diff --git a/packages/jats/caption/CaptionComponent.js b/lib/jats/caption/CaptionComponent.js similarity index 100% rename from packages/jats/caption/CaptionComponent.js rename to lib/jats/caption/CaptionComponent.js diff --git a/packages/jats/caption/CaptionConverter.js b/lib/jats/caption/CaptionConverter.js similarity index 95% rename from packages/jats/caption/CaptionConverter.js rename to lib/jats/caption/CaptionConverter.js index bbab175bb..f30b6724b 100644 --- a/packages/jats/caption/CaptionConverter.js +++ b/lib/jats/caption/CaptionConverter.js @@ -1,4 +1,4 @@ -import XMLIterator from '../../../util/XMLIterator' +import XMLIterator from '../../util/XMLIterator' export default { diff --git a/packages/jats/caption/package.js b/lib/jats/caption/package.js similarity index 100% rename from packages/jats/caption/package.js rename to lib/jats/caption/package.js diff --git a/packages/jats/contrib-group/ContribGroup.js b/lib/jats/contrib-group/ContribGroup.js similarity index 100% rename from packages/jats/contrib-group/ContribGroup.js rename to lib/jats/contrib-group/ContribGroup.js diff --git a/packages/jats/contrib-group/ContribGroupComponent.js b/lib/jats/contrib-group/ContribGroupComponent.js similarity index 93% rename from packages/jats/contrib-group/ContribGroupComponent.js rename to lib/jats/contrib-group/ContribGroupComponent.js index 309470aac..a242339a0 100644 --- a/packages/jats/contrib-group/ContribGroupComponent.js +++ b/lib/jats/contrib-group/ContribGroupComponent.js @@ -1,5 +1,5 @@ import { Component } from 'substance' -import renderNodeComponent from '../../../util/renderNodeComponent' +import renderNodeComponent from '../../util/renderNodeComponent' class ContribGroupComponent extends Component { didMount() { diff --git a/packages/jats/contrib-group/ContribGroupConverter.js b/lib/jats/contrib-group/ContribGroupConverter.js similarity index 94% rename from packages/jats/contrib-group/ContribGroupConverter.js rename to lib/jats/contrib-group/ContribGroupConverter.js index 2cd421ce2..e22357163 100644 --- a/packages/jats/contrib-group/ContribGroupConverter.js +++ b/lib/jats/contrib-group/ContribGroupConverter.js @@ -1,4 +1,4 @@ -import XMLIterator from '../../../util/XMLIterator' +import XMLIterator from '../../util/XMLIterator' let CONTRIB_GROUP = ['contrib', 'address', 'aff', 'aff-alternatives', 'author-comment', 'bio', 'email', 'etal', 'ext-link', 'fn', 'on-behalf-of', 'role', 'uri', 'xref', 'x'] diff --git a/packages/jats/contrib-group/_index.css b/lib/jats/contrib-group/_index.css similarity index 100% rename from packages/jats/contrib-group/_index.css rename to lib/jats/contrib-group/_index.css diff --git a/packages/jats/contrib-group/package.js b/lib/jats/contrib-group/package.js similarity index 100% rename from packages/jats/contrib-group/package.js rename to lib/jats/contrib-group/package.js diff --git a/packages/jats/contrib/Contrib.js b/lib/jats/contrib/Contrib.js similarity index 100% rename from packages/jats/contrib/Contrib.js rename to lib/jats/contrib/Contrib.js diff --git a/packages/jats/contrib/ContribComponent.js b/lib/jats/contrib/ContribComponent.js similarity index 100% rename from packages/jats/contrib/ContribComponent.js rename to lib/jats/contrib/ContribComponent.js diff --git a/packages/jats/contrib/ContribConverter.js b/lib/jats/contrib/ContribConverter.js similarity index 100% rename from packages/jats/contrib/ContribConverter.js rename to lib/jats/contrib/ContribConverter.js diff --git a/packages/jats/contrib/EditContrib.js b/lib/jats/contrib/EditContrib.js similarity index 100% rename from packages/jats/contrib/EditContrib.js rename to lib/jats/contrib/EditContrib.js diff --git a/packages/jats/contrib/_contrib.css b/lib/jats/contrib/_contrib.css similarity index 100% rename from packages/jats/contrib/_contrib.css rename to lib/jats/contrib/_contrib.css diff --git a/packages/jats/contrib/_edit-contrib.css b/lib/jats/contrib/_edit-contrib.css similarity index 100% rename from packages/jats/contrib/_edit-contrib.css rename to lib/jats/contrib/_edit-contrib.css diff --git a/packages/jats/contrib/_index.css b/lib/jats/contrib/_index.css similarity index 100% rename from packages/jats/contrib/_index.css rename to lib/jats/contrib/_index.css diff --git a/packages/jats/contrib/contribUtils.js b/lib/jats/contrib/contribUtils.js similarity index 93% rename from packages/jats/contrib/contribUtils.js rename to lib/jats/contrib/contribUtils.js index b121bd132..08a0752f9 100644 --- a/packages/jats/contrib/contribUtils.js +++ b/lib/jats/contrib/contribUtils.js @@ -1,5 +1,5 @@ -import toDOM from '../../../util/toDOM' -import getFullName from '../../../util/getFullName' +import toDOM from '../../util/toDOM' +import getFullName from '../../util/getFullName' import { getAffs } from '../aff/affUtils' /* diff --git a/packages/jats/contrib/package.js b/lib/jats/contrib/package.js similarity index 100% rename from packages/jats/contrib/package.js rename to lib/jats/contrib/package.js diff --git a/packages/jats/ext-link/EditExtLinkTool.js b/lib/jats/ext-link/EditExtLinkTool.js similarity index 100% rename from packages/jats/ext-link/EditExtLinkTool.js rename to lib/jats/ext-link/EditExtLinkTool.js diff --git a/packages/jats/ext-link/ExtLink.js b/lib/jats/ext-link/ExtLink.js similarity index 100% rename from packages/jats/ext-link/ExtLink.js rename to lib/jats/ext-link/ExtLink.js diff --git a/packages/jats/ext-link/ExtLinkComponent.js b/lib/jats/ext-link/ExtLinkComponent.js similarity index 100% rename from packages/jats/ext-link/ExtLinkComponent.js rename to lib/jats/ext-link/ExtLinkComponent.js diff --git a/packages/jats/ext-link/ExtLinkConverter.js b/lib/jats/ext-link/ExtLinkConverter.js similarity index 100% rename from packages/jats/ext-link/ExtLinkConverter.js rename to lib/jats/ext-link/ExtLinkConverter.js diff --git a/packages/jats/ext-link/ExtLinkTool.js b/lib/jats/ext-link/ExtLinkTool.js similarity index 100% rename from packages/jats/ext-link/ExtLinkTool.js rename to lib/jats/ext-link/ExtLinkTool.js diff --git a/packages/jats/ext-link/_index.css b/lib/jats/ext-link/_index.css similarity index 100% rename from packages/jats/ext-link/_index.css rename to lib/jats/ext-link/_index.css diff --git a/packages/jats/ext-link/package.js b/lib/jats/ext-link/package.js similarity index 100% rename from packages/jats/ext-link/package.js rename to lib/jats/ext-link/package.js diff --git a/packages/jats/figure/Figure.js b/lib/jats/figure/Figure.js similarity index 100% rename from packages/jats/figure/Figure.js rename to lib/jats/figure/Figure.js diff --git a/packages/jats/figure/FigureComponent.js b/lib/jats/figure/FigureComponent.js similarity index 94% rename from packages/jats/figure/FigureComponent.js rename to lib/jats/figure/FigureComponent.js index bdfd878bc..a2dd0cf9d 100644 --- a/packages/jats/figure/FigureComponent.js +++ b/lib/jats/figure/FigureComponent.js @@ -1,5 +1,5 @@ import { Component } from 'substance' -import renderNodeComponent from '../../../util/renderNodeComponent' +import renderNodeComponent from '../../util/renderNodeComponent' class FigureComponent extends Component { diff --git a/packages/jats/figure/FigureConverter.js b/lib/jats/figure/FigureConverter.js similarity index 98% rename from packages/jats/figure/FigureConverter.js rename to lib/jats/figure/FigureConverter.js index 958236298..04e40bf7b 100644 --- a/packages/jats/figure/FigureConverter.js +++ b/lib/jats/figure/FigureConverter.js @@ -1,5 +1,5 @@ import JATS from '../JATS' -import XMLIterator from '../../../util/XMLIterator' +import XMLIterator from '../../util/XMLIterator' let ACCESS_OR_LINK = JATS.ACCESS.concat(JATS.ADDRESS_LINK) let FIGURE_CONTENT = JATS.BLOCK_MATH diff --git a/packages/jats/figure/FigureTarget.js b/lib/jats/figure/FigureTarget.js similarity index 95% rename from packages/jats/figure/FigureTarget.js rename to lib/jats/figure/FigureTarget.js index f005d10ba..5b6e94717 100644 --- a/packages/jats/figure/FigureTarget.js +++ b/lib/jats/figure/FigureTarget.js @@ -1,5 +1,5 @@ import { Component } from 'substance' -import renderNodeComponent from '../../../util/renderNodeComponent' +import renderNodeComponent from '../../util/renderNodeComponent' /* Renders a keyboard-selectable figure target item diff --git a/packages/jats/figure/_figure-target.css b/lib/jats/figure/_figure-target.css similarity index 100% rename from packages/jats/figure/_figure-target.css rename to lib/jats/figure/_figure-target.css diff --git a/packages/jats/figure/_index.css b/lib/jats/figure/_index.css similarity index 100% rename from packages/jats/figure/_index.css rename to lib/jats/figure/_index.css diff --git a/packages/jats/figure/package.js b/lib/jats/figure/package.js similarity index 100% rename from packages/jats/figure/package.js rename to lib/jats/figure/package.js diff --git a/packages/jats/footnote/Footnote.js b/lib/jats/footnote/Footnote.js similarity index 100% rename from packages/jats/footnote/Footnote.js rename to lib/jats/footnote/Footnote.js diff --git a/packages/jats/footnote/FootnoteComponent.js b/lib/jats/footnote/FootnoteComponent.js similarity index 91% rename from packages/jats/footnote/FootnoteComponent.js rename to lib/jats/footnote/FootnoteComponent.js index bef24087a..1303781f1 100644 --- a/packages/jats/footnote/FootnoteComponent.js +++ b/lib/jats/footnote/FootnoteComponent.js @@ -1,5 +1,5 @@ import { Component, TextPropertyComponent } from 'substance' -import renderNodeComponent from '../../../util/renderNodeComponent' +import renderNodeComponent from '../../util/renderNodeComponent' class FootnoteComponent extends Component { diff --git a/packages/jats/footnote/FootnoteConverter.js b/lib/jats/footnote/FootnoteConverter.js similarity index 94% rename from packages/jats/footnote/FootnoteConverter.js rename to lib/jats/footnote/FootnoteConverter.js index 6194bf3ec..7afc0c237 100644 --- a/packages/jats/footnote/FootnoteConverter.js +++ b/lib/jats/footnote/FootnoteConverter.js @@ -1,4 +1,4 @@ -import XMLIterator from '../../../util/XMLIterator' +import XMLIterator from '../../util/XMLIterator' export default { diff --git a/packages/jats/footnote/_index.css b/lib/jats/footnote/_index.css similarity index 100% rename from packages/jats/footnote/_index.css rename to lib/jats/footnote/_index.css diff --git a/packages/jats/footnote/package.js b/lib/jats/footnote/package.js similarity index 100% rename from packages/jats/footnote/package.js rename to lib/jats/footnote/package.js diff --git a/packages/jats/front/Front.js b/lib/jats/front/Front.js similarity index 100% rename from packages/jats/front/Front.js rename to lib/jats/front/Front.js diff --git a/packages/jats/front/FrontComponent.js b/lib/jats/front/FrontComponent.js similarity index 88% rename from packages/jats/front/FrontComponent.js rename to lib/jats/front/FrontComponent.js index 4cf9abb65..5a03ea683 100644 --- a/packages/jats/front/FrontComponent.js +++ b/lib/jats/front/FrontComponent.js @@ -1,5 +1,5 @@ import { Component } from 'substance' -import renderNodeComponent from '../../../util/renderNodeComponent' +import renderNodeComponent from '../../util/renderNodeComponent' class FrontComponent extends Component { diff --git a/packages/jats/front/FrontConverter.js b/lib/jats/front/FrontConverter.js similarity index 95% rename from packages/jats/front/FrontConverter.js rename to lib/jats/front/FrontConverter.js index f3587a934..16952dbdc 100644 --- a/packages/jats/front/FrontConverter.js +++ b/lib/jats/front/FrontConverter.js @@ -1,4 +1,4 @@ -import XMLIterator from '../../../util/XMLIterator' +import XMLIterator from '../../util/XMLIterator' let FRONT_CONTENT = ['def-list', 'list', 'ack', 'bio', 'fn-group', 'glossary', 'notes'] diff --git a/packages/jats/front/package.js b/lib/jats/front/package.js similarity index 100% rename from packages/jats/front/package.js rename to lib/jats/front/package.js diff --git a/packages/jats/graphic/Graphic.js b/lib/jats/graphic/Graphic.js similarity index 100% rename from packages/jats/graphic/Graphic.js rename to lib/jats/graphic/Graphic.js diff --git a/packages/jats/graphic/GraphicComponent.js b/lib/jats/graphic/GraphicComponent.js similarity index 100% rename from packages/jats/graphic/GraphicComponent.js rename to lib/jats/graphic/GraphicComponent.js diff --git a/packages/jats/graphic/GraphicConverter.js b/lib/jats/graphic/GraphicConverter.js similarity index 96% rename from packages/jats/graphic/GraphicConverter.js rename to lib/jats/graphic/GraphicConverter.js index 5e04245ed..82c7fa98c 100644 --- a/packages/jats/graphic/GraphicConverter.js +++ b/lib/jats/graphic/GraphicConverter.js @@ -1,5 +1,5 @@ import JATS from '../JATS' -import XMLIterator from '../../../util/XMLIterator' +import XMLIterator from '../../util/XMLIterator' let GRAPHIC_ELEMENTS = JATS.ACCESS .concat(JATS.ADDRESS_LINK) diff --git a/packages/jats/graphic/_index.css b/lib/jats/graphic/_index.css similarity index 100% rename from packages/jats/graphic/_index.css rename to lib/jats/graphic/_index.css diff --git a/packages/jats/graphic/package.js b/lib/jats/graphic/package.js similarity index 100% rename from packages/jats/graphic/package.js rename to lib/jats/graphic/package.js diff --git a/packages/jats/italic/Italic.js b/lib/jats/italic/Italic.js similarity index 100% rename from packages/jats/italic/Italic.js rename to lib/jats/italic/Italic.js diff --git a/packages/jats/italic/ItalicCommand.js b/lib/jats/italic/ItalicCommand.js similarity index 100% rename from packages/jats/italic/ItalicCommand.js rename to lib/jats/italic/ItalicCommand.js diff --git a/packages/jats/italic/ItalicConverter.js b/lib/jats/italic/ItalicConverter.js similarity index 100% rename from packages/jats/italic/ItalicConverter.js rename to lib/jats/italic/ItalicConverter.js diff --git a/packages/jats/italic/ItalicTool.js b/lib/jats/italic/ItalicTool.js similarity index 100% rename from packages/jats/italic/ItalicTool.js rename to lib/jats/italic/ItalicTool.js diff --git a/packages/jats/italic/_index.css b/lib/jats/italic/_index.css similarity index 100% rename from packages/jats/italic/_index.css rename to lib/jats/italic/_index.css diff --git a/packages/jats/italic/package.js b/lib/jats/italic/package.js similarity index 100% rename from packages/jats/italic/package.js rename to lib/jats/italic/package.js diff --git a/packages/jats/label/Label.js b/lib/jats/label/Label.js similarity index 100% rename from packages/jats/label/Label.js rename to lib/jats/label/Label.js diff --git a/packages/jats/label/LabelComponent.js b/lib/jats/label/LabelComponent.js similarity index 100% rename from packages/jats/label/LabelComponent.js rename to lib/jats/label/LabelComponent.js diff --git a/packages/jats/label/LabelConverter.js b/lib/jats/label/LabelConverter.js similarity index 100% rename from packages/jats/label/LabelConverter.js rename to lib/jats/label/LabelConverter.js diff --git a/packages/jats/label/package.js b/lib/jats/label/package.js similarity index 100% rename from packages/jats/label/package.js rename to lib/jats/label/package.js diff --git a/packages/jats/monospace/Monospace.js b/lib/jats/monospace/Monospace.js similarity index 100% rename from packages/jats/monospace/Monospace.js rename to lib/jats/monospace/Monospace.js diff --git a/packages/jats/monospace/MonospaceConverter.js b/lib/jats/monospace/MonospaceConverter.js similarity index 100% rename from packages/jats/monospace/MonospaceConverter.js rename to lib/jats/monospace/MonospaceConverter.js diff --git a/packages/jats/monospace/_index.css b/lib/jats/monospace/_index.css similarity index 100% rename from packages/jats/monospace/_index.css rename to lib/jats/monospace/_index.css diff --git a/packages/jats/monospace/package.js b/lib/jats/monospace/package.js similarity index 100% rename from packages/jats/monospace/package.js rename to lib/jats/monospace/package.js diff --git a/packages/jats/package.js b/lib/jats/package.js similarity index 100% rename from packages/jats/package.js rename to lib/jats/package.js diff --git a/packages/jats/paragraph/Paragraph.js b/lib/jats/paragraph/Paragraph.js similarity index 100% rename from packages/jats/paragraph/Paragraph.js rename to lib/jats/paragraph/Paragraph.js diff --git a/packages/jats/paragraph/ParagraphComponent.js b/lib/jats/paragraph/ParagraphComponent.js similarity index 100% rename from packages/jats/paragraph/ParagraphComponent.js rename to lib/jats/paragraph/ParagraphComponent.js diff --git a/packages/jats/paragraph/ParagraphConverter.js b/lib/jats/paragraph/ParagraphConverter.js similarity index 100% rename from packages/jats/paragraph/ParagraphConverter.js rename to lib/jats/paragraph/ParagraphConverter.js diff --git a/packages/jats/paragraph/package.js b/lib/jats/paragraph/package.js similarity index 100% rename from packages/jats/paragraph/package.js rename to lib/jats/paragraph/package.js diff --git a/packages/jats/ref-list/RefList.js b/lib/jats/ref-list/RefList.js similarity index 100% rename from packages/jats/ref-list/RefList.js rename to lib/jats/ref-list/RefList.js diff --git a/packages/jats/ref-list/RefListComponent.js b/lib/jats/ref-list/RefListComponent.js similarity index 94% rename from packages/jats/ref-list/RefListComponent.js rename to lib/jats/ref-list/RefListComponent.js index a9a709aa7..1048e8983 100644 --- a/packages/jats/ref-list/RefListComponent.js +++ b/lib/jats/ref-list/RefListComponent.js @@ -1,5 +1,5 @@ import { Component } from 'substance' -import renderNodeComponent from '../../../util/renderNodeComponent' +import renderNodeComponent from '../../util/renderNodeComponent' class RefListComponent extends Component { didMount() { diff --git a/packages/jats/ref-list/RefListConverter.js b/lib/jats/ref-list/RefListConverter.js similarity index 96% rename from packages/jats/ref-list/RefListConverter.js rename to lib/jats/ref-list/RefListConverter.js index 89120d15c..214f469cd 100644 --- a/packages/jats/ref-list/RefListConverter.js +++ b/lib/jats/ref-list/RefListConverter.js @@ -1,5 +1,5 @@ import JATS from '../JATS' -import XMLIterator from '../../../util/XMLIterator' +import XMLIterator from '../../util/XMLIterator' let REFLIST_CONTENT = ['ref', 'ref-list'].concat(JATS.PARA_LEVEL) diff --git a/packages/jats/ref-list/_index.css b/lib/jats/ref-list/_index.css similarity index 100% rename from packages/jats/ref-list/_index.css rename to lib/jats/ref-list/_index.css diff --git a/packages/jats/ref-list/package.js b/lib/jats/ref-list/package.js similarity index 100% rename from packages/jats/ref-list/package.js rename to lib/jats/ref-list/package.js diff --git a/packages/jats/ref/Ref.js b/lib/jats/ref/Ref.js similarity index 100% rename from packages/jats/ref/Ref.js rename to lib/jats/ref/Ref.js diff --git a/packages/jats/ref/RefComponent.js b/lib/jats/ref/RefComponent.js similarity index 100% rename from packages/jats/ref/RefComponent.js rename to lib/jats/ref/RefComponent.js diff --git a/packages/jats/ref/RefConverter.js b/lib/jats/ref/RefConverter.js similarity index 100% rename from packages/jats/ref/RefConverter.js rename to lib/jats/ref/RefConverter.js diff --git a/packages/jats/ref/RefTarget.js b/lib/jats/ref/RefTarget.js similarity index 100% rename from packages/jats/ref/RefTarget.js rename to lib/jats/ref/RefTarget.js diff --git a/packages/jats/ref/_index.css b/lib/jats/ref/_index.css similarity index 100% rename from packages/jats/ref/_index.css rename to lib/jats/ref/_index.css diff --git a/packages/jats/ref/package.js b/lib/jats/ref/package.js similarity index 100% rename from packages/jats/ref/package.js rename to lib/jats/ref/package.js diff --git a/packages/jats/ref/refToHTML.js b/lib/jats/ref/refToHTML.js similarity index 100% rename from packages/jats/ref/refToHTML.js rename to lib/jats/ref/refToHTML.js diff --git a/packages/jats/section/Section.js b/lib/jats/section/Section.js similarity index 100% rename from packages/jats/section/Section.js rename to lib/jats/section/Section.js diff --git a/packages/jats/section/SectionComponent.js b/lib/jats/section/SectionComponent.js similarity index 100% rename from packages/jats/section/SectionComponent.js rename to lib/jats/section/SectionComponent.js diff --git a/packages/jats/section/SectionConverter.js b/lib/jats/section/SectionConverter.js similarity index 97% rename from packages/jats/section/SectionConverter.js rename to lib/jats/section/SectionConverter.js index 9607e0dfa..d88d44c2b 100644 --- a/packages/jats/section/SectionConverter.js +++ b/lib/jats/section/SectionConverter.js @@ -1,5 +1,5 @@ import JATS from '../JATS' -import XMLIterator from '../../../util/XMLIterator' +import XMLIterator from '../../util/XMLIterator' export default { diff --git a/packages/jats/section/_index.css b/lib/jats/section/_index.css similarity index 100% rename from packages/jats/section/_index.css rename to lib/jats/section/_index.css diff --git a/packages/jats/section/package.js b/lib/jats/section/package.js similarity index 100% rename from packages/jats/section/package.js rename to lib/jats/section/package.js diff --git a/packages/jats/subscript/Subscript.js b/lib/jats/subscript/Subscript.js similarity index 100% rename from packages/jats/subscript/Subscript.js rename to lib/jats/subscript/Subscript.js diff --git a/packages/jats/subscript/SubscriptConverter.js b/lib/jats/subscript/SubscriptConverter.js similarity index 100% rename from packages/jats/subscript/SubscriptConverter.js rename to lib/jats/subscript/SubscriptConverter.js diff --git a/packages/jats/subscript/_index.css b/lib/jats/subscript/_index.css similarity index 100% rename from packages/jats/subscript/_index.css rename to lib/jats/subscript/_index.css diff --git a/packages/jats/subscript/package.js b/lib/jats/subscript/package.js similarity index 100% rename from packages/jats/subscript/package.js rename to lib/jats/subscript/package.js diff --git a/packages/jats/superscript/Superscript.js b/lib/jats/superscript/Superscript.js similarity index 100% rename from packages/jats/superscript/Superscript.js rename to lib/jats/superscript/Superscript.js diff --git a/packages/jats/superscript/SuperscriptConverter.js b/lib/jats/superscript/SuperscriptConverter.js similarity index 100% rename from packages/jats/superscript/SuperscriptConverter.js rename to lib/jats/superscript/SuperscriptConverter.js diff --git a/packages/jats/superscript/_index.css b/lib/jats/superscript/_index.css similarity index 100% rename from packages/jats/superscript/_index.css rename to lib/jats/superscript/_index.css diff --git a/packages/jats/superscript/package.js b/lib/jats/superscript/package.js similarity index 100% rename from packages/jats/superscript/package.js rename to lib/jats/superscript/package.js diff --git a/packages/jats/table-wrap/TableWrap.js b/lib/jats/table-wrap/TableWrap.js similarity index 100% rename from packages/jats/table-wrap/TableWrap.js rename to lib/jats/table-wrap/TableWrap.js diff --git a/packages/jats/table-wrap/TableWrapComponent.js b/lib/jats/table-wrap/TableWrapComponent.js similarity index 100% rename from packages/jats/table-wrap/TableWrapComponent.js rename to lib/jats/table-wrap/TableWrapComponent.js diff --git a/packages/jats/table-wrap/TableWrapConverter.js b/lib/jats/table-wrap/TableWrapConverter.js similarity index 100% rename from packages/jats/table-wrap/TableWrapConverter.js rename to lib/jats/table-wrap/TableWrapConverter.js diff --git a/packages/jats/table-wrap/package.js b/lib/jats/table-wrap/package.js similarity index 100% rename from packages/jats/table-wrap/package.js rename to lib/jats/table-wrap/package.js diff --git a/packages/jats/table/Table.js b/lib/jats/table/Table.js similarity index 100% rename from packages/jats/table/Table.js rename to lib/jats/table/Table.js diff --git a/packages/jats/table/TableComponent.js b/lib/jats/table/TableComponent.js similarity index 100% rename from packages/jats/table/TableComponent.js rename to lib/jats/table/TableComponent.js diff --git a/packages/jats/table/TableConverter.js b/lib/jats/table/TableConverter.js similarity index 100% rename from packages/jats/table/TableConverter.js rename to lib/jats/table/TableConverter.js diff --git a/packages/jats/table/package.js b/lib/jats/table/package.js similarity index 100% rename from packages/jats/table/package.js rename to lib/jats/table/package.js diff --git a/packages/jats/title-group/TitleGroup.js b/lib/jats/title-group/TitleGroup.js similarity index 100% rename from packages/jats/title-group/TitleGroup.js rename to lib/jats/title-group/TitleGroup.js diff --git a/packages/jats/title-group/TitleGroupComponent.js b/lib/jats/title-group/TitleGroupComponent.js similarity index 90% rename from packages/jats/title-group/TitleGroupComponent.js rename to lib/jats/title-group/TitleGroupComponent.js index 4d4aed110..7353a5d30 100644 --- a/packages/jats/title-group/TitleGroupComponent.js +++ b/lib/jats/title-group/TitleGroupComponent.js @@ -1,5 +1,5 @@ import { Component } from 'substance' -import renderNodeComponent from '../../../util/renderNodeComponent' +import renderNodeComponent from '../../util/renderNodeComponent' class TitleGroupComponent extends Component { diff --git a/packages/jats/title-group/TitleGroupConverter.js b/lib/jats/title-group/TitleGroupConverter.js similarity index 95% rename from packages/jats/title-group/TitleGroupConverter.js rename to lib/jats/title-group/TitleGroupConverter.js index b193222c8..ce2b7730d 100644 --- a/packages/jats/title-group/TitleGroupConverter.js +++ b/lib/jats/title-group/TitleGroupConverter.js @@ -1,5 +1,5 @@ import JATS from '../JATS' -import XMLIterator from '../../../util/XMLIterator' +import XMLIterator from '../../util/XMLIterator' export default { diff --git a/packages/jats/title-group/package.js b/lib/jats/title-group/package.js similarity index 100% rename from packages/jats/title-group/package.js rename to lib/jats/title-group/package.js diff --git a/packages/jats/title/Title.js b/lib/jats/title/Title.js similarity index 100% rename from packages/jats/title/Title.js rename to lib/jats/title/Title.js diff --git a/packages/jats/title/TitleComponent.js b/lib/jats/title/TitleComponent.js similarity index 100% rename from packages/jats/title/TitleComponent.js rename to lib/jats/title/TitleComponent.js diff --git a/packages/jats/title/TitleConverter.js b/lib/jats/title/TitleConverter.js similarity index 100% rename from packages/jats/title/TitleConverter.js rename to lib/jats/title/TitleConverter.js diff --git a/packages/jats/title/_index.css b/lib/jats/title/_index.css similarity index 100% rename from packages/jats/title/_index.css rename to lib/jats/title/_index.css diff --git a/packages/jats/title/package.js b/lib/jats/title/package.js similarity index 100% rename from packages/jats/title/package.js rename to lib/jats/title/package.js diff --git a/packages/jats/xref/AddXRefCommand.js b/lib/jats/xref/AddXRefCommand.js similarity index 100% rename from packages/jats/xref/AddXRefCommand.js rename to lib/jats/xref/AddXRefCommand.js diff --git a/packages/jats/xref/AddXRefTool.js b/lib/jats/xref/AddXRefTool.js similarity index 100% rename from packages/jats/xref/AddXRefTool.js rename to lib/jats/xref/AddXRefTool.js diff --git a/packages/jats/xref/EditXRefCommand.js b/lib/jats/xref/EditXRefCommand.js similarity index 100% rename from packages/jats/xref/EditXRefCommand.js rename to lib/jats/xref/EditXRefCommand.js diff --git a/packages/jats/xref/EditXRefTool.js b/lib/jats/xref/EditXRefTool.js similarity index 100% rename from packages/jats/xref/EditXRefTool.js rename to lib/jats/xref/EditXRefTool.js diff --git a/packages/jats/xref/XRef.js b/lib/jats/xref/XRef.js similarity index 100% rename from packages/jats/xref/XRef.js rename to lib/jats/xref/XRef.js diff --git a/packages/jats/xref/XRefComponent.js b/lib/jats/xref/XRefComponent.js similarity index 100% rename from packages/jats/xref/XRefComponent.js rename to lib/jats/xref/XRefComponent.js diff --git a/packages/jats/xref/XRefConverter.js b/lib/jats/xref/XRefConverter.js similarity index 100% rename from packages/jats/xref/XRefConverter.js rename to lib/jats/xref/XRefConverter.js diff --git a/packages/jats/xref/XRefTargets.js b/lib/jats/xref/XRefTargets.js similarity index 100% rename from packages/jats/xref/XRefTargets.js rename to lib/jats/xref/XRefTargets.js diff --git a/packages/jats/xref/_edit-xref-tool.css b/lib/jats/xref/_edit-xref-tool.css similarity index 100% rename from packages/jats/xref/_edit-xref-tool.css rename to lib/jats/xref/_edit-xref-tool.css diff --git a/packages/jats/xref/_index.css b/lib/jats/xref/_index.css similarity index 100% rename from packages/jats/xref/_index.css rename to lib/jats/xref/_index.css diff --git a/packages/jats/xref/_scrollbar-highlights.css b/lib/jats/xref/_scrollbar-highlights.css similarity index 100% rename from packages/jats/xref/_scrollbar-highlights.css rename to lib/jats/xref/_scrollbar-highlights.css diff --git a/packages/jats/xref/_xref-targets.css b/lib/jats/xref/_xref-targets.css similarity index 100% rename from packages/jats/xref/_xref-targets.css rename to lib/jats/xref/_xref-targets.css diff --git a/packages/jats/xref/_xref.css b/lib/jats/xref/_xref.css similarity index 100% rename from packages/jats/xref/_xref.css rename to lib/jats/xref/_xref.css diff --git a/packages/jats/xref/getXRefTargets.js b/lib/jats/xref/getXRefTargets.js similarity index 100% rename from packages/jats/xref/getXRefTargets.js rename to lib/jats/xref/getXRefTargets.js diff --git a/packages/jats/xref/package.js b/lib/jats/xref/package.js similarity index 100% rename from packages/jats/xref/package.js rename to lib/jats/xref/package.js diff --git a/packages/publisher/Publisher.js b/lib/publisher/Publisher.js similarity index 100% rename from packages/publisher/Publisher.js rename to lib/publisher/Publisher.js diff --git a/packages/publisher/PublisherPackage.js b/lib/publisher/PublisherPackage.js similarity index 100% rename from packages/publisher/PublisherPackage.js rename to lib/publisher/PublisherPackage.js diff --git a/packages/publisher/PublisherTOCProvider.js b/lib/publisher/PublisherTOCProvider.js similarity index 100% rename from packages/publisher/PublisherTOCProvider.js rename to lib/publisher/PublisherTOCProvider.js diff --git a/packages/publisher/_index.css b/lib/publisher/_index.css similarity index 100% rename from packages/publisher/_index.css rename to lib/publisher/_index.css diff --git a/examples/tagging/README.md b/lib/tagging/README.md similarity index 100% rename from examples/tagging/README.md rename to lib/tagging/README.md diff --git a/packages/tagging/TaggingPackage.js b/lib/tagging/TaggingPackage.js similarity index 100% rename from packages/tagging/TaggingPackage.js rename to lib/tagging/TaggingPackage.js diff --git a/packages/tagging/aff/TagAffCommand.js b/lib/tagging/aff/TagAffCommand.js similarity index 100% rename from packages/tagging/aff/TagAffCommand.js rename to lib/tagging/aff/TagAffCommand.js diff --git a/packages/tagging/aff/TagAffTool.js b/lib/tagging/aff/TagAffTool.js similarity index 100% rename from packages/tagging/aff/TagAffTool.js rename to lib/tagging/aff/TagAffTool.js diff --git a/packages/tagging/contrib/TagContribCommand.js b/lib/tagging/contrib/TagContribCommand.js similarity index 100% rename from packages/tagging/contrib/TagContribCommand.js rename to lib/tagging/contrib/TagContribCommand.js diff --git a/packages/tagging/contrib/TagContribTool.js b/lib/tagging/contrib/TagContribTool.js similarity index 100% rename from packages/tagging/contrib/TagContribTool.js rename to lib/tagging/contrib/TagContribTool.js diff --git a/packages/tagging/ref/TagRefCommand.js b/lib/tagging/ref/TagRefCommand.js similarity index 100% rename from packages/tagging/ref/TagRefCommand.js rename to lib/tagging/ref/TagRefCommand.js diff --git a/packages/tagging/ref/TagRefTool.js b/lib/tagging/ref/TagRefTool.js similarity index 100% rename from packages/tagging/ref/TagRefTool.js rename to lib/tagging/ref/TagRefTool.js diff --git a/examples/ExampleXMLStore.js b/lib/texture/ExampleXMLStore.js similarity index 79% rename from examples/ExampleXMLStore.js rename to lib/texture/ExampleXMLStore.js index 25f03d700..9ea043a0d 100644 --- a/examples/ExampleXMLStore.js +++ b/lib/texture/ExampleXMLStore.js @@ -2,20 +2,22 @@ import { request } from 'substance' class ExampleXMLStore { + constructor(data) { + this.data = data + } + readXML(documentId, cb) { let cached = localStorage.getItem(documentId) if (cached) { return cb(null, cached) } - request('GET', '../data/'+documentId+'.xml', null, cb) + cb(null, this.data[documentId]) } - // TODO make functional writeXML(documentId, xml, cb) { localStorage.setItem(documentId, xml) cb(null) } - } export default ExampleXMLStore diff --git a/packages/texture/FileClientStub.js b/lib/texture/FileClientStub.js similarity index 100% rename from packages/texture/FileClientStub.js rename to lib/texture/FileClientStub.js diff --git a/packages/texture/SaveHandlerStub.js b/lib/texture/SaveHandlerStub.js similarity index 100% rename from packages/texture/SaveHandlerStub.js rename to lib/texture/SaveHandlerStub.js diff --git a/packages/texture/Texture.js b/lib/texture/Texture.js similarity index 100% rename from packages/texture/Texture.js rename to lib/texture/Texture.js diff --git a/packages/texture/TextureConfigurator.js b/lib/texture/TextureConfigurator.js similarity index 77% rename from packages/texture/TextureConfigurator.js rename to lib/texture/TextureConfigurator.js index 98c480830..7851e128e 100644 --- a/packages/texture/TextureConfigurator.js +++ b/lib/texture/TextureConfigurator.js @@ -9,7 +9,7 @@ class TextureConfigurator extends Configurator { this.config.saveHandler = new SaveHandlerStub() this.config.fileClient = new FileClientStub() - this.config.XMLStoreClass = null + this.config.xmlStore = null this.config.InterfaceComponentClass = null } @@ -40,14 +40,18 @@ class TextureConfigurator extends Configurator { return this.config.saveHandler } - setXMLStore(XMLStoreClass) { - this.config.XMLStoreClass = XMLStoreClass + setXMLStore(XMLStoreClass, params) { + this.config.xmlStore = { + Class: XMLStoreClass, + params: params + } return this } getXMLStore() { - let XMLStoreClass = this.config.XMLStoreClass - return new XMLStoreClass() + let xmlStore = this.config.xmlStore + let XMLStoreClass = this.config.xmlStore.Class + return new XMLStoreClass(this.config.xmlStore.params) } } diff --git a/packages/texture/package.js b/lib/texture/package.js similarity index 100% rename from packages/texture/package.js rename to lib/texture/package.js diff --git a/packages/unsupported/UnsupportedInlineNode.js b/lib/unsupported/UnsupportedInlineNode.js similarity index 100% rename from packages/unsupported/UnsupportedInlineNode.js rename to lib/unsupported/UnsupportedInlineNode.js diff --git a/packages/unsupported/UnsupportedInlineNodeCommand.js b/lib/unsupported/UnsupportedInlineNodeCommand.js similarity index 100% rename from packages/unsupported/UnsupportedInlineNodeCommand.js rename to lib/unsupported/UnsupportedInlineNodeCommand.js diff --git a/packages/unsupported/UnsupportedInlineNodeComponent.js b/lib/unsupported/UnsupportedInlineNodeComponent.js similarity index 100% rename from packages/unsupported/UnsupportedInlineNodeComponent.js rename to lib/unsupported/UnsupportedInlineNodeComponent.js diff --git a/packages/unsupported/UnsupportedInlineNodeJATSConverter.js b/lib/unsupported/UnsupportedInlineNodeJATSConverter.js similarity index 100% rename from packages/unsupported/UnsupportedInlineNodeJATSConverter.js rename to lib/unsupported/UnsupportedInlineNodeJATSConverter.js diff --git a/packages/unsupported/UnsupportedInlineNodeTool.js b/lib/unsupported/UnsupportedInlineNodeTool.js similarity index 100% rename from packages/unsupported/UnsupportedInlineNodeTool.js rename to lib/unsupported/UnsupportedInlineNodeTool.js diff --git a/packages/unsupported/UnsupportedNode.js b/lib/unsupported/UnsupportedNode.js similarity index 100% rename from packages/unsupported/UnsupportedNode.js rename to lib/unsupported/UnsupportedNode.js diff --git a/packages/unsupported/UnsupportedNodeComponent.js b/lib/unsupported/UnsupportedNodeComponent.js similarity index 100% rename from packages/unsupported/UnsupportedNodeComponent.js rename to lib/unsupported/UnsupportedNodeComponent.js diff --git a/packages/unsupported/UnsupportedNodeJATSConverter.js b/lib/unsupported/UnsupportedNodeJATSConverter.js similarity index 100% rename from packages/unsupported/UnsupportedNodeJATSConverter.js rename to lib/unsupported/UnsupportedNodeJATSConverter.js diff --git a/packages/unsupported/UnsupportedNodePackage.js b/lib/unsupported/UnsupportedNodePackage.js similarity index 100% rename from packages/unsupported/UnsupportedNodePackage.js rename to lib/unsupported/UnsupportedNodePackage.js diff --git a/packages/unsupported/_index.css b/lib/unsupported/_index.css similarity index 100% rename from packages/unsupported/_index.css rename to lib/unsupported/_index.css diff --git a/util/XMLIterator.js b/lib/util/XMLIterator.js similarity index 100% rename from util/XMLIterator.js rename to lib/util/XMLIterator.js diff --git a/util/diff.html b/lib/util/diff.html similarity index 100% rename from util/diff.html rename to lib/util/diff.html diff --git a/util/getFullName.js b/lib/util/getFullName.js similarity index 100% rename from util/getFullName.js rename to lib/util/getFullName.js diff --git a/util/renderNodeComponent.js b/lib/util/renderNodeComponent.js similarity index 100% rename from util/renderNodeComponent.js rename to lib/util/renderNodeComponent.js diff --git a/util/toDOM.js b/lib/util/toDOM.js similarity index 100% rename from util/toDOM.js rename to lib/util/toDOM.js diff --git a/make.js b/make.js index 0fa02733d..306be5d2c 100644 --- a/make.js +++ b/make.js @@ -1,64 +1,35 @@ var b = require('substance-bundler') +var fs = require('fs') +var path = require('path') -b.task('clean', function() { - b.rm('./dist') -}) - -// copy assets -b.task('assets', function() { - b.copy('examples/index.html', './dist/') - b.copy('texture.css', './dist/') - b.copy('packages/**/*.css', './dist/') - b.copy('examples/data', './dist/data') - b.copy('node_modules/font-awesome', './dist/font-awesome') -}) - -// this optional task makes it easier to work on Substance core -b.task('substance', function() { - b.make('substance', 'clean', 'css', 'browser:pure') - b.copy('node_modules/substance/dist', './dist/substance') -}) - -b.task('substance:all', function() { - b.make('substance') -}) - -function buildExample(example) { - return function() { - b.copy('examples/'+example+'/index.html', './dist/'+example+'/') - b.copy('examples/'+example+'/*.css', './dist/'+example+'/', { root: 'examples/'+example }) - b.js('examples/'+example+'/app.js', { - // need buble if we want to minify later - buble: false, - external: ['substance'], - commonjs: { include: ['node_modules/lodash/**'] }, - targets: [{ - // useStrict: false, // need for Safari 9 to work - dest: './dist/'+example+'/app.js', - format: 'umd', moduleName: example, - }] - }) - } -} - -b.task('author', ['clean', 'substance', 'assets'], buildExample('author')) -b.task('publisher', ['clean', 'substance', 'assets'], buildExample('publisher')) -b.task('tagging', ['author'], buildExample('tagging')) -b.task('examples', ['author', 'publisher', 'tagging']) - -// build all examples -b.task('default', ['examples']) - +var DIST = 'dist/' +var NPM = '.npm/' +var NPMDIST = NPM+'dist/' var TEST ='.test/' -b.task('test:clean', function() { +b.task('test:server', function() { + // Cleanup b.rm(TEST) -}) + b.make('substance') -b.task('test:assets', function() { // TODO: it would be nice to treat such glob patterns // differently, so that we do not need to specify glob root b.copy('./node_modules/substance-test/dist/*', TEST, { root: './node_modules/substance-test/dist' }) + + b.js('./test/index.js', { + // buble necessary here, for nodejs + buble: true, + external: ['substance-test', 'substance'], + commonjs: { + include: [ + '/**/lodash/**', + '/**/substance-cheerio/**' + ] + }, + targets: [ + { dest: TEST+'tests.cjs.js', format: 'cjs' }, + ] + }) }) b.task('test:browser', function() { @@ -74,25 +45,98 @@ b.task('test:browser', function() { }) }) -b.task('test:server', function() { - b.js('./test/index.js', { - // buble necessary here, for nodejs - buble: true, - external: ['substance-test', 'substance'], - commonjs: { - include: [ - '/**/lodash/**', - '/**/substance-cheerio/**' - ] - }, - targets: [ - { dest: TEST+'tests.cjs.js', format: 'cjs' }, - ] +b.task('test', ['test:browser', 'test:server']) + +/* Development bundle */ +b.task('dev', function() { + _buildDist(DIST, false) +}) + +/* Prepare NPM bundle */ +b.task('npm', function() { + // Cleanup + b.rm(NPM) + _buildDist(NPMDIST, true) + + // Copy source + b.copy('index.es.js', NPM) + b.copy('lib/**/*.js', NPM) + + // Copy stuff + [ + 'package.json', + 'LICENSE.md', + 'README.md', + 'CHANGELOG.md', + 'make.js' + ].forEach(function(f) { + b.copy(f, NPM) }) }) -b.task('test', ['substance:all', 'test:clean', 'test:assets', 'test:browser', 'test:server']) +b.task('default', ['dev']) + +function _buildDist(DIST, transpileToES5) { + // Bundle Substance and Texture JS + _substanceJS(DIST+'substance', transpileToES5) + _textureJS(DIST, transpileToES5) + // Bundle CSS + b.css('texture.css', DIST+'texture.css') + // Copy assets + _distCopyAssets(DIST) +} + +function _substanceJS(DEST, transpileToES5) { + if (transpileToES5) { + b.make('substance', 'clean', 'css', 'browser') + } else { + b.make('substance', 'clean', 'css', 'browser:pure') + + } + b.copy('node_modules/substance/dist', DEST) +} + +function _textureJS(DEST, transpileToES5) { + b.js('./index.es.js', { + buble: transpileToES5, + external: ['substance'], + commonjs: { include: ['node_modules/lodash/**'] }, + targets: [{ + useStrict: !transpileToES5, + dest: DEST+'texture.js', + format: 'umd', moduleName: 'texture', sourceMapRoot: __dirname, sourceMapPrefix: 'texture' + }] + }) +} + +function _distCopyAssets(DIST) { + b.copy('./node_modules/font-awesome', DIST+'font-awesome') + + // Landing page + b.copy('./index.html', DIST+'index.html') + // Examples + b.copy('./examples', DIST+'examples') + + // Convert XML files to data.js + b.custom('Bundle XML files as data.js', { + src: ['data/*.xml'], + dest: DIST+'examples/data.js', + execute: function(files) { + let xmls = {} + files.forEach(function(f) { + let xml = fs.readFileSync(f, 'utf8') + let docId = path.basename(f, '.xml') + xmls[docId] = xml + }) + let out = [ + "window.XMLFILES = ", + JSON.stringify(xmls) + ].join('') + fs.writeFileSync(DIST+'examples/data.js', out) + } + }) +} // starts a server when CLI argument '-s' is set b.setServerPort(5555) diff --git a/package.json b/package.json index 7853adc8b..2a024c6f2 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "substance-scientist", + "name": "substance-scientist-tmp", "description": "A scientific editor and reader for JATS files.", "dependencies": { "lodash": "^4.14.1", @@ -7,7 +7,7 @@ }, "devDependencies": { "font-awesome": "4.5.0", - "substance-bundler": "0.4.26", + "substance-bundler": "0.5.0", "substance-test": "0.2.5" }, "scripts": { diff --git a/packages/tagging/README.md b/packages/tagging/README.md deleted file mode 100644 index 45c820a7f..000000000 --- a/packages/tagging/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Experimental UX for tagging - -The considered use-case is to start from a generated JATS file -e.g. from a DOCX converter. -The JATS content has structural issues, e.g., wrong section levels, detached figure captions, etc., which need to be corrected. - -The proposed UI let's the user select such content and apply certain tools that help to get from unstructured or wrong structured to well structured content. diff --git a/test/jats/createJATSConfigurator.js b/test/jats/createJATSConfigurator.js index a52c6c749..c03e0aad4 100644 --- a/test/jats/createJATSConfigurator.js +++ b/test/jats/createJATSConfigurator.js @@ -1,8 +1,8 @@ import { module } from './test' import { Configurator } from 'substance' -import JATSPackage from '../../packages/jats/package' -import InlineWrapperPackage from '../../packages/inline-wrapper/InlineWrapperPackage' -import UnsupportedNodePackage from '../../packages/unsupported/UnsupportedNodePackage' +import JATSPackage from '../../lib/jats/package' +import InlineWrapperPackage from '../../lib/inline-wrapper/InlineWrapperPackage' +import UnsupportedNodePackage from '../../lib/unsupported/UnsupportedNodePackage' export default function createJATSConfigurator() { var configurator = new Configurator(); diff --git a/test/jats/test.js b/test/jats/test.js index a081ccfd8..9533f3248 100644 --- a/test/jats/test.js +++ b/test/jats/test.js @@ -5,7 +5,7 @@ import includes from 'lodash/includes' import isArray from 'lodash/isArray' import { DefaultDOMElement } from 'substance' import createJATSConfigurator from './createJATSConfigurator' -import JATSImporter from '../../packages/jats/JATSImporter' +import JATSImporter from '../../lib/jats/JATSImporter' let _test = test.withExtension('withFixture', function(fixtureXML) { var tapeArgs = Array.prototype.slice.call(arguments, 1) diff --git a/texture.css b/texture.css index d78fad989..e47aa8b6a 100644 --- a/texture.css +++ b/texture.css @@ -1 +1 @@ -@import './packages/_index.css'; \ No newline at end of file +@import './lib/_index.css'; \ No newline at end of file From 2afef636d792aadf9ccd922ca1352f67f74a3b73 Mon Sep 17 00:00:00 2001 From: Michael Aufreiter Date: Fri, 7 Oct 2016 19:33:08 +0200 Subject: [PATCH 167/167] Get ready for the release. --- .gitignore | 1 + examples/author.html | 19 ++++++++----------- examples/publisher.html | 12 +++++------- examples/tagging.html | 14 ++++++-------- index.html | 2 +- make.js | 15 +++++++++------ package.json | 6 +++--- texture.css | 1 + 8 files changed, 34 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index 30c02690e..3ec74d1fc 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ dist node_modules .lock-wscript .test +.npm diff --git a/examples/author.html b/examples/author.html index 47d3423cb..19140ebd1 100644 --- a/examples/author.html +++ b/examples/author.html @@ -6,31 +6,28 @@