From 8f3efc2235f836dd2b624d569d97a7ae0dad77ff Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aleksander=20=C5=81ukasz?= Date: Sun, 8 Dec 2013 16:17:02 +0100 Subject: [PATCH 1/1] editor: first take on plugins, core plugin with breakContent transformation --- src/editor/entrypoint.js | 4 +- src/editor/modules/data/data.js | 5 ++ .../modules/documentCanvas/canvas/keyboard.js | 2 +- src/editor/plugins/core/core.js | 31 ++++++++++ src/editor/plugins/core/core.test.js | 59 +++++++++++++++++++ src/fnpjs/runner.js | 12 +++- 6 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 src/editor/plugins/core/core.js create mode 100644 src/editor/plugins/core/core.test.js diff --git a/src/editor/entrypoint.js b/src/editor/entrypoint.js index 20460b3..ac19d6e 100644 --- a/src/editor/entrypoint.js +++ b/src/editor/entrypoint.js @@ -48,11 +48,13 @@ '../fnpjs/runner', 'rng', './modules', + 'plugins/core/core', 'libs/bootstrap' - ], function($, runner, rng, modules) { + ], function($, runner, rng, modules, corePlugin) { $(function() { var app = new runner.Runner(rng, modules); app.setBootstrappedData('data', RNG_BOOTSTRAP_DATA); + app.registerPlugin(corePlugin); app.start({rootSelector:'#editor_root'}); }); }); diff --git a/src/editor/modules/data/data.js b/src/editor/modules/data/data.js index e90a1b6..006bf0f 100644 --- a/src/editor/modules/data/data.js +++ b/src/editor/modules/data/data.js @@ -18,6 +18,11 @@ return function(sandbox) { var wlxmlDocument = wlxml.WLXMLDocumentFromXML(sandbox.getBootstrappedData().document); wlxmlDocument.registerExtension(listExtension); + sandbox.getPlugins().forEach(function(plugin) { + if(plugin.documentExtension) { + wlxmlDocument.registerExtension(plugin.documentExtension); + } + }); function readCookie(name) { diff --git a/src/editor/modules/documentCanvas/canvas/keyboard.js b/src/editor/modules/documentCanvas/canvas/keyboard.js index 418dc93..e48917c 100644 --- a/src/editor/modules/documentCanvas/canvas/keyboard.js +++ b/src/editor/modules/documentCanvas/canvas/keyboard.js @@ -93,7 +93,7 @@ handlers.push({key: KEYS.ENTER, // gotoOptions = {caretTo: 'start'}; // } - var result = position.element.data('wlxmlNode').transform('rng.breakContent', {offset: position.offset}), + var result = position.element.data('wlxmlNode').breakContent({offset: position.offset}), goto, gotoOptions; if(result.emptyText) { goto = result.createdEmpty; diff --git a/src/editor/plugins/core/core.js b/src/editor/plugins/core/core.js new file mode 100644 index 0000000..718a985 --- /dev/null +++ b/src/editor/plugins/core/core.js @@ -0,0 +1,31 @@ +define(function(require) { + +'use strict'; + +var _ = require('libs/underscore'), + plugin = {documentExtension: {textNode: {}}}; + + +plugin.documentExtension.textNode.transformations = { + breakContent: { + impl: function(args) { + var node = this, + newNodes, emptyText; + newNodes = node.split({offset: args.offset}); + [newNodes.first, newNodes.second].some(function(newNode) { + if(!(newNode.contents().length)) { + emptyText = newNode.append({text: ''}); + return true; // break + } + }); + return _.extend(newNodes, {emptyText: emptyText}); + }, + getChangeRoot: function() { + return this.context.parent().parent(); + } + } +}; + +return plugin; + +}); \ No newline at end of file diff --git a/src/editor/plugins/core/core.test.js b/src/editor/plugins/core/core.test.js new file mode 100644 index 0000000..940e22e --- /dev/null +++ b/src/editor/plugins/core/core.test.js @@ -0,0 +1,59 @@ +define(function(require) { + +'use strict'; +/* globals describe, it */ + +var chai = require('libs/chai'), + wlxml = require('wlxml/wlxml'), + corePlugin = require('./core.js'), + expect = chai.expect; + +var getDocumentFromXML = function(xml, options) { + var doc = wlxml.WLXMLDocumentFromXML(xml, options || {}); + doc.registerExtension(corePlugin.documentExtension); + return doc; +}; + + +describe('Document extensions', function() { + describe('break content', function() { + it('break text into two nodes', function() { + var doc = getDocumentFromXML('
Alice
'), + textNode = doc.root.contents()[0].contents()[0]; + + var result = textNode.breakContent({offset:3}); + + var section = doc.root; + expect(section.contents().length).to.equal(2); + expect(section.contents()[0].contents()[0].getText()).to.equal('Ali'); + expect(section.contents()[1].contents()[0].getText()).to.equal('ce'); + + expect(result.first.sameNode(section.contents()[0])).to.equal(true); + expect(result.second.sameNode(section.contents()[1])).to.equal(true); + expect(result.emptyText).to.equal(undefined, 'no new text node created'); + }); + it('puts empty text node when breaking at the very beginning', function() { + var doc = getDocumentFromXML('
Alice
'), + textNode = doc.root.contents()[0].contents()[0]; + + var result = textNode.breakContent({offset:0}), + firstNode = doc.root.contents()[0]; + + expect(result.emptyText.sameNode(firstNode.contents()[0])); + expect(result.emptyText.getText()).to.equal(''); + }); + it('puts empty text node when breaking at the very end', function() { + var doc = getDocumentFromXML('
Alice
'), + textNode = doc.root.contents()[0].contents()[0]; + + var result = textNode.breakContent({offset:5}), + secondNode = doc.root.contents()[1]; + + expect(result.emptyText.sameNode(secondNode.contents()[0])); + expect(result.emptyText.getText()).to.equal(''); + }); + }); +}); + + +}); \ No newline at end of file diff --git a/src/fnpjs/runner.js b/src/fnpjs/runner.js index 0da2916..eeef9f9 100644 --- a/src/fnpjs/runner.js +++ b/src/fnpjs/runner.js @@ -12,7 +12,8 @@ var Runner = function(app, modules) { var bootstrappedData = {}, options = {}, moduleInstances = {}, - eventListeners = []; + eventListeners = [], + plugins = []; _.each(_.keys(modules || {}), function(moduleName) { if(_.contains(app.permissions[moduleName] || [], 'handleEvents')) { @@ -53,13 +54,20 @@ var Runner = function(app, modules) { this.getDOM = _.contains(permissions, 'getDOM') ? function() { return $(options.rootSelector); } : undefined; - + + this.getPlugins = function() { + return plugins; + }; }; this.setBootstrappedData = function(moduleName, data) { bootstrappedData[moduleName] = data; }; + + this.registerPlugin = function(plugin) { + plugins.push(plugin); + }; this.start = function(_options) { options = _.extend({ -- 2.20.1