vuejs2rangy

Error: Highlighter type 'Range' is not valid


I am facing this error when serializing a selection using Rangy. I am running version 1.3.2 of Rangy and I am selecting text from the dom level. Has anyone come across this issue? I traced it deeper in the rangy library and found out that it only supportes textContent and TextRange type and not Range. However, I am not sure where the Range type is coming from. Any suggestion? The complete function is below.

    const textHighlighter = ContentViewerBaseClass.getTextHighlighter()
    const thisSelection = rangy.getSelection()
    const highlightedText = thisSelection.text()
    serializedData: textHighlighter.serialize(thisSelection),


  public onAddHighlightToSelectedText(highlight: { color, fontColor }) {
    const textHighlighter = ContentViewerBaseClass.getTextHighlighter()

    const thisSelection = rangy.getSelection()
    const highlightedText = thisSelection.text()

    // Ensure no search highlight markup is overlapped
    const allSearchMatchesMarkup =
        this.$refs.contentContainer.querySelectorAll(`.${this.searchMarkupClassName}`)

    const overlappingSearchMarkup = []
    if (allSearchMatchesMarkup) {
        for (const i of allSearchMatchesMarkup) {
            if (thisSelection.containsNode(i, true)) {
                overlappingSearchMarkup.push(i.id)
            }
        }
    }

    let highlightTarget = null
    if (this.currentContentType === ContentType.PDF) {
        highlightTarget = thisSelection.anchorNode.parentElement.closest(`[id^=page-]`)
    } else {
        highlightTarget = this.$refs.contentContainer
    }

    textHighlighter.highlightSelection(this.highlightClassName, {
        selection: thisSelection,
        containerElementId: highlightTarget.id,
    })

    // Create a unique id for this highlight
    const thisHighlightId = `s${String(Date.now())}`

    thisSelection.getRangeAt(0).getNodes([1], (el) => {
        if (el && el.classList.contains(this.highlightClassName)) {
            if (el.classList.contains(this.searchMarkupClassName)) {
                // handle overlap of enriched item and highlighted search item
                el = this.addOverlappingHighlightSearchTextIdToNode(el, thisHighlightId)
            }
            el.id = thisHighlightId

            el.style.backgroundColor = highlight.color

            if (this.currentContentType === ContentType.PDF) {
                el.style.color = 'transparent'
            }

            el.setAttribute('data-note', '')

            this.annotatedElementClicked = el
            return el
        }
    })

    if (this.currentContentType === ContentType.PDF) {
        const pageDomElement =
            this.$refs.contentContainer.querySelector(`#${thisHighlightId}`).closest(`[id^=page-]`)

        if (pageDomElement) {
            if (!this.isPdfContentInArrayFormat) {
                this.currentPageId = pageDomElement.id.substring(pageDomElement.id.indexOf('-') + 1)
            }
        }
    }

    this.saveHighlight({
        id: thisHighlightId,
        type: EnrichmentType.HIGHLIGHT,
        highlightColor: highlight.color,
        highlightedText,
        noteAdded: '',
        contentId: this.currentPageId || '',
        pageId: this.currentContentType === ContentType.PDF ? String(this.currentPageIndex + 1) :
            this.currentPageId,

        pageTitle: this.currentContentType === ContentType.PDF ? `Page ${this.currentPageIndex + 1}` :
            this.currentPageTitle,

        pageIndex: this.currentPageIndex,
        contentType: this.currentContentType,
        timeAdded: String(Date.now()),
        serializedData: textHighlighter.serialize(thisSelection),
    } as IEnrichmentItem)

    // Clear the text selection shading on the document
    thisSelection.removeAllRanges()
}

Solution

  • I fixed the problem by forcing the serializaer to use the type it needed by adding. This is a workaround for now and someone has already opened an issue in the rangy GitHub repository re this issue.

    thisSelection.type = 'textContent' before calling it

        thisSelection.type = 'textContent'
    
        this.saveHighlight({
            id: thisHighlightId,
            type: EnrichmentType.HIGHLIGHT,
            highlightColor: highlight.color,
            highlightedText,
            noteAdded: '',
            contentId: this.currentPageId || '',
            pageId: this.currentContentType === ContentType.PDF ? String(this.currentPageIndex + 1) :
                this.currentPageId,
    
            pageTitle: this.currentContentType === ContentType.PDF ? `Page ${this.currentPageIndex + 1}` :
                this.currentPageTitle,
    
            pageIndex: this.currentPageIndex,
            contentType: this.currentContentType,
            timeAdded: String(Date.now()),
            serializedData: textHighlighter.serialize(thisSelection),
        } as IEnrichmentItem)