/**
* 注册命名空间:baidu.css
*/
baidu.namespace.register("baidu.css");
/**
* css相关处理
* @author zhaoxianlie
*/
baidu.css = (function(){
var _readyQueen = null;
var _localdata = null;
var _stats = null;
var _styleBlockCount = 0;
var _rootPath = null;
/**
* 存储页面上的css源代码
* @item {fileName:'',fileContent:''}
*/
var _rawCssSource = [];
var _summaryInformation = null;
/**
* 初始化css文件的读取队列
* @param {Object} isFinished 是否读取完成
*/
var _initReadyQueen = function(isFinished){
_readyQueen = {
curIndex : 0, //当前正处于读取的index
queen : [], //css文件队列,格式为:{link:"",style:""},其中link和style不可能同时有值
callback : new Function(), //回调方法
finished : isFinished //是否读取完成
};
_localdata = {};
};
/**
* 初始化侦测结果
*/
var _initSummaryInformation = function(){
_summaryInformation = {
styles : [], //所有的style标签和所有的link[rel=stylesheet]
cssMinified : { //css文件是否被压缩
files : [],
count : 0
},
backgroundImages : [], //css背景图片统计
expressions : [], //css expression统计
duplicatedFiles : [] //重复引入的文件
};
};
/**
* 初始化Stats
*/
var _initStats = function(){
_stats = {
matched: {count:0,selectors:[]}, //匹配上的
unmatched: {count:0,selectors:[]}, //未匹配上的
ignored: {count:0,selectors:[]} //忽略的
};
};
/**
* 增加一项读取项
* @param {Object} readyItem 格式为:{link:Object,style:Object}
*/
var _addReadyItem = function(readyItem){
_readyQueen.queen.push(readyItem);
};
/**
* 获取当前正在解析的Style块
*/
var _getCurrentReadyItem = function(){
return _readyQueen.queen[_readyQueen.curIndex];
};
/**
* 判断当前读取的是否为最后一个Style块
*/
var _isLastReadyItem = function(){
return (_readyQueen.curIndex == _readyQueen.queen.length);
};
/**
* 读取队列移动到下一个元素
*/
var _moveToNextReadyItem = function(){
_readyQueen.curIndex += 1;
};
/**
* 判断当前队列是否读取完毕
*/
var _isDealFinished = function(){
return _readyQueen.finished;
};
/**
* 设置当前文件的根路径
* @param {Object} path
*/
var _setCurRootPath = function(path) {
var reg = /(.*\/)([^\/]+\.css)/;
var p = reg.exec((path || '').replace(/\?.*/,''));
_rootPath = p ? p[1] : '';
};
/**
* 获取当前正在解析的文件的根路径
*/
var _getCurRootPath = function(){
return _rootPath || '';
};
/**
* 根据文件路径,提取文件名
* @param {Object} path 文件url
*/
var _getFileName = function(path){
var reg = /(.*\/)([^\/]+\.css)/;
var p = reg.exec((path || '').replace(/\?.*/,''));
return p ? p[2] : "style块" + ++_styleBlockCount;
};
/**
* 保存CSS代码
* @param {Object} _filePath 文件完整路径
* @param {Object} _fileContent 内容
*/
var _saveCssSource = function(_filePath,_fileContent){
//过滤CSS注释
_fileContent = _fileContent.replace(/\/\*[\S\s]*?\*\//g,'');
//提取文件名
var _fileName = _getFileName(_filePath);
_rawCssSource.push({
href : _filePath ? _filePath : '#',
fileName : _fileName,
fileContent : _fileContent
});
//对@import处理
try{
var reg = /@import\s+url\(\s*(\"|\')(.*)\1\s*\)(\s*;)?/ig;
_fileContent.replace(reg,function($0,$1,$2){
_addReadyItem({link:{href:_getCurRootPath() + $2},style:null});
});
}catch(err){
}
};
/**
* 获取一个比较标准的图片地址
* @param {Object} bgUrl
*/
var _getBgImageUrl = function(bgUrl){
if(bgUrl.indexOf('http://') != 0) {
bgUrl = bgUrl.replace(/['"]/g,"");
var __rp = _getCurRootPath();
if(bgUrl.indexOf('/') == 0){
__rp = '';
} else if(bgUrl.indexOf('./') == 0) {
bgUrl = bgUrl.substr(2);
} else if(bgUrl.indexOf('../') == 0) {
bgUrl = bgUrl.substr(3);
if(__rp.lastIndexOf('/') == __rp.length - 1) {
__rp = __rp.substr(0,__rp.length - 1);
}
__rp = __rp.substr(0,__rp.lastIndexOf('/') + 1);
}
bgUrl = __rp + bgUrl
}
return bgUrl;
};
/**
* 寻找并统计CSS背景图片
* @param {Object} _fileName
* @param {Object} _fileContent
*/
var _findBackgroundImage = function(_fileName,_fileContent){
var reg = /(background|background-image):(?:[\#\w]+\s+)?url\(([^\)]*)\)/ig;
var arr = [];
_fileContent.replace(/\/\*[\S\s]*?\*\//g,'').replace(/\r?\n/,'')
.replace(/\s+\'|\"/g,'').replace(reg,function($0,$1,$2){
$2 = $2.replace(/\?.*/,'');
arr.push(_getBgImageUrl($2));
});
if(arr.length) {
_summaryInformation.backgroundImages.push({
fileName:_fileName,
bgImages : arr
});
}
};
/**
* 寻找并统计css中的expression
* @param {Object} _fileName
* @param {Object} _fileContent
*/
var _findExpression = function(_fileName,_fileContent){
var reg = /:expression\(/ig;
var arr = _fileContent.replace(/\/\*[\S\s]*?\*\//g,'').replace(/\r?\n/,'')
.replace(/\s+/g,'').split(reg);
if(arr.length - 1) {
_summaryInformation.expressions.push({
fileName : _fileName,
count : arr.length - 1
});
}
};
/**
* 检测某个css文件是否被压缩
* @param {Object} cssObj css文件对象
* @config {String} href 文件路径
* @config {String} fileName 文件名
* @config {String} fileContent 文件内容
*/
var _detectCssMinify = function(cssObj){
var lines = cssObj.fileContent.split(/\n/);
var average_length_perline = cssObj.fileContent.length / lines.length;
if (average_length_perline < 150 && lines.length > 1) {
_summaryInformation.cssMinified.count++;
_summaryInformation.cssMinified.files.push({
href : cssObj.href,
fileName : cssObj.fileName
});
}
};
/**
* 将stylesheet归类进行检测
* @param {Array} styleheets CSSstyleheet对象数组
*/
var _getCssData = function(styleheets){
//从页面上获取 或者