Skip to content

Commit

Permalink
Merge pull request #12011 from emberjs/glimmer-component
Browse files Browse the repository at this point in the history
Glimmer component
  • Loading branch information
rwjblue committed Aug 17, 2015
2 parents 295fa60 + c4e43a2 commit ae6c9e8
Show file tree
Hide file tree
Showing 54 changed files with 1,790 additions and 1,356 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import run from 'ember-metal/run_loop';
import Logger from 'ember-metal/logger';
import Controller from 'ember-runtime/controllers/controller';
import Route from 'ember-routing/system/route';
import Component from 'ember-views/views/component';
import Component from 'ember-views/components/component';
import View from 'ember-views/views/view';
import Service from 'ember-runtime/system/service';
import EmberObject from 'ember-runtime/system/object';
Expand Down
4 changes: 1 addition & 3 deletions packages/ember-htmlbars/lib/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import lookupHelper from 'ember-htmlbars/hooks/lookup-helper';
import hasHelper from 'ember-htmlbars/hooks/has-helper';
import invokeHelper from 'ember-htmlbars/hooks/invoke-helper';
import element from 'ember-htmlbars/hooks/element';
import attributes from 'ember-htmlbars/hooks/attributes';

import helpers from 'ember-htmlbars/helpers';
import keywords, { registerKeyword } from 'ember-htmlbars/keywords';
Expand Down Expand Up @@ -62,8 +61,7 @@ merge(emberHooks, {
lookupHelper,
hasHelper,
invokeHelper,
element,
attributes
element
});

import debuggerKeyword from 'ember-htmlbars/keywords/debugger';
Expand Down
26 changes: 26 additions & 0 deletions packages/ember-htmlbars/lib/glimmer-component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import CoreView from 'ember-views/views/core_view';
import ViewChildViewsSupport from 'ember-views/mixins/view_child_views_support';
import ViewStateSupport from 'ember-views/mixins/view_state_support';
import TemplateRenderingSupport from 'ember-views/mixins/template_rendering_support';
import ClassNamesSupport from 'ember-views/mixins/class_names_support';
import InstrumentationSupport from 'ember-views/mixins/instrumentation_support';
import AriaRoleSupport from 'ember-views/mixins/aria_role_support';
import ViewMixin from 'ember-views/mixins/view_support';
import EmberView from 'ember-views/views/view';

export default CoreView.extend(
ViewChildViewsSupport,
ViewStateSupport,
TemplateRenderingSupport,
ClassNamesSupport,
InstrumentationSupport,
AriaRoleSupport,
ViewMixin, {
isComponent: true,
isGlimmerComponent: true,

init() {
this._super(...arguments);
this._viewRegistry = this._viewRegistry || EmberView.views;
}
});
50 changes: 0 additions & 50 deletions packages/ember-htmlbars/lib/hooks/attributes.js

This file was deleted.

