"use strict"; module.exports = function(Promise, INTERNAL, tryConvertToPromise) { var rejectThis = function(_, e) { this._reject(e); }; var targetRejected = function(e, context) { context.promiseRejectionQueued = true; context.bindingPromise._then(rejectThis, rejectThis, null, this, e); }; var bindingResolved = function(thisArg, context) { this._setBoundTo(thisArg); if (this._isPending()) { this._resolveCallback(context.target); } }; var bindingRejected = function(e, context) { if (!context.promiseRejectionQueued) this._reject(e); }; Promise.prototype.bind = function (thisArg) { var maybePromise = tryConvertToPromise(thisArg); var ret = new Promise(INTERNAL); ret._propagateFrom(this, 1); var target = this._target(); if (maybePromise instanceof Promise) { var context = { promiseRejectionQueued: false, promise: ret, target: target, bindingPromise: maybePromise }; target._then(INTERNAL, targetRejected, ret._progress, ret, context); maybePromise._then( bindingResolved, bindingRejected, ret._progress, ret, context); } else { ret._setBoundTo(thisArg); ret._resolveCallback(target); } return ret; }; Promise.prototype._setBoundTo = function (obj) { if (obj !== undefined) { this._bitField = this._bitField | 131072; this._boundTo = obj; } else { this._bitField = this._bitField & (~131072); } }; Promise.prototype._isBound = function () { return (this._bitField & 131072) === 131072; }; Promise.bind = function (thisArg, value) { var maybePromise = tryConvertToPromise(thisArg); var ret = new Promise(INTERNAL); if (maybePromise instanceof Promise) { maybePromise._then(function(thisArg) { ret._setBoundTo(thisArg); ret._resolveCallback(value); }, ret._reject, ret._progress, ret, null); } else { ret._setBoundTo(thisArg); ret._resolveCallback(value); } return ret; }; };