forked from oxUnd/fis-postprocessor-require-async
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
144 lines (129 loc) · 4.51 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
* package fis
* subpackage fis-plus
*
* @see http://fis.baidu.com/
*
* @author Yang,junlong at 2016-02-16 15:27:03 build.
* @version $Id$
*/
'use strict';
var ld, rd;
function pregQuote (str, delimiter) {
// http://kevin.vanzonneveld.net
return (str + '').replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
}
function addAsync(file, value) {
var hasBrackets = false;
var values = [];
value = value.trim().replace(/(^\[|\]$)/g, function(m, v) {
if (v) {
hasBrackets = true;
}
return '';
});
values = value.split(/\s*,\s*/);
values = values.map(function(v) {
var info = fis.util.stringQuote(v);
v = info.rest.trim();
var uri = fis.uri.getId(v, file.dirname);
if (file.extras.async.indexOf(uri.id) < 0) {
file.extras.async.push(uri.id);
}
return info.quote + uri.id + info.quote;
});
return {
values: values,
hasBrackets: hasBrackets
};
}
//analyse [@require.async id] syntax in comment
function analyseComment(file, comment){
var reg = /(@require\.async\s+)('[^']+'|"[^"]+"|[^\s;!@#%^&*()]+)/g;
return comment.replace(reg, function(m, prefix, value){
addAsync(file, value);
return '';
});
}
//require.async(path) to require resource
function parseJs(content, file, conf){
var reg = /"(?:[^\\"\r\n\f]|\\[\s\S])*"|'(?:[^\\'\n\r\f]|\\[\s\S])*'|(\/\/[^\r\n\f]+|\/\*[\s\S]+?(?:\*\/|$))|\b(require\.async|require)\s*\(\s*("(?:[^\\"\r\n\f]|\\[\s\S])*"|'(?:[^\\'\n\r\f]|\\[\s\S])*'|\[[\s\S]*?\])\s*/g;
return content.replace(reg, function(m, comment, type, value){
if(type){
switch (type){
case 'require.async':
var res = addAsync(file, value);
if (res.hasBrackets) {
m = 'require.async([' + res.values.join(', ') + ']';
} else {
m = 'require.async(' + res.values.join(', ');
}
break;
case 'require':
// 只处理 require 的数组用法
if (value[0] === '[') {
var res = addAsync(file, value);
m = 'require([' + res.values.join(', ') + ']';
}
break;
}
} else if (comment) {
m = analyseComment(file, comment);
}
return m;
});
}
//<script|style ...>...</script|style> to analyse as js|css
function parseHtml(content, file, conf){
var reg = /(<script(?:\s+[\s\S]*?["'\s\w\/]>|\s*>))([\s\S]*?)(?=<\/script>|$)/ig;
content = content.replace(reg, function(m, $1, $2) {
if($1){//<script>
m = $1 + parseJs($2, file, conf);
}
return m;
});
reg = new RegExp('('+ld+'script(?:\\s+[\\s\\S]*?["\'\\s\\w\\/]'+rd+'|\\s*'+rd+'))([\\s\\S]*?)(?='+ld+'\\/script'+rd+'|$)', 'ig');
return content.replace(reg, function(m, $1, $2) {
if($1){//<script>
m = $1 + parseJs($2, file, conf);
}
return m;
});
}
module.exports = function(content, file, conf){
var o_ld = ld = conf.left_delimiter || fis.config.get('settings.smarty.left_delimiter') || fis.config.get('settings.template.left_delimiter') || '{%';
var o_rd = rd = conf.right_delimiter || fis.config.get('settings.smarty.right_delimiter') || fis.config.get('settings.template.right_delimiter') || '%}';
ld = pregQuote(ld);
rd = pregQuote(rd);
var initial = false;
if (file.extras == undefined) {
file.extras = {};
initial = true;
}
file.extras.async = [];
if (file.isHtmlLike) {
content = parseHtml(content, file, conf);
if (file.extras.isPage) {
var reg = new RegExp(ld + 'extends\\s+'), pos;
if(reg.test(content)){
pos = content.indexOf(o_ld + '/block' + o_rd);
} else {
pos = content.indexOf(o_ld + 'head' + o_rd);
}
if(pos > 0){
var insert = o_ld + "require name='" + file.id + "'" + o_rd;
content = content.substring(0, pos) + insert + content.substring(pos);
}
}
} else if (file.rExt === '.js') {
content = parseJs(content, file, conf);
}
//
if (file.extras.async.length == 0) {
delete file.extras.async;
if (initial) {
delete file.extras;
}
}
return content;
};