Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUGFIX beta] Fix positional params in contextual components with dot syntax #12626

Merged
merged 1 commit into from
Nov 19, 2015
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
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