mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
# Backport This will backport the following commits from `main` to `8.7`: - [[@kbn/handlebars] Minor refactor (#150440)](https://github.com/elastic/kibana/pull/150440) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Thomas Watson","email":"watson@elastic.co"},"sourceCommit":{"committedDate":"2023-02-09T11:21:32Z","message":"[@kbn/handlebars] Minor refactor (#150440)","sha":"5f0b56d3bc470eba4753dfa806154814609deee0","branchLabelMapping":{"^v8.8.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","backport:prev-minor","v8.8.0"],"number":150440,"url":"https://github.com/elastic/kibana/pull/150440","mergeCommit":{"message":"[@kbn/handlebars] Minor refactor (#150440)","sha":"5f0b56d3bc470eba4753dfa806154814609deee0"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v8.8.0","labelRegex":"^v8.8.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/150440","number":150440,"mergeCommit":{"message":"[@kbn/handlebars] Minor refactor (#150440)","sha":"5f0b56d3bc470eba4753dfa806154814609deee0"}}]}] BACKPORT--> Co-authored-by: Thomas Watson <watson@elastic.co>
This commit is contained in:
parent
ab9bbccf42
commit
7aba553780
4 changed files with 39 additions and 60 deletions
|
@ -506,12 +506,13 @@ describe('blocks', () => {
|
|||
it('should call multiple decorators in the same program body in the expected order and get the expected output', () => {
|
||||
let decoratorCall = 0;
|
||||
let progCall = 0;
|
||||
expectTemplate('{{*decorator}}con{{*decorator}}tent')
|
||||
.beforeRender(() => {
|
||||
expectTemplate('{{*decorator}}con{{*decorator}}tent', {
|
||||
beforeRender() {
|
||||
// ensure the counters are reset between EVAL/AST render calls
|
||||
decoratorCall = 0;
|
||||
progCall = 0;
|
||||
})
|
||||
},
|
||||
})
|
||||
.withInput({
|
||||
decoratorCall: 0,
|
||||
progCall: 0,
|
||||
|
|
|
@ -24,6 +24,7 @@ global.kbnHandlebarsEnv = null;
|
|||
|
||||
interface TestOptions {
|
||||
beforeEach?: Function;
|
||||
beforeRender?: Function;
|
||||
}
|
||||
|
||||
export function expectTemplate(template: string, options?: TestOptions) {
|
||||
|
@ -39,7 +40,6 @@ export function forEachCompileFunctionName(
|
|||
class HandlebarsTestBench {
|
||||
private template: string;
|
||||
private options: TestOptions;
|
||||
private beforeRenderFn: Function = () => {};
|
||||
private compileOptions?: ExtendedCompileOptions;
|
||||
private runtimeOptions?: ExtendedRuntimeOptions;
|
||||
private helpers: { [name: string]: Handlebars.HelperDelegate | undefined } = {};
|
||||
|
@ -52,11 +52,6 @@ class HandlebarsTestBench {
|
|||
this.options = options;
|
||||
}
|
||||
|
||||
beforeRender(fn: Function) {
|
||||
this.beforeRenderFn = fn;
|
||||
return this;
|
||||
}
|
||||
|
||||
withCompileOptions(compileOptions?: ExtendedCompileOptions) {
|
||||
this.compileOptions = compileOptions;
|
||||
return this;
|
||||
|
@ -159,16 +154,14 @@ class HandlebarsTestBench {
|
|||
private compileAndExecuteEval() {
|
||||
const renderEval = this.compileEval();
|
||||
|
||||
const runtimeOptions: ExtendedRuntimeOptions = Object.assign(
|
||||
{
|
||||
helpers: this.helpers,
|
||||
partials: this.partials,
|
||||
decorators: this.decorators,
|
||||
},
|
||||
this.runtimeOptions
|
||||
);
|
||||
const runtimeOptions: ExtendedRuntimeOptions = {
|
||||
helpers: this.helpers as Record<string, Function>,
|
||||
partials: this.partials as Record<string, HandlebarsTemplateDelegate>,
|
||||
decorators: this.decorators,
|
||||
...this.runtimeOptions,
|
||||
};
|
||||
|
||||
this.beforeRenderFn();
|
||||
this.execBeforeRender();
|
||||
|
||||
return renderEval(this.input, runtimeOptions);
|
||||
}
|
||||
|
@ -176,16 +169,14 @@ class HandlebarsTestBench {
|
|||
private compileAndExecuteAST() {
|
||||
const renderAST = this.compileAST();
|
||||
|
||||
const runtimeOptions: ExtendedRuntimeOptions = Object.assign(
|
||||
{
|
||||
helpers: this.helpers,
|
||||
partials: this.partials,
|
||||
decorators: this.decorators,
|
||||
},
|
||||
this.runtimeOptions
|
||||
);
|
||||
const runtimeOptions: ExtendedRuntimeOptions = {
|
||||
helpers: this.helpers as Record<string, Function>,
|
||||
partials: this.partials as Record<string, HandlebarsTemplateDelegate>,
|
||||
decorators: this.decorators,
|
||||
...this.runtimeOptions,
|
||||
};
|
||||
|
||||
this.beforeRenderFn();
|
||||
this.execBeforeRender();
|
||||
|
||||
return renderAST(this.input, runtimeOptions);
|
||||
}
|
||||
|
@ -200,6 +191,10 @@ class HandlebarsTestBench {
|
|||
return handlebarsEnv.compileAST(this.template, this.compileOptions);
|
||||
}
|
||||
|
||||
private execBeforeRender() {
|
||||
this.options.beforeRender?.();
|
||||
}
|
||||
|
||||
private execBeforeEach() {
|
||||
if (this.options.beforeEach) {
|
||||
this.options.beforeEach();
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// https://www.typescriptlang.org/docs/handbook/modules.html#export--and-import--require
|
||||
import Handlebars from 'handlebars';
|
||||
|
||||
import type { DecoratorsHash, ExtendedCompileOptions, ExtendedRuntimeOptions } from './types';
|
||||
import type { ExtendedCompileOptions, ExtendedRuntimeOptions } from './types';
|
||||
import { ElasticHandlebarsVisitor } from './visitor';
|
||||
|
||||
const originalCreate = Handlebars.create;
|
||||
|
@ -46,11 +46,8 @@ Handlebars.compileAST = function (
|
|||
}
|
||||
|
||||
// If `Handlebars.compileAST` is reassigned, `this` will be undefined.
|
||||
const helpers = (this ?? Handlebars).helpers;
|
||||
const partials = (this ?? Handlebars).partials;
|
||||
const decorators = (this ?? Handlebars).decorators as DecoratorsHash;
|
||||
const visitor = new ElasticHandlebarsVisitor(this ?? Handlebars, input, options);
|
||||
|
||||
const visitor = new ElasticHandlebarsVisitor(this, input, options, helpers, partials, decorators);
|
||||
return (context: any, runtimeOptions?: ExtendedRuntimeOptions) =>
|
||||
visitor.render(context, runtimeOptions);
|
||||
};
|
||||
|
|
|
@ -27,7 +27,6 @@ import type {
|
|||
HelpersHash,
|
||||
NodeType,
|
||||
NonBlockHelperOptions,
|
||||
PartialsHash,
|
||||
ProcessableBlockStatementNode,
|
||||
ProcessableNode,
|
||||
ProcessableNodeWithPathParts,
|
||||
|
@ -51,9 +50,6 @@ export class ElasticHandlebarsVisitor extends Handlebars.Visitor {
|
|||
private template?: string;
|
||||
private compileOptions: ExtendedCompileOptions;
|
||||
private runtimeOptions?: ExtendedRuntimeOptions;
|
||||
private initialHelpers: HelpersHash;
|
||||
private initialPartials: PartialsHash;
|
||||
private initialDecorators: DecoratorsHash;
|
||||
private blockParamNames: any[][] = [];
|
||||
private blockParamValues: any[][] = [];
|
||||
private ast?: hbs.AST.Program;
|
||||
|
@ -65,10 +61,7 @@ export class ElasticHandlebarsVisitor extends Handlebars.Visitor {
|
|||
constructor(
|
||||
env: typeof Handlebars,
|
||||
input: string | hbs.AST.Program,
|
||||
options: ExtendedCompileOptions = {},
|
||||
helpers: HelpersHash,
|
||||
partials: PartialsHash,
|
||||
decorators: DecoratorsHash
|
||||
options: ExtendedCompileOptions = {}
|
||||
) {
|
||||
super();
|
||||
|
||||
|
@ -80,13 +73,7 @@ export class ElasticHandlebarsVisitor extends Handlebars.Visitor {
|
|||
this.template = input as string;
|
||||
}
|
||||
|
||||
this.compileOptions = Object.assign(
|
||||
{
|
||||
data: true,
|
||||
},
|
||||
options
|
||||
);
|
||||
|
||||
this.compileOptions = { data: true, ...options };
|
||||
this.compileOptions.knownHelpers = Object.assign(
|
||||
Object.create(null),
|
||||
{
|
||||
|
@ -102,10 +89,6 @@ export class ElasticHandlebarsVisitor extends Handlebars.Visitor {
|
|||
this.compileOptions.knownHelpers
|
||||
);
|
||||
|
||||
this.initialHelpers = Object.assign({}, helpers);
|
||||
this.initialPartials = Object.assign({}, partials);
|
||||
this.initialDecorators = Object.assign({}, decorators);
|
||||
|
||||
const protoAccessControl = createProtoAccessControl({});
|
||||
|
||||
const container: Container = (this.container = {
|
||||
|
@ -156,13 +139,16 @@ export class ElasticHandlebarsVisitor extends Handlebars.Visitor {
|
|||
render(context: any, options: ExtendedRuntimeOptions = {}): string {
|
||||
this.contexts = [context];
|
||||
this.output = [];
|
||||
this.runtimeOptions = Object.assign({}, options);
|
||||
this.container.helpers = Object.assign(this.initialHelpers, options.helpers);
|
||||
this.container.partials = Object.assign(this.initialPartials, options.partials);
|
||||
this.container.decorators = Object.assign(
|
||||
this.initialDecorators,
|
||||
options.decorators as DecoratorsHash
|
||||
);
|
||||
this.runtimeOptions = { ...options };
|
||||
this.container.helpers = {
|
||||
...this.env.helpers,
|
||||
...(options.helpers as HelpersHash),
|
||||
};
|
||||
this.container.partials = { ...this.env.partials, ...options.partials };
|
||||
this.container.decorators = {
|
||||
...(this.env.decorators as DecoratorsHash),
|
||||
...(options.decorators as DecoratorsHash),
|
||||
};
|
||||
this.container.hooks = {};
|
||||
this.processedRootDecorators = false;
|
||||
this.processedDecoratorsForProgram.clear();
|
||||
|
@ -540,7 +526,7 @@ export class ElasticHandlebarsVisitor extends Handlebars.Visitor {
|
|||
};
|
||||
|
||||
if (fn.partials) {
|
||||
options.partials = Object.assign({}, options.partials, fn.partials);
|
||||
options.partials = { ...options.partials, ...fn.partials };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -694,7 +680,7 @@ export class ElasticHandlebarsVisitor extends Handlebars.Visitor {
|
|||
nextContext: any,
|
||||
runtimeOptions: ExtendedRuntimeOptions = {}
|
||||
) => {
|
||||
runtimeOptions = Object.assign({}, runtimeOptions);
|
||||
runtimeOptions = { ...runtimeOptions };
|
||||
|
||||
// inherit data in blockParams from parent program
|
||||
runtimeOptions.data = runtimeOptions.data || this.runtimeOptions!.data;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue