refactor(compiler): element.sourceSpan
should span the outerHTML
(#38581)
Previously, the `sourceSpan` and `startSourceSpan` were the same object, which meant that you had the following situation: ``` element = <div>some content</div> sourceSpan = <div> startSourceSpan = <div> endSourceSpan = </div> ``` This made `sourceSpan` redundant and meant that if you wanted a span for the whole element including its content and closing tag, it had to be computed. Now `sourceSpan` is separated from `startSourceSpan` resulting in: ``` element = <div>some content</div> sourceSpan = <div>some content</div> startSourceSpan = <div> endSourceSpan = </div> ``` PR Close #38581
This commit is contained in:

committed by
Andrew Scott

parent
a68f1a78a7
commit
1d8c5d88cd
@ -83,7 +83,7 @@ class _I18nVisitor implements html.Visitor {
|
||||
const isVoid: boolean = getHtmlTagDefinition(el.name).isVoid;
|
||||
const startPhName =
|
||||
context.placeholderRegistry.getStartTagPlaceholderName(el.name, attrs, isVoid);
|
||||
context.placeholderToContent[startPhName] = el.sourceSpan.toString();
|
||||
context.placeholderToContent[startPhName] = el.startSourceSpan.toString();
|
||||
|
||||
let closePhName = '';
|
||||
|
||||
|
@ -258,7 +258,9 @@ class _TreeBuilder {
|
||||
}
|
||||
const end = this._peek.sourceSpan.start;
|
||||
const span = new ParseSourceSpan(startTagToken.sourceSpan.start, end);
|
||||
const el = new html.Element(fullName, attrs, [], span, span, undefined);
|
||||
// Create a separate `startSpan` because `span` will be modified when there is an `end` span.
|
||||
const startSpan = new ParseSourceSpan(startTagToken.sourceSpan.start, end);
|
||||
const el = new html.Element(fullName, attrs, [], span, startSpan, undefined);
|
||||
this._pushElement(el);
|
||||
if (selfClosing) {
|
||||
// Elements that are self-closed have their `endSourceSpan` set to the full span, as the
|
||||
@ -301,6 +303,7 @@ class _TreeBuilder {
|
||||
// removed from the element stack at this point are closed implicitly, so they won't get
|
||||
// an end source span (as there is no explicit closing element).
|
||||
el.endSourceSpan = endSourceSpan;
|
||||
el.sourceSpan.end = endSourceSpan.end || el.sourceSpan.end;
|
||||
|
||||
this._elementStack.splice(stackIndex, this._elementStack.length - stackIndex);
|
||||
return true;
|
||||
|
@ -544,7 +544,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
||||
|
||||
private addNamespaceInstruction(nsInstruction: o.ExternalReference, element: t.Element) {
|
||||
this._namespace = nsInstruction;
|
||||
this.creationInstruction(element.sourceSpan, nsInstruction);
|
||||
this.creationInstruction(element.startSourceSpan, nsInstruction);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -671,15 +671,16 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
||||
trimTrailingNulls(parameters));
|
||||
} else {
|
||||
this.creationInstruction(
|
||||
element.sourceSpan, isNgContainer ? R3.elementContainerStart : R3.elementStart,
|
||||
element.startSourceSpan, isNgContainer ? R3.elementContainerStart : R3.elementStart,
|
||||
trimTrailingNulls(parameters));
|
||||
|
||||
if (isNonBindableMode) {
|
||||
this.creationInstruction(element.sourceSpan, R3.disableBindings);
|
||||
this.creationInstruction(element.startSourceSpan, R3.disableBindings);
|
||||
}
|
||||
|
||||
if (i18nAttrs.length > 0) {
|
||||
this.i18nAttributesInstruction(elementIndex, i18nAttrs, element.sourceSpan);
|
||||
this.i18nAttributesInstruction(
|
||||
elementIndex, i18nAttrs, element.startSourceSpan ?? element.sourceSpan);
|
||||
}
|
||||
|
||||
// Generate Listeners (outputs)
|
||||
@ -695,7 +696,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
||||
// Note: it's important to keep i18n/i18nStart instructions after i18nAttributes and
|
||||
// listeners, to make sure i18nAttributes instruction targets current element at runtime.
|
||||
if (isI18nRootElement) {
|
||||
this.i18nStart(element.sourceSpan, element.i18n!, createSelfClosingI18nInstruction);
|
||||
this.i18nStart(element.startSourceSpan, element.i18n!, createSelfClosingI18nInstruction);
|
||||
}
|
||||
}
|
||||
|
||||
@ -827,7 +828,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
||||
|
||||
if (!createSelfClosingInstruction) {
|
||||
// Finish element construction mode.
|
||||
const span = element.endSourceSpan || element.sourceSpan;
|
||||
const span = element.endSourceSpan ?? element.sourceSpan;
|
||||
if (isI18nRootElement) {
|
||||
this.i18nEnd(span, createSelfClosingI18nInstruction);
|
||||
}
|
||||
@ -919,7 +920,8 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
||||
// elements, in case of inline templates, corresponding instructions will be generated in the
|
||||
// nested template function.
|
||||
if (i18nAttrs.length > 0) {
|
||||
this.i18nAttributesInstruction(templateIndex, i18nAttrs, template.sourceSpan);
|
||||
this.i18nAttributesInstruction(
|
||||
templateIndex, i18nAttrs, template.startSourceSpan ?? template.sourceSpan);
|
||||
}
|
||||
|
||||
// Add the input bindings
|
||||
|
Reference in New Issue
Block a user