Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

juice

Package Overview
Dependencies
Maintainers
3
Versions
74
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

juice - npm Package Compare versions

Comparing version 1.0.2 to 1.1.0

6

History.md

@@ -0,1 +1,7 @@

1.1.0 / 2015-05-04
==================
* Fix order of inlined style properties. Now sorted by selector specificity, resulting in the same computed styles that the original CSS would have had.
* Add option to inline pseudo elements as <span> elements
1.0.2 / 2015-04-27

@@ -2,0 +8,0 @@ ==================

117

lib/juice.js

@@ -78,2 +78,6 @@

if (options && options.inlinePseudoElements) {
editedElements.forEach(inlinePseudoElements);
}
if (options && options.applyWidthAttributes) {

@@ -90,6 +94,7 @@ editedElements.forEach(setWidthAttrs);

, style = rule[1]
, selector = new Selector(sel);
, selector = new Selector(sel)
, parsedSelector = selector.parsed()
, pseudoElementType = getPseudoElementType(parsedSelector);
// skip rule if the selector has any pseudos which are ignored
var parsedSelector = selector.parsed();
for (var i = 0; i < parsedSelector.length; ++i) {

@@ -105,2 +110,10 @@ var subSel = parsedSelector[i];

if (pseudoElementType) {
var last = parsedSelector[parsedSelector.length - 1];
var pseudos = last.pseudos;
last.pseudos = filterElementPseudos(last.pseudos),
sel = parsedSelector.toString();
last.pseudos = pseudos;
}
var els;

@@ -113,4 +126,18 @@ try {

}
els.each(function () {
var el = this;
if (pseudoElementType) {
var pseudoElPropName = "pseudo" + pseudoElementType;
var pseudoEl = el[pseudoElPropName];
if (!pseudoEl) {
pseudoEl = el[pseudoElPropName] = $("<span />");
pseudoEl.pseudoElementType = pseudoElementType;
pseudoEl.pseudoElementParent = el;
el[pseudoElPropName] = pseudoEl;
}
el = pseudoEl;
}
if (!el.styleProps) {

@@ -154,16 +181,39 @@ el.styleProps = {}

function setStyleAttrs(el) {
var style = [];
for (var i in el.styleProps) {
style.push(el.styleProps[i].prop + ": " + el.styleProps[i].value.replace(/["]/g, "'") + ";");
var props = Object.keys(el.styleProps).map(function(key) {
return el.styleProps[key];
});
// sort properties by their originating selector's specificity so that
// props like "padding" and "padding-bottom" are resolved as expected.
props.sort(function(a, b) {
return a.selector.specificity().join("").localeCompare(
b.selector.specificity().join(""));
});
var string = props
.filter(function(prop) {
// Content becomes the innerHTML of pseudo elements, not used as a
// style property
return prop.prop !== "content";
})
.map(function(prop) {
return prop.prop + ": " + prop.value.replace(/["]/g, "'") + ";";
})
.join(" ");
if (string) {
$(el).attr('style', string);
}
// 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 inlinePseudoElements(el) {
if (el.pseudoElementType && el.styleProps.content) {
el.html(parseContent(el.styleProps.content.value));
var parent = el.pseudoElementParent;
if (el.pseudoElementType === "before") {
$(parent).prepend(el);
}
else {
$(parent).append(el);
}
}
}
function setWidthAttrs(el) {

@@ -196,2 +246,43 @@ var elName = el.name.toUpperCase();

function parseContent(content) {
if (content === "none" || content === "normal") {
return "";
}
// Naive parsing, assume well-formed value
content = content.slice(1, content.length - 1);
// Naive unescape, assume no unicode char codes
content = content.replace(/\\/g, "");
return content;
}
// Return "before" or "after" if the given selector is a pseudo element (e.g.,
// a::after).
function getPseudoElementType(selector) {
if (selector.length === 0) {
return;
}
var pseudos = selector[selector.length - 1].pseudos;
if (!pseudos) {
return;
}
for (var i = 0; i < pseudos.length; i++) {
if (isPseudoElementName(pseudos[i])) {
return pseudos[i].name;
}
}
}
function isPseudoElementName(pseudo) {
return pseudo.name === "before" || pseudo.name === "after";
}
function filterElementPseudos(pseudos) {
return pseudos.filter(function(pseudo) {
return !isPseudoElementName(pseudo);
});
}
function juiceDocument($, options) {

@@ -198,0 +289,0 @@ options = getDefaultOptions(options);

2

package.json
{
"name": "juice",
"version": "1.0.2",
"version": "1.1.0",
"description": "Inlines css into html source",

@@ -5,0 +5,0 @@ "bin": "./bin/juice",

@@ -53,3 +53,4 @@ [![Build Status](https://travis-ci.org/Automattic/juice.png?branch=master)](https://travis-ci.org/Automattic/juice)

* `applyAttributesTableElements` - whether to create attributes for styles in `juice.styleToAttribute` on elements set in `juice.tableElements`. Defaults to `false`.
* `webResources` - An options object that will be passed through to web-resource-inliner for juice functions that will get remote resources (`juiceResources` and `juiceFile`). Defaults to `{}`.
* `webResources` - An options object that will be passed to [web-resource-inliner](https://www.npmjs.com/package/web-resource-inliner) for juice functions that will get remote resources (`juiceResources` and `juiceFile`). Defaults to `{}`.
* `inlinePseudoElements` - Whether to insert pseudo elements (`::before` and `::after`) as `<span>` into the DOM. *Note*: Inserting pseudo elements will modify the DOM and may conflict with CSS selectors elsewhere on the page (e.g., `:last-child`).

@@ -56,0 +57,0 @@ ### Methods

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