X-Git-Url: https://git.mdrn.pl/fnpeditor.git/blobdiff_plain/5f121e33df901aa33a79b2896e79759da6411948..b54134dba23e4a09a31655ff6697eacb915659bb:/src/smartxml/fragments.js diff --git a/src/smartxml/fragments.js b/src/smartxml/fragments.js new file mode 100644 index 0000000..9bb92cc --- /dev/null +++ b/src/smartxml/fragments.js @@ -0,0 +1,120 @@ +define(function(require) { + +'use strict'; + +var $ = require('libs/jquery'), + _ = require('libs/underscore'); + + +var Fragment = function(document) { + this.document = document; +}; +$.extend(Fragment.prototype, { + isValid: function() { + return false; + } +}); + + +var NodeFragment = function(document, params) { + Fragment.call(this, document); + this.node = params.node; +}; +NodeFragment.prototype = Object.create(Fragment.prototype); +$.extend(NodeFragment.prototype, { + isValid: function() { + return this.document.containsNode(this.node); + } +}); + + +var CaretFragment = function(document, params) { + NodeFragment.call(this, document, params); + this.offset = params.offset; + +}; +CaretFragment.prototype = Object.create(NodeFragment.prototype); +$.extend(CaretFragment.prototype, { + isValid: function() { + /* globals Node */ + return NodeFragment.prototype.isValid.call(this) && + this.node.nodeType === Node.TEXT_NODE && + _.isNumber(this.offset); + } +}); + + + +var RangeFragment = function(document, params) { + Fragment.call(this, document); + + if(params.node1.sameNode(params.node2)) { + this.startNode = this.endNode = params.node1; + } else { + /*jshint bitwise: false*/ + /* globals Node */ + var node1First = params.node1.nativeNode.compareDocumentPosition(params.node2.nativeNode) & Node.DOCUMENT_POSITION_FOLLOWING; + (node1First ? ['start', 'end'] : ['end','start']).forEach(function(prefix, idx) { + this[prefix + 'Node'] = params['node'+(idx+1)]; + }.bind(this)); + } +}; +RangeFragment.prototype = Object.create(Fragment.prototype); +$.extend(RangeFragment.prototype, { + isValid: function() { + return this.document.containsNode(this.startNode) && this.document.containsNode(this.endNode); + }, + hasSiblingBoundries: function() { + return this.isValid() && this.startNode.isSiblingOf(this.endNode); + }, + boundriesSiblingParents: function() { + return this.startNode.document.getSiblingParents({ + node1: this.startNode, + node2: this.endNode + }); + }, + getCommonParent: function() { + var siblingParents = this.boundriesSiblingParents(); + if(siblingParents) { + return siblingParents.node1.parent(); + } + }, +}); + +var TextRangeFragment = function(document, params) { + var orderChanged; + + RangeFragment.call(this, document, params); + + if(this.startNode.sameNode(this.endNode)) { + this.startOffset = Math.min(params.offset1, params.offset2); + this.endOffset = Math.max(params.offset1, params.offset2); + } else { + orderChanged = !params.node1.sameNode(this.startNode); + this.startOffset = orderChanged ? params.offset2 : params.offset1; + this.endOffset = orderChanged ? params.offset1 : params.offset2; + } +}; +TextRangeFragment.prototype = Object.create(RangeFragment.prototype); +$.extend(TextRangeFragment.prototype, { + isValid: function() { + return RangeFragment.prototype.isValid.call(this) && + _.isNumber(this.startOffset) && + _.isNumber(this.endOffset); + } +}); + +var FragmentTypes = { + Fragment: Fragment, + NodeFragment: NodeFragment, + CaretFragment: CaretFragment, + RangeFragment: RangeFragment, + TextRangeFragment: TextRangeFragment +}; +_.values(FragmentTypes).forEach(function(Type) { + $.extend(Type.prototype, FragmentTypes); +}); + +return FragmentTypes; + +}); \ No newline at end of file