kartograph / kartograph.js

UNMAINTAINED Open source JavaScript renderer for Kartograph SVG maps
http://kartograph.org
GNU Lesser General Public License v3.0
1.51k stars 227 forks source link

Function.prototype.bind() is unconditionally overwritten with a bad polyfill #59

Open mpetrovich opened 10 years ago

mpetrovich commented 10 years ago

This issue can cause seemingly random issues with other scripts and libraries. For instance, this issue is the cause of our Intercom integration not working.

kartograph.js / src / core / proj.coffee, line 22:

Function::bind = (scope) ->
    _function = @
    ->
        _function.apply scope,arguments

This overwrites Function.prototype.bind() even for browsers that have it natively. Even worse, this polyfill is not correct per the spec. bind() can take any number of additional arguments to pass to the bound function: fun.bind(thisArg[, arg1[, arg2[, ...]]]).

Please (a) conditionally assign the polyfill, and (b) use a better polyfill:

Function.prototype.bind = Function.prototype.bind || function (oThis) {
  if (typeof this !== "function") {
    // closest thing possible to the ECMAScript 5
    // internal IsCallable function
    throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
  }

  var aArgs = Array.prototype.slice.call(arguments, 1), 
      fToBind = this, 
      fNOP = function () {},
      fBound = function () {
        return fToBind.apply(this instanceof fNOP && oThis
               ? this
               : oThis,
               aArgs.concat(Array.prototype.slice.call(arguments)));
      };

  fNOP.prototype = this.prototype;
  fBound.prototype = new fNOP();

  return fBound;
};
stereoscott commented 9 years ago

+1 from us on this. The patch just required changing Function::bind = (scope) -> to Function::bind ?= (scope) ->