X-Git-Url: https://git.mdrn.pl/fnpeditor.git/blobdiff_plain/a91d838aca2cb6b1330454a6e92616a73a2e1255..72dfc92f908add69b4d862e9b6c3107e2a8acd21:/modules/documentCanvas/canvas/canvas.js diff --git a/modules/documentCanvas/canvas/canvas.js b/modules/documentCanvas/canvas/canvas.js index d883835..e6b8135 100644 --- a/modules/documentCanvas/canvas/canvas.js +++ b/modules/documentCanvas/canvas/canvas.js @@ -115,7 +115,17 @@ $.extend(Canvas.prototype, { wrapperElement.after({text: suffixOutside}); return wrapperElement; }, - list: {} + getDocumentElement: function(from) { + if(from instanceof HTMLElement || from instanceof Text) { + return documentElement.wrap(from, this); + } + }, + getCursor: function() { + return new Cursor(this); + }, + + list: {}, + }); $.extend(Canvas.prototype.list, { @@ -135,7 +145,8 @@ $.extend(Canvas.prototype.list, { var place = 'before'; var canvas = this; - parent.children().forEach(function(element) { + parent.children().some(function(element) { + var _e = element; if(element.sameNode(params.element1)) place = 'inside'; if(place === 'inside') { @@ -147,15 +158,15 @@ $.extend(Canvas.prototype.list, { element.setWlxmlClass('item'); elementsToWrap.push(element); } - if(element.sameNode(params.element2)) - return false; + if(_e.sameNode(params.element2)) + return true; }); var listElement = documentElement.DocumentNodeElement.create({tag: 'div', klass: 'list-items' + (params.type === 'enum' ? '-enum' : '')}); var toret; if(parent.is('list')) { - listElement.wrap({tag: 'div', klass: 'item'}); + listElement.wrapWithNodeElement({tag: 'div', klass: 'item'}); toret = listElement.parent(); } else { toret = listElement; @@ -169,47 +180,167 @@ $.extend(Canvas.prototype.list, { }); }, extractItems: function(params) { + params = _.extend({merge: true}, params); var list = params.element1.parent(); if(!list.is('list') || !(list.sameNode(params.element2.parent()))) return false; var idx1 = list.childIndex(params.element1), idx2 = list.childIndex(params.element2), + precedingItems = [], extractedItems = [], succeedingItems = [], items = list.children(), + listIsNested = list.parent().getWlxmlClass() === 'item', i; - for(i = Math.min(idx1,idx2); i <= Math.max(idx1, idx2); i++) { - extractedItems.push(items[i]); - items[i].detach(); - } - for(i = i; i < items.length; i++) { - succeedingItems.push(items[i]); - items[i].detach(); + if(idx1 > idx2) { + var tmp = idx1; idx1 = idx2; idx2 = tmp; } - var last = list; - extractedItems.forEach(function(item) { - item.setWlxmlClass(null); // - last.after(item); - last = item; + items.forEach(function(item, idx) { + if(idx < idx1) + precedingItems.push(item); + else if(idx >= idx1 && idx <= idx2) { + extractedItems.push(item); + } + else { + succeedingItems.push(item); + } }); - if(list.children().length === 0) - list.detach(); - - if(succeedingItems.length > 0) { - var secondList = documentElement.DocumentNodeElement.create({tag: 'div', klass:'list-items'}, this); - last.after(secondList); - + var reference = listIsNested ? list.parent() : list; + if(succeedingItems.length === 0) { + var reference_orig = reference; + extractedItems.forEach(function(item) { + reference.after(item); + reference = item; + if(!listIsNested) + item.setWlxmlClass(null); + }); + if(precedingItems.length === 0) + reference_orig.detach(); + } else if(precedingItems.length === 0) { + extractedItems.forEach(function(item) { + reference.before(item); + if(!listIsNested) + item.setWlxmlClass(null); + }); + } else { + extractedItems.forEach(function(item) { + reference.after(item); + if(!listIsNested) + item.setWlxmlClass(null); + reference = item; + }); + var secondList = documentElement.DocumentNodeElement.create({tag: 'div', klass:'list-items'}, this), + toAdd = secondList; + + if(listIsNested) { + toAdd = secondList.wrapWithNodeElement({tag: 'div', klass:'item'}); + } succeedingItems.forEach(function(item) { secondList.append(item); }); + + reference.after(toAdd); + } + if(!params.merge && listIsNested) { + return this.extractItems({element1: extractedItems[0], element2: extractedItems[extractedItems.length-1]}); } + return true; + }, + areItemsOfTheSameList: function(params) { + var e1 = params.element1, + e2 = params.element2; + return e1.parent().sameNode(e2.parent()) + && e1.parent().is('list'); } }); + +var Cursor = function(canvas) { + this.canvas = canvas; +}; + +$.extend(Cursor.prototype, { + isSelecting: function() { + var selection = window.getSelection(); + return !selection.isCollapsed; + }, + isSelectingWithinElement: function() { + return this.isSelecting() && this.getSelectionStart().element.sameNode(this.getSelectionEnd().element); + }, + isSelectingSiblings: function() { + return this.isSelecting() && this.getSelectionStart().element.parent().sameNode(this.getSelectionEnd().element.parent()); + }, + getPosition: function() { + return this.getSelectionAnchor(); + }, + getSelectionStart: function() { + return this.getSelectionBoundry('start'); + }, + getSelectionEnd: function() { + return this.getSelectionBoundry('end'); + }, + getSelectionAnchor: function() { + return this.getSelectionBoundry('anchor'); + }, + getSelectionBoundry: function(which) { + var selection = window.getSelection(), + anchorElement = this.canvas.getDocumentElement(selection.anchorNode), + focusElement = this.canvas.getDocumentElement(selection.focusNode); + + if(which === 'anchor') { + return { + element: anchorElement, + offset: selection.anchorOffset + }; + } + + var element, + offset; + + if(anchorElement.parent().sameNode(focusElement.parent())) { + var parent = anchorElement.parent(), + anchorFirst = parent.childIndex(anchorElement) < parent.childIndex(focusElement); + if(anchorFirst) { + if(which === 'start') { + element = anchorElement; + offset = selection.anchorOffset; + } + else if(which === 'end') { + element = focusElement, + offset = selection.focusOffset; + } + } else { + if(which === 'start') { + element = focusElement, + offset = selection.focusOffset + } + else if(which === 'end') { + element = anchorElement; + offset = selection.anchorOffset; + } + } + } else { + // TODO: Handle order + if(which === 'start') { + element = anchorElement; + offset = selection.anchorOffset + } else { + element = focusElement; + offset = selection.focusOffset + } + } + + return { + element: element, + offset: offset + } + } +}) + return { fromXML: function(xml) { return new Canvas(xml);