editor: wip full backspace/insert support
[fnpeditor.git] / src / editor / plugins / core / core.js
index 450f147..0ac9cff 100644 (file)
@@ -8,9 +8,10 @@ var _ = require('libs/underscore'),
     footnote = require('plugins/core/footnote'),
     switchTo = require('plugins/core/switch'),
     lists = require('plugins/core/lists'),
-    plugin = {name: 'core', actions: [], canvas: {}, documentExtension: {textNode: {}}},
+    plugin = {name: 'core', actions: [], canvas: {}, documentExtension: {textNode: {}, elementNode: {}}},
     Dialog = require('views/dialog/dialog'),
-    canvasElements = require('plugins/core/canvasElements');
+    canvasElements = require('plugins/core/canvasElements'),
+    metadataEditor = require('plugins/core/metadataEditor/metadataEditor');
 
 
 
@@ -81,6 +82,87 @@ plugin.documentExtension.textNode.transformations = {
     }
 };
 
+plugin.documentExtension.elementNode.transformations = {
+    moveUp: function() {
+        var toMerge = this,
+            prev = toMerge.prev();
+
+        var merge = function(from, to) {
+            var toret;
+            from.contents().forEach(function(node, idx) {
+                var len, ret;
+                if(idx === 0 && node.nodeType === Node.TEXT_NODE) {
+                    len = node.getText().length;
+                }
+                ret = to.append(node);
+                
+                if(idx === 0) {
+                    toret = {
+                        node: ret,
+                        offset: ret.getText().length - len
+                    };
+                }
+            });
+            from.detach();
+            return toret;
+        };
+
+        var strategies = [
+            {
+                applies: function() {
+                    return toMerge.is('p');
+                },
+                run: function() {
+                    if(prev && prev.is('p') || prev.is({tagName: 'header'})) {
+                        return merge(toMerge, prev);
+                    }
+                    if(prev && prev.is('list')) {
+                        var items = prev.contents().filter(function(n) { return n.is('item');});
+                        return merge(toMerge, items[items.length-1]);
+                    }
+                }
+            },
+            {
+                applies: function() {
+                    return toMerge.is({tagName: 'header'});
+                },
+                run: function() {
+                    if(prev && prev.is('p') || prev.is({tagName: 'header'})) {
+                        return merge(toMerge, prev);
+                    }
+                }
+            },
+            {
+                applies: function() {
+                    return toMerge.is('item');
+                },
+                run: function() {
+                    var list;
+                    if(prev && prev.is('item')) {
+                        return merge(toMerge, prev);
+                    } else if(!prev && (list = toMerge.parent()) && list.is('list')) {
+                        list.before(toMerge);
+                        toMerge.setClass('p');
+                        if(!list.contents().length) {
+                            list.detach();
+                        }
+                        return {node: toMerge.contents()[0], offset:0};
+                    }
+                }
+            }
+        ];
+
+        var toret;
+        strategies.some(function(strategy) {
+            if(strategy.applies()) {
+                toret = strategy.run();
+                return true;
+            }
+        });
+        return toret;
+    }
+};
+
 var undoRedoAction = function(dir) {
     return {
         name: dir,
@@ -389,6 +471,7 @@ var linkAction = {
     }
 };
 
+var metadataParams = {};
 
 plugin.actions = [
     undoRedoAction('undo'),
@@ -396,7 +479,8 @@ plugin.actions = [
     commentAction,
     createWrapTextAction({name: 'emphasis', klass: 'emp', wrapDescription: gettext('Mark as emphasized'), unwrapDescription: gettext('Remove emphasis')}),
     createWrapTextAction({name: 'cite', klass: 'cite', wrapDescription: gettext('Mark as citation'), unwrapDescription: gettext('Remove citation')}),
-    linkAction
+    linkAction,
+    metadataEditor.action(metadataParams)
 ].concat(plugin.actions, templates.actions, footnote.actions, switchTo.actions, lists.actions);
 
 
@@ -404,6 +488,15 @@ plugin.actions = [
 plugin.config = function(config) {
     // templates.actions[0].config(config.templates);
     templates.actions[0].params.template.options = config.templates;
+    metadataParams.config = (config.metadata || []).sort(function(configRow1, configRow2) {
+        if(configRow1.key < configRow2.key) {
+            return -1;
+        }
+        if(configRow1.key > configRow2.key) {
+            return 1;
+        }
+        return 0;
+    });
 };
 
 plugin.canvasElements = canvasElements;