Skip to content

Commit

Permalink
Use diff of prev/next marker's markups instead of assuming consistent…
Browse files Browse the repository at this point in the history
… order

fixes #51
  • Loading branch information
bantic committed Aug 10, 2015
1 parent de00376 commit 59b96ef
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 24 deletions.
31 changes: 8 additions & 23 deletions src/js/models/marker.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ export const MARKER_TYPE = 'marker';
import {
normalizeTagName
} from '../utils/dom-utils';
import { detect } from 'content-kit-editor/utils/array-utils';
import {
detect,
difference
} from 'content-kit-editor/utils/array-utils';

const Marker = class Marker {
constructor(value='', markups=[]) {
Expand Down Expand Up @@ -104,31 +107,13 @@ const Marker = class Marker {
}

get openedMarkups() {
if (!this.previousSibling) {
return this.markups.slice();
}
let i;
for (i=0; i<this.markups.length; i++) {
// FIXME this should iterate everything and return all things that are not
// on this marker -- it assumes the markups are always in the same order
if (this.markups[i] !== this.previousSibling.markups[i]) {
return this.markups.slice(i);
}
}
return [];
let previousMarkups = this.previousSibling && this.previousSibling.markups;
return difference(this.markups, previousMarkups || []);
}

get closedMarkups() {
if (!this.nextSibling) {
return this.markups.slice();
}
let i;
for (i=0; i<this.markups.length; i++) {
if (this.markups[i] !== this.nextSibling.markups[i]) {
return this.markups.slice(i);
}
}
return [];
let nextMarkups = this.nextSibling && this.nextSibling.markups;
return difference(this.markups, nextMarkups || []);
}

// FIXME this should be implemented as a linked list
Expand Down
18 changes: 17 additions & 1 deletion src/js/utils/array-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,24 @@ function forEach(enumerable, callback) {
}
}

/**
* @return {Array} The things in enumerable that are not in otherEnumerable,
* aka the relative complement of `otherEnumerable` in `enumerable`
*/
function difference(enumerable, otherEnumerable) {
const diff = [];
forEach(enumerable, (item) => {
if (otherEnumerable.indexOf(item) === -1) {
diff.push(item);
}
});

return diff;
}

export {
detect,
forEach,
any
any,
difference
};
34 changes: 34 additions & 0 deletions tests/unit/renderers/editor-dom-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,40 @@ test('rerender a marker after removing a markup from it (when both markers have
'<p>text1<b>text2</b></p>');
});

test('render when contiguous markers have out-of-order markups', (assert) => {
const post = builder.createPost();
const section = builder.createMarkupSection('p');

const b = builder.createMarkup('B'),
i = builder.createMarkup('I');

const markers = [
builder.createMarker('bi', [b,i]),
builder.createMarker('ib', [i,b]),
builder.createMarker('plain', [])
];
const m1 = markers[0];

markers.forEach(m => section.appendMarker(m));
post.appendSection(section);

let node = new RenderNode(post);
let renderTree = new RenderTree(node);
node.renderTree = renderTree;
render(renderTree);

assert.equal(node.element.innerHTML,
'<p><b><i>biib</i></b>plain</p>');

// remove 'b' from 1st marker, rerender
m1.removeMarkup(b);
m1.renderNode.markDirty();
render(renderTree);

assert.equal(node.element.innerHTML,
'<p><i>bi<b>ib</b></i>plain</p>');
});

/*
test("It renders a renderTree with rendered dirty section", (assert) => {
/*
Expand Down

0 comments on commit 59b96ef

Please sign in to comment.