html-head-element.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. "use strict";
  2. /**
  3. * @license
  4. * Copyright Google LLC All Rights Reserved.
  5. *
  6. * Use of this source code is governed by an MIT-style license that can be
  7. * found in the LICENSE file at https://angular.io/license
  8. */
  9. Object.defineProperty(exports, "__esModule", { value: true });
  10. const schematics_1 = require("@angular-devkit/schematics");
  11. const parse5_element_1 = require("./parse5-element");
  12. const parse5_1 = require("parse5");
  13. /** Appends the given element HTML fragment to the `<head>` element of the specified HTML file. */
  14. function appendHtmlElementToHead(host, htmlFilePath, elementHtml) {
  15. const htmlFileBuffer = host.read(htmlFilePath);
  16. if (!htmlFileBuffer) {
  17. throw new schematics_1.SchematicsException(`Could not read file for path: ${htmlFilePath}`);
  18. }
  19. const htmlContent = htmlFileBuffer.toString();
  20. if (htmlContent.includes(elementHtml)) {
  21. return;
  22. }
  23. const headTag = getHtmlHeadTagElement(htmlContent);
  24. if (!headTag) {
  25. throw `Could not find '<head>' element in HTML file: ${htmlFileBuffer}`;
  26. }
  27. // We always have access to the source code location here because the `getHeadTagElement`
  28. // function explicitly has the `sourceCodeLocationInfo` option enabled.
  29. const endTagOffset = headTag.sourceCodeLocation.endTag.startOffset;
  30. const indentationOffset = parse5_element_1.getChildElementIndentation(headTag);
  31. const insertion = `${' '.repeat(indentationOffset)}${elementHtml}`;
  32. const recordedChange = host
  33. .beginUpdate(htmlFilePath)
  34. .insertRight(endTagOffset, `${insertion}\n`);
  35. host.commitUpdate(recordedChange);
  36. }
  37. exports.appendHtmlElementToHead = appendHtmlElementToHead;
  38. /** Parses the given HTML file and returns the head element if available. */
  39. function getHtmlHeadTagElement(htmlContent) {
  40. const document = parse5_1.parse(htmlContent, { sourceCodeLocationInfo: true });
  41. const nodeQueue = [...document.childNodes];
  42. while (nodeQueue.length) {
  43. const node = nodeQueue.shift();
  44. if (node.nodeName.toLowerCase() === 'head') {
  45. return node;
  46. }
  47. else if (node.childNodes) {
  48. nodeQueue.push(...node.childNodes);
  49. }
  50. }
  51. return null;
  52. }
  53. exports.getHtmlHeadTagElement = getHtmlHeadTagElement;
  54. //# sourceMappingURL=html-head-element.js.map