Skip to content
Merged
Show file tree
Hide file tree
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
37 changes: 3 additions & 34 deletions packages/ember-glimmer/lib/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,10 @@ import ViewMixin from 'ember-views/mixins/view_support';
import ActionSupport from 'ember-views/mixins/action_support';
import TargetActionSupport from 'ember-runtime/mixins/target_action_support';
import symbol from 'ember-metal/symbol';
import EmptyObject from 'ember-metal/empty_object';
import { get } from 'ember-metal/property_get';
import { PROPERTY_DID_CHANGE } from 'ember-metal/property_events';
import { getAttrFor } from 'ember-views/compat/attrs-proxy';
import {
UPDATE,
TO_ROOT_REFERENCE,
REFERENCE_FOR_KEY,
RootReference,
PropertyReference
} from './utils/references';
import { UPDATE, RootReference } from './utils/references';
import { DirtyableTag } from 'glimmer-reference';
import { readDOMAttr } from 'glimmer-runtime';
import { assert, deprecate } from 'ember-metal/debug';
Expand All @@ -28,7 +21,6 @@ import { getOwner } from 'container/owner';
export const DIRTY_TAG = symbol('DIRTY_TAG');
export const ARGS = symbol('ARGS');
export const ROOT_REF = symbol('ROOT_REF');
export const REFS = symbol('REFS');
export const IS_DISPATCHING_ATTRS = symbol('IS_DISPATCHING_ATTRS');
export const HAS_BLOCK = symbol('HAS_BLOCK');

