mirror of
https://github.com/kkapsner/CanvasBlocker
synced 2025-07-03 03:56:26 +02:00
First implementation of the fakeInput mode. (And other improvements.)
This commit is contained in:
parent
b6d08459a5
commit
a2fa00fb98
5 changed files with 188 additions and 59 deletions
|
@ -7,80 +7,165 @@
|
|||
|
||||
var randomSupply = null;
|
||||
|
||||
function getFakeCanvas(window, original){
|
||||
var context = window.HTMLCanvasElement.prototype.getContext.call(original, "2d");
|
||||
var imageData, data, source;
|
||||
if (context){
|
||||
imageData = window.CanvasRenderingContext2D.prototype.getImageData.call(context, 0, 0, original.width, original.height);
|
||||
source = imageData.data;
|
||||
function getContext(window, canvas){
|
||||
return window.HTMLCanvasElement.prototype.getContext.call(canvas, "2d") ||
|
||||
window.HTMLCanvasElement.prototype.getContext.call(canvas, "webgl") ||
|
||||
window.HTMLCanvasElement.prototype.getContext.call(canvas, "experimental-webgl") ||
|
||||
window.HTMLCanvasElement.prototype.getContext.call(canvas, "webgl2") ||
|
||||
window.HTMLCanvasElement.prototype.getContext.call(canvas, "experimental-webgl2");
|
||||
}
|
||||
function getImageData(window, context){
|
||||
if (context instanceof window.CanvasRenderingContext2D){
|
||||
return window.CanvasRenderingContext2D.prototype.getImageData.call(context, 0, 0, context.canvas.width, context.canvas.height);
|
||||
}
|
||||
else {
|
||||
context =
|
||||
window.HTMLCanvasElement.prototype.getContext.call(original, "webgl") ||
|
||||
window.HTMLCanvasElement.prototype.getContext.call(original, "experimental-webgl") ||
|
||||
window.HTMLCanvasElement.prototype.getContext.call(original, "webgl2") ||
|
||||
window.HTMLCanvasElement.prototype.getContext.call(original, "experimental-webgl2");
|
||||
imageData = new window.wrappedJSObject.ImageData(original.width, original.height);
|
||||
source = new window.wrappedJSObject.Uint8Array(imageData.data.length);
|
||||
var imageData = new window.wrappedJSObject.ImageData(context.canvas.width, context.canvas.height);
|
||||
window.WebGLRenderingContext.prototype.readPixels.call(
|
||||
context,
|
||||
0, 0, original.width, original.height,
|
||||
0, 0, context.canvas.width, context.canvas.height,
|
||||
context.RGBA, context.UNSIGNED_BYTE,
|
||||
source
|
||||
imageData.data
|
||||
);
|
||||
return imageData;
|
||||
}
|
||||
data = imageData.data;
|
||||
}
|
||||
|
||||
function getFakeCanvas(window, original){
|
||||
var context = getContext(window, original);
|
||||
var imageData = getImageData(window, context);
|
||||
var data = imageData.data;
|
||||
var l = data.length;
|
||||
var rng = randomSupply.getRng(l, window);
|
||||
|
||||
for (var i = 0; i < l; i += 1){
|
||||
data[i] = rng(source[i], i);
|
||||
data[i] = rng(data[i], i);
|
||||
}
|
||||
var canvas = original.cloneNode(true);
|
||||
context = window.HTMLCanvasElement.prototype.getContext.call(canvas, "2d");
|
||||
context.putImageData(imageData, 0, 0);
|
||||
return canvas;
|
||||
}
|
||||
function randomMixImageData(window, imageData1, imageData2){
|
||||
var data1 = imageData1.data;
|
||||
var data2 = imageData2.data;
|
||||
var l = data1.length;
|
||||
if (l === data2.length){
|
||||
var rng = randomSupply.getRng(l, window);
|
||||
|
||||
for (var i = 0; i < l; i += 1){
|
||||
if (data1[i] > data2[i]){
|
||||
data2[i] = data1[i] - rng(data1[i] - data2[i], i);
|
||||
}
|
||||
else if (data1[i] < data2[i]){
|
||||
data2[i] = data1[i] + rng(data2[i] - data1[i], i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return imageData2;
|
||||
}
|
||||
|
||||
function getWindow(canvas){
|
||||
return canvas.ownerDocument.defaultView;
|
||||
}
|
||||
function hasType(status, type){
|
||||
return status.type.indexOf(type) !== -1;
|
||||
}
|
||||
|
||||
exports.setRandomSupply = function(supply){
|
||||
randomSupply = supply;
|
||||
};
|
||||
var canvasContextType = new WeakMap();
|
||||
// changed functions and their fakes
|
||||
exports.changedFunctions = {
|
||||
getContext: {
|
||||
type: "context",
|
||||
object: "HTMLCanvasElement"
|
||||
getStatus: function(obj, status){
|
||||
return {
|
||||
mode: hasType(status, "block")? "block": "fake",
|
||||
type: status.type,
|
||||
active: true
|
||||
};
|
||||
},
|
||||
object: "HTMLCanvasElement",
|
||||
fakeGenerator: function(prefs, notify){
|
||||
return function(context, contextAttributes){
|
||||
var window = getWindow(this);
|
||||
canvasContextType.set(this, context);
|
||||
return window.HTMLCanvasElement.prototype.getContext.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
},
|
||||
toDataURL: {
|
||||
type: "readout",
|
||||
getStatus: function(obj, status){
|
||||
if (hasType(status, "input")){
|
||||
var contextType = canvasContextType.get(obj);
|
||||
status.active = contextType && contextType !== "2d";
|
||||
}
|
||||
else {
|
||||
status.active = hasType(status, "readout");
|
||||
}
|
||||
return status;
|
||||
},
|
||||
object: "HTMLCanvasElement",
|
||||
fake: function toDataURL(){
|
||||
var window = getWindow(this);
|
||||
return window.HTMLCanvasElement.prototype.toDataURL.apply(getFakeCanvas(window, this), arguments);
|
||||
fakeGenerator: function(prefs, notify){
|
||||
return function toDataURL(){
|
||||
notify("fakedReadout");
|
||||
var window = getWindow(this);
|
||||
return window.HTMLCanvasElement.prototype.toDataURL.apply(getFakeCanvas(window, this), arguments);
|
||||
};
|
||||
}
|
||||
},
|
||||
toBlob: {
|
||||
type: "readout",
|
||||
getStatus: function(obj, status){
|
||||
if (hasType(status, "input")){
|
||||
var contextType = canvasContextType.get(obj);
|
||||
status.active = contextType && contextType !== "2d";
|
||||
}
|
||||
else {
|
||||
status.active = hasType(status, "readout");
|
||||
}
|
||||
return status;
|
||||
},
|
||||
object: "HTMLCanvasElement",
|
||||
fake: function toBlob(callback){
|
||||
var window = getWindow(this);
|
||||
return window.HTMLCanvasElement.prototype.toBlob.apply(getFakeCanvas(window, this), arguments);
|
||||
fakeGenerator: function(prefs, notify){
|
||||
return function toBlob(callback){
|
||||
notify("fakedReadout");
|
||||
var window = getWindow(this);
|
||||
return window.HTMLCanvasElement.prototype.toBlob.apply(getFakeCanvas(window, this), arguments);
|
||||
};
|
||||
},
|
||||
exportOptions: {allowCallbacks: true}
|
||||
},
|
||||
mozGetAsFile: {
|
||||
type: "readout",
|
||||
getStatus: function(obj, status){
|
||||
if (hasType(status, "input")){
|
||||
var contextType = canvasContextType.get(obj);
|
||||
status.active = contextType && contextType !== "2d";
|
||||
}
|
||||
else {
|
||||
status.active = hasType(status, "readout");
|
||||
}
|
||||
return status;
|
||||
},
|
||||
object: "HTMLCanvasElement",
|
||||
mozGetAsFile: function mozGetAsFile(callback){
|
||||
var window = getWindow(this);
|
||||
return window.HTMLCanvasElement.prototype.mozGetAsFile.apply(getFakeCanvas(window, this), arguments);
|
||||
fakeGenerator: function(prefs, notify){
|
||||
return function mozGetAsFile(callback){
|
||||
notify("fakedReadout");
|
||||
var window = getWindow(this);
|
||||
return window.HTMLCanvasElement.prototype.mozGetAsFile.apply(getFakeCanvas(window, this), arguments);
|
||||
};
|
||||
}
|
||||
},
|
||||
getImageData: {
|
||||
type: "readout",
|
||||
getStatus: function(obj, status){
|
||||
if (hasType(status, "input")){
|
||||
var contextType = canvasContextType.get(obj);
|
||||
status.active = contextType && contextType !== "2d";
|
||||
}
|
||||
else {
|
||||
status.active = hasType(status, "readout");
|
||||
}
|
||||
return status;
|
||||
},
|
||||
object: "CanvasRenderingContext2D",
|
||||
fakeGenerator: function(prefs, notify){
|
||||
var maxSize = prefs("maxFakeSize") || Number.POSITIVE_INFINITY;
|
||||
|
@ -91,7 +176,7 @@
|
|||
context = this;
|
||||
}
|
||||
else {
|
||||
notify();
|
||||
notify("fakedReadout");
|
||||
context = window.HTMLCanvasElement.prototype.getContext.call(
|
||||
getFakeCanvas(window, this.canvas),
|
||||
"2d"
|
||||
|
@ -107,14 +192,55 @@
|
|||
};
|
||||
}
|
||||
},
|
||||
fillText: {
|
||||
getStatus: function(obj, status){
|
||||
status.active = hasType(status, "input");
|
||||
return status;
|
||||
},
|
||||
object: "CanvasRenderingContext2D",
|
||||
fakeGenerator: function(prefs, notify){
|
||||
return function fillText(str, x, y){
|
||||
notify("fakedInput");
|
||||
var window = getWindow(this.canvas);
|
||||
var oldImageData = getImageData(window, this);
|
||||
var ret = window.CanvasRenderingContext2D.prototype.fillText.apply(this, arguments);
|
||||
var newImageData = getImageData(window, this);
|
||||
this.putImageData(randomMixImageData(window, oldImageData, newImageData), 0, 0);
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
},
|
||||
strokeText: {
|
||||
getStatus: function(obj, status){
|
||||
status.active = hasType(status, "input");
|
||||
return status;
|
||||
},
|
||||
object: "CanvasRenderingContext2D",
|
||||
fakeGenerator: function(prefs, notify){
|
||||
return function strokeText(str, x, y){
|
||||
notify("fakedInput");
|
||||
var window = getWindow(this.canvas);
|
||||
var oldImageData = getImageData(window, this);
|
||||
var ret = window.CanvasRenderingContext2D.prototype.strokeText.apply(this, arguments);
|
||||
var newImageData = getImageData(window, this);
|
||||
this.putImageData(randomMixImageData(window, oldImageData, newImageData), 0, 0);
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
},
|
||||
readPixels: {
|
||||
type: "readout",
|
||||
getStatus: function(obj, status){
|
||||
status.active = hasType(status, "readout") || hasType(status, "input");
|
||||
return status;
|
||||
},
|
||||
object: "WebGLRenderingContext",
|
||||
fake: function readPixels(x, y, width, height, format, type, pixels){
|
||||
var window = getWindow(this.canvas);
|
||||
var context = window.HTMLCanvasElement.prototype.getContext.call(getFakeCanvas(window, this.canvas), "webGL");
|
||||
return window.WebGLRenderingContext.prototype.readPixels.apply(context, arguments);
|
||||
|
||||
fakeGenerator: function(prefs, notify){
|
||||
return function readPixels(x, y, width, height, format, type, pixels){
|
||||
notify("fakedReadout");
|
||||
var window = getWindow(this.canvas);
|
||||
var context = window.HTMLCanvasElement.prototype.getContext.call(getFakeCanvas(window, this.canvas), "webGL");
|
||||
return window.WebGLRenderingContext.prototype.readPixels.apply(context, arguments);
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue