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