1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | var id = 1;
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | exports.VOID = 0;
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 | exports.TAG = 1;
|
30 | exports.ELEMENT = 1;
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | exports.TEXT = 2;
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 | exports.CDATA = 3;
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | exports.PROCESSING = 4;
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | exports.COMMENT = 5;
|
61 |
|
62 |
|
63 |
|
64 |
|
65 | exports.DOCTYPE = 6;
|
66 |
|
67 |
|
68 |
|
69 |
|
70 | exports.TYPE = 7;
|
71 |
|
72 |
|
73 |
|
74 |
|
75 | exports.ENTITY = 8;
|
76 |
|
77 |
|
78 |
|
79 |
|
80 | exports.VERBATIM = 98;
|
81 |
|
82 |
|
83 |
|
84 |
|
85 | exports.PAGES = 99;
|
86 |
|
87 |
|
88 |
|
89 |
|
90 | exports.clone = function(root) {
|
91 | return JSON.parse(JSON.stringify(root));
|
92 | };
|
93 |
|
94 |
|
95 |
|
96 |
|
97 | exports.nextId = function() {
|
98 | return "W" + (id++);
|
99 | };
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 | exports.getElementByName = function(root, name) {
|
107 | if (!root) return null;
|
108 | if (root.name && root.name.toLowerCase() === name.toLowerCase()) return root;
|
109 | if (Array.isArray(root.children)) {
|
110 | var i, node;
|
111 | for (i = 0 ; i < root.children.length ; i++) {
|
112 | node = exports.getElementByName(root.children[i], name);
|
113 | if (node !== null) return node;
|
114 | }
|
115 | }
|
116 | return null;
|
117 | };
|
118 |
|
119 |
|
120 |
|
121 |
|
122 | exports.removeChild = function(parent, child) {
|
123 | if (Array.isArray(parent.children)) {
|
124 | var i, node;
|
125 | for (i = 0 ; i < parent.children.length ; i++) {
|
126 | node = parent.children[i];
|
127 | if (node === child) {
|
128 | parent.children.splice(i, 1);
|
129 | break;
|
130 | }
|
131 | }
|
132 | }
|
133 | };
|
134 |
|
135 | exports.trim = function(root) {
|
136 | var children = root.children;
|
137 | function isEmpty(node) {
|
138 | if (node.type != exports.TEXT) return false;
|
139 | if (!node.text) return false;
|
140 | if (node.text.trim().length == 0) return true;
|
141 | return false;
|
142 | }
|
143 | while (children.length > 0 && isEmpty(children[0])) {
|
144 | children.shift();
|
145 | }
|
146 | while (children.length > 0 && isEmpty(children[children.length - 1])) {
|
147 | children.pop();
|
148 | }
|
149 | if (children.length > 0) {
|
150 | if (children[0].type == exports.TEXT) {
|
151 | children[0].text = children[0].text.trimLeft();
|
152 | }
|
153 | if (children[children.length - 1].type == exports.TEXT) {
|
154 | children[children.length - 1].text = children[children.length - 1].text.trimRight();
|
155 | }
|
156 | }
|
157 | };
|
158 |
|
159 | exports.trimLeft = function(root) {
|
160 | var children = root.children;
|
161 | function isEmpty(node) {
|
162 | if (node.type != exports.TEXT) return false;
|
163 | if (!node.text) return false;
|
164 | if (node.text.trim().length == 0) return true;
|
165 | return false;
|
166 | }
|
167 | while (children.length > 0 && isEmpty(children[0])) {
|
168 | children.shift();
|
169 | }
|
170 | if (children.length > 0) {
|
171 | if (children[0].type == exports.TEXT) {
|
172 | children[0].text = children[0].text.trimLeft();
|
173 | }
|
174 | }
|
175 | };
|
176 |
|
177 | exports.trimRight = function(root) {
|
178 | var children = root.children;
|
179 | function isEmpty(node) {
|
180 | if (node.type != exports.TEXT) return false;
|
181 | if (!node.text) return false;
|
182 | if (node.text.trim().length == 0) return true;
|
183 | return false;
|
184 | }
|
185 | while (children.length > 0 && isEmpty(children[children.length - 1])) {
|
186 | children.pop();
|
187 | }
|
188 | if (children.length > 0) {
|
189 | if (children[children.length - 1].type == exports.TEXT) {
|
190 | children[children.length - 1].text = children[children.length - 1].text.trimRight();
|
191 | }
|
192 | }
|
193 | };
|
194 |
|
195 |
|
196 |
|
197 |
|
198 | exports.toString = function(node) {
|
199 | var txt = '',
|
200 | key, val;
|
201 | if (!node) return '';
|
202 | if (node.type == exports.TAG) {
|
203 | txt += "<" + node.name;
|
204 | for (key in node.attribs) {
|
205 | val = "" + node.attribs[key];
|
206 | txt += " " + key;
|
207 | if( typeof val === 'string' ) {
|
208 |
|
209 | txt += "=" + JSON.stringify(val) + "";
|
210 | }
|
211 | }
|
212 | if (typeof node.html === 'string') {
|
213 | txt += ">" + node.html;
|
214 | }
|
215 | else if (node.children && node.children.length > 0) {
|
216 | txt += ">";
|
217 | node.children.forEach(
|
218 | function(child) {
|
219 | txt += exports.toString(child);
|
220 | }
|
221 | );
|
222 | txt += "</" + node.name + ">";
|
223 | } else {
|
224 | if (node.void) txt += ">";
|
225 | else if (node.autoclose) txt += "/>";
|
226 | else txt += "></" + node.name + ">";
|
227 | }
|
228 | }
|
229 | else if (node.type == exports.ENTITY) {
|
230 | txt += node.text;
|
231 | }
|
232 | else if (node.type == exports.VERBATIM) {
|
233 | txt += node.text;
|
234 | }
|
235 | else if (node.type == exports.TEXT) {
|
236 | txt += node.text.replace(/&/g, '&').replace(/</g, '<');
|
237 | }
|
238 | else if (node.type == exports.PROCESSING) {
|
239 | txt += "<?" + node.name;
|
240 | for (key in node.attribs) {
|
241 | val = "" + node.attribs[key];
|
242 | txt += " " + key + "=" + JSON.stringify(val) + "";
|
243 | }
|
244 | txt += "?>";
|
245 | }
|
246 | else if (typeof node.html === 'string') {
|
247 | txt += node.html;
|
248 | }
|
249 | else if (node.children) {
|
250 | node.children.forEach(
|
251 | function(child) {
|
252 | txt += exports.toString(child);
|
253 | }
|
254 | );
|
255 | }
|
256 |
|
257 | return txt;
|
258 | };
|
259 |
|
260 |
|
261 |
|
262 | exports.debug = function(node, indent) {
|
263 | if (typeof indent === 'undefined') indent = '';
|
264 | if (!node) {
|
265 | return console.log(indent + "UNDEFINED!");
|
266 | }
|
267 | if (node.type == exports.TEXT) {
|
268 | console.log(indent + "\"" + node.text.trim() + "\"");
|
269 | } else {
|
270 | if (node.children && node.children.length > 0) {
|
271 | console.log(
|
272 | indent + "<" + (node.name ? node.name : node.type) + "> "
|
273 | + (node.attribs ? JSON.stringify(node.attribs) : '')
|
274 | );
|
275 | node.children.forEach(
|
276 | function(child) {
|
277 | exports.debug(child, indent + ' ');
|
278 | }
|
279 | );
|
280 | console.log(indent + "</" + (node.name ? node.name : node.type) + "> ");
|
281 | } else {
|
282 | console.log(
|
283 | indent + "<" + (node.name ? node.name : node.type) + " "
|
284 | + (node.attribs ? JSON.stringify(node.attribs) : '') + " />"
|
285 | );
|
286 | }
|
287 | }
|
288 | };
|
289 |
|
290 |
|
291 |
|
292 |
|
293 |
|
294 |
|
295 |
|
296 |
|
297 | exports.walk = function(node, functionBotomUp, functionTopDown, parent) {
|
298 | if (!node) return;
|
299 | var i, child, replacement, children;
|
300 | if (typeof functionTopDown === 'function') {
|
301 | functionTopDown(node, parent);
|
302 | }
|
303 | if (node.children) {
|
304 | children = [];
|
305 | node.children.forEach(
|
306 | function(item) {
|
307 | children.push(item);
|
308 | }
|
309 | );
|
310 | children.forEach(
|
311 | function(child) {
|
312 | exports.walk(child, functionBotomUp, functionTopDown, node);
|
313 | }
|
314 | );
|
315 | }
|
316 | if (typeof functionBotomUp === 'function') {
|
317 | return functionBotomUp(node, parent);
|
318 | }
|
319 | };
|
320 |
|
321 |
|
322 |
|
323 | exports.att = function(node, name, value) {
|
324 | if (typeof value === 'undefined') {
|
325 | if (node.attribs) {
|
326 | return node.attribs[name];
|
327 | }
|
328 | return undefined;
|
329 | }
|
330 | if (!node.attribs) {
|
331 | node.attribs = {};
|
332 | }
|
333 | node.attribs[name] = value;
|
334 | };
|
335 |
|
336 |
|
337 |
|
338 | exports.text = function(node, text) {
|
339 | if (typeof text === 'undefined') {
|
340 | if (node.type == exports.TEXT) {
|
341 | return node.text;
|
342 | }
|
343 | if (node.children) {
|
344 | var txt = "";
|
345 | node.children.forEach(
|
346 | function(child) {
|
347 | txt += exports.text(child);
|
348 | }
|
349 | );
|
350 | return txt;
|
351 | } else {
|
352 | return "";
|
353 | }
|
354 | } else {
|
355 | node.children = [
|
356 | {
|
357 | type: exports.TEXT,
|
358 | text: text
|
359 | }
|
360 | ];
|
361 | }
|
362 | };
|
363 |
|
364 |
|
365 |
|
366 | exports.createError = function(msg) {
|
367 | return {
|
368 | type: exports.TAG,
|
369 | name: "div",
|
370 | attribs: {
|
371 | style: "margin:4px;padding:4px;border:2px solid #fff;color:#fff;background:#f00;"
|
372 | + "box-shadow:0 0 2px #000;overflow:auto;font-family:monospace;font-size:1rem;"
|
373 | },
|
374 | children: [
|
375 | {
|
376 | type: exports.TEXT,
|
377 | text: msg.replace("\n", "<br/>", "g")
|
378 | }
|
379 | ]
|
380 | };
|
381 | };
|
382 |
|
383 |
|
384 |
|
385 | exports.addClass = function(node, className) {
|
386 | if (!node.attribs) {
|
387 | node.attribs = {};
|
388 | }
|
389 | var classes = (node.attribs["class"] || "").split(/[ \t\n\r]/g);
|
390 | var i;
|
391 | for (i = 0 ; i < classes.length ; i++) {
|
392 | if (className == classes[i]) return false;
|
393 | }
|
394 | var txt = "";
|
395 | classes.push(className);
|
396 | for (i = 0 ; i < classes.length ; i++) {
|
397 | if (txt.length > 0) {
|
398 | txt += " ";
|
399 | }
|
400 | txt += classes[i];
|
401 | }
|
402 | if (txt.length > 0) {
|
403 | node.attribs["class"] = txt;
|
404 | }
|
405 | return true;
|
406 | };
|
407 |
|
408 |
|
409 |
|
410 | exports.createJavascript = function(code) {
|
411 | return {
|
412 | type: exports.TAG,
|
413 | name: "script",
|
414 | attribs: {
|
415 | type: "text/javascript"
|
416 | },
|
417 | children: [
|
418 | {
|
419 | type: exports.TEXT,
|
420 | text: "//<![CDATA[\n" + code + "//]]>"
|
421 | }
|
422 | ]
|
423 | };
|
424 | };
|
425 |
|
426 | exports.forEachAttrib = function(node, func) {
|
427 | var attribs = node.attribs,
|
428 | attName, attValue, count = 0;
|
429 | if (!attribs) return 0;
|
430 | for (attName in attribs) {
|
431 | attValue = attribs[attName];
|
432 | if (typeof attValue === 'string') {
|
433 | func(attName, attValue);
|
434 | }
|
435 | }
|
436 | return count;
|
437 | };
|
438 |
|
439 |
|
440 |
|
441 |
|
442 | exports.forEachChild = function(node, func) {
|
443 | var children = node.children, i, child;
|
444 | if (!children) return false;
|
445 | for (i = 0 ; i < children.length ; i++) {
|
446 | child = children[i];
|
447 | if (typeof child.type === 'undefined' || child.type == exports.VOID) {
|
448 | exports.forEachChild(child, func);
|
449 | }
|
450 | else if (true === func(child, i)) {
|
451 | break;
|
452 | }
|
453 | }
|
454 | return i;
|
455 | };
|
456 |
|
457 |
|
458 |
|
459 |
|
460 |
|
461 |
|
462 |
|
463 |
|
464 |
|
465 |
|
466 |
|
467 |
|
468 |
|
469 |
|
470 |
|
471 |
|
472 |
|
473 |
|
474 |
|
475 |
|
476 |
|
477 |
|
478 |
|
479 |
|
480 |
|
481 |
|
482 |
|
483 |
|
484 |
|
485 |
|
486 |
|
487 |
|
488 |
|
489 |
|
490 |
|
491 |
|
492 |
|
493 | exports.normalizeChildren = function(node, recurse) {
|
494 | if (typeof recurse === 'undefined') recurse = false;
|
495 | if (node.children) {
|
496 | var children = [];
|
497 | extractNonVoidChildren(node, children);
|
498 | node.children = children;
|
499 | if (recurse) {
|
500 | node.children.forEach(
|
501 | function(child) {
|
502 | exports.normalizeChildren(child, true);
|
503 | }
|
504 | );
|
505 | }
|
506 | }
|
507 | };
|
508 |
|
509 | function extractNonVoidChildren(node, target) {
|
510 | if (typeof target === 'undefined') target = [];
|
511 | if (node.children && node.children.length > 0) {
|
512 | node.children.forEach(
|
513 | function(child) {
|
514 | if (!child.type || child.type == exports.VOID) {
|
515 | extractNonVoidChildren(child, target);
|
516 | } else {
|
517 | target.push(child);
|
518 | }
|
519 | }
|
520 | );
|
521 | }
|
522 | return target;
|
523 | }
|
524 |
|
525 |
|
526 |
|
527 |
|
528 | exports.findChild = function(root, tagname) {
|
529 | if (!Array.isArray(root.children)) return null;
|
530 | for (var i = 0 ; i < root.children.length ; i++) {
|
531 | var item = root.children[i];
|
532 | if (item.type == exports.TAG && item.name == tagname) return item;
|
533 | }
|
534 | return null;
|
535 | };
|
536 |
|
537 |
|
538 |
|
539 |
|
540 |
|
541 | exports.findOrAppendChild = function(root, tagname, attribs, children) {
|
542 | var child = exports.findChild(root, tagname);
|
543 | if (child) return child;
|
544 | child = exports.tag(tagname, attribs, children);
|
545 | if (!Array.isArray(root.children)) {
|
546 | root.children = [child];
|
547 | } else {
|
548 | root.children.push(child);
|
549 | }
|
550 | return child;
|
551 | };
|
552 |
|
553 |
|
554 |
|
555 |
|
556 | exports.div = function(attribs, children) {
|
557 | return exports.tag("div", attribs, children);
|
558 | };
|
559 |
|
560 |
|
561 |
|
562 |
|
563 |
|
564 |
|
565 |
|
566 |
|
567 |
|
568 |
|
569 |
|
570 | exports.tag = function(name, attribs, children) {
|
571 | if (!attribs) attribs = {};
|
572 | if (typeof attribs === 'string') attribs = {"class": attribs};
|
573 | if (typeof children === 'undefined') children = [];
|
574 | if (!Array.isArray(children)) {
|
575 | if (typeof children === 'string') {
|
576 | children = {
|
577 | type: exports.TEXT,
|
578 | text: children
|
579 | };
|
580 | }
|
581 | children = [children];
|
582 | }
|
583 | return {
|
584 | type: exports.TAG,
|
585 | name: name,
|
586 | attribs: attribs,
|
587 | children: children
|
588 | };
|
589 | };
|
590 |
|
591 |
|
592 |
|
593 | exports.createText = function(dic) {
|
594 | var key, val, children = [];
|
595 | for (key in dic) {
|
596 | val = dic[key];
|
597 | children.push(
|
598 | {
|
599 | type: exports.TAG,
|
600 | name: "span",
|
601 | attribs: {
|
602 | lang: key
|
603 | },
|
604 | children: [
|
605 | {
|
606 | type: exports.TEXT,
|
607 | text: val
|
608 | }
|
609 | ]
|
610 | }
|
611 | );
|
612 | }
|
613 | return children;
|
614 | };
|
615 |
|
616 |
|
617 |
|
618 |
|
619 |
|
620 |
|
621 |
|
622 | exports.keepOnlyTagChildren = function(root) {
|
623 | if (!root.children) return root;
|
624 | var children = [];
|
625 | root.children.forEach(
|
626 | function(node) {
|
627 | if (node.type == exports.TAG) {
|
628 | children.push(node);
|
629 | }
|
630 | }
|
631 | );
|
632 | root.children = children;
|
633 | return root;
|
634 | };
|
635 |
|
636 |
|
637 |
|
638 |
|
639 |
|
640 |
|
641 | exports.fromHtml = function( html ) {
|
642 |
|
643 | };
|