Rework lists to each have their own getters
This was necessary for them to each have their own enumerable properties. The React Native ListViewDataSource uses Object.keys() to the indexes.
This commit is contained in:
parent
0ed5ba2d8e
commit
a9cac20f79
|
@ -272,6 +272,7 @@ static JSGlobalContextRef s_context;
|
|||
return @{
|
||||
@"type": @(RJSTypeGet(realm::PropertyTypeArray).c_str()),
|
||||
@"id": @(oid),
|
||||
@"size": @(array->link_view->size()),
|
||||
@"schema": [self objectSchemaToJSONObject:array->object_schema]
|
||||
};
|
||||
}
|
||||
|
|
16
lib/lists.js
16
lib/lists.js
|
@ -5,7 +5,7 @@ let util = require('./util');
|
|||
|
||||
let idKey = Symbol();
|
||||
let realmKey = Symbol();
|
||||
let prototype = util.createListPrototype(getterForLength, getterForIndex, setterForIndex);
|
||||
let prototype = {};
|
||||
|
||||
exports.create = create;
|
||||
|
||||
|
@ -15,9 +15,7 @@ exports.create = create;
|
|||
'push',
|
||||
'unshift',
|
||||
'splice',
|
||||
].forEach(function(name, i) {
|
||||
let growthMethod = (i >= 2);
|
||||
|
||||
].forEach(function(name) {
|
||||
Object.defineProperty(prototype, name, {
|
||||
value: function() {
|
||||
let listId = this[idKey];
|
||||
|
@ -28,11 +26,7 @@ exports.create = create;
|
|||
}
|
||||
|
||||
let result = rpc.callListMethod(realmId, listId, name, Array.from(arguments));
|
||||
|
||||
// Since this method might have grown the list, ensure index properties are defined.
|
||||
if (growthMethod) {
|
||||
prototype[util.growListPrototypeKey](this.length);
|
||||
}
|
||||
this[util.resizeListKey]();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -40,13 +34,13 @@ exports.create = create;
|
|||
});
|
||||
|
||||
function create(realmId, info) {
|
||||
let list = Object.create(prototype);
|
||||
let list = util.createList(prototype, getterForLength, getterForIndex, setterForIndex);
|
||||
let size = info.size;
|
||||
|
||||
list[realmKey] = realmId;
|
||||
list[idKey] = info.id;
|
||||
|
||||
list[util.growListPrototypeKey](size);
|
||||
list[util.resizeListKey](size);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
|
|
@ -5,18 +5,17 @@ let util = require('./util');
|
|||
|
||||
let idKey = Symbol();
|
||||
let realmKey = Symbol();
|
||||
let prototype = util.createListPrototype(getterForLength, getterForIndex);
|
||||
|
||||
exports.create = create;
|
||||
|
||||
function create(realmId, info) {
|
||||
let results = Object.create(prototype);
|
||||
let results = util.createList(null, getterForLength, getterForIndex);
|
||||
let size = info.size;
|
||||
|
||||
results[realmKey] = realmId;
|
||||
results[idKey] = info.resultsId;
|
||||
|
||||
results[util.growListPrototypeKey](size);
|
||||
results[util.resizeListKey](size);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
|
42
lib/util.js
42
lib/util.js
|
@ -1,35 +1,45 @@
|
|||
'use strict';
|
||||
|
||||
let growListPrototypeKey = exports.growListPrototypeKey = Symbol();
|
||||
let resizeListKey = exports.resizeListKey = Symbol();
|
||||
|
||||
exports.createListPrototype = createListPrototype;
|
||||
exports.createList = createList;
|
||||
|
||||
function createListPrototype(getterForLength, getterForIndex, setterForIndex) {
|
||||
let prototype = {};
|
||||
let maxSize = 0;
|
||||
function createList(prototype, getterForLength, getterForIndex, setterForIndex) {
|
||||
var list = prototype ? Object.create(prototype) : {};
|
||||
var size = 0;
|
||||
|
||||
Object.defineProperty(prototype, 'length', {
|
||||
get: getterForLength
|
||||
});
|
||||
Object.defineProperty(list, 'length', {get: getterForLength});
|
||||
|
||||
prototype[growListPrototypeKey] = function(size) {
|
||||
if (size < maxSize) {
|
||||
list[resizeListKey] = function(length) {
|
||||
if (length == null) {
|
||||
length = this.length;
|
||||
}
|
||||
if (length == size) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (length > size) {
|
||||
let props = {};
|
||||
for (let i = maxSize; i <= size; i++) {
|
||||
|
||||
for (let i = size; i < length; i++) {
|
||||
props[i] = {
|
||||
get: getterForIndex(i),
|
||||
set: setterForIndex && setterForIndex(i),
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: Use ES6 Proxy once it's supported on Chrome!
|
||||
Object.defineProperties(prototype, props);
|
||||
|
||||
maxSize = size + 1;
|
||||
Object.defineProperties(this, props);
|
||||
}
|
||||
else if (length < size) {
|
||||
for (let i = size - 1; i >= length; i--) {
|
||||
delete this[i];
|
||||
}
|
||||
}
|
||||
|
||||
return prototype;
|
||||
size = length;
|
||||
};
|
||||
|
||||
return list;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue