UNPKG

2.64 kBJavaScriptView Raw
1/**
2 * @license
3 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
4 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7 * Code distributed by Google as part of the polymer project is also
8 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9 */
10
11// jshint node: true
12'use strict';
13
14var dom5 = require('dom5');
15var pred = dom5.predicates;
16
17var 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
31var noSemiColonInsertion = /\/\/|;\s*$|\*\/\s*$/;
32
33module.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 // remove newline after script to get rid of nasty whitespace
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 // newline + semicolon should be enough to capture all cases of concat
79 var js = contents.join('\n');
80
81 return {
82 html: html,
83 js: js
84 };
85};