1
0
mirror of https://github.com/kkapsner/CanvasBlocker synced 2024-12-22 21:00:23 +01:00

Further improved DOMRect performance

Additional factor 2.6 = total factor 4.7 (For #253).
This commit is contained in:
kkapsner 2019-05-04 13:44:02 +02:00
parent 89124235c0
commit 2c291322cf
2 changed files with 73 additions and 187 deletions

View File

@ -29,7 +29,7 @@
} }
const registeredRects = new WeakMap(); const registeredRects = new WeakMap();
function registerDOMRect(domRect, notify){ function registerDOMRect(domRect, notify, window, prefs){
registeredRects.set(getWrapped(domRect), { registeredRects.set(getWrapped(domRect), {
notify: function(){ notify: function(){
let done = false; let done = false;
@ -39,7 +39,9 @@
notify(message); notify(message);
} }
}; };
}() }(),
window,
prefs
}); });
} }
function getDOMRectRegistration(domRect){ function getDOMRectRegistration(domRect){
@ -94,7 +96,7 @@
var {prefs, notify, window, original} = check; var {prefs, notify, window, original} = check;
var ret = original.apply(this, window.Array.from(args)); var ret = original.apply(this, window.Array.from(args));
for (let i = 0; i < ret.length; i += 1){ for (let i = 0; i < ret.length; i += 1){
registerDOMRect(ret[i], notify); registerDOMRect(ret[i], notify, window, prefs);
} }
return ret; return ret;
}); });
@ -108,7 +110,7 @@
return checkerWrapper(checker, this, arguments, function(args, check){ return checkerWrapper(checker, this, arguments, function(args, check){
var {prefs, notify, window, original} = check; var {prefs, notify, window, original} = check;
var ret = original.apply(this, window.Array.from(args)); var ret = original.apply(this, window.Array.from(args));
registerDOMRect(ret, notify); registerDOMRect(ret, notify, window, prefs);
return ret; return ret;
}); });
}; };
@ -122,7 +124,7 @@
return checkerWrapper(checker, this, arguments, function(args, check){ return checkerWrapper(checker, this, arguments, function(args, check){
var {prefs, notify, window, original} = check; var {prefs, notify, window, original} = check;
var ret = original.apply(this, window.Array.from(args)); var ret = original.apply(this, window.Array.from(args));
registerDOMRect(ret, notify); registerDOMRect(ret, notify, window, prefs);
return ret; return ret;
}); });
}; };
@ -135,7 +137,7 @@
return checkerWrapper(checker, this, arguments, function(args, check){ return checkerWrapper(checker, this, arguments, function(args, check){
var {prefs, notify, window, original} = check; var {prefs, notify, window, original} = check;
var ret = original.apply(this, window.Array.from(args)); var ret = original.apply(this, window.Array.from(args));
registerDOMRect(ret, notify); registerDOMRect(ret, notify, window, prefs);
return ret; return ret;
}); });
}; };
@ -148,7 +150,7 @@
return checkerWrapper(checker, this, arguments, function(args, check){ return checkerWrapper(checker, this, arguments, function(args, check){
var {prefs, notify, window, original} = check; var {prefs, notify, window, original} = check;
var ret = original.apply(this, window.Array.from(args)); var ret = original.apply(this, window.Array.from(args));
registerDOMRect(ret, notify); registerDOMRect(ret, notify, window, prefs);
return ret; return ret;
}); });
}; };
@ -156,189 +158,72 @@
}, },
}; };
function createCheckerCallback(property){ function generateChangedDOMRectPropertyGetter(property, readonly = false){
return function(args, check){ const changedGetter = {
const {prefs, notify, window, original} = check; objectGetters: readonly?
if (prefs("protectDOMRect", window.location)){ [
function(window){return window.DOMRectReadOnly && window.DOMRectReadOnly.prototype;}
]:
[
function(window){return window.DOMRect && window.DOMRect.prototype;},
function(window){return window.DOMRectReadOnly && window.DOMRectReadOnly.prototype;}
],
name: property,
getterGenerator: function(){
const temp = {
get [property](){
const registration = getDOMRectRegistration(this); const registration = getDOMRectRegistration(this);
if (registration){ if (registration){
return getFakeDomRect(window, this, prefs, registration.notify)[property]; return getFakeDomRect(
registration.window,
this,
registration.prefs,
registration.notify
)[property];
} }
return this[property];
} }
const originalValue = original.apply(this, window.Array.from(args));
return originalValue;
}; };
return Object.getOwnPropertyDescriptor(temp, property).get;
} }
function setProperty(domRect, window, original, newValue, property, prefs){ // eslint-disable-line max-params };
const registration = getDOMRectRegistration(domRect); if (!readonly){
changedGetter.setterGenerator = function(window, original, prefs){
const temp = {
set [property](newValue){
const registration = getDOMRectRegistration(this);
if (registration){ if (registration){
const fakeDomRect = getFakeDomRect(window, domRect, prefs, registration.notify); const fakeDomRect = getFakeDomRect(window, this, prefs, registration.notify);
registeredRects.delete(getWrapped(domRect)); registeredRects.delete(getWrapped(this));
["x", "y", "width", "height"].forEach(function(prop){ ["x", "y", "width", "height"].forEach(function(prop){
if (prop === property){ if (prop === property){
domRect[prop] = newValue; this[prop] = newValue;
} }
else { else {
domRect[prop] = fakeDomRect[prop]; this[prop] = fakeDomRect[prop];
} }
}); });
} }
else { else {
original.apply(domRect, window.Array.from(arguments)); original.apply(this, window.Array.from(arguments));
} }
} }
};
return Object.getOwnPropertyDescriptor(temp, property).set;
};
}
return changedGetter;
}
scope.changedGetters = [ scope.changedGetters = [
{ generateChangedDOMRectPropertyGetter("x", false),
objectGetters: [ generateChangedDOMRectPropertyGetter("y", false),
function(window){return window.DOMRect && window.DOMRect.prototype;}, generateChangedDOMRectPropertyGetter("width", false),
function(window){return window.DOMRectReadOnly && window.DOMRectReadOnly.prototype;} generateChangedDOMRectPropertyGetter("height", false),
], generateChangedDOMRectPropertyGetter("left", true),
name: "x", generateChangedDOMRectPropertyGetter("right", true),
getterGenerator: function(checker){ generateChangedDOMRectPropertyGetter("top", true),
const temp = { generateChangedDOMRectPropertyGetter("bottom", true),
get x(){
return checkerWrapper(checker, this, arguments, createCheckerCallback("x"));
}
};
return Object.getOwnPropertyDescriptor(temp, "x").get;
},
setterGenerator: function(window, original, prefs){
const temp = {
set x(x){
setProperty(this, window, original, x, "x", prefs);
}
};
return Object.getOwnPropertyDescriptor(temp, "x").set;
}
},
{
objectGetters: [
function(window){return window.DOMRect && window.DOMRect.prototype;},
function(window){return window.DOMRectReadOnly && window.DOMRectReadOnly.prototype;}
],
name: "y",
getterGenerator: function(checker){
const temp = {
get y(){
return checkerWrapper(checker, this, arguments, createCheckerCallback("y"));
}
};
return Object.getOwnPropertyDescriptor(temp, "y").get;
},
setterGenerator: function(window, original, prefs){
const temp = {
set y(y){
setProperty(this, window, original, y, "y", prefs);
}
};
return Object.getOwnPropertyDescriptor(temp, "y").set;
}
},
{
objectGetters: [
function(window){return window.DOMRect && window.DOMRect.prototype;},
function(window){return window.DOMRectReadOnly && window.DOMRectReadOnly.prototype;}
],
name: "width",
getterGenerator: function(checker){
const temp = {
get width(){
return checkerWrapper(checker, this, arguments, createCheckerCallback("width"));
}
};
return Object.getOwnPropertyDescriptor(temp, "width").get;
},
setterGenerator: function(window, original, prefs){
const temp = {
set width(width){
setProperty(this, window, original, width, "width", prefs);
}
};
return Object.getOwnPropertyDescriptor(temp, "width").set;
}
},
{
objectGetters: [
function(window){return window.DOMRect && window.DOMRect.prototype;},
function(window){return window.DOMRectReadOnly && window.DOMRectReadOnly.prototype;}
],
name: "height",
getterGenerator: function(checker){
const temp = {
get height(){
return checkerWrapper(checker, this, arguments, createCheckerCallback("height"));
}
};
return Object.getOwnPropertyDescriptor(temp, "height").get;
},
setterGenerator: function(window, original, prefs){
const temp = {
set height(height){
setProperty(this, window, original, height, "height", prefs);
}
};
return Object.getOwnPropertyDescriptor(temp, "height").set;
}
},
{
objectGetters: [
function(window){return window.DOMRectReadOnly && window.DOMRectReadOnly.prototype;}
],
name: "left",
getterGenerator: function(checker){
const callback = createCheckerCallback("left");
const temp = {
get left(){
return checkerWrapper(checker, this, arguments, callback);
}
};
return Object.getOwnPropertyDescriptor(temp, "left").get;
}
},
{
objectGetters: [
function(window){return window.DOMRectReadOnly && window.DOMRectReadOnly.prototype;}
],
name: "right",
getterGenerator: function(checker){
const temp = {
get right(){
return checkerWrapper(checker, this, arguments, createCheckerCallback("right"));
}
};
return Object.getOwnPropertyDescriptor(temp, "right").get;
}
},
{
objectGetters: [
function(window){return window.DOMRectReadOnly && window.DOMRectReadOnly.prototype;}
],
name: "top",
getterGenerator: function(checker){
const temp = {
get top(){
return checkerWrapper(checker, this, arguments, createCheckerCallback("top"));
}
};
return Object.getOwnPropertyDescriptor(temp, "top").get;
}
},
{
objectGetters: [
function(window){return window.DOMRectReadOnly && window.DOMRectReadOnly.prototype;}
],
name: "bottom",
getterGenerator: function(checker){
const temp = {
get bottom(){
return checkerWrapper(checker, this, arguments, createCheckerCallback("bottom"));
}
};
return Object.getOwnPropertyDescriptor(temp, "bottom").get;
}
},
{ {
objectGetters: [ objectGetters: [
function(window){ function(window){
@ -352,7 +237,7 @@
return checkerWrapper(checker, this, arguments, function(args, check){ return checkerWrapper(checker, this, arguments, function(args, check){
const {prefs, notify, window, original} = check; const {prefs, notify, window, original} = check;
const originalValue = original.apply(this, window.Array.from(args)); const originalValue = original.apply(this, window.Array.from(args));
registerDOMRect(originalValue, notify); registerDOMRect(originalValue, notify, window, prefs);
return originalValue; return originalValue;
}); });
} }
@ -373,7 +258,7 @@
return checkerWrapper(checker, this, arguments, function(args, check){ return checkerWrapper(checker, this, arguments, function(args, check){
const {prefs, notify, window, original} = check; const {prefs, notify, window, original} = check;
const originalValue = original.apply(this, window.Array.from(args)); const originalValue = original.apply(this, window.Array.from(args));
registerDOMRect(originalValue, notify); registerDOMRect(originalValue, notify, window, prefs);
return originalValue; return originalValue;
}); });
} }
@ -394,7 +279,7 @@
return checkerWrapper(checker, this, arguments, function(args, check){ return checkerWrapper(checker, this, arguments, function(args, check){
const {prefs, notify, window, original} = check; const {prefs, notify, window, original} = check;
const originalValue = original.apply(this, window.Array.from(args)); const originalValue = original.apply(this, window.Array.from(args));
registerDOMRect(originalValue, notify); registerDOMRect(originalValue, notify, window, prefs);
return originalValue; return originalValue;
}); });
} }

View File

@ -21,6 +21,7 @@ Version 0.5.9:
- faking audio did not work with white random generator - faking audio did not work with white random generator
- enabled copying from settings description when they are "hidden" - enabled copying from settings description when they are "hidden"
- fixed description for "show notifications" - fixed description for "show notifications"
- improved DOMRect performance
known issues: known issues:
- if a data URL is blocked the page action button does not appear - if a data URL is blocked the page action button does not appear