From a34d3724798807f1e8bfa4aa6cdc47191b1ee831 Mon Sep 17 00:00:00 2001 From: Stanislav Dunajcan Date: Tue, 21 Mar 2023 14:21:14 +0100 Subject: [PATCH 1/3] Added test for scope with renamed import --- __tests__/tests.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/__tests__/tests.js b/__tests__/tests.js index c14f3cfe..2b911255 100644 --- a/__tests__/tests.js +++ b/__tests__/tests.js @@ -920,6 +920,23 @@ describe('htmlbars-inline-precompile', function () { }); }); + it('correctly handles scope function (object with different key value)', function () { + const source = ''; + transform( + `import { precompileTemplate } from '@ember/template-compilation'; + import Foo$1 from 'foo'; + var compiled = precompileTemplate('${source}', { + scope() { return { + Foo: Foo$1, + }; + }});` + ); + expect(optionsReceived).toEqual({ + contents: source, + locals: ['Foo'], + }); + }); + it('errors if scope contains mismatched keys/values', function () { expect(() => { transform( From 3f011719414a98215794c6fcac6b792ded055473 Mon Sep 17 00:00:00 2001 From: Stanislav Dunajcan Date: Thu, 23 Mar 2023 12:00:07 +0100 Subject: [PATCH 2/3] Allowed scope to have different key and value --- index.js | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/index.js b/index.js index cca75317..5ad6c44c 100644 --- a/index.js +++ b/index.js @@ -72,17 +72,18 @@ module.exports = function (babel) { ); } - return objExpression.properties.map((prop) => { + return objExpression.properties.reduce((res, prop) => { let { key, value } = prop; - if (value.type !== 'Identifier' || value.name !== key.name) { + if (value.type !== 'Identifier') { throw buildError( `Scope objects for \`${name}\` may only contain direct references to in-scope values, e.g. { ${key.name} } or { ${key.name}: ${key.name} }` ); } - return key.name; - }); + res[key.name] = value.name; + return res; + }, {}); } function parseObjectExpression(state, buildError, name, node, shouldParseScope = false) { @@ -109,6 +110,10 @@ module.exports = function (babel) { function compileTemplate(precompile, template, templateCompilerIdentifier, _options) { let options = Object.assign({ contents: template }, _options); + if (_options.locals) { + options.locals = Object.keys(_options.locals); + } + let precompileResultString; if (options.insertRuntimeErrors) { @@ -121,10 +126,16 @@ module.exports = function (babel) { precompileResultString = precompile(template, options); } - let precompileResultAST = babel.parse(`var precompileResult = ${precompileResultString};`, { - babelrc: false, - configFile: false, - }); + const keys = Object.keys(_options.locals ?? {}).join(','); + const values = Object.values(_options.locals ?? {}).join(','); + + let precompileResultAST = babel.parse( + `var precompileResult = ((${keys})=>(${precompileResultString}))(${values}); `, + { + babelrc: false, + configFile: false, + } + ); let templateExpression = precompileResultAST.program.body[0].declarations[0].init; @@ -139,17 +150,17 @@ module.exports = function (babel) { } function getScope(scope) { - let names = []; + let properties = {}; while (scope) { for (let binding in scope.bindings) { - names.push(binding); + properties[binding] = binding; } scope = scope.parent; } - return names; + return properties; } function shouldUseAutomaticScope(options) { From eaf868274303fb62db2e927a1fe547cf277a1e10 Mon Sep 17 00:00:00 2001 From: Stanislav Dunajcan Date: Thu, 23 Mar 2023 12:00:29 +0100 Subject: [PATCH 3/3] Removed unnecessary test --- __tests__/tests.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/__tests__/tests.js b/__tests__/tests.js index 2b911255..e68ec6fb 100644 --- a/__tests__/tests.js +++ b/__tests__/tests.js @@ -937,16 +937,6 @@ describe('htmlbars-inline-precompile', function () { }); }); - it('errors if scope contains mismatched keys/values', function () { - expect(() => { - transform( - "import { precompileTemplate } from '@ember/template-compilation';\nvar compiled = precompileTemplate('hello', { scope: { foo: bar } });" - ); - }).toThrow( - /Scope objects for `precompileTemplate` may only contain direct references to in-scope values, e.g. { foo } or { foo: foo }/ - ); - }); - it('errors if scope is not an object', function () { expect(() => { transform(