/* eslint-env qunit */
import window from 'global/window';
import document from 'global/document';
import sinon from 'sinon';
import * as Dom from '../../../src/js/utils/dom.js';
QUnit.module('dom');
QUnit.test('should create an element', function(assert) {
const div = Dom.createEl();
const span = Dom.createEl('span', {
innerHTML: 'fdsa'
}, {
'data-test': 'asdf'
});
assert.strictEqual(div.nodeName, 'DIV');
assert.strictEqual(span.nodeName, 'SPAN');
assert.strictEqual(span.getAttribute('data-test'), 'asdf');
assert.strictEqual(span.innerHTML, 'fdsa');
});
QUnit.test('should create an element, supporting textContent', function(assert) {
const span = Dom.createEl('span', {textContent: 'howdy'});
if (span.textContent) {
assert.strictEqual(span.textContent, 'howdy', 'works in browsers that support textContent');
} else {
assert.strictEqual(span.innerText, 'howdy', 'works in browsers that DO NOT support textContent');
}
});
QUnit.test('should create an element with content', function(assert) {
const span = Dom.createEl('span');
const div = Dom.createEl('div', undefined, undefined, span);
assert.strictEqual(div.firstChild, span);
});
QUnit.test('should insert an element first in another', function(assert) {
const el1 = document.createElement('div');
const el2 = document.createElement('div');
const parent = document.createElement('div');
Dom.prependTo(el1, parent);
assert.strictEqual(parent.firstChild, el1, 'inserts first into empty parent');
Dom.prependTo(el2, parent);
assert.strictEqual(parent.firstChild, el2, 'inserts first into parent with child');
});
QUnit.test('addClass()', function(assert) {
const el = document.createElement('div');
assert.expect(5);
Dom.addClass(el, 'test-class');
assert.strictEqual(el.className, 'test-class', 'adds a single class');
Dom.addClass(el, 'test-class');
assert.strictEqual(el.className, 'test-class', 'does not duplicate classes');
assert.throws(function() {
Dom.addClass(el, 'foo foo-bar');
}, 'throws when attempting to add a class with whitespace');
Dom.addClass(el, 'test2_className');
assert.strictEqual(el.className, 'test-class test2_className', 'adds second class');
Dom.addClass(el, 'FOO');
assert.strictEqual(el.className, 'test-class test2_className FOO', 'adds third class');
});
QUnit.test('removeClass()', function(assert) {
const el = document.createElement('div');
el.className = 'test-class test2_className FOO bar';
assert.expect(4);
Dom.removeClass(el, 'test-class');
assert.strictEqual(el.className, 'test2_className FOO bar', 'removes one class');
assert.throws(function() {
Dom.removeClass(el, 'test2_className bar');
}, 'throws when attempting to remove a class with whitespace');
Dom.removeClass(el, 'test2_className');
assert.strictEqual(el.className, 'FOO bar', 'removes another class');
Dom.removeClass(el, 'FOO');
assert.strictEqual(el.className, 'bar', 'removes another class');
});
QUnit.test('hasClass()', function(assert) {
const el = document.createElement('div');
el.className = 'test-class foo foo test2_className FOO bar';
assert.strictEqual(Dom.hasClass(el, 'test-class'), true, 'class detected');
assert.strictEqual(Dom.hasClass(el, 'foo'), true, 'class detected');
assert.strictEqual(Dom.hasClass(el, 'test2_className'), true, 'class detected');
assert.strictEqual(Dom.hasClass(el, 'FOO'), true, 'class detected');
assert.strictEqual(Dom.hasClass(el, 'bar'), true, 'class detected');
assert.strictEqual(Dom.hasClass(el, 'test2'),
false,
'valid substring - but not a class - correctly not detected');
assert.strictEqual(Dom.hasClass(el, 'className'),
false,
'valid substring - but not a class - correctly not detected');
assert.throws(function() {
Dom.hasClass(el, 'FOO bar');
}, 'throws when attempting to detect a class with whitespace');
});
QUnit.test('toggleClass()', function(assert) {
const el = Dom.createEl('div', {className: 'foo bar'});
const predicateToggles = [
{
toggle: 'foo',
predicate: true,
className: 'foo bar',
message: 'if predicate `true` matches state of the element, do nothing'
},
{
toggle: 'baz',
predicate: false,
className: 'foo bar',
message: 'if predicate `false` matches state of the element, do nothing'
},
{
toggle: 'baz',
predicate: true,
className: 'foo bar baz',
message: 'if predicate `true` differs from state of the element, add the class'
},
{
toggle: 'foo',
predicate: false,
className: 'bar baz',
message: 'if predicate `false` differs from state of the element, remove the class'
},
{
toggle: 'bar',
predicate: () => true,
className: 'bar baz',
message: 'if a predicate function returns `true`, ' +
'matching the state of the element, do nothing'
},
{
toggle: 'foo',
predicate: () => false,
className: 'bar baz',
message: 'if a predicate function returns `false`, matching ' +
'the state of the element, do nothing'
},
{
toggle: 'foo',
predicate: () => true,
className: 'bar baz foo',
message: 'if a predicate function returns `true`, ' +
'differing from state of the element, add the class'
},
{
toggle: 'foo',
predicate: () => false,
className: 'bar baz',
message: 'if a predicate function returns `false`, differing ' +
'from state of the element, remove the class'
},
{
toggle: 'foo',
predicate: Function.prototype,
className: 'bar baz foo',
message: 'if a predicate function returns `undefined` and ' +
'the element does not have the class, add the class'
},
{
toggle: 'bar',
predicate: Function.prototype,
className: 'baz foo',
message: 'if a predicate function returns `undefined` and the ' +
'element has the class, remove the class'
},
{
toggle: 'bar',
predicate: () => [],
className: 'baz foo bar',
message: 'if a predicate function returns a defined non-boolean ' +
'value and the element does not have the class, add the class'
},
{
toggle: 'baz',
predicate: () => 'this is incorrect',
className: 'foo bar',
message: 'if a predicate function returns a defined non-boolean value ' +
'and the element has the class, remove the class'
}
];
assert.expect(3 + predicateToggles.length);
Dom.toggleClass(el, 'bar');
assert.strictEqual(el.className, 'foo', 'toggles a class off, if present');
Dom.toggleClass(el, 'bar');
assert.strictEqual(el.className, 'foo bar', 'toggles a class on, if absent');
assert.throws(function() {
Dom.toggleClass(el, 'foo bar');
}, 'throws when attempting to toggle a class with whitespace');
predicateToggles.forEach(x => {
Dom.toggleClass(el, x.toggle, x.predicate);
assert.strictEqual(el.className, x.className, x.message);
});
});
QUnit.test('should set element attributes from object', function(assert) {
const el = document.createElement('div');
el.id = 'el1';
Dom.setAttributes(el, {'controls': true, 'data-test': 'asdf'});
assert.equal(el.getAttribute('id'), 'el1');
assert.equal(el.getAttribute('controls'), '');
assert.equal(el.getAttribute('data-test'), 'asdf');
});
QUnit.test('should read tag attributes from elements, including HTML5 in all browsers', function(assert) {
// Creating the source/track tags outside of the video tag prevents log errors
const tags = `