/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict" ;
function selectedTextEventPromises(stateChangeType) {
return [
waitForMacEventWithInfo(
"AXSelectedTextChanged" , (elem, info) => {
return (
info.AXTextStateChangeType == stateChangeType &&
elem.getAttributeValue(
"AXDOMIdentifier" ) ==
"body"
);
}),
waitForMacEventWithInfo(
"AXSelectedTextChanged" , (elem, info) => {
return (
info.AXTextStateChangeType == stateChangeType &&
elem.getAttributeValue(
"AXDOMIdentifier" ) ==
"input"
);
}),
];
}
async
function testInput(browser, accDoc) {
let input = getNativeInterface(accDoc,
"input" );
is(input.getAttributeValue(
"AXDescription" ),
"Name" ,
"Correct input label" );
is(input.getAttributeValue(
"AXTitle" ),
"" ,
"Correct input title" );
is(input.getAttributeValue(
"AXValue" ),
"Elmer Fudd" ,
"Correct input value" );
is(
input.getAttributeValue(
"AXNumberOfCharacters" ),
10,
"Correct length of value"
);
ok(input.attributeNames.includes(
"AXSelectedText" ),
"Has AXSelectedText" );
ok(
input.attributeNames.includes(
"AXSelectedTextRange" ),
"Has AXSelectedTextRange"
);
let evt = Promise.all([
waitForMacEvent(
"AXFocusedUIElementChanged" ,
"input" ),
...selectedTextEventPromises(AXTextStateChangeTypeSelectionMove),
]);
await SpecialPowers.spawn(browser, [], () => {
content.document.getElementById(
"input" ).focus();
});
await evt;
evt = Promise.all(
selectedTextEventPromises(AXTextStateChangeTypeSelectionExtend)
);
await SpecialPowers.spawn(browser, [], () => {
let elm = content.document.getElementById(
"input" );
if (elm.setSelectionRange) {
elm.setSelectionRange(6, 9);
}
else {
let r =
new content.Range();
let textNode = elm.firstElementChild.firstChild;
r.setStart(textNode, 6);
r.setEnd(textNode, 9);
let s = content.getSelection();
s.removeAllRanges();
s.addRange(r);
}
});
await evt;
is(
input.getAttributeValue(
"AXSelectedText" ),
"Fud" ,
"Correct text is selected"
);
Assert .deepEqual(
input.getAttributeValue(
"AXSelectedTextRange" ),
[6, 3],
"correct range selected"
);
ok(
input.isAttributeSettable(
"AXSelectedTextRange" ),
"AXSelectedTextRange is settable"
);
evt = Promise.all(
selectedTextEventPromises(AXTextStateChangeTypeSelectionExtend)
);
input.setAttributeValue(
"AXSelectedTextRange" , NSRange(1, 7));
await evt;
Assert .deepEqual(
input.getAttributeValue(
"AXSelectedTextRange" ),
[1, 7],
"correct range selected"
);
is(
input.getAttributeValue(
"AXSelectedText" ),
"lmer Fu" ,
"Correct text is selected"
);
let domSelection = await SpecialPowers.spawn(browser, [], () => {
let elm = content.document.querySelector(
"input#input" );
if (elm) {
return elm.value.substring(elm.selectionStart, elm.selectionEnd);
}
return content.getSelection().toString();
});
is(domSelection,
"lmer Fu" ,
"correct DOM selection" );
is(
input.getParameterizedAttributeValue(
"AXStringForRange" , NSRange(3, 5)),
"er Fu" ,
"AXStringForRange works"
);
}
/**
* Input selection test
*/
addAccessibleTask(
`<input aria-label=
"Name" id=
"input" value=
"Elmer Fudd" >`,
testInput
);
/**
* contenteditable selection test
*/
addAccessibleTask(
`<div aria-label=
"Name" tabindex=
"0" role=
"textbox" aria-multiline=
"true" id=
"input" co
ntenteditable>
<p>Elmer Fudd</p>
</div>`,
testInput
);
/**
* test contenteditable with selection that extends past editable part
*/
addAccessibleTask(
`<span aria-label="Name"
tabindex="0"
role="textbox"
id="input"
contenteditable>Elmer Fudd</span> <span id="notinput" >is the name</span>`,
async (browser, accDoc) => {
let evt = Promise.all([
waitForMacEvent("AXFocusedUIElementChanged" , "input" ),
waitForMacEvent("AXSelectedTextChanged" , "body" ),
waitForMacEvent("AXSelectedTextChanged" , "input" ),
]);
await SpecialPowers.spawn(browser, [], () => {
content.document.getElementById("input" ).focus();
});
await evt;
evt = waitForEvent(EVENT_TEXT_CARET_MOVED);
await SpecialPowers.spawn(browser, [], () => {
let input = content.document.getElementById("input" );
let notinput = content.document.getElementById("notinput" );
let r = new content.Range();
r.setStart(input.firstChild, 4);
r.setEnd(notinput.firstChild, 6);
let s = content.getSelection();
s.removeAllRanges();
s.addRange(r);
});
await evt;
let input = getNativeInterface(accDoc, "input" );
is(
input.getAttributeValue("AXSelectedText" ),
"r Fudd" ,
"Correct text is selected in #input"
);
is(
stringForRange(
input,
input.getAttributeValue("AXSelectedTextMarkerRange" )
),
"r Fudd is the" ,
"Correct text is selected in document"
);
}
);
/**
* test nested content editables and their ancestor getters.
*/
addAccessibleTask(
`<div id="outer" role="textbox" contenteditable="true" >
<p id="p" >Bob <a href="#" id="link" >Loblaw's
<div id="inner" role="textbox" contenteditable="true" >
Law <a href="#" id="inner_link" >Blog</a>
</div>
</div>`,
(browser, accDoc) => {
let link = getNativeInterface(accDoc, "link" );
let innerLink = getNativeInterface(accDoc, "inner_link" );
let idmatches = (elem, id) => {
is(elem.getAttributeValue("AXDOMIdentifier" ), id, "Matches ID" );
};
idmatches(link.getAttributeValue("AXEditableAncestor" ), "outer" );
idmatches(link.getAttributeValue("AXFocusableAncestor" ), "outer" );
idmatches(link.getAttributeValue("AXHighestEditableAncestor" ), "outer" );
idmatches(innerLink.getAttributeValue("AXEditableAncestor" ), "inner" );
idmatches(innerLink.getAttributeValue("AXFocusableAncestor" ), "inner" );
idmatches(
innerLink.getAttributeValue("AXHighestEditableAncestor" ),
"outer"
);
}
);
Messung V0.5 C=97 H=100 G=98
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland