Skip to content

Commit 5d6c832

Browse files
committed
change token data structure
1 parent bd849c6 commit 5d6c832

File tree

12 files changed

+5962
-3974
lines changed

12 files changed

+5962
-3974
lines changed

lib/lang/css/lexer.js

Lines changed: 58 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ var think = require('thinkjs-util');
44
var lexer = require('../../util/lexer.js');
55
var TOKEN = require('../../util/token.js');
66
var config = require('./config.js');
7+
var baseConfig = require('../../util/config.js');
78
//var util = require('./util.js');
89

910

1011
var atType = config.atType;
12+
var multiComment = baseConfig.comments[1];
1113
//var isAttrChar = util.isAttrChar;
1214

1315
module.exports = think.Class(lexer, {
@@ -20,6 +22,11 @@ module.exports = think.Class(lexer, {
2022
parse_selector: false,
2123
parse_value: false,
2224
},
25+
/**
26+
* prev token type
27+
* @type {Number}
28+
*/
29+
prevTokenType: 0,
2330
/**
2431
* get next token
2532
* @return {void} []
@@ -59,7 +66,7 @@ module.exports = think.Class(lexer, {
5966
*/
6067
getValueToken: function(){
6168
var ret = '', code, chr;
62-
var escape = false, comment;
69+
var escape = false, comments = [], comment;
6370
/*jshint -W084 */
6471
while(this.pos < this.length){
6572
chr = this.text[this.pos];
@@ -71,23 +78,20 @@ module.exports = think.Class(lexer, {
7178
}
7279
// ; or }
7380
if (code === 0x3b || code === 0x7d) {
74-
if (comment) {
75-
this.rollback();
76-
}
7781
break;
7882
}
79-
if (!this.isWhiteSpace(chr)) {
80-
comment = '';
83+
if (comments.length && !this.isWhiteSpace(chr) && !this.lookAt(multiComment[0])) {
84+
comments = [];
8185
}
8286
if (!escape && (code === 0x22 || code === 0x27)) {
8387
ret += this.getQuote({
8488
rollback: true
8589
}).value;
8690
continue;
8791
}else if (code === 0x2f) {
88-
this.record();
89-
comment = this.getCommentToken(1, 0, false);
92+
comment = this.getCommentToken(1, true, !comments.length);
9093
if (comment) {
94+
comments.push(comment);
9195
continue;
9296
}
9397
}else if (code === 0x28) { // ( )
@@ -102,39 +106,39 @@ module.exports = think.Class(lexer, {
102106
ret += this.next();
103107
}
104108
var token = this.getToken(TOKEN.CSS_VALUE, ret);
105-
token.value = this.removeRightSpace(ret);
109+
token.value = this.skipRightSpace(ret);
110+
111+
if (comments.length) {
112+
this.addComment(comments);
113+
}
106114
return token;
107115
},
108116
/**
109-
* remove right space
110-
* @param {String} value []
111-
* @return {String} []
117+
* add comment to next token
118+
* @param {Array} comments []
112119
*/
113-
removeRightSpace: function(value){
114-
var index = value.length - 1;
115-
var times = 0, chr;
116-
//if last char is \n, remove it
117-
//and set newlines for next token
118-
while(true){
119-
chr = value[index];
120-
if (this.isWhiteSpace(chr)) {
121-
index--;
122-
if (chr === '\n') {
123-
times++;
124-
}
125-
continue;
126-
}
127-
break;
120+
addComment: function(comments){
121+
switch(comments.length){
122+
case 1:
123+
this.commentBefore.push(comments[0]);
124+
break;
125+
case 2:
126+
this.commentBefore.push(comments[0], comments[1]);
127+
break;
128+
case 3:
129+
this.commentBefore.push(comments[0], comments[1], comments[2]);
130+
break;
131+
default:
132+
[].push.call(this.commentBefore, comments);
133+
break;
128134
}
129-
this.newlines += times;
130-
return value.slice(0, index + 1);
131135
},
132136
/**
133137
* get selector or name token
134138
* @return {Object} []
135139
*/
136140
getSelectorOrPropertyToken: function(){
137-
var ret = '', code, str, token, type, chr, comment;
141+
var ret = '', code, str, token, type, chr, comments = [], comment;
138142
this.record();
139143
/*jshint -W084 */
140144
while(this.pos < this.length){
@@ -158,12 +162,12 @@ module.exports = think.Class(lexer, {
158162
}
159163
break;
160164
}
161-
if (!this.isWhiteSpace(chr)) {
162-
comment = '';
165+
if (comments.length && !this.isWhiteSpace(chr) && !this.lookAt(multiComment[0])) {
166+
comments = [];
163167
}
164168
if (code === 0x2f) {
165169
this.record();
166-
comment = this.getCommentToken(1, 0, false);
170+
comment = this.getCommentToken(1, true, !comments.length);
167171
if (comment) {
168172
continue;
169173
}
@@ -184,7 +188,11 @@ module.exports = think.Class(lexer, {
184188
ret += this.next();
185189
}
186190
token = this.getToken(type, ret);
187-
token.value = this.removeRightSpace(ret);
191+
token.value = this.skipRightSpace(ret);
192+
193+
if (comments.length) {
194+
this.addComment(comments);
195+
}
188196
return token;
189197
},
190198
/**
@@ -196,7 +204,7 @@ module.exports = think.Class(lexer, {
196204
while(this.text.charCodeAt(this.pos) === 0x2f && this.text.charCodeAt(this.pos + 1) === 0x2a){
197205
var comment = this.getCommentToken(1, 0);
198206
if (comment) {
199-
this.comments.push(comment);
207+
this.commentBefore.push(comment);
200208
}else{
201209
break;
202210
}
@@ -248,7 +256,21 @@ module.exports = think.Class(lexer, {
248256
ret += this.next();
249257
}
250258
var token = this.getToken(type, ret);
251-
token.value = this.removeRightSpace(ret);
259+
token.value = this.skipRightSpace(ret);
252260
return token;
261+
},
262+
/**
263+
* run
264+
* @return {Array} [text tokens]
265+
*/
266+
run: function(options){
267+
this._run(options);
268+
var ret = [], token;
269+
/*jshint -W084 */
270+
for(;token = this.getNextToken();){
271+
this.prevTokenType = token.type;
272+
ret.push(token);
273+
}
274+
return ret;
253275
}
254276
})

lib/lang/html/compress.js

Lines changed: 23 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,6 @@ module.exports = think.Class(base, {
5959
* @type {Object}
6060
*/
6161
prevToken: null,
62-
/**
63-
* space before token
64-
* @type {Boolean}
65-
*/
66-
spaceBefore: false,
67-
/**
68-
* space before next token
69-
* @type {String}
70-
*/
71-
spaceBeforeNextToken: false,
7262
/**
7363
* next token
7464
* @type {Object}
@@ -90,14 +80,13 @@ module.exports = think.Class(base, {
9080
*/
9181
getToken: function(){
9282
if (!this.token) {
93-
this.token = this.tokens[this.index];
83+
this.token = this.tokens[0];
9484
}else{
95-
this.prevToken = this.token;
9685
if (!this.nextToken) {
9786
return null;
9887
}
88+
this.prevToken = this.token;
9989
this.token = this.nextToken;
100-
this.spaceBefore = this.spaceBeforeNextToken;
10190
}
10291
var prevToken = this.prevToken;
10392
if (prevToken) {
@@ -118,18 +107,14 @@ module.exports = think.Class(base, {
118107
}
119108
}
120109
this.nextToken = null;
121-
this.spaceBeforeNextToken = false;
122110
var next;
123-
/*jshint -W084 */
124-
for(;next = this.tokens[++this.index];){
111+
while(this.index < this.length - 1){
112+
next = this.tokens[++this.index];
125113
if (next.type === TOKEN.ILLEGAL) {
126114
continue;
127115
}
128-
if (next.type !== TOKEN.HTML_TEXT || !/^\s+$/.test(next.value)) {
129-
this.nextToken = next;
130-
break;
131-
}
132-
this.spaceBeforeNextToken = true;
116+
this.nextToken = next;
117+
break;
133118
}
134119
return this.token;
135120
},
@@ -411,7 +396,7 @@ module.exports = think.Class(base, {
411396
var where = optionalEndTags[tag], nextToken = this.nextToken;
412397
// next token has comment
413398
if (where.next_comment === false) {
414-
if (nextToken && nextToken.comments.length && !options.remove_comment) {
399+
if (nextToken && nextToken.commentBefore.length && !options.remove_comment) {
415400
return value;
416401
}
417402
}
@@ -453,16 +438,12 @@ module.exports = think.Class(base, {
453438
var ret = '', options = this.options;
454439
// not remove comment
455440
if (!options.remove_comment) {
456-
var comments = token.comments;
441+
var comments = token.commentBefore;
457442
for(var i = 0, length = comments.length; i < length; i++){
458443
ret += comments[i].value;
459444
}
460445
}
461-
if (this.lastHasSpace) {
462-
return ret;
463-
}
464-
var space = this.spaceBefore || token.newlines;
465-
if (!space) {
446+
if (this.lastHasSpace || !this.token.spaceBefore) {
466447
return ret;
467448
}
468449
var type = token.type;
@@ -474,10 +455,6 @@ module.exports = think.Class(base, {
474455
type === TOKEN.TPL) {
475456
return ret;
476457
}
477-
// space before style or script can removed
478-
if (type === TOKEN.HTML_TAG_SCRIPT || type === TOKEN.HTML_TAG_STYLE) {
479-
return ret;
480-
}
481458
//safe tag
482459
if (type === TOKEN.HTML_TAG_END || type === TOKEN.HTML_TAG_START) {
483460
if (token._tag in safeTag) {
@@ -491,18 +468,20 @@ module.exports = think.Class(base, {
491468
return ret;
492469
}
493470
if (options.remove_space_in_block_tag) {
471+
// www </div> => www</div>
472+
if (token._tag in blockTag && prevType === TOKEN.HTML_TEXT) {
473+
return ret;
474+
}
494475
// remove space between 2 block end tags
495476
// </div> </div> => </div></div>
496477
if (prevType === TOKEN.HTML_TAG_END && type === TOKEN.HTML_TAG_END) {
497-
if (blockTag[prev._tag] && blockTag[token._tag]) {
478+
if (prev._tag in blockTag && token._tag in blockTag) {
498479
return ret;
499480
}
500481
}
501482
// www <div> => www<div>
502-
else if (type === TOKEN.HTML_TAG_START) {
503-
if (blockTag[token._tag]) {
504-
return ret;
505-
}
483+
else if (type === TOKEN.HTML_TAG_START && token._tag in blockTag) {
484+
return ret;
506485
}
507486
}
508487
}
@@ -515,29 +494,20 @@ module.exports = think.Class(base, {
515494
* @return {String} []
516495
*/
517496
compressText: function(token){
518-
var value = token.value;
497+
var value = token.value, space = token.spaceBefore ? ' ' : '';
519498
// async api may have line comment, can't compress it
520499
if (value.indexOf('//') > -1) {
521-
return value;
500+
return space + value;
522501
}
502+
value = value.replace(/\s+/g, ' ');
523503
var prev = this.prevToken, options = this.options;
524504
//if prev token is block tag, trim it
525505
if (prev && (prev.type === TOKEN.HTML_TAG_START || prev.type === TOKEN.HTML_TAG_END)) {
526506
if (options.remove_space_in_block_tag && blockTag[prev._tag]) {
527-
return value.trim();
528-
}
529-
}
530-
if (token.newlines) {
531-
value = ' ' + value;
532-
}
533-
value = value.replace(/\s+/g, ' ');
534-
//remove space before doctype
535-
if (value === ' ' && this.nextToken) {
536-
var type = this.nextToken.type;
537-
if (type === TOKEN.HTML_DOCTYPE || type === TOKEN.HTML_TAG_SCRIPT || type === TOKEN.HTML_TAG_STYLE) {
538-
return '';
507+
return value;
539508
}
540509
}
510+
value = space + value;
541511
return value;
542512
},
543513
/**
@@ -587,12 +557,13 @@ module.exports = think.Class(base, {
587557
* @return {String} []
588558
*/
589559
run: function(options){
590-
this.super('run', options);
560+
this._run(options);
591561
var instance = this.getInstance(lexer, true);
592562
this.tokens = instance.run({
593563
tag_attrs: true
594564
});
595565
this.index = 0;
566+
this.length = this.tokens.length;
596567
//don't compress xml text
597568
if (instance.isXML) {
598569
return this.text;

0 commit comments

Comments
 (0)