I am using a Range object as a limiter on another Range object representing the current selection, such that anything that is inside the selected range but is outside the boundaries of the limiting range is trimmed off. To compare the two Ranges’ positions, I’m using the Range.compareBoundaryPoints() function, but the results make no sense.
The element I’m working with looks like this:
<p id="myBlock" contenteditable="true">
Hello hello hello, this is a great big block of test text.
</p>
The ranges are defined and their positional relationship retrieved as follows:
var limitingRange = document.createRange();
limitingRange.selectNodeContents($('#myBlock')[0]);
var selectedRange = window.getSelection().getRangeAt(0).cloneRange(); //Use whatever method is supported by the browser to get the Range
var endToStart = limitingRange.compareBoundaryPoints(Range.END_TO_START, selectedRange);
var startToEnd = limitingRange.compareBoundaryPoints(Range.START_TO_END, selectedRange);
var startToStart = limitingRange.compareBoundaryPoints(Range.START_TO_START, selectedRange);
var endToEnd = limitingRange.compareBoundaryPoints(Range.END_TO_END, selectedRange);
I then select the word “this” in the text and run the function. My ranges look like this (I’m inventing the .start and .end notation to try and make my description clearer):
(limitingRange.start)Hello hello hello, (selectedRange.start)this(selectedRange.end) is a great big block of test text.(limitingRange.end)
The resulting values are:
endToStart = -1
startToEnd = 1
startToStart = -1
endToEnd = 1
I am baffled as to how to interpret the results of the function. Based on the specification it seems like, for example, endToStart should contain -1 if the end of selectedRange comes before the start of limitingRange, but that’s obviously not the case. What’s going on here?
I’m answering my own question: Typing out what was going on led me to actually understand the function’s behavior, which really is strange.
The result of a.compareBoundaryPoints(X_TO_Y, b) is the comparison of a.Y to b.X. -1 if a.Y comes before b.X, 0 if they are at the same position, and 1 if it comes after.
So in endToStart in the above example, limitingRange.start is being compared to selectedRange.end, with -1 indicating that limitingRange.start comes first.
startToEnd: limitingRange.end comes after selectedRange.start, so the result is 1.
startToStart: limitingRange.start comes before selectedRange.start, so the result is -1.
endToEnd: limitingRange.end comes after selectedRange.end, so the result is 1
Leaving me with only the question: Why does this function behave this way? The names of the constants are the opposite of what one would intuitively expect.