diff --git a/CHANGELOG.md b/CHANGELOG.md index db74157..61913b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # 更新日志 +## 0.3.6 + +* 修复 BUG [#43](https://github.com/aui/font-spider/issues/43) +* 提高程序稳定性 + ## 0.3.5 * 升级 fontmin 版本 diff --git a/README.md b/README.md index 0218c48..64c9fb9 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,14 @@ # 字蛛 -[][node-version-url][![NPM Version][npm-image]][npm-url] +[][node-version-url][![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] [![Node.js Version][node-version-image]][node-version-url] -[![NPM Downloads][downloads-image]][downloads-url] - -[![Node.js Version][node-version-image]][node-version-url] - -中文 WebFont 自动化压缩工具,它能自动分析页面使用的 WebFont 并进行按需压缩。 +中文 WebFont 自动化压缩工具,它能自动分析页面使用的 WebFont 并进行按需压缩,并不需要指定字体与字符。 官方网站: ## 特性 -在网页中呈现艺术字体,WebFont 比图片拥有更好的体验,它支持选中、搜索、翻译、朗读、缩放等,而字蛛作为一个 WebFont 压缩转码工具,拥有如下特性: +在网页中呈现艺术字体,WebFont 会比图片拥有更好的体验,它支持选中、搜索、翻译、朗读、缩放等。字蛛作为一个 WebFont 压缩转码工具,拥有如下特性: 1. 按需压缩:数 MB 的中文字体可被压成几十 KB 2. 简单可靠:完全基于 CSS 规则,无需 js 与服务端辅助 @@ -104,11 +100,11 @@ font-spider --ignore *-icon.css,*.eot dest/*.html ## 限制 - 仅支持 `link` 与 `style` 标签引入的样式,不支持元素行内样式 -- CSS `content` 属性插入的字符需要定义 `font-family`,不支持继承 - 仅支持固定的文本与样式,不支持 javascript 动态插入的元素与样式 -- .otf 字体需要转换成 .ttf 才能被压缩 +- .otf 字体需要转换成 .ttf 才能被压缩 - 仅支持 `utf-8` 编码 - 不支持 CSS `unicode-range` 属性 +- 不支持字体继承(例如 CSS `content` 属性插入的字符需要定义 `font-family`) ## 字体兼容性参考 diff --git a/package.json b/package.json index 8e8b639..3bd11ce 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "font-spider", "description": "Webfont optimizer", - "version": "0.3.5", + "version": "0.3.6", "homepage": "https://github.com/aui/font-spider", "author": { "name": "aui", diff --git a/src/compress/index.js b/src/compress/index.js index f78e019..5640032 100644 --- a/src/compress/index.js +++ b/src/compress/index.js @@ -22,6 +22,13 @@ function Compress (webFont, options) { return new Promise(function (resolve, reject) { + + if (webFont.length === 0) { + resolve(webFont); + return; + } + + number ++; options = getOptions(options); diff --git a/src/spider/css-parser.js b/src/spider/css-parser.js index 0f80ab4..787c0cb 100644 --- a/src/spider/css-parser.js +++ b/src/spider/css-parser.js @@ -29,52 +29,72 @@ function CssParser (resource /*,importLength*/) { } - var file = resource.file; - var content = resource.content; - var options = resource.options; - var cache = options.cache; - var cssParser; - - - if (cache) { - cssParser = CssParser.cache[file]; - if (cssParser) { - // 深拷贝缓存 - return cssParser.then(utils.copy); - } - } + return new Promise(function (resolve, reject) { + + var file = resource.file; + var content = resource.content; + var options = resource.options; + var cache = options.cache; + var ast, tasks; - var ast; - // CSSOM BUG? - content = content.replace(/@charset\b.+;/g, ''); + if (cache) { + tasks = CssParser.cache[file]; + if (tasks) { + // 深拷贝缓存 + return resolve(utils.copy(tasks)); + } + } - try { - ast = CSSOM.parse(content); - } catch (errors) { + + // CSSOM BUG? + content = content.replace(/@charset\b.+;/g, ''); - return Promise.reject( - new VError(errors, 'parse "%s" failed', file) - ); - } - cssParser = new CssParser - .Parser(ast, file, options, importLength); + try { + ast = CSSOM.parse(content); + } catch (errors) { + + return reject( + new VError(errors, 'parse "%s" failed', file) + ); + } - if (cache) { - CssParser.cache[file] = cssParser; - } - if (options.debug) { - cssParser.then(function (data) { - console.log(''); - console.log('[DEBUG]', 'CssParser', file); - console.log(data); - return data; - }); - } + tasks = new CssParser + .Parser(ast, file, options, importLength); + - return cssParser; + Promise.all(tasks) + .then(function (tasks) { + var cssInfo = []; + tasks.forEach(function (item) { + if (Array.isArray(item)) { + cssInfo = cssInfo.concat(item); + } else if (item instanceof CssParser.Model) { + cssInfo.push(item); + } + }); + + + if (cache) { + CssParser.cache[file] = cssInfo; + } + + + if (options.debug) { + console.log(''); + console.log('[DEBUG]', 'CssParser', file); + console.log(cssInfo); + } + + resolve(cssInfo); + + }) + .catch(reject); + + + }); } @@ -152,35 +172,18 @@ CssParser.Parser = function (ast, file, options, importLength) { ast.cssRules.forEach(function (rule) { var type = rule.constructor.name; - var ret; + var cssInfo; if (typeof that[type] === 'function') { - ret = that[type](rule); - if (ret) { - tasks.push(ret); + cssInfo = that[type](rule); + if (cssInfo) { + tasks.push(cssInfo); } } }); - - var promise = Promise.all(tasks) - .then(function (list) { - - var ret = []; - list.forEach(function (item) { - if (Array.isArray(item)) { - ret = ret.concat(item); - } else if (item instanceof CssParser.Model) { - ret.push(item); - } - }); - - return ret; - }); - - - return promise; + return tasks; }; diff --git a/src/spider/html-parser.js b/src/spider/html-parser.js index bfd5a0c..a262e6e 100644 --- a/src/spider/html-parser.js +++ b/src/spider/html-parser.js @@ -27,22 +27,23 @@ function HtmlParser (resource) { } + return new Promise(function (resolve, reject) { + var file = resource.file; + var content = resource.content; + var options = resource.options; + var $; - var file = resource.file; - var content = resource.content; - var options = resource.options; - var $; + try { + $ = cheerio.load(content); + } catch (error) { + var errors = new VError(error, 'parse "%s" failed', file); + return reject(errors); + } - try { - $ = cheerio.load(content); - return new HtmlParser.Parser($, file, options); - } catch (error) { - - var errors = new VError(error, 'parse "%s" failed', file); - return Promise.reject(errors); - } + resolve(new HtmlParser.Parser($, file, options)); + }); } @@ -80,8 +81,6 @@ HtmlParser.Parser = function ($, file, options) { // http://font-spider.org >>> http://font-spider.org // http://font-spider.org/html/test.html >>> http://font-spider.org/html this.base = $('base[href]').attr('href') || utils.dirname(file); - - return Promise.resolve(this); }; diff --git a/src/spider/index.js b/src/spider/index.js index 5999b9c..a95a0ad 100644 --- a/src/spider/index.js +++ b/src/spider/index.js @@ -62,7 +62,6 @@ function Spider (htmlFiles, options) { webFonts.forEach(function (font) { - //console.log(font); font.chars = chars[font.id]; // 对字符进行除重操作 @@ -109,62 +108,61 @@ Spider.Model = function WebFont (id, name, files, chars, selectors) { * @return {Promise} */ Spider.Parser = function (htmlFile, options) { - - var resource; - var that = this; - var isBuffer = typeof htmlFile === 'object' && htmlFile.isBuffer(); - - - if (isBuffer) { - - resource = Promise.resolve(new Resource.Model( - htmlFile.path, - htmlFile.contents.toString(), - utils.options(options, { - from: 'Node', - cache: false - }) - )); - - htmlFile = htmlFile.path; - - } else { - - resource = new Resource( - htmlFile, - null, - utils.options(options, { - from: 'Node', - cache: false - } - )); - } + return new Promise(function (resolve, reject) { + var resource; + var isBuffer = typeof htmlFile === 'object' && htmlFile.isBuffer(); + + if (isBuffer) { + + resource = resolve(new Resource.Model( + htmlFile.path, + htmlFile.contents.toString(), + utils.options(options, { + from: 'Node', + cache: false + }) + )); + + htmlFile = htmlFile.path; + + } else { + + resource = new Resource( + htmlFile, + null, + utils.options(options, { + from: 'Node', + cache: false + } + )); + } - this.options = options; - var spiderBeforeLoad = options.spiderBeforeLoad; - var spiderLoad = options.spiderLoad; - var spiderError = options.spiderError; - - spiderBeforeLoad(htmlFile); - - return new HtmlParser(resource) - .then(function (htmlParser) { - this.htmlParser = htmlParser; - this.htmlFile = htmlFile; - return htmlParser; - }.bind(this)) - .then(that.getCssInfo.bind(this)) - .then(this.getFontInfo.bind(this)) - .then(this.getCharsInfo.bind(this)) - .then(function (webFonts) { - spiderLoad(htmlFile); - return webFonts; - }) - .catch(function (errors) { - spiderError(htmlFile, errors); - return Promise.reject(errors); - }); + this.options = options; + var spiderBeforeLoad = options.spiderBeforeLoad; + var spiderLoad = options.spiderLoad; + var spiderError = options.spiderError; + + spiderBeforeLoad(htmlFile); + + new HtmlParser(resource) + .then(function (htmlParser) { + this.htmlParser = htmlParser; + this.htmlFile = htmlFile; + return htmlParser; + }.bind(this)) + .then(this.getCssInfo.bind(this)) + .then(this.getFontInfo.bind(this)) + .then(this.getCharsInfo.bind(this)) + .then(function (webFonts) { + spiderLoad(htmlFile); + resolve(webFonts); + }) + .catch(function (errors) { + spiderError(htmlFile, errors); + reject(errors); + }); + }.bind(this)); };