1+ import NodeIterator from '../node-iterator'
2+ import { textNode } from '../node-type'
3+
14/**
25 * @param {HTMLElement | Array | String } target
36 * @param {Document } document
@@ -228,21 +231,21 @@ export const createRangeFromCharacterRange = (element, actualStartIndex, actualE
228231 let startNode , endNode , startOffset , endOffset
229232
230233 while ( walker . nextNode ( ) ) {
231- const textNode = walker . currentNode
232- const nodeLength = textNode . nodeValue . length
234+ const node = walker . currentNode
235+ const nodeLength = node . nodeValue . length
233236
234237 if ( currentIndex + nodeLength <= actualStartIndex ) {
235238 currentIndex += nodeLength
236239 continue
237240 }
238241
239242 if ( ! startNode ) {
240- startNode = textNode
243+ startNode = node
241244 startOffset = actualStartIndex - currentIndex
242245 }
243246
244247 if ( currentIndex + nodeLength >= actualEndIndex ) {
245- endNode = textNode
248+ endNode = node
246249 endOffset = actualEndIndex - currentIndex
247250 break
248251 }
@@ -260,3 +263,87 @@ export const createRangeFromCharacterRange = (element, actualStartIndex, actualE
260263 }
261264}
262265
266+ export function findStartExcludingWhitespace ( { root, startContainer, startOffset, whitespacesOnTheLeft} ) {
267+ const isTextNode = startContainer . nodeType === textNode
268+ if ( ! isTextNode ) {
269+ return findStartExcludingWhitespace ( {
270+ root,
271+ startContainer : startContainer . childNodes [ startOffset ] ,
272+ startOffset : 0 ,
273+ whitespacesOnTheLeft
274+ } )
275+ }
276+
277+ const offsetAfterWhitespace = startOffset + whitespacesOnTheLeft
278+ if ( startContainer . length > offsetAfterWhitespace ) {
279+ return [ startContainer , offsetAfterWhitespace ]
280+ }
281+
282+ // Pass the root so that the iterator can traverse to siblings
283+ const iterator = new NodeIterator ( root )
284+ // Set the position to the node which is selected
285+ iterator . nextNode = startContainer
286+ // Iterate once to avoid returning self
287+ iterator . getNextTextNode ( )
288+
289+ const container = iterator . getNextTextNode ( )
290+ if ( ! container ) {
291+ // No more text nodes - use the end of the last text node
292+ const previousTextNode = iterator . getPreviousTextNode ( )
293+ return [ previousTextNode , previousTextNode . length ]
294+ }
295+
296+ return findStartExcludingWhitespace ( {
297+ root,
298+ startContainer : container ,
299+ startOffset : 0 ,
300+ whitespacesOnTheLeft : offsetAfterWhitespace - startContainer . length
301+ } )
302+ }
303+
304+ export function findEndExcludingWhitespace ( { root, endContainer, endOffset, whitespacesOnTheRight} ) {
305+ const isTextNode = endContainer . nodeType === textNode
306+ if ( ! isTextNode ) {
307+ const isFirstNode = ! endContainer . childNodes [ endOffset - 1 ]
308+ const container = isFirstNode
309+ ? endContainer . childNodes [ endOffset ]
310+ : endContainer . childNodes [ endOffset - 1 ]
311+ let offset = 0
312+ if ( ! isFirstNode ) {
313+ offset = container . nodeType === textNode
314+ ? container . length
315+ : container . childNodes . length
316+ }
317+ return findEndExcludingWhitespace ( {
318+ root,
319+ endContainer : container ,
320+ endOffset : offset ,
321+ whitespacesOnTheRight
322+ } )
323+ }
324+
325+ const offsetBeforeWhitespace = endOffset - whitespacesOnTheRight
326+ if ( offsetBeforeWhitespace > 0 ) {
327+ return [ endContainer , offsetBeforeWhitespace ]
328+ }
329+
330+ // Pass the root so that the iterator can traverse to siblings
331+ const iterator = new NodeIterator ( root )
332+ // Set the position to the node which is selected
333+ iterator . previous = endContainer
334+ // Iterate once to avoid returning self
335+ iterator . getPreviousTextNode ( )
336+
337+ const container = iterator . getPreviousTextNode ( )
338+ if ( ! container ) {
339+ // No more text nodes - use the start of the first text node
340+ return [ iterator . getNextTextNode ( ) , 0 ]
341+ }
342+
343+ return findEndExcludingWhitespace ( {
344+ root,
345+ endContainer : container ,
346+ endOffset : container . length ,
347+ whitespacesOnTheRight : whitespacesOnTheRight - endOffset
348+ } )
349+ }
0 commit comments