"use strict"; module.exports = function(Promise, NEXT_FILTER, tryConvertToPromise) { var util = require("./util.js"); var isPrimitive = util.isPrimitive; var thrower = util.thrower; function returnThis() { return this; } function throwThis() { throw this; } function return$(r) { return function() { return r; }; } function throw$(r) { return function() { throw r; }; } function promisedFinally(ret, reasonOrValue, isFulfilled) { var then; if (isPrimitive(reasonOrValue)) { then = isFulfilled ? return$(reasonOrValue) : throw$(reasonOrValue); } else { then = isFulfilled ? returnThis : throwThis; } return ret._then(then, thrower, undefined, reasonOrValue, undefined); } function finallyHandler(reasonOrValue) { var promise = this.promise; var handler = this.handler; var ret = promise._isBound() ? handler.call(promise._boundValue()) : handler(); if (ret !== undefined) { var maybePromise = tryConvertToPromise(ret, promise); if (maybePromise instanceof Promise) { maybePromise = maybePromise._target(); return promisedFinally(maybePromise, reasonOrValue, promise.isFulfilled()); } } if (promise.isRejected()) { NEXT_FILTER.e = reasonOrValue; return NEXT_FILTER; } else { return reasonOrValue; } } function tapHandler(value) { var promise = this.promise; var handler = this.handler; var ret = promise._isBound() ? handler.call(promise._boundValue(), value) : handler(value); if (ret !== undefined) { var maybePromise = tryConvertToPromise(ret, promise); if (maybePromise instanceof Promise) { maybePromise = maybePromise._target(); return promisedFinally(maybePromise, value, true); } } return value; } Promise.prototype._passThroughHandler = function (handler, isFinally) { if (typeof handler !== "function") return this.then(); var promiseAndHandler = { promise: this, handler: handler }; return this._then( isFinally ? finallyHandler : tapHandler, isFinally ? finallyHandler : undefined, undefined, promiseAndHandler, undefined); }; Promise.prototype.lastly = Promise.prototype["finally"] = function (handler) { return this._passThroughHandler(handler, true); }; Promise.prototype.tap = function (handler) { return this._passThroughHandler(handler, false); }; };