Add code to each canvas context method

I am trying to add code to all methods called in a canvas context. I am trying to do this, so I can add each command to the array of commands. This is the code I would think (but not working):

var canvas = Object.getPrototypeOf(document.createElement('canvas').getContext('2d')); for(p in canvas){ if(canvas.hasOwnProperty(p)){ var original = canvas[p]; canvas[p] = function(){ //extra code to be run return original.apply(this,arguments); } } } 

It seems to me that this should work, but it is not. If I use this code in the example, I get NOT_SUPPORTED_ERR: DOM Exception 9

Demo: http://jsfiddle.net/J3tUD/2/

+4
source share
2 answers

The problem you are suffering with is that the variables are not covered in blocks.

When your function starts, it updates the context prototype so that each function calls the same original function, which is the last element that belongs to the original prototype. In this case, it is webkitGetImageDataHD .

This means that when you call ctx.beginPath(); , you really call ctx.webkitGetImageDataHD(); . This method expects 4 arguments, and since it has not received them, it throws a DOM 9 exception.

Since JavaScript does not support the scope of the block, you need to force the scope to be changed using the function. By modifying your example, we can create a new function, where original is a fixed value:

 var context = Object.getPrototypeOf(document.createElement('canvas').getContext('2d')); function bind(context, p) { // context, p, and original never change. var original = context[p]; context[p] = function(){ console.log(p, arguments); return original.apply(this,arguments); } } // p changes with every iteration. for(p in context){ if(context.hasOwnProperty(p)){ bind(context, p); } } 

Find a working demo here: http://jsfiddle.net/bnickel/UG9gF/

+5
source

JavaScript has no block scope, and you only have one original variable containing the last enumerated function.

This solution will not change the prototype context ( host object !), But only copies for myContext :

 var myContext = someCanvas.getContext('2d'); var CanvasRenderingContext2DPrototype = Object.getPrototypeOf(myContext); for (var p in CanvasRenderingContext2DPrototype) (function(original, prop) { myContext[prop] = function() { // some extra code original.apply(myContext, arguments); }; })(CanvasRenderingContext2DPrototype[p], p); 
+2
source

All Articles