Skip to content

Commit

Permalink
Merge pull request #15245 from emberjs/bump-glimmer
Browse files Browse the repository at this point in the history
Bump glimmer-vm packages to 0.24.
  • Loading branch information
rwjblue authored May 29, 2017
2 parents d42a2a6 + 33391a8 commit 91d8f08
Show file tree
Hide file tree
Showing 50 changed files with 914 additions and 1,096 deletions.
2 changes: 1 addition & 1 deletion broccoli/packages.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ module.exports.emberPkgES = function _emberPkgES(name, rollup, externs) {
}

module.exports.glimmerPkgES = function _glimmerPkgES(name, externs = []) {
return new Rollup(findLib(name, 'dist/modules'), {
return new Rollup(findLib(name, 'dist/modules/es5'), {
rollup: {
entry: 'index.js',
dest: `${name}.js`,
Expand Down
4 changes: 2 additions & 2 deletions ember-cli-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ module.exports = function(options) {
let emberTemplateCompiler = emberPkgES('ember-template-compiler');
let emberTemplateCompilerES5 = toES5(emberTemplateCompiler, { annotation: 'ember-template-compiler' });
let glimmerSyntax = toES5(
glimmerPkgES('@glimmer/syntax', ['handlebars', 'simple-html-tokenizer']),
glimmerPkgES('@glimmer/syntax', ['@glimmer/util', 'handlebars', 'simple-html-tokenizer']),
{ annotation: '@glimmer/syntax' }
);
let glimmerCompiler = toES5(
Expand Down Expand Up @@ -384,4 +384,4 @@ function testHarnessFiles() {
jquery(),
qunit()
];
}
}
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@
"link:glimmer": "node bin/yarn-link-glimmer.js"
},
"dependencies": {
"@glimmer/compiler": "^0.22.1",
"@glimmer/node": "^0.22.1",
"@glimmer/reference": "^0.22.1",
"@glimmer/runtime": "^0.22.1",
"@glimmer/util": "^0.22.1",
"@glimmer/compiler": "^0.24.0-beta.4",
"@glimmer/node": "^0.24.0-beta.4",
"@glimmer/reference": "^0.24.0-beta.4",
"@glimmer/runtime": "^0.24.0-beta.4",
"@glimmer/util": "^0.24.0-beta.4",
"broccoli-funnel": "^1.2.0",
"broccoli-merge-trees": "^2.0.0",
"ember-cli-get-component-path-option": "^1.0.0",
Expand Down
68 changes: 68 additions & 0 deletions packages/ember-glimmer/lib/component-managers/abstract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { DEBUG } from 'ember-env-flags';

// implements the ComponentManager interface as defined in glimmer:
// https://github.com/glimmerjs/glimmer-vm/blob/v0.24.0-beta.4/packages/%40glimmer/runtime/lib/component/interfaces.ts#L21

export default class AbstractManager {
constructor() {
this.debugStack = undefined;
}

prepareArgs(definition, args) {
return null;
}

// must be implemented by inheritors, inheritors should also
// call `this._pushToDebugStack` to ensure the rerendering
// assertion messages are properly maintained
create(env, definition, args, dynamicScope, caller, hasBlock) {
if (DEBUG) {
throw new Error('AbstractManager#create must be implemented.');
}
}

layoutFor(definition, bucket, env) {
if (DEBUG) {
throw new Error('AbstractManager#create must be implemented.');
}
}

getSelf(bucket) { return bucket; }

didCreateElement(bucket, element, operations) { }

// inheritors should also call `this.debugStack.pop()` to
// ensure the rerendering assertion messages are properly
// maintained
didRenderLayout(bucket, bounds) { }

didCreate(bucket) { }

getTag(bucket) { return null; }

// inheritors should also call `this._pushToDebugStack`
// to ensure the rerendering assertion messages are
// properly maintained
update(bucket, dynamicScope) { }

// inheritors should also call `this.debugStack.pop()` to
// ensure the rerendering assertion messages are properly
// maintained
didUpdateLayout(bucket, bounds) { }

didUpdate(bucket) { }

getDestructor(bucket) { }
}

if (DEBUG) {
AbstractManager.prototype._pushToDebugStack = function(name, environment) {
this.debugStack = environment.debugStack;
this.debugStack.push(name);
};

AbstractManager.prototype._pushEngineToDebugStack = function(name, environment) {
this.debugStack = environment.debugStack;
this.debugStack.pushEngine(name);
};
}
174 changes: 147 additions & 27 deletions packages/ember-glimmer/lib/component-managers/curly.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { OWNER } from 'ember-utils';
import { OWNER, assign } from 'ember-utils';
import { combineTagged } from '@glimmer/reference';
import {
PrimitiveReference
PrimitiveReference,
ComponentDefinition
} from '@glimmer/runtime';
import {
assert
Expand All @@ -22,23 +24,15 @@ import {
get,
_instrumentStart
} from 'ember-metal';
import {
gatherArgs,
ComponentArgs
} from '../utils/process-args';
import { processComponentArgs } from '../utils/process-args';
import {
dispatchLifeCycleHook,
setViewElement
} from 'ember-views';
import { privatize as P } from 'container';
import AbstractManager from '../syntax/abstract-manager';
import ComponentStateBucket from '../syntax/component-state-bucket';
import {
initialRenderInstrumentDetails,
rerenderInstrumentDetails,
validatePositionalParameters,
processComponentInitializationAssertions
} from '../syntax/curly-component';
import AbstractManager from './abstract';
import ComponentStateBucket from '../utils/curly-component-state-bucket';
import { PropertyReference } from '../utils/references';

const DEFAULT_LAYOUT = P`template:components/-default`;

Expand Down Expand Up @@ -94,7 +88,7 @@ class CurlyComponentLayoutCompiler {
}

compile(builder) {
builder.wrapLayout(this.template.asLayout());
builder.wrapLayout(this.template);
builder.tag.dynamic(tagName);
builder.attrs.dynamic('role', ariaRole);
builder.attrs.static('class', 'ember-view');
Expand All @@ -103,13 +97,69 @@ class CurlyComponentLayoutCompiler {

CurlyComponentLayoutCompiler.id = 'curly';

export class PositionalArgumentReference {
constructor(references) {
this.tag = combineTagged(references);
this._references = references;
}

value() {
return this._references.map(reference => reference.value());
}

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

export default class CurlyComponentManager extends AbstractManager {
prepareArgs(definition, args) {
if (definition.ComponentClass) {
validatePositionalParameters(args.named, args.positional.values, definition.ComponentClass.class.positionalParams);
let componentPositionalParamsDefinition = definition.ComponentClass.class.positionalParams;

if (DEBUG && componentPositionalParamsDefinition) {
validatePositionalParameters(args.named, args.positional, componentPositionalParamsDefinition);
}

return gatherArgs(args, definition);
let componentHasRestStylePositionalParams = typeof componentPositionalParamsDefinition === 'string';
let componentHasPositionalParams = componentHasRestStylePositionalParams || componentPositionalParamsDefinition.length > 0;
let needsPositionalParamMunging = componentHasPositionalParams && args.positional.length !== 0;
let isClosureComponent = definition.args;

if (!needsPositionalParamMunging && !isClosureComponent) {
return null;
}

let capturedArgs = args.capture();
// grab raw positional references array
let positional = capturedArgs.positional.references;

// handle prep for closure component with positional params
let curriedNamed;
if (definition.args) {
let remainingDefinitionPositionals = definition.args.positional.slice(positional.length);
positional = positional.concat(remainingDefinitionPositionals);
curriedNamed = definition.args.named;
}

// handle positionalParams
let positionalParamsToNamed;
if (componentHasRestStylePositionalParams) {
positionalParamsToNamed = {
[componentPositionalParamsDefinition]: new PositionalArgumentReference(positional)
};
positional = [];
} else if (componentHasPositionalParams){
positionalParamsToNamed = {};
let length = Math.min(positional.length, componentPositionalParamsDefinition.length);
for (let i = 0; i < length; i++) {
let name = componentPositionalParamsDefinition[i];
positionalParamsToNamed[name] = positional[i];
}
}

let named = assign({}, curriedNamed, positionalParamsToNamed, capturedArgs.named.map);

return { positional, named };
}

create(environment, definition, args, dynamicScope, callerSelfRef, hasBlock) {
Expand All @@ -121,8 +171,8 @@ export default class CurlyComponentManager extends AbstractManager {

let factory = definition.ComponentClass;

let processedArgs = ComponentArgs.create(args);
let { props } = processedArgs.value();
let capturedArgs = args.named.capture();
let props = processComponentArgs(capturedArgs);

aliasIdToElementId(args, props);

Expand Down Expand Up @@ -154,7 +204,7 @@ export default class CurlyComponentManager extends AbstractManager {
}
}

let bucket = new ComponentStateBucket(environment, component, processedArgs, finalizer);
let bucket = new ComponentStateBucket(environment, component, capturedArgs, finalizer);

if (args.named.has('class')) {
bucket.classRef = args.named.get('class');
Expand Down Expand Up @@ -266,19 +316,16 @@ export default class CurlyComponentManager extends AbstractManager {
bucket.finalizer = _instrumentStart('render.component', rerenderInstrumentDetails, component);

if (!args.tag.validate(argsRevision)) {
let { attrs, props } = args.value();
let props = processComponentArgs(args);

bucket.argsRevision = args.tag.value();

let oldAttrs = component.attrs;
let newAttrs = attrs;

component[IS_DISPATCHING_ATTRS] = true;
component.setProperties(props);
component[IS_DISPATCHING_ATTRS] = false;

dispatchLifeCycleHook(component, 'didUpdateAttrs', oldAttrs, newAttrs);
dispatchLifeCycleHook(component, 'didReceiveAttrs', oldAttrs, newAttrs);
dispatchLifeCycleHook(component, 'didUpdateAttrs');
dispatchLifeCycleHook(component, 'didReceiveAttrs');
}

if (environment.isInteractive) {
Expand Down Expand Up @@ -306,3 +353,76 @@ export default class CurlyComponentManager extends AbstractManager {
return stateBucket;
}
}

export function validatePositionalParameters(named, positional, positionalParamsDefinition) {
if (DEBUG) {
if (!named || !positional || !positional.length) {
return;
}

let paramType = typeof positionalParamsDefinition;

if (paramType === 'string') {
assert(`You cannot specify positional parameters and the hash argument \`${positionalParamsDefinition}\`.`, !named.has(positionalParamsDefinition));
} else {
if (positional.length < positionalParamsDefinition.length) {
positionalParamsDefinition = positionalParamsDefinition.slice(0, positional.length);
}

for (let i = 0; i < positionalParamsDefinition.length; i++) {
let name = positionalParamsDefinition[i];

assert(
`You cannot specify both a positional param (at position ${i}) and the hash argument \`${name}\`.`,
!named.has(name)
);
}
}
}
}

export function processComponentInitializationAssertions(component, props) {
assert(`classNameBindings must not have spaces in them: ${component.toString()}`, (() => {
let { classNameBindings } = component;
for (let i = 0; i < classNameBindings.length; i++) {
let binding = classNameBindings[i];
if (binding.split(' ').length > 1) {
return false;
}
}
return true;
})());

assert('You cannot use `classNameBindings` on a tag-less component: ' + component.toString(), (() => {
let { classNameBindings, tagName } = component;
return tagName !== '' || !classNameBindings || classNameBindings.length === 0;
})());

assert('You cannot use `elementId` on a tag-less component: ' + component.toString(), (() => {
let { elementId, tagName } = component;
return tagName !== '' || props.id === elementId || (!elementId && elementId !== '');
})());

assert('You cannot use `attributeBindings` on a tag-less component: ' + component.toString(), (() => {
let { attributeBindings, tagName } = component;
return tagName !== '' || !attributeBindings || attributeBindings.length === 0;
})());
}

export function initialRenderInstrumentDetails(component) {
return component.instrumentDetails({ initialRender: true });
}

export function rerenderInstrumentDetails(component) {
return component.instrumentDetails({ initialRender: false });
}

const MANAGER = new CurlyComponentManager();

export class CurlyComponentDefinition extends ComponentDefinition {
constructor(name, ComponentClass, template, args, customManager) {
super(name, customManager || MANAGER, ComponentClass);
this.template = template;
this.args = args;
}
}
Loading

0 comments on commit 91d8f08

Please sign in to comment.