UNPKG

@extjs/sencha-cmd-linux-32

Version:

Productivity and performance optimization tool for building applications with Sencha Ext JS and Sencha Touch.

295 lines (254 loc) 10.6 kB
"use strict"; var Fashion = require('../export/Base.js'); var Env = require('../Env.js'); var Literal = require('../export/type/Literal.js'); var FunctionCall = require('../export/type/FunctionCall.js'); module.exports = { init (runtime) { var mimeTypeMap = { otf: 'font-opentype', eot: 'application/vnd.ms-fontobject', ttf: 'font/truetype', svg: 'image/svg+xml', woff: 'application/x-font-woff', woff2: 'application/x-font-woff2', gif: 'image/gif', png: 'image/png' }, report = false, excludes = [], includes = [], maxItemSize = -1; runtime.registerProcessor({ getSourceFromCall (obj) { var args = obj.args, source; if (args.items) { args = args.items; } if (!Array.isArray(args)) { args = [args]; } if (args.length === 1) { source = args[0]; } if (source.value) { source = source.value; } else { source = source.toString(); } return source; }, getSubstring (source, char) { var idx = source.indexOf(char); if (idx > -1) { source = source.substring(0, idx); } return source }, detectExtension (source) { source = this.getSubstring(source, '#'); source = this.getSubstring(source, '?'); var idx = source.lastIndexOf('.'), extension = source.substring(idx + 1); return extension; }, detectMimeType (source) { var extension = this.detectExtension(source), mapped = mimeTypeMap[extension]; return mapped || 'application/octet-stream'; }, encodeBytes (bytes) { if (Env.isNode) { return bytes.toString('base64'); } var str = ''; for (var i = 0; i < bytes.length; i++) { str += String.fromCharCode(bytes[i]); } return btoa(str); }, isMatch (source, filters) { for (var f = 0; f < filters.length; f++) { if (filters[f].test(source)) { return true; } } return false; }, isExcluded (source) { return this.isMatch(source, excludes); }, isIncluded (source) { return this.isMatch(source, includes); }, inlineUrl (obj, mimeType, charset) { var me = this, context = me.context, cache = context.cache || (context.cache = {}), source = me.getSourceFromCall(obj), url, queue, extension, inlineTag, inlineExtensionTag, skip; if (!source) { return; } mimeType = mimeType || me.detectMimeType(source); charset = charset || "UTF-8"; url = me.basePath + '/' + source; extension = this.detectExtension(url); inlineTag = obj.hasTag('inline'); inlineExtensionTag = obj.hasTag('inline\\:' + extension); skip = false; if (this.isExcluded(source)) { skip = true; } else if (this.isIncluded(source)) { skip = false; } else if (inlineExtensionTag === false) { skip = true; } else if (inlineExtensionTag === null && inlineTag === false) { skip = true; } if (skip) { return; } queue = cache[url] || function () { var token = { nodes: [], url: url }; function inlineData (bytes) { var data, arg, optNode; try { // 'getBinaryData' method provided on xhr by doRequest data = me.encodeBytes(bytes); arg = new Literal(encodeURI([ "data:", mimeType, charset ? ';charset=' + charset : '', ';base64', ',', data ].join(''))); Fashion.debug("creating inline data node for : " + url); optNode = new FunctionCall('url', [arg]); } catch (e) { Fashion.error(e); } if (maxItemSize > -1) { if (arg.value.length > maxItemSize) { // if we exceeded the limit, disable the optimization node optNode = null; } } if (optNode && report) { var size = data.length, num = token.nodes.length; Fashion.log(num + " * " + size + " bytes for " + url + "."); } // loop over all nodes in the nodes array // using the visitTarget property to override // the node and call context.ready.unblock() for (var n = 0; n < token.nodes.length; n++) { if (optNode) { var node = token.nodes[n]; node.visitTarget = optNode; } context.ready.unblock(); } } if (!Env.isBrowser) { var fs = Env.fs; fs.readFile(url, function(err, data){ if (!err) { inlineData(data); } else { Fashion.error(err); context.ready.unblock(); } }); } else { Env.doRequest({ url: url, async: true, binary: true, params: { _dc: new Date().getTime() }, onComplete (options, xhr) { try { inlineData(xhr.getBinaryData()); } catch (err) { Fashion.error(err); } }, onError (options, xhr) { for (var n = 0; n < token.nodes.length; n++) { context.ready.unblock(); } } }); } return token; }(); queue.nodes.push(obj); context.ready.block(); }, functioncall (obj) { var name = obj.name; if (name === 'url') { if (this.fontFace) { this.inlineUrl(obj); } else if (this.currDeclaration) { var name = this.currDeclaration.property; if (name === 'background-image') { this.inlineUrl(obj); } } } }, declaration (obj) { var declWas = this.declaration; this.currDeclaration = obj; obj.descend(this); this.currDeclaration = declWas }, ruleset (obj) { var ffWas = this.fontFace, rulesetWas = this.currRuleset; this.currRuleset = obj; if (obj.isAtRule()) { if (obj.getFirstSelectorStr() === '@font-face') { this.fontFace = obj; } } obj.descend(this); this.currRuleset = rulesetWas; this.fontFace = ffWas; }, execute (obj, ctx) { this.context = ctx; this.basePath = runtime.context.getConfig('basePath'); var config = runtime.context.getConfig('inliner'); if (config && config.enable) { if (config.report) { report = config.report; } if (config.excludes) { for (var i = 0; i < config.excludes.length; i++) { excludes.push(new RegExp(config.excludes[i])); } } if (config.includes) { for (var i = 0; i < config.includes.length; i++) { includes.push(new RegExp(config.includes[i])); } } maxItemSize = config.maxItemSize || -1; this.visit(obj); } } }); } };