Skip to content

Commit e425075

Browse files
authored
Instantiable env (developit#25)
* Experiment: Re-enable instantiability by providing an undom.env() function that returns a new undom() factory with new prototypes. * fix whitespace from merge
1 parent f58a931 commit e425075

File tree

1 file changed

+164
-157
lines changed

1 file changed

+164
-157
lines changed

src/undom.js

Lines changed: 164 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -19,192 +19,199 @@ const NODE_TYPES = {
1919
};
2020
*/
2121

22+
function createEnvironment() {
2223

23-
function isElement(node) {
24-
return node.nodeType===1;
25-
}
26-
27-
class Node {
28-
constructor(nodeType, nodeName) {
29-
this.nodeType = nodeType;
30-
this.nodeName = nodeName;
31-
this.childNodes = [];
32-
}
33-
get nextSibling() {
34-
let p = this.parentNode;
35-
if (p) return p.childNodes[findWhere(p.childNodes, this, true, true) + 1];
36-
}
37-
get previousSibling() {
38-
let p = this.parentNode;
39-
if (p) return p.childNodes[findWhere(p.childNodes, this, true, true) - 1];
40-
}
41-
get firstChild() {
42-
return this.childNodes[0];
24+
function isElement(node) {
25+
return node.nodeType===1;
4326
}
44-
get lastChild() {
45-
return this.childNodes[this.childNodes.length-1];
46-
}
47-
appendChild(child) {
48-
this.insertBefore(child);
49-
return child;
50-
}
51-
insertBefore(child, ref) {
52-
child.remove();
53-
child.parentNode = this;
54-
if (ref) splice(this.childNodes, ref, child, true);
55-
else this.childNodes.push(child);
56-
return child;
57-
}
58-
replaceChild(child, ref) {
59-
if (ref.parentNode===this) {
60-
this.insertBefore(child, ref);
61-
ref.remove();
62-
return ref;
27+
28+
class Node {
29+
constructor(nodeType, nodeName) {
30+
this.nodeType = nodeType;
31+
this.nodeName = nodeName;
32+
this.childNodes = [];
33+
}
34+
get nextSibling() {
35+
let p = this.parentNode;
36+
if (p) return p.childNodes[findWhere(p.childNodes, this, true, true) + 1];
37+
}
38+
get previousSibling() {
39+
let p = this.parentNode;
40+
if (p) return p.childNodes[findWhere(p.childNodes, this, true, true) - 1];
41+
}
42+
get firstChild() {
43+
return this.childNodes[0];
44+
}
45+
get lastChild() {
46+
return this.childNodes[this.childNodes.length-1];
47+
}
48+
appendChild(child) {
49+
this.insertBefore(child);
50+
return child;
51+
}
52+
insertBefore(child, ref) {
53+
child.remove();
54+
child.parentNode = this;
55+
if (ref) splice(this.childNodes, ref, child, true);
56+
else this.childNodes.push(child);
57+
return child;
58+
}
59+
replaceChild(child, ref) {
60+
if (ref.parentNode===this) {
61+
this.insertBefore(child, ref);
62+
ref.remove();
63+
return ref;
64+
}
65+
}
66+
removeChild(child) {
67+
splice(this.childNodes, child, false, true);
68+
return child;
69+
}
70+
remove() {
71+
if (this.parentNode) this.parentNode.removeChild(this);
6372
}
6473
}
65-
removeChild(child) {
66-
splice(this.childNodes, child, false, true);
67-
return child;
68-
}
69-
remove() {
70-
if (this.parentNode) this.parentNode.removeChild(this);
71-
}
72-
}
7374

7475

75-
class Text extends Node {
76-
constructor(text) {
77-
super(3, '#text'); // TEXT_NODE
78-
this.nodeValue = text;
79-
}
80-
set textContent(text) {
81-
this.nodeValue = text;
82-
}
83-
get textContent() {
84-
return this.nodeValue;
76+
class Text extends Node {
77+
constructor(text) {
78+
super(3, '#text'); // TEXT_NODE
79+
this.nodeValue = text;
80+
}
81+
set textContent(text) {
82+
this.nodeValue = text;
83+
}
84+
get textContent() {
85+
return this.nodeValue;
86+
}
8587
}
86-
}
8788

8889

89-
class Element extends Node {
90-
constructor(nodeType, nodeName) {
91-
super(nodeType || 1, nodeName); // ELEMENT_NODE
92-
this.attributes = [];
93-
this.__handlers = {};
94-
this.style = {};
95-
}
90+
class Element extends Node {
91+
constructor(nodeType, nodeName) {
92+
super(nodeType || 1, nodeName); // ELEMENT_NODE
93+
this.attributes = [];
94+
this.__handlers = {};
95+
this.style = {};
96+
}
9697

97-
get className() { return this.getAttribute('class'); }
98-
set className(val) { this.setAttribute('class', val); }
98+
get className() { return this.getAttribute('class'); }
99+
set className(val) { this.setAttribute('class', val); }
99100

100-
get cssText() { return this.getAttribute('style'); }
101-
set cssText(val) { this.setAttribute('style', val); }
101+
get cssText() { return this.getAttribute('style'); }
102+
set cssText(val) { this.setAttribute('style', val); }
102103

103-
get children() {
104-
return this.childNodes.filter(isElement);
105-
}
104+
get children() {
105+
return this.childNodes.filter(isElement);
106+
}
106107

107-
setAttribute(key, value) {
108-
this.setAttributeNS(null, key, value);
109-
}
110-
getAttribute(key) {
111-
return this.getAttributeNS(null, key);
112-
}
113-
removeAttribute(key) {
114-
this.removeAttributeNS(null, key);
115-
}
108+
setAttribute(key, value) {
109+
this.setAttributeNS(null, key, value);
110+
}
111+
getAttribute(key) {
112+
return this.getAttributeNS(null, key);
113+
}
114+
removeAttribute(key) {
115+
this.removeAttributeNS(null, key);
116+
}
116117

117-
setAttributeNS(ns, name, value) {
118-
let attr = findWhere(this.attributes, createAttributeFilter(ns, name), false, false);
119-
if (!attr) this.attributes.push(attr = { ns, name });
120-
attr.value = String(value);
121-
}
122-
getAttributeNS(ns, name) {
123-
let attr = findWhere(this.attributes, createAttributeFilter(ns, name), false, false);
124-
return attr && attr.value;
125-
}
126-
removeAttributeNS(ns, name) {
127-
splice(this.attributes, createAttributeFilter(ns, name), false, false);
128-
}
118+
setAttributeNS(ns, name, value) {
119+
let attr = findWhere(this.attributes, createAttributeFilter(ns, name), false, false);
120+
if (!attr) this.attributes.push(attr = { ns, name });
121+
attr.value = String(value);
122+
}
123+
getAttributeNS(ns, name) {
124+
let attr = findWhere(this.attributes, createAttributeFilter(ns, name), false, false);
125+
return attr && attr.value;
126+
}
127+
removeAttributeNS(ns, name) {
128+
splice(this.attributes, createAttributeFilter(ns, name), false, false);
129+
}
129130

130-
addEventListener(type, handler) {
131-
(this.__handlers[toLower(type)] || (this.__handlers[toLower(type)] = [])).push(handler);
132-
}
133-
removeEventListener(type, handler) {
134-
splice(this.__handlers[toLower(type)], handler, false, true);
135-
}
136-
dispatchEvent(event) {
137-
let t = event.target = this,
138-
c = event.cancelable,
139-
l, i;
140-
do {
141-
event.currentTarget = t;
142-
l = t.__handlers && t.__handlers[toLower(event.type)];
143-
if (l) for (i=l.length; i--; ) {
144-
if ((l[i].call(t, event) === false || event._end) && c) {
145-
event.defaultPrevented = true;
131+
addEventListener(type, handler) {
132+
(this.__handlers[toLower(type)] || (this.__handlers[toLower(type)] = [])).push(handler);
133+
}
134+
removeEventListener(type, handler) {
135+
splice(this.__handlers[toLower(type)], handler, false, true);
136+
}
137+
dispatchEvent(event) {
138+
let t = event.target = this,
139+
c = event.cancelable,
140+
l, i;
141+
do {
142+
event.currentTarget = t;
143+
l = t.__handlers && t.__handlers[toLower(event.type)];
144+
if (l) for (i=l.length; i--; ) {
145+
if ((l[i].call(t, event) === false || event._end) && c) {
146+
event.defaultPrevented = true;
147+
}
146148
}
147-
}
148-
} while (event.bubbles && !(c && event._stop) && (t=t.parentNode));
149-
return l!=null;
149+
} while (event.bubbles && !(c && event._stop) && (t=t.parentNode));
150+
return l!=null;
151+
}
150152
}
151-
}
152153

153154

154-
class Document extends Element {
155-
constructor() {
156-
super(9, '#document'); // DOCUMENT_NODE
157-
}
155+
class Document extends Element {
156+
constructor() {
157+
super(9, '#document'); // DOCUMENT_NODE
158+
}
158159

159-
createElement(type) {
160-
return new Element(null, String(type).toUpperCase());
161-
}
160+
createElement(type) {
161+
return new Element(null, String(type).toUpperCase());
162+
}
162163

163-
createElementNS(ns, type) {
164-
let element = this.createElement(type);
165-
element.namespace = ns;
166-
return element;
167-
}
164+
createElementNS(ns, type) {
165+
let element = this.createElement(type);
166+
element.namespace = ns;
167+
return element;
168+
}
168169

169170

170-
createTextNode(text) {
171-
return new Text(text);
171+
createTextNode(text) {
172+
return new Text(text);
173+
}
172174
}
173-
}
174175

175176

176-
class Event {
177-
constructor(type, opts) {
178-
this.type = type;
179-
this.bubbles = !!(opts && opts.bubbles);
180-
this.cancelable = !!(opts && opts.cancelable);
181-
}
182-
stopPropagation() {
183-
this._stop = true;
184-
}
185-
stopImmediatePropagation() {
186-
this._end = this._stop = true;
187-
}
188-
preventDefault() {
189-
this.defaultPrevented = true;
177+
class Event {
178+
constructor(type, opts) {
179+
this.type = type;
180+
this.bubbles = !!(opts && opts.bubbles);
181+
this.cancelable = !!(opts && opts.cancelable);
182+
}
183+
stopPropagation() {
184+
this._stop = true;
185+
}
186+
stopImmediatePropagation() {
187+
this._end = this._stop = true;
188+
}
189+
preventDefault() {
190+
this.defaultPrevented = true;
191+
}
190192
}
191-
}
192193

193194

194-
/** Create a minimally viable DOM Document
195+
/** Create a minimally viable DOM Document
195196
* @returns {Document} document
196197
*/
197-
export default function createDocument() {
198-
let document = new Document();
199-
assign(document, document.defaultView = { document, Document, Node, Text, Element, SVGElement: Element, Event });
200-
document.appendChild(
201-
document.documentElement = document.createElement('html')
202-
);
203-
document.documentElement.appendChild(
204-
document.head = document.createElement('head')
205-
);
206-
document.documentElement.appendChild(
207-
document.body = document.createElement('body')
208-
);
209-
return document;
198+
function createDocument() {
199+
let document = new Document();
200+
assign(document, document.defaultView = { document, Document, Node, Text, Element, SVGElement: Element, Event });
201+
document.appendChild(
202+
document.documentElement = document.createElement('html')
203+
);
204+
document.documentElement.appendChild(
205+
document.head = document.createElement('head')
206+
);
207+
document.documentElement.appendChild(
208+
document.body = document.createElement('body')
209+
);
210+
return document;
211+
}
212+
213+
createDocument.env = createEnvironment;
214+
return createDocument;
210215
}
216+
217+
export default createEnvironment();

0 commit comments

Comments
 (0)