Socket
Socket
Sign inDemoInstall

inline-css

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

inline-css - npm Package Compare versions

Comparing version 2.1.0 to 2.1.1

.npmignore

51

index.js
'use strict';
var extractCss = require('extract-css'),
inlineCss = require('./lib/inline-css'),
Promise = require('bluebird');
var Promise = require('bluebird'),
inlineContent = require('./lib/inlineContent');
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)) {

@@ -18,36 +18,15 @@ obj[key] = src[key];

function inlineContent(src, options) {
return new Promise(function (resolve, reject) {
var content;
if (!options.url) {
reject('options.url is required');
}
extractCss(src, options, function (err, html, css) {
if (err) {
return reject(err);
}
css += '\n' + options.extraCss;
content = inlineCss(html, css, options);
resolve(content);
});
});
}
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);

@@ -54,0 +33,0 @@ inlineContent(html, opt)

@@ -5,37 +5,13 @@ 'use strict';

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'];
pseudoCheck = require('./pseudoCheck'),
handleRule = require('./handleRule'),
flatten = require('flatten'),
setStyleAttrs = require('./setStyleAttrs'),
setWidthAttrs = require('./setWidthAttrs'),
removeClassId = require('./removeClassId'),
setTableAttrs = require('./setTableAttrs');
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'
}
};
module.exports = function (html, css, options) {
var rules = parseCSS(css),
var opts = options || {},
rules = parseCSS(css),
editedElements = [],

@@ -46,177 +22,44 @@ $ = cheerio.load(html, {

function handleRule(rule) {
var sel = rule[0],
style = rule[1],
selector = new Selector(sel);
rules.forEach(function (rule) {
var el,
ignoredPseudos;
// skip rule if the selector has any pseudos which are ignored
var parsedSelector = selector.parsed();
ignoredPseudos = pseudoCheck(rule);
for (var i = 0; i < parsedSelector.length; ++i) {
var subSel = parsedSelector[i];
if (subSel.pseudos) {
for (var j = 0; j < subSel.pseudos.length; ++j) {
var subSelPseudo = subSel.pseudos[j];
if (ignoredPseudos.indexOf(subSelPseudo.name) >= 0) {
return;
}
}
}
if (ignoredPseudos) {
return false;
}
var $els;
try {
el = handleRule(rule, $);
try {
$els = $(sel);
editedElements.push(el);
} catch (err) {
// skip invalid selector
return;
return false;
}
$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;
// flatten array if nested
editedElements = flatten(editedElements);
if (winner === prop) {
el.styleProps[name] = prop;
}
} else {
el.styleProps[name] = prop;
}
}
}
editedElements.forEach(function (el) {
setStyleAttrs(el, $);
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') + ' } ';
addProps(parseCSS(cssText)[0][1], styleSelector);
}
// store reference to an element we need to compile style="" attr for
editedElements.push(el);
}
addProps(style, selector);
});
}
function setStyleAttrs(el) {
var style = [];
for (var 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';
}
}
style.push(el.styleProps[i].prop + ': ' + el.styleProps[i].value.replace(/["]/g, '\'') + ';');
if (opts.applyWidthAttributes) {
setWidthAttrs(el, $);
}
// 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];
return (aProp > bProp ? 1 : aProp < bProp ? -1 : 0);
});
$(el).attr('style', style.join(' '));
}
function setWidthAttrs(el) {
if (widthElements.indexOf(el.name) > -1) {
for (var i in el.styleProps) {
if (el.styleProps[i].prop === 'width' && el.styleProps[i].value.match(/px/)) {
var pxWidth = el.styleProps[i].value.replace('px', '');
$(el).attr('width', pxWidth);
return;
}
}
if (opts.removeHtmlSelectors) {
removeClassId(el, $);
}
}
});
function removeHtmlSelectors(el) {
var selectors = ['class', 'id'];
selectors.forEach(function (selector) {
var attribute = $(el).attr(selector);
if (typeof attribute !== 'undefined') {
$(el).removeAttr(selector);
}
if (opts.applyTableAttributes) {
$('table').each(function (index, el) {
setTableAttrs(el, $);
});
}
function applyStylesAsProps($el, styleToAttrMap) {
for (var style in styleToAttrMap) {
var styleVal = $el.css(style);
if (styleVal != undefined) {
$el.attr(styleToAttrMap[style], styleVal);
$el.css(style, '');
}
}
}
function setTableAttrs(index, el) {
var $el = $(el);
if (!$el.attr('border')) {
$el.attr('border', 0);
}
if (!$el.attr('cellpadding')) {
$el.attr('cellpadding', 0);
}
if (!$el.attr('cellspacing')) {
$el.attr('cellspacing', 0);
}
for (var selector in tableStyleAttrMap){
if (selector == 'table'){
applyStylesAsProps($el, tableStyleAttrMap['table']);
} else {
$el.find(selector).each(function(i, childEl){
applyStylesAsProps($(childEl), tableStyleAttrMap[selector]);
});
}
}
}
rules.forEach(handleRule);
editedElements.forEach(setStyleAttrs);
if (options) {
if (options.applyWidthAttributes) {
editedElements.forEach(setWidthAttrs);
}
if (options.applyTableAttributes) {
$('table').each(setTableAttrs);
}
}
if (options && options.removeHtmlSelectors) {
editedElements.forEach(removeHtmlSelectors);
}
return $.html();
};
{
"name": "inline-css",
"version": "2.1.0",
"version": "2.1.1",
"description": "Inline css into an html file.",
"main": "index.js",
"directories": {
"test": "test"
},
"dependencies": {

@@ -12,12 +15,29 @@ "bluebird": "^2.9.25",

"extract-css": "^1.0.0",
"flatten": "0.0.1",
"style-selector": "^1.0.0"
},
"devDependencies": {
"coveralls": "^2.11.6",
"gulp": "^3.9.0",
"gulp-eslint": "^1.1.1",
"gulp-mocha": "^2.0.0",
"gulp-util": "^3.0.2",
"mocha": "^2.1.0",
"nyc": "^5.0.0",
"should": "^5.2.0"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "gulp test",
"coverage": "istanbul cover _mocha --report html -- -R spec && open coverage/index.html"
"test": "mocha",
"lint": "gulp lint",
"coverage": "nyc npm test && nyc report",
"coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls"
},
"repository": {
"type": "git",
"url": "https://github.com/jonkemp/inline-css"
},
"files": [
"index.js",
"lib"
],
"repository": "jonkemp/inline-css",
"keywords": [

@@ -30,17 +50,3 @@ "inline",

"author": "Jonathan Kemp <kempdogg@gmail.com> (http://jonkemp.com/)",
"license": "MIT",
"bugs": {
"url": "https://github.com/jonkemp/inline-css/issues"
},
"homepage": "https://github.com/jonkemp/inline-css",
"devDependencies": {
"gulp": "^3.9.0",
"gulp-jscs": "^3.0.0",
"gulp-jshint": "^1.9.0",
"gulp-mocha": "^2.0.0",
"gulp-util": "^3.0.2",
"istanbul": "0.3.x",
"mocha": "^2.1.0",
"should": "^5.2.0"
}
"license": "MIT"
}

@@ -1,2 +0,2 @@

# inline-css [![npm](http://img.shields.io/npm/v/inline-css.svg?style=flat)](https://badge.fury.io/js/inline-css) [![Build Status](https://travis-ci.org/jonkemp/inline-css.svg?branch=master)](https://travis-ci.org/jonkemp/inline-css)
# inline-css [![npm](http://img.shields.io/npm/v/inline-css.svg?style=flat)](https://badge.fury.io/js/inline-css) [![Build Status](https://travis-ci.org/jonkemp/inline-css.svg?branch=master)](https://travis-ci.org/jonkemp/inline-css) [![Coverage Status](https://coveralls.io/repos/jonkemp/inline-css/badge.svg?branch=master&service=github)](https://coveralls.io/github/jonkemp/inline-css?branch=master)

@@ -152,4 +152,15 @@ [![NPM](https://nodei.co/npm/inline-css.png?downloads=true)](https://nodei.co/npm/inline-css/)

#### options.removeHtmlSelectors
Type: `Boolean`
Default: `false`
Whether to remove the `class` and `id` attributes from the markup.
## Contributing
See the [CONTRIBUTING Guidelines](https://github.com/jonkemp/inline-css/blob/master/CONTRIBUTING.md)
## License
MIT © [Jonathan Kemp](http://jonkemp.com)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc