Skip to content

Commit

Permalink
Refactor postEditor#insertPost to handle more situations
Browse files Browse the repository at this point in the history
  * fix bug in post#cloneRange when range starts in list item
  * add assert.isPostSimilar, assert.isRenderTreeEqual, assert.isPositionEqual

Fix #249 #259
  • Loading branch information
bantic committed Dec 15, 2015
1 parent 76b01fb commit 8b8ad0f
Show file tree
Hide file tree
Showing 17 changed files with 1,856 additions and 392 deletions.
3 changes: 1 addition & 2 deletions src/js/editor/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -754,8 +754,7 @@ class Editor {
let pastedPost = parsePostFromPaste(event, this.builder, this._parserPlugins);

this.run(postEditor => {
let nextPosition = postEditor.insertPost(position, pastedPost);
postEditor.setRange(new Range(nextPosition));
postEditor.insertPost(position, pastedPost);
});
}

Expand Down
71 changes: 29 additions & 42 deletions src/js/editor/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import mixin from '../utils/mixin';
import assert from '../utils/assert';
import { normalizeTagName } from '../utils/dom-utils';
import Range from '../utils/cursor/range';
import PostInserter from './post/post-inserter';

function isListSectionTagName(tagName) {
return tagName === 'ul' || tagName === 'ol';
Expand Down Expand Up @@ -720,6 +721,30 @@ class PostEditor {
return this.moveSectionBefore(collection, renderedSection, beforeSection);
}

// TODO write tests for this
insertMarkers(position, markers) {
let { section, offset } = position;
assert('Cannot insert markers at non-markerable position',
section.isMarkerable);

let edit = section.splitMarkerAtOffset2(offset);
edit.removed.forEach(marker => this._scheduleForRemoval(marker));
edit.added.forEach(marker => this._markDirty(marker));

let prevMarker = section.markerBeforeOffset(offset);
markers.forEach(marker => {
section.markers.insertAfter(marker, prevMarker);
offset += marker.length;
prevMarker = marker;
});

this._coalesceMarkers(section);
this._markDirty(section);

position.offset = offset;
return position;
}

insertText(position, text) {
let section = position.section;
if (!section.isMarkerable) {
Expand Down Expand Up @@ -1061,47 +1086,11 @@ class PostEditor {
* @method insertPost
* @param {Position} position
* @param {Post} post
* @return {Position} position at end of inserted content
* @private
*/
insertPost(position, newPost) {
if (newPost.isBlank) {
return position;
}
const post = this.editor.post;

let [preSplit, postSplit] = this.splitSection(position);
let nextPosition = position.clone();

newPost.sections.forEach((section, index) => {
if (index === 0 && preSplit.canJoin(section)) {
preSplit.join(section);
this._markDirty(preSplit);

nextPosition = preSplit.tailPosition();
} else {
section = section.clone();
this.insertSectionBefore(post.sections, section, postSplit);

nextPosition = section.tailPosition();
}
});

if (postSplit.isBlank) {
this.removeSection(postSplit);
}

if (preSplit.canJoin(postSplit) && preSplit.next === postSplit) {
nextPosition = preSplit.tailPosition();

preSplit.join(postSplit);
this._markDirty(preSplit);
this.removeSection(postSplit);
} else if (preSplit.isBlank) {
this.removeSection(preSplit);
}

return nextPosition;
let post = this.editor.post;
new PostInserter(this, post).insert(position, newPost);
}

/**
Expand Down Expand Up @@ -1184,16 +1173,14 @@ class PostEditor {
}

/**
* Flush any work on the queue. `editor.run` already does this, calling this
* Flush any work on the queue. `editor.run` already does this. Calling this
* method directly should not be needed outside `editor.run`.
*
* @method complete
* @private
*/
complete() {
if (this._didComplete) {
throw new Error('Post editing can only be completed once');
}
assert('Post editing can only be completed once', !this._didComplete);

this.runCallbacks(CALLBACK_QUEUES.BEFORE_COMPLETE);
this._didComplete = true;
Expand Down
Loading

0 comments on commit 8b8ad0f

Please sign in to comment.