Skip to content

Commit

Permalink
Fix issues with eslint.
Browse files Browse the repository at this point in the history
  • Loading branch information
jonkemp committed Dec 11, 2015
1 parent a9bf04f commit 9cb1aa6
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 97 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"no-loop-func": 2,
"no-multi-spaces": 2,
"no-multi-str": 2,
"no-param-reassign": 2,
"no-param-reassign": 1,
"no-unused-expressions": 2,
"no-useless-call": 2,
"no-useless-concat": 2,
Expand Down
25 changes: 13 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ var extractCss = require('extract-css'),
Promise = require('bluebird');

function extend(obj, src) {
var own = {}.hasOwnProperty;
var key,
own = {}.hasOwnProperty;

for (var key in src) {
for (key in src) {
if (own.call(src, key)) {
obj[key] = src[key];
}
Expand Down Expand Up @@ -39,16 +40,16 @@ function inlineContent(src, options) {
module.exports = function (html, options) {
return new Promise(function (resolve, reject) {
var opt = extend({
extraCss: '',
applyStyleTags: true,
removeStyleTags: true,
applyLinkTags: true,
removeLinkTags: true,
preserveMediaQueries: false,
removeHtmlSelectors: false,
applyWidthAttributes: false,
applyTableAttributes: false
}, options);
extraCss: '',
applyStyleTags: true,
removeStyleTags: true,
applyLinkTags: true,
removeLinkTags: true,
preserveMediaQueries: false,
removeHtmlSelectors: false,
applyWidthAttributes: false,
applyTableAttributes: false
}, options);

inlineContent(html, opt)
.then(function (data) {
Expand Down
191 changes: 107 additions & 84 deletions lib/inline-css.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,35 @@ var parseCSS = require('css-rules'),
cheerio = require('cheerio'),
Selector = require('style-selector'),
Property = require('css-property'),
styleSelector = new Selector('<style attribute>', [1, 0, 0, 0]),
importantSelector = new Selector('<!important>', [2, 0, 0, 0]),
ignoredPseudos = ['hover', 'active', 'focus', 'visited', 'link'],
widthElements = ['table', 'td', 'img'];

var tableStyleAttrMap = {
'table': {
'float': 'align',
'background-color': 'bgcolor',
'width': 'width',
'height': 'height'
},
'tr': {
'background-color': 'bgcolor',
'vertical-align': 'valign',
'text-align': 'align'
},
'td,th': {
'background-color': 'bgcolor',
'width': 'width',
'height': 'height',
'vertical-align': 'valign',
'text-align': 'align',
'white-space': 'nowrap'
},
'tbody,thead,tfoot': {
'vertical-align': 'valign',
'text-align': 'align'
}
};
styleSelector = new Selector('<style attribute>', [ 1, 0, 0, 0 ]),
importantSelector = new Selector('<!important>', [ 2, 0, 0, 0 ]),
ignoredPseudos = [ 'hover', 'active', 'focus', 'visited', 'link' ],
widthElements = [ 'table', 'td', 'img' ],
tableStyleAttrMap = {
'table': {
'float': 'align',
'background-color': 'bgcolor',
'width': 'width',
'height': 'height'
},
'tr': {
'background-color': 'bgcolor',
'vertical-align': 'valign',
'text-align': 'align'
},
'td,th': {
'background-color': 'bgcolor',
'width': 'width',
'height': 'height',
'vertical-align': 'valign',
'text-align': 'align',
'white-space': 'nowrap'
},
'tbody,thead,tfoot': {
'vertical-align': 'valign',
'text-align': 'align'
}
};

module.exports = function (html, css, options) {
var rules = parseCSS(css),
Expand All @@ -42,20 +41,55 @@ module.exports = function (html, css, options) {
decodeEntities: false
});

// go through the properties
function addProps(el, style, selector) {
var i,
l = style.length,
name,
value,
sel,
prop,
existing,
winner;

for (i = 0; i < l; i++) {
name = style[i];
value = style[name];
sel = style._importants[name] ? importantSelector : selector;
prop = new Property(name, value, sel);
existing = el.styleProps[name];

if (existing) {
winner = existing.compare(prop);

if (winner === prop) {
el.styleProps[name] = prop;
}
} else {
el.styleProps[name] = prop;
}
}
}

function handleRule(rule) {
var sel = rule[0],
style = rule[1],
selector = new Selector(sel);
var i,
j,
subSel,
subSelPseudo,
sel = rule[0],
style = rule[1],
selector = new Selector(sel),
$els;

// skip rule if the selector has any pseudos which are ignored
var parsedSelector = selector.parsed();

for (var i = 0; i < parsedSelector.length; ++i) {
var subSel = parsedSelector[i];
for (i = 0; i < parsedSelector.length; ++i) {
subSel = parsedSelector[i];

if (subSel.pseudos) {
for (var j = 0; j < subSel.pseudos.length; ++j) {
var subSelPseudo = subSel.pseudos[j];
for (j = 0; j < subSel.pseudos.length; ++j) {
subSelPseudo = subSel.pseudos[j];

if (ignoredPseudos.indexOf(subSelPseudo.name) >= 0) {
return;
Expand All @@ -64,86 +98,67 @@ module.exports = function (html, css, options) {
}
}

var $els;

try {
$els = $(sel);
} catch (err) {
// skip invalid selector
return;
}

$els.each(function (index, el) {
// go through the properties
function addProps(style, selector) {
for (var i = 0, l = style.length; i < l; i++) {
var name = style[i],
value = style[name],
sel = style._importants[name] ? importantSelector : selector,
prop = new Property(name, value, sel),
existing = el.styleProps[name],
winner,
loser;

if (existing) {
winner = existing.compare(prop);
loser = prop === winner ? existing : prop;

if (winner === prop) {
el.styleProps[name] = prop;
}
} else {
el.styleProps[name] = prop;
}
}
}
var cssText;

if (!el.styleProps) {
el.styleProps = {};

// if the element has inline styles, fake selector with topmost specificity
if ($(el).attr('style')) {
var cssText = '* { ' + $(el).attr('style') + ' } ';
cssText = '* { ' + $(el).attr('style') + ' } ';

addProps(parseCSS(cssText)[0][1], styleSelector);
addProps(el, parseCSS(cssText)[0][1], styleSelector);
}

// store reference to an element we need to compile style="" attr for
editedElements.push(el);
}

addProps(style, selector);
addProps(el, style, selector);
});
}

function setStyleAttrs(el) {
var style = [];
var i,
style = [];

for (var i in el.styleProps) {
for (i in el.styleProps) {

// add !important
if (typeof el.styleProps[i].selector.spec !== 'undefined') {
if (el.styleProps[i].selector.spec[0] === 2) {
el.styleProps[i].value = el.styleProps[i].value + ' !important';
el.styleProps[i].value += ' !important';
}
}
style.push(el.styleProps[i].prop + ': ' + el.styleProps[i].value.replace(/["]/g, '\'') + ';');
}

// sorting will arrange styles like padding: before padding-bottom: which will preserve the expected styling
style = style.sort(function (a, b) {
var aProp = a.split(':')[0];
var bProp = b.split(':')[0];
var aProp = a.split(':')[0],
bProp = b.split(':')[0];

return (aProp > bProp ? 1 : aProp < bProp ? -1 : 0);
});
$(el).attr('style', style.join(' '));
}

function setWidthAttrs(el) {
var i,
pxWidth;

if (widthElements.indexOf(el.name) > -1) {
for (var i in el.styleProps) {
for (i in el.styleProps) {
if (el.styleProps[i].prop === 'width' && el.styleProps[i].value.match(/px/)) {
var pxWidth = el.styleProps[i].value.replace('px', '');
pxWidth = el.styleProps[i].value.replace('px', '');

$(el).attr('width', pxWidth);
return;
Expand All @@ -153,7 +168,7 @@ module.exports = function (html, css, options) {
}

function removeHtmlSelectors(el) {
var selectors = ['class', 'id'];
var selectors = [ 'class', 'id' ];

selectors.forEach(function (selector) {
var attribute = $(el).attr(selector);
Expand All @@ -165,17 +180,28 @@ module.exports = function (html, css, options) {
}

function applyStylesAsProps($el, styleToAttrMap) {
for (var style in styleToAttrMap) {
var styleVal = $el.css(style);
if (styleVal != undefined) {
var style,
styleVal;

for (style in styleToAttrMap) {
styleVal = $el.css(style);

if (styleVal !== undefined) {
$el.attr(styleToAttrMap[style], styleVal);
$el.css(style, '');
}
}
}

function setTableAttrs(index, el) {
var $el = $(el);
var selector,
$el = $(el);

function batchApplyStylesAsProps(sel) {
$el.find(selector).each(function (i, childEl) {
applyStylesAsProps($(childEl), tableStyleAttrMap[sel]);
});
}

if (!$el.attr('border')) {
$el.attr('border', 0);
Expand All @@ -188,14 +214,11 @@ module.exports = function (html, css, options) {
}



for (var selector in tableStyleAttrMap){
if (selector == 'table'){
applyStylesAsProps($el, tableStyleAttrMap['table']);
for (selector in tableStyleAttrMap) {
if (selector === 'table') {
applyStylesAsProps($el, tableStyleAttrMap.table);
} else {
$el.find(selector).each(function(i, childEl){
applyStylesAsProps($(childEl), tableStyleAttrMap[selector]);
});
batchApplyStylesAsProps(selector);
}
}
}
Expand Down

0 comments on commit 9cb1aa6

Please sign in to comment.