Socket
Socket
Sign inDemoInstall

undom

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

undom - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

register.js

159

dist/undom.js

@@ -7,2 +7,40 @@ (function (global, factory) {

function assign(obj, props) {
for (var i in props) obj[i] = props[i];
}
function toLower(str) {
return String(str).toLowerCase();
}
function createAttributeFilter(ns, name) {
return function (o) { return o.ns===ns && o.name===toLower(name); };
}
function splice(arr, item, add, byValueOnly) {
var i = arr ? findWhere(arr, item, true, byValueOnly) : -1;
if (~i) add ? arr.splice(i, 0, add) : arr.splice(i, 1);
return i;
}
function findWhere(arr, fn, returnIndex, byValueOnly) {
var i = arr.length;
while (i--) if (typeof fn==='function' && !byValueOnly ? fn(arr[i]) : arr[i]===fn) break;
return returnIndex ? i : arr[i];
}
/*
const NODE_TYPES = {
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
TEXT_NODE: 3,
CDATA_SECTION_NODE: 4,
ENTITY_REFERENCE_NODE: 5,
COMMENT_NODE: 6,
PROCESSING_INSTRUCTION_NODE: 7,
DOCUMENT_NODE: 9
};
*/
/** Create a minimally viable DOM Document

@@ -12,17 +50,2 @@ * @returns {Document} document

function undom() {
var NODE_TYPES = {
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
TEXT_NODE: 3,
CDATA_SECTION_NODE: 4,
ENTITY_REFERENCE_NODE: 5,
COMMENT_NODE: 6,
PROCESSING_INSTRUCTION_NODE: 7,
DOCUMENT_NODE: 9
};
function assign(obj, props) {
for (var i in props) obj[i] = props[i];
}
var Node = function Node(nodeType, nodeName) {

@@ -34,25 +57,29 @@ this.nodeType = nodeType;

Node.prototype.appendChild = function appendChild (child) {
child.remove();
child.parentNode = this;
this.childNodes.push(child);
if (this.children && child.nodeType===1) this.children.push(child);
this.childNodes.push(child);
};
Node.prototype.insertBefore = function insertBefore (child, ref) {
var i = this.childNodes.indexOf(ref);
if (~i) this.childNodes.splice(i, 0, child);
if (this.children && child.nodeType===1) {
while (i<this.childNodes.length && this.childNodes[i].nodeType!==1) i++;
if (i<this.childNodes.length) {
this.children.splice(this.children.indexOf(this.childNodes[i]), 0, child);
}
child.remove();
var i = splice(this.childNodes, ref, child);
if (!ref) this.appendChild(child);
else if (~i && child.nodeType===1) {
while (i<this.childNodes.length && (ref = this.childNodes[i]).nodeType!==1 || ref===child) i++;
if (ref) splice(this.children, ref, child);
}
};
Node.prototype.removeChild = function removeChild (child) {
var i = this.childNodes.indexOf(child);
if (~i) this.childNodes.splice(i, 1);
if (this.children && child.nodeType===1) {
i = this.children.indexOf(child);
if (~i) this.children.splice(this.children.indexOf(child), 1);
Node.prototype.replaceChild = function replaceChild (child, ref) {
if (ref.parentNode===this) {
this.insertBefore(child, ref);
ref.remove();
}
};
assign(Node, NODE_TYPES);
assign(Node.prototype, NODE_TYPES);
Node.prototype.removeChild = function removeChild (child) {
splice(this.childNodes, child);
if (child.nodeType===1) splice(this.children, child);
};
Node.prototype.remove = function remove () {
if (this.parentNode) this.parentNode.removeChild(this);
};

@@ -62,3 +89,3 @@

function TextNode(text) {
Node.call(this, 3, '#text'); // NODE_TYPES.TEXT_NODE
Node.call(this, 3, '#text'); // TEXT_NODE
this.textContent = this.nodeValue = text;

@@ -77,5 +104,6 @@ }

function Element(nodeType, nodeName) {
Node.call(this, nodeType || 1, nodeName); // NODE_TYPES.ELEMENT_NODE
Node.call(this, nodeType || 1, nodeName); // ELEMENT_NODE
this.attributes = [];
this.children = [];
this.__handlers = {};
}

@@ -86,2 +114,3 @@

Element.prototype.constructor = Element;
Element.prototype.setAttribute = function setAttribute (key, value) {

@@ -96,22 +125,33 @@ this.setAttributeNS(null, key, value);

};
Element.prototype.setAttributeNS = function setAttributeNS (ns, name, value) {
name = String(name).toLowerCase();
value = String(value);
var attr = this.attributes.filter( function (o) { return o.ns===ns && o.name===name; } )[0];
if (!attr) this.attributes.push({ ns: ns, name: name, value: value });
else attr.value = value;
var attr = findWhere(this.attributes, createAttributeFilter(ns, name));
if (!attr) this.attributes.push(attr = { ns: ns, name: name });
attr.value = String(value);
};
Element.prototype.getAttributeNS = function getAttributeNS (ns, name) {
var attr = this.attributes.filter( function (o) { return o.ns===ns && o.name===name; } )[0];
var attr = findWhere(this.attributes, createAttributeFilter(ns, name));
return attr && attr.value;
};
Element.prototype.removeAttributeNS = function removeAttributeNS (ns, name) {
var this$1 = this;
splice(this.attributes, createAttributeFilter(ns, name));
};
for (var i=this.attributes.length; i--; ) {
if (this$1.attributes[i].ns===ns && this$1.attributes[i].name===name) {
this$1.attributes.splice(i, 1);
return;
Element.prototype.addEventListener = function addEventListener (type, handler) {
(this.__handlers[toLower(type)] || (this.__handlers[toLower(type)] = [])).push(handler);
};
Element.prototype.removeEventListener = function removeEventListener (type, handler) {
splice(this.__handlers[toLower(type)], handler, 0, true);
};
Element.prototype.dispatchEvent = function dispatchEvent (event) {
var t = event.currentTarget = this,
c = event.cancelable,
l, i;
do {
l = t.__handlers[toLower(event.type)];
if (l) for (i=l.length; i--; ) {
if ((l[i](event)===false || event._end) && c) break;
}
}
} while (event.bubbles && !(c && event._stop) && (event.target=t=t.parentNode));
return !event.defaultPrevented;
};

@@ -136,2 +176,18 @@

var Event = function Event(type, opts) {
this.type = type;
this.bubbles = !!opts.bubbles;
this.cancelable = !!opts.cancelable;
};
Event.prototype.stopPropagation = function stopPropagation () {
this._stop = true;
};
Event.prototype.stopImmediatePropagation = function stopImmediatePropagation () {
this._end = this._stop = true;
};
Event.prototype.preventDefault = function preventDefault () {
this.defaultPrevented = true;
};
function createElement(type) {

@@ -141,2 +197,3 @@ return new Element(null, String(type).toUpperCase());

function createElementNS(ns, type) {

@@ -148,2 +205,3 @@ var element = createElement(type);

function createTextNode(text) {

@@ -153,13 +211,12 @@ return new TextNode(text);

function createDocument() {
var document = new Document();
assign(document, {
Document: Document, Node: Node, TextNode: TextNode, Element: Element,
createElement: createElement, createElementNS: createElementNS, createTextNode: createTextNode
});
document.documentElement = document;
document.appendChild(document.body = document.createElement('body'));
assign(document, document.defaultView = { document: document, Document: Document, Node: Node, TextNode: TextNode, Element: Element, Event: Event });
assign(document, { documentElement:document, createElement: createElement, createElementNS: createElementNS, createTextNode: createTextNode });
document.appendChild(document.body = createElement('body'));
return document;
}
return createDocument();

@@ -166,0 +223,0 @@ }

@@ -1,2 +0,2 @@

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.undom=e()}(this,function(){function t(){function t(t,e){for(var n in e)t[n]=e[n]}function e(t){return new c(null,String(t).toUpperCase())}function n(t,n){var i=e(n);return i.namespace=t,i}function i(t){return new u(t)}function o(){var o=new h;return t(o,{Document:h,Node:s,TextNode:u,Element:c,createElement:e,createElementNS:n,createTextNode:i}),o.documentElement=o,o.appendChild(o.body=o.createElement("body")),o}var r={ELEMENT_NODE:1,ATTRIBUTE_NODE:2,TEXT_NODE:3,CDATA_SECTION_NODE:4,ENTITY_REFERENCE_NODE:5,COMMENT_NODE:6,PROCESSING_INSTRUCTION_NODE:7,DOCUMENT_NODE:9},s=function(t,e){this.nodeType=t,this.nodeName=e,this.childNodes=[]};s.prototype.appendChild=function(t){this.children&&1===t.nodeType&&this.children.push(t),this.childNodes.push(t)},s.prototype.insertBefore=function(t,e){var n=this.childNodes.indexOf(e);if(~n&&this.childNodes.splice(n,0,t),this.children&&1===t.nodeType){for(;n<this.childNodes.length&&1!==this.childNodes[n].nodeType;)n++;n<this.childNodes.length&&this.children.splice(this.children.indexOf(this.childNodes[n]),0,t)}},s.prototype.removeChild=function(t){var e=this.childNodes.indexOf(t);~e&&this.childNodes.splice(e,1),this.children&&1===t.nodeType&&(e=this.children.indexOf(t),~e&&this.children.splice(this.children.indexOf(t),1))},t(s,r),t(s.prototype,r);var u=function(t){function e(e){t.call(this,3,"#text"),this.textContent=this.nodeValue=e}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(s),c=function(t){function e(e,n){t.call(this,e||1,n),this.attributes=[],this.children=[]}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setAttribute=function(t,e){this.setAttributeNS(null,t,e)},e.prototype.getAttribute=function(t){return this.getAttributeNS(null,t)},e.prototype.removeAttribute=function(t){this.removeAttributeNS(null,t)},e.prototype.setAttributeNS=function(t,e,n){e=String(e).toLowerCase(),n=String(n);var i=this.attributes.filter(function(n){return n.ns===t&&n.name===e})[0];i?i.value=n:this.attributes.push({ns:t,name:e,value:n})},e.prototype.getAttributeNS=function(t,e){var n=this.attributes.filter(function(n){return n.ns===t&&n.name===e})[0];return n&&n.value},e.prototype.removeAttributeNS=function(t,e){for(var n=this,i=this.attributes.length;i--;)if(n.attributes[i].ns===t&&n.attributes[i].name===e)return void n.attributes.splice(i,1)},e}(s),h=function(t){function e(){t.call(this,9,"#document")}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(c);return o()}return t});
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.undom=e()}(this,function(){function t(t,e){for(var n in e)t[n]=e[n]}function e(t){return String(t).toLowerCase()}function n(t,n){return function(o){return o.ns===t&&o.name===e(n)}}function o(t,e,n,o){var i=t?r(t,e,!0,o):-1;return~i&&(n?t.splice(i,0,n):t.splice(i,1)),i}function r(t,e,n,o){for(var r=t.length;r--&&("function"!=typeof e||o?t[r]!==e:!e(t[r])););return n?r:t[r]}function i(){function i(t){return new d(null,String(t).toUpperCase())}function u(t,e){var n=i(e);return n.namespace=t,n}function p(t){return new h(t)}function s(){var e=new a;return t(e,e.defaultView={document:e,Document:a,Node:c,TextNode:h,Element:d,Event:l}),t(e,{documentElement:e,createElement:i,createElementNS:u,createTextNode:p}),e.appendChild(e.body=i("body")),e}var c=function(t,e){this.nodeType=t,this.nodeName=e,this.childNodes=[]};c.prototype.appendChild=function(t){t.remove(),t.parentNode=this,this.childNodes.push(t),this.children&&1===t.nodeType&&this.children.push(t)},c.prototype.insertBefore=function(t,e){t.remove();var n=o(this.childNodes,e,t);if(e){if(~n&&1===t.nodeType){for(;n<this.childNodes.length&&1!==(e=this.childNodes[n]).nodeType||e===t;)n++;e&&o(this.children,e,t)}}else this.appendChild(t)},c.prototype.replaceChild=function(t,e){e.parentNode===this&&(this.insertBefore(t,e),e.remove())},c.prototype.removeChild=function(t){o(this.childNodes,t),1===t.nodeType&&o(this.children,t)},c.prototype.remove=function(){this.parentNode&&this.parentNode.removeChild(this)};var h=function(t){function e(e){t.call(this,3,"#text"),this.textContent=this.nodeValue=e}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(c),d=function(t){function i(e,n){t.call(this,e||1,n),this.attributes=[],this.children=[],this.__handlers={}}return t&&(i.__proto__=t),i.prototype=Object.create(t&&t.prototype),i.prototype.constructor=i,i.prototype.setAttribute=function(t,e){this.setAttributeNS(null,t,e)},i.prototype.getAttribute=function(t){return this.getAttributeNS(null,t)},i.prototype.removeAttribute=function(t){this.removeAttributeNS(null,t)},i.prototype.setAttributeNS=function(t,e,o){var i=r(this.attributes,n(t,e));i||this.attributes.push(i={ns:t,name:e}),i.value=String(o)},i.prototype.getAttributeNS=function(t,e){var o=r(this.attributes,n(t,e));return o&&o.value},i.prototype.removeAttributeNS=function(t,e){o(this.attributes,n(t,e))},i.prototype.addEventListener=function(t,n){(this.__handlers[e(t)]||(this.__handlers[e(t)]=[])).push(n)},i.prototype.removeEventListener=function(t,n){o(this.__handlers[e(t)],n,0,!0)},i.prototype.dispatchEvent=function(t){var n,o,r=t.currentTarget=this,i=t.cancelable;do if(n=r.__handlers[e(t.type)])for(o=n.length;o--&&(n[o](t)!==!1&&!t._end||!i););while(t.bubbles&&(!i||!t._stop)&&(t.target=r=r.parentNode));return!t.defaultPrevented},i}(c),a=function(t){function e(){t.call(this,9,"#document")}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e}(d),l=function(t,e){this.type=t,this.bubbles=!!e.bubbles,this.cancelable=!!e.cancelable};return l.prototype.stopPropagation=function(){this._stop=!0},l.prototype.stopImmediatePropagation=function(){this._end=this._stop=!0},l.prototype.preventDefault=function(){this.defaultPrevented=!0},s()}return i});
//# sourceMappingURL=undom.min.js.map
{
"name": "undom",
"amdName": "undom",
"version": "0.1.0",
"version": "0.2.0",
"description": "Minimally viable DOM Document implementation.",

@@ -62,4 +62,6 @@ "main": "dist/undom.js",

"rollup-plugin-buble": "^0.12.1",
"sinon": "^1.17.4",
"sinon-chai": "^2.8.0",
"uglify-js": "^2.6.2"
}
}

@@ -16,2 +16,12 @@ # undom

## Project Goals
Undom aims to find a sweet spot between size/performance and utility. The goal is to provide the simplest possible implementation of a DOM Document, such that libraries relying on the DOM can run in places where there isn't one available.
The intent to keep things as simple as possible means undom lacks some DOM features like HTML parsing & serialization, Web Components, etc. These features can be added through additional libraries.
---
## Installation

@@ -27,2 +37,17 @@

## Require Hook
In CommonJS environments, simply import `undom/register` to patch the global object with a singleton Document.
```js
require('undom/register');
// now you have a DOM.
document.createElement('div');
```
---
## Usage

@@ -40,1 +65,48 @@

```
---
## Recipe: Serialize to HTML
One task `undom` doesn't handle for you by default is HTML serialization. A proper implementation of this would be cumbersome to maintain and would rely heavily on getters and setters, which limits browser support. Below is a simple recipe for serializing an `undom` Element (Document, etc) to HTML.
#### Small & in ES2015:
```js
Element.prototype.toString = el => this.nodeType===3 ? enc(this.textContent) : (
'<'+this.nodeName.toLowerCase() + this.attributes.map(attr).join('') + '>' +
this.childNodes.map(serialize).join('') + '</'+this.nodeName.toLowerCase()+'>'
);
let attr = a => ` ${a.name}="${enc(a.value)}"`;
let enc = s => s.replace(/[&'"<>]/g, a => `&#${a};`);
```
#### ES3 Version
This also does pretty-printing.
```js
function serialize(el) {
if (el.nodeType===3) return el.textContent;
var name = String(el.nodeName).toLowerCase(),
str = '<'+name,
c, i;
for (i=0; i<el.attributes.length; i++) {
str += ' '+el.attributes[i].name+'="'+el.attributes[i].value+'"';
}
str += '>';
for (i=0; i<el.childNodes.length; i++) {
c = serialize(el.childNodes[i]);
if (c) str += '\n\t'+c.replace(/\n/g,'\n\t');
}
return str + (c?'\n':'') + '</'+name+'>';
}
function enc(s) {
return s.replace(/[&'"<>]/g, function(a){ return `&#${a};` });
}
```

@@ -0,2 +1,23 @@

import {
assign,
toLower,
splice,
findWhere,
createAttributeFilter
} from './util';
/*
const NODE_TYPES = {
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
TEXT_NODE: 3,
CDATA_SECTION_NODE: 4,
ENTITY_REFERENCE_NODE: 5,
COMMENT_NODE: 6,
PROCESSING_INSTRUCTION_NODE: 7,
DOCUMENT_NODE: 9
};
*/
/** Create a minimally viable DOM Document

@@ -6,17 +27,2 @@ * @returns {Document} document

export default function undom() {
const NODE_TYPES = {
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
TEXT_NODE: 3,
CDATA_SECTION_NODE: 4,
ENTITY_REFERENCE_NODE: 5,
COMMENT_NODE: 6,
PROCESSING_INSTRUCTION_NODE: 7,
DOCUMENT_NODE: 9
};
function assign(obj, props) {
for (let i in props) obj[i] = props[i];
}
class Node {

@@ -29,26 +35,30 @@ constructor(nodeType, nodeName) {

appendChild(child) {
child.remove();
child.parentNode = this;
this.childNodes.push(child);
if (this.children && child.nodeType===1) this.children.push(child);
this.childNodes.push(child);
}
insertBefore(child, ref) {
let i = this.childNodes.indexOf(ref);
if (~i) this.childNodes.splice(i, 0, child);
if (this.children && child.nodeType===1) {
while (i<this.childNodes.length && this.childNodes[i].nodeType!==1) i++;
if (i<this.childNodes.length) {
this.children.splice(this.children.indexOf(this.childNodes[i]), 0, child);
}
child.remove();
let i = splice(this.childNodes, ref, child);
if (!ref) this.appendChild(child);
else if (~i && child.nodeType===1) {
while (i<this.childNodes.length && (ref = this.childNodes[i]).nodeType!==1 || ref===child) i++;
if (ref) splice(this.children, ref, child);
}
}
removeChild(child) {
let i = this.childNodes.indexOf(child);
if (~i) this.childNodes.splice(i, 1);
if (this.children && child.nodeType===1) {
i = this.children.indexOf(child);
if (~i) this.children.splice(this.children.indexOf(child), 1);
replaceChild(child, ref) {
if (ref.parentNode===this) {
this.insertBefore(child, ref);
ref.remove();
}
}
removeChild(child) {
splice(this.childNodes, child);
if (child.nodeType===1) splice(this.children, child);
}
remove() {
if (this.parentNode) this.parentNode.removeChild(this);
}
}
assign(Node, NODE_TYPES);
assign(Node.prototype, NODE_TYPES);

@@ -58,3 +68,3 @@

constructor(text) {
super(3, '#text'); // NODE_TYPES.TEXT_NODE
super(3, '#text'); // TEXT_NODE
this.textContent = this.nodeValue = text;

@@ -67,6 +77,8 @@ }

constructor(nodeType, nodeName) {
super(nodeType || 1, nodeName); // NODE_TYPES.ELEMENT_NODE
super(nodeType || 1, nodeName); // ELEMENT_NODE
this.attributes = [];
this.children = [];
this.__handlers = {};
}
setAttribute(key, value) {

@@ -81,20 +93,33 @@ this.setAttributeNS(null, key, value);

}
setAttributeNS(ns, name, value) {
name = String(name).toLowerCase();
value = String(value);
let attr = this.attributes.filter( o => o.ns===ns && o.name===name )[0];
if (!attr) this.attributes.push({ ns, name, value });
else attr.value = value;
let attr = findWhere(this.attributes, createAttributeFilter(ns, name));
if (!attr) this.attributes.push(attr = { ns, name });
attr.value = String(value);
}
getAttributeNS(ns, name) {
let attr = this.attributes.filter( o => o.ns===ns && o.name===name )[0];
let attr = findWhere(this.attributes, createAttributeFilter(ns, name));
return attr && attr.value;
}
removeAttributeNS(ns, name) {
for (let i=this.attributes.length; i--; ) {
if (this.attributes[i].ns===ns && this.attributes[i].name===name) {
this.attributes.splice(i, 1);
return;
splice(this.attributes, createAttributeFilter(ns, name));
}
addEventListener(type, handler) {
(this.__handlers[toLower(type)] || (this.__handlers[toLower(type)] = [])).push(handler);
}
removeEventListener(type, handler) {
splice(this.__handlers[toLower(type)], handler, 0, true);
}
dispatchEvent(event) {
let t = event.currentTarget = this,
c = event.cancelable,
l, i;
do {
l = t.__handlers[toLower(event.type)];
if (l) for (i=l.length; i--; ) {
if ((l[i](event)===false || event._end) && c) break;
}
}
} while (event.bubbles && !(c && event._stop) && (event.target=t=t.parentNode));
return !event.defaultPrevented;
}

@@ -111,2 +136,20 @@ }

class Event {
constructor(type, opts) {
this.type = type;
this.bubbles = !!opts.bubbles;
this.cancelable = !!opts.cancelable;
}
stopPropagation() {
this._stop = true;
}
stopImmediatePropagation() {
this._end = this._stop = true;
}
preventDefault() {
this.defaultPrevented = true;
}
}
function createElement(type) {

@@ -116,2 +159,3 @@ return new Element(null, String(type).toUpperCase());

function createElementNS(ns, type) {

@@ -123,2 +167,3 @@ let element = createElement(type);

function createTextNode(text) {

@@ -128,14 +173,13 @@ return new TextNode(text);

function createDocument() {
let document = new Document();
assign(document, {
Document, Node, TextNode, Element,
createElement, createElementNS, createTextNode
});
document.documentElement = document;
document.appendChild(document.body = document.createElement('body'));
assign(document, document.defaultView = { document, Document, Node, TextNode, Element, Event });
assign(document, { documentElement:document, createElement, createElementNS, createTextNode });
document.appendChild(document.body = createElement('body'));
return document;
}
return createDocument();
}
import undom from '../src/undom';
import { expect } from 'chai';
import chai, { expect } from 'chai';
import { spy } from 'sinon';
import sinonChai from 'sinon-chai';
chai.use(sinonChai);

@@ -35,2 +38,62 @@ describe('undom', () => {

describe('#appendChild', () => {
it('should set parentNode', () => {
let child = document.createElement('span');
let parent = document.createElement('div');
parent.appendChild(child);
expect(child).to.have.property('parentNode', parent);
});
it('should insert into .children / .childNodes', () => {
let child = document.createElement('span');
let parent = document.createElement('div');
parent.appendChild(child);
expect(parent).to.have.property('childNodes').that.deep.equals([child]);
expect(parent).to.have.property('children').that.deep.equals([child]);
expect(child).to.have.property('parentNode', parent);
parent.appendChild(child);
expect(parent, 're-append').to.have.property('childNodes').that.deep.equals([child]);
expect(parent, 're-append').to.have.property('children').that.deep.equals([child]);
expect(child, 're-append').to.have.property('parentNode', parent);
});
it('should remove child from any current parentNode', () => {
let child = document.createElement('span');
let parent1 = document.createElement('div');
let parent2 = document.createElement('div');
parent1.appendChild(child);
expect(parent1.childNodes).to.eql([child]);
expect(child).to.have.property('parentNode', parent1);
parent2.appendChild(child);
expect(child, 'switch parentNode').to.have.property('parentNode', parent2);
expect(parent1.childNodes, 'old parent').to.eql([]);
expect(parent2.childNodes, 'new parent').to.eql([child]);
});
});
describe('#replaceChild()', () => {
it('should replace a child', () => {
let parent = document.createElement('div');
let child1 = document.createElement('child1');
let child2 = document.createElement('child2');
let child3 = document.createElement('child3');
let child4 = document.createElement('child4');
parent.appendChild(child1);
parent.appendChild(child2);
parent.appendChild(child3);
expect(parent).to.have.property('childNodes').eql([child1, child2, child3]);
expect(parent).to.have.property('children').eql([child1, child2, child3]);
parent.replaceChild(child4, child2);
expect(parent).to.have.property('childNodes').eql([child1, child4, child3]);
expect(parent).to.have.property('children').eql([child1, child4, child3]);
});
});
describe('#setAttribute()', () => {

@@ -71,3 +134,122 @@ it('should set a given named attribute', () => {

});
describe('#addEventListener', () => {
it('should append listener to event list', () => {
let el = document.createElement('div');
expect(el.__handlers).to.eql({});
let fn = () => {};
el.addEventListener('type', fn);
expect(el.__handlers).to.eql({ type: [fn] });
});
it('should allow duplicates', () => {
let el = document.createElement('div');
let fn = () => {};
el.addEventListener('type', fn);
el.addEventListener('type', fn);
expect(el.__handlers).to.eql({ type: [fn, fn] });
});
it('should normalize type', () => {
let el = document.createElement('div');
let fn = () => {};
el.addEventListener('TYPE', fn);
el.addEventListener('TyPe', fn);
el.addEventListener('type', fn);
expect(el.__handlers).to.eql({ type: [fn, fn, fn] });
});
});
describe('#removeEventListener', () => {
it('should remove existing listeners', () => {
let el = document.createElement('div');
let fn = () => {};
el.addEventListener('type', fn);
el.removeEventListener('type', fn);
expect(el.__handlers).to.eql({ type: [] });
});
it('should normalize type', () => {
let el = document.createElement('div');
let fn = () => {};
el.addEventListener('type', fn);
el.addEventListener('type', fn);
el.addEventListener('type', fn);
el.removeEventListener('TYPE', fn);
el.removeEventListener('TyPe', fn);
el.removeEventListener('type', fn);
expect(el.__handlers).to.eql({ type: [] });
});
it('should remove only one listener at a time', () => {
let el = document.createElement('div');
let fn = () => {};
el.addEventListener('type', fn);
el.addEventListener('type', fn);
el.removeEventListener('type', fn);
expect(el.__handlers).to.eql({ type: [fn] });
el.removeEventListener('type', fn);
expect(el.__handlers).to.eql({ type: [] });
});
});
describe('#dispatchEvent()', () => {
it('should invoke matched listener', () => {
let event = { type:'foo', cancelable:true, bubbles:true };
let el = document.createElement('div');
let fn = spy();
let fn2 = spy();
el.addEventListener('foo', fn);
el.addEventListener('bar', fn2);
el.dispatchEvent(event);
expect(fn).to.have.been.calledOnce;
expect(fn2).not.to.have.been.called;
});
it('should invoke multiple listeners', () => {
let event = { type:'foo', cancelable:true, bubbles:true };
let el = document.createElement('div');
let fn = spy();
el.addEventListener('foo', fn);
el.addEventListener('foo', fn);
el.addEventListener('foo', fn);
el.dispatchEvent(event);
expect(fn).to.have.been.calledThrice;
});
it('should bubble if enabled', () => {
let event = { type:'foo', cancelable:true, bubbles:true };
let child = document.createElement('div');
let parent = document.createElement('div');
parent.appendChild(child);
child.addEventListener('foo', child.fn = spy());
parent.addEventListener('foo', parent.fn = spy());
child.dispatchEvent(event);
expect(child.fn).to.have.been.calledOnce;
expect(parent.fn).to.have.been.calledOnce;
child.fn.reset();
parent.fn.reset();
parent.dispatchEvent(event);
expect(child.fn).not.to.have.been.called;
child.fn.reset();
parent.fn.reset();
event.bubbles = false;
child.addEventListener('foo', e => e._stop = true );
child.dispatchEvent(event);
expect(parent.fn).not.to.have.been.called;
});
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc