diff --git a/src/libs/SelectionScraper/index.js b/src/libs/SelectionScraper/index.js index 00e46d5aed7a..2d81d9f6ccf6 100644 --- a/src/libs/SelectionScraper/index.js +++ b/src/libs/SelectionScraper/index.js @@ -43,7 +43,8 @@ const getHTMLOfSelection = () => { // If clonedSelection has no text content this data has no meaning to us. if (clonedSelection.textContent) { - let node = null; + let parent; + let child = clonedSelection; // If selection starts and ends within same text node we use its parentNode. This is because we can't // use closest function on a [Text](https://developer.mozilla.org/en-US/docs/Web/API/Text) node. @@ -61,19 +62,21 @@ const getHTMLOfSelection = () => { // // and finally commonAncestorContainer.parentNode.closest('data-testid') is targeted dom. if (range.commonAncestorContainer instanceof HTMLElement) { - node = range.commonAncestorContainer.closest(`[${tagAttribute}]`); + parent = range.commonAncestorContainer.closest(`[${tagAttribute}]`); } else { - node = range.commonAncestorContainer.parentNode.closest(`[${tagAttribute}]`); + parent = range.commonAncestorContainer.parentNode.closest(`[${tagAttribute}]`); } - // This means "range.commonAncestorContainer" is a text node. We simply get its parent node. - if (!node) { - node = range.commonAncestorContainer.parentNode; + // Keep traversing up to clone all parents with 'data-testid' attribute. + while (parent) { + const cloned = parent.cloneNode(); + cloned.appendChild(child); + child = cloned; + + parent = parent.parentNode.closest(`[${tagAttribute}]`); } - node = node.cloneNode(); - node.appendChild(clonedSelection); - div.appendChild(node); + div.appendChild(child); } }