1
0
mirror of https://github.com/kkapsner/CanvasBlocker synced 2024-12-22 12:50:36 +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);
};
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
scope.changedFunctions = {
getContext: {
@ -225,106 +282,38 @@
},
toDataURL: {
type: "readout",
getStatus: 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;
},
getStatus: createGetStatus("readout+"),
object: "HTMLCanvasElement",
fakeGenerator: function(checker){
return function toDataURL(){
return checkerWrapper(checker, this, arguments, function(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));
}
});
return checkerWrapper(checker, this, arguments, useFakeCanvasCallback);
};
}
},
toBlob: {
type: "readout",
getStatus: 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;
},
getStatus: createGetStatus("readout+"),
object: "HTMLCanvasElement",
fakeGenerator: function(checker){
return function toBlob(callback){
return checkerWrapper(checker, this, arguments, function(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));
}
});
return checkerWrapper(checker, this, arguments, useFakeCanvasCallback);
};
},
exportOptions: {allowCallbacks: true}
},
mozGetAsFile: {
type: "readout",
getStatus: 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;
},
getStatus: createGetStatus("readout+"),
object: "HTMLCanvasElement",
fakeGenerator: function(checker){
return function mozGetAsFile(callback){
return checkerWrapper(checker, this, arguments, function(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));
}
});
return checkerWrapper(checker, this, arguments, useFakeCanvasCallback);
};
}
},
getImageData: {
type: "readout",
getStatus: function(obj, status, prefs){
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker("readout");
return status;
},
getStatus: createGetStatus("readout"),
object: "CanvasRenderingContext2D",
fakeGenerator: function(checker){
return function getImageData(sx, sy, sw, sh){
@ -354,12 +343,7 @@
},
isPointInPath: {
type: "readout",
getStatus: function(obj, status, prefs){
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker("readout");
return status;
},
getStatus: createGetStatus("readout"),
object: "CanvasRenderingContext2D",
fakeGenerator: function(checker){
return function isPointInPath(x, y){
@ -381,12 +365,7 @@
},
isPointInStroke: {
type: "readout",
getStatus: function(obj, status, prefs){
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker("readout");
return status;
},
getStatus: createGetStatus("readout"),
object: "CanvasRenderingContext2D",
fakeGenerator: function(checker){
return function isPointInStroke(x, y){
@ -417,84 +396,27 @@
},
fillText: {
type: "input",
getStatus: function(obj, status, prefs){
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker("input");
return status;
},
getStatus: createGetStatus("input"),
object: "CanvasRenderingContext2D",
fakeGenerator: function(checker){
return function fillText(str, x, y){
return checkerWrapper(checker, this, arguments, function(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));
}
});
return checkerWrapper(checker, this, arguments, mixOnInputCallback);
};
}
},
strokeText: {
type: "input",
getStatus: function(obj, status, prefs){
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker("input");
return status;
},
getStatus: createGetStatus("input"),
object: "CanvasRenderingContext2D",
fakeGenerator: function(checker){
return function strokeText(str, x, y){
return checkerWrapper(checker, this, arguments, function(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));
}
});
return checkerWrapper(checker, this, arguments, mixOnInputCallback);
};
}
},
readPixels: {
type: "readout",
getStatus: function(obj, status, prefs){
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker(["readout", "input"]);
return status;
},
getStatus: createGetStatus(["readout", "input"]),
object: ["WebGLRenderingContext", "WebGL2RenderingContext"],
fakeGenerator: function(checker){
// eslint-disable-next-line max-params
@ -520,12 +442,7 @@
},
getParameter: {
type: "readout",
getStatus: function(obj, status, prefs){
const protectedPartChecker = getProtectedPartChecker(prefs, status.url);
status = Object.create(status);
status.active = protectedPartChecker(["readout", "input"]);
return status;
},
getStatus: createGetStatus(["readout", "input"]),
object: ["WebGLRenderingContext", "WebGL2RenderingContext"],
fakeGenerator: function(checker){
webgl.initializeParameterDefinitions();