Better range handling.
This commit is contained in:
parent
871acf7c2d
commit
19cc8fda33
@ -110,13 +110,13 @@ class Client {
|
||||
return;
|
||||
}
|
||||
|
||||
textSource.setLength(this.options.scanLength);
|
||||
textSource.setEndOffset(this.options.scanLength);
|
||||
bgFindTerm(textSource.text(), ({definitions, length}) => {
|
||||
if (length === 0) {
|
||||
this.hidePopup();
|
||||
} else {
|
||||
const sequence = ++this.sequence;
|
||||
textSource.setLength(length);
|
||||
textSource.setEndOffset(length);
|
||||
|
||||
bgRenderText(
|
||||
{definitions, root: this.fgRoot, options: this.options, sequence},
|
||||
|
@ -32,8 +32,14 @@ class TextSourceImage {
|
||||
return this.img.getAttribute('alt') || '';
|
||||
}
|
||||
|
||||
setLength(length) {
|
||||
setStartOffset(length) {
|
||||
// NOP
|
||||
return 0;
|
||||
}
|
||||
|
||||
setEndOffset(length) {
|
||||
this.length = length;
|
||||
return length;
|
||||
}
|
||||
|
||||
containsPoint(point) {
|
||||
|
@ -32,8 +32,14 @@ class TextSourceInput {
|
||||
return this.input.nodeName === 'BUTTON' ? this.input.innerHTML : this.input.value;
|
||||
}
|
||||
|
||||
setLength(length) {
|
||||
setStartOffset(length) {
|
||||
// NOP
|
||||
return 0;
|
||||
}
|
||||
|
||||
setEndOffset(length) {
|
||||
this.length = length;
|
||||
return length;
|
||||
}
|
||||
|
||||
containsPoint(point) {
|
||||
|
@ -26,9 +26,16 @@ class TextSourceRange {
|
||||
return this.rng.toString();
|
||||
}
|
||||
|
||||
setLength(length) {
|
||||
const end = TextSourceRange.seekEnd(this.rng.startContainer, this.rng.startOffset + length);
|
||||
setEndOffset(length) {
|
||||
const end = TextSourceRange.seekForward(this.rng.startContainer, this.rng.startOffset + length);
|
||||
this.rng.setEnd(end.node, end.offset);
|
||||
return length - end.length;
|
||||
}
|
||||
|
||||
setStartOffset(length) {
|
||||
const start = TextSourceRange.seekBackward(this.rng.startContainer, length + (this.rng.startContainer.length - this.rng.startOffset));
|
||||
this.rng.setStart(start.node, start.offset);
|
||||
return length - start.length;
|
||||
}
|
||||
|
||||
containsPoint(point) {
|
||||
@ -67,29 +74,24 @@ class TextSourceRange {
|
||||
return other.rng && other.rng.compareBoundaryPoints(Range.START_TO_START, this.rng) == 0;
|
||||
}
|
||||
|
||||
static seekEnd(node, length) {
|
||||
static seekForward(node, length) {
|
||||
const state = {node, offset: 0, length};
|
||||
|
||||
if (!TextSourceRange.seekEndRecurse(node, state)) {
|
||||
return {node: state.node, offset: state.offset};
|
||||
if (!TextSourceRange.seekForwardHelper(node, state)) {
|
||||
return state;
|
||||
}
|
||||
|
||||
for (let sibling = node.nextSibling; sibling !== null; sibling = sibling.nextSibling) {
|
||||
if (!TextSourceRange.seekEndRecurse(sibling, state)) {
|
||||
return {node: state.node, offset: state.offset};
|
||||
for (let current = node; current !== null; current = current.parentElement) {
|
||||
for (let sibling = current.nextSibling; sibling !== null; sibling = sibling.nextSibling) {
|
||||
if (!TextSourceRange.seekForwardHelper(sibling, state)) {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let sibling = node.parentElement.nextSibling; sibling !== null; sibling = sibling.nextSibling) {
|
||||
if (!TextSourceRange.seekEndRecurse(sibling, state)) {
|
||||
return {node: state.node, offset: state.offset};
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
return {node: state.node, offset: state.offset};
|
||||
}
|
||||
|
||||
static seekEndRecurse(node, state) {
|
||||
static seekForwardHelper(node, state) {
|
||||
if (node.nodeType === 3) {
|
||||
const consumed = Math.min(node.length, state.length);
|
||||
state.node = node;
|
||||
@ -97,7 +99,41 @@ class TextSourceRange {
|
||||
state.length -= consumed;
|
||||
} else {
|
||||
for (let i = 0; i < node.childNodes.length; ++i) {
|
||||
if (!TextSourceRange.seekEndRecurse(node.childNodes[i], state)) {
|
||||
if (!TextSourceRange.seekForwardHelper(node.childNodes[i], state)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return state.length > 0;
|
||||
}
|
||||
|
||||
static seekBackward(node, length) {
|
||||
const state = {node, offset: node.length, length};
|
||||
if (!TextSourceRange.seekBackwardHelper(node, state)) {
|
||||
return state;
|
||||
}
|
||||
|
||||
for (let current = node; current !== null; current = current.parentElement) {
|
||||
for (let sibling = current.previousSibling; sibling !== null; sibling = sibling.previousSibling) {
|
||||
if (!TextSourceRange.seekBackwardHelper(sibling, state)) {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
static seekBackwardHelper(node, state) {
|
||||
if (node.nodeType === 3) {
|
||||
const consumed = Math.min(node.length, state.length);
|
||||
state.node = node;
|
||||
state.offset = node.length - consumed;
|
||||
state.length -= consumed;
|
||||
} else {
|
||||
for (let i = node.childNodes.length - 1; i >= 0; --i) {
|
||||
if (!TextSourceRange.seekBackwardHelper(node.childNodes[i], state)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user