Skip to content

Commit

Permalink
Merge pull request #12626 from Serabe/fix-12625
Browse files Browse the repository at this point in the history
[BUGFIX beta] Fix positional params in contextual components with dot syntax
  • Loading branch information
rwjblue committed Nov 19, 2015
2 parents 6b3e6ea + a18490a commit 9c58ec6
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 10 deletions.
16 changes: 16 additions & 0 deletions packages/ember-htmlbars/lib/hooks/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
COMPONENT_HASH,
isComponentCell,
mergeInNewHash,
processPositionalParamsFromCell,
} from 'ember-htmlbars/keywords/closure-component';

var IS_ANGLE_CACHE = new Cache(1000, function(key) {
Expand All @@ -33,6 +34,21 @@ export default function componentHook(renderNode, env, scope, _tagName, params,
let componentCell = stream.value();
if (isComponentCell(componentCell)) {
tagName = componentCell[COMPONENT_PATH];

/*
* Processing positional params before merging into a hash must be done
* here to avoid problems with rest positional parameters rendered using
* the dot notation.
*
* Closure components (for the contextual component feature) do not
* actually keep the positional params, but process them at each level.
* Therefore, when rendering a closure component with the component
* helper we process the parameters and attributes and then merge those
* on top of the closure component attributes.
*
*/
processPositionalParamsFromCell(componentCell, params, attrs);
params = [];
attrs = mergeInNewHash(componentCell[COMPONENT_HASH], attrs);
}
}
Expand Down
12 changes: 8 additions & 4 deletions packages/ember-htmlbars/lib/keywords/closure-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,23 @@ export function isComponentCell(component) {
}

function createNestedClosureComponentCell(componentCell, params, hash) {
let positionalParams = componentCell[COMPONENT_POSITIONAL_PARAMS];

// This needs to be done in each nesting level to avoid raising assertions
processPositionalParams(null, positionalParams, params, hash);
processPositionalParamsFromCell(componentCell, params, hash);

return {
[COMPONENT_PATH]: componentCell[COMPONENT_PATH],
[COMPONENT_HASH]: mergeInNewHash(componentCell[COMPONENT_HASH], hash),
[COMPONENT_POSITIONAL_PARAMS]: positionalParams,
[COMPONENT_POSITIONAL_PARAMS]: componentCell[COMPONENT_POSITIONAL_PARAMS],
[COMPONENT_CELL]: true
};
}

export function processPositionalParamsFromCell(componentCell, params, hash) {
let positionalParams = componentCell[COMPONENT_POSITIONAL_PARAMS];

processPositionalParams(null, positionalParams, params, hash);
}

function createNewClosureComponentCell(env, componentPath, params, hash) {
let positionalParams = getPositionalParams(env.owner, componentPath);

Expand Down
6 changes: 2 additions & 4 deletions packages/ember-htmlbars/lib/keywords/element-component.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import assign from 'ember-metal/assign';
import {
COMPONENT_PATH,
COMPONENT_POSITIONAL_PARAMS,
COMPONENT_HASH,
isComponentCell,
mergeInNewHash,
processPositionalParamsFromCell,
} from './closure-component';
import { processPositionalParams } from 'ember-htmlbars/utils/extract-positional-params';

export default {
setupState(lastState, env, scope, params, hash) {
Expand Down Expand Up @@ -58,10 +57,9 @@ function render(morph, env, scope, [path, ...params], hash, template, inverse, v

if (isComponentCell(path)) {
let closureComponent = env.hooks.getValue(path);
let positionalParams = closureComponent[COMPONENT_POSITIONAL_PARAMS];

// This needs to be done in each nesting level to avoid raising assertions
processPositionalParams(null, positionalParams, params, hash);
processPositionalParamsFromCell(closureComponent, params, hash);
params = [];
hash = mergeInNewHash(closureComponent[COMPONENT_HASH], hash);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export default function extractPositionalParams(renderNode, component, params, a
}

export function processPositionalParams(renderNode, positionalParams, params, attrs) {
let isNamed = typeof positionalParams === 'string';
let isRest = typeof positionalParams === 'string';

if (isNamed) {
if (isRest) {
processRestPositionalParameters(renderNode, positionalParams, params, attrs);
} else {
processNamedPositionalParameters(renderNode, positionalParams, params, attrs);
Expand Down
27 changes: 27 additions & 0 deletions packages/ember-htmlbars/tests/helpers/closure_component_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,33 @@ if (isEnabled('ember-contextual-components')) {
equal(component.$().text(), expectedText, '-looked-up component rendered');
});

QUnit.test('renders with dot path and with rest positional parameters', function() {
let LookedUp = Component.extend();
LookedUp.reopenClass({
positionalParams: 'params'
});
owner.register(
'component:-looked-up',
LookedUp
);
let expectedText = 'Hodi';
owner.register(
'template:components/-looked-up',
compile('{{params}}')
);

let template = compile('{{#with (hash lookedup=(component "-looked-up")) as |object|}}{{object.lookedup expectedText "Hola"}}{{/with}}');
component = Component.extend({
[OWNER]: owner,
template
}).create({
expectedText
});

runAppend(component);
equal(component.$().text(), `${expectedText},Hola`, '-looked-up component rendered with rest params');
});

QUnit.test('adding parameters to a closure component\'s instance does not add it to other instances', function(assert) {
owner.register(
'template:components/select-box',
Expand Down

0 comments on commit 9c58ec6

Please sign in to comment.