Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default switch behavior #33

Merged
merged 8 commits into from
Aug 23, 2013
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ <h1>Lorem ipsum</h1>
</header>

<div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. <a href="http://www.google.it">Sed cursus</a> ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. </p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. <a href="http://www.google.it">Sed <strong>test</strong> asdas</a> ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. </p>

<h2>
Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh
Expand Down
36 changes: 36 additions & 0 deletions spec/content.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
describe('Test content', function() {
describe('normalizeTags', function() {
var plain = $('<div>Plain <strong>text</strong><strong>block</strong> example snippet</div>')[0];
var plainWithSpace = $('<div>Plain <strong>text</strong> <strong>block</strong> example snippet</div>')[0];
var nested = $('<div>Nested <strong><em>text</em></strong><strong><em>block</em></strong> example snippet</div>')[0];
var nestedMixed = $('<div>Nested <strong>and mixed <em>text</em></strong><strong><em>block</em> <em>examples</em></strong> snippet</div>')[0];

it('should work with plain block', function() {
var expected = $('<div>Plain <strong>textblock</strong> example snippet</div>')[0];
var actual = plain.cloneNode(true);
content.normalizeTags(actual);
expect(actual.innerHTML).toEqual(expected.innerHTML);
});

it('should not merge tags if not consecutives', function() {
var expected = plainWithSpace.cloneNode(true);
var actual = plainWithSpace.cloneNode(true);
content.normalizeTags(actual);
expect(actual.innerHTML).toEqual(expected.innerHTML);
});

it('should work with nested blocks', function() {
var expected = $('<div>Nested <strong><em>textblock</em></strong> example snippet</div>')[0];
var actual = nested.cloneNode(true);
content.normalizeTags(actual);
expect(actual.innerHTML).toEqual(expected.innerHTML);
});

it('should work with nested blocks that mix other tags', function() {
var expected = $('<div>Nested <strong>and mixed <em>textblock</em> <em>examples</em></strong> snippet</div>')[0];
var actual = nestedMixed.cloneNode(true);
content.normalizeTags(actual);
expect(actual.innerHTML).toEqual(expected.innerHTML);
});
});
});
18 changes: 18 additions & 0 deletions spec/parser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,23 @@ describe("Test parser", function() {
expect(parser.isBeginningOfHost(oneWord, endContainer, 1)).toEqual(false);
});

it("isSameNode should fail when tags are different", function() {
var source = text.firstChild;
var target = link.firstChild;
expect(parser.isSameNode(target, source)).toEqual(false);
});

it("isSameNode should fail when attributes are different", function() {
var source = link.firstChild;
var target = link.firstChild.cloneNode(true);
target.setAttribute('key', 'value');
expect(parser.isSameNode(target, source)).toEqual(false);
});

it("isSameNode should work when nodes have same tag and attributes", function() {
var source = link.firstChild;
var target = link.firstChild.cloneNode(true);
expect(parser.isSameNode(target, source)).toEqual(true);
});
});

4 changes: 3 additions & 1 deletion src/behavior.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ var behavior = (function() {
return {
focus: function(element) {
log('Default focus behavior');
content.normalizeSpaces(element);
content.removeEmptyTags(element);
},

blur: function(element) {
log('Default blur behavior');
element.innerHTML = content.cleanInternals(element.innerHTML);
content.normalizeTags(element);
content.cleanInternals(element);
},

flow: function(element, action) {
Expand Down
56 changes: 52 additions & 4 deletions src/content.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,65 @@
var content = (function() {
return {
cleanInternals: function(htmlString) {
return htmlString.replace(/\u200B/g, '<br />');
normalizeTags: function(element) {
var i, j, node, sibling;

var fragment = document.createDocumentFragment();

for (i = 0; i < element.childNodes.length; i++) {
node = element.childNodes[i];
if(!node) continue;

if(node.nodeType === 1) {
sibling = node;
while((sibling = sibling.nextSibling) !== null) {
if(!parser.isSameNode(sibling, node))
break;

for(j = 0; j < sibling.childNodes.length; j++) {
node.appendChild(sibling.childNodes[j].cloneNode(true));
}

sibling.parentNode.removeChild(sibling);
}

this.normalizeTags(node);
}

fragment.appendChild(node.cloneNode(true));
}

while (element.firstChild) {
element.removeChild(element.firstChild);
}
element.appendChild(fragment);
},

cleanInternals: function(element) {
element.innerHTML = element.innerHTML.replace(/\u200B/g, '<br />');
},

normalizeSpaces: function(element) {
var firstChild = element.firstChild;

if(!firstChild) return;

if(firstChild.nodeType === 3) {
firstChild.nodeValue = firstChild.nodeValue.replace(/^(\s)/, '\u00A0');
}
else {
this.normalizeSpaces(firstChild);
}
},

removeEmptyTags: function(element) {
var i, len, node;

for (i = 0, len = element.childNodes.length; i < len; i++) {
node = element.childNodes[i];
if(node && (!node.textContent || string.trim(node.textContent) === '')) node.parentNode.removeChild(node);
if(node && !node.textContent) {
node.parentNode.removeChild(node);
}
}
}
};

})();
18 changes: 18 additions & 0 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,24 @@ var parser = (function() {
else
return container.childNodes[offset] === container.lastChild;
}
},

isSameNode: function(target, source) {
var i, len, attr;

if(target.nodeType !== source.nodeType)
return false;

if(target.nodeName !== source.nodeName)
return false;

for(i = 0, len = target.attributes.length; i < len; i++) {
attr = target.attributes[i];
if(source.getAttribute(attr.name) !== attr.value)
return false;
}

return true;
}
};
})();