ember-introjs
Version:
An Ember Component for intro.js
453 lines (357 loc) • 15.3 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('simple-html-tokenizer')) :
typeof define === 'function' && define.amd ? define(['simple-html-tokenizer'], factory) :
(factory(global.HTML5Tokenizer));
}(this, (function (simpleHtmlTokenizer) { 'use strict';
var index$1 = typeof SimpleDOM === 'undefined' ? require('./simple-dom.js') : SimpleDOM;var Node = index$1.Node;
var Document = index$1.Document;
var HTMLParser = index$1.HTMLParser;
var HTMLSerializer = index$1.HTMLSerializer;
var voidMap = index$1.voidMap;
QUnit.module('Document');
QUnit.test("creating a document node", function(assert) {
var document = new Document();
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
assert.strictEqual(document.nodeType, 9, "document has node type of 9");
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeName
assert.strictEqual(document.nodeName, "#document", "document node has the name #document");
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeValue
assert.strictEqual(document.nodeValue, null, "for the document itself, nodeValue returns null");
});
QUnit.module('Element');
// See http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-core.html#ID-B63ED1A3
QUnit.test("appending a document fragment appends the fragment's children and not the fragment itself", function(assert) {
var document = new Document();
var frag = document.createDocumentFragment();
var elem = document.createElement('div');
var body = document.body;
assert.strictEqual(body.firstChild, null, "body has no children");
frag.appendChild(elem);
body.appendChild(frag);
assert.strictEqual(body.firstChild.tagName, "DIV", "fragment's child is added as child of document");
});
// See http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-core.html#ID-B63ED1A3
QUnit.test("appending a document fragment (via insertBefore) appends the fragment's children and not the fragment itself", function(assert) {
var document = new Document();
var frag = document.createDocumentFragment();
var elem = document.createElement('div');
var existing = document.createElement('main');
var body = document.body;
body.appendChild(existing);
assert.strictEqual(body.firstChild.tagName, "MAIN", "sanity check: the main element was actually inserted");
assert.strictEqual(body.lastChild.tagName, "MAIN", "sanity check: the main element was actually inserted");
frag.appendChild(elem);
body.insertBefore(frag, existing);
assert.strictEqual(body.firstChild.tagName, "DIV", "The body's first child is now DIV");
assert.strictEqual(body.lastChild.tagName, "MAIN", "The body's last child is now MAIN");
});
// http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-536297177
QUnit.test("child nodes can be access via item()", function(assert) {
var document = new Document();
var parent = document.createElement('div');
var child1 = document.createElement('p');
var child2 = document.createElement('img');
assert.strictEqual(parent.childNodes.item(0), null, "attempting to access an item that doesn't exist returns null");
parent.appendChild(child1);
parent.appendChild(child2);
assert.strictEqual(parent.childNodes.item(0), child1);
assert.strictEqual(parent.childNodes.item(1), child2);
assert.strictEqual(parent.childNodes.item(2), null);
parent.removeChild(child1);
assert.strictEqual(parent.childNodes.item(0), child2);
assert.strictEqual(parent.childNodes.item(1), null);
parent.removeChild(child2);
assert.strictEqual(parent.childNodes.item(0), null);
assert.strictEqual(parent.childNodes.item(1), null);
});
QUnit.test("insertBefore can insert before the last child node", function(assert) {
var document = new Document();
var parent = document.createElement('div');
var child1 = document.createElement('p');
var child2 = document.createElement('img');
var child3 = document.createElement('span');
parent.appendChild(child1);
parent.appendChild(child2);
parent.insertBefore(child3, child2);
assert.strictEqual(parent.childNodes.item(1), child3);
});
QUnit.test("insertBefore removes the node from its parent before inserting", function(assert) {
var document = new Document();
var body = document.body;
var parent = document.createElement('div');
var child = document.createElement('span');
parent.appendChild(child);
body.appendChild(parent);
assert.strictEqual(parent.firstChild, child, 'precond - parent.firstChild === child');
assert.strictEqual(parent.lastChild, child, 'precond - parent.lastChild === child');
assert.strictEqual(body.firstChild, parent, 'precond - body.firstChild === parent');
document.body.insertBefore(child, body.firstChild);
assert.strictEqual(body.firstChild, child, 'body firstChild replaced with child');
assert.strictEqual(child.parentNode, body, 'child parentNode updated to body');
assert.strictEqual(parent.firstChild, null, 'child removed from parent (firstChild)');
assert.strictEqual(parent.lastChild, null, 'child removed from parent (lastChild)');
});
QUnit.test("cloneNode(true) recursively clones nodes", function(assert) {
var document = new Document();
var parent = document.createElement('div');
var child1 = document.createElement('p');
var child2 = document.createElement('img');
child2.setAttribute('src', 'hamster.png');
var child3 = document.createElement('span');
parent.appendChild(child1);
parent.appendChild(child2);
parent.appendChild(child3);
var child11 = document.createTextNode('hello');
var child12 = document.createElement('span');
child12.appendChild(document.createTextNode(' world'));
var child13 = document.createTextNode('!');
child1.appendChild(child11);
child1.appendChild(child12);
child1.appendChild(child13);
var clone = parent.cloneNode(true);
assert.notEqual(parent.firstChild, null);
assert.notStrictEqual(clone.firstChild, parent.firstChild);
var clone2 = parent.cloneNode(true);
assert.notEqual(parent.firstChild, null);
assert.notStrictEqual(clone2.firstChild, clone.firstChild);
assert.notStrictEqual(clone2.firstChild, parent.firstChild);
var fragment = document.createDocumentFragment();
fragment.appendChild(clone);
var actual = new HTMLSerializer(voidMap).serialize(fragment);
assert.equal(actual, '<div><p>hello<span> world</span>!</p><img src="hamster.png"><span></span></div>');
});
QUnit.test("head + metatags", function(assert) {
var document = new Document();
var meta = document.createElement('meta');
meta.setAttribute('name', 'description');
meta.setAttribute('content', 'something here');
var head = document.head;
head.appendChild(meta);
var actual = new HTMLSerializer(voidMap).serialize(head.firstChild);
assert.strictEqual(head.firstChild.tagName, "META", "sanity check: the meta element was actually inserted");
assert.equal(actual, '<meta name="description" content="something here">');
});
QUnit.test("setAttribute converts non strings", function (assert) {
var document = new Document();
var div = document.createElement('div');
div.setAttribute('a', 0);
assert.strictEqual(div.getAttribute('a'), '0');
div.setAttribute('a', 1);
assert.strictEqual(div.getAttribute('a'), '1');
div.setAttribute('a', null);
assert.strictEqual(div.getAttribute('a'), 'null');
div.setAttribute('a', undefined);
assert.strictEqual(div.getAttribute('a'), 'undefined');
div.setAttribute('a', true);
assert.strictEqual(div.getAttribute('a'), 'true');
div.setAttribute('a', false);
assert.strictEqual(div.getAttribute('a'), 'false');
});
QUnit.module('Node');
QUnit.test("#insertBefore", function(assert) {
var body = new Node(1, 'body');
var div = new Node(1, 'div');
var span = new Node(1, 'span');
var ul = new Node(1, 'ul');
span.previousSibling = new Node(1, 'p');
var appendChildReturn = body.appendChild(div);
assert.strictEqual(appendChildReturn, div, 'appendChild should return the node it is appending');
body.insertBefore(span, div);
assert.strictEqual(span.parentNode, body, "nodes parent is set");
assert.strictEqual(span.previousSibling, null, "nodes previous sibling is cleared");
assert.strictEqual(span.nextSibling, div, "nodes next sibling is set");
assert.strictEqual(div.previousSibling, span, "next sibling's previous sibling is set");
assert.strictEqual(div.nextSibling, null, "next sibling's next sibling is set");
assert.strictEqual(div.parentNode, body, "next sibling's parent is set");
assert.strictEqual(body.firstChild, span, "parents first child is set");
assert.strictEqual(body.lastChild, div, "parents last child is set");
});
var document = (function (){
if (typeof window !== 'undefined' && window.document) {
return window.document;
}
return new Document();
}());
function element(tagName, attrs) {
var el = document.createElement(tagName);
for (var key in attrs) {
el.setAttribute(key, attrs[key]);
}
for (var i=2; i<arguments.length; i++) {
el.appendChild(arguments[i]);
}
return el;
}
function fragment() {
var frag = document.createDocumentFragment();
for (var i=0; i<arguments.length; i++) {
frag.appendChild(arguments[i]);
}
return frag;
}
function text(s) {
return document.createTextNode(s);
}
function html(s) {
return document.createRawHTMLSection(s);
}
QUnit.module('Basic HTML parsing', {
beforeEach: function() {
this.parser = new HTMLParser(simpleHtmlTokenizer.tokenize, document, voidMap);
}
});
QUnit.test('simple parse', function (assert) {
var fragment$$1 = this.parser.parse('<div>Hello</div>');
assert.ok(fragment$$1);
var node = fragment$$1.firstChild;
assert.ok(node);
assert.equal(node.nodeType, 1);
assert.equal(node.nodeName.toLowerCase(), 'div');
assert.ok(node.firstChild);
assert.equal(node.firstChild.nodeType, 3);
assert.equal(node.firstChild.nodeValue, 'Hello');
});
QUnit.test('nested parse', function (assert) {
var fragment$$1 = this.parser.parse('text before<div>Hello</div>text between<div id=foo title="Hello World">World</div>text after');
assert.ok(fragment$$1);
var node = fragment$$1.firstChild;
assert.ok(node);
assert.equal(node.nodeType, 3);
assert.equal(node.nodeValue, 'text before');
node = node.nextSibling;
assert.ok(node);
assert.equal(node.nodeType, 1);
assert.equal(node.nodeName, 'DIV');
assert.ok(node.firstChild);
assert.equal(node.firstChild.nodeType, 3);
assert.equal(node.firstChild.nodeValue, 'Hello');
node = node.nextSibling;
assert.ok(node);
assert.equal(node.nodeType, 3);
assert.equal(node.nodeValue, 'text between');
node = node.nextSibling;
assert.ok(node);
assert.equal(node.nodeType, 1);
assert.equal(node.nodeName, 'DIV');
var expectedValues = {
id: 'foo',
title: 'Hello World'
};
assert.equal(node.attributes.length, 2);
assert.equal(node.attributes[0].value, expectedValues[node.attributes[0].name]);
assert.equal(node.attributes[1].value, expectedValues[node.attributes[1].name]);
assert.equal(node.attributes.length, 2);
assert.ok(node.firstChild);
assert.equal(node.firstChild.nodeType, 3);
assert.equal(node.firstChild.nodeValue, 'World');
node = node.nextSibling;
assert.ok(node);
assert.equal(node.nodeType, 3);
assert.equal(node.nodeValue, 'text after');
});
QUnit.test('void tags', function (assert) {
var fragment$$1 = this.parser.parse('<div>Hello<br>World<img src="http://example.com/image.png"></div>');
assert.ok(fragment$$1);
var node = fragment$$1.firstChild;
assert.ok(node);
assert.equal(node.nodeType, 1);
assert.equal(node.nodeName, 'DIV');
node = node.firstChild;
assert.ok(node);
assert.equal(node.nodeType, 3);
assert.equal(node.nodeValue, 'Hello');
node = node.nextSibling;
assert.ok(node);
assert.equal(node.nodeType, 1);
assert.equal(node.nodeName, 'BR');
node = node.nextSibling;
assert.ok(node);
assert.equal(node.nodeType, 3);
assert.equal(node.nodeValue, 'World');
node = node.nextSibling;
assert.ok(node);
assert.equal(node.nodeType, 1);
assert.equal(node.nodeName, 'IMG');
assert.equal(node.getAttribute('src'), 'http://example.com/image.png');
assert.equal(node.nextSibling, null);
});
/*globals window*/
QUnit.module('Serializer', {
beforeEach: function() {
this.serializer = new HTMLSerializer(voidMap);
}
});
QUnit.test('serializes single element correctly', function (assert) {
var actual = this.serializer.serialize(element('div'));
assert.equal(actual, '<div></div>');
});
QUnit.test('serializes element with attribute number value correctly', function (assert) {
var actual = this.serializer.serialize(element('div', {"height": 500}));
assert.equal(actual, '<div height="500"></div>');
});
QUnit.test('serializes single void element correctly', function (assert) {
var actual = this.serializer.serialize(element('img', { src: 'foo' }));
assert.equal(actual, '<img src="foo">');
});
QUnit.test('serializes complex tree correctly', function (assert) {
var actual = this.serializer.serialize(fragment(
element('div', { id: 'foo' },
element('b', {},
text('Foo & Bar')
),
text('!'),
element('img', { src: 'foo' })
)
));
assert.equal(actual, '<div id="foo"><b>Foo & Bar</b>!<img src="foo"></div>');
});
QUnit.test('does not serialize siblings of an element', function (assert) {
var html$$1 = element('html');
var head = element('head');
var body = element('body');
head.appendChild(element('meta', { content: 'foo' }));
head.appendChild(element('meta', { content: 'bar' }));
html$$1.appendChild(head);
html$$1.appendChild(body);
var actual = this.serializer.serialize(head);
assert.equal(actual, '<head><meta content="foo"><meta content="bar"></head>');
actual = this.serializer.serialize(body);
assert.equal(actual, '<body></body>');
});
QUnit.test('serializes children but not self', function (assert) {
var actual = this.serializer.serializeChildren(fragment(
element('div', { id: 'foo' },
element('b', {},
text('Foo & Bar')
),
text('!'),
element('img', { src: 'foo' })
)
).firstChild);
assert.equal(actual, '<b>Foo & Bar</b>!<img src="foo">');
});
// SimpleDOM supports an extension of the DOM API that allows inserting strings of
// unparsed, raw HTML into the document. When the document is subsequently serialized,
// the raw text of the HTML nodes is inserted into the HTML.
//
// This performance optimization allows users of SimpleDOM (like Ember's FastBoot) to insert
// raw HTML snippets into the final serialized output without requiring a parsing and
// reserialization round-trip.
if (typeof window === 'undefined') {
QUnit.test('serializes raw HTML', function(assert) {
var actual = this.serializer.serialize(fragment(
element('div', { id: 'foo' },
text('<p></p>')
)
));
assert.equal(actual, '<div id="foo"><p></p></div>');
actual = this.serializer.serialize(fragment(
element('div', { id: 'foo' },
html('<p></p>')
)
));
assert.equal(actual, '<div id="foo"><p></p></div>');
});
}
})));
//# sourceMappingURL=simple-dom-test.js.map