refactor(ivy): minor refactoring of Host Bindings function generation (#28379)
Prior to this change, generation of host bindings and host styles was guarded by the "if" statement, which always returned true. Enforcing more strict check for bindings length broke some tests, since host styling instructions generation were inside the same "if" block. This update decouples bindings instruction generation from styling instructions, which makes it less error prone. PR Close #28379
This commit is contained in:
parent
66ce3b2f2f
commit
778d5739e2
|
@ -643,6 +643,23 @@ function createHostBindingsFunction(
|
||||||
const hostBindingSourceSpan = meta.typeSourceSpan;
|
const hostBindingSourceSpan = meta.typeSourceSpan;
|
||||||
const directiveSummary = metadataAsSummary(meta);
|
const directiveSummary = metadataAsSummary(meta);
|
||||||
|
|
||||||
|
let valueConverter: ValueConverter;
|
||||||
|
const getValueConverter = () => {
|
||||||
|
if (!valueConverter) {
|
||||||
|
const hostVarsCountFn = (numSlots: number): number => {
|
||||||
|
const originalVarsCount = totalHostVarsCount;
|
||||||
|
totalHostVarsCount += numSlots;
|
||||||
|
return originalVarsCount;
|
||||||
|
};
|
||||||
|
valueConverter = new ValueConverter(
|
||||||
|
constantPool,
|
||||||
|
() => error('Unexpected node'), // new nodes are illegal here
|
||||||
|
hostVarsCountFn,
|
||||||
|
() => error('Unexpected pipe')); // pipes are illegal here
|
||||||
|
}
|
||||||
|
return valueConverter;
|
||||||
|
};
|
||||||
|
|
||||||
// Calculate host event bindings
|
// Calculate host event bindings
|
||||||
const eventBindings =
|
const eventBindings =
|
||||||
bindingParser.createDirectiveHostEventAsts(directiveSummary, hostBindingSourceSpan);
|
bindingParser.createDirectiveHostEventAsts(directiveSummary, hostBindingSourceSpan);
|
||||||
|
@ -653,23 +670,7 @@ function createHostBindingsFunction(
|
||||||
|
|
||||||
// Calculate the host property bindings
|
// Calculate the host property bindings
|
||||||
const bindings = bindingParser.createBoundHostProperties(directiveSummary, hostBindingSourceSpan);
|
const bindings = bindingParser.createBoundHostProperties(directiveSummary, hostBindingSourceSpan);
|
||||||
|
(bindings || []).forEach((binding: ParsedProperty) => {
|
||||||
const bindingFn = (implicit: any, value: AST) => {
|
|
||||||
return convertPropertyBinding(
|
|
||||||
null, implicit, value, 'b', BindingForm.TrySimple, () => error('Unexpected interpolation'));
|
|
||||||
};
|
|
||||||
if (bindings) {
|
|
||||||
const hostVarsCountFn = (numSlots: number): number => {
|
|
||||||
const originalVarsCount = totalHostVarsCount;
|
|
||||||
totalHostVarsCount += numSlots;
|
|
||||||
return originalVarsCount;
|
|
||||||
};
|
|
||||||
const valueConverter = new ValueConverter(
|
|
||||||
constantPool,
|
|
||||||
/* new nodes are illegal here */ () => error('Unexpected node'), hostVarsCountFn,
|
|
||||||
/* pipes are illegal here */ () => error('Unexpected pipe'));
|
|
||||||
|
|
||||||
for (const binding of bindings) {
|
|
||||||
const name = binding.name;
|
const name = binding.name;
|
||||||
const stylePrefix = getStylingPrefix(name);
|
const stylePrefix = getStylingPrefix(name);
|
||||||
if (stylePrefix === 'style') {
|
if (stylePrefix === 'style') {
|
||||||
|
@ -680,14 +681,13 @@ function createHostBindingsFunction(
|
||||||
parseNamedProperty(name).propertyName, binding.expression, binding.sourceSpan);
|
parseNamedProperty(name).propertyName, binding.expression, binding.sourceSpan);
|
||||||
} else {
|
} else {
|
||||||
// resolve literal arrays and literal objects
|
// resolve literal arrays and literal objects
|
||||||
const value = binding.expression.visit(valueConverter);
|
const value = binding.expression.visit(getValueConverter());
|
||||||
const bindingExpr = bindingFn(bindingContext, value);
|
const bindingExpr = bindingFn(bindingContext, value);
|
||||||
|
|
||||||
const {bindingName, instruction, isAttribute} = getBindingNameAndInstruction(binding);
|
const {bindingName, instruction, isAttribute} = getBindingNameAndInstruction(binding);
|
||||||
|
|
||||||
const securityContexts =
|
const securityContexts =
|
||||||
bindingParser
|
bindingParser.calcPossibleSecurityContexts(meta.selector || '', bindingName, isAttribute)
|
||||||
.calcPossibleSecurityContexts(meta.selector || '', bindingName, isAttribute)
|
|
||||||
.filter(context => context !== core.SecurityContext.NONE);
|
.filter(context => context !== core.SecurityContext.NONE);
|
||||||
|
|
||||||
let sanitizerFn: o.ExternalExpr|null = null;
|
let sanitizerFn: o.ExternalExpr|null = null;
|
||||||
|
@ -695,8 +695,8 @@ function createHostBindingsFunction(
|
||||||
if (securityContexts.length === 2 &&
|
if (securityContexts.length === 2 &&
|
||||||
securityContexts.indexOf(core.SecurityContext.URL) > -1 &&
|
securityContexts.indexOf(core.SecurityContext.URL) > -1 &&
|
||||||
securityContexts.indexOf(core.SecurityContext.RESOURCE_URL) > -1) {
|
securityContexts.indexOf(core.SecurityContext.RESOURCE_URL) > -1) {
|
||||||
// Special case for some URL attributes (such as "src" and "href") that may be a part of
|
// Special case for some URL attributes (such as "src" and "href") that may be a part
|
||||||
// different security contexts. In this case we use special santitization function and
|
// of different security contexts. In this case we use special santitization function and
|
||||||
// select the actual sanitizer at runtime based on a tag name that is provided while
|
// select the actual sanitizer at runtime based on a tag name that is provided while
|
||||||
// invoking sanitization function.
|
// invoking sanitization function.
|
||||||
sanitizerFn = o.importExpr(R3.sanitizeUrlOrResourceUrl);
|
sanitizerFn = o.importExpr(R3.sanitizeUrlOrResourceUrl);
|
||||||
|
@ -723,7 +723,7 @@ function createHostBindingsFunction(
|
||||||
updateStatements.push(...bindingExpr.stmts);
|
updateStatements.push(...bindingExpr.stmts);
|
||||||
updateStatements.push(o.importExpr(instruction).callFn(instructionParams).toStmt());
|
updateStatements.push(o.importExpr(instruction).callFn(instructionParams).toStmt());
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
// since we're dealing with directives/components and both have hostBinding
|
// since we're dealing with directives/components and both have hostBinding
|
||||||
// functions, we need to generate a special hostAttrs instruction that deals
|
// functions, we need to generate a special hostAttrs instruction that deals
|
||||||
|
@ -754,11 +754,10 @@ function createHostBindingsFunction(
|
||||||
// finally each binding that was registered in the statement above will need to be added to
|
// finally each binding that was registered in the statement above will need to be added to
|
||||||
// the update block of a component/directive templateFn/hostBindingsFn so that the bindings
|
// the update block of a component/directive templateFn/hostBindingsFn so that the bindings
|
||||||
// are evaluated and updated for the element.
|
// are evaluated and updated for the element.
|
||||||
styleBuilder.buildUpdateLevelInstructions(valueConverter).forEach(instruction => {
|
styleBuilder.buildUpdateLevelInstructions(getValueConverter()).forEach(instruction => {
|
||||||
updateStatements.push(createStylingStmt(instruction, bindingContext, bindingFn));
|
updateStatements.push(createStylingStmt(instruction, bindingContext, bindingFn));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (totalHostVarsCount) {
|
if (totalHostVarsCount) {
|
||||||
createStatements.unshift(
|
createStatements.unshift(
|
||||||
|
@ -785,6 +784,11 @@ function createHostBindingsFunction(
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bindingFn(implicit: any, value: AST) {
|
||||||
|
return convertPropertyBinding(
|
||||||
|
null, implicit, value, 'b', BindingForm.TrySimple, () => error('Unexpected interpolation'));
|
||||||
|
}
|
||||||
|
|
||||||
function createStylingStmt(
|
function createStylingStmt(
|
||||||
instruction: Instruction, bindingContext: any, bindingFn: Function): o.Statement {
|
instruction: Instruction, bindingContext: any, bindingFn: Function): o.Statement {
|
||||||
const params = instruction.buildParams(value => bindingFn(bindingContext, value).currValExpr);
|
const params = instruction.buildParams(value => bindingFn(bindingContext, value).currValExpr);
|
||||||
|
|
Loading…
Reference in New Issue