diff --git a/source/adapter.js b/source/adapter.js index 3936189..5886a51 100644 --- a/source/adapter.js +++ b/source/adapter.js @@ -382,6 +382,59 @@ AdapterJS.addEvent = function(elem, evnt, func) { } }; +AdapterJS.recursivePolyfillBind = function(obj) { + if (!obj) { + return; + } + + // these objects cause infinite recursion in IE; ignore them + var recursionBlacklist = ['attachEvent()', 'detachEvent()', 'getLastException()']; + if (obj.value && recursionBlacklist.indexOf(obj.value.trim()) > -1) { + return; + } + + var pluginProperties = Object.keys(obj); + for (var i = 0; i < pluginProperties.length; i++) { + var currentProperty = obj[pluginProperties[i]]; + + if ((typeof currentProperty === 'function' || (currentProperty && currentProperty.call)) && !currentProperty.bind) { + // with the NPAPI/ActiveX JS functions you have to bind the bindPolyfill function to the NPAPI function and + // then call the bound function with the obj because the function must be called on its parent object + currentProperty.bind = bindPolyfill.bind(currentProperty)(obj); + } else if (typeof currentProperty === 'object') { + AdapterJS.recursivePolyfillBind(currentProperty); + } + } +} + +// adapted from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Polyfill +function bindPolyfill(oThis) { + // NPAPI/ActiveX JS functions are objects with a call property + if (typeof this !== 'function' && !(this && this.call)) { + // 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 + ? this + : oThis, + aArgs.concat(Array.prototype.slice.call(arguments))); + }; + + if (this.prototype) { + // Function.prototype doesn't have a prototype property + fNOP.prototype = this.prototype; + } + fBound.prototype = new fNOP(); + + return fBound; +}; + AdapterJS.renderNotificationBar = function (message, buttonText, buttonCallback) { // only inject once the page is ready if (document.readyState !== 'interactive' && document.readyState !== 'complete') { @@ -1133,7 +1186,11 @@ if (['webkit', 'moz', 'ms', 'AppleWebKit'].indexOf(AdapterJS.webrtcDetectedType) if (iceServers) { servers.iceServers = iceServers; } - return AdapterJS.WebRTCPlugin.plugin.PeerConnection(servers); + + // polyfill plugin functions with bind() + var peerConnection = AdapterJS.WebRTCPlugin.plugin.PeerConnection(servers); + AdapterJS.recursivePolyfillBind(peerConnection); + return peerConnection; } else { var mandatory = (constraints && constraints.mandatory) ? constraints.mandatory : null;