Skip to content

Commit

Permalink
Merge pull request #19426 from emberjs/expose-glimmer-syntax-from-tem…
Browse files Browse the repository at this point in the history
…plate-compiler

[BUGFIX release] Expose `@glimmer/syntax` from template compiler privately for use in Embroider.
  • Loading branch information
rwjblue authored Feb 25, 2021
2 parents 3aff3c5 + b46eee7 commit 9295b59
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 4 deletions.
8 changes: 8 additions & 0 deletions packages/ember-template-compiler/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ENV } from '@ember/-internals/environment';
import { FEATURES } from '@ember/canary-features';
import * as _GlimmerSyntax from '@glimmer/syntax';
import VERSION from 'ember/version';
import require from 'require';

Expand Down Expand Up @@ -28,12 +29,19 @@ export { default as precompile } from './lib/system/precompile';
export { default as compile } from './lib/system/compile';
export {
default as compileOptions,
buildCompileOptions as _buildCompileOptions,
transformsFor as _transformsFor,
registerPlugin,
unregisterPlugin,
} from './lib/system/compile-options';
export { RESOLUTION_MODE_TRANSFORMS, STRICT_MODE_TRANSFORMS } from './lib/plugins/index';
export { EmberPrecompileOptions } from './lib/types';

export { preprocess as _preprocess, print as _print } from '@glimmer/syntax';
export { precompile as _precompile } from '@glimmer/compiler';

export { _GlimmerSyntax, VERSION };

// used to bootstrap templates
import './lib/system/bootstrap';

Expand Down
21 changes: 17 additions & 4 deletions packages/ember-template-compiler/lib/system/compile-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ function malformedComponentLookup(string: string) {
return string.indexOf('::') === -1 && string.indexOf(':') > -1;
}

export default function compileOptions(
_options: Partial<EmberPrecompileOptions> = {}
): PrecompileOptions {
export function buildCompileOptions(
_options: Partial<EmberPrecompileOptions>
): EmberPrecompileOptions {
let options: EmberPrecompileOptions = assign(
{ meta: {}, isProduction: false, plugins: { ast: [] } },
_options,
Expand All @@ -42,7 +42,20 @@ export default function compileOptions(
meta.moduleName = options.moduleName;
}

let builtInPlugins = options.strictMode ? STRICT_MODE_TRANSFORMS : RESOLUTION_MODE_TRANSFORMS;
return options;
}

export function transformsFor(options: EmberPrecompileOptions): readonly PluginFunc[] {
return EMBER_STRICT_MODE && options.strictMode
? STRICT_MODE_TRANSFORMS
: RESOLUTION_MODE_TRANSFORMS;
}

export default function compileOptions(
_options: Partial<EmberPrecompileOptions> = {}
): PrecompileOptions {
let options = buildCompileOptions(_options);
let builtInPlugins = transformsFor(options);

if (!_options.plugins) {
options.plugins = { ast: [...USER_PLUGINS, ...builtInPlugins] };
Expand Down
92 changes: 92 additions & 0 deletions packages/ember-template-compiler/tests/basic-usage-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import {
_buildCompileOptions,
_preprocess,
_print,
registerPlugin,
unregisterPlugin,
} from '../index';
import { moduleFor, RenderingTestCase } from 'internal-test-helpers';

function reverseElementNodeTag() {
return {
name: 'reverse-element-node-tag',
visitor: {
ElementNode(node) {
node.tag = node.tag.split('').reverse().join('');
},
},
};
}

function removeDataTest() {
return {
name: 'remove-data-test',

visitor: {
ElementNode(node) {
for (let i = 0; i < node.attributes.length; i++) {
let attribute = node.attributes[i];

if (attribute.name === 'data-test') {
node.attributes.splice(i, 1);
}
}
},
},
};
}

moduleFor(
'ember-template-compiler: Embroider-like compilation',
class extends RenderingTestCase {
afterEach() {
expectDeprecation(() => {
unregisterPlugin('ast', removeDataTest);
}, /unregisterPlugin is deprecated, please pass plugins directly via `compile` and\/or `precompile`/);
return super.afterEach();
}

'@test can process a subset of AST plugins and print'(assert) {
let template = '<div data-test="foo" data-blah="derp" class="hahaha">&nbsp;</div>';

// build up options including strictMode default values, customizeComponentName, meta.moduleName, etc
let options = _buildCompileOptions({
mode: 'codemod',
moduleName: 'components/foo',
plugins: { ast: [removeDataTest] },
});

let transformedTemplateAST = _preprocess(template, options);

// print back to a handlebars string
let result = _print(transformedTemplateAST, { entityEncoding: 'raw' });

assert.equal(result, '<div data-blah="derp" class="hahaha">&nbsp;</div>');
}

'@test registerPlugin based transforms can be avoided'(assert) {
expectDeprecation(() => {
registerPlugin('ast', removeDataTest);
}, /registerPlugin is deprecated, please pass plugins directly via `compile` and\/or `precompile`/);

let template = '<div data-test="foo" data-blah="derp" class="hahaha">&nbsp;</div>';

// build up options including strictMode default values, customizeComponentName, meta.moduleName, etc
let options = _buildCompileOptions({
mode: 'codemod',
moduleName: 'components/foo',
plugins: {
ast: [reverseElementNodeTag],
},
});

let transformedTemplateAST = _preprocess(template, options);

// print back to a handlebars string
let result = _print(transformedTemplateAST, { entityEncoding: 'raw' });

// only reverseElementNodeTag has ran, **not** removeDataTest
assert.equal(result, '<vid data-test="foo" data-blah="derp" class="hahaha">&nbsp;</vid>');
}
}
);

0 comments on commit 9295b59

Please sign in to comment.