Comparing version 0.3.2 to 0.3.3
@@ -0,0 +0,0 @@ /** |
@@ -0,0 +0,0 @@ /** |
@@ -26,2 +26,4 @@ /** | ||
cfg.target = cfg.src || cfg.target; | ||
cfg.native2ascii = cfg.native2ascii !== false; | ||
cfg.replaceFont = cfg.replaceFont !== false; | ||
if(!cfg.target) { | ||
@@ -61,3 +63,3 @@ throw new Error('Please enter css path'); | ||
filepath: self.config.target | ||
} | ||
}; | ||
}, | ||
@@ -74,3 +76,3 @@ isExcluded: function(filename){ | ||
isRemoteFile: function(filepath){ | ||
return /http(s?):\/\//.test(filepath); | ||
return (/http(s?):\/\//).test(filepath); | ||
}, | ||
@@ -139,3 +141,2 @@ getFileContent: function(file, callback){ | ||
fileContent = iconv.encode(fileContent, config.outputEncoding || 'gbk'); | ||
var comboFile = config.output; | ||
@@ -262,2 +263,25 @@ // if output is not a file name, then generate a file name with .combo.css or .css. | ||
data = compressor._restoreComments(data, preservedTokens); | ||
//convert ZH to unicode | ||
if(config.native2ascii === true){ | ||
data = data.replace(/[\u4E00-\u9FA5\uF900-\uFA2D]/g,function($1){ | ||
return '\\'+utils.a2u($1).replace('%u',''); | ||
}); | ||
} | ||
//convert unicode font-family to EN | ||
if(config.replaceFont === true){ | ||
data = data.replace(/[\'|\"](\\\w{4}.*)[\'|\"]/g,function($1,$2){ | ||
$2 = $2.trim(); | ||
var en = utils.unicode2En($2), | ||
temp = ''; | ||
if(_.isArray(en)){ | ||
for(var i = 0;i<en.length;i++) { | ||
temp += '"' + en[i] + '",'; | ||
} | ||
en = temp.slice(0,-1); | ||
}else{ | ||
en = '"' + en + '"'; | ||
} | ||
return $2 ? en : $1; | ||
}); | ||
} | ||
self.generateOutput(data); | ||
@@ -264,0 +288,0 @@ |
231
lib/utils.js
var fs = require('fs'), | ||
url = require('url'), | ||
path = require('path'), | ||
http = require('http'); | ||
url = require('url'), | ||
path = require('path'), | ||
http = require('http'); | ||
var ZNMAP = { | ||
'\\534E\\6587\\7EC6\\9ED1': ['STHeiti Light [STXihei]', 'STXiheii'], | ||
'\\534E\\6587\\9ED1\\4F53': 'STHeiti', | ||
'\\4E3D\\9ED1 Pro': 'LiHei Pro Medium', | ||
'\\4E3D\\5B8B Pro': 'LiSong Pro Light', | ||
'\\6807\\6977\\4F53': ["DFKai-SB","BiauKai"], | ||
'\\82F9\\679C\\4E3D\\4E2D\\9ED1': 'Apple LiGothic Medium', | ||
'\\82F9\\679C\\4E3D\\7EC6\\5B8B': 'Apple LiSung Light', | ||
'\\65B0\\7EC6\\660E\4F53': 'PMingLiU', | ||
'\\7EC6\\660E\\4F53': 'MingLiU', | ||
'\\9ED1\\4F53': 'SimHei', | ||
'\\5B8B\\4F53': 'SimSun', | ||
'\\65B0\\5B8B\\4F53': 'NSimSun', | ||
'\\4EFF\\5B8B': 'FangSong', | ||
'\\6977\\4F53': 'KaiTi', | ||
'\\4EFF\\5B8B_GB2312': 'FangSong_GB2312', | ||
'\\6977\\4F53_GB2312': 'KaiTi_GB2312', | ||
'\\5FAE\\x8F6F\\6B63\\9ED1\\4F53': 'Microsoft JhengHei', | ||
'\\5FAE\\8F6F\\96C5\\9ED1': 'Microsoft YaHei', | ||
'\\96B6\\4E66': 'LiSu', | ||
'\\5E7C\\5706': 'YouYuan', | ||
'\\534E\\6587\\6977\\4F53': 'STKaiti', | ||
'\\534E\\6587\\5B8B\\4F53': 'STSong', | ||
'\\534E\\6587\\4E2D\\5B8B': 'STZhongsong', | ||
'\\534E\\6587\\4EFF\\5B8B': 'STFangsong', | ||
'\\65B9\\6B63\\8212\\4F53': 'FZShuTi', | ||
'\\65B9\\6B63\\59DA\\4F53': 'FZYaoti', | ||
'\\534E\\6587\\5F69\\4E91': 'STCaiyun', | ||
'\\534E\\6587\\7425\\73C0': 'STHupo', | ||
'\\534E\\6587\\96B6\\4E66': 'STLiti', | ||
'\\534E\\6587\\884C\\6977': 'STXingkai', | ||
'\\534E\\6587\\65B0\\9B4F': 'STXinwei' | ||
}; | ||
module.exports = { | ||
debug: false, | ||
log: function(msg, type){ | ||
var self = this; | ||
type = type ? type : 'info'; | ||
if(msg && (self.debug || (!self.debug && type != 'debug'))){ | ||
console.log((type ? '[' + type.toUpperCase() + '] ' : '') + msg); | ||
} | ||
}, | ||
/** | ||
debug: false, | ||
log: function(msg, type) { | ||
var self = this; | ||
type = type ? type: 'info'; | ||
if (msg && (self.debug || (!self.debug && type != 'debug'))) { | ||
console.log((type ? '[' + type.toUpperCase() + '] ': '') + msg); | ||
} | ||
}, | ||
/** | ||
* analyze @charset first. | ||
@@ -22,76 +59,100 @@ * @example: | ||
*/ | ||
detectCharset: function(input){ | ||
var result = /@charset\s+['|"](\w*)["|'];/.exec(input), | ||
charset = 'UTF-8'; | ||
if(result && result[1]){ | ||
charset = result[1]; | ||
detectCharset: function(input) { | ||
var result = /@charset\s+['|"](\w*)["|'];/.exec(input), | ||
charset = 'UTF-8'; | ||
if (result && result[1]) { | ||
charset = result[1]; | ||
} | ||
// else{ | ||
// var detect = jschardet.detect(input); | ||
// if(detect && detect.confidence > 0.9){ | ||
// charset = detect.encoding; | ||
// } | ||
// } | ||
return charset; | ||
}, | ||
mkdirSync: function(dirpath, mode) { | ||
var self = this; | ||
if (!fs.existsSync(dirpath)) { | ||
// try to create parent dir first. | ||
self.mkdirSync(path.dirname(dirpath), mode); | ||
fs.mkdirSync(dirpath, mode); | ||
} | ||
}, | ||
getRemoteFile: function(filePath, callback) { | ||
var self = this, | ||
content = null, | ||
buffers = [], | ||
count = 0, | ||
options = url.parse(filePath); | ||
// TODO https ? | ||
if (typeof options != 'undefined') { | ||
// debug && console.log('start request'); | ||
var req = http.request(options, function(res) { | ||
// debug && console.log('status: ' + res.statusCode); | ||
var charset = 'utf-8'; | ||
if (typeof res.headers['content-type'] !== 'undefined') { | ||
var regResult = res.headers['content-type'].match(/;charset=(\S+)/); | ||
if (regResult !== null && regResult[1]) { | ||
charset = regResult[1]; | ||
self.log('The charset of url ' + filePath + ' is: ' + charset, 'debug'); | ||
} | ||
} | ||
res.on('data', function(chunk) { | ||
// content += chunk; | ||
buffers.push(chunk); | ||
count += chunk.length; | ||
}); | ||
res.on('end', function() { | ||
switch (buffers.length) { | ||
case 0: | ||
content = new Buffer(0); | ||
break; | ||
case 1: | ||
content = buffers[0]; | ||
break; | ||
default: | ||
content = new Buffer(count); | ||
for (var i = 0, pos = 0, l = buffers.length; i < l; i++) { | ||
var chunk = buffers[i]; | ||
chunk.copy(content, pos); | ||
pos += chunk.length; | ||
} | ||
break; | ||
} | ||
callback && callback(content, charset); | ||
}); | ||
}); | ||
req.on('error', function(e) { | ||
self.log('request error: ' + e, 'error'); | ||
}); | ||
req.end(); | ||
} else { | ||
self.log('parse error: ' + filePath, 'error'); | ||
callback && callback(content); | ||
} | ||
}, | ||
//中文转unicode | ||
a2u: function(text) { | ||
text = escape(text.toString()).replace(/\+/g, "%2B"); | ||
var matches = text.match(/(%([0-9A-F]{2}))/gi); | ||
if (matches) { | ||
for (var matchid = 0; matchid < matches.length; matchid++) { | ||
var code = matches[matchid].substring(1, 3); | ||
if (parseInt(code, 16) >= 128) { | ||
text = text.replace(matches[matchid], '%u00' + code); | ||
} | ||
} | ||
} | ||
text = text.replace('%25', '%u0025'); | ||
return text; | ||
}, | ||
unicode2En: function(code) { | ||
if(ZNMAP.hasOwnProperty(code)){ | ||
return ZNMAP[code]; | ||
} | ||
// else{ | ||
// var detect = jschardet.detect(input); | ||
// if(detect && detect.confidence > 0.9){ | ||
// charset = detect.encoding; | ||
// } | ||
// } | ||
return charset; | ||
}, | ||
mkdirSync: function(dirpath, mode) { | ||
var self = this; | ||
if(!fs.existsSync(dirpath)) { | ||
// try to create parent dir first. | ||
self.mkdirSync(path.dirname(dirpath), mode); | ||
fs.mkdirSync(dirpath, mode); | ||
} | ||
}, | ||
getRemoteFile: function(filePath, callback){ | ||
var self = this, | ||
content = null, | ||
buffers = [], | ||
count = 0, | ||
options = url.parse(filePath); | ||
// TODO https ? | ||
if(typeof options != 'undefined'){ | ||
// debug && console.log('start request'); | ||
var req = http.request(options, function(res){ | ||
// debug && console.log('status: ' + res.statusCode); | ||
var charset = 'utf-8'; | ||
if(typeof res.headers['content-type'] !== 'undefined'){ | ||
var regResult = res.headers['content-type'].match(/;charset=(\S+)/); | ||
if(regResult !== null && regResult[1]){ | ||
charset = regResult[1]; | ||
self.log('The charset of url ' + filePath + ' is: ' + charset, 'debug'); | ||
} | ||
} | ||
res.on('data', function(chunk){ | ||
// content += chunk; | ||
buffers.push(chunk); | ||
count += chunk.length; | ||
}); | ||
res.on('end', function(){ | ||
switch(buffers.length) { | ||
case 0: content = new Buffer(0); | ||
break; | ||
case 1: content = buffers[0]; | ||
break; | ||
default: | ||
content = new Buffer(count); | ||
for (var i = 0, pos = 0, l = buffers.length; i < l; i++) { | ||
var chunk = buffers[i]; | ||
chunk.copy(content, pos); | ||
pos += chunk.length; | ||
} | ||
break; | ||
} | ||
callback && callback(content, charset); | ||
}); | ||
}); | ||
req.on('error', function(e){ | ||
self.log('request error: ' + e, 'error'); | ||
}); | ||
req.end(); | ||
}else{ | ||
self.log('parse error: ' + filePath, 'error'); | ||
callback && callback(content); | ||
} | ||
} | ||
return code; | ||
} | ||
}; | ||
}; |
@@ -0,0 +0,0 @@ The MIT License |
{ | ||
"name":"css-combo", | ||
"version":"0.3.2", | ||
"version":"0.3.3", | ||
"description":"css module combo tool", | ||
@@ -5,0 +5,0 @@ "author":"daxingplay <daxingplay@gmail.com>", |
@@ -39,10 +39,10 @@ # css-combo | ||
var CSSCombo = require('css-combo'); | ||
CSSCombo.build(cfg, function(err){ callback(); }); | ||
CSSCombo.build(src, dest, cfg, function(err){ callback(); }); | ||
* src 入口文件的地址 | ||
* dest 输出目录或者输出的完整路径(含文件名,推荐),可以使用相对路径 | ||
* cfg 参数可以配置以下选项: | ||
* target:{String} 入口文件 | ||
* inputEncoding:{String} 输入文件编码,可选,默认检测入口文件中的@charset设置。如果入口文件没有设置@charset,那么最好设置本选项 | ||
* outputEncoding:{String} 输出文件编码,可选,默认UTF-8 | ||
* output:{String} 输出目录或者输出的完整路径(含文件名,推荐),可以使用相对路径 | ||
* exclude:{Array} 黑名单正则数组,可选,默认空 | ||
@@ -52,2 +52,4 @@ * compress: {Boolean} 是否压缩,默认为true,处理规则同YUICompressor | ||
* paths: {Array} `@import`额外查找的路径。 | ||
* native2ascii: {Boolean} 是否替换中文为Unicode字符,默认为true | ||
* replaceFont: {Boolean} 是否把中文的字体名称替换成英文名称,默认为true,此选项依赖上面的选项,即必须native2ascii配置为true才有效。强烈建议各位开发者在书写CSS的时候就使用英文名称,比如微软雅黑,写成'Microsoft YaHei' | ||
@@ -64,2 +66,3 @@ ### 在grunt中使用 ### | ||
* 0.3.3:增加替换中文的字体名称为英文名称的方法 | ||
* 0.2.2:修正打包之后输出文件编码问题 | ||
@@ -66,0 +69,0 @@ * 0.2.7:build参数更改,提供更多形式的输入,去掉部分log信息 |
@@ -63,2 +63,23 @@ var CssCombo = require('../lib/index'), | ||
}); | ||
//a2u ZH test | ||
it('should replace ZH text to css unicode',function(done){ | ||
CssCombo.build({ | ||
target: path.resolve(__dirname, 'css/a2u.source.css'), | ||
debug: false, | ||
inputEncoding: 'utf-8', | ||
outputEncoding: 'utf-8', | ||
output:path.resolve(__dirname, 'css/a2u.combo.css'), | ||
compress: 0 | ||
},function(e,report){ | ||
if(e){ | ||
throw new Error(e); | ||
}else{ | ||
report = report[0]; | ||
if(report.content.match(/[\u4E00-\u9FA5\uF900-\uFA2D]/)){ | ||
throw new Error('report.content Error'); | ||
} | ||
} | ||
done(); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
655439
35
2894
71