createElementPropertyAst function
BoundElementPropertyAst
createElementPropertyAst(
- String elementName,
- String name,
- BoundValue value,
- SourceSpan sourceSpan,
- ElementSchemaRegistry schemaRegistry,
Implementation
BoundElementPropertyAst createElementPropertyAst(
String elementName,
String name,
BoundValue value,
SourceSpan sourceSpan,
ElementSchemaRegistry schemaRegistry,
) {
String? unit;
String? namespace;
PropertyBindingType? bindingType;
String? boundPropertyName;
TemplateSecurityContext? securityContext;
var parts = name.split(_propertyPartsSeparator);
if (identical(parts.length, 1)) {
boundPropertyName = schemaRegistry.getMappedPropName(parts[0]);
securityContext =
schemaRegistry.securityContext(elementName, boundPropertyName);
bindingType = PropertyBindingType.property;
if (!schemaRegistry.hasProperty(elementName, boundPropertyName)) {
if (boundPropertyName == 'ngclass') {
CompileContext.current.reportAndRecover(BuildError.forSourceSpan(
sourceSpan,
'Please use camel-case ngClass instead of ngclass in your template',
));
} else {
CompileContext.current.reportAndRecover(BuildError.forSourceSpan(
sourceSpan,
"Can't bind to '$boundPropertyName' since it isn't a known "
'native property or known directive. Please fix typo or add to '
'directives list.',
));
}
}
} else {
if (parts[0] == _attributePrefix) {
boundPropertyName = parts[1];
if (boundPropertyName.toLowerCase().startsWith('on')) {
CompileContext.current.reportAndRecover(BuildError.forSourceSpan(
sourceSpan,
'Binding to event attribute \'$boundPropertyName\' '
'is disallowed for security reasons, please use '
'(${boundPropertyName.substring(2)})=...',
));
}
unit = parts.length > 2 ? parts[2] : null;
if (unit != null && unit != 'if') {
CompileContext.current.reportAndRecover(BuildError.forSourceSpan(
sourceSpan,
'Invalid attribute unit "$unit"',
));
}
// NB: For security purposes, use the mapped property name, not the
// attribute name.
securityContext = schemaRegistry.securityContext(
elementName, schemaRegistry.getMappedPropName(boundPropertyName));
var nsSeparatorIdx = boundPropertyName.indexOf(':');
if (nsSeparatorIdx > -1) {
namespace = boundPropertyName.substring(0, nsSeparatorIdx);
boundPropertyName = boundPropertyName.substring(nsSeparatorIdx + 1);
}
bindingType = PropertyBindingType.attribute;
} else if (parts[0] == _classPrefix) {
boundPropertyName = parts[1];
bindingType = PropertyBindingType.cssClass;
securityContext = TemplateSecurityContext.none;
} else if (parts[0] == _stylePrefix) {
unit = parts.length > 2 ? parts[2] : null;
boundPropertyName = parts[1];
bindingType = PropertyBindingType.style;
securityContext = TemplateSecurityContext.style;
} else {
// Throw an error, otherwise it builds a BoundElementPropertyAst with null
// fields that will result in a crash when trying to transform this Ast
// node to an IR node.
CompileContext.current.reportAndRecover(BuildError.forSourceSpan(
sourceSpan,
"Invalid property name '$name'",
));
bindingType = null;
securityContext = null;
}
}
return BoundElementPropertyAst(
namespace,
boundPropertyName,
bindingType,
securityContext,
value,
unit,
sourceSpan,
);
}