/**
 * Copyright (c) Tiny Technologies, Inc. All rights reserved.
 * Licensed under the LGPL or a commercial license.
 * For LGPL see License.txt in the project root for license information.
 * For commercial licenses see https://www.tiny.cloud/
 */ import DOMUtils from 'tinymce/core/api/dom/DOMUtils' ; import * as Range from './Range' ; const DOM = DOMUtils . DOM ; param { DOMRange } rng return { Object } const createBookmark = function ( rng ) { const bookmark = { } ; const setupEndPoint = function ( start ? ) { let offsetNode , container , offset ; container = rng [ start ? 'startContainer' : 'endContainer' ] ; offset = rng [ start ? 'startOffset' : 'endOffset' ] ; if ( container . nodeType === 1 ) { offsetNode = DOM . create ( 'span' , { 'data-mce-type' : 'bookmark' } ) ; if ( container . hasChildNodes ( ) ) { offset = Math . min ( offset , container . childNodes . length - 1 ) ; if ( start ) { container . insertBefore ( offsetNode , container . childNodes [ offset ] ) ; } else { DOM . insertAfter ( offsetNode , container . childNodes [ offset ] ) ; } } else { container . appendChild ( offsetNode ) ; } container = offsetNode ; offset = 0 ; } bookmark [ start ? 'startContainer' : 'endContainer' ] = container ; bookmark [ start ? 'startOffset' : 'endOffset' ] = offset ; } ; setupEndPoint ( true ) ; if ( ! rng . collapsed ) { setupEndPoint ( ) ; } return bookmark ; } ; const resolveBookmark = function ( bookmark ) { function restoreEndPoint ( start ? ) { let container , offset , node ; const nodeIndex = function ( container ) { let node = container . parentNode . firstChild , idx = 0 ; while ( node ) { if ( node === container ) { return idx ; } if ( node . nodeType !== 1 || node . getAttribute ( 'data-mce-type' ) !== 'bookmark' ) { idx ++ ; } node = node . nextSibling ; } return - 1 ; } ; container = node = bookmark [ start ? 'startContainer' : 'endContainer' ] ; offset = bookmark [ start ? 'startOffset' : 'endOffset' ] ; if ( ! container ) { return ; } if ( container . nodeType === 1 ) { offset = nodeIndex ( container ) ; container = container . parentNode ; DOM . remove ( node ) ; if ( ! container . hasChildNodes ( ) && DOM . isBlock ( container ) ) { container . appendChild ( DOM . create ( 'br' ) ) ; } } bookmark [ start ? 'startContainer' : 'endContainer' ] = container ; bookmark [ start ? 'startOffset' : 'endOffset' ] = offset ; } restoreEndPoint ( true ) ; restoreEndPoint ( ) ; const rng = DOM . createRng ( ) ; rng . setStart ( bookmark . startContainer , bookmark . startOffset ) ; if ( bookmark . endContainer ) { rng . setEnd ( bookmark . endContainer , bookmark . endOffset ) ; } return Range . normalizeRange ( rng ) ; } ; export { createBookmark , resolveBookmark } ;