Skip to content

Commit

Permalink
Merge pull request #11359 from emberjs/in-template-config
Browse files Browse the repository at this point in the history
Implements RFC #60 (Component Unification)
  • Loading branch information
tomdale committed Jul 8, 2015
2 parents 7290cd0 + e7866ca commit b587c48
Show file tree
Hide file tree
Showing 10 changed files with 469 additions and 205 deletions.
50 changes: 26 additions & 24 deletions packages/ember-htmlbars/lib/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ 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 All @@ -38,30 +39,31 @@ var emberHooks = merge({}, hooks);
emberHooks.keywords = keywords;

merge(emberHooks, {
linkRenderNode: linkRenderNode,
createFreshScope: createFreshScope,
bindShadowScope: bindShadowScope,
bindSelf: bindSelf,
bindScope: bindScope,
bindLocal: bindLocal,
updateSelf: updateSelf,
getRoot: getRoot,
getChild: getChild,
getValue: getValue,
getCellOrValue: getCellOrValue,
subexpr: subexpr,
concat: concat,
cleanupRenderNode: cleanupRenderNode,
destroyRenderNode: destroyRenderNode,
willCleanupTree: willCleanupTree,
didCleanupTree: didCleanupTree,
didRenderNode: didRenderNode,
classify: classify,
component: component,
lookupHelper: lookupHelper,
hasHelper: hasHelper,
invokeHelper: invokeHelper,
element: element
linkRenderNode,
createFreshScope,
bindShadowScope,
bindSelf,
bindScope,
bindLocal,
updateSelf,
getRoot,
getChild,
getValue,
getCellOrValue,
subexpr,
concat,
cleanupRenderNode,
destroyRenderNode,
willCleanupTree,
didCleanupTree,
didRenderNode,
classify,
component,
lookupHelper,
hasHelper,
invokeHelper,
element,
attributes
});

import debuggerKeyword from 'ember-htmlbars/keywords/debugger';
Expand Down
50 changes: 50 additions & 0 deletions packages/ember-htmlbars/lib/hooks/attributes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { render, internal } from 'htmlbars-runtime';

export default function attributes(morph, env, scope, template, parentNode, visitor) {
let state = morph.state;
let block = state.block;

if (!block) {
let element = findRootElement(parentNode);
if (!element) { return; }

normalizeClassStatement(template.statements, element);

template.element = element;
block = morph.state.block = internal.blockFor(render, template, { scope });
}

block(env, [], undefined, morph, undefined, visitor);
}

function normalizeClassStatement(statements, element) {
let className = element.getAttribute('class');
if (!className) { return; }

for (let i=0, l=statements.length; i<l; i++) {
let statement = statements[i];

if (statement[1] === 'class') {
statement[2][2].unshift(className);
}
}
}

function findRootElement(parentNode) {
let node = parentNode.firstChild;
let found = null;

while (node) {
if (node.nodeType === 1) {
// found more than one top-level element, so there is no "root element"
if (found) { return null; }
found = node;
}
node = node.nextSibling;
}

let className = found && found.getAttribute('class');
if (!className || className.split(' ').indexOf('ember-view') === -1) {
return found;
}
}
50 changes: 36 additions & 14 deletions packages/ember-htmlbars/lib/hooks/component.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ComponentNodeManager from 'ember-htmlbars/node-managers/component-node-manager';
import buildComponentTemplate from 'ember-views/system/build-component-template';

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

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

if (tagName.charAt(0) === '<') {
tagName = tagName.slice(1, -1);
let angles = tagName.match(/^(@?)<(.*)>$/);

if (angles) {
tagName = angles[2];
isAngleBracket = true;
isTopLevel = !!angles[1];
}

var parentView = env.view;

var manager = ComponentNodeManager.create(renderNode, env, {
tagName,
params,
attrs,
parentView,
templates,
isAngleBracket,
parentScope: scope
});

state.manager = manager;
if (!isTopLevel || tagName !== env.view.tagName) {
var manager = ComponentNodeManager.create(renderNode, env, {
tagName,
params,
attrs,
parentView,
templates,
isAngleBracket,
isTopLevel,
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);
}

manager.render(env, visitor);
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ ComponentNodeManager.create = function(renderNode, env, options) {

extractPositionalParams(renderNode, component, params, attrs);

var results = buildComponentTemplate(
let results = buildComponentTemplate(
{ layout, component, isAngleBracket }, attrs, { templates, scope: parentScope }
);

Expand Down
Loading

0 comments on commit b587c48

Please sign in to comment.