1

I know how to intercept a native function in JavaScript. For example, I use the code below to intercept document.createElement:

var origParseFloat = document.createElement;
document.createElement = function(str) {
     alert("Called");
     return origParseFloat(str);
}

My question here is that how can I intercept methods of an object. I mean what if I want to intercept toDataURL() which is a method for CanvasElement.The code above does not work in this case. so now the main question is how can I intercept toDataURL() in a case such as below:

canvas = document.createElement('canvas');
var tdu = canvas.toDataURL();
0

1 Answer 1

5

You need to monkey patch the method on the prototype it appears in, in your case HTMLCanvasElement.prototype.toDataURL.

var origToDataURL = HTMLCanvasElement.prototype.toDataURL;
HTMLCanvasElement.prototype.toDataURL = function() {
  var r = origToDataURL.apply(this, arguments);
  console.log('toDataURL:', r);
  return r;
};


var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.fillRect(25, 25, 50, 50);
canvas.toDataURL();
<canvas id="canvas" width="100" height="100"></canvas>

Alternately, if you know the canvas element is created with document.createElement, I suppose you could define a new method on that instance, but this method is less-reliable as elements created with HTML would be missed, and the object structure is technically different.

You can also do something similar for getter functions.

// Function to find the prototype chain object that has a property.
function findPrototypeProperty(obj, prop) {
    while (!obj.hasOwnProperty(prop)) {
        obj = Object.getPrototypeOf(obj);
    }
    return obj;
}

var property = 'sampleRate';
var proto = findPrototypeProperty(AudioContext.prototype, property);

var desc = Object.getOwnPropertyDescriptor(proto, property);
var getter = desc.get;
desc.get = function() {
    var r = getter.apply(this, arguments);
    console.log(property, r);
    return r;
};
Object.defineProperty(proto, property, desc);


var audioCtx = new AudioContext();
void(audioCtx.sampleRate);

Sign up to request clarification or add additional context in comments.

2 Comments

Really appreciate your answer, Could you please also help with the property? I mean what if I want to find out if a property is accessed. For example: baseAudioContext.sampleRate
@Bathooman I've added a sample on hijacking the sampleRate getter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.