Skip to content

Commit

Permalink
Merge pull request #19695 from mixonic/mixonic/partial
Browse files Browse the repository at this point in the history
Remove {{partial}}
  • Loading branch information
mixonic committed Aug 17, 2021
2 parents c166010 + 51b3a9e commit 28e5a63
Show file tree
Hide file tree
Showing 8 changed files with 3 additions and 745 deletions.
41 changes: 0 additions & 41 deletions packages/@ember/-internals/glimmer/index.ts
Expand Up @@ -292,47 +292,6 @@
@public
*/

/**
The `partial` helper renders another template without
changing the template context:
```handlebars
{{foo}}
{{partial "nav"}}
```
The above example template will render a template named
"-nav", which has the same context as the parent template
it's rendered into, so if the "-nav" template also referenced
`{{foo}}`, it would print the same thing as the `{{foo}}`
in the above example.
If a "-nav" template isn't found, the `partial` helper will
fall back to a template named "nav".
### Bound template names
The parameter supplied to `partial` can also be a path
to a property containing a template name, e.g.:
```handlebars
{{partial someTemplateName}}
```
The above example will look up the value of `someTemplateName`
on the template context (e.g. a controller) and use that
value as the name of the template to render. If the resolved
value is falsy, nothing will be rendered. If `someTemplateName`
changes, the partial will be re-rendered using the new template
name.
@method partial
@for Ember.Templates.helpers
@param {String} partialName The name of the template to render minus the leading underscore.
@deprecated Use a component instead
@public
*/

export { templateFactory as template, templateCacheCounters } from '@glimmer/opcode-compiler';

