Skip to content

Commit 3c2574f

Browse files
committed
add support for one-time "serialize" callback functions
Kinda like a more explicit `context` variable
1 parent a7ea23a commit 3c2574f

File tree

2 files changed

+216
-127
lines changed

2 files changed

+216
-127
lines changed

index.js

Lines changed: 80 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -29,64 +29,92 @@ exports.serializeNodeList = serializeNodeList;
2929
*
3030
* @param {Node} node - DOM Node to serialize
3131
* @param {String} [context] - optional arbitrary "context" string to use (useful for event listeners)
32+
* @param {Function} [fn] - optional callback function to use in the "serialize" event for this call
3233
* return {String}
3334
* @public
3435
*/
3536

36-
function serialize (node, context) {
37+
function serialize (node, context, fn) {
3738
if (!node) return '';
38-
var nodeType = node.nodeType;
39+
if ('function' === typeof context) {
40+
fn = context;
41+
context = null;
42+
}
43+
if (!context) context = null;
3944

40-
if (!nodeType && 'number' === typeof node.length) {
41-
// assume it's a NodeList or Array of Nodes
42-
return exports.serializeNodeList(node);
45+
if ('function' === typeof fn) {
46+
// one-time "serialize" event listener
47+
node.addEventListener('serialize', fn, false);
4348
}
4449

45-
// emit a custom "serialize" event on `node`, in case there
46-
// are event listeners for custom serialization of this node
47-
var e = new CustomEvent('serialize', {
48-
bubbles: true,
49-
cancelable: true,
50-
detail: { serialize: null, context: context }
51-
});
50+
var rtn;
51+
var nodeType = node.nodeType;
5252

53-
var cancelled = !node.dispatchEvent(e);
54-
if (cancelled) return '';
55-
56-
// `e.detail.serialize` can be set to a:
57-
// String - returned directly
58-
// Node - goes through serializer logic instead of `node`
59-
// Anything else - get Stringified first, and then returned directly
60-
if (e.detail.serialize != null) {
61-
if ('string' === typeof e.detail.serialize) {
62-
return e.detail.serialize;
63-
} else if ('number' === typeof e.detail.serialize.nodeType) {
64-
// make it go through the serialization logic
65-
return serialize(e.detail.serialize);
66-
} else {
67-
return String(e.detail.serialize);
53+
if (!nodeType && 'number' === typeof node.length) {
54+
// assume it's a NodeList or Array of Nodes
55+
rtn = exports.serializeNodeList(node, context);
56+
} else {
57+
58+
// emit a custom "serialize" event on `node`, in case there
59+
// are event listeners for custom serialization of this node
60+
var e = new CustomEvent('serialize', {
61+
bubbles: true,
62+
cancelable: true,
63+
detail: {
64+
serialize: null,
65+
context: context
66+
}
67+
});
68+
69+
if (node.dispatchEvent(e)) {
70+
71+
// `e.detail.serialize` can be set to a:
72+
// String - returned directly
73+
// Node - goes through serializer logic instead of `node`
74+
// Anything else - get Stringified first, and then returned directly
75+
if (e.detail.serialize != null) {
76+
if ('string' === typeof e.detail.serialize) {
77+
rtn = e.detail.serialize;
78+
} else if ('number' === typeof e.detail.serialize.nodeType) {
79+
// make it go through the serialization logic
80+
rtn = serialize(e.detail.serialize, context);
81+
} else {
82+
rtn = String(e.detail.serialize);
83+
}
84+
} else {
85+
// default serialization logic
86+
switch (nodeType) {
87+
case 1 /* element */:
88+
rtn = exports.serializeElement(node, context);
89+
break;
90+
case 2 /* attribute */:
91+
rtn = exports.serializeAttribute(node);
92+
break;
93+
case 3 /* text */:
94+
rtn = exports.serializeText(node);
95+
break;
96+
case 8 /* comment */:
97+
rtn = exports.serializeComment(node);
98+
break;
99+
case 9 /* document */:
100+
rtn = exports.serializeDocument(node, context);
101+
break;
102+
case 10 /* doctype */:
103+
rtn = exports.serializeDoctype(node);
104+
break;
105+
case 11 /* document fragment */:
106+
rtn = exports.serializeDocumentFragment(node, context);
107+
break;
108+
}
109+
}
68110
}
69111
}
70112

71-
// default serialization logic
72-
switch (nodeType) {
73-
case 1 /* element */:
74-
return exports.serializeElement(node);
75-
case 2 /* attribute */:
76-
return exports.serializeAttribute(node);
77-
case 3 /* text */:
78-
return exports.serializeText(node);
79-
case 8 /* comment */:
80-
return exports.serializeComment(node);
81-
case 9 /* document */:
82-
return exports.serializeDocument(node);
83-
case 10 /* doctype */:
84-
return exports.serializeDoctype(node);
85-
case 11 /* document fragment */:
86-
return exports.serializeDocumentFragment(node);
113+
if ('function' === typeof fn) {
114+
node.removeEventListener('serialize', fn, false);
87115
}
88116

89-
return '';
117+
return rtn || '';
90118
}
91119

92120
/**
@@ -103,7 +131,7 @@ function serializeAttribute (node) {
103131
* Serialize a DOM element.
104132
*/
105133

106-
function serializeElement (node) {
134+
function serializeElement (node, context) {
107135
var c, i, l;
108136
var name = node.nodeName.toLowerCase();
109137

@@ -118,7 +146,7 @@ function serializeElement (node) {
118146
r += '>';
119147

120148
// child nodes
121-
r += exports.serializeNodeList(node.childNodes);
149+
r += exports.serializeNodeList(node.childNodes, context);
122150

123151
// closing tag, only for non-void elements
124152
if (!voidElements[name]) {
@@ -151,8 +179,8 @@ function serializeComment (node) {
151179
* Serialize a Document node.
152180
*/
153181

154-
function serializeDocument (node) {
155-
return exports.serializeNodeList(node.childNodes);
182+
function serializeDocument (node, context) {
183+
return exports.serializeNodeList(node.childNodes, context);
156184
}
157185

158186
/**
@@ -179,18 +207,18 @@ function serializeDoctype (node) {
179207
* Serialize a DocumentFragment instance.
180208
*/
181209

182-
function serializeDocumentFragment (node) {
183-
return exports.serializeNodeList(node.childNodes);
210+
function serializeDocumentFragment (node, context) {
211+
return exports.serializeNodeList(node.childNodes, context);
184212
}
185213

186214
/**
187215
* Serialize a NodeList/Array of nodes.
188216
*/
189217

190-
function serializeNodeList (list) {
218+
function serializeNodeList (list, context, fn) {
191219
var r = '';
192220
for (var i = 0, l = list.length; i < l; i++) {
193-
r += serialize(list[i]);
221+
r += serialize(list[i], context, fn);
194222
}
195223
return r;
196224
}

0 commit comments

Comments
 (0)