%PDF- %PDF-
Direktori : /home/opti/workflow/node_modules/juice/lib/ |
Current File : /home/opti/workflow/node_modules/juice/lib/utils.js |
'use strict'; /** * Module dependencies. */ var mensch = require('mensch'); var own = {}.hasOwnProperty; var Selector = require('./selector'); var Property = require('./property'); exports.Selector = Selector; exports.Property = Property; /** * Returns an array of the selectors. * * @license Sizzle CSS Selector Engine - MIT * @param {String} selectorText from mensch * @api public */ exports.extract = function extract(selectorText) { var attr = 0; var sels = []; var sel = ''; for (var i = 0, l = selectorText.length; i < l; i++) { var c = selectorText.charAt(i); if (attr) { if (']' === c || ')' === c) { attr--; } sel += c; } else { if (',' === c) { sels.push(sel); sel = ''; } else { if ('[' === c || '(' === c) { attr++; } if (sel.length || (c !== ',' && c !== '\n' && c !== ' ')) { sel += c; } } } } if (sel.length) { sels.push(sel); } return sels; }; /** * Returns a parse tree for a CSS source. * If it encounters multiple selectors separated by a comma, it splits the * tree. * * @param {String} css source * @api public */ exports.parseCSS = function(css) { var parsed = mensch.parse(css, {position: true, comments: true}); var rules = typeof parsed.stylesheet != 'undefined' && parsed.stylesheet.rules ? parsed.stylesheet.rules : []; var ret = []; for (var i = 0, l = rules.length; i < l; i++) { if (rules[i].type == 'rule') { var rule = rules[i]; var selectors = rule.selectors; for (var ii = 0, ll = selectors.length; ii < ll; ii++) { ret.push([selectors[ii], rule.declarations]); } } } return ret; }; /** * Returns preserved text for a CSS source. * * @param {String} css source * @param {Object} options * @api public */ exports.getPreservedText = function(css, options, ignoredPseudos) { var parsed = mensch.parse(css, {position: true, comments: true}); var rules = typeof parsed.stylesheet != 'undefined' && parsed.stylesheet.rules ? parsed.stylesheet.rules : []; var preserved = []; var lastStart = null; for (var i = rules.length - 1; i >= 0; i--) { if ((options.fontFaces && rules[i].type === 'font-face') || (options.mediaQueries && rules[i].type === 'media') || (options.keyFrames && rules[i].type === 'keyframes') || (options.pseudos && rules[i].selectors && this.matchesPseudo(rules[i].selectors[0], ignoredPseudos))) { preserved.unshift( mensch.stringify( { stylesheet: { rules: [ rules[i] ] }}, { comments: false, indentation: ' ' } ) ); } lastStart = rules[i].position.start; } if (preserved.length === 0) { return false; } return '\n' + preserved.join('\n') + '\n'; }; exports.normalizeLineEndings = function(text) { return text.replace(/\r\n/g, '\n').replace(/\n/g, '\r\n'); }; exports.matchesPseudo = function(needle, haystack) { return haystack.find(function (element) { return needle.indexOf(element) > -1; }) } /** * Compares two specificity vectors, returning the winning one. * * @param {Array} vector a * @param {Array} vector b * @return {Array} * @api public */ exports.compareFunc = function(a, b) { var min = Math.min(a.length, b.length); for (var i = 0; i < min; i++) { if (a[i] === b[i]) { continue; } if (a[i] > b[i]) { return 1; } return -1; } return a.length - b.length; }; exports.compare = function(a, b) { return exports.compareFunc(a, b) == 1 ? a : b; }; exports.extend = function(obj, src) { for (var key in src) { if (own.call(src, key)) { obj[key] = src[key]; } } return obj; }; exports.getDefaultOptions = function(options) { var result = exports.extend({ extraCss: '', insertPreservedExtraCss: true, applyStyleTags: true, removeStyleTags: true, preserveMediaQueries: true, preserveFontFaces: true, preserveKeyFrames: true, preservePseudos: true, applyWidthAttributes: true, applyHeightAttributes: true, applyAttributesTableElements: true, url: '' }, options); result.webResources = result.webResources || {}; return result; };