"use strict"; module.exports = function(Promise, INTERNAL) { var util = require("./util.js"); var errorObj = util.errorObj; var isObject = util.isObject; function tryConvertToPromise(obj, context) { if (isObject(obj)) { if (obj instanceof Promise) { return obj; } else if (isAnyBluebirdPromise(obj)) { var ret = new Promise(INTERNAL); obj._then( ret._fulfillUnchecked, ret._rejectUncheckedCheckError, ret._progressUnchecked, ret, null ); return ret; } var then = util.tryCatch(getThen)(obj); if (then === errorObj) { if (context) context._pushContext(); var ret = Promise.reject(then.e); if (context) context._popContext(); return ret; } else if (typeof then === "function") { return doThenable(obj, then, context); } } return obj; } function getThen(obj) { return obj.then; } var hasProp = {}.hasOwnProperty; function isAnyBluebirdPromise(obj) { return hasProp.call(obj, "_promise0"); } function doThenable(x, then, context) { var promise = new Promise(INTERNAL); var ret = promise; if (context) context._pushContext(); promise._captureStackTrace(); if (context) context._popContext(); var synchronous = true; var result = util.tryCatch(then).call(x, resolveFromThenable, rejectFromThenable, progressFromThenable); synchronous = false; if (promise && result === errorObj) { promise._rejectCallback(result.e, true, true); promise = null; } function resolveFromThenable(value) { if (!promise) return; if (x === value) { promise._rejectCallback( Promise._makeSelfResolutionError(), false, true); } else { promise._resolveCallback(value); } promise = null; } function rejectFromThenable(reason) { if (!promise) return; promise._rejectCallback(reason, synchronous, true); promise = null; } function progressFromThenable(value) { if (!promise) return; if (typeof promise._progress === "function") { promise._progress(value); } } return ret; } return tryConvertToPromise; };