UNPKG

ohayolibs

Version:

Ohayo is a set of essential modules for ohayojp.

145 lines (123 loc) 4.12 kB
import { SchematicsException, Tree } from '@angular-devkit/schematics'; import { InsertChange } from '@schematics/angular/utility/change'; import * as parse5 from 'parse5'; import { Project } from './project'; /** Gets the app index.html file */ export function getIndexHtmlPath(_host: Tree, project: Project): string { const buildTarget = (project.targets || project.architect)!.build.options; if (buildTarget.index && buildTarget.index.endsWith('index.html')) { return buildTarget.index; } throw new SchematicsException('No index.html file was found.'); } /** * Parses the index.html file to get the HEAD tag position. */ export function getTag(host: Tree, src: string, tagName: string): { startOffset: any; endOffset: any } { if ((parse5 as any).treeAdapters) { return getTagInV4(host, src, tagName); } const document = parse5.parse(src, { sourceCodeLocationInfo: true, } as any) as any; let resNode: any; const visit = (nodes: any[]) => { 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[]) => { 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(host: Tree, project: Project): { indexPath: string; src: string } { const indexPath = getIndexHtmlPath(host, project); const buffer = host.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(host: Tree, project: Project, link: string): void { const { indexPath, src } = getIndexHtmlContent(host, project); if (src.indexOf(link) === -1) { const node = getTag(host, src, 'head'); const insertion = new InsertChange(indexPath, node.startOffset, link); const recorder = host.beginUpdate(indexPath); recorder.insertLeft(insertion.pos, insertion.toAdd); host.commitUpdate(recorder); } } /** * Adds a style to the index.html head end tag */ export function addHeadStyle(host: Tree, project: Project, style: string): void { const { indexPath, src } = getIndexHtmlContent(host, project); if (src.indexOf(style) === -1) { const node = getTag(host, src, 'head'); const insertion = new InsertChange(indexPath, node.endOffset, style); const recorder = host.beginUpdate(indexPath); recorder.insertLeft(insertion.pos, insertion.toAdd); host.commitUpdate(recorder); } } /** * Adds a html to the index.html body end tag */ export function addHtmlToBody(host: Tree, project: Project, html: string): void { const { indexPath, src } = getIndexHtmlContent(host, project); if (src.indexOf(html) === -1) { const node = getTag(host, src, 'body'); const insertion = new InsertChange(indexPath, node.endOffset, html); const recorder = host.beginUpdate(indexPath); recorder.insertLeft(insertion.pos, insertion.toAdd); host.commitUpdate(recorder); } }