CasperJS bind issue

The shim below isn’t needed anymore if PhantomJS 2 is used. Sadly CasperJS 1.1-beta3 doesn’t support it yet, so you might want to use the master branch from GitHub.


The problem is that PhantomJS v1.x does not support the Function.prototype.bind. You need to add a shim for that. In CasperJS it goes into the page.initialized event handler. This shim works well for me on instragram:

casper.on( 'page.initialized', function(){
    this.evaluate(function(){
        var isFunction = function(o) {
          return typeof o == 'function';
        };

        var bind,
          slice = [].slice,
          proto = Function.prototype,
          featureMap;

        featureMap = {
          'function-bind': 'bind'
        };

        function has(feature) {
          var prop = featureMap[feature];
          return isFunction(proto[prop]);
        }

        // check for missing features
        if (!has('function-bind')) {
          // adapted from Mozilla Developer Network example at
          // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
          bind = function bind(obj) {
            var args = slice.call(arguments, 1),
              self = this,
              nop = function() {
              },
              bound = function() {
                return self.apply(this instanceof nop ? this : (obj || {}), args.concat(slice.call(arguments)));
              };
            nop.prototype = this.prototype || {}; // Firefox cries sometimes if prototype is undefined
            bound.prototype = new nop();
            return bound;
          };
          proto.bind = bind;
        }
    });
});

It doesn’t work if the shim is exported into its own file and included through the clientScripts option, because those are appended after the instagram javascript which is too late.

What might also work is registering to page.resource.received event.

There is also the pure PhantomJS question: bind polyfill for PhantomJS

Leave a Comment