Skip to content

refactor(schematics): do not depend on parse5 twice #13594

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,28 @@
* found in the LICENSE file at https://angular.io/license
*/

import {WorkspaceProject} from '@angular-devkit/core/src/workspace';
import {SchematicsException, Tree} from '@angular-devkit/schematics';
import {getChildElementIndentation} from '@angular/cdk/schematics';
import {getChildElementIndentation} from './parse5-element';
import {DefaultTreeDocument, DefaultTreeElement, parse as parseHtml} from 'parse5';
import {getIndexHtmlPath} from './project-index-html';

/** Appends the given element HTML fragment to the `<head>` element of the specified HTML file. */
export function appendHtmlElementToHead(host: Tree, htmlFilePath: string, elementHtml: string) {
const htmlFileBuffer = host.read(htmlFilePath);

/** 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}`);
if (!htmlFileBuffer) {
throw new SchematicsException(`Could not read file for path: ${htmlFilePath}`);
}

const htmlContent = indexHtmlBuffer.toString();
const htmlContent = htmlFileBuffer.toString();

if (htmlContent.includes(elementHtml)) {
return;
}

const headTag = getHeadTagElement(htmlContent);
const headTag = getHtmlHeadTagElement(htmlContent);

if (!headTag) {
throw `Could not find '<head>' element in HTML file: ${indexPath}`;
throw `Could not find '<head>' element in HTML file: ${htmlFileBuffer}`;
}

// We always have access to the source code location here because the `getHeadTagElement`
Expand All @@ -41,15 +37,15 @@ export function appendElementToHead(host: Tree, project: WorkspaceProject, eleme
const insertion = `${' '.repeat(indentationOffset)}${elementHtml}`;

const recordedChange = host
.beginUpdate(indexPath)
.beginUpdate(htmlFilePath)
.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;
export function getHtmlHeadTagElement(htmlContent: string): DefaultTreeElement | null {
const document = parseHtml(htmlContent, {sourceCodeLocationInfo: true}) as DefaultTreeDocument;
const nodeQueue = [...document.childNodes];

while (nodeQueue.length) {
Expand Down
1 change: 1 addition & 0 deletions src/cdk/schematics/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from './ast';
export * from './ast/ng-module-imports';
export * from './build-component';
export * from './get-project';
export * from './html-head-element';
export * from './parse5-element';
export * from './project-main-file';
export * from './project-style-file';
Expand Down
3 changes: 0 additions & 3 deletions src/lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@
"dependencies": {
"tslib": "^1.7.1"
},
"optionalDependencies": {
"parse5": "^5.0.0"
},
"schematics": "./schematics/collection.json",
"ng-update": {
"migrations": "./schematics/migration.json",
Expand Down
1 change: 0 additions & 1 deletion src/lib/schematics/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ ts_library(
# TODO(devversion): Only include jasmine for test sources (See: tsconfig types).
"@npm//@types/jasmine",
"@npm//@types/node",
"@npm//parse5",
"@npm//tslint",
"@npm//typescript",
],
Expand Down
9 changes: 6 additions & 3 deletions src/lib/schematics/ng-add/fonts/material-fonts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,26 @@
*/

import {Tree} from '@angular-devkit/schematics';
import {getProjectFromWorkspace} from '@angular/cdk/schematics';
import {appendHtmlElementToHead, getProjectFromWorkspace} from '@angular/cdk/schematics';
import {getWorkspace} from '@schematics/angular/utility/config';
import {Schema} from '../schema';
import {appendElementToHead} from './head-element';
import {getIndexHtmlPath} from './project-index-html';

/** 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 projectIndexHtmlPath = getIndexHtmlPath(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">`));
fonts.forEach(f => {
appendHtmlElementToHead(host, projectIndexHtmlPath, `<link href="${f}" rel="stylesheet">`);
});

return host;
};
Expand Down
8 changes: 1 addition & 7 deletions src/lib/schematics/ng-add/setup-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {chain, noop, Rule, SchematicsException, Tree} from '@angular-devkit/schematics';
import {chain, noop, Rule, Tree} from '@angular-devkit/schematics';
import {
addModuleImportToRootModule,
getProjectFromWorkspace,
Expand All @@ -17,7 +17,6 @@ import {
import {red, bold} from 'chalk';
import {getWorkspace} from '@schematics/angular/utility/config';
import {getAppModulePath} from '@schematics/angular/utility/ng-ast-utils';
import * as parse5 from 'parse5';
import {addFontsToIndex} from './fonts/material-fonts';
import {addHammerJsToMain} from './gestures/hammerjs-import';
import {Schema} from './schema';
Expand All @@ -36,11 +35,6 @@ const noopAnimationsModuleName = 'NoopAnimationsModule';
* - Adds Browser Animation to app.module
*/
export default function(options: Schema): Rule {
if (!parse5) {
throw new SchematicsException('Parse5 is required but could not be found! Please install ' +
'"parse5" manually in order to continue.');
}

return chain([
options && options.gestures ? addHammerJsToMain(options) : noop(),
addAnimationsModule(options),
Expand Down