Skip to content

Commit

Permalink
[FEATURE set-component-template] Add @ember/component/template-only
Browse files Browse the repository at this point in the history
As part of RFC 481 this adds the `@ember/component/template-only` module, and
its associated implementation.

Co-authored-by: Robert Jackson <me@rwjblue.com>
  • Loading branch information
chancancode and rwjblue committed Jul 10, 2019
1 parent b31998b commit ebafed5
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 2 deletions.
7 changes: 6 additions & 1 deletion packages/@ember/-internals/glimmer/lib/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
EMBER_GLIMMER_SET_COMPONENT_TEMPLATE,
EMBER_MODULE_UNIFICATION,
} from '@ember/canary-features';
import { isTemplateOnlyComponent } from '@ember/component/template-only';
import { assert } from '@ember/debug';
import { _instrumentStart } from '@ember/instrumentation';
import {
Expand Down Expand Up @@ -449,7 +450,11 @@ export default class RuntimeResolver implements IRuntimeResolver<OwnedTemplateMe

let definition: Option<ComponentDefinition> = null;

if (pair.component === null && ENV._TEMPLATE_ONLY_GLIMMER_COMPONENTS) {
if (pair.component === null) {
if(ENV._TEMPLATE_ONLY_GLIMMER_COMPONENTS) {
definition = new TemplateOnlyComponentDefinition(layout!);
}
} else if (EMBER_GLIMMER_SET_COMPONENT_TEMPLATE && isTemplateOnlyComponent(pair.component.class)) {
definition = new TemplateOnlyComponentDefinition(layout!);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { moduleFor, RenderingTestCase, classes, runTask } from 'internal-test-helpers';
import { EMBER_GLIMMER_SET_COMPONENT_TEMPLATE } from '@ember/canary-features';

import { ENV } from '@ember/-internals/environment';
import { setComponentTemplate } from '@ember/-internals/glimmer';
import templateOnly from '@ember/component/template-only';
import { compile } from 'ember-template-compiler';

class TemplateOnlyComponentsTest extends RenderingTestCase {
registerComponent(name, template) {
Expand Down Expand Up @@ -247,3 +251,49 @@ moduleFor(
}
}
);

if (EMBER_GLIMMER_SET_COMPONENT_TEMPLATE) {
moduleFor(
'Components test: template-only components (using `templateOnlyComponent()`)',
class extends RenderingTestCase {
['@test it can render a component']() {
this.registerComponent('foo-bar', { ComponentClass: templateOnly(), template: 'hello' });

this.render('{{foo-bar}}');

this.assertInnerHTML('hello');

this.assertStableRerender();
}

['@test it can render a component when template was not registered']() {
let ComponentClass = templateOnly();
setComponentTemplate(compile('hello'), ComponentClass);

this.registerComponent('foo-bar', { ComponentClass });

this.render('{{foo-bar}}');

this.assertInnerHTML('hello');

this.assertStableRerender();
}

['@test setComponentTemplate takes precedence over registered layout']() {
let ComponentClass = templateOnly();
setComponentTemplate(compile('hello'), ComponentClass);

this.registerComponent('foo-bar', {
ComponentClass,
template: 'this should not be rendered',
});

this.render('{{foo-bar}}');

this.assertInnerHTML('hello');

this.assertStableRerender();
}
}
);
}
1 change: 1 addition & 0 deletions packages/@ember/component/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Component } from '@ember/-internals/glimmer';
16 changes: 16 additions & 0 deletions packages/@ember/component/template-only.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// This is only exported for types, don't use this class directly
export class TemplateOnlyComponent {
constructor(public moduleName: string) {}

toString(): string {
return '@ember/component/template-only';
}
}

export default function templateOnlyComponent(moduleName: string): TemplateOnlyComponent {
return new TemplateOnlyComponent(moduleName);
}

export function isTemplateOnlyComponent(component: unknown): component is TemplateOnlyComponent {
return component instanceof TemplateOnlyComponent;
}
3 changes: 2 additions & 1 deletion packages/ember/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ import Engine from '@ember/engine';
import EngineInstance from '@ember/engine/instance';
import { assign, merge } from '@ember/polyfills';
import { LOGGER, EMBER_EXTEND_PROTOTYPES, JQUERY_INTEGRATION } from '@ember/deprecated-features';

import templateOnlyComponent from '@ember/component/template-only';
// ****@ember/-internals/environment****

const Ember = (typeof context.imports.Ember === 'object' && context.imports.Ember) || {};
Expand Down Expand Up @@ -540,6 +540,7 @@ Ember._modifierManagerCapabilties = modifierCapabilties;
if (EMBER_GLIMMER_SET_COMPONENT_TEMPLATE) {
Ember._getComponentTemplate = getComponentTemplate;
Ember._setComponentTemplate = setComponentTemplate;
Ember._templateOnlyComponent = templateOnlyComponent;
}
Ember.Handlebars = {
template,
Expand Down
3 changes: 3 additions & 0 deletions packages/ember/tests/reexports_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,9 @@ let allExports = [
EMBER_GLIMMER_SET_COMPONENT_TEMPLATE
? ['_getComponentTemplate', '@ember/-internals/glimmer', 'getComponentTemplate']
: null,
EMBER_GLIMMER_SET_COMPONENT_TEMPLATE
? ['_templateOnlyComponent', '@ember/component/template-only', 'default']
: null,

// @ember/-internals/runtime
['A', '@ember/-internals/runtime'],
Expand Down

0 comments on commit ebafed5

Please sign in to comment.