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

Code cleanup: improve modifiedCanvasAPI

This commit is contained in:
kkapsner 2019-12-29 11:46:47 +01:00
parent e3182b562b
commit 8506757c62

View File

@ -185,8 +185,65 @@
webgl.setRandomSupply(supply); webgl.setRandomSupply(supply);
}; };
const canvasContextType = new WeakMap(); const canvasContextType = new WeakMap();
function createGetStatus(protectedPart){
if (protectedPart === "readout+"){
return function(obj, status, prefs){
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker("readout");
if (!status.active && protectedPartChecker("input")){
const contextType = canvasContextType.get(obj);
status.active = contextType !== "2d";
}
return status;
};
}
return function getStatus(obj, status, prefs){
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker(protectedPart);
return status;
};
}
function useFakeCanvasCallback(args, check){
const {prefs, notify, window, original} = check;
if (canvasSizeShouldBeFaked(this, prefs)){
const fakeCanvas = getFakeCanvas(window, this, prefs);
if (fakeCanvas !== this){
notify("fakedReadout");
}
return original.apply(fakeCanvas, window.Array.from(args));
}
else {
return original.apply(this, window.Array.from(args));
}
}
function mixOnInputCallback(args, check){
const {prefs, notify, window, original} = check;
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
notify("fakedInput");
let oldImageData;
try {
// "this" is not trustable - it may be not a context
oldImageData = getImageData(window, this).imageData;
}
catch (error){
// nothing to do here
}
// if "this" is not a correct context the next line will throw an error
const ret = original.apply(this, window.Array.from(args));
const newImageData = getImageData(window, this).imageData;
this.putImageData(randomMixImageData(window, oldImageData, newImageData), 0, 0);
return ret;
}
else {
return original.apply(this, window.Array.from(args));
}
}
// changed functions and their fakes // changed functions and their fakes
scope.changedFunctions = { scope.changedFunctions = {
getContext: { getContext: {
@ -225,106 +282,38 @@
}, },
toDataURL: { toDataURL: {
type: "readout", type: "readout",
getStatus: function(obj, status, prefs){ getStatus: createGetStatus("readout+"),
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker("readout");
if (!status.active && protectedPartChecker("input")){
const contextType = canvasContextType.get(obj);
status.active = contextType !== "2d";
}
return status;
},
object: "HTMLCanvasElement", object: "HTMLCanvasElement",
fakeGenerator: function(checker){ fakeGenerator: function(checker){
return function toDataURL(){ return function toDataURL(){
return checkerWrapper(checker, this, arguments, function(args, check){ return checkerWrapper(checker, this, arguments, useFakeCanvasCallback);
const {prefs, notify, window, original} = check;
if (canvasSizeShouldBeFaked(this, prefs)){
const fakeCanvas = getFakeCanvas(window, this, prefs);
if (fakeCanvas !== this){
notify("fakedReadout");
}
return original.apply(fakeCanvas, window.Array.from(args));
}
else {
return original.apply(this, window.Array.from(args));
}
});
}; };
} }
}, },
toBlob: { toBlob: {
type: "readout", type: "readout",
getStatus: function(obj, status, prefs){ getStatus: createGetStatus("readout+"),
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker("readout");
if (!status.active && protectedPartChecker("input")){
const contextType = canvasContextType.get(obj);
status.active = contextType !== "2d";
}
return status;
},
object: "HTMLCanvasElement", object: "HTMLCanvasElement",
fakeGenerator: function(checker){ fakeGenerator: function(checker){
return function toBlob(callback){ return function toBlob(callback){
return checkerWrapper(checker, this, arguments, function(args, check){ return checkerWrapper(checker, this, arguments, useFakeCanvasCallback);
const {prefs, notify, window, original} = check;
if (canvasSizeShouldBeFaked(this, prefs)){
const fakeCanvas = getFakeCanvas(window, this, prefs);
if (fakeCanvas !== this){
notify("fakedReadout");
}
return original.apply(fakeCanvas, window.Array.from(args));
}
else {
return original.apply(this, window.Array.from(args));
}
});
}; };
}, },
exportOptions: {allowCallbacks: true} exportOptions: {allowCallbacks: true}
}, },
mozGetAsFile: { mozGetAsFile: {
type: "readout", type: "readout",
getStatus: function(obj, status, prefs){ getStatus: createGetStatus("readout+"),
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker("readout");
if (!status.active && protectedPartChecker("input")){
const contextType = canvasContextType.get(obj);
status.active = contextType !== "2d";
}
return status;
},
object: "HTMLCanvasElement", object: "HTMLCanvasElement",
fakeGenerator: function(checker){ fakeGenerator: function(checker){
return function mozGetAsFile(callback){ return function mozGetAsFile(callback){
return checkerWrapper(checker, this, arguments, function(args, check){ return checkerWrapper(checker, this, arguments, useFakeCanvasCallback);
const {prefs, notify, window, original} = check;
if (canvasSizeShouldBeFaked(this, prefs)){
const fakeCanvas = getFakeCanvas(window, this, prefs);
if (fakeCanvas !== this){
notify("fakedReadout");
}
return original.apply(fakeCanvas, window.Array.from(args));
}
else {
return original.apply(this, window.Array.from(args));
}
});
}; };
} }
}, },
getImageData: { getImageData: {
type: "readout", type: "readout",
getStatus: function(obj, status, prefs){ getStatus: createGetStatus("readout"),
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker("readout");
return status;
},
object: "CanvasRenderingContext2D", object: "CanvasRenderingContext2D",
fakeGenerator: function(checker){ fakeGenerator: function(checker){
return function getImageData(sx, sy, sw, sh){ return function getImageData(sx, sy, sw, sh){
@ -354,12 +343,7 @@
}, },
isPointInPath: { isPointInPath: {
type: "readout", type: "readout",
getStatus: function(obj, status, prefs){ getStatus: createGetStatus("readout"),
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker("readout");
return status;
},
object: "CanvasRenderingContext2D", object: "CanvasRenderingContext2D",
fakeGenerator: function(checker){ fakeGenerator: function(checker){
return function isPointInPath(x, y){ return function isPointInPath(x, y){
@ -381,12 +365,7 @@
}, },
isPointInStroke: { isPointInStroke: {
type: "readout", type: "readout",
getStatus: function(obj, status, prefs){ getStatus: createGetStatus("readout"),
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker("readout");
return status;
},
object: "CanvasRenderingContext2D", object: "CanvasRenderingContext2D",
fakeGenerator: function(checker){ fakeGenerator: function(checker){
return function isPointInStroke(x, y){ return function isPointInStroke(x, y){
@ -417,84 +396,27 @@
}, },
fillText: { fillText: {
type: "input", type: "input",
getStatus: function(obj, status, prefs){ getStatus: createGetStatus("input"),
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker("input");
return status;
},
object: "CanvasRenderingContext2D", object: "CanvasRenderingContext2D",
fakeGenerator: function(checker){ fakeGenerator: function(checker){
return function fillText(str, x, y){ return function fillText(str, x, y){
return checkerWrapper(checker, this, arguments, function(args, check){ return checkerWrapper(checker, this, arguments, mixOnInputCallback);
const {prefs, notify, window, original} = check;
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
notify("fakedInput");
let oldImageData;
try {
// "this" is not trustable - it may be not a context
oldImageData = getImageData(window, this).imageData;
}
catch (error){
// nothing to do here
}
// if "this" is not a correct context the next line will throw an error
const ret = original.apply(this, window.Array.from(args));
const newImageData = getImageData(window, this).imageData;
this.putImageData(randomMixImageData(window, oldImageData, newImageData), 0, 0);
return ret;
}
else {
return original.apply(this, window.Array.from(args));
}
});
}; };
} }
}, },
strokeText: { strokeText: {
type: "input", type: "input",
getStatus: function(obj, status, prefs){ getStatus: createGetStatus("input"),
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker("input");
return status;
},
object: "CanvasRenderingContext2D", object: "CanvasRenderingContext2D",
fakeGenerator: function(checker){ fakeGenerator: function(checker){
return function strokeText(str, x, y){ return function strokeText(str, x, y){
return checkerWrapper(checker, this, arguments, function(args, check){ return checkerWrapper(checker, this, arguments, mixOnInputCallback);
const {prefs, notify, window, original} = check;
if (!this || canvasSizeShouldBeFaked(this.canvas, prefs)){
notify("fakedInput");
let oldImageData;
try {
// "this" is not trustable - it may be not a context
oldImageData = getImageData(window, this).imageData;
}
catch (error){
// nothing to do here
}
// if "this" is not a correct context the next line will throw an error
const ret = original.apply(this, window.Array.from(args));
const newImageData = getImageData(window, this).imageData;
this.putImageData(randomMixImageData(window, oldImageData, newImageData), 0, 0);
return ret;
}
else {
return original.apply(this, window.Array.from(args));
}
});
}; };
} }
}, },
readPixels: { readPixels: {
type: "readout", type: "readout",
getStatus: function(obj, status, prefs){ getStatus: createGetStatus(["readout", "input"]),
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker(["readout", "input"]);
return status;
},
object: ["WebGLRenderingContext", "WebGL2RenderingContext"], object: ["WebGLRenderingContext", "WebGL2RenderingContext"],
fakeGenerator: function(checker){ fakeGenerator: function(checker){
// eslint-disable-next-line max-params // eslint-disable-next-line max-params
@ -520,12 +442,7 @@
}, },
getParameter: { getParameter: {
type: "readout", type: "readout",
getStatus: function(obj, status, prefs){ getStatus: createGetStatus(["readout", "input"]),
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker(["readout", "input"]);
return status;
},
object: ["WebGLRenderingContext", "WebGL2RenderingContext"], object: ["WebGLRenderingContext", "WebGL2RenderingContext"],
fakeGenerator: function(checker){ fakeGenerator: function(checker){
webgl.initializeParameterDefinitions(); webgl.initializeParameterDefinitions();