Jordan Schwartz
Jordan Schwartz

Reputation: 105

Rangy range contained within a jquery selector

I'm working on a JavaScript wrapper around the Rangy JavaScript plugin. What I'm trying to do: given a jQuery selector and a range, detect if the range is contained within the selector. This is for a space where a user will read a document and be able to make comments about particular sections. So I have a div with id="viewer" that contains the document, and I have an area of buttons that do things after a user selects some text. Here is the (broken) function:

function selectedRangeInRegion(selector) {
    var selectionArea = $(selector);
    var range = rangy.getSelection().getRangeAt(0);
    var inArea = (selectionArea.has(range.startContainer).length > 0);

    if (inArea) {
        return range;
    } else {
        return null;
    }
}

It appears that selectionArea.has(range.startContainer) returns an array of size 0. I have tried wrapping like: $(range.startContainer). Any tips?


I developed a solution for this problem. This assumes you have a div selector and that your content does not have any divs:

function containsLegalRange(selector, range) {
  var foundContainingNode = false;

  var container = range.commonAncestorContainer

  var nearestDiv = $(container).closest("div");    
  if (nearestDiv.attr("id") == selector) {
    return true
  }
  else {
    return false
  }
}

Upvotes: 0

Views: 1690

Answers (2)

Tim Down
Tim Down

Reputation: 324627

That's not how has() works: the parameter you pass to it is either a selector string or a DOM element, whereas range.startContainer is a DOM node that may in practice be a text node or an element.

I don't think there will be a way that's as easy as you're hoping. The following is as simple as I can think of off the top of my head.

jsFiddle: http://jsfiddle.net/TRVCm/

Code:

function containsRange(selector, range, allowPartiallySelected) {
    var foundContainingNode = false;
    $(selector).each(function() {
        if (range.containsNode(this, allowPartiallySelected)) {
            foundContainingNode = true;
            return false;
        }
    });
    return foundContainingNode;
}

Upvotes: 2

BumbleB2na
BumbleB2na

Reputation: 10743

.has() can be weird sometimes and produce .length == 0 when it is not supposed to. Try this way instead:

function selectedRangeInRegion(selector) {
  var range = rangy.getSelection().getRangeAt(0);
  var selectionArea = selector + ':has(\'' + range.startContainer + '\')';
  var inArea = $(selectionArea).length > 0);
  if (inArea) {
    return range; 
  }
  else {
    return null;
  }
}

Upvotes: 0

Related Questions