mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-14 09:39:15 +00:00
switch to eslint-config-standard
This commit is contained in:
@@ -24,7 +24,7 @@ const PARSE5_OPTS = {
|
|||||||
* @param {Boolean} [options.compress=true] Compress resulting critical CSS
|
* @param {Boolean} [options.compress=true] Compress resulting critical CSS
|
||||||
*/
|
*/
|
||||||
module.exports = class CrittersWebpackPlugin {
|
module.exports = class CrittersWebpackPlugin {
|
||||||
constructor(options) {
|
constructor (options) {
|
||||||
this.options = options || {};
|
this.options = options || {};
|
||||||
this.urlFilter = this.options.filter;
|
this.urlFilter = this.options.filter;
|
||||||
if (this.urlFilter instanceof RegExp) {
|
if (this.urlFilter instanceof RegExp) {
|
||||||
@@ -33,7 +33,7 @@ module.exports = class CrittersWebpackPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Invoked by Webpack during plugin initialization */
|
/** Invoked by Webpack during plugin initialization */
|
||||||
apply(compiler) {
|
apply (compiler) {
|
||||||
const outputPath = compiler.options.output.path;
|
const outputPath = compiler.options.output.path;
|
||||||
|
|
||||||
// hook into the compiler to get a Compilation instance...
|
// hook into the compiler to get a Compilation instance...
|
||||||
@@ -47,7 +47,7 @@ module.exports = class CrittersWebpackPlugin {
|
|||||||
let externalStylesProcessed = Promise.resolve();
|
let externalStylesProcessed = Promise.resolve();
|
||||||
|
|
||||||
// `external:false` skips processing of external sheets
|
// `external:false` skips processing of external sheets
|
||||||
if (this.options.external!==false) {
|
if (this.options.external !== false) {
|
||||||
const externalSheets = document.querySelectorAll('link[rel="stylesheet"]');
|
const externalSheets = document.querySelectorAll('link[rel="stylesheet"]');
|
||||||
externalStylesProcessed = Promise.all(externalSheets.map(
|
externalStylesProcessed = Promise.all(externalSheets.map(
|
||||||
link => this.embedLinkedStylesheet(link, compilation, outputPath)
|
link => this.embedLinkedStylesheet(link, compilation, outputPath)
|
||||||
@@ -71,7 +71,7 @@ module.exports = class CrittersWebpackPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Inline the target stylesheet referred to by a <link rel="stylesheet"> (assuming it passes `options.filter`) */
|
/** Inline the target stylesheet referred to by a <link rel="stylesheet"> (assuming it passes `options.filter`) */
|
||||||
embedLinkedStylesheet(link, compilation, outputPath) {
|
embedLinkedStylesheet (link, compilation, outputPath) {
|
||||||
const href = link.getAttribute('href');
|
const href = link.getAttribute('href');
|
||||||
const document = link.ownerDocument;
|
const document = link.ownerDocument;
|
||||||
|
|
||||||
@@ -105,12 +105,12 @@ module.exports = class CrittersWebpackPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Parse the stylesheet within a <style> element, then reduce it to contain only rules used by the document. */
|
/** Parse the stylesheet within a <style> element, then reduce it to contain only rules used by the document. */
|
||||||
processStyle(style) {
|
processStyle (style) {
|
||||||
const done = Promise.resolve();
|
const done = Promise.resolve();
|
||||||
const document = style.ownerDocument;
|
const document = style.ownerDocument;
|
||||||
|
|
||||||
// basically `.textContent`
|
// basically `.textContent`
|
||||||
let sheet = style.childNodes.length>0 && style.childNodes.map( node => node.nodeValue ).join('\n');
|
let sheet = style.childNodes.length > 0 && style.childNodes.map(node => node.nodeValue).join('\n');
|
||||||
|
|
||||||
// store a reference to the previous serialized stylesheet for reporting stats
|
// store a reference to the previous serialized stylesheet for reporting stats
|
||||||
const before = sheet;
|
const before = sheet;
|
||||||
@@ -122,7 +122,7 @@ module.exports = class CrittersWebpackPlugin {
|
|||||||
|
|
||||||
// Walk all CSS rules, transforming unused rules to comments (which get removed)
|
// Walk all CSS rules, transforming unused rules to comments (which get removed)
|
||||||
visit(ast, rule => {
|
visit(ast, rule => {
|
||||||
if (rule.type==='rule') {
|
if (rule.type === 'rule') {
|
||||||
// Filter the selector list down to only those matche
|
// Filter the selector list down to only those matche
|
||||||
rule.selectors = rule.selectors.filter(sel => {
|
rule.selectors = rule.selectors.filter(sel => {
|
||||||
// Strip pseudo-elements and pseudo-classes, since we only care that their associated elements exist.
|
// Strip pseudo-elements and pseudo-classes, since we only care that their associated elements exist.
|
||||||
@@ -131,23 +131,22 @@ module.exports = class CrittersWebpackPlugin {
|
|||||||
return document.querySelector(sel, document) != null;
|
return document.querySelector(sel, document) != null;
|
||||||
});
|
});
|
||||||
// If there are no matched selectors, remove the rule:
|
// If there are no matched selectors, remove the rule:
|
||||||
if (rule.selectors.length===0) {
|
if (rule.selectors.length === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are no remaining rules, remove the whole rule.
|
// If there are no remaining rules, remove the whole rule.
|
||||||
return !rule.rules || rule.rules.length!==0;
|
return !rule.rules || rule.rules.length !== 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
sheet = css.stringify(ast, { compress: this.options.compress!==false });
|
sheet = css.stringify(ast, { compress: this.options.compress !== false });
|
||||||
|
|
||||||
return done.then(() => {
|
return done.then(() => {
|
||||||
// If all rules were removed, get rid of the style element entirely
|
// If all rules were removed, get rid of the style element entirely
|
||||||
if (sheet.trim().length===0) {
|
if (sheet.trim().length === 0) {
|
||||||
sheet.parentNode.removeChild(sheet);
|
sheet.parentNode.removeChild(sheet);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// replace the inline stylesheet with its critical'd counterpart
|
// replace the inline stylesheet with its critical'd counterpart
|
||||||
while (style.lastChild) {
|
while (style.lastChild) {
|
||||||
style.removeChild(style.lastChild);
|
style.removeChild(style.lastChild);
|
||||||
@@ -163,27 +162,25 @@ module.exports = class CrittersWebpackPlugin {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** Recursively walk all rules in a stylesheet.
|
/** Recursively walk all rules in a stylesheet.
|
||||||
* The iterator can explicitly return `false` to remove the current node.
|
* The iterator can explicitly return `false` to remove the current node.
|
||||||
*/
|
*/
|
||||||
function visit(node, fn) {
|
function visit (node, fn) {
|
||||||
if (node.stylesheet) return visit(node.stylesheet, fn);
|
if (node.stylesheet) return visit(node.stylesheet, fn);
|
||||||
|
|
||||||
node.rules = node.rules.filter(rule => {
|
node.rules = node.rules.filter(rule => {
|
||||||
if (rule.rules) {
|
if (rule.rules) {
|
||||||
visit(rule, fn);
|
visit(rule, fn);
|
||||||
}
|
}
|
||||||
return fn(rule)!==false;
|
return fn(rule) !== false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Enhance an htmlparser2-style DOM with basic manipulation methods. */
|
/** Enhance an htmlparser2-style DOM with basic manipulation methods. */
|
||||||
function makeDomInteractive(document) {
|
function makeDomInteractive (document) {
|
||||||
defineProperties(document, DocumentExtensions);
|
defineProperties(document, DocumentExtensions);
|
||||||
// Find the first <html> element within the document
|
// Find the first <html> element within the document
|
||||||
document.documentElement = document.childNodes.filter( child => String(child.tagName).toLowerCase()==='html' )[0];
|
// document.documentElement = document.childNodes.filter( child => String(child.tagName).toLowerCase()==='html' )[0];
|
||||||
|
|
||||||
// Extend Element.prototype with DOM manipulation methods.
|
// Extend Element.prototype with DOM manipulation methods.
|
||||||
// Note: document.$$scratchElement is also used by createTextNode()
|
// Note: document.$$scratchElement is also used by createTextNode()
|
||||||
@@ -203,62 +200,64 @@ function makeDomInteractive(document) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Essentially Object.defineProperties() except any functions are assigned as values rather than descriptors. */
|
/** Essentially Object.defineProperties() except any functions are assigned as values rather than descriptors. */
|
||||||
function defineProperties(obj, properties) {
|
function defineProperties (obj, properties) {
|
||||||
for (const i in properties) {
|
for (const i in properties) {
|
||||||
const value = properties[i];
|
const value = properties[i];
|
||||||
Object.defineProperty(obj, i, typeof value === 'function' ? { value } : value);
|
Object.defineProperty(obj, i, typeof value === 'function' ? { value } : value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {document,Element}.getElementsByTagName() is the only traversal method required by nwmatcher. */
|
/** {document,Element}.getElementsByTagName() is the only traversal method required by nwmatcher.
|
||||||
function getElementsByTagName(tagName) {
|
* Note: if perf issues arise, 2 faster but more verbose implementations are benchmarked here:
|
||||||
|
* https://esbench.com/bench/5ac3b647f2949800a0f619e1
|
||||||
|
*/
|
||||||
|
function getElementsByTagName (tagName) {
|
||||||
// Only return Element/Document nodes
|
// Only return Element/Document nodes
|
||||||
if (this.nodeType!==1 && this.nodeType!==9 || this.type==='directive') return [];
|
if ((this.nodeType !== 1 && this.nodeType !== 9) || this.type === 'directive') return [];
|
||||||
return Array.prototype.concat.apply(
|
return Array.prototype.concat.apply(
|
||||||
// Add current element if it matches tag
|
// Add current element if it matches tag
|
||||||
(tagName === '*' || (this.tagName && (this.tagName == tagName || this.nodeName === tagName.toUpperCase()))) ? [this] : [],
|
(tagName === '*' || (this.tagName && (this.tagName === tagName || this.nodeName === tagName.toUpperCase()))) ? [this] : [],
|
||||||
// Check children recursively
|
// Check children recursively
|
||||||
this.children.map(child => getElementsByTagName.call(child, tagName))
|
this.children.map(child => getElementsByTagName.call(child, tagName))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Methods and descriptors to mix into Element.prototype */
|
/** Methods and descriptors to mix into Element.prototype */
|
||||||
const ElementExtensions = {
|
const ElementExtensions = {
|
||||||
nodeName: {
|
nodeName: {
|
||||||
get() {
|
get () {
|
||||||
return this.tagName.toUpperCase();
|
return this.tagName.toUpperCase();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
insertBefore(child, referenceNode) {
|
insertBefore (child, referenceNode) {
|
||||||
if (!referenceNode) return this.appendChild(child);
|
if (!referenceNode) return this.appendChild(child);
|
||||||
treeAdapter.insertBefore(this, child, referenceNode);
|
treeAdapter.insertBefore(this, child, referenceNode);
|
||||||
return child;
|
return child;
|
||||||
},
|
},
|
||||||
appendChild(child) {
|
appendChild (child) {
|
||||||
treeAdapter.appendChild(this, child);
|
treeAdapter.appendChild(this, child);
|
||||||
return child;
|
return child;
|
||||||
},
|
},
|
||||||
removeChild(child) {
|
removeChild (child) {
|
||||||
treeAdapter.detachNode(child);
|
treeAdapter.detachNode(child);
|
||||||
},
|
},
|
||||||
setAttribute(name, value) {
|
setAttribute (name, value) {
|
||||||
if (this.attribs == null) this.attribs = {};
|
if (this.attribs == null) this.attribs = {};
|
||||||
if (value == null) value = '';
|
if (value == null) value = '';
|
||||||
this.attribs[name] = value;
|
this.attribs[name] = value;
|
||||||
},
|
},
|
||||||
removeAttribute(name) {
|
removeAttribute (name) {
|
||||||
if (this.attribs != null) {
|
if (this.attribs != null) {
|
||||||
delete this.attribs[name];
|
delete this.attribs[name];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getAttribute(name) {
|
getAttribute (name) {
|
||||||
return this.attribs != null && this.attribs[name];
|
return this.attribs != null && this.attribs[name];
|
||||||
},
|
},
|
||||||
hasAttribute(name) {
|
hasAttribute (name) {
|
||||||
return this.attribs != null && this.attribs[name] != null;
|
return this.attribs != null && this.attribs[name] != null;
|
||||||
},
|
},
|
||||||
getAttributeNode(name) {
|
getAttributeNode (name) {
|
||||||
const value = this.getAttribute(name);
|
const value = this.getAttribute(name);
|
||||||
if (value != null) return { specified: true, value };
|
if (value != null) return { specified: true, value };
|
||||||
},
|
},
|
||||||
@@ -270,19 +269,30 @@ const DocumentExtensions = {
|
|||||||
// document is just an Element in htmlparser2, giving it a nodeType of ELEMENT_NODE.
|
// document is just an Element in htmlparser2, giving it a nodeType of ELEMENT_NODE.
|
||||||
// nwmatcher requires that it at least report a correct nodeType of DOCUMENT_NODE.
|
// nwmatcher requires that it at least report a correct nodeType of DOCUMENT_NODE.
|
||||||
nodeType: {
|
nodeType: {
|
||||||
get() {
|
get () {
|
||||||
return 9;
|
return 9;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nodeName: {
|
nodeName: {
|
||||||
get() {
|
get () {
|
||||||
return '#document';
|
return '#document';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
createElement(name) {
|
documentElement: {
|
||||||
|
get () {
|
||||||
|
// Find the first <html> element within the document
|
||||||
|
return this.childNodes.filter(child => String(child.tagName).toLowerCase() === 'html')[0];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
get () {
|
||||||
|
return this.querySelector('body');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createElement (name) {
|
||||||
return treeAdapter.createElement(name, null, []);
|
return treeAdapter.createElement(name, null, []);
|
||||||
},
|
},
|
||||||
createTextNode(text) {
|
createTextNode (text) {
|
||||||
// there is no dedicated createTextNode equivalent in htmlparser2's DOM, so
|
// there is no dedicated createTextNode equivalent in htmlparser2's DOM, so
|
||||||
// we have to insert Text and then remove and return the resulting Text node.
|
// we have to insert Text and then remove and return the resulting Text node.
|
||||||
const scratch = this.$$scratchElement;
|
const scratch = this.$$scratchElement;
|
||||||
@@ -291,14 +301,14 @@ const DocumentExtensions = {
|
|||||||
treeAdapter.detachNode(node);
|
treeAdapter.detachNode(node);
|
||||||
return node;
|
return node;
|
||||||
},
|
},
|
||||||
querySelector(sel) {
|
querySelector (sel) {
|
||||||
return this.$match.first(sel, this.documentElement);
|
return this.$match.first(sel, this.documentElement);
|
||||||
},
|
},
|
||||||
querySelectorAll(sel) {
|
querySelectorAll (sel) {
|
||||||
return this.$match.select(sel, this.documentElement);
|
return this.$match.select(sel, this.documentElement);
|
||||||
},
|
},
|
||||||
getElementsByTagName,
|
getElementsByTagName,
|
||||||
// nwmatcher uses inexistence of `document.addEventListener` to detect IE:
|
// nwmatcher uses inexistence of `document.addEventListener` to detect IE:
|
||||||
// https://github.com/dperini/nwmatcher/blob/3edb471e12ce7f7d46dc1606c7f659ff45675a29/src/nwmatcher.js#L353
|
// https://github.com/dperini/nwmatcher/blob/3edb471e12ce7f7d46dc1606c7f659ff45675a29/src/nwmatcher.js#L353
|
||||||
addEventListener: Object
|
addEventListener: Object
|
||||||
};
|
};
|
||||||
|
|||||||
19
package.json
19
package.json
@@ -9,14 +9,19 @@
|
|||||||
"lint": "eslint src"
|
"lint": "eslint src"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "eslint-config-developit",
|
"extends": [
|
||||||
|
"standard",
|
||||||
|
"standard-jsx"
|
||||||
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"indent": [
|
"indent": [
|
||||||
2,
|
2,
|
||||||
2
|
2
|
||||||
],
|
],
|
||||||
"object-shorthand": 0,
|
"semi": [
|
||||||
"prefer-arrow-callback": 0,
|
2,
|
||||||
|
"always"
|
||||||
|
],
|
||||||
"prefer-const": 1
|
"prefer-const": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -43,7 +48,13 @@
|
|||||||
"css-loader": "^0.28.11",
|
"css-loader": "^0.28.11",
|
||||||
"ejs-loader": "^0.3.1",
|
"ejs-loader": "^0.3.1",
|
||||||
"eslint": "^4.18.2",
|
"eslint": "^4.18.2",
|
||||||
"eslint-config-developit": "^1.1.1",
|
"eslint-config-standard": "^11.0.0",
|
||||||
|
"eslint-config-standard-jsx": "^5.0.0",
|
||||||
|
"eslint-plugin-import": "^2.10.0",
|
||||||
|
"eslint-plugin-node": "^6.0.1",
|
||||||
|
"eslint-plugin-promise": "^3.7.0",
|
||||||
|
"eslint-plugin-react": "^7.7.0",
|
||||||
|
"eslint-plugin-standard": "^3.0.1",
|
||||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||||
"fork-ts-checker-notifier-webpack-plugin": "^0.4.0",
|
"fork-ts-checker-notifier-webpack-plugin": "^0.4.0",
|
||||||
"fork-ts-checker-webpack-plugin": "^0.4.1",
|
"fork-ts-checker-webpack-plugin": "^0.4.1",
|
||||||
|
|||||||
@@ -3,17 +3,17 @@ import { options } from 'preact';
|
|||||||
const classNameDescriptor = {
|
const classNameDescriptor = {
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
configurable: true,
|
configurable: true,
|
||||||
get() {
|
get () {
|
||||||
return this.class;
|
return this.class;
|
||||||
},
|
},
|
||||||
set(value) {
|
set (value) {
|
||||||
this.class = value;
|
this.class = value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let old = options.vnode;
|
const old = options.vnode;
|
||||||
options.vnode = vnode => {
|
options.vnode = vnode => {
|
||||||
let a = vnode.attributes;
|
const a = vnode.attributes;
|
||||||
if (a != null) {
|
if (a != null) {
|
||||||
if ('className' in a) {
|
if ('className' in a) {
|
||||||
a.class = a.className;
|
a.class = a.className;
|
||||||
|
|||||||
Reference in New Issue
Block a user