Search code examples
javascriptmootoolsmootools-events

The Right Way of Intercepting Javascript Function Calls


I am writing a browser extension for the popular video chatting platform, Omegle. The extension needs access to internal events of the omegle app. The app uses Mootools for firing events, and creates a new global object (COMETBackend) that inherits the Events class of mootools. I am trying to intercept function calls to the fireEvent function of the COMETBackend object, by injecting this code into the DOM:

let proxy = COMETBackend.prototype.fireEvent;

COMETBackend.prototype.fireEvent =  function (...args) {
    console.log(...args)
    return proxy(...args);
}

Events Class from Mootools.js

var Events = new Class({
    $events: {},
    addEvent: function(c, b, a) {
        c = Events.removeOn(c);
        if (b != $empty) {
            this.$events[c] = this.$events[c] || [];
            this.$events[c].include(b);
            if (a) {
                b.internal = true;
            }
        }
        return this;
    },
    addEvents: function(a) {
        for (var b in a) {
            this.addEvent(b, a[b]);
        }
        return this;
    },
    fireEvent: function(c, b, a) {
        c = Events.removeOn(c);
        if (!this.$events || !this.$events[c]) {
            return this;
        }
        this.$events[c].each(function(d) {
            d.create({
                bind: this,
                delay: a,
                "arguments": b
            })();
        }, this);
        return this;
    },
    removeEvent: function(b, a) {
        b = Events.removeOn(b);
        if (!this.$events[b]) {
            return this;
        }
        if (!a.internal) {
            this.$events[b].erase(a);
        }
        return this;
    },
    removeEvents: function(c) {
        var d;
        if ($type(c) == "object") {
            for (d in c) {
                this.removeEvent(d, c[d]);
            }
            return this;
        }
        if (c) {
            c = Events.removeOn(c);
        }
        for (d in this.$events) {
            if (c && c != d) {
                continue;
            }
            var b = this.$events[d];
            for (var a = b.length; a--; a) {
                this.removeEvent(d, b[a]);
            }
        }
        return this;
    }
});

COMETBackend Object from Omegle.js

var COMETBackend = new Class({
    Implements: [Options, Events],
    initialize: function(a) {
        this.setOptions(a),
            this.clientID = null,
            this.stopped = !1
    }....

Now, in the console, the interception seems to have worked as i get the event logs i needed, but omegle for some reason is not responding to those events now, so the interception seems to have broken app's functionality.

Any ideas as to why that happened? am i not intercepting the calls properly?


Solution

  • let proxy = COMETBackend.prototype.fireEvent;
    return proxy(...args);
    

    Invoking proxy this way causes its 'this' parameter to be lost. Instead:

    return proxy.apply(this, args)