UNPKG

ng-alain

Version:

Schematics specific to NG-ALAIN

152 lines (128 loc) 4.41 kB
import { ProjectDefinition } from '@angular-devkit/core/src/workspace'; import { SchematicsException, Tree } from '@angular-devkit/schematics'; import { InsertChange } from '@schematics/angular/utility/change'; import * as parse5 from 'parse5'; import { BUILD_TARGET_BUILD, getProjectTarget } from './workspace'; /** Gets the app index.html file */ export function getIndexHtmlPath(host: Tree, project: ProjectDefinition): string { const targetOptions = getProjectTarget(project, BUILD_TARGET_BUILD); if (typeof targetOptions.index === 'string' && targetOptions.index.endsWith('index.html')) { return targetOptions.index; } const htmlPath = `${project.sourceRoot}/index.html`; if (host.exists(htmlPath)) { return htmlPath; } throw new SchematicsException('No index.html file was found.'); } /** * Parses the index.html file to get the HEAD tag position. */ export function getTag(tree: Tree, src: string, tagName: string): { startOffset: any; endOffset: any } { if ((parse5 as any).treeAdapters) { return getTagInV4(tree, src, tagName); } const document = parse5.parse(src, { sourceCodeLocationInfo: true } as any) as any; let resNode: any; const visit = (nodes: any[]): void => { nodes.forEach(node => { const element = node as any; if (element.nodeName === tagName) { resNode = element; } else { if (element.childNodes) { visit(element.childNodes); } } }); }; visit(document.childNodes); if (!resNode) { throw new SchematicsException('Head element not found!'); } return { startOffset: resNode.sourceCodeLocation.startTag.endOffset, endOffset: resNode.sourceCodeLocation.endTag.startOffset }; } export function getTagInV4(_host: Tree, src: string, tagName: string): { startOffset: any; endOffset: any } { const document: any = parse5.parse(src, { locationInfo: true } as any); let resNode; const visit = (nodes: any[]): void => { nodes.forEach(node => { const element: any = node; if (element.tagName === tagName) { resNode = element; } else { if (element.childNodes) { visit(element.childNodes); } } }); }; visit(document.childNodes); if (!resNode) { throw new SchematicsException('Head element not found!'); } return { startOffset: resNode.__location.startTag.endOffset, endOffset: resNode.__location.endTag.startOffset }; } /** * Get index.html content */ export function getIndexHtmlContent(tree: Tree, project: ProjectDefinition): { indexPath: string; src: string } { const indexPath = getIndexHtmlPath(tree, project); const buffer = tree.read(indexPath); if (!buffer) { throw new SchematicsException(`Could not find file for path '${indexPath}'`); } return { indexPath, src: buffer.toString() }; } /** * Adds a link to the index.html head tag */ export function addHeadLink(tree: Tree, project: ProjectDefinition, link: string): void { const { indexPath, src } = getIndexHtmlContent(tree, project); if (src.indexOf(link) === -1) { const node = getTag(tree, src, 'head'); const insertion = new InsertChange(indexPath, node.startOffset, link); const recorder = tree.beginUpdate(indexPath); recorder.insertLeft(insertion.pos, insertion.toAdd); tree.commitUpdate(recorder); } } /** * Adds a style to the index.html head end tag */ export function addHeadStyle(tree: Tree, project: ProjectDefinition, style: string): void { const { indexPath, src } = getIndexHtmlContent(tree, project); if (src.indexOf(style) === -1) { const node = getTag(tree, src, 'head'); const insertion = new InsertChange(indexPath, node.endOffset, style); const recorder = tree.beginUpdate(indexPath); recorder.insertLeft(insertion.pos, insertion.toAdd); tree.commitUpdate(recorder); } } /** * Adds a html to the index.html body end tag */ export function addHtmlToBody(tree: Tree, project: ProjectDefinition, html: string): void { const { indexPath, src } = getIndexHtmlContent(tree, project); if (src.indexOf(html) === -1) { const node = getTag(tree, src, 'body'); const insertion = new InsertChange(indexPath, node.endOffset, html); const recorder = tree.beginUpdate(indexPath); recorder.insertLeft(insertion.pos, insertion.toAdd); tree.commitUpdate(recorder); } }