How to use Rangy with PDFjs text layer?

38 Views Asked by At

I'm using Rangy library to select text and apply highlight class on it, the problem is when is select a partial of text the rest become unselectable!

My highlight function:

  applyHighlight() {
   rangy.init()
   let selection = rangy.getSelection();
   if (selection.rangeCount > 0) {
   let highlighter = rangy.createHighlighter();
   highlighter.addClassApplier(rangy.createClassApplier('highlight-yellow'));
   highlighter.highlightSelection('highlight-yellow');
   rangy.getSelection().removeAllRanges();
}}

CSS class

 .highlight-yellow {
  margin: -1px !important;
  padding: 1px !important;
  background-color: rgb(252, 238, 124) !important;
  border-radius: 4px !important;
  opacity: 50%;
  cursor: pointer;}

A screenshots to describe the issue..

here is the highlighted spans enter image description here

and this is what it looks like from the console enter image description here

As you can see the "copies are not made or distributed" part is becomes unselectable and it goes out from the span scope.

1

There are 1 best solutions below

6
ADITYA On

You might need to modify your highlight function to handle partial selections more effectively.

applyHighlight() {
    rangy.init();
    let selection = rangy.getSelection();
    if (!selection.isCollapsed) {
        let highlighter = rangy.createHighlighter();
        highlighter.addClassApplier(rangy.createClassApplier('highlight-yellow'));

        let ranges = [];

        // Function to recursively traverse the DOM and identify text nodes within the selection
        function traverse(node) {
            if (node.nodeType === Node.TEXT_NODE && selection.containsNode(node, true)) {
                // Create a range for each text node within the selection
                let range = rangy.createRange();
                range.selectNodeContents(node);
                ranges.push(range);
            } else if (node.nodeType === Node.ELEMENT_NODE) {
                // Check if the selection partially overlaps with this element
                let range = rangy.createRange();
                range.selectNode(node);
                if (!range.isCollapsed && selection.overlaps(range)) {
                    // Split the selection and recursively traverse child nodes
                    for (let i = 0; i < node.childNodes.length; i++) {
                        traverse(node.childNodes[i]);
                    }
                }
            }
        }

        // Traverse the common ancestor container of the selection
        traverse(selection.getRangeAt(0).commonAncestorContainer);

        // Highlight each range separately
        for (let i = 0; i < ranges.length; i++) {
            highlighter.highlightRanges('highlight-yellow', [ranges[i]]);
        }

        rangy.getSelection().removeAllRanges();
    }
}