import { TagName } from "@fluid-example/flow-util-lib" ; import { FlowDocument } from "../document" ; import { debug } from "./debug" ; const enum ClipboardFormat { html = "text/html" , text = "text/text" } export function paste ( doc , data , position ) { let content ; if ( content = data . getData ( ClipboardFormat . html ) ) { debug ( "paste('text/html'): %s" , content ) ; const root = document . createElement ( "span" ) ; root . innerHTML = content ; pasteChildren ( doc , root , position ) ; } else if ( content = data . getData ( ClipboardFormat . html ) ) { debug ( "paste('text/plain'): %s" , content ) ; doc . insertText ( position , content ) ; } else { debug ( "paste(%o): Unhandled clipboard type" , data . types ) ; } } const ignoredTags = [ TagName . meta ] ; function pasteChildren ( doc , root , position ) { let _position = position ; for ( let child = root . firstChild ; child !== null ; child = child . nextSibling ) { switch ( child . nodeType ) { case document . TEXT_NODE : { const text = child as Text ; doc . insertText ( _position , text . textContent ) ; _position += text . textContent . length ; break ; } case document . ELEMENT_NODE : { const el = child as HTMLElement ; const tag = el . tagName as TagName ; const emitTag = ! ignoredTags . includes ( tag ) ; if ( emitTag ) { doc . insertTags ( [ tag ] , _position ) ; doc . setAttr ( _position , _position + 1 , [ ... el . attributes ] . reduce ( ( accumulator , value ) => { accumulator [ value . name ] = value . textContent ; return accumulator ; } , { } ) ) ; doc . setCssStyle ( _position , _position + 1 , el . style . cssText ) ; _position ++ ; } _position = pasteChildren ( doc , el , _position ) ; if ( emitTag ) { _position ++ ; } break ; } default : } } return _position ; }