-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(schematics): properly add font stylesheets (#12636)
* refactor(schematics): properly add font stylesheets * No longer just inserts the Material fonts (icon font and Roboto) at the beginning of the `<head>` element. The link elements should be appended and properly indented. * Moves utils that are specific to the `install` / `ng-add` schematic into the given schematic folder instead of having them in the global schematic utility folder. * Fixes that multiple runs of `ng add @angular/material` result in duplicate styles in the project `styles.ext` file. * Improved head element find logic (BFS)
- Loading branch information
1 parent
4d430bd
commit 9169c05
Showing
12 changed files
with
227 additions
and
157 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC 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 {SchematicsException, Tree} from '@angular-devkit/schematics'; | ||
import {WorkspaceProject} from '@schematics/angular/utility/config'; | ||
import {DefaultTreeDocument, DefaultTreeElement, parse as parseHtml} from 'parse5'; | ||
import {getChildElementIndentation} from '../../utils/parse5-element'; | ||
import {getIndexHtmlPath} from './project-index-html'; | ||
|
||
/** Appends the given element HTML fragment to the index.html head tag. */ | ||
export function appendElementToHead(host: Tree, project: WorkspaceProject, elementHtml: string) { | ||
const indexPath = getIndexHtmlPath(project); | ||
const indexHtmlBuffer = host.read(indexPath); | ||
|
||
if (!indexHtmlBuffer) { | ||
throw new SchematicsException(`Could not find file for path: ${indexPath}`); | ||
} | ||
|
||
const htmlContent = indexHtmlBuffer.toString(); | ||
|
||
if (htmlContent.includes(elementHtml)) { | ||
return; | ||
} | ||
|
||
const headTag = getHeadTagElement(htmlContent); | ||
|
||
if (!headTag) { | ||
throw `Could not find '<head>' element in HTML file: ${indexPath}`; | ||
} | ||
|
||
const endTagOffset = headTag.sourceCodeLocation.endTag.startOffset; | ||
const indentationOffset = getChildElementIndentation(headTag); | ||
const insertion = `${' '.repeat(indentationOffset)}${elementHtml}`; | ||
|
||
const recordedChange = host | ||
.beginUpdate(indexPath) | ||
.insertRight(endTagOffset, `${insertion}\n`); | ||
|
||
host.commitUpdate(recordedChange); | ||
} | ||
|
||
/** Parses the given HTML file and returns the head element if available. */ | ||
export function getHeadTagElement(src: string): DefaultTreeElement | null { | ||
const document = parseHtml(src, {sourceCodeLocationInfo: true}) as DefaultTreeDocument; | ||
const nodeQueue = [...document.childNodes]; | ||
|
||
while (nodeQueue.length) { | ||
const node = nodeQueue.shift() as DefaultTreeElement; | ||
|
||
if (node.nodeName.toLowerCase() === 'head') { | ||
return node; | ||
} else if (node.childNodes) { | ||
nodeQueue.push(...node.childNodes); | ||
} | ||
} | ||
|
||
return null; | ||
} |
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,30 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC 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 {Tree} from '@angular-devkit/schematics'; | ||
import {getWorkspace} from '@schematics/angular/utility/config'; | ||
import {getProjectFromWorkspace} from '../../utils/get-project'; | ||
import {Schema} from '../schema'; | ||
import {appendElementToHead} from './head-element'; | ||
|
||
/** Adds the Material Design fonts to the index HTML file. */ | ||
export function addFontsToIndex(options: Schema): (host: Tree) => Tree { | ||
return (host: Tree) => { | ||
const workspace = getWorkspace(host); | ||
const project = getProjectFromWorkspace(workspace, options.project); | ||
|
||
const fonts = [ | ||
'https://fonts.googleapis.com/css?family=Roboto:300,400,500', | ||
'https://fonts.googleapis.com/icon?family=Material+Icons', | ||
]; | ||
|
||
fonts.forEach(f => appendElementToHead(host, project, `<link href="${f}" rel="stylesheet">`)); | ||
|
||
return host; | ||
}; | ||
} |
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,21 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC 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 {SchematicsException} from '@angular-devkit/schematics'; | ||
import {WorkspaceProject} from '@schematics/angular/utility/config'; | ||
|
||
/** Looks for the index HTML file in the given project and returns its path. */ | ||
export function getIndexHtmlPath(project: WorkspaceProject): string { | ||
const buildTarget = project.architect.build.options; | ||
|
||
if (buildTarget.index && buildTarget.index.endsWith('index.html')) { | ||
return buildTarget.index; | ||
} | ||
|
||
throw new SchematicsException('No index.html file was found.'); | ||
} |
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
File renamed without changes.
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
Oops, something went wrong.