Expand All @@ -47,9 +39,9 @@ const Component = CoreView.extend(

init() {
this._super(...arguments);
this[IS_DISPATCHING_ATTRS] = false;
this[DIRTY_TAG] = new DirtyableTag();
this[ROOT_REF] = null;
this[REFS] = new EmptyObject();
this[ROOT_REF] = new RootReference(this);

// If a `defaultLayout` was specified move it to the `layout` prop.
// `layout` is no longer a CP, so this just ensures that the `defaultLayout`
Expand Down Expand Up @@ -95,8 +87,6 @@ const Component = CoreView.extend(
this[property.name] = property.descriptor.value;
},

[IS_DISPATCHING_ATTRS]: false,

[PROPERTY_DID_CHANGE](key) {
if (this[IS_DISPATCHING_ATTRS]) { return; }

Expand All @@ -118,27 +108,6 @@ const Component = CoreView.extend(

readDOMAttr(name) {
return readDOMAttr(this.element, name);
},

[TO_ROOT_REFERENCE]() {
let ref = this[ROOT_REF];

if (!ref) {
ref = this[ROOT_REF] = new RootReference(this);
}

return ref;
},

[REFERENCE_FOR_KEY](key) {
let refs = this[REFS];
let ref = refs[key];

if (ref) {
return ref;
} else {
return refs[key] = new PropertyReference(this[TO_ROOT_REFERENCE](), key);
}
}
}
);
Expand Down
5 changes: 2 additions & 3 deletions packages/ember-glimmer/lib/syntax/curly-component.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { StatementSyntax, ValueReference, EvaluatedArgs, EvaluatedNamedArgs, EvaluatedPositionalArgs } from 'glimmer-runtime';
import { TO_ROOT_REFERENCE } from '../utils/references';
import { AttributeBinding, ClassNameBinding, IsVisibleBinding } from '../utils/bindings';
import { DIRTY_TAG, IS_DISPATCHING_ATTRS, HAS_BLOCK } from '../component';
import { ROOT_REF, DIRTY_TAG, IS_DISPATCHING_ATTRS, HAS_BLOCK } from '../component';
import { assert, runInDebug } from 'ember-metal/debug';
import processArgs from '../utils/process-args';
import { privatize as P } from 'container/registry';
Expand Down Expand Up @@ -224,7 +223,7 @@ class CurlyComponentManager {
}

getSelf({ component }) {
return component[TO_ROOT_REFERENCE]();
return component[ROOT_REF];
}

didCreateElement({ component, classRef }, element, operations) {
Expand Down
6 changes: 3 additions & 3 deletions packages/ember-glimmer/lib/utils/bindings.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { assert } from 'ember-metal/debug';
import { dasherize } from 'ember-runtime/system/string';
import { CachedReference, map, referenceFromParts } from 'glimmer-reference';
import { REFERENCE_FOR_KEY, TO_ROOT_REFERENCE } from './references';
import { ROOT_REF } from '../component';
import { htmlSafe, isHTMLSafe } from './string';

function referenceForKey(component, key) {
return component[REFERENCE_FOR_KEY](key);
return component[ROOT_REF].get(key);
}

function referenceForParts(component, parts) {
return referenceFromParts(component[TO_ROOT_REFERENCE](), parts);
return referenceFromParts(component[ROOT_REF], parts);
}

export const AttributeBinding = {
Expand Down
32 changes: 4 additions & 28 deletions packages/ember-glimmer/lib/utils/iterable.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,42 +200,18 @@ class EachInIterable extends AbstractIterable {

let valueTag = this.valueTag = new UpdatableTag(CONSTANT_TAG);

this.wasProxy = false;
this.proxyWrapperTag = null;
this.proxyContentTag = null;

this.tag = combine([ref.tag, valueTag]);
}

iterate() {
let { ref, keyFor, valueTag, wasProxy } = this;
let { ref, keyFor, valueTag } = this;

let iterable = ref.value();

if (isProxy(iterable)) {
let proxy = iterable;
let content = get(proxy, 'content');

if (wasProxy) {
this.proxyWrapperTag.update(tagFor(proxy));
this.proxyContentTag.update(tagFor(content));
} else {
this.wasProxy = true;
let proxyWrapperTag = this.proxyWrapperTag = new UpdatableTag(tagFor(proxy));
let proxyContentTag = this.proxyContentTag = new UpdatableTag(tagFor(content));

valueTag.update(combine([proxyWrapperTag, proxyContentTag]));
}

iterable = content;
} else {
valueTag.update(tagFor(iterable));
valueTag.update(tagFor(iterable));

if (wasProxy) {
this.wasProxy = true;
this.proxyWrapperTag = null;
this.proxyContentTag = null;
}
if (isProxy(iterable)) {
iterable = get(iterable, 'content');
}

let typeofIterable = typeof iterable;
Expand Down
108 changes: 69 additions & 39 deletions packages/ember-glimmer/lib/utils/references.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { set } from 'ember-metal/property_set';
import { tagFor } from 'ember-metal/tags';
import { didRender } from 'ember-metal/transaction';
import symbol from 'ember-metal/symbol';
import EmptyObject from 'ember-metal/empty_object';
import { CONSTANT_TAG, ConstReference, DirtyableTag, UpdatableTag, combine, isConst } from 'glimmer-reference';
import { ConditionalReference as GlimmerConditionalReference, NULL_REFERENCE, UNDEFINED_REFERENCE } from 'glimmer-runtime';
import emberToBool from './to-bool';
Expand All @@ -13,8 +14,6 @@ import isEnabled from 'ember-metal/features';
import { isProxy } from 'ember-runtime/mixins/-proxy';

export const UPDATE = symbol('UPDATE');
export const TO_ROOT_REFERENCE = symbol('TO_ROOT_REFERENCE');
export const REFERENCE_FOR_KEY = symbol('REFERENCE_FOR_KEY');

// @implements PathReference
export class PrimitiveReference extends ConstReference {
Expand All @@ -32,7 +31,7 @@ class EmberPathReference {
// @abstract value()

get(key) {
return new PropertyReference(this, key);
return PropertyReference.create(this, key);
}
}

Expand Down Expand Up @@ -64,10 +63,19 @@ export class CachedReference extends EmberPathReference {

// @implements PathReference
export class RootReference extends ConstReference {
constructor(value) {
super(value);
this.children = new EmptyObject();
}

get(propertyKey) {
let self = this.value();
let ref = self[REFERENCE_FOR_KEY] && self[REFERENCE_FOR_KEY](propertyKey);
return ref || new PropertyReference(this, propertyKey);
let ref = this.children[propertyKey];

if (!ref) {
ref = this.children[propertyKey] = new RootPropertyReference(this.inner, propertyKey);
}

return ref;
}
}

Expand Down Expand Up @@ -106,7 +114,56 @@ if (isEnabled('ember-glimmer-detect-backtracking-rerender') ||
};
}

export class PropertyReference extends CachedReference { // jshint ignore:line
export class PropertyReference extends CachedReference {
static create(parentReference, propertyKey) {
if (isConst(parentReference)) {
return new RootPropertyReference(parentReference.value(), propertyKey);
} else {
return new NestedPropertyReference(parentReference, propertyKey);
}
}

get(key) {
return new NestedPropertyReference(this, key);
}
}

export class RootPropertyReference extends PropertyReference {
constructor(parentValue, propertyKey) {
super();

this._parentValue = parentValue;
this._propertyKey = propertyKey;

if (isEnabled('ember-glimmer-detect-backtracking-rerender') ||
isEnabled('ember-glimmer-allow-backtracking-rerender')) {
this.tag = new TwoWayFlushDetectionTag(tagFor(parentValue), propertyKey, this);
} else {
this.tag = tagFor(parentValue);
}

if (isEnabled('mandatory-setter')) {
watchKey(parentValue, propertyKey, metaFor(parentValue));
}
}

compute() {
let { _parentValue, _propertyKey } = this;

if (isEnabled('ember-glimmer-detect-backtracking-rerender') ||
isEnabled('ember-glimmer-allow-backtracking-rerender')) {
this.tag.didCompute(_parentValue);
}

return get(_parentValue, _propertyKey);
}

[UPDATE](value) {
set(this._parentValue, this._propertyKey, value);
}
}

export class NestedPropertyReference extends PropertyReference {
constructor(parentReference, propertyKey) {
super();

Expand All @@ -117,10 +174,6 @@ export class PropertyReference extends CachedReference { // jshint ignore:line
this._parentObjectTag = parentObjectTag;
this._propertyKey = propertyKey;

this._wasProxy = false;
this._proxyWrapperTag = null;
this._proxyContentTag = null;

if (isEnabled('ember-glimmer-detect-backtracking-rerender') ||
isEnabled('ember-glimmer-allow-backtracking-rerender')) {
let tag = combine([parentReferenceTag, parentObjectTag]);
Expand All @@ -131,32 +184,11 @@ export class PropertyReference extends CachedReference { // jshint ignore:line
}

compute() {
let { _parentReference, _parentObjectTag, _wasProxy, _propertyKey } = this;
let { _parentReference, _parentObjectTag, _propertyKey } = this;

let parentValue = _parentReference.value();

if (isProxy(parentValue)) {
let proxyContent = get(parentValue, 'content');

if (_wasProxy) {
this._proxyWrapperTag.update(tagFor(parentValue));
this._proxyContentTag.update(tagFor(proxyContent));
} else {
this._wasProxy = true;
let _proxyWrapperTag = this._proxyWrapperTag = new UpdatableTag(tagFor(parentValue));
let _proxyContentTag = this._proxyContentTag = new UpdatableTag(tagFor(proxyContent));

_parentObjectTag.update(combine([_proxyWrapperTag, _proxyContentTag]));
}
} else {
_parentObjectTag.update(tagFor(parentValue));

if (_wasProxy) {
this._wasProxy = false;
this._proxyWrapperTag = null;
this._proxyContentTag = null;
}
}
_parentObjectTag.update(tagFor(parentValue));

if (typeof parentValue === 'object' && parentValue) {
if (isEnabled('mandatory-setter')) {
Expand All @@ -179,10 +211,6 @@ export class PropertyReference extends CachedReference { // jshint ignore:line
let parent = this._parentReference.value();
set(parent, this._propertyKey, value);
}

get(propertyKey) {
return new PropertyReference(this, propertyKey);
}
}

export class UpdatableReference extends EmberPathReference {
Expand Down Expand Up @@ -218,7 +246,9 @@ export class ConditionalReference extends GlimmerConditionalReference {
if (isConst(reference)) {
let value = reference.value();

if (!isProxy(value)) {
if (isProxy(value)) {
return new RootPropertyReference(value, 'isTruthy');
} else {
return new PrimitiveReference(emberToBool(value));
}
}
Expand Down
3 changes: 2 additions & 1 deletion packages/ember-metal/lib/tags.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { meta as metaFor } from './meta';
import require, { has } from 'require';

let hasGlimmer = has('glimmer-reference');
const hasGlimmer = has('glimmer-reference');

let CONSTANT_TAG, CURRENT_TAG, DirtyableTag, makeTag, run;

let hasViews = () => false;
Expand Down
2 changes: 1 addition & 1 deletion packages/ember-metal/lib/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ if (isEnabled('ember-glimmer-detect-backtracking-rerender') ||
let label;

if (lastRef) {
while (lastRef && lastRef._propertyKey && lastRef._parentReference) {
while (lastRef && lastRef._propertyKey) {
parts.unshift(lastRef._propertyKey);
lastRef = lastRef._parentReference;
}
Expand Down
Loading