forked from angular/angular
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(upgrade): support multi-slot projection in upgrade/static (angul…
…ar#14282) Closes angular#14261
- Loading branch information
1 parent
ab40fcb
commit 914797a
Showing
19 changed files
with
1,135 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
The following code has been copied from the Angular compiler to be used in the upgrade library without | ||
the need to import the entire compiler: | ||
|
||
* `selector.ts` | ||
* `ml_parser/html_tags.ts` | ||
* `ml_parser/tags.ts` | ||
* `createElementCssSelector.ts` |
55 changes: 55 additions & 0 deletions
55
packages/upgrade/src/common/compiler_helpers/createElementCssSelector.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/** | ||
* @license | ||
* Copyright Google Inc. All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import {CssSelector} from './selector'; | ||
|
||
/* | ||
* The following items are copied from the Angular Compiler to be used here | ||
* without the need to import the entire compiler into the build | ||
*/ | ||
|
||
const CLASS_ATTR = 'class'; | ||
|
||
export function createElementCssSelector( | ||
elementName: string, attributes: [string, string][]): CssSelector { | ||
const cssSelector = new CssSelector(); | ||
const elNameNoNs = splitNsName(elementName)[1]; | ||
|
||
cssSelector.setElement(elNameNoNs); | ||
|
||
for (let i = 0; i < attributes.length; i++) { | ||
const attrName = attributes[i][0]; | ||
const attrNameNoNs = splitNsName(attrName)[1]; | ||
const attrValue = attributes[i][1]; | ||
|
||
cssSelector.addAttribute(attrNameNoNs, attrValue); | ||
if (attrName.toLowerCase() == CLASS_ATTR) { | ||
const classes = splitClasses(attrValue); | ||
classes.forEach(className => cssSelector.addClassName(className)); | ||
} | ||
} | ||
return cssSelector; | ||
} | ||
|
||
export function splitNsName(elementName: string): [string, string] { | ||
if (elementName[0] != ':') { | ||
return [null, elementName]; | ||
} | ||
|
||
const colonIndex = elementName.indexOf(':', 1); | ||
|
||
if (colonIndex == -1) { | ||
throw new Error(`Unsupported format "${elementName}" expecting ":namespace:name"`); | ||
} | ||
|
||
return [elementName.slice(1, colonIndex), elementName.slice(colonIndex + 1)]; | ||
} | ||
|
||
export function splitClasses(classAttrValue: string): string[] { | ||
return classAttrValue.trim().split(/\s+/g); | ||
} |
129 changes: 129 additions & 0 deletions
129
packages/upgrade/src/common/compiler_helpers/ml_parser/html_tags.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
/** | ||
* @license | ||
* Copyright Google Inc. All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import {TagContentType, TagDefinition} from './tags'; | ||
|
||
export class HtmlTagDefinition implements TagDefinition { | ||
private closedByChildren: {[key: string]: boolean} = {}; | ||
|
||
closedByParent: boolean = false; | ||
requiredParents: {[key: string]: boolean}; | ||
parentToAdd: string; | ||
implicitNamespacePrefix: string; | ||
contentType: TagContentType; | ||
isVoid: boolean; | ||
ignoreFirstLf: boolean; | ||
canSelfClose: boolean = false; | ||
|
||
constructor( | ||
{closedByChildren, requiredParents, implicitNamespacePrefix, | ||
contentType = TagContentType.PARSABLE_DATA, closedByParent = false, isVoid = false, | ||
ignoreFirstLf = false}: { | ||
closedByChildren?: string[], | ||
closedByParent?: boolean, | ||
requiredParents?: string[], | ||
implicitNamespacePrefix?: string, | ||
contentType?: TagContentType, | ||
isVoid?: boolean, | ||
ignoreFirstLf?: boolean | ||
} = {}) { | ||
if (closedByChildren && closedByChildren.length > 0) { | ||
closedByChildren.forEach(tagName => this.closedByChildren[tagName] = true); | ||
} | ||
this.isVoid = isVoid; | ||
this.closedByParent = closedByParent || isVoid; | ||
if (requiredParents && requiredParents.length > 0) { | ||
this.requiredParents = {}; | ||
// The first parent is the list is automatically when none of the listed parents are present | ||
this.parentToAdd = requiredParents[0]; | ||
requiredParents.forEach(tagName => this.requiredParents[tagName] = true); | ||
} | ||
this.implicitNamespacePrefix = implicitNamespacePrefix; | ||
this.contentType = contentType; | ||
this.ignoreFirstLf = ignoreFirstLf; | ||
} | ||
|
||
requireExtraParent(currentParent: string): boolean { | ||
if (!this.requiredParents) { | ||
return false; | ||
} | ||
|
||
if (!currentParent) { | ||
return true; | ||
} | ||
|
||
const lcParent = currentParent.toLowerCase(); | ||
const isParentTemplate = lcParent === 'template' || currentParent === 'ng-template'; | ||
return !isParentTemplate && this.requiredParents[lcParent] != true; | ||
} | ||
|
||
isClosedByChild(name: string): boolean { | ||
return this.isVoid || name.toLowerCase() in this.closedByChildren; | ||
} | ||
} | ||
|
||
// see http://www.w3.org/TR/html51/syntax.html#optional-tags | ||
// This implementation does not fully conform to the HTML5 spec. | ||
const TAG_DEFINITIONS: {[key: string]: HtmlTagDefinition} = { | ||
'base': new HtmlTagDefinition({isVoid: true}), | ||
'meta': new HtmlTagDefinition({isVoid: true}), | ||
'area': new HtmlTagDefinition({isVoid: true}), | ||
'embed': new HtmlTagDefinition({isVoid: true}), | ||
'link': new HtmlTagDefinition({isVoid: true}), | ||
'img': new HtmlTagDefinition({isVoid: true}), | ||
'input': new HtmlTagDefinition({isVoid: true}), | ||
'param': new HtmlTagDefinition({isVoid: true}), | ||
'hr': new HtmlTagDefinition({isVoid: true}), | ||
'br': new HtmlTagDefinition({isVoid: true}), | ||
'source': new HtmlTagDefinition({isVoid: true}), | ||
'track': new HtmlTagDefinition({isVoid: true}), | ||
'wbr': new HtmlTagDefinition({isVoid: true}), | ||
'p': new HtmlTagDefinition({ | ||
closedByChildren: [ | ||
'address', 'article', 'aside', 'blockquote', 'div', 'dl', 'fieldset', 'footer', 'form', | ||
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', | ||
'main', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul' | ||
], | ||
closedByParent: true | ||
}), | ||
'thead': new HtmlTagDefinition({closedByChildren: ['tbody', 'tfoot']}), | ||
'tbody': new HtmlTagDefinition({closedByChildren: ['tbody', 'tfoot'], closedByParent: true}), | ||
'tfoot': new HtmlTagDefinition({closedByChildren: ['tbody'], closedByParent: true}), | ||
'tr': new HtmlTagDefinition({ | ||
closedByChildren: ['tr'], | ||
requiredParents: ['tbody', 'tfoot', 'thead'], | ||
closedByParent: true | ||
}), | ||
'td': new HtmlTagDefinition({closedByChildren: ['td', 'th'], closedByParent: true}), | ||
'th': new HtmlTagDefinition({closedByChildren: ['td', 'th'], closedByParent: true}), | ||
'col': new HtmlTagDefinition({requiredParents: ['colgroup'], isVoid: true}), | ||
'svg': new HtmlTagDefinition({implicitNamespacePrefix: 'svg'}), | ||
'math': new HtmlTagDefinition({implicitNamespacePrefix: 'math'}), | ||
'li': new HtmlTagDefinition({closedByChildren: ['li'], closedByParent: true}), | ||
'dt': new HtmlTagDefinition({closedByChildren: ['dt', 'dd']}), | ||
'dd': new HtmlTagDefinition({closedByChildren: ['dt', 'dd'], closedByParent: true}), | ||
'rb': new HtmlTagDefinition({closedByChildren: ['rb', 'rt', 'rtc', 'rp'], closedByParent: true}), | ||
'rt': new HtmlTagDefinition({closedByChildren: ['rb', 'rt', 'rtc', 'rp'], closedByParent: true}), | ||
'rtc': new HtmlTagDefinition({closedByChildren: ['rb', 'rtc', 'rp'], closedByParent: true}), | ||
'rp': new HtmlTagDefinition({closedByChildren: ['rb', 'rt', 'rtc', 'rp'], closedByParent: true}), | ||
'optgroup': new HtmlTagDefinition({closedByChildren: ['optgroup'], closedByParent: true}), | ||
'option': new HtmlTagDefinition({closedByChildren: ['option', 'optgroup'], closedByParent: true}), | ||
'pre': new HtmlTagDefinition({ignoreFirstLf: true}), | ||
'listing': new HtmlTagDefinition({ignoreFirstLf: true}), | ||
'style': new HtmlTagDefinition({contentType: TagContentType.RAW_TEXT}), | ||
'script': new HtmlTagDefinition({contentType: TagContentType.RAW_TEXT}), | ||
'title': new HtmlTagDefinition({contentType: TagContentType.ESCAPABLE_RAW_TEXT}), | ||
'textarea': | ||
new HtmlTagDefinition({contentType: TagContentType.ESCAPABLE_RAW_TEXT, ignoreFirstLf: true}), | ||
}; | ||
|
||
const _DEFAULT_TAG_DEFINITION = new HtmlTagDefinition(); | ||
|
||
export function getHtmlTagDefinition(tagName: string): HtmlTagDefinition { | ||
return TAG_DEFINITIONS[tagName.toLowerCase()] || _DEFAULT_TAG_DEFINITION; | ||
} |
Oops, something went wrong.