X-Git-Url: https://git.mdrn.pl/fnpeditor.git/blobdiff_plain/471df249233a0064cdd3c4efe890536d8b304037..fc54b1e72b7ed4992bbc4a2ef3ae7f02393d174d:/src/editor/plugins/core/core.js diff --git a/src/editor/plugins/core/core.js b/src/editor/plugins/core/core.js index 5d3a57f..150464e 100644 --- a/src/editor/plugins/core/core.js +++ b/src/editor/plugins/core/core.js @@ -9,7 +9,9 @@ var _ = require('libs/underscore'), switchTo = require('plugins/core/switch'), lists = require('plugins/core/lists'), plugin = {name: 'core', actions: [], canvas: {}, documentExtension: {textNode: {}}}, - Dialog = require('views/dialog/dialog'); + Dialog = require('views/dialog/dialog'), + canvasElements = require('plugins/core/canvasElements'); + plugin.documentExtension.textNode.transformations = { @@ -31,15 +33,37 @@ plugin.documentExtension.textNode.transformations = { } }, mergeContentUp: function() { - var myPrev = this.prev(), + /* globals Node */ + var myPrev = this, + base = this, ret; - if(myPrev) { - ret = myPrev.append(this); + if(myPrev.nodeType === Node.TEXT_NODE) { + if(myPrev.getIndex() > 0) { + return; + } + myPrev = base = myPrev.parent(); + } + + myPrev = myPrev && myPrev.prev(); + + if(myPrev && myPrev.nodeType === Node.ELEMENT_NODE) { + var ptr = this, + next; + while(ptr) { + next = ptr.next(); + if(!ret) { + ret = myPrev.append(ptr); + } else { + myPrev.append(ptr); + } + + ptr = next; + } + if(base !== this) { + base.detach(); + } return {node: ret, offset: ret.sameNode(this) ? null : ret.getText().length - this.getText().length}; - } else { - var range = this.parent().unwrapContent(); - return {node: range.element1, offset: 0}; } } }; @@ -136,7 +160,7 @@ var commentAction = { params.fragment instanceof params.fragment.NodeFragment && !params.fragment.node.isRoot() }; if(state.allowed) { - state.description = gettext('Insert comment after current node'); + state.description = gettext('Insert comment'); } return state; } @@ -155,38 +179,81 @@ var createWrapTextAction = function(createParams) { }, parent; - if( - !params.fragment || !params.fragment.isValid() || - !(params.fragment instanceof params.fragment.TextRangeFragment) || - !params.fragment.hasSiblingBoundries()) { - return _.extend(state, {allowed: false}); - } - - parent = params.fragment.startNode.parent(); - if(parent && parent.is(createParams.klass) || parent.isInside(createParams.klass)) { + if(!params.fragment || !params.fragment.isValid()) { return _.extend(state, {allowed: false}); } - return _.extend(state, { - allowed: true, - description: createParams.description, - execute: function(callback, params) { - params.fragment.document.transaction(function() { - var parent = params.fragment.startNode.parent(); - return parent.wrapText({ - _with: {tagName: 'span', attrs: {'class': createParams.klass}}, - offsetStart: params.fragment.startOffset, - offsetEnd: params.fragment.endOffset, - textNodeIdx: [params.fragment.startNode.getIndex(), params.fragment.endNode.getIndex()] + if(params.fragment instanceof params.fragment.CaretFragment && params.fragment.node.isInside(createParams.klass)) { + return _.extend(state, { + allowed: true, + toggled: true, + description: createParams.unwrapDescription, + execute: function(callback, params) { + var node = params.fragment.node, + doc = node.document, + toRemove = node.getParent(createParams.klass), + prefLen = 0; + + if(node.sameNode(toRemove.contents()[0]) && toRemove.isPrecededByTextNode()) { + prefLen = toRemove.prev().getText().length; + } + + doc.transaction(function() { + var ret = toRemove.unwrapContent(), + newFragment = params.fragment; + if(!newFragment.isValid()) { + newFragment = doc.createFragment(doc.CaretFragment, { + node: ret.element1, + offset: prefLen + params.fragment.offset + }); + } + return newFragment; + }, { + metadata: { + description: createParams.unwrapDescription + }, + success: callback }); - }, { - metadata: { - description: createParams.description - }, - success: callback - }); + } + }); + } + + if(params.fragment instanceof params.fragment.TextRangeFragment && params.fragment.hasSiblingBoundries()) { + parent = params.fragment.startNode.parent(); + if(parent && parent.is(createParams.klass) || parent.isInside(createParams.klass)) { + return _.extend(state, {allowed: false}); } - }); + + return _.extend(state, { + allowed: true, + description: createParams.wrapDescription, + execute: function(callback, params) { + params.fragment.document.transaction(function() { + var parent = params.fragment.startNode.parent(), + doc = params.fragment.document, + wrapper, lastTextNode; + + wrapper = parent.wrapText({ + _with: {tagName: 'span', attrs: {'class': createParams.klass}}, + offsetStart: params.fragment.startOffset, + offsetEnd: params.fragment.endOffset, + textNodeIdx: [params.fragment.startNode.getIndex(), params.fragment.endNode.getIndex()] + }); + + lastTextNode = wrapper.getLastTextNode(); + if(lastTextNode) { + return doc.createFragment(doc.CaretFragment, {node: lastTextNode, offset: lastTextNode.getText().length}); + } + }, { + metadata: { + description: createParams.wrapDescription + }, + success: callback + }); + } + }); + } + return _.extend(state, {allowed: false}); } }; }; @@ -280,7 +347,12 @@ var linkAction = { if(params.fragment instanceof params.fragment.CaretFragment) { if(params.fragment.node.isInside('link')) { - return {allowed: true, toggled: true, execute: editLink}; + return { + allowed: true, + toggled: true, + description: gettext('Edit link'), + execute: editLink + }; } } return {allowed: false}; @@ -292,8 +364,8 @@ plugin.actions = [ undoRedoAction('undo'), undoRedoAction('redo'), commentAction, - createWrapTextAction({name: 'emphasis', klass: 'emp', description: gettext('Mark as emphasized')}), - createWrapTextAction({name: 'cite', klass: 'cite', description: gettext('Mark as citation')}), + 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 ].concat(plugin.actions, templates.actions, footnote.actions, switchTo.actions, lists.actions); @@ -304,6 +376,8 @@ plugin.config = function(config) { templates.actions[0].params.template.options = config.templates; }; +plugin.canvasElements = canvasElements; + return plugin; }); \ No newline at end of file