/** * 注册命名空间: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){ //从页面上获取 或者