<script>
// Call the testing methods from the parent window var is = parent.is; var ok = parent.ok;
// spin() spins the event loop for two cycles, giving time for
// selectionchange events to be fired, and handled by our listeners.
function spin() {
return new Promise(function(a) {
parent.SimpleTest.executeSoon(function() {
parent.SimpleTest.executeSoon(a)
});
});
}
document.addEventListener('selectstart', function(aEvent) {
console.log("originaltarget", aEvent.originalTarget, "new", selectstartTarget);
is(aEvent.originalTarget, selectstartTarget, "The original target of selectstart");
selectstartTarget = null;
console.log(selectstart);
selectstart++;
if (cancel) {
aEvent.preventDefault();
}
});
document.addEventListener('selectionchange', function(aEvent) {
ok(isProperSelectionChangeTarget(aEvent.target), "The target of selectionchange should be one of document, input, or textarea");
console.log(selectionchange);
selectionchange++;
});
elt("input").addEventListener('selectionchange', function(aEvent) {
is (aEvent.originalTarget, elt("input"), "The original target of selectionchange should be the input");
console.log(inputSelectionchange);
inputSelectionchange++;
});
elt("textarea").addEventListener('selectionchange', function(aEvent) {
is (aEvent.originalTarget, elt("textarea"), "The original target of selectionchange should be the textarea");
console.log(textareaSelectionchange);
textareaSelectionchange++;
});
is(
selectstart,
selectstartOnDocument,
`${
aTestDescription
}: "selectstart" event on the document node should be fired ${
selectstartOnDocument
} times ${aSituationDescription}`
);
is(
selectionchange,
selectionchangeOnDocument,
`${
aTestDescription
}: "selectionchange" event on the document node should be fired ${
selectionchangeOnDocument
} times ${aSituationDescription}`
);
is(
inputSelectionchange,
selectionchangeOnInput,
`${
aTestDescription
}: "selectionchange" event on the <input> should be fired ${
selectionchangeOnInput
} times ${aSituationDescription}`
);
is(
textareaSelectionchange,
selectionchangeOnTextarea,
`${
aTestDescription
}: "selectionchange" event on the <textarea> should be fired ${
selectionchangeOnTextarea
} times ${aSituationDescription}`
);
}
var selection = document.getSelection();
function isCollapsed() {
is(selection.isCollapsed, true, "Selection is collapsed");
}
function isNotCollapsed() {
is(selection.isCollapsed, false, "Selection is not collapsed");
}
// Make sure setting the element to contentEditable doesn't cause any selectionchange events
await testWithSettingContentEditableAttribute( "Setting contenteditable attribute to true of
should not change selection",
elt("ce"),
true,
{}
);
// Make sure setting the element to not be contentEditable doesn't cause any selectionchange events
await testWithSettingContentEditableAttribute( 'Setting contenteditable attribute to false of
should not change selection',
elt("ce"),
false,
{}
);
// Now make the div contentEditable and proceed with the test
await testWithSettingContentEditableAttribute( 'Setting contenteditable attribute to true of
should not change selection',
elt("ce"),
true,
{}
);
// Focus the contenteditable text
await testWithSynthesizingMouse( 'Clicking in
// Move the selection to the right, this should only fire selectstart once
selectstartTarget = elt("ce").firstChild;
await testWithSynthesizingKey( 'Synthesizing Shift-ArrowRight to select a character in the text node of
should start to select again and change selection', "KEY_ArrowRight",
{ shiftKey: true },
{ selectstartOnDocument: 1, selectionchangeOnDocument: 1 }
);
isNotCollapsed();
await testWithSynthesizingKey( 'Synthesizing Shift-ArrowRight again to select 2 characters in the text node of
// Move it back so that the selection is empty again
await testWithSynthesizingKey( 'Synthesizing Shift-ArrowLeft to shrink selection in the text node of
should change selection', "KEY_ArrowLeft",
{ shiftKey: true },
{ selectionchangeOnDocument: 1 }
);
isNotCollapsed();
await testWithSynthesizingKey( 'Synthesizing Shift-ArrowLeft again to collapse selection in the text node of
// Going from empty to non-empty should fire selectstart again
selectstartTarget = elt("ce").firstChild;
await testWithSynthesizingKey( 'Synthesizing Shift-ArrowLeft again to select a character on the other side in the text node of
should start to select and change selection', "KEY_ArrowLeft",
{ shiftKey: true },
{ selectstartOnDocument: 1, selectionchangeOnDocument: 1 }
);
isNotCollapsed();
async function testWithSynthesizingMouseDrag(
aDescription,
aElement,
aSelectstartTarget
) {
// Select a region
await testWithSynthesizingMouse(
`Pressing left mouse button ${
aDescription
} should not start to select but should change selection`,
aElement,
{ x: 50 }, "mousedown",
{ selectionchangeOnDocument: 1 }
);
isCollapsed();
selectstartTarget = aSelectstartTarget;
await testWithSynthesizingMouse(
`Dragging mouse to right to extend selection ${
aDescription
} should start to select and change selection`,
aElement,
{ x: 100 }, "mousemove",
{ selectstartOnDocument: 1, selectionchangeOnDocument: 1 }
);
isNotCollapsed();
// Moving it more shouldn't trigger a start (move back to empty)
await testWithSynthesizingMouse(
`Dragging mouse to left to shrink selection ${
aDescription
} should change selection`,
aElement,
{ x: 75 }, "mousemove",
{ selectionchangeOnDocument: 1 }
);
isNotCollapsed();
await testWithSynthesizingMouse(
`Dragging mouse to left to collapse selection ${
aDescription
} should change selection`,
aElement,
{ x: 50 }, "mousemove",
{ selectionchangeOnDocument: 1 }
);
isCollapsed();
// Wiggling the mouse a little such that it doesn't select any
// characters shouldn't trigger a selection
await testWithSynthesizingMouse(
`Dragging mouse to bottom a bit ${
aDescription
} should not cause selection change`,
aElement,
{ x: 50, y: 11 }, "mousemove",
{}
);
isCollapsed();
// Moving the mouse again from an empty selection should trigger a
// selectstart
selectstartTarget = aSelectstartTarget;
await testWithSynthesizingMouse(
`Dragging mouse to left to extend selection ${
aDescription
} should start to select and change selection`,
aElement,
{ x: 25 }, "mousemove",
{ selectstartOnDocument: 1, selectionchangeOnDocument: 1 }
);
isNotCollapsed();
// Releasing the mouse shouldn't do anything
await testWithSynthesizingMouse(
`Releasing left mouse button to stop dragging ${
aDescription
} should not change selection`,
aElement,
{ x: 25 }, "mouseup",
{}
);
isNotCollapsed();
// And neither should moving your mouse around when the mouse
// button isn't pressed
await testWithSynthesizingMouse(
`Just moving mouse to right ${
aDescription
} should not start to select nor change selection`,
aElement,
{ x: 50 }, "mousemove",
{}
);
isNotCollapsed();
// Clicking in an random location should move the selection, but not perform a
// selectstart
await testWithSynthesizingMouse(
`Clicking to collapse selection ${
aDescription
} should cause only selection change`,
aElement,
{ x: 50 }, "click",
{ selectionchangeOnDocument: 1 }
);
isCollapsed();
// Clicking there again should do nothing
await testWithSynthesizingMouse(
`Clicking same position again ${
aDescription
} should not change selection`,
aElement,
{ x: 50 }, "click",
{}
);
isCollapsed();
// Selecting a region, and canceling the selectstart should mean that the
// selection remains collapsed
await testWithSynthesizingMouse(
`Pressing left mouse button on different character to move caret ${
aDescription
} should cause only selection change`,
aElement,
{ x: 75 }, "mousedown",
{ selectionchangeOnDocument: 1 }
);
isCollapsed();
cancel = true;
selectstartTarget = aSelectstartTarget;
await testWithSynthesizingMouse(
`Moving mouse to right to extend selection but selectstart event will be prevented default ${
aDescription
} should start to select and change selection`,
aElement,
{ x: 100 }, "mousemove",
{ selectstartOnDocument: 1, selectionchangeOnDocument: 1 }
);
isCollapsed();
await testWithSynthesizingMouse(
`Releasing the left mouse button after dragging but selectstart was prevented the default ${
aDescription
} should not change selection`,
aElement,
{ x: 100 }, "mouseup",
{}
);
isCollapsed();
}
// Should work both on normal
await testWithSynthesizingMouseDrag( "on the text node in the non-editable
",
elt("inner"),
elt("inner").firstChild
);
// and contenteditable fields
await testWithSynthesizingMouseDrag( 'on the text node in the editable
',
elt("ce"),
elt("ce").firstChild
);
// and fields with elements in them
await testWithSynthesizingMouseDrag( "on the text node in the non-editable
reset();
// Select all should fire both selectstart and change
selectstartTarget = document.body;
await testWithSynthesizingKey( "Select All when no editor has focus should start to select and select all content", "a", { accelKey: true },
{ selectstartOnDocument: 1, selectionchangeOnDocument: 1 }
);
isNotCollapsed();
// Clear the selection
await testWithSynthesizingMouse( "Clicking in the non-editable
// Even if we already have a selection
await testWithSynthesizingMouse( "Pressing the left mouse button in non-editable
should change selection",
elt("inner"),
{ x: 75 }, "mousedown",
{ selectionchangeOnDocument: 1 }
);
isCollapsed();
selectstartTarget = elt("inner").firstChild;
await testWithSynthesizingMouse( "Dragging mouse to right to extend selection should start and change selection",
elt("inner"),
{ x: 100 }, "mousemove",
{ selectstartOnDocument: 1, selectionchangeOnDocument: 1 }
);
isNotCollapsed();
await testWithSynthesizingMouse( "Releasing the left mouse button should not change selection",
elt("inner"),
{ x: 100 }, "mouseup",
{}
);
isNotCollapsed();
selectstartTarget = document.body;
await testWithSynthesizingKey( "Select All when no editor has focus should start to select and select all content (again)", "a",
{ accelKey: true },
{ selectstartOnDocument: 1, selectionchangeOnDocument: 1 }
);
isNotCollapsed();
// Clear the selection
await testWithSynthesizingMouse( "Clicking in the non-editable
// Make sure that a synthesized selection change doesn't fire selectstart
getSelection().removeAllRanges();
await spin();
is(
selectstart,
0, "Selection.removeAllRanges() should not cause selectstart event"
);
is(
selectionchange,
1, "Selection.removeAllRanges() should cause selectionchange event"
);
reset();
isCollapsed();
await (async function test_Selection_selectNode() {
const range = document.createRange();
range.selectNode(elt("inner"));
getSelection().addRange(range);
await spin();
is(
selectstart,
0, "Selection.addRange() should not cause selectstart event"
);
is(
selectionchange,
1, "Selection.addRange() should cause selectionchange event"
);
reset();
isNotCollapsed();
})();
// Change the range, without replacing
await (async function test_Selection_getRangeAt_selectNode() {
getSelection().getRangeAt(0).selectNode(elt("ce"));
await spin();
is(
selectstart,
0, "Selection.getRangeAt(0).selectNode() should not cause selectstart event"
);
is(
selectionchange,
1, "Selection.getRangeAt(0).selectNode() should cause selectionchange event"
);
reset();
isNotCollapsed();
})();
// Remove the range
getSelection().removeAllRanges();
await spin();
is(
selectstart,
0, "Selection.removeAllRanges() should not cause selectstart event (again)"
);
is(
selectionchange,
1, "Selection.removeAllRanges() should cause selectionchange event (again)"
);
reset();
isCollapsed();
for (const textControl of [elt("input"), elt("textarea")]) {
await UpdateSelectEventsOnTextControlsPref({
selectstart: false,
selectionchange: false,
});
// Without the dom.select_events.textcontrols.enabled pref,
// pressing the mouse shouldn't do anything.
await testWithSynthesizingMouse(
`Pressing the left mouse button in <${
textControl.tagName.toLocaleLowerCase()
}> should change selection of the document`,
textControl,
{ x: 50 }, "mousedown",
{
selectionchangeOnDocument: 1,
}
);
// Releasing the mouse shouldn't do anything
await testWithSynthesizingMouse(
`Releasing the left mouse button in <${
textControl.tagName.toLocaleLowerCase()
}> should not change any selection`,
textControl,
{ x: 50 }, "mouseup",
{}
);
for (const selectstart of [1, 0]) {
await UpdateSelectEventsOnTextControlsPref({
selectstart,
selectionchange: true,
});
const selectstartEventSetting = `selectstart in text controls is ${
selectstart ? "enabled" : "disabled"
}`;
await testWithSynthesizingMouse(
`Pressing the left mouse button in <${
textControl.tagName.toLocaleLowerCase()
}> should change selection (${selectstartEventSetting})`,
textControl,
{ x: 40 }, "mousedown",
{
selectionchangeOnDocument: 1,
selectionchangeOnInput: isInput ? 1 : 0,
selectionchangeOnTextarea: isInput ? 0 : 1,
}
);
selectstartTarget = textControl;
await testWithSynthesizingMouse(
`Dragging mouse to right to extend selection in <${
textControl.tagName.toLocaleLowerCase()
}> should start to select and change selection (${
selectstartEventSetting
})`,
textControl,
{ x: 100 }, "mousemove",
{
selectstartOnDocument: selectstart,
selectionchangeOnDocument: 1,
selectionchangeOnInput: isInput ? 1 : 0,
selectionchangeOnTextarea: isInput ? 0 : 1,
}
);
// Moving it more shouldn't trigger a start (move back to empty)
await testWithSynthesizingMouse(
`Dragging mouse to left to shrink selection in <${
textControl.tagName.toLocaleLowerCase()
}> should change selection (${selectstartEventSetting})`,
textControl,
{ x: 75 }, "mousemove",
{
selectionchangeOnDocument: 1,
selectionchangeOnInput: isInput ? 1 : 0,
selectionchangeOnTextarea: isInput ? 0 : 1,
}
);
await testWithSynthesizingMouse(
`Dragging mouse to left to collapse selection in <${
textControl.tagName.toLocaleLowerCase()
}> should change selection (${selectstartEventSetting})`,
textControl,
{ x: 40 }, "mousemove",
{
selectionchangeOnDocument: 1,
selectionchangeOnInput: isInput ? 1 : 0,
selectionchangeOnTextarea: isInput ? 0 : 1,
}
);
// Wiggling the mouse a little such that it doesn't select any
// characters shouldn't trigger a selection
await testWithSynthesizingMouse(
`Pressing the left mouse button at caret in <${
textControl.tagName.toLocaleLowerCase()
}> should not change selection (${selectstartEventSetting})`,
textControl,
{
x: 40,
y: 11,
}, "mousemove",
{}
);
// Moving the mouse again from an empty selection should trigger a
// selectstart
selectstartTarget = textControl;
await testWithSynthesizingMouse(
`Dragging mouse to left to extend selection in <${
textControl.tagName.toLocaleLowerCase()
}> should start to select and change selection (${
selectstartEventSetting
})`,
textControl,
{ x: 25 }, "mousemove",
{
selectstartOnDocument: selectstart,
selectionchangeOnDocument: 1,
selectionchangeOnInput: isInput ? 1 : 0,
selectionchangeOnTextarea: isInput ? 0 : 1,
}
);
// Releasing the mouse shouldn't do anything
await testWithSynthesizingMouse(
`Releasing the left mouse button in <${
textControl.tagName.toLocaleLowerCase()
}> should not change selection (${selectstartEventSetting})`,
textControl,
{ x: 25 }, "mouseup",
{}
);
// And neither should moving your mouse around when the mouse
// button isn't pressed
await testWithSynthesizingMouse(
`Just moving mouse to right in <${
textControl.tagName.toLocaleLowerCase()
}> should not start to select nor change selection (${
selectstartEventSetting
})`,
textControl,
{ x: 50 }, "mousemove",
{}
);
// Clicking in an random location should move the selection, but
// not perform a selectstart
await testWithSynthesizingMouse(
`Clicking in <${
textControl.tagName.toLocaleLowerCase()
}> should change selection, but should not start selection (${
selectstartEventSetting
})`,
textControl,
{ x: 50 }, "click",
{
selectionchangeOnDocument: 1,
selectionchangeOnInput: isInput ? 1 : 0,
selectionchangeOnTextarea: isInput ? 0 : 1,
}
);
// Clicking there again should do nothing
await testWithSynthesizingMouse(
`Clicking at caret in <${
textControl.tagName.toLocaleLowerCase()
}> should not change selection (${selectstartEventSetting})`,
textControl,
{ x: 50 }, "click",
{}
);
// Selecting a region, and canceling the selectstart should mean that the
// selection remains collapsed
await testWithSynthesizingMouse(
`Pressing the left mouse button at different character in <${
textControl.tagName.toLocaleLowerCase()
}> should change selection (${selectstartEventSetting})`,
textControl,
{ x: 75 }, "mousedown",
{
selectionchangeOnDocument: 1,
selectionchangeOnInput: isInput ? 1 : 0,
selectionchangeOnTextarea: isInput ? 0 : 1,
}
);
cancel = true;
selectstartTarget = textControl;
await testWithSynthesizingMouse(
`Dragging mouse to right to extend selection in <${
textControl.tagName.toLocaleLowerCase()
}> but the default of selectstart is prevented should cause selectstart and selectionchange events (${
selectstartEventSetting
})`,
textControl,
{ x: 100 }, "mousemove",
{
selectstartOnDocument: selectstart,
selectionchangeOnDocument: 1,
selectionchangeOnInput: isInput ? 1 : 0,
selectionchangeOnTextarea: isInput ? 0 : 1,
}
);
await testWithSynthesizingMouse(
`Releasing the left mouse button in <${
textControl.tagName.toLocaleLowerCase()
}> should not cause changing selection (${selectstartEventSetting})`,
textControl,
{ x: 100 }, "mouseup",
{}
);
}
}
// Marking the input and textarea as display: none and then as visible again
// shouldn't trigger any changes, although the nodes will be re-framed
for (const textControl of [elt("input"), elt("textarea")]) {
await (async function test_set_display_of_text_control_to_none() {
textControl.setAttribute("style", "display: none;");
await spin();
checkEventCounts(
`Setting display of <${
textControl.tagName.toLocaleLowerCase()
}> to none`, "",
{}
);
reset();
})();
// When selection is at the end of contentEditable's content,
// clearing the content should trigger selection events.
await (async function test_removing_contenteditable() {
const savedContent = elt("ce").innerHTML;
document.getSelection().setBaseAndExtent(elt("ce"), 1, elt("ce"), 1);
await spin();
reset();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.