1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | 'use strict';
|
13 |
|
14 | var dom5 = require('dom5');
|
15 | var pred = dom5.predicates;
|
16 |
|
17 | var inlineScriptFinder = pred.AND(
|
18 | pred.hasTagName('script'),
|
19 | pred.OR(
|
20 | pred.NOT(
|
21 | pred.hasAttr('type')
|
22 | ),
|
23 | pred.hasAttrValue('type', 'application/javascript'),
|
24 | pred.hasAttrValue('type', 'text/javascript')
|
25 | ),
|
26 | pred.NOT(
|
27 | pred.hasAttr('src')
|
28 | )
|
29 | );
|
30 |
|
31 | var noSemiColonInsertion = /\/\/|;\s*$|\*\/\s*$/;
|
32 |
|
33 | module.exports = function crisp(options) {
|
34 | var source = options.source || '';
|
35 | var jsFileName = options.jsFileName || '';
|
36 | var scriptInHead = options.scriptInHead !== false;
|
37 | var onlySplit = options.onlySplit || false;
|
38 | var alwaysWriteScript = options.alwaysWriteScript || false;
|
39 |
|
40 | var doc = dom5.parse(source);
|
41 | var body = dom5.query(doc, pred.hasTagName('body'));
|
42 | var head = dom5.query(doc, pred.hasTagName('head'));
|
43 | var scripts = dom5.queryAll(doc, inlineScriptFinder);
|
44 |
|
45 | var contents = [];
|
46 | scripts.forEach(function(sn) {
|
47 | var nidx = sn.parentNode.childNodes.indexOf(sn) + 1;
|
48 | var next = sn.parentNode.childNodes[nidx];
|
49 | dom5.remove(sn);
|
50 |
|
51 | if (next && dom5.isTextNode(next) && !/\S/.test(dom5.getTextContent(next))) {
|
52 | dom5.remove(next);
|
53 | }
|
54 | var content = dom5.getTextContent(sn).trim();
|
55 | var lines = content.split('\n');
|
56 | var lastline = lines[lines.length - 1];
|
57 | if (!noSemiColonInsertion.test(lastline)) {
|
58 | content += ';';
|
59 | }
|
60 | contents.push(content);
|
61 | });
|
62 |
|
63 | if (!onlySplit) {
|
64 | if (contents.length > 0 || alwaysWriteScript) {
|
65 | var newScript = dom5.constructors.element('script');
|
66 | dom5.setAttribute(newScript, 'src', jsFileName);
|
67 | if (scriptInHead) {
|
68 | dom5.setAttribute(newScript, 'defer', '');
|
69 | head.childNodes.unshift(newScript);
|
70 | newScript.parentNode = head;
|
71 | } else {
|
72 | dom5.append(body, newScript);
|
73 | }
|
74 | }
|
75 | }
|
76 |
|
77 | var html = dom5.serialize(doc);
|
78 |
|
79 | var js = contents.join('\n');
|
80 |
|
81 | return {
|
82 | html: html,
|
83 | js: js
|
84 | };
|
85 | };
|