Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add inlineStyles plugin (rewrite of localStyles plugin) #592

Merged
merged 167 commits into from Oct 22, 2017
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
167 commits
Select commit Hold shift + click to select a range
87b7bb0
Add plugin file.
strarsis Sep 6, 2016
298c072
Remove unused requires.
strarsis Sep 6, 2016
b4c8df9
Add package dependencies required by inlineStyles plugin.
strarsis Sep 6, 2016
34e6bfa
Fix jshint error / improve code + comment.
strarsis Sep 6, 2016
b68892b
Add inlineStyles plugin to enabled plugins list in svgo default config.
strarsis Sep 6, 2016
bf29ceb
Add missing cheerio package dependency.
strarsis Sep 6, 2016
fe759cb
Add test + fix for properly handling empty style elements.
strarsis Sep 6, 2016
8ef17ee
Fix css rule match logic.
strarsis Sep 6, 2016
5bfd498
Add second test for removing classes that only match once or not at all.
strarsis Sep 6, 2016
3615c0e
Migrate to csso instead css parser.
strarsis Sep 6, 2016
5d1f98d
Adjust test 2 expected output to normal csso output.
strarsis Sep 6, 2016
46aeebe
Add further tests.
strarsis Sep 6, 2016
f16abbf
Improve comment cosmetically.
strarsis Sep 6, 2016
814369d
Add code for removing style elements that now got empty content.
strarsis Sep 6, 2016
a3cec04
Move string trim() to condition in order to preserve subtleties in cs…
strarsis Sep 6, 2016
86cc454
Use juice options key.
strarsis Oct 6, 2016
65836b7
Fix context.
strarsis Oct 6, 2016
c809447
Fix jshint error.
strarsis Oct 6, 2016
a69b35b
Move to cheerio-support code to lib/.
strarsis Oct 10, 2016
2fb2be9
Remove juice module for now until node compatibility issue with juice…
strarsis Oct 10, 2016
5a7af23
Implement alternative inlining code (without juice).
strarsis Oct 10, 2016
a1f1e32
Implement feature for skipping selectors that match more than once.
strarsis Oct 10, 2016
30f01a2
Fix jshint errors.
strarsis Oct 10, 2016
91554ef
Fix jshint issue on node v0.12.x.
strarsis Oct 10, 2016
e123e29
Improve comment.
strarsis Oct 13, 2016
ebcd712
Add comments.
strarsis Oct 13, 2016
6740ab0
Use for-in loops instead for-of loops for compatibility for node 0.10.
strarsis Oct 13, 2016
150868d
Replace juice with css-select.
strarsis Nov 18, 2016
193d93b
Adjust plugin to use new css-select adapter option, remove mocking.
strarsis Nov 18, 2016
92c5c48
Use more clear syntax for tag check.
strarsis Nov 18, 2016
2104ad4
Improve code.
strarsis Nov 18, 2016
e5dc5ba
Add missing existsOne implementation.
strarsis Nov 18, 2016
1d63cc0
Match up adapter code to adapter example code in css-select README.
strarsis Nov 18, 2016
7897ed7
Use terminology (node/elem) from adapter example in css-select README.
strarsis Nov 18, 2016
3f31b34
Add/improve TODO comment remarks.
strarsis Nov 18, 2016
8bc26fe
Remove TODO for getSiblings (resolved).
strarsis Nov 19, 2016
19a19c5
Improve comments.
strarsis Nov 19, 2016
f3d5de0
Cosmetic comment improvements.
strarsis Nov 19, 2016
c7b46d5
Fix + simplify css-select adapter.
strarsis Nov 20, 2016
b3853c8
Use css-select base adapter for reducing required csso adapter code.
strarsis Nov 20, 2016
941b6ca
Cosmetic comment change.
strarsis Nov 20, 2016
b6dd3d1
Add object.assign shim for node v0.1x support.
strarsis Nov 20, 2016
8862918
Fix/improve csso API usage in adapter.
strarsis Nov 20, 2016
57b84a8
Change css-select-base-adapter package source to npm.
strarsis Nov 20, 2016
297f394
Improve svgo API usage.
strarsis Nov 21, 2016
3e54b1c
Move to own css selection method.
strarsis Nov 21, 2016
f37d589
Add / improve comments.
strarsis Nov 21, 2016
01d16f1
Use better emtpy <style/> check.
strarsis Nov 21, 2016
fe49aa7
Improve comment.
strarsis Nov 21, 2016
f7adbc4
Improve code.
strarsis Nov 22, 2016
af8a2ac
Replace parent references with parent node search function.
strarsis Nov 25, 2016
913c380
Cosmetic code changes.
strarsis Nov 25, 2016
821c3f2
Fix getText method.
strarsis Nov 27, 2016
279431b
Let adapter methods return null when single node/attribute is expecte…
strarsis Nov 27, 2016
7ea1b95
Fix for non-existing style attribute in target element
strarsis Dec 6, 2016
b3ddf64
Cosmetic code change.
strarsis Dec 6, 2016
3c0dc05
Improve comments.
strarsis Dec 9, 2016
5da1482
Improve variable names.
strarsis Dec 9, 2016
73fcd3c
Add support for mediaqueries.
strarsis Dec 9, 2016
28271b4
Add test for mediaqueries.
strarsis Dec 9, 2016
2ef6a97
Update css-select package dependency reference.
strarsis Dec 9, 2016
f6e5f40
Use native spliceContent method.
strarsis Dec 11, 2016
f4b3c58
Remove findParent(...) as jsAPI parentNode property already reference…
strarsis Dec 11, 2016
f5c1003
Add proper specificity handling for !important.
strarsis Dec 11, 2016
0019773
Fix !important handling/sorting.
strarsis Dec 12, 2016
a33efc8
Improve variable/function names.
strarsis Dec 12, 2016
123f94a
Add test for issue https://github.com/svg/svgo/pull/592#issuecomment-…
strarsis Dec 12, 2016
e371ef3
Fix jshint unused variable error.
strarsis Dec 12, 2016
f222530
Add fix for leaking declaration references (csso.translate(...)).
strarsis Dec 12, 2016
a336b3c
Remove !important removal for inline styles (inline-relative specific…
strarsis Dec 12, 2016
82eab75
Adjust test.
strarsis Dec 12, 2016
94d36fe
Use more systematic tests.
strarsis Dec 12, 2016
f5eed30
Simplify loops to one.
strarsis Dec 13, 2016
f9eda39
Add test + support for styles in CDATA.
strarsis Dec 13, 2016
5688e3b
Improve comment.
strarsis Dec 13, 2016
ccff9b2
Improve code.
strarsis Dec 13, 2016
8784548
Fix !important(ce) sorting + tests.
strarsis Dec 13, 2016
cc27c46
Simplified select-css method + adapter.
strarsis Dec 14, 2016
6709815
Add comment to test.
strarsis Dec 14, 2016
e79a0d5
Remove unnecessary line.
strarsis Dec 14, 2016
49eb9f6
Cosmetic code changes.
strarsis Dec 14, 2016
43aba2f
Cosmetic code changes.
strarsis Dec 14, 2016
2b0ad6b
Move css query feature into svgo core (jsAPI).
strarsis Dec 14, 2016
da20869
Improve comment.
strarsis Dec 14, 2016
94651a0
Cosmetic code change.
strarsis Dec 14, 2016
c096aa0
Rename querySelector to querySelectorAll so it matches its DOM API eq…
strarsis Dec 18, 2016
3e2ccb4
Move css-select options to variable in jsAPI.
strarsis Dec 18, 2016
56a229c
Add further DOM API CSS related methods.
strarsis Dec 18, 2016
b3e085d
Rename data variable to document as it is more intuitive.
strarsis Dec 19, 2016
a67ed53
Improve css-select adapter module file name.
strarsis Dec 19, 2016
db20f5b
Add further css select adapter API related comments.
strarsis Jan 2, 2017
cedfda2
Use latest npm package for css-select dependency.
strarsis Jan 19, 2017
a794897
Add support for pseudo classes.
strarsis Jan 21, 2017
5dd38da
Improve variable names.
strarsis Jan 21, 2017
5beb962
Fix lint error.
strarsis Jan 21, 2017
c90ac18
Simplify selector structure/flattening.
strarsis Jan 21, 2017
3964dc4
Improve comment.
strarsis Jan 21, 2017
1c7240a
Add comments for documenting options.
strarsis Jan 26, 2017
5c3b65a
Merge branch 'master' into inlineStyles
strarsis Jan 30, 2017
e9e2be9
Fix syntax error.
strarsis Jan 30, 2017
c8241c4
Remove PseudoClass to use from its SimpleSelector for proper matching…
strarsis Feb 1, 2017
b6d6c35
Use lowercase for specificity module variable.
strarsis Feb 1, 2017
6167206
Add logic handling Atrules without styles (like @import).
strarsis Feb 11, 2017
350bf74
Change to strict equals.
strarsis Feb 11, 2017
c130ecc
Use isEmpty() instead null check.
strarsis Feb 11, 2017
aa7a786
Improve test for Atrules.
strarsis Feb 11, 2017
ab1c8bb
Add fix for some Atrules.
strarsis Feb 11, 2017
ed029c5
Add test for complex mediaquery + <defs/>.
strarsis Feb 11, 2017
de85b0f
Add clean up for empty <defs/>.
strarsis Feb 11, 2017
30569d1
Add Atrules with nesting to Atrules test.
strarsis Feb 11, 2017
57601a9
Gracefully skipping troubling selectors.
strarsis Feb 25, 2017
634cb43
Replace specificity calculation with built-in csso one.
strarsis Feb 25, 2017
92b692e
Fix phpdoc.
strarsis Feb 25, 2017
cb069be
Remove unnecessary loop.
strarsis Feb 26, 2017
23e6b0a
Adjust tests to new CSSStyleDeclarations setting (deduplicated styles…
strarsis Mar 18, 2017
2a7f45a
Implement new CSSStyleDeclarations interface.
strarsis Mar 18, 2017
57827dd
Remove console.log(...).
strarsis Mar 18, 2017
58ea1bd
Add loop skip.
strarsis Mar 18, 2017
6117cd4
Fix loop continue.
strarsis Mar 18, 2017
1fa6197
Disable unneeded parse options, adjust tests to slightly different st…
strarsis Mar 18, 2017
2d82153
Remove unnecessary explicit stylesheet context.
strarsis Mar 18, 2017
c50aea5
Simplify getCssText().
strarsis Mar 18, 2017
a678f6d
Simpler cssoToStyleDeclaration(...) return object.
strarsis Mar 18, 2017
d123b9d
Fix indent.
strarsis Mar 18, 2017
4a19b9b
Simplify cleanPseudos(...).
strarsis Mar 18, 2017
b8a7fe8
Simplify filterByPseudos(...).
strarsis Mar 18, 2017
df4752a
Simplify/improve flattenToSelectors(...).
strarsis Mar 19, 2017
52819cf
Translate mq expression ast only when it is of MediaQueryList type.
strarsis Mar 19, 2017
11ab2c5
Fix jshint error.
strarsis Mar 19, 2017
16cc3aa
Disable unneeded parse options.
strarsis Mar 19, 2017
c12bc17
Add extra getProperties method.
strarsis Mar 19, 2017
8af462b
Use getters/setters for integration.
strarsis Mar 20, 2017
25fd3ac
Adjust test to slightly different styles output format.
strarsis Mar 20, 2017
907bef2
Clean up debug code.
strarsis Mar 20, 2017
3d2450c
Use proposed code for pseudo selector children array.
strarsis Mar 20, 2017
4f47d7d
Improve cache validations.
strarsis Mar 20, 2017
b92236d
Remove unnecessary map get(...).
strarsis Mar 20, 2017
2d91c97
Improve getCssText().
strarsis Mar 20, 2017
13a81ec
Fix style caching.
strarsis Mar 20, 2017
4f40972
Adjust tests to different style output.
strarsis Mar 20, 2017
bb01e68
Use strict comparisons.
strarsis Mar 20, 2017
cd17121
Improve warnings.
strarsis Mar 20, 2017
ecad2d7
Improve exception handling.
strarsis Mar 20, 2017
eb9de31
Remove now unneeded object.assign shim.
strarsis Mar 21, 2017
af0e638
Merge branch 'master' into inlineStyles
strarsis Mar 22, 2017
0ae071e
Update inlineStyles.js
strarsis Mar 22, 2017
3312973
Clean up superfluous code from last merge.
strarsis Mar 22, 2017
82c277e
Fix arguments.
strarsis Mar 23, 2017
a3f17d9
Add jsdocs.
strarsis Mar 23, 2017
e6dbda6
Add + improve jdoc.
strarsis Mar 23, 2017
9792063
Add newline to end of file.
strarsis Apr 3, 2017
751dad0
Lock css-tree package version.
strarsis Apr 3, 2017
d212cee
Fix indents/formatting.
strarsis Apr 3, 2017
baa1ffe
Improve require of csstree List.
strarsis Apr 3, 2017
d909bb5
Use css-tree npm release.
strarsis Apr 3, 2017
ec35e22
Clean up csso prefixes.
strarsis Apr 3, 2017
1bc5542
Pin css-tree to alpha18.
strarsis Apr 3, 2017
935e195
Merge remote-tracking branch 'upstream/master' into inlineStyles
strarsis Apr 4, 2017
64106c2
Adjust test to style output format.
strarsis Apr 4, 2017
f45c1f3
Add some css-style-declaration integration improvements.
strarsis Apr 14, 2017
ec6ac96
Improve handling of indexOf boolean.
strarsis Apr 17, 2017
a8237a1
Add csstools methods for better getting/setting CSS strings of style …
strarsis Apr 20, 2017
5dfc185
Merge branch 'master' into inlineStyles
strarsis Sep 5, 2017
912dd08
Add clean up for class + ID attributes, adjust tests.
strarsis Sep 8, 2017
165fec4
Fix test 03.
strarsis Sep 8, 2017
43dae25
Update css-tree to alpha22.
strarsis Sep 8, 2017
a7f79b1
Merge branch 'master' into inlineStyles
strarsis Oct 21, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .svgo.yml
Expand Up @@ -23,6 +23,7 @@ plugins:
- removeXMLNS
- removeEditorsNSData
- cleanupAttrs
- inlineStyles
- minifyStyles
- convertStyleToAttrs
- cleanupIDs
Expand Down
11 changes: 7 additions & 4 deletions package.json
Expand Up @@ -48,13 +48,16 @@
"jshint": "jshint --show-non-errors ."
},
"dependencies": {
"sax": "~1.2.1",
"cheerio": "^0.22.0",
"coa": "~1.0.1",
"js-yaml": "~3.6.1",
"colors": "~1.1.2",
"whet.extend": "~0.9.9",
"css": "^2.2.1",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CSSO also has a parser (but probably with a bit different AST), so it could be reused without adding dependency.

"csso": "~2.2.1",
"js-yaml": "~3.6.1",
"juice": "^2.0.0",
"mkdirp": "~0.5.1",
"csso": "~2.2.1"
"sax": "~1.2.1",
"whet.extend": "~0.9.9"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what.extend was removed here: 4495a34

Copy link
Contributor Author

@strarsis strarsis Jun 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexjlockwood: Should I merge this change into this PR branch?
No merge conflicts are reported, so it can be automatically merged in?

},
"devDependencies": {
"mocha": "~3.0.2",
Expand Down
246 changes: 246 additions & 0 deletions plugins/inlineStyles.js
@@ -0,0 +1,246 @@
'use strict';

exports.type = 'full';

exports.active = true;

exports.params = {
juice: {}
};

exports.description = 'moves styles from <style> to element styles';


var cssParser = require('css'),
cheerio = require('cheerio'),
juice = require('juice'),
JSAPI = require('../lib/svgo/jsAPI.js');


function monkeysSvgo(item, callFn, arg) {
item.content.forEach(function(childItem) {
if(callFn(item, childItem, arg) && !childItem.isEmpty()) { // recurse
monkeysSvgo(childItem, callFn, arg);
}
});
}

function isSvgoElem(elem) {
return typeof elem !== 'undefined';
}

function cheerioLoadXml(xml) {
return cheerio.load(xml, { xmlMode: true });
}
function getXmlTag(elem) {
return '<' + elem + '>';
}
function makeCheerioElem(elem) {
return cheerioLoadXml(getXmlTag(elem));
}
function makeCheerioInst(elem) {
return makeCheerioElem(elem)(elem);
}

function parsePrefixable(fullName) {
var a = fullName.split(':');
if(a.length == 1) {
return { name: a[0] };
}
return { prefix: a[0], name: a[1] };
}

function processSvgoElem(pae, ae, $) {
// note: <xml> element skipped by svgo parser

if(pae.elem == '#document') {
pae.$ = $; // attach top cheerio ast node to top svgo ast node
}

var textToElem = pae;
if(isSvgoElem(ae.elem)) {
var nameInfo = parsePrefixable(ae.elem);

ae.$ = makeCheerioInst(nameInfo.name);
pae.$.append(ae.$);

if(ae.attrs && Object.keys(ae.attrs).length > 0) {
for(var attrKey in ae.attrs) {
var attr = ae.attrs[attrKey];

var attrNamePrefixed = '';
if(attr.prefix) {
attrNamePrefixed = attr.prefix + ':';
}
attrNamePrefixed = attrNamePrefixed + attr.name;

ae.$.attr(attrNamePrefixed, attr.value);
}
}

if(nameInfo.prefix) {
ae.$.prefix = nameInfo.prefix;
}

textToElem = ae;
}

if(typeof ae.text !== 'undefined') {
textToElem.$.text(ae.text);
}

return true;
}

function createEmptyCheerioDoc() {
var document = makeCheerioElem('dummy');
var $document = document.root().empty();
return $document;
}

function svgoAst2CheerioAst(data) {
var $document = createEmptyCheerioDoc();
monkeysSvgo(data, processSvgoElem, $document);
return $document;
}


function monkeysCheerio($item, callFn, arg) {
if(typeof $item.children === 'object') {
for(var childItemIndex in $item.children) {
var $childItem = $item.children[ childItemIndex ];
if(callFn($item, $childItem, arg) && $item.children.length > 0) { // recurse
monkeysCheerio($childItem, callFn, arg);
}
}
} else if(typeof $item.children === 'function') {
$item.children().each(function(childItemIndex, $childItem) {
if(callFn($item, $childItem, arg) && $item.children.length > 0) { // "
monkeysCheerio($childItem, callFn, arg);
}
});
} else {
return;
}
}

function isCheerioElem($elem) {
return typeof $elem !== 'undefined';
}
function isCheerioText($elem) {
return $elem.type == 'text';
}

function makeSvgoElem(elem, parentElem) {
return new JSAPI({ elem: elem }, parentElem);
}
function makeSvgoText(text, parentElem) {
return new JSAPI({ text: text }, parentElem);
}

function processCheerioElem($pae, $ae, s) {

if($pae.name == 'root') {
$pae.s = s; // attach top svgo ast node to top cheerio ast node
}

var $textToElem = $pae;
if(isCheerioElem($ae) && !isCheerioText($ae)) {
$ae.s = makeSvgoElem($ae.name, $pae.s);

$pae.s.content = $pae.s.content || [];
$pae.s.content.push($ae.s);


if($ae.attribs && Object.keys($ae.attribs).length > 0) {
for(var attrName in $ae.attribs) {
var attrValue = $ae.attribs[attrName];
var attrNameInfo = parsePrefixable(attrName);
$ae.s.addAttr({
name: attrNameInfo.name,
prefix: attrNameInfo.prefix || '', // explicit empty string otherwise expected
local: attrNameInfo.name,
value: attrValue
});
}
}

$textToElem = $ae;
}


if(isCheerioText($ae)) {
$pae.s.content = $pae.s.content || [];

$textToElem.s.content.push( makeSvgoText($ae.data, $pae.s) );
}

return true;
}

function cheerioAst2SvgoAst($) {
var data = makeSvgoElem('#document');
var $document = $.root()[0];
monkeysCheerio($document, processCheerioElem, data);
return data;
}




/**
* Moves styles from <style> to element styles
*
* @author strarsis <strarsis@gmail.com>
*/
exports.fn = function(data, svgoOptions) {

// svgo ast to cheerio ast
var $o = svgoAst2CheerioAst(data);
var $ = cheerioLoadXml($o.html());


// juice options required for svg and css classes cleanup
svgoOptions.xmlMode = true;
svgoOptions.removeStyleTags = false;

var $i = juice.juiceDocument($, svgoOptions);


// as last step, remove classes when they are used only by one element in document:
var $styles = $('style');
$styles.each(function(si, $style) {
if($style.children.length == 0) {
return;
}

var css = $style.children[0].data;
var cssAst = cssParser.parse(css);

var cssRules = cssAst.stylesheet.rules;
cssRules.forEach(function(cssRule, cssRuleIndex) {
if(cssRule.type != 'rule') {
return;
}

cssRule.selectors.forEach(function(selector, selectorIndex) {
var $matches = $i(selector);
if($matches.length <= 1) { // if matches only once or not at all
cssRule.selectors.splice(selectorIndex, 1);
}
});

if(cssRule.selectors.length == 0) { // clean up rules without any selectors left
cssRules.splice(cssRuleIndex, 1);
}
});

var newCss = cssParser.stringify(cssAst);
$style.children[0].data = newCss;
});


var dataNew = cheerioAst2SvgoAst($i);

return dataNew;
};
13 changes: 13 additions & 0 deletions test/plugins/inlineStyles.01.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions test/plugins/inlineStyles.02.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.