export { default as RootTemplate } from './lib/templates/root';
Expand Down
77 changes: 3 additions & 74 deletions packages/@ember/-internals/glimmer/lib/resolver.ts
@@ -1,17 +1,14 @@
import { privatize as P } from '@ember/-internals/container';
import { ENV } from '@ember/-internals/environment';
import { Factory, FactoryClass, LookupOptions, Owner } from '@ember/-internals/owner';
import { assert, deprecate } from '@ember/debug';
import { PARTIALS } from '@ember/deprecated-features';
import EmberError from '@ember/error';
import { assert } from '@ember/debug';
import { _instrumentStart } from '@ember/instrumentation';
import { DEBUG } from '@glimmer/env';
import {
CompileTimeResolver,
HelperDefinitionState,
ModifierDefinitionState,
Option,
PartialDefinition,
ResolvedComponentDefinition,
RuntimeResolver,
Template,
Expand All @@ -22,7 +19,6 @@ import {
getInternalComponentManager,
setInternalHelperManager,
} from '@glimmer/manager';
import { PartialDefinitionImpl } from '@glimmer/opcode-compiler';
import {
array,
concat,
Expand Down Expand Up @@ -114,66 +110,6 @@ function lookupComponentPair(
}
}

let lookupPartial: { templateName: string; owner: Owner } | any;
let templateFor: { owner: Owner; underscored: string; name: string } | any;
let parseUnderscoredName: { templateName: string } | any;

if (PARTIALS) {
lookupPartial = function (templateName: string, owner: Owner) {
deprecate(
`The use of \`{{partial}}\` is deprecated, please refactor the "${templateName}" partial to a component`,
false,
{
id: 'ember-views.partial',
until: '4.0.0',
url: 'https://deprecations.emberjs.com/v3.x#toc_ember-views-partial',
for: 'ember-source',
since: {
enabled: '3.15.0-beta.1',
},
}
);

if (templateName === null) {
return;
}

let template = templateFor(owner, parseUnderscoredName(templateName), templateName);

assert(`Unable to find partial with name "${templateName}"`, Boolean(template));

return template;
};

templateFor = function (owner: any, underscored: string, name: string) {
if (PARTIALS) {
if (!name) {
return;
}
assert(`templateNames are not allowed to contain periods: ${name}`, name.indexOf('.') === -1);

if (!owner) {
throw new EmberError(
'Container was not found when looking up a views template. ' +
'This is most likely due to manually instantiating an Ember.View. ' +
'See: http://git.io/EKPpnA'
);
}

return owner.lookup(`template:${underscored}`) || owner.lookup(`template:${name}`);
}
};

parseUnderscoredName = function (templateName: string) {
let nameParts = templateName.split('/');
let lastPart = nameParts[nameParts.length - 1];

nameParts[nameParts.length - 1] = `_${lastPart}`;

return nameParts.join('/');
};
}

const BUILTIN_KEYWORD_HELPERS = {
action,
mut,
Expand Down Expand Up @@ -227,15 +163,8 @@ const CLASSIC_HELPER_MANAGER_ASSOCIATED = new _WeakSet();
export default class ResolverImpl implements RuntimeResolver<Owner>, CompileTimeResolver<Owner> {
private componentDefinitionCache: Map<object, ResolvedComponentDefinition | null> = new Map();

lookupPartial(name: string, owner: Owner): Option<PartialDefinition> {
if (PARTIALS) {
let templateFactory = lookupPartial(name, owner);
let template = templateFactory(owner);

return new PartialDefinitionImpl(name, template);
} else {
return null;
}
lookupPartial(): null {
return null;
}

lookupHelper(name: string, owner: Owner): Option<HelperDefinitionState> {
Expand Down
Expand Up @@ -157,44 +157,6 @@ moduleFor(
);
}

setupAppAndRoutableEngineWithPartial(hooks) {
this.addTemplate('application', 'Application{{outlet}}');

this.router.map(function () {
this.mount('blog');
});
this.add('route-map:blog', function () {});
this.add(
'route:application',
Route.extend({
model() {
hooks.push('application - application');
},
})
);

this.add(
'engine:blog',
Engine.extend({
Resolver: ModuleBasedTestResolver,

init() {
this._super(...arguments);
this.register('template:foo', compile('foo partial'));
this.register('template:application', compile('Engine{{outlet}} {{partial "foo"}}'));
this.register(
'route:application',
Route.extend({
model() {
hooks.push('engine - application');
},
})
);
},
})
);
}

setupRoutelessEngine(hooks) {
this.addTemplate('application', 'Application{{mount "chat-engine"}}');
this.add(
Expand All @@ -207,82 +169,14 @@ moduleFor(
);
}

setupAppAndRoutlessEngineWithPartial(hooks) {
this.setupRoutelessEngine(hooks);

this.add(
'engine:chat-engine',
Engine.extend({
Resolver: ModuleBasedTestResolver,

init() {
this._super(...arguments);
this.register('template:foo', compile('foo partial'));
this.register('template:application', compile('Engine {{partial "foo"}}'));
this.register(
'controller:application',
Controller.extend({
init() {
this._super(...arguments);
hooks.push('engine - application');
},
})
);
},
})
);
}

additionalEngineRegistrations(callback) {
this._additionalEngineRegistrations = callback;
}

setupEngineWithAttrs() {
this.addTemplate('application', 'Application{{mount "chat-engine"}}');

this.add(
'engine:chat-engine',
Engine.extend({
Resolver: ModuleBasedTestResolver,

init() {
this._super(...arguments);
this.register('template:components/foo-bar', compile(`{{partial "troll"}}`));
this.register('template:troll', compile('{{attrs.wat}}'));
this.register(
'controller:application',
Controller.extend({
contextType: 'Engine',
})
);
this.register(
'template:application',
compile('Engine {{foo-bar wat=this.contextType}}')
);
},
})
);
}

stringsEndWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}

['@test attrs in an engine']() {
expectDeprecation(
`The use of \`{{partial}}\` is deprecated, please refactor the "troll" partial to a component`
);
expectDeprecation(
'Using {{attrs}} to reference named arguments has been deprecated. {{attrs.wat}} should be updated to {{@wat}}. (L1:C2) '
);

this.setupEngineWithAttrs([]);

return this.visit('/').then(() => {
this.assertText('ApplicationEngine Engine');
});
}

['@test sharing a template between engine and application has separate refinements']() {
this.assert.expect(2);

Expand Down Expand Up @@ -467,50 +361,6 @@ moduleFor(
});
}

['@test visit() with partials in routable engine'](assert) {
assert.expect(3);

expectDeprecation(
`The use of \`{{partial}}\` is deprecated, please refactor the "foo" partial to a component`
);

let hooks = [];

this.setupAppAndRoutableEngineWithPartial(hooks);

return this.visit('/blog', { shouldRender: true }).then(() => {
this.assertText('ApplicationEngine foo partial');

this.assert.deepEqual(
hooks,
['application - application', 'engine - application'],
'the expected hooks were fired'
);
});
}

['@test visit() with partials in non-routable engine'](assert) {
assert.expect(3);

expectDeprecation(
`The use of \`{{partial}}\` is deprecated, please refactor the "foo" partial to a component`
);

let hooks = [];

this.setupAppAndRoutlessEngineWithPartial(hooks);

return this.visit('/', { shouldRender: true }).then(() => {
this.assertText('ApplicationEngine foo partial');

this.assert.deepEqual(
hooks,
['application - application', 'engine - application'],
'the expected hooks were fired'
);
});
}

['@test deactivate should be called on Engine Routes before destruction'](assert) {
assert.expect(3);

Expand Down
Expand Up @@ -746,50 +746,6 @@ moduleFor(
});
}

['@test it can render a basic component with a block when the yield is in a partial']() {
this.registerPartial('_partialWithYield', 'yielded: [{{yield}}]');

this.registerComponent('foo-bar', {
template: '{{partial "partialWithYield"}} - In component',
});

expectDeprecation(() => {
this.render('{{#foo-bar}}hello{{/foo-bar}}');
}, 'The use of `{{partial}}` is deprecated, please refactor the "partialWithYield" partial to a component');

this.assertComponentElement(this.firstChild, {
content: 'yielded: [hello] - In component',
});

runTask(() => this.rerender());

this.assertComponentElement(this.firstChild, {
content: 'yielded: [hello] - In component',
});
}

['@test it can render a basic component with a block param when the yield is in a partial']() {
this.registerPartial('_partialWithYield', 'yielded: [{{yield "hello"}}]');

this.registerComponent('foo-bar', {
template: '{{partial "partialWithYield"}} - In component',
});

expectDeprecation(() => {
this.render('{{#foo-bar as |value|}}{{value}}{{/foo-bar}}');
}, 'The use of `{{partial}}` is deprecated, please refactor the "partialWithYield" partial to a component');

this.assertComponentElement(this.firstChild, {
content: 'yielded: [hello] - In component',
});

runTask(() => this.rerender());

this.assertComponentElement(this.firstChild, {
content: 'yielded: [hello] - In component',
});
}

['@test it renders the layout with the component instance as the context']() {
let instance;

Expand Down

0 comments on commit 28e5a63

Please sign in to comment.