Skip to content
This repository was archived by the owner on Feb 24, 2021. It is now read-only.

Adding SVG recipes as well as modification to cssUsage.js to allow a flag for stripping the url value #55

Closed
wants to merge 14 commits into from
583 changes: 299 additions & 284 deletions Recipe.min.js

Large diffs are not rendered by default.

589 changes: 302 additions & 287 deletions cssUsage.src.js

Large diffs are not rendered by default.

53 changes: 34 additions & 19 deletions src/cssUsage.js
Original file line number Diff line number Diff line change
@@ -602,7 +602,7 @@ void function() { try {
/**
* This will transform a value into an array of value identifiers
*/
function createValueArray(value, propertyName) {
function createValueArray(value, propertyName, stripUrlValue) {

// Trim value on the edges
value = value.trim();
@@ -622,10 +622,15 @@ void function() { try {
value = value.replace(/('|‘|’|")/g, "");
}

// Collapse whitespace
value = value.trim().replace(/\s+/g, " ");

// Divide at commas to separate different font names
value = value.split(/\s*,\s*/g);

// Divide at commas and spaces to separate different values
value = value.split(/\s*(?:,|[/])\s*|\s+/g);
return value;

case '--var':

// Replace strings by dummies
@@ -635,36 +640,45 @@ void function() { try {
// Replace url(...) functions by dummies
value = value.replace(/([a-z]?)[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]*)[)])*[)])*[)])*[)])*[)]/g, "$1()");
value = value.replace(/([a-z]?)[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]*)[)])*[)])*[)])*[)])*[)]/g, "$1()");

// Remove group contents (...), {...} and [...]
value = value.replace(/[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]*)[)])*[)])*[)])*[)])*[)]/g, " <parentheses-block> ");
value = value.replace(/[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]*)[)])*[)])*[)])*[)])*[)]/g, " <parentheses-block> ");
value = value.replace(/[{](?:[^{}]+|[{](?:[^{}]+|[{](?:[^{}]+|[{](?:[^{}]+|[{](?:[^{}]*)[}])*[}])*[}])*[}])*[}]/g, " <curly-brackets-block> ");
value = value.replace(/[{](?:[^{}]+|[{](?:[^{}]+|[{](?:[^{}]+|[{](?:[^{}]+|[{](?:[^{}]*)[}])*[}])*[}])*[}])*[}]/g, " <curly-brackets-block> ");
value = value.replace(/[\[](?:[^\[\]]+|[\[](?:[^\[\]]+|[\[](?:[^\[\]]+|[\[](?:[^\[\]]+|[\[](?:[^\[\]]*)[\]])*[\]])*[\]])*[\]])*[\]]/g, " <square-brackets-block> ");
value = value.replace(/[\[](?:[^\[\]]+|[\[](?:[^\[\]]+|[\[](?:[^\[\]]+|[\[](?:[^\[\]]+|[\[](?:[^\[\]]*)[\]])*[\]])*[\]])*[\]])*[\]]/g, " <square-brackets-block> ");

break;

default:

// Replace strings by dummies
value = value.replace(/"([^"\\]|\\[^"\\]|\\\\|\\")*"/g,' <string> ')
.replace(/'([^'\\]|\\[^'\\]|\\\\|\\')*'/g,' <string> ');

// Replace url(...) functions by dummies
if (value.indexOf("(") != -1) {
value = value.replace(/([a-z]?)[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]*)[)])*[)])*[)])*[)])*[)]/g, "$1() ");
value = value.replace(/([a-z]?)[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]*)[)])*[)])*[)])*[)])*[)]/g, "$1() ");
// Don't divide commas and spaces if we want the inside of Url values
if (stripUrlValue){
// Replace strings by dummies
value = value.replace(/"([^"\\]|\\[^"\\]|\\\\|\\")*"/g,' <string> ')
.replace(/'([^'\\]|\\[^'\\]|\\\\|\\')*'/g,' <string> ');

// Replace url(...) functions by dummies
if (value.indexOf("(") != -1) {
value = value.replace(/([a-z]?)[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]*)[)])*[)])*[)])*[)])*[)]/g, "$1() ");
value = value.replace(/([a-z]?)[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]+|[(](?:[^()]*)[)])*[)])*[)])*[)])*[)]/g, "$1() ");
}

