All files / src/app/core/utils/dom dom.service.ts

35.71% Statements 10/28
46.66% Branches 7/15
25% Functions 3/12
33.33% Lines 9/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155111x 111x               111x   27x   27x                                                                                                                                                   9x                     9x 9x 9x                                                                                                            
import { DOCUMENT } from '@angular/common';
import { Inject, Injectable, Renderer2, RendererFactory2, RendererStyleFlags2 } from '@angular/core';
 
/**
 * Utility Service for DOM Manipulations using Angular Renderer2. It allows you to manipulate DOM elements without accessing the DOM directly. While working with SSR DOM manipulations are not possible on server, this is also handled properly.
 *
 **/
 
@Injectable({ providedIn: 'root' })
export class DomService {
  private renderer: Renderer2;
  constructor(private rendererFactory: RendererFactory2, @Inject(DOCUMENT) private document: Document) {
    // Get an instance of Renderer2
    this.renderer = this.rendererFactory.createRenderer(undefined, undefined);
  }
 
  /**
   * Appends a child to a given parent node.
   *
   * @param parent  The parent element.
   * @param el      The child element.
   */
  appendChild(parent: HTMLElement, el: HTMLElement): void {
    return this.renderer.appendChild(parent, el);
  }
 
  /**
   * Gets a (unique) element by its id
   *
   * @param id  The element id.
   * @param el  The html element.
   */
  getElementById(id: string): HTMLElement {
    return this.document.getElementById(id);
  }
 
  /**
   * Creates an HTML element specified by tagName and if a parent is given appends it to a parent element.
   *
   * @param tagName The type of element to be created, e.g. 'div'
   * @param parent  The parent element.
   * @returns       The created element.
   */
  createElement<T extends HTMLElement>(tagName: string, parent?: HTMLElement): T {
    const el: T = this.renderer.createElement(tagName);
    Iif (parent) {
      this.appendChild(parent, el);
    }
    return el;
  }
 
  /**
   *  Returns the first element within the document that matches the specified selector. If no matches are found a new element is created.
   *
   * @param selector  A valid CSS selector string.
   * @param tagName   The type of element to be created if no element is found.
   * @param parent    The parent element for the element to be created.
   * @returns         Either the found or created element.
   */
  getOrCreateElement<T extends HTMLElement>(selector: string, tagName: string, parent?: HTMLElement): T {
    const el: T = this.document.querySelector(selector);
    return el ? el : this.createElement<T>(tagName, parent);
  }
 
  /**
   * Creates a text node with the given text and if a parent is given appends it to a parent element.
   *
   * @param text    The text string.
   * @param parent  The parent element.
   * @returns       The created element.
   */
  createTextNode(text: string, parent?: HTMLElement) {
    const textNode = this.renderer.createText(text);
    Iif (parent) {
      this.appendChild(parent, textNode);
    }
    return textNode;
  }
 
  /**
   * Sets an attribute value for an element in the DOM.
   *
   * @param el              The element.
   * @param attributeName   The attribute name.
   * @param value           The value to be set.
   */
  setAttribute(el: HTMLElement, attributeName: string, value: string): void {
    this.renderer.setAttribute(el, attributeName, value);
  }
 
  /**
   * Sets an attribute value for the first element in the DOM that matches the specified selector. If no matches are found nothing is done.
   *
   * @param selector  A valid CSS selector string.
   * @param attributeName   The attribute name.
   * @param value           The value to be set.
   */
  setAttributeForSelector(selector: string, attributeName: string, value: string) {
    const el: HTMLElement = this.document.querySelector(selector);
    if (el) {
      this.setAttribute(el, attributeName, value);
    }
  }
 
  /**
   * Sets the value of a property of an element in the DOM.
   *
   * @param el              The element.
   * @param name            The property name.
   * @param value           The value to be set.
   */
  setProperty(el: HTMLElement, name: string, value: string | boolean): void {
    return this.renderer.setProperty(el, name, value);
  }
 
  /**
   * Sets the value of a CSS custom property (variable).
   *
   * @param propertyName    The name of the custom property (without prefix '--').
   * @param propertyValue   The value to be set.
   */
  setCssCustomProperty(propertyName: string, propertyValue: string): void {
    this.renderer.setStyle(
      this.document.documentElement,
      `--${propertyName.toLowerCase()}`,
      propertyValue.toString(),
      RendererStyleFlags2.DashCase
    );
  }
 
  /**
   * Adds a class to an element in the DOM.
   *
   * @param el              The element.
   * @param cssClass        The class name.
   */
  addClass(el: HTMLElement, cssClass: string): void {
    Iif (el) {
      this.renderer.addClass(el, cssClass);
    }
  }
 
  /**
   * Removes a class from an element in the DOM.
   *
   * @param el              The element.
   * @param cssClass        The class name.
   */
  removeClass(el: HTMLElement, cssClass: string) {
    Iif (el) {
      this.renderer.removeClass(el, cssClass);
    }
  }
}