mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-31 01:28:55 +00:00
740 lines
21 KiB
HTML
740 lines
21 KiB
HTML
<!DOCTYPE html>
|
|
<meta charset="UTF-8">
|
|
<script src="./testing.js"></script>
|
|
|
|
<div id="test-content">
|
|
<p id="p1">The quick brown fox</p>
|
|
<p id="p2">jumps over the lazy dog</p>
|
|
<div id="nested">
|
|
<span id="s1">Hello</span>
|
|
<span id="s2">World</span>
|
|
</div>
|
|
</div>
|
|
|
|
<script id=basic>
|
|
{
|
|
const sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
|
|
testing.expectEqual(0, sel.rangeCount);
|
|
testing.expectEqual("None", sel.type);
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
testing.expectEqual(null, sel.anchorNode);
|
|
testing.expectEqual(null, sel.focusNode);
|
|
testing.expectEqual(0, sel.anchorOffset);
|
|
testing.expectEqual(0, sel.focusOffset);
|
|
testing.expectEqual("none", sel.direction);
|
|
}
|
|
</script>
|
|
|
|
<script id=collapse>
|
|
{
|
|
const sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
const p1 = document.getElementById("p1");
|
|
const textNode = p1.firstChild;
|
|
|
|
// Collapse to a position
|
|
sel.collapse(textNode, 4);
|
|
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual("Caret", sel.type);
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
testing.expectEqual(textNode, sel.anchorNode);
|
|
testing.expectEqual(textNode, sel.focusNode);
|
|
testing.expectEqual(4, sel.anchorOffset);
|
|
testing.expectEqual(4, sel.focusOffset);
|
|
testing.expectEqual("none", sel.direction);
|
|
|
|
// Collapse to null removes all ranges
|
|
sel.collapse(null);
|
|
testing.expectEqual(0, sel.rangeCount);
|
|
testing.expectEqual("None", sel.type);
|
|
}
|
|
</script>
|
|
|
|
<script id=setPosition>
|
|
{
|
|
const sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
const p2 = document.getElementById("p2");
|
|
const textNode = p2.firstChild;
|
|
|
|
// setPosition is an alias for collapse
|
|
sel.setPosition(textNode, 10);
|
|
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual("Caret", sel.type);
|
|
testing.expectEqual(textNode, sel.anchorNode);
|
|
testing.expectEqual(10, sel.anchorOffset);
|
|
|
|
// Test default offset
|
|
sel.setPosition(textNode);
|
|
testing.expectEqual(0, sel.anchorOffset);
|
|
|
|
// Test null
|
|
sel.setPosition(null);
|
|
testing.expectEqual(0, sel.rangeCount);
|
|
}
|
|
</script>
|
|
|
|
<script id=addRange>
|
|
{
|
|
const sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
|
|
const range1 = document.createRange();
|
|
const p1 = document.getElementById("p1");
|
|
range1.selectNodeContents(p1);
|
|
|
|
sel.addRange(range1);
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual("Range", sel.type);
|
|
testing.expectEqual(false, sel.isCollapsed);
|
|
|
|
// Adding same range again should do nothing
|
|
sel.addRange(range1);
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
|
|
// Adding different range
|
|
const range2 = document.createRange();
|
|
const p2 = document.getElementById("p2");
|
|
range2.selectNodeContents(p2);
|
|
|
|
sel.addRange(range2);
|
|
|
|
// Firefox does support multiple ranges so it will be 2 here instead of 1.
|
|
// Chrome and Safari don't so we don't either.
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
}
|
|
</script>
|
|
|
|
<script id=getRangeAt>
|
|
{
|
|
const sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
|
|
const range = document.createRange();
|
|
const p1 = document.getElementById("p1");
|
|
range.selectNodeContents(p1);
|
|
sel.addRange(range);
|
|
|
|
const retrieved = sel.getRangeAt(0);
|
|
testing.expectEqual(range, retrieved);
|
|
}
|
|
</script>
|
|
|
|
<script id=removeRange>
|
|
{
|
|
const sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
|
|
const range1 = document.createRange();
|
|
const range2 = document.createRange();
|
|
const p1 = document.getElementById("p1");
|
|
const p2 = document.getElementById("p2");
|
|
|
|
range1.selectNodeContents(p1);
|
|
range2.selectNodeContents(p2);
|
|
|
|
sel.addRange(range1);
|
|
sel.addRange(range2);
|
|
|
|
// Firefox does support multiple ranges so it will be 2 here instead of 1.
|
|
// Chrome and Safari don't so we don't either.
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
|
|
// Chrome doesn't throw an error here even though the spec defines it:
|
|
// https://w3c.github.io/selection-api/#dom-selection-removerange
|
|
testing.expectError('NotFoundError', () => { sel.removeRange(range2); });
|
|
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual(range1, sel.getRangeAt(0));
|
|
}
|
|
</script>
|
|
|
|
<script id=removeAllRanges>
|
|
{
|
|
const sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
|
|
const range1 = document.createRange();
|
|
const range2 = document.createRange();
|
|
|
|
range1.selectNodeContents(document.getElementById("p1"));
|
|
range2.selectNodeContents(document.getElementById("p2"));
|
|
|
|
sel.addRange(range1);
|
|
sel.addRange(range2);
|
|
|
|
// Firefox does support multiple ranges so it will be 2 here instead of 1.
|
|
// Chrome and Safari don't so we don't either.
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
|
|
sel.removeAllRanges();
|
|
testing.expectEqual(0, sel.rangeCount);
|
|
testing.expectEqual("none", sel.direction);
|
|
}
|
|
</script>
|
|
|
|
<script id=empty>
|
|
{
|
|
const sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
const range = document.createRange();
|
|
range.selectNodeContents(document.getElementById("p1"));
|
|
|
|
sel.addRange(range);
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
|
|
// empty() is an alias for removeAllRanges()
|
|
sel.empty();
|
|
testing.expectEqual(0, sel.rangeCount);
|
|
}
|
|
</script>
|
|
|
|
<script id=collapseToStart>
|
|
{
|
|
const sel = window.getSelection();
|
|
const p1 = document.getElementById("p1");
|
|
const textNode = p1.firstChild;
|
|
|
|
const range = document.createRange();
|
|
range.setStart(textNode, 4);
|
|
range.setEnd(textNode, 15);
|
|
|
|
sel.removeAllRanges();
|
|
sel.addRange(range);
|
|
|
|
testing.expectEqual(false, sel.isCollapsed);
|
|
testing.expectEqual(4, sel.anchorOffset);
|
|
testing.expectEqual(15, sel.focusOffset);
|
|
|
|
sel.collapseToStart();
|
|
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual(textNode, sel.anchorNode);
|
|
testing.expectEqual(4, sel.anchorOffset);
|
|
testing.expectEqual(4, sel.focusOffset);
|
|
testing.expectEqual("none", sel.direction);
|
|
}
|
|
</script>
|
|
|
|
<script id=collapseToEnd>
|
|
{
|
|
const sel = window.getSelection();
|
|
const p1 = document.getElementById("p1");
|
|
const textNode = p1.firstChild;
|
|
|
|
const range = document.createRange();
|
|
range.setStart(textNode, 4);
|
|
range.setEnd(textNode, 15);
|
|
|
|
sel.removeAllRanges();
|
|
sel.addRange(range);
|
|
|
|
testing.expectEqual(false, sel.isCollapsed);
|
|
|
|
sel.collapseToEnd();
|
|
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual(textNode, sel.anchorNode);
|
|
testing.expectEqual(15, sel.anchorOffset);
|
|
testing.expectEqual(15, sel.focusOffset);
|
|
testing.expectEqual("none", sel.direction);
|
|
}
|
|
</script>
|
|
|
|
<script id=extend>
|
|
{
|
|
const sel = window.getSelection();
|
|
const p1 = document.getElementById("p1");
|
|
const textNode = p1.firstChild;
|
|
|
|
// Start with collapsed selection
|
|
sel.collapse(textNode, 10);
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
testing.expectEqual(10, sel.anchorOffset);
|
|
testing.expectEqual("none", sel.direction);
|
|
|
|
// Extend forward
|
|
sel.extend(textNode, 15);
|
|
testing.expectEqual(false, sel.isCollapsed);
|
|
testing.expectEqual(10, sel.anchorOffset);
|
|
testing.expectEqual(15, sel.focusOffset);
|
|
testing.expectEqual("forward", sel.direction);
|
|
|
|
// Extend backward from anchor
|
|
sel.extend(textNode, 5);
|
|
testing.expectEqual(false, sel.isCollapsed);
|
|
testing.expectEqual(10, sel.anchorOffset);
|
|
testing.expectEqual(5, sel.focusOffset);
|
|
testing.expectEqual("backward", sel.direction);
|
|
|
|
// Extend to same position as anchor
|
|
sel.extend(textNode, 10);
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
testing.expectEqual(10, sel.anchorOffset);
|
|
testing.expectEqual(10, sel.focusOffset);
|
|
testing.expectEqual("none", sel.direction);
|
|
}
|
|
</script>
|
|
|
|
<script id=direction>
|
|
{
|
|
const sel = window.getSelection();
|
|
const p1 = document.getElementById("p1");
|
|
const textNode = p1.firstChild;
|
|
|
|
// Forward selection
|
|
sel.collapse(textNode, 5);
|
|
sel.extend(textNode, 10);
|
|
testing.expectEqual("forward", sel.direction);
|
|
testing.expectEqual(5, sel.anchorOffset);
|
|
testing.expectEqual(10, sel.focusOffset);
|
|
|
|
// Backward selection
|
|
sel.collapse(textNode, 10);
|
|
sel.extend(textNode, 5);
|
|
testing.expectEqual("backward", sel.direction);
|
|
testing.expectEqual(10, sel.anchorOffset);
|
|
testing.expectEqual(5, sel.focusOffset);
|
|
|
|
// None (collapsed)
|
|
sel.collapse(textNode, 7);
|
|
testing.expectEqual("none", sel.direction);
|
|
}
|
|
</script>
|
|
|
|
<script id=containsNode>
|
|
{
|
|
const sel = window.getSelection();
|
|
const nested = document.getElementById("nested");
|
|
const s1 = document.getElementById("s1");
|
|
const s2 = document.getElementById("s2");
|
|
|
|
const range = document.createRange();
|
|
range.selectNodeContents(nested);
|
|
|
|
sel.removeAllRanges();
|
|
sel.addRange(range);
|
|
|
|
// Partial containment
|
|
testing.expectEqual(true, sel.containsNode(s1, true));
|
|
testing.expectEqual(true, sel.containsNode(s2, true));
|
|
testing.expectEqual(true, sel.containsNode(nested, true));
|
|
|
|
// Node outside selection
|
|
const p1 = document.getElementById("p1");
|
|
testing.expectEqual(false, sel.containsNode(p1, false));
|
|
testing.expectEqual(false, sel.containsNode(p1, true));
|
|
}
|
|
</script>
|
|
|
|
|
|
<script id=deleteFromDocument>
|
|
{
|
|
const sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
|
|
const p1 = document.getElementById("p1");
|
|
const textNode = p1.firstChild;
|
|
const originalText = textNode.textContent;
|
|
|
|
const range = document.createRange();
|
|
range.setStart(textNode, 4);
|
|
range.setEnd(textNode, 15);
|
|
|
|
sel.removeAllRanges();
|
|
sel.addRange(range);
|
|
|
|
sel.deleteFromDocument();
|
|
|
|
// Text should be deleted
|
|
const expectedText = originalText.slice(0, 4) + originalText.slice(15);
|
|
testing.expectEqual(expectedText, textNode.textContent);
|
|
|
|
// Selection should be collapsed at deletion point
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
|
|
// Restore original text for other tests
|
|
textNode.textContent = originalText;
|
|
}
|
|
</script>
|
|
|
|
<script id=typeProperty>
|
|
{
|
|
const sel = window.getSelection();
|
|
const p1 = document.getElementById("p1");
|
|
const textNode = p1.firstChild;
|
|
|
|
// None type
|
|
sel.removeAllRanges();
|
|
testing.expectEqual("None", sel.type);
|
|
|
|
// Caret type (collapsed)
|
|
sel.collapse(textNode, 5);
|
|
testing.expectEqual("Caret", sel.type);
|
|
|
|
// Range type (not collapsed)
|
|
sel.extend(textNode, 10);
|
|
testing.expectEqual("Range", sel.type);
|
|
}
|
|
</script>
|
|
|
|
<script id=selectAllChildren>
|
|
{
|
|
const sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
|
|
const nested = document.getElementById("nested");
|
|
const s1 = document.getElementById("s1");
|
|
const s2 = document.getElementById("s2");
|
|
|
|
// Select all children of nested div
|
|
sel.selectAllChildren(nested);
|
|
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual("Range", sel.type);
|
|
testing.expectEqual(false, sel.isCollapsed);
|
|
|
|
// Anchor and focus should be on the parent node
|
|
testing.expectEqual(nested, sel.anchorNode);
|
|
testing.expectEqual(nested, sel.focusNode);
|
|
|
|
// Should start at offset 0 (before first child)
|
|
testing.expectEqual(0, sel.anchorOffset);
|
|
|
|
const childrenCount = nested.childNodes.length;
|
|
|
|
// Should end at offset equal to number of children (after last child)
|
|
testing.expectEqual(childrenCount, sel.focusOffset);
|
|
|
|
// Direction should be forward
|
|
testing.expectEqual("forward", sel.direction);
|
|
|
|
// Should not fully contain the parent itself
|
|
testing.expectEqual(false, sel.containsNode(nested, false));
|
|
|
|
// But should partially contain the parent
|
|
testing.expectEqual(true, sel.containsNode(nested, true));
|
|
|
|
// Verify the range
|
|
const range = sel.getRangeAt(0);
|
|
testing.expectEqual(nested, range.startContainer);
|
|
testing.expectEqual(nested, range.endContainer);
|
|
testing.expectEqual(0, range.startOffset);
|
|
testing.expectEqual(childrenCount, range.endOffset);
|
|
}
|
|
</script>
|
|
|
|
<script id=selectAllChildrenEmpty>
|
|
{
|
|
const sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
|
|
// Create an empty element
|
|
const empty = document.createElement("div");
|
|
document.body.appendChild(empty);
|
|
|
|
// Select all children of empty element
|
|
sel.selectAllChildren(empty);
|
|
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual("Caret", sel.type); // Collapsed because no children
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
testing.expectEqual(empty, sel.anchorNode);
|
|
testing.expectEqual(0, sel.anchorOffset);
|
|
testing.expectEqual(0, sel.focusOffset);
|
|
|
|
// Clean up
|
|
document.body.removeChild(empty);
|
|
}
|
|
</script>
|
|
|
|
<script id=selectAllChildrenReplacesSelection>
|
|
{
|
|
const sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
|
|
// Start with an existing selection
|
|
const p1 = document.getElementById("p1");
|
|
sel.selectAllChildren(p1);
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual(p1, sel.anchorNode);
|
|
|
|
// selectAllChildren should replace the existing selection
|
|
const p2 = document.getElementById("p2");
|
|
sel.selectAllChildren(p2);
|
|
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual(p2, sel.anchorNode);
|
|
testing.expectEqual(p2, sel.focusNode);
|
|
|
|
// Verify old selection is gone
|
|
const range = sel.getRangeAt(0);
|
|
testing.expectEqual(p2, range.startContainer);
|
|
testing.expectEqual(false, p1 == range.startContainer);
|
|
}
|
|
</script>
|
|
|
|
<script id=setBaseAndExtent>
|
|
{
|
|
const sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
|
|
const p1 = document.getElementById("p1");
|
|
const textNode = p1.firstChild;
|
|
|
|
// Forward selection (anchor before focus)
|
|
sel.setBaseAndExtent(textNode, 4, textNode, 15);
|
|
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual("Range", sel.type);
|
|
testing.expectEqual(false, sel.isCollapsed);
|
|
testing.expectEqual(textNode, sel.anchorNode);
|
|
testing.expectEqual(4, sel.anchorOffset);
|
|
testing.expectEqual(textNode, sel.focusNode);
|
|
testing.expectEqual(15, sel.focusOffset);
|
|
testing.expectEqual("forward", sel.direction);
|
|
|
|
// Backward selection (anchor after focus)
|
|
sel.setBaseAndExtent(textNode, 15, textNode, 4);
|
|
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual("Range", sel.type);
|
|
testing.expectEqual(textNode, sel.anchorNode);
|
|
testing.expectEqual(15, sel.anchorOffset);
|
|
testing.expectEqual(textNode, sel.focusNode);
|
|
testing.expectEqual(4, sel.focusOffset);
|
|
testing.expectEqual("backward", sel.direction);
|
|
|
|
// Collapsed selection (anchor equals focus)
|
|
sel.setBaseAndExtent(textNode, 10, textNode, 10);
|
|
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual("Caret", sel.type);
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
testing.expectEqual(10, sel.anchorOffset);
|
|
testing.expectEqual(10, sel.focusOffset);
|
|
testing.expectEqual("none", sel.direction);
|
|
|
|
// Across different nodes
|
|
const p2 = document.getElementById("p2");
|
|
const textNode2 = p2.firstChild;
|
|
|
|
sel.setBaseAndExtent(textNode, 4, textNode2, 5);
|
|
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual(textNode, sel.anchorNode);
|
|
testing.expectEqual(4, sel.anchorOffset);
|
|
testing.expectEqual(textNode2, sel.focusNode);
|
|
testing.expectEqual(5, sel.focusOffset);
|
|
testing.expectEqual("forward", sel.direction);
|
|
|
|
// Should replace existing selection
|
|
sel.setBaseAndExtent(textNode, 0, textNode, 3);
|
|
testing.expectEqual(1, sel.rangeCount);
|
|
testing.expectEqual(0, sel.anchorOffset);
|
|
testing.expectEqual(3, sel.focusOffset);
|
|
}
|
|
</script>
|
|
|
|
<script id=selectionChangeEvent>
|
|
{
|
|
const sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
let eventCount = 0;
|
|
let lastEvent = null;
|
|
|
|
const listener = (e) => {
|
|
eventCount++;
|
|
lastEvent = e;
|
|
};
|
|
document.addEventListener('selectionchange', listener);
|
|
|
|
const p1 = document.getElementById("p1");
|
|
const textNode = p1.firstChild;
|
|
const nested = document.getElementById("nested");
|
|
|
|
sel.collapse(textNode, 5);
|
|
sel.extend(textNode, 10);
|
|
sel.collapseToStart();
|
|
sel.collapseToEnd();
|
|
sel.removeAllRanges();
|
|
const range = document.createRange();
|
|
range.setStart(textNode, 4);
|
|
range.setEnd(textNode, 15);
|
|
sel.addRange(range);
|
|
sel.removeRange(range);
|
|
const newRange = document.createRange();
|
|
newRange.selectNodeContents(p1);
|
|
sel.addRange(newRange);
|
|
sel.removeAllRanges();
|
|
sel.selectAllChildren(nested);
|
|
sel.setBaseAndExtent(textNode, 4, textNode, 15);
|
|
sel.collapse(textNode, 5);
|
|
sel.extend(textNode, 10);
|
|
sel.deleteFromDocument();
|
|
|
|
document.removeEventListener('selectionchange', listener);
|
|
textNode.textContent = "The quick brown fox";
|
|
|
|
testing.onload(() => {
|
|
testing.expectEqual(14, eventCount);
|
|
testing.expectEqual('selectionchange', lastEvent.type);
|
|
testing.expectEqual(document, lastEvent.target);
|
|
testing.expectEqual(false, lastEvent.bubbles);
|
|
testing.expectEqual(false, lastEvent.cancelable);
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<script id=modifyCharacterForward>
|
|
{
|
|
const sel = window.getSelection();
|
|
const p1 = document.getElementById("p1");
|
|
const textNode = p1.firstChild; // "The quick brown fox"
|
|
|
|
// Collapse to position 4 (after "The ")
|
|
sel.collapse(textNode, 4);
|
|
testing.expectEqual(4, sel.anchorOffset);
|
|
|
|
// Move forward one character
|
|
sel.modify("move", "forward", "character");
|
|
testing.expectEqual(5, sel.anchorOffset);
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
testing.expectEqual("none", sel.direction);
|
|
|
|
// Move forward again
|
|
sel.modify("move", "forward", "character");
|
|
testing.expectEqual(6, sel.anchorOffset);
|
|
}
|
|
</script>
|
|
|
|
<script id=modifyWordForward>
|
|
{
|
|
const sel = window.getSelection();
|
|
const p1 = document.getElementById("p1");
|
|
const textNode = p1.firstChild; // "The quick brown fox"
|
|
|
|
// Collapse to start
|
|
sel.collapse(textNode, 0);
|
|
|
|
// Move forward one word - should land at end of "The"
|
|
sel.modify("move", "forward", "word");
|
|
testing.expectEqual(3, sel.anchorOffset);
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
|
|
// Move forward again - should skip space and land at end of "quick"
|
|
sel.modify("move", "forward", "word");
|
|
testing.expectEqual(9, sel.anchorOffset);
|
|
}
|
|
</script>
|
|
|
|
<script id=modifyCharacterBackward>
|
|
{
|
|
const sel = window.getSelection();
|
|
const p1 = document.getElementById("p1");
|
|
const textNode = p1.firstChild; // "The quick brown fox"
|
|
|
|
// Collapse to position 6
|
|
sel.collapse(textNode, 6);
|
|
testing.expectEqual(6, sel.anchorOffset);
|
|
|
|
// Move backward one character
|
|
sel.modify("move", "backward", "character");
|
|
testing.expectEqual(5, sel.anchorOffset);
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
testing.expectEqual("none", sel.direction);
|
|
|
|
// Move backward again
|
|
sel.modify("move", "backward", "character");
|
|
testing.expectEqual(4, sel.anchorOffset);
|
|
}
|
|
</script>
|
|
|
|
<script id=modifyWordBackward>
|
|
{
|
|
const sel = window.getSelection();
|
|
const p1 = document.getElementById("p1");
|
|
const textNode = p1.firstChild; // "The quick brown fox"
|
|
|
|
// Collapse to end of "quick" (offset 9)
|
|
sel.collapse(textNode, 9);
|
|
|
|
// Move backward one word - should land at start of "quick"
|
|
sel.modify("move", "backward", "word");
|
|
testing.expectEqual(4, sel.anchorOffset);
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
|
|
// Move backward again - should land at start of "The"
|
|
sel.modify("move", "backward", "word");
|
|
testing.expectEqual(0, sel.anchorOffset);
|
|
}
|
|
</script>
|
|
|
|
<script id=modifyCharacterForwardFromElementNode>
|
|
{
|
|
const sel = window.getSelection();
|
|
const p1 = document.getElementById("p1");
|
|
sel.collapse(p1, 1);
|
|
|
|
testing.expectEqual(p1, sel.anchorNode);
|
|
testing.expectEqual(1, sel.anchorOffset);
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
|
|
sel.modify("move", "forward", "character");
|
|
|
|
testing.expectEqual(3, sel.anchorNode.nodeType);
|
|
testing.expectEqual(true, sel.anchorNode !== p1.firstChild);
|
|
}
|
|
</script>
|
|
|
|
<script id=modifyCharacterForwardFromElementNodeMidChildren>
|
|
{
|
|
const sel = window.getSelection();
|
|
const nested = document.getElementById("nested");
|
|
|
|
sel.collapse(nested, nested.childNodes.length);
|
|
|
|
testing.expectEqual(nested, sel.anchorNode);
|
|
testing.expectEqual(nested.childNodes.length, sel.anchorOffset);
|
|
|
|
sel.modify("move", "forward", "character");
|
|
|
|
// Must land on a text node strictly after #nested
|
|
testing.expectEqual(3, sel.anchorNode.nodeType);
|
|
testing.expectEqual(false, nested.contains(sel.anchorNode));
|
|
}
|
|
</script>
|
|
|
|
<script id=modifyWordForwardFromElementNode>
|
|
{
|
|
const sel = window.getSelection();
|
|
const p1 = document.getElementById("p1");
|
|
sel.collapse(p1, 1);
|
|
|
|
sel.modify("move", "forward", "word");
|
|
|
|
// Must land on a text node strictly after p1
|
|
testing.expectEqual(3, sel.anchorNode.nodeType);
|
|
testing.expectEqual(false, p1.contains(sel.anchorNode));
|
|
testing.expectEqual(true, sel.isCollapsed);
|
|
}
|
|
</script>
|
|
|
|
<script id=modifyCharacterForwardNewNodeOffsetNotElement>
|
|
{
|
|
const sel = window.getSelection();
|
|
const p1 = document.getElementById("p1");
|
|
|
|
sel.collapse(p1, 1);
|
|
sel.modify("move", "forward", "character");
|
|
|
|
testing.expectEqual(3, sel.anchorNode.nodeType);
|
|
}
|
|
</script>
|