Refactor & speed up styleSectionsEqual
This commit is contained in:
parent
19f1490f0a
commit
d53db2d45c
73
storage.js
73
storage.js
|
@ -367,13 +367,17 @@ function getDomains(url) {
|
||||||
|
|
||||||
|
|
||||||
function getType(o) {
|
function getType(o) {
|
||||||
if (typeof o == "undefined" || typeof o == "string") {
|
if (typeof o == 'undefined' || typeof o == 'string') {
|
||||||
return typeof o;
|
return typeof o;
|
||||||
}
|
}
|
||||||
if (o instanceof Array) {
|
// with the persistent cachedStyles the Array reference is usually different
|
||||||
return "array";
|
// so let's check for e.g. type of 'every' which is only present on arrays
|
||||||
|
// (in the context of our extension)
|
||||||
|
if (o instanceof Array || typeof o.every == 'function') {
|
||||||
|
return 'array';
|
||||||
}
|
}
|
||||||
throw "Not supported - " + o;
|
console.warn('Unsupported type:', o);
|
||||||
|
return 'undefined';
|
||||||
}
|
}
|
||||||
|
|
||||||
const namespacePattern = /^\s*(@namespace[^;]+;\s*)+$/;
|
const namespacePattern = /^\s*(@namespace[^;]+;\s*)+$/;
|
||||||
|
@ -752,29 +756,56 @@ function styleSectionsEqual(styleA, styleB) {
|
||||||
if (styleA.sections.length != styleB.sections.length) {
|
if (styleA.sections.length != styleB.sections.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const properties = ['code', 'urlPrefixes', 'urls', 'domains', 'regexps'];
|
const propNames = ['code', 'urlPrefixes', 'urls', 'domains', 'regexps'];
|
||||||
return styleA.sections.every(sectionA =>
|
const typeBcaches = [];
|
||||||
styleB.sections.some(sectionB =>
|
checkingEveryInA: for (let sectionA of styleA.sections) {
|
||||||
properties.every(property => sectionEquals(sectionA, sectionB, property))
|
const typeAcache = new Map();
|
||||||
)
|
for (let name of propNames) {
|
||||||
);
|
typeAcache.set(name, getType(sectionA[name]));
|
||||||
|
}
|
||||||
function sectionEquals(a, b, property) {
|
lookingForDupeInB: for (let i = 0, sectionB; (sectionB = styleB.sections[i]); i++) {
|
||||||
const aProp = a[property], typeA = getType(aProp);
|
const typeBcache = typeBcaches[i] = typeBcaches[i] || new Map();
|
||||||
const bProp = b[property], typeB = getType(bProp);
|
comparingProps: for (let name of propNames) {
|
||||||
|
const propA = sectionA[name], typeA = typeAcache.get(name);
|
||||||
|
const propB = sectionB[name];
|
||||||
|
let typeB = typeBcache.get(name);
|
||||||
|
if (!typeB) {
|
||||||
|
typeB = getType(propB);
|
||||||
|
typeBcache.set(name, typeB);
|
||||||
|
}
|
||||||
if (typeA != typeB) {
|
if (typeA != typeB) {
|
||||||
// consider empty arrays equivalent to lack of property
|
const bothEmptyOrUndefined =
|
||||||
return ((typeA == 'undefined' || (typeA == 'array' && aProp.length == 0)) &&
|
(typeA == 'undefined' || (typeA == 'array' && propA.length == 0)) &&
|
||||||
(typeB == 'undefined' || (typeB == 'array' && bProp.length == 0)));
|
(typeB == 'undefined' || (typeB == 'array' && propB.length == 0));
|
||||||
|
if (bothEmptyOrUndefined) {
|
||||||
|
continue comparingProps;
|
||||||
|
} else {
|
||||||
|
continue lookingForDupeInB;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (typeA == 'undefined') {
|
if (typeA == 'undefined') {
|
||||||
return true;
|
continue comparingProps;
|
||||||
}
|
}
|
||||||
if (typeA == 'array') {
|
if (typeA == 'array') {
|
||||||
return aProp.length == bProp.length && aProp.every(item => bProp.includes(item));
|
if (propA.length != propB.length) {
|
||||||
|
continue lookingForDupeInB;
|
||||||
}
|
}
|
||||||
if (typeA == 'string') {
|
for (let item of propA) {
|
||||||
return aProp == bProp;
|
if (propB.indexOf(item) < 0) {
|
||||||
|
continue lookingForDupeInB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
continue comparingProps;
|
||||||
|
}
|
||||||
|
if (typeA == 'string' && propA != propB) {
|
||||||
|
continue lookingForDupeInB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// dupe found
|
||||||
|
continue checkingEveryInA;
|
||||||
|
}
|
||||||
|
// dupe not found
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user