UNPKG

@ryusei/code

Version:

<div align="center"> <a href="https://code.ryuseijs.com"> <img alt="RyuseiCode" src="https://code.ryuseijs.com/images/svg/logo.svg" width="70"> </a>

97 lines (82 loc) 2.24 kB
import { create, focus, remove, styles } from '../../utils'; /** * The class for normalizing different copy/paste behaviours in browsers. * * @since 0.1.0 */ export class Clipboard { /** * Creates a temporary textarea element. * * @param text - A value for the textarea. * * @return A created element. */ private create( text: string ): HTMLTextAreaElement { const textarea = create( 'textarea', {}, document.body ); const offset = '-999999px'; styles( textarea, { position: 'absolute', top: offset, left: offset } ); textarea.value = text; focus( textarea ); textarea.setSelectionRange( 0, text.length ); return textarea; } /** * Pastes the text via execCommand for old browsers. * * @return A pasted text. */ private execPaste(): string { const textarea = this.create( '' ); document.execCommand( 'paste' ); const { value } = textarea; remove( textarea ); return value; } /** * Copies the provided text via execCommand for old browsers. * * @param text - A text to copy. * @param onFailed - Optional. A callback fired when copy failed. */ private execCopy( text: string, onFailed?: () => void ): void { const textarea = this.create( text ); try { document.execCommand( 'copy' ); } catch ( e ) { if ( onFailed ) { onFailed(); } } remove( textarea ); } /** * Pastes the clipboard text. * * @param onPaste - A callback fired after pasting a text, taking a pasted value as the first argument. */ paste( onPaste: ( text: string ) => void ): void { const { clipboard } = navigator; if ( clipboard ) { clipboard.readText().then( onPaste ); } else { onPaste( this.execPaste() ); } } /** * Copies the passed text. * * @param text - A text to copy. * @param onFailed - Optional. A callback fired when copy failed. */ copy( text: string, onFailed?: () => void ): void { const { clipboard } = navigator; if ( clipboard ) { clipboard.writeText( text ).catch( () => { this.execCopy( text, onFailed ); } ); } else { this.execCopy( text, onFailed ); } } }