// Collapse whitespace
value = value.trim().replace(/\s+/g, " ");

// Divide at commas and spaces to separate different values
value = value.split(/\s*(?:,|[/])\s*|\s+/g);
}

}

// Collapse whitespace
value = value.trim().replace(/\s+/g, " ");

// Divide at commas and spaces to separate different values
value = value.split(/\s*(?:,|[/])\s*|\s+/g);

// This fixes a bug where there is only one item and it's not split by the value.split
// What ends up happening is that this function returns a string, not an array.
// This causes an issue because when we do .length in the for loop after this, it returns the length of the string, not the array.
if( typeof value === 'string' ) {
value = [ value ];
}

return value;
}
@@ -849,7 +863,8 @@ void function() { try {
}

// divide the value into simplified components
var specifiedValuesArray = CSSUsage.CSSValues.createValueArray(styleValue,normalizedKey);
var stripUrlValue = true;
var specifiedValuesArray = CSSUsage.CSSValues.createValueArray(styleValue, normalizedKey, stripUrlValue);
var values = new Array();
for(var j = specifiedValuesArray.length; j--;) {
values.push(CSSUsage.CSSValues.parseValues(specifiedValuesArray[j],normalizedKey));
34 changes: 34 additions & 0 deletions src/recipes/archive/SVGInUrl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
RECIPE: SVGInUrl
-------------------------------------------------------------
Author: Joshua Berenhaus
Description: Find CSS Properties with url("___.svg") or url(data:image/svg+xml___)
*/

void function() {
window.CSSUsage.StyleWalker.recipesToRun.push( function SVGInUrl( element, results) {
if(element.CSSUsage){
var x = Object.keys(element.CSSUsage);


for(var n = 0; n < x.length; n++){
var value = element.CSSUsage[Object.keys(element.CSSUsage)[n]] //Grab the value of each item in the object
//we want to know which are urls
if(/url\((.+\.svg.?)\)/.test(value)){
results['SVGInUrl'] = results['SVGInUrl'] || {count : 0}
results['SVGInUrl'].count++;
break;
// } else if (/url\((data\:image\/svg\+xml.+)\)/.test(value)){
} else if (/svg\+xml\;base64/.test(value)){
results['SVGInUrlExplicit'] = results['SVGInUrlExplicit'] || {count : 0}
results['SVGInUrlExplicit'].count++;
break;
}
}
}
return results;
});
}();



20 changes: 20 additions & 0 deletions src/recipes/archive/SVGSyntaxUsed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
RECIPE: SVGSyntaxUsed
-------------------------------------------------------------
Author: Joshua Berenhaus
Description: <svg> tag found
*/

void function() {
window.CSSUsage.StyleWalker.recipesToRun.push( function SVGSyntaxUsed( element, results) {
if(element.nodeName == "svg") {
results['SVGSyntaxUsed'] = results['SVGSyntaxUsed'] || { count: 0 };
results['SVGSyntaxUsed'].count++;
}

return results;
});
}();



28 changes: 28 additions & 0 deletions src/recipes/archive/SVGUsedOnHtmlElementData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
RECIPE: SVGUsedOnHtmlElementData
-------------------------------------------------------------
Author: Joshua Berenhaus
Description: Find instances that match <___ data="___.svg"> or <___ type="image/svg+xml" data="___.svg">
*/

void function() {
window.CSSUsage.StyleWalker.recipesToRun.push( function SVGUsedOnHtmlElementData( element, results) {
for(var n = 0; n < element.attributes.length; n++) {
if(element.attributes[n].name == "type" && element.attributes[n].value.indexOf("image/svg+xml") != -1) {
if(element.attributes[n+1].name == "data" && element.attributes[n+1].value.indexOf(".svg") != -1){
results['SVGUsedOnHtmlElementDataExplicit'] = results['SVGUsedOnHtmlElementDataExplicit'] || { count: 0 };
results['SVGUsedOnHtmlElementDataExplicit'].count++;
break;
}
} else if (element.attributes[n].name == "data" && element.attributes[n].value.indexOf(".svg") != -1){
results['SVGUsedOnHtmlElementData'] = results['SVGUsedOnHtmlElementData'] || { count: 0 };
results['SVGUsedOnHtmlElementData'].count++;
break;
}
}
return results;
});
}();



29 changes: 29 additions & 0 deletions src/recipes/archive/SVGUsedOnHtmlElementSrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
RECIPE: SVGUsedOnHtmlElementSrc
-------------------------------------------------------------
Author: Joshua Berenhaus
Description: Find instances of <img src="___.svg"
*/

void function() {
window.CSSUsage.StyleWalker.recipesToRun.push( function SVGUsedOnHtmlElementSrc( element, results) {
var patt = new RegExp(/data\:image\/svg\+xml.+/);
for(var n = 0; n < element.attributes.length; n++) {
if(element.attributes[n].name == "src") {
if(element.attributes[n].value.indexOf(".svg") != -1){
results['SVGUsedOnHtmlElementSrc'] = results['SVGUsedOnHtmlElementSrc'] || { count: 0 };
results['SVGUsedOnHtmlElementSrc'].count++;
break;
} else if (patt.test(element.attributes[n].value)){
results['SVGUsedOnHtmlElementSrcExplicit'] = results['SVGUsedOnHtmlElementSrcExplicit'] || {count : 0}
results['SVGUsedOnHtmlElementSrcExplicit'].count++;
break;
}
}
}
return results;
});
}();



13 changes: 0 additions & 13 deletions src/recipes/archive/recipe-template.js

This file was deleted.

1 change: 1 addition & 0 deletions tests/recipes/microsoftedge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 61 additions & 0 deletions tests/recipes/svginvestigation.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>SVG Investigation</title>
<link rel="manifest" href="/manifest.json">
<script src="../../Recipe.min.js"></script>
<!-- SVG as a CSS image -->
<style>
#borderimg {
border: 10px solid transparent;
border-image: url(microsoftedge.svg) 30 round;
padding-bottom: 40px;
}

/* file size: 8.2ko | optimized file size: 7.2ko | base64 size: 9.6ko (thanks b64.io!)*/
#svgimg {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDYwIDY0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0xOC44NyAzOGMwIDEuNTQgMC4yMyAyLjk0IDAuNyA0LjIgMC41IDEuMjQgMS4xNSAyLjM1IDEuOTggMy4zMnMxLjggMS44IDIuOTQgMi41YzEuMSAwLjcgMi4zIDEuMjggMy41OCAxLjczIDEuMjcgMC40NiAyLjYgMC44IDMuOTUgMS4wMiAxLjM3IDAuMjIgMi43IDAuMzMgNC4wNSAwLjMzIDEuNyAwIDMuMjgtMC4xMyA0Ljc4LTAuNCAxLjUtMC4yOCAyLjk2LTAuNjUgNC40LTEuMTJzMi44My0xLjAzIDQuMjItMS42N2MxLjQtMC42NCAyLjgyLTEuMzQgNC4yOC0yLjEydjEzLjU2Yy0xLjYzIDAuOC0zLjIzIDEuNDctNC44MyAyLjA1LTEuNiAwLjU2LTMuMiAxLjA1LTQuODMgMS40NC0xLjYzIDAuNC0zLjI4IDAuNy00Ljk3IDAuODhzLTMuNDIgMC4yOC01LjIyIDAuMjhjLTIuNCAwLTQuNzItMC4yOC02Ljk1LTAuODNzLTQuMzItMS4zNC02LjI4LTIuMzgtMy43NS0yLjMtNS4zOC0zLjc4Yy0xLjY0LTEuNDgtMy4wMy0zLjE1LTQuMi01cy0yLjA3LTMuODgtMi43Mi02LjA2Yy0wLjYzLTIuMTgtMC45NS00LjUtMC45NS02Ljk2IDAtMi42MyAwLjM2LTUuMTMgMS4wOC03LjUyIDAuNzMtMi40IDEuNzYtNC41OCAzLjEyLTYuNTggMS4zNS0yIDMtMy43OCA0Ljk1LTUuMzNzNC4xNC0yLjgyIDYuNTgtMy44Yy0xLjMzIDEuMzMtMi4zNyAyLjktMy4xIDQuNzMtMC43NSAxLjgyLTEuMjIgMy42NS0xLjQzIDUuNDhoMjIuNzhjMC0yLjMtMC4yMy00LjMtMC43LTYuMDJzLTEuMjItMy4xNS0yLjI3LTQuMjhjLTEuMDQtMS4xNC0yLjM4LTItNC4wMy0yLjU2LTEuNjUtMC41Ny0zLjY0LTAuODYtNS45Ny0wLjg2LTIuNzUgMC01LjUgMC40LTguMjUgMS4yMy0yLjc1IDAuOC01LjM2IDEuOTUtNy44NCAzLjQtMi40OCAxLjQ3LTQuNzYgMy4yLTYuODQgNS4xOC0yLjA4IDItMy44MyA0LjE1LTUuMjUgNi40OCAwLjMtMi43IDAuOS01LjMgMS43My03Ljc3czEuOTMtNC43NyAzLjI1LTYuOWMxLjMyLTIuMSAyLjg3LTQuMDIgNC42NC01Ljc0czMuNzMtMy4yIDUuOS00LjQgNC40Ny0yLjE3IDYuOTctMi44MmMyLjUtMC41NyA1LjE2LTAuOTEgNy45Ni0wLjkxIDEuNjQgMCAzLjI3IDAuMTUgNC45IDAuNDQgMS42MyAwLjMgMy4yMiAwLjcgNC43NyAxLjIyIDMuMDggMS4wNiA1LjgzIDIuNTQgOC4yNSA0LjQyIDIuNDIgMS45IDQuNDUgNC4wNiA2LjEgNi41M3MyLjkgNS4yIDMuNzYgOC4xNyAxLjMgNi4wNiAxLjMgOS4yN3Y3Ljk1aC00MC45MXoiIGZpbGw9IiMwMDc4RDciLz48L3N2Zz4K);
}

