• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"use strict";
2module.exports = function(
3    Promise, PromiseArray, tryConvertToPromise, apiRejection) {
4var util = require("./util");
5var isObject = util.isObject;
6var es5 = require("./es5");
7var Es6Map;
8if (typeof Map === "function") Es6Map = Map;
9
10var mapToEntries = (function() {
11    var index = 0;
12    var size = 0;
13
14    function extractEntry(value, key) {
15        this[index] = value;
16        this[index + size] = key;
17        index++;
18    }
19
20    return function mapToEntries(map) {
21        size = map.size;
22        index = 0;
23        var ret = new Array(map.size * 2);
24        map.forEach(extractEntry, ret);
25        return ret;
26    };
27})();
28
29var entriesToMap = function(entries) {
30    var ret = new Es6Map();
31    var length = entries.length / 2 | 0;
32    for (var i = 0; i < length; ++i) {
33        var key = entries[length + i];
34        var value = entries[i];
35        ret.set(key, value);
36    }
37    return ret;
38};
39
40function PropertiesPromiseArray(obj) {
41    var isMap = false;
42    var entries;
43    if (Es6Map !== undefined && obj instanceof Es6Map) {
44        entries = mapToEntries(obj);
45        isMap = true;
46    } else {
47        var keys = es5.keys(obj);
48        var len = keys.length;
49        entries = new Array(len * 2);
50        for (var i = 0; i < len; ++i) {
51            var key = keys[i];
52            entries[i] = obj[key];
53            entries[i + len] = key;
54        }
55    }
56    this.constructor$(entries);
57    this._isMap = isMap;
58    this._init$(undefined, isMap ? -6 : -3);
59}
60util.inherits(PropertiesPromiseArray, PromiseArray);
61
62PropertiesPromiseArray.prototype._init = function () {};
63
64PropertiesPromiseArray.prototype._promiseFulfilled = function (value, index) {
65    this._values[index] = value;
66    var totalResolved = ++this._totalResolved;
67    if (totalResolved >= this._length) {
68        var val;
69        if (this._isMap) {
70            val = entriesToMap(this._values);
71        } else {
72            val = {};
73            var keyOffset = this.length();
74            for (var i = 0, len = this.length(); i < len; ++i) {
75                val[this._values[i + keyOffset]] = this._values[i];
76            }
77        }
78        this._resolve(val);
79        return true;
80    }
81    return false;
82};
83
84PropertiesPromiseArray.prototype.shouldCopyValues = function () {
85    return false;
86};
87
88PropertiesPromiseArray.prototype.getActualLength = function (len) {
89    return len >> 1;
90};
91
92function props(promises) {
93    var ret;
94    var castValue = tryConvertToPromise(promises);
95
96    if (!isObject(castValue)) {
97        return apiRejection("cannot await properties of a non-object\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
98    } else if (castValue instanceof Promise) {
99        ret = castValue._then(
100            Promise.props, undefined, undefined, undefined, undefined);
101    } else {
102        ret = new PropertiesPromiseArray(castValue).promise();
103    }
104
105    if (castValue instanceof Promise) {
106        ret._propagateFrom(castValue, 2);
107    }
108    return ret;
109}
110
111Promise.prototype.props = function () {
112    return props(this);
113};
114
115Promise.props = function (promises) {
116    return props(promises);
117};
118};
119