mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-02-04 06:23:45 +00:00
add Selection WebAPI test
This commit is contained in:
408
src/browser/tests/selection.html
Normal file
408
src/browser/tests/selection.html
Normal file
@@ -0,0 +1,408 @@
|
|||||||
|
<!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);
|
||||||
|
testing.expectEqual(2, 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);
|
||||||
|
testing.expectEqual(2, sel.rangeCount);
|
||||||
|
|
||||||
|
sel.removeRange(range1);
|
||||||
|
testing.expectEqual(1, sel.rangeCount);
|
||||||
|
testing.expectEqual(range2, sel.getRangeAt(0));
|
||||||
|
|
||||||
|
// Removing non-existent range does nothing
|
||||||
|
sel.removeRange(range1);
|
||||||
|
testing.expectEqual(1, sel.rangeCount);
|
||||||
|
}
|
||||||
|
</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);
|
||||||
|
testing.expectEqual(2, 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("forward", 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);
|
||||||
|
|
||||||
|
// Full containment (default)
|
||||||
|
testing.expectEqual(true, sel.containsNode(s1, false));
|
||||||
|
testing.expectEqual(true, sel.containsNode(s2, false));
|
||||||
|
testing.expectEqual(false, sel.containsNode(nested, false));
|
||||||
|
|
||||||
|
// 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=multipleRanges>
|
||||||
|
{
|
||||||
|
const sel = window.getSelection();
|
||||||
|
sel.removeAllRanges();
|
||||||
|
|
||||||
|
const p1 = document.getElementById("p1");
|
||||||
|
const p2 = document.getElementById("p2");
|
||||||
|
|
||||||
|
const range1 = document.createRange();
|
||||||
|
const range2 = document.createRange();
|
||||||
|
|
||||||
|
range1.selectNodeContents(p1);
|
||||||
|
range2.selectNodeContents(p2);
|
||||||
|
|
||||||
|
sel.addRange(range1);
|
||||||
|
sel.addRange(range2);
|
||||||
|
|
||||||
|
testing.expectEqual(2, sel.rangeCount);
|
||||||
|
|
||||||
|
testing.expectEqual(p1, sel.anchorNode);
|
||||||
|
testing.expectEqual(p2, sel.focusNode);
|
||||||
|
testing.expectEqual(0, sel.anchorOffset);
|
||||||
|
testing.expectEqual(p2.childNodes.length, sel.focusOffset);
|
||||||
|
}
|
||||||
|
</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>
|
||||||
Reference in New Issue
Block a user