</style>
</head>
<body>
<!-- SVGInUrl: SVG in border-image CSS as url() -->
<p id="borderimg">
This is text with a SVG border image
</p>

<!-- SVG in background-image CSS as base64-->
<p id="svgimg">
This is text with a SVG background image
</p>

<!-- SVGUsedOnHtmlElementSrc: SVG as an HTML image -->
<p> SVG Image as svg file url
<img src="microsoftedge.svg" />
</p>

<!-- SVG image as base64 data image-->
<p> SVG Image as base64 data image
<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDYwIDY0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0xOC44NyAzOGMwIDEuNTQgMC4yMyAyLjk0IDAuNyA0LjIgMC41IDEuMjQgMS4xNSAyLjM1IDEuOTggMy4zMnMxLjggMS44IDIuOTQgMi41YzEuMSAwLjcgMi4zIDEuMjggMy41OCAxLjczIDEuMjcgMC40NiAyLjYgMC44IDMuOTUgMS4wMiAxLjM3IDAuMjIgMi43IDAuMzMgNC4wNSAwLjMzIDEuNyAwIDMuMjgtMC4xMyA0Ljc4LTAuNCAxLjUtMC4yOCAyLjk2LTAuNjUgNC40LTEuMTJzMi44My0xLjAzIDQuMjItMS42N2MxLjQtMC42NCAyLjgyLTEuMzQgNC4yOC0yLjEydjEzLjU2Yy0xLjYzIDAuOC0zLjIzIDEuNDctNC44MyAyLjA1LTEuNiAwLjU2LTMuMiAxLjA1LTQuODMgMS40NC0xLjYzIDAuNC0zLjI4IDAuNy00Ljk3IDAuODhzLTMuNDIgMC4yOC01LjIyIDAuMjhjLTIuNCAwLTQuNzItMC4yOC02Ljk1LTAuODNzLTQuMzItMS4zNC02LjI4LTIuMzgtMy43NS0yLjMtNS4zOC0zLjc4Yy0xLjY0LTEuNDgtMy4wMy0zLjE1LTQuMi01cy0yLjA3LTMuODgtMi43Mi02LjA2Yy0wLjYzLTIuMTgtMC45NS00LjUtMC45NS02Ljk2IDAtMi42MyAwLjM2LTUuMTMgMS4wOC03LjUyIDAuNzMtMi40IDEuNzYtNC41OCAzLjEyLTYuNTggMS4zNS0yIDMtMy43OCA0Ljk1LTUuMzNzNC4xNC0yLjgyIDYuNTgtMy44Yy0xLjMzIDEuMzMtMi4zNyAyLjktMy4xIDQuNzMtMC43NSAxLjgyLTEuMjIgMy42NS0xLjQzIDUuNDhoMjIuNzhjMC0yLjMtMC4yMy00LjMtMC43LTYuMDJzLTEuMjItMy4xNS0yLjI3LTQuMjhjLTEuMDQtMS4xNC0yLjM4LTItNC4wMy0yLjU2LTEuNjUtMC41Ny0zLjY0LTAuODYtNS45Ny0wLjg2LTIuNzUgMC01LjUgMC40LTguMjUgMS4yMy0yLjc1IDAuOC01LjM2IDEuOTUtNy44NCAzLjQtMi40OCAxLjQ3LTQuNzYgMy4yLTYuODQgNS4xOC0yLjA4IDItMy44MyA0LjE1LTUuMjUgNi40OCAwLjMtMi43IDAuOS01LjMgMS43My03Ljc3czEuOTMtNC43NyAzLjI1LTYuOWMxLjMyLTIuMSAyLjg3LTQuMDIgNC42NC01Ljc0czMuNzMtMy4yIDUuOS00LjQgNC40Ny0yLjE3IDYuOTctMi44MmMyLjUtMC41NyA1LjE2LTAuOTEgNy45Ni0wLjkxIDEuNjQgMCAzLjI3IDAuMTUgNC45IDAuNDQgMS42MyAwLjMgMy4yMiAwLjcgNC43NyAxLjIyIDMuMDggMS4wNiA1LjgzIDIuNTQgOC4yNSA0LjQyIDIuNDIgMS45IDQuNDUgNC4wNiA2LjEgNi41M3MyLjkgNS4yIDMuNzYgOC4xNyAxLjMgNi4wNiAxLjMgOS4yN3Y3Ljk1aC00MC45MXoiIGZpbGw9IiMwMDc4RDciLz48L3N2Zz4K" />
</p>

<!-- SVGUsedOnHtmlElementDataExplicit: SVG as some other type of element as base64 -->
<p> SVG as some other type of element as explicit object data
<object type="image/svg+xml" data="microsoftedge.svg"> </object>
</p>

<!-- SVGUsedOnHtmlElementData: SVG as some other type of element as object data -->
<p> SVG as some other type of element as object data
<object data="microsoftedge.svg"> </object>
</p>

<!-- Inline SVG -->
<svg width="100" height="100">
  <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>
</body>
</html>