File

src/app/directives/clipboard/clipboard.service.ts

Index

Properties
Methods
Accessors

Constructor

constructor(document: any, window: any)
Parameters :
Name Type Optional
document any no
window any no

Methods

Private clearSelection
clearSelection(inputElement: HTMLInputElement | HTMLTextAreaElement, window: Window)
Parameters :
Name Type Optional
inputElement HTMLInputElement | HTMLTextAreaElement no
window Window no
Returns : void
Public copyFromContent
copyFromContent(content: string, renderer: Renderer)

Creates a fake textarea element, sets its value from text property, and makes a selection on it.

Parameters :
Name Type Optional
content string no
renderer Renderer no
Returns : boolean
Public copyFromInputElement
copyFromInputElement(targetElm: HTMLInputElement | HTMLTextAreaElement, renderer: Renderer)

copyFromInputElement

Parameters :
Name Type Optional
targetElm HTMLInputElement | HTMLTextAreaElement no
renderer Renderer no
Returns : boolean
Private copyText
copyText()
Returns : boolean
Private createTempTextArea
createTempTextArea(doc: Document, window: Window)
Parameters :
Name Type Optional
doc Document no
window Window no
Returns : HTMLTextAreaElement
Public destroy
destroy()
Returns : void
Public isTargetValid
isTargetValid(element: HTMLInputElement | HTMLTextAreaElement)
Parameters :
Name Type Optional
element HTMLInputElement | HTMLTextAreaElement no
Returns : boolean
Private selectTarget
selectTarget(inputElement: HTMLInputElement | HTMLTextAreaElement, renderer: Renderer)
Parameters :
Name Type Optional
inputElement HTMLInputElement | HTMLTextAreaElement no
renderer Renderer no
Returns : number | undefined

Properties

Private tempTextArea
tempTextArea: HTMLTextAreaElement | undefined
Type : HTMLTextAreaElement | undefined

Accessors

isSupported
getisSupported()
import {
  Inject,
  Injectable,
  Optional,
  Renderer,
  SkipSelf,
  InjectionToken
} from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';
import { WINDOW } from './window-token';

@Injectable()
export class ClipboardService {
  private tempTextArea: HTMLTextAreaElement | undefined;
  constructor(
    @Inject(DOCUMENT) private document: any,
    @Inject(WINDOW) private window: any
  ) {}
  public get isSupported(): boolean {
    return (
      !!this.document.queryCommandSupported &&
      !!this.document.queryCommandSupported('copy')
    );
  }

  public isTargetValid(
    element: HTMLInputElement | HTMLTextAreaElement
  ): boolean {
    if (
      element instanceof HTMLInputElement ||
      element instanceof HTMLTextAreaElement
    ) {
      if (element.hasAttribute('disabled')) {
        // tslint:disable-next-line:max-line-length
        throw new Error(
          'Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'
        );
      }
      return true;
    }
    throw new Error('Target should be input or textarea');
  }

  /**
   * copyFromInputElement
   */
  public copyFromInputElement(
    targetElm: HTMLInputElement | HTMLTextAreaElement,
    renderer: Renderer
  ): boolean {
    try {
      this.selectTarget(targetElm, renderer);
      const re = this.copyText();
      this.clearSelection(targetElm, this.window);
      return re;
    } catch (error) {
      return false;
    }
  }

  /**
   * Creates a fake textarea element, sets its value from `text` property,
   * and makes a selection on it.
   */
  public copyFromContent(content: string, renderer: Renderer) {
    if (!this.tempTextArea) {
      this.tempTextArea = this.createTempTextArea(this.document, this.window);
      this.document.body.appendChild(this.tempTextArea);
    }
    this.tempTextArea.value = content;
    return this.copyFromInputElement(this.tempTextArea, renderer);
  }

  // remove temporary textarea if any
  public destroy() {
    if (this.tempTextArea) {
      this.document.body.removeChild(this.tempTextArea);
      this.tempTextArea = undefined;
    }
  }

  // select the target html input element
  private selectTarget(
    inputElement: HTMLInputElement | HTMLTextAreaElement,
    renderer: Renderer
  ): number | undefined {
    renderer.invokeElementMethod(inputElement, 'select');
    renderer.invokeElementMethod(inputElement, 'setSelectionRange', [
      0,
      inputElement.value.length
    ]);
    return inputElement.value.length;
  }

  private copyText(): boolean {
    return this.document.execCommand('copy');
  }
  // Removes current selection and focus from `target` element.
  private clearSelection(
    inputElement: HTMLInputElement | HTMLTextAreaElement,
    window: Window
  ) {
    // tslint:disable-next-line:no-unused-expression
    inputElement && inputElement.blur();
    window.getSelection().removeAllRanges();
  }

  // create a fake textarea for copy command
  private createTempTextArea(
    doc: Document,
    window: Window
  ): HTMLTextAreaElement {
    const isRTL = doc.documentElement.getAttribute('dir') === 'rtl';
    let ta: HTMLTextAreaElement;
    ta = doc.createElement('textarea');
    // Prevent zooming on iOS
    ta.style.fontSize = '12pt';
    // Reset box model
    ta.style.border = '0';
    ta.style.padding = '0';
    ta.style.margin = '0';
    // Move element out of screen horizontally
    ta.style.position = 'absolute';
    ta.style[isRTL ? 'right' : 'left'] = '-9999px';
    // Move element to the same position vertically
    const yPosition = window.pageYOffset || doc.documentElement.scrollTop;
    ta.style.top = yPosition + 'px';
    ta.setAttribute('readonly', '');
    return ta;
  }
}
// this pattern is mentioned in https://github.com/angular/angular/issues/13854 in #43
export function CLIPBOARD_SERVICE_PROVIDER_FACTORY(
  doc: Document,
  win: Window,
  parentDispatcher: ClipboardService
) {
  return parentDispatcher || new ClipboardService(doc, win);
}

export const CLIPBOARD_SERVICE_PROVIDER = {
  deps: [DOCUMENT, WINDOW, [new Optional(), new SkipSelf(), ClipboardService]],
  provide: ClipboardService,
  useFactory: CLIPBOARD_SERVICE_PROVIDER_FACTORY
};

results matching ""

    No results matching ""