8 changes: 7 additions & 1 deletion packages/ember-htmlbars/lib/hooks/bind-self.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ export default function bindSelf(env, scope, _self) {
if (self && self.isView) {
newStream(scope.locals, 'view', self, null);
newStream(scope.locals, 'controller', scope.locals.view.getKey('controller'));
newStream(scope, 'self', scope.locals.view.getKey('context'), null, true);

if (self.isGlimmerComponent) {
newStream(scope, 'self', self, null, true);
} else {
newStream(scope, 'self', scope.locals.view.getKey('context'), null, true);
}

return;
}

Expand Down
4 changes: 1 addition & 3 deletions packages/ember-htmlbars/lib/hooks/bind-shadow-scope.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
@submodule ember-htmlbars
*/

import Component from 'ember-views/views/component';

export default function bindShadowScope(env, parentScope, shadowScope, options) {
if (!options) { return; }

Expand All @@ -16,7 +14,7 @@ export default function bindShadowScope(env, parentScope, shadowScope, options)
}

var view = options.view;
if (view && !(view instanceof Component)) {
if (view && !view.isComponent) {
newStream(shadowScope.locals, 'view', view, null);

if (!didOverrideController) {
Expand Down
91 changes: 73 additions & 18 deletions packages/ember-htmlbars/lib/hooks/component.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import ComponentNodeManager from 'ember-htmlbars/node-managers/component-node-manager';
import buildComponentTemplate from 'ember-views/system/build-component-template';
import buildComponentTemplate, { buildHTMLTemplate } from 'ember-views/system/build-component-template';
import lookupComponent from 'ember-htmlbars/utils/lookup-component';
import Ember from 'ember-metal/core';

export default function componentHook(renderNode, env, scope, _tagName, params, attrs, templates, visitor) {
var state = renderNode.state;
Expand All @@ -12,7 +14,8 @@ export default function componentHook(renderNode, env, scope, _tagName, params,

let tagName = _tagName;
let isAngleBracket = false;
let isTopLevel;
let isTopLevel = false;
let isDasherized = false;

let angles = tagName.match(/^(@?)<(.*)>$/);

Expand All @@ -22,9 +25,73 @@ export default function componentHook(renderNode, env, scope, _tagName, params,
isTopLevel = !!angles[1];
}

var parentView = env.view;
if (tagName.indexOf('-') !== -1) {
isDasherized = true;
}

let parentView = env.view;

// | Top-level | Invocation: <foo-bar> | Invocation: {{foo-bar}} |
// ----------------------------------------------------------------------
// | <div> | <div> is component el | no special semantics (a) |
// | <foo-bar> | <foo-bar> is identity el | EWTF |
// | <bar-baz> | recursive invocation | no special semantics |
// | {{anything}} | EWTF | no special semantics |
//
// (a) needs to be implemented specially, because the usual semantics of
// <div> are defined by the compiled template, and we need to emulate
// those semantics.

let currentComponent = env.view;
let isInvokedWithAngles = currentComponent && currentComponent._isAngleBracket;
let isInvokedWithCurlies = currentComponent && !currentComponent._isAngleBracket;

// <div> at the top level of a <foo-bar> invocation
let isComponentHTMLElement = isAngleBracket && !isDasherized && isInvokedWithAngles;

// <foo-bar> at the top level of a <foo-bar> invocation
let isComponentIdentityElement = isAngleBracket && isTopLevel && tagName === env.view.tagName;

// <div> at the top level of a {{foo-bar}} invocation
let isNormalHTMLElement = isAngleBracket && !isDasherized && isInvokedWithCurlies;

let component, layout;
if (isDasherized || !isAngleBracket) {
let result = lookupComponent(env.container, tagName);
component = result.component;
layout = result.layout;

if (isAngleBracket && isDasherized && !component && !layout) {
isComponentHTMLElement = true;
} else {
Ember.assert(`HTMLBars error: Could not find component named "${tagName}" (no component or template with that name was found)`, !!(component || layout));
}
}

if (isComponentIdentityElement || isComponentHTMLElement) {
// Inside the layout for <foo-bar> invoked with angles, this is the top-level element
// for the component. It can either be `<foo-bar>` (the "identity element") or any
// normal HTML element (non-dasherized).
let templateOptions = {
component: currentComponent,
tagName,
isAngleBracket: true,
isComponentElement: true,
outerAttrs: scope.attrs,
parentScope: scope
};

let contentOptions = { templates, scope };

let { block } = buildComponentTemplate(templateOptions, attrs, contentOptions);
block(env, [], undefined, renderNode, scope, visitor);
} else if (isNormalHTMLElement) {
let block = buildHTMLTemplate(tagName, attrs, { templates, scope });
block(env, [], undefined, renderNode, scope, visitor);
} else {
// Invoking a component from the outside (either via <foo-bar> angle brackets
// or {{foo-bar}} legacy curlies).

if (!isTopLevel || tagName !== env.view.tagName) {
var manager = ComponentNodeManager.create(renderNode, env, {
tagName,
params,
Expand All @@ -33,24 +100,12 @@ export default function componentHook(renderNode, env, scope, _tagName, params,
templates,
isAngleBracket,
isTopLevel,
component,
layout,
parentScope: scope
});

state.manager = manager;
manager.render(env, visitor);
} else {
let component = env.view;
let templateOptions = {
component,
isAngleBracket: true,
isComponentElement: true,
outerAttrs: scope.attrs,
parentScope: scope
};

let contentOptions = { templates, scope };

let { block } = buildComponentTemplate(templateOptions, attrs, contentOptions);
block(env, [], undefined, renderNode, scope, visitor);
}
}
5 changes: 5 additions & 0 deletions packages/ember-htmlbars/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ import legacyEachWithKeywordHelper from 'ember-htmlbars/helpers/-legacy-each-wit
import htmlSafeHelper from 'ember-htmlbars/helpers/-html-safe';
import DOMHelper from 'ember-htmlbars/system/dom-helper';
import Helper, { helper as makeHelper } from 'ember-htmlbars/helper';
import GlimmerComponent from 'ember-htmlbars/glimmer-component';

// importing adds template bootstrapping
// initializer to enable embedded templates
Expand Down Expand Up @@ -160,5 +161,9 @@ Ember.HTMLBars = {
DOMHelper
};

if (isEnabled('ember-htmlbars-component-generation')) {
Ember.GlimmerComponent = GlimmerComponent;
}

Helper.helper = makeHelper;
Ember.Helper = Helper;
Loading

0 comments on commit ae6c9e8

Please sign in to comment.