Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 69 additions & 28 deletions packages/ember-metal/lib/meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ let members = {
mixins: inheritedMap,
bindings: inheritedMap,
values: inheritedMap,
deps: inheritedMapOfMaps,
deps: inheritedArrayOfArrays,
chainWatchers: ownCustomObject,
chains: inheritedCustomObject,
tag: ownCustomObject
Expand Down Expand Up @@ -176,45 +176,80 @@ Meta.prototype._findInherited = function(key, subkey) {

export const UNDEFINED = symbol('undefined');

// Implements a member that provides a lazily created map of maps,
// Implements a member that provides a lazily created array of arrays,
// with inheritance at both levels.
function inheritedMapOfMaps(name, Meta) {
function inheritedArrayOfArrays(name, Meta) {
let key = memberProperty(name);
let capitalized = capitalize(name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to just pass the capitalized name at the call site?


Meta.prototype['write' + capitalized] = function(subkey, itemkey, value) {
let outerMap = this._getOrCreateOwnMap(key);
let innerMap = outerMap[subkey];
if (!innerMap) {
innerMap = outerMap[subkey] = new EmptyObject();
Meta.prototype['write' + capitalized] = function(subkey, itemKey, value) {
Copy link
Contributor

@chadhietala chadhietala Jun 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can you do write${capitalized}, same goes for the other dynamic method. 😄

let keyArray = this[key];
if (!keyArray) {
keyArray = this[key] = [];
}
innerMap[itemkey] = value;

for (let i = 0; i < keyArray.length; i++) {
if (keyArray[i][0] === subkey) {
let subkeyArray = keyArray[i][1];

for (let j = 0; j < subkeyArray.length; j++) {
if (subkeyArray[j][0] === itemKey) {
subkeyArray[j][1] = value;
return;
}
}

subkeyArray.push([itemKey, value]);
}
}

// add the subkey to the outerArray
keyArray.push([
subkey,
// array of itemKeys for the subkey
[
[itemKey, value]
]
]);
};

Meta.prototype['peek' + capitalized] = function(subkey, itemkey) {
Meta.prototype['peek' + capitalized] = function(subkey, itemKey) {
let pointer = this;
while (pointer !== undefined) {
let map = pointer[key];
if (map) {
let value = map[subkey];
if (value) {
if (value[itemkey] !== undefined) {
return value[itemkey];
let keyArray = pointer[key];
if (keyArray) {
for (let i = 0; i < keyArray.length; i++) {
if (keyArray[i][0] === subkey) {
let subkeyArray = keyArray[i][1];

for (let j = 0; j < subkeyArray.length; j++) {
if (subkeyArray[j][0] === itemKey) {
return subkeyArray[j][1];
}
}
}
}
}

pointer = pointer.parent;
}
};

Meta.prototype['has' + capitalized] = function(subkey) {
let pointer = this;
while (pointer !== undefined) {
if (pointer[key] && pointer[key][subkey]) {
return true;
let keyArray = pointer[key];
if (keyArray) {
for (let i = 0; i < keyArray.length; i++) {
if (keyArray[i][0] === subkey) {
return true;
}
}
}

pointer = pointer.parent;
}

return false;
};

Expand All @@ -228,20 +263,26 @@ Meta.prototype._forEachIn = function(key, subkey, fn) {
let seen = new EmptyObject();
let calls = [];
while (pointer !== undefined) {
let map = pointer[key];
if (map) {
let innerMap = map[subkey];
if (innerMap) {
for (let innerKey in innerMap) {
if (!seen[innerKey]) {
seen[innerKey] = true;
calls.push([innerKey, innerMap[innerKey]]);
let keyArray = pointer[key];
if (keyArray) {
for (let i = 0; i < keyArray.length; i++) {
if (keyArray[i][0] === subkey) {
let subkeyArray = keyArray[i][1];

for (let j = 0; j < subkeyArray.length; j++) {
let innerKey = subkeyArray[j][0];

if (!seen[innerKey]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should seen be a Dict? What is the upper bound of seen?

seen[innerKey] = true;
calls.push(subkeyArray[j]);
}
}
}
}
}
pointer = pointer.parent;
}

for (let i = 0; i < calls.length; i++) {
let [innerKey, value] = calls[i];
fn(innerKey, value);
Expand Down Expand Up @@ -343,7 +384,7 @@ if (isEnabled('mandatory-setter')) {
}

// choose the one appropriate for given platform
let setMeta = function(obj, meta) {
function setMeta(obj, meta) {
// if `null` already, just set it to the new value
// otherwise define property first
if (obj[META_FIELD] !== null) {
Expand All @@ -355,7 +396,7 @@ let setMeta = function(obj, meta) {
}

obj[META_FIELD] = meta;
};
}

/**
Retrieves the meta hash for an object. If `writable` is true ensures the
Expand Down