{"version":3,"file":"ngx-line-truncation.mjs","sources":["../../../projects/line-truncation-lib/src/lib/line-truncation.directive.ts","../../../projects/line-truncation-lib/src/lib/line-truncation-lib.module.ts","../../../projects/line-truncation-lib/src/public_api.ts","../../../projects/line-truncation-lib/src/ngx-line-truncation.ts"],"sourcesContent":["import {\n  AfterViewInit,\n  Directive,\n  ElementRef,\n  EventEmitter,\n  Input,\n  OnInit,\n  Output,\n  Renderer2,\n  OnDestroy,\n  HostListener\n} from \"@angular/core\";\nimport { getContentHeight, getLineHeight, truncate } from \"line-truncation\";\nimport { Subject, Subscription, BehaviorSubject } from \"rxjs\";\nimport { debounceTime, skip } from \"rxjs/operators\";\n\n/**\n * This Directive allows you to specify the number of lines that you want to truncate a text by.\n *\n * @example\n * <!-- with <p> -->\n *   <p [innerHTML]=\"description\"\n *      [line-truncation]=\"5\"\n *      (hasTruncated)=\"onTruncationFinish(e)\">\n *   </p>\n * <!-- with div -->\n *  <div [line-truncation]=\"5\">your text</div>\n *\n */\n\ninterface Options {\n  ellipsis: string;\n}\n\n@Directive({\n  selector: \"[line-truncation]\",\n  exportAs: \"lineTruncation\"\n})\nexport class LineTruncationDirective\n  implements AfterViewInit, OnInit, OnDestroy {\n  @Input(\"line-truncation\")\n  lines = 1;\n\n  @Input()\n  options: Options = { ellipsis: \"\\u2026\" };\n\n  @Input() set disabled(val: boolean) {\n    this._disabled$.next(val);\n  }\n\n  @Input()\n  watchChanges = false;\n\n  @Output()\n  hasTruncated = new EventEmitter<boolean>();\n\n  elementClone: Node;\n  MAX_TRIES = 10;\n  observerFlag = true;\n\n  _disabled$ = new BehaviorSubject<boolean>(false);\n  element = this.elementRef.nativeElement;\n  windowResize$ = new Subject<Event>();\n  windowListener: Subscription;\n  mutationObserver: MutationObserver;\n  isTruncated: boolean;\n\n  @HostListener(\"window:resize\", [\"$event\"])\n  handleClick(event: Event) {\n    this.windowResize$.next(event);\n  }\n\n  constructor(private elementRef: ElementRef<HTMLElement>, private renderer: Renderer2) {}\n  /**\n   * Hide the original text content until we've finished the truncation\n   */\n  ngOnInit() {\n    this._disabled$.pipe(skip(1)).subscribe(disable => {\n      // If there is elementClone, then recover\n      if (!!this.elementClone) {\n        this.putbackElement();\n      }\n\n      if (disable) {\n        // shut down listener, observer\n        this.disconnectMutationObserver();\n        this.disconnectWindowLisener();\n      } else {\n        // re-register\n        this.truncationInit();\n        // re-execute truncation\n        this.truncateWhenNecessary(this.element);\n      }\n    });\n    // first emit handling\n    if (!this._disabled$.getValue()) {\n      this.truncationInit();\n    }\n  }\n\n  ngAfterViewInit() {\n    this.truncateWhenNecessary(this.element);\n  }\n\n  truncateWhenNecessary(\n    element: HTMLElement,\n    tries: number = 1,\n    maxTries = this.MAX_TRIES\n  ) {\n    if (this._disabled$.getValue()) {\n      return;\n    }\n    // backup original element before truncation\n    this.elementClone = element.cloneNode(true);\n\n    if (tries > maxTries) {\n      return;\n    }\n\n    // Allows buffer period for DOM to be ready\n    setTimeout(() => {\n      // Recursively call the truncate itself if Client Height is not ready\n      if (element.clientHeight > 0) {\n        const contentHeight = getContentHeight(element);\n        const lineHeight = getLineHeight(element);\n        const targetHeight = this.lines * lineHeight;\n\n        if (contentHeight > targetHeight) {\n          try {\n            truncate(\n              element,\n              this.lines,\n              this.options.ellipsis,\n              this.handler.bind(this)\n            );\n          } catch (e) {\n            this.handler(true);\n          }\n        } else {\n          // when there is no need, simply show the element, emit false and unsubscribe from MutationObserver if `watchChanges` prop was falsy\n          this.handler(false);\n        }\n      }\n    }, 100);\n  }\n\n  handler(e: boolean) {\n    this.isTruncated = e;\n    this.hasTruncated.emit(this.isTruncated);\n\n    if (!this.watchChanges) {\n      this.observerFlag = false;\n      this.disconnectMutationObserver();\n    }\n    this.renderer.removeStyle(this.element, \"visibility\");\n  }\n\n  truncationInit() {\n    this.renderer.setStyle(this.element, \"visibility\", \"hidden\");\n    this.initWindowResizeListener(this.element);\n    this.initMutationObserver(this.element);\n  }\n\n  putbackElement() {\n    // grab old child nodes\n    const childNodes: Node[] = Array.from(this.elementClone.childNodes);\n    // clean element\n    while (this.element.firstChild) {\n      this.element.removeChild(this.element.firstChild);\n    }\n\n    // push child node to element shell\n    childNodes.forEach(node => {\n      this.element.appendChild(node);\n    });\n\n    this.elementClone = null;\n  }\n\n  initWindowResizeListener(element: HTMLElement) {\n    this.windowListener = this.windowResize$\n      .pipe(debounceTime(500))\n      .subscribe(() => {\n        this.renderer.setStyle(element, \"visibility\", \"hidden\");\n        this.putbackElement();\n        this.truncateWhenNecessary(element);\n      });\n  }\n\n  initMutationObserver(element: HTMLElement) {\n    this.mutationObserver = new MutationObserver(() => {\n      if (this.observerFlag) {\n        this.truncateWhenNecessary(element);\n      }\n    });\n\n    this.mutationObserver.observe(element, {\n      childList: true\n    });\n  }\n\n  disconnectMutationObserver() {\n    if (this.mutationObserver) {\n      this.mutationObserver.disconnect();\n    }\n  }\n\n  disconnectWindowLisener() {\n    if (this.windowListener) {\n      this.windowListener.unsubscribe();\n    }\n  }\n\n  ngOnDestroy() {\n    this._disabled$.complete();\n    this.disconnectMutationObserver();\n    this.disconnectWindowLisener();\n  }\n}\n","import { NgModule } from '@angular/core';\nimport { LineTruncationDirective } from './line-truncation.directive';\n\n@NgModule({\n  declarations: [LineTruncationDirective],\n  exports: [LineTruncationDirective],\n})\nexport class LineTruncationLibModule {}\n","/*\n * Public API Surface of line-truncation-lib\n */\n\nexport * from './lib/line-truncation-lib.module';\nexport * from './lib/line-truncation.directive';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}