Skip to content

Commit

Permalink
Allow markers to determine if they closing or opening markup
Browse files Browse the repository at this point in the history
  • Loading branch information
mixonic committed Jul 22, 2015
1 parent 0f69dc1 commit aec3812
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 59 deletions.
15 changes: 15 additions & 0 deletions src/js/models/marker.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ const Marker = class Marker {
}
return [];
}

// FIXME this should be implemented as a linked list
get nextSibling() {
let index = this.section.markers.indexOf(this);
if (index > -1 && index < this.section.markers.length-1) {
return this.section.markers[index + 1];
}
}

get previousSibling() {
let index = this.section.markers.indexOf(this);
if (index > 0) {
return this.section.markers[index - 1];
}
}
};

export default Marker;
1 change: 1 addition & 0 deletions src/js/models/markup-section.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default class Section {
}

appendMarker(marker) {
marker.section = this;
this.markers.push(marker);
}

Expand Down
8 changes: 4 additions & 4 deletions src/js/parsers/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,23 +79,23 @@ function parseMarkers(section, postBuilder, topNode) {

if (currentNode.firstChild) {
if (isValidMarkerElement(currentNode) && text !== null) {
section.markers.push(postBuilder.generateMarker(markups.slice(), text));
section.appendMarker(postBuilder.generateMarker(markups.slice(), text));
text = null;
}
currentNode = currentNode.firstChild;
} else if (currentNode.nextSibling) {
if (currentNode === topNode) {
section.markers.push(postBuilder.generateMarker(markups.slice(), text));
section.appendMarker(postBuilder.generateMarker(markups.slice(), text));
break;
} else {
currentNode = currentNode.nextSibling;
if (currentNode.nodeType === ELEMENT_NODE && isValidMarkerElement(currentNode) && text !== null) {
section.markers.push(postBuilder.generateMarker(markups.slice(), text));
section.appendMarker(postBuilder.generateMarker(markups.slice(), text));
text = null;
}
}
} else {
section.markers.push(postBuilder.generateMarker(markups.slice(), text));
section.appendMarker(postBuilder.generateMarker(markups.slice(), text));

while (currentNode && !currentNode.nextSibling && currentNode !== topNode) {
currentNode = currentNode.parentNode;
Expand Down
2 changes: 1 addition & 1 deletion src/js/parsers/mobiledoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export default class MobiledocParser {
this.markups.push(this.markerTypes[index]);
});
const marker = this.builder.generateMarker(this.markups.slice(), value);
section.markers.push(marker);
section.appendMarker(marker);
this.markups = this.markups.slice(0, this.markups.length-closeCount);
}
}
102 changes: 52 additions & 50 deletions tests/unit/parsers/dom-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ test('blank textnodes are ignored', (assert) => {
let post = parser.parse(buildDOM('<p>first line</p>\n<p>second line</p>'));

let expectedFirst = builder.generateMarkupSection('P');
expectedFirst.markers.push(builder.generateMarker([], 'first line'));
expectedFirst.appendMarker(builder.generateMarker([], 'first line'));
expectedPost.appendSection(expectedFirst);
let expectedSecond = builder.generateMarkupSection('P');
expectedSecond.markers.push(builder.generateMarker([], 'second line'));
expectedSecond.appendMarker(builder.generateMarker([], 'second line'));
expectedPost.appendSection(expectedSecond);

assert.deepEqual(post, expectedPost);
Expand All @@ -46,10 +46,10 @@ test('textnode adjacent to p tag becomes section', (assert) => {
const post = parser.parse(buildDOM('<p>first line</p>second line'));

let expectedFirst = builder.generateMarkupSection('P');
expectedFirst.markers.push(builder.generateMarker([], 'first line'));
expectedFirst.appendMarker(builder.generateMarker([], 'first line'));
expectedPost.appendSection(expectedFirst);
let expectedSecond = builder.generateMarkupSection('P', {}, true);
expectedSecond.markers.push(builder.generateMarker([], 'second line'));
expectedSecond.appendMarker(builder.generateMarker([], 'second line'));
expectedPost.appendSection(expectedSecond);

assert.deepEqual(post, expectedPost);
Expand All @@ -59,7 +59,7 @@ test('p tag (section markup) should create a block', (assert) => {
const post = parser.parse(buildDOM('<p>text</p>'));

let expectedFirst = builder.generateMarkupSection('P');
expectedFirst.markers.push(builder.generateMarker([], 'text'));
expectedFirst.appendMarker(builder.generateMarker([], 'text'));
expectedPost.appendSection(expectedFirst);

assert.deepEqual(post, expectedPost);
Expand All @@ -69,7 +69,7 @@ test('strong tag (stray markup) without a block should create a block', (assert)
const post = parser.parse(buildDOM('<strong>text</strong>'));

let expectedFirst = builder.generateMarkupSection('P', {}, true);
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
builder.generateMarkup('STRONG')
], 'text'));
expectedPost.appendSection(expectedFirst);
Expand All @@ -82,12 +82,12 @@ test('strong tag with inner em (stray markup) without a block should create a bl

let expectedFirst = builder.generateMarkupSection('P', {}, true);
let strong = builder.generateMarkup('STRONG');
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
strong,
builder.generateMarkup('EM')
], 'stray'));
expectedFirst.markers.push(builder.generateMarker([strong], ' markup tags'));
expectedFirst.markers.push(builder.generateMarker([], '.'));
expectedFirst.appendMarker(builder.generateMarker([strong], ' markup tags'));
expectedFirst.appendMarker(builder.generateMarker([], '.'));
expectedPost.appendSection(expectedFirst);

assert.deepEqual(post, expectedPost);
Expand All @@ -97,7 +97,7 @@ test('stray text (stray markup) should create a block', (assert) => {
const post = parser.parse(buildDOM('text'));

let expectedFirst = builder.generateMarkupSection('P', {}, true);
expectedFirst.markers.push(builder.generateMarker([], 'text'));
expectedFirst.appendMarker(builder.generateMarker([], 'text'));
expectedPost.appendSection(expectedFirst);

assert.deepEqual(post, expectedPost);
Expand All @@ -107,11 +107,11 @@ test('text node, strong tag, text node (stray markup) without a block should cre
const post = parser.parse(buildDOM('start <strong>bold</strong> end'));

let expectedFirst = builder.generateMarkupSection('P', {}, true);
expectedFirst.markers.push(builder.generateMarker([], 'start '));
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([], 'start '));
expectedFirst.appendMarker(builder.generateMarker([
builder.generateMarkup('STRONG')
], 'bold'));
expectedFirst.markers.push(builder.generateMarker([], ' end'));
expectedFirst.appendMarker(builder.generateMarker([], ' end'));
expectedPost.appendSection(expectedFirst);

assert.deepEqual(post, expectedPost);
Expand All @@ -121,7 +121,7 @@ test('italic tag (stray markup) without a block should create a block', (assert)
const post = parser.parse(buildDOM('<em>text</em>'));

let expectedFirst = builder.generateMarkupSection('P', {}, true);
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
builder.generateMarkup('EM')
], 'text'));
expectedPost.appendSection(expectedFirst);
Expand All @@ -133,7 +133,7 @@ test('u tag (stray markup) without a block should strip U and create a block', (
const post = parser.parse(buildDOM('<u>text</u>'));

let expectedFirst = builder.generateMarkupSection('P', {}, true);
expectedFirst.markers.push(builder.generateMarker([], 'text'));
expectedFirst.appendMarker(builder.generateMarker([], 'text'));
expectedPost.appendSection(expectedFirst);

assert.deepEqual(post, expectedPost);
Expand All @@ -144,7 +144,7 @@ test('a tag (stray markup) without a block should create a block', (assert) => {
const post = parser.parse(buildDOM('<a href="'+url+'">text</a>'));

let expectedFirst = builder.generateMarkupSection('P', {}, true);
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
builder.generateMarkup('A', ['href', url])
], 'text'));
expectedPost.appendSection(expectedFirst);
Expand All @@ -157,8 +157,8 @@ test('markup: break', (assert) => {
const post = parser.parse(buildDOM('line <br/>break'));
let expectedFirst = builder.generateMarkupSection('P', {}, true);
expectedFirst.markers.push(builder.generateMarker([], 0, 'line '));
expectedFirst.markers.push(builder.generateMarker([], 0, 'break'));
expectedFirst.appendMarker(builder.generateMarker([], 0, 'line '));
expectedFirst.appendMarker(builder.generateMarker([], 0, 'break'));
expectedPost.appendSection(expectedFirst);
assert.deepEqual(post, expectedPost);
Expand All @@ -169,8 +169,8 @@ test('sub tag (stray markup) without a block should filter SUB and create a bloc
const post = parser.parse(buildDOM('footnote<sub>1</sub>'));

let expectedFirst = builder.generateMarkupSection('P', {}, true);
expectedFirst.markers.push(builder.generateMarker([], 'footnote'));
expectedFirst.markers.push(builder.generateMarker([], '1'));
expectedFirst.appendMarker(builder.generateMarker([], 'footnote'));
expectedFirst.appendMarker(builder.generateMarker([], '1'));
expectedPost.appendSection(expectedFirst);

assert.deepEqual(post, expectedPost);
Expand All @@ -180,8 +180,8 @@ test('sup tag (stray markup) without a block should filter SUP and create a bloc
const post = parser.parse(buildDOM('e=mc<sup>2</sup>'));

let expectedFirst = builder.generateMarkupSection('P', {}, true);
expectedFirst.markers.push(builder.generateMarker([], 'e=mc'));
expectedFirst.markers.push(builder.generateMarker([], '2'));
expectedFirst.appendMarker(builder.generateMarker([], 'e=mc'));
expectedFirst.appendMarker(builder.generateMarker([], '2'));
expectedPost.appendSection(expectedFirst);

assert.deepEqual(post, expectedPost);
Expand All @@ -191,10 +191,10 @@ test('list (stray markup) without a block should create a block', (assert) => {
const post = parser.parse(buildDOM('<ul><li>Item 1</li><li>Item 2</li></ul>'));

let expectedFirst = builder.generateMarkupSection('UL');
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
builder.generateMarkup('LI')
], 'Item 1'));
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
builder.generateMarkup('LI')
], 'Item 2'));
expectedPost.appendSection(expectedFirst);
Expand All @@ -206,39 +206,41 @@ test('nested tags (section markup) should create a block', (assert) => {
const post = parser.parse(buildDOM('<p><em><strong>Double.</strong></em> <strong><em>Double staggered</em> start.</strong> <strong>Double <em>staggered end.</em></strong> <strong>Double <em>staggered</em> middle.</strong></p>'));

let expectedFirst = builder.generateMarkupSection('P');
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
builder.generateMarkup('EM'),
builder.generateMarkup('STRONG')
], 'Double.'));
expectedFirst.markers.push(builder.generateMarker([], ' '));
expectedFirst.appendMarker(builder.generateMarker([], ' '));
let firstStrong = builder.generateMarkup('STRONG');
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
firstStrong,
builder.generateMarkup('EM')
], 'Double staggered'));
expectedFirst.markers.push(builder.generateMarker([firstStrong], ' start.'));
expectedFirst.markers.push(builder.generateMarker([], ' '));
expectedFirst.appendMarker(builder.generateMarker([firstStrong], ' start.'));
expectedFirst.appendMarker(builder.generateMarker([], ' '));
let secondStrong = builder.generateMarkup('STRONG');
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
secondStrong
], 'Double '));
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
secondStrong,
builder.generateMarkup('EM')
], 'staggered end.'));
expectedFirst.markers.push(builder.generateMarker([], ' '));
expectedFirst.appendMarker(builder.generateMarker([], ' '));
let thirdStrong = builder.generateMarkup('STRONG');
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
thirdStrong
], 'Double '));
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
thirdStrong,
builder.generateMarkup('EM')
], 'staggered'));
expectedFirst.markers.push(builder.generateMarker([thirdStrong], ' middle.'));
expectedFirst.appendMarker(builder.generateMarker([thirdStrong], ' middle.'));
expectedPost.appendSection(expectedFirst);

assert.deepEqual(post, expectedPost);
let sectionMarkers = post.sections[0].markers;
assert.equal(sectionMarkers[2].markups[0], sectionMarkers[3].markups[0]);
});

/*
Expand Down Expand Up @@ -343,7 +345,7 @@ test('attributes', (assert) => {
const post = parser.parse(buildDOM(`<p><a href="${href}" rel="${rel}">Link to google.com</a></p>`));

let expectedFirst = builder.generateMarkupSection('P');
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
builder.generateMarkup('A', ['href', href, 'rel', rel])
], 'Link to google.com'));
expectedPost.appendSection(expectedFirst);
Expand All @@ -355,7 +357,7 @@ test('attributes filters out inline styles and classes', (assert) => {
const post = parser.parse(buildDOM('<p class="test" style="color:red;"><b style="line-height:11px">test</b></p>'));

let expectedFirst = builder.generateMarkupSection('P');
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
builder.generateMarkup('B')
], 'test'));
expectedPost.appendSection(expectedFirst);
Expand All @@ -367,7 +369,7 @@ test('blocks: paragraph', (assert) => {
const post = parser.parse(buildDOM('<p>TEXT</p>'));

let expectedFirst = builder.generateMarkupSection('P');
expectedFirst.markers.push(builder.generateMarker([], 'TEXT'));
expectedFirst.appendMarker(builder.generateMarker([], 'TEXT'));
expectedPost.appendSection(expectedFirst);

assert.deepEqual(post, expectedPost);
Expand All @@ -377,7 +379,7 @@ test('blocks: heading', (assert) => {
const post = parser.parse(buildDOM('<h2>TEXT</h2>'));

let expectedFirst = builder.generateMarkupSection('H2');
expectedFirst.markers.push(builder.generateMarker([], 'TEXT'));
expectedFirst.appendMarker(builder.generateMarker([], 'TEXT'));
expectedPost.appendSection(expectedFirst);

assert.deepEqual(post, expectedPost);
Expand All @@ -387,7 +389,7 @@ test('blocks: subheading', (assert) => {
const post = parser.parse(buildDOM('<h3>TEXT</h3>'));

let expectedFirst = builder.generateMarkupSection('H3');
expectedFirst.markers.push(builder.generateMarker([], 'TEXT'));
expectedFirst.appendMarker(builder.generateMarker([], 'TEXT'));
expectedPost.appendSection(expectedFirst);

assert.deepEqual(post, expectedPost);
Expand All @@ -412,7 +414,7 @@ test('blocks: quote', (assert) => {
const post = parser.parse(buildDOM('<blockquote>quote</blockquote>'));

let expectedFirst = builder.generateMarkupSection('BLOCKQUOTE');
expectedFirst.markers.push(builder.generateMarker([], 'quote'));
expectedFirst.appendMarker(builder.generateMarker([], 'quote'));
expectedPost.appendSection(expectedFirst);

assert.deepEqual(post, expectedPost);
Expand All @@ -422,11 +424,11 @@ test('blocks: list', (assert) => {
const post = parser.parse(buildDOM('<ul><li>Item 1</li> <li>Item 2</li></ul>'));

let expectedFirst = builder.generateMarkupSection('UL');
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
builder.generateMarkup('LI')
], 'Item 1'));
expectedFirst.markers.push(builder.generateMarker([], ' '));
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([], ' '));
expectedFirst.appendMarker(builder.generateMarker([
builder.generateMarkup('LI')
], 'Item 2'));
expectedPost.appendSection(expectedFirst);
Expand All @@ -438,11 +440,11 @@ test('blocks: ordered list', (assert) => {
const post = parser.parse(buildDOM('<ol><li>Item 1</li> <li>Item 2</li></ol>'));

let expectedFirst = builder.generateMarkupSection('OL');
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
builder.generateMarkup('LI')
], 'Item 1'));
expectedFirst.markers.push(builder.generateMarker([], ' '));
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([], ' '));
expectedFirst.appendMarker(builder.generateMarker([
builder.generateMarkup('LI')
], 'Item 2'));
expectedPost.appendSection(expectedFirst);
Expand Down Expand Up @@ -505,12 +507,12 @@ test('converts tags to mapped values', (assert) => {

let expectedFirst = builder.generateMarkupSection('P');
let bold = builder.generateMarkup('B');
expectedFirst.markers.push(builder.generateMarker([
expectedFirst.appendMarker(builder.generateMarker([
bold,
builder.generateMarkup('I')
], 'Converts'));
expectedFirst.markers.push(builder.generateMarker([bold], ' tags'));
expectedFirst.markers.push(builder.generateMarker([], '.'));
expectedFirst.appendMarker(builder.generateMarker([bold], ' tags'));
expectedFirst.appendMarker(builder.generateMarker([], '.'));
expectedPost.appendSection(expectedFirst);

assert.deepEqual(post, expectedPost);
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/parsers/mobiledoc-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ test('#parse doc without marker types', (assert) => {

let section = builder.generateMarkupSection('P', [], false);
let marker = builder.generateMarker([], 'hello world');
section.markers.push(marker);
section.appendMarker(marker);
post.appendSection(section);

assert.deepEqual(
Expand Down Expand Up @@ -69,7 +69,7 @@ test('#parse doc with marker type', (assert) => {
builder.generateMarker([aMarkerType, bMarkerType], 'brave new'),
builder.generateMarker([aMarkerType], 'world')
];
section.markers = markers;
markers.forEach(marker => section.appendMarker(marker));
post.appendSection(section);

assert.deepEqual(
Expand Down
Loading

0 comments on commit aec3812

Please sign in to comment.