/* 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"; /** * Test simple text selection */ addAccessibleTask(`

Hello World

`, async (browser, accDoc) => { let macDoc = accDoc.nativeInterface.QueryInterface( Ci.nsIAccessibleMacInterface ); let startMarker = macDoc.getAttributeValue("AXStartTextMarker"); let endMarker = macDoc.getAttributeValue("AXEndTextMarker"); let range = macDoc.getParameterizedAttributeValue( "AXTextMarkerRangeForUnorderedTextMarkers", [startMarker, endMarker] ); is(stringForRange(macDoc, range), "Hello World"); let evt = waitForMacEventWithInfo("AXSelectedTextChanged", (elem, info) => { return ( !info.AXTextStateSync && info.AXTextStateChangeType == AXTextStateChangeTypeSelectionExtend && elem.getAttributeValue("AXRole") == "AXWebArea" ); }); await SpecialPowers.spawn(browser, [], () => { let p = content.document.getElementById("p"); let r = new content.Range(); r.setStart(p.firstChild, 1); r.setEnd(p.firstChild, 8); let s = content.getSelection(); s.addRange(r); }); await evt; range = macDoc.getAttributeValue("AXSelectedTextMarkerRange"); is(stringForRange(macDoc, range), "ello Wo"); let firstWordRange = macDoc.getParameterizedAttributeValue( "AXRightWordTextMarkerRangeForTextMarker", startMarker ); is(stringForRange(macDoc, firstWordRange), "Hello"); evt = waitForMacEventWithInfo("AXSelectedTextChanged", (elem, info) => { return ( !info.AXTextStateSync && info.AXTextStateChangeType == AXTextStateChangeTypeSelectionExtend && elem.getAttributeValue("AXRole") == "AXWebArea" ); }); macDoc.setAttributeValue("AXSelectedTextMarkerRange", firstWordRange); await evt; range = macDoc.getAttributeValue("AXSelectedTextMarkerRange"); is(stringForRange(macDoc, range), "Hello"); // Collapse selection evt = waitForMacEventWithInfo("AXSelectedTextChanged", (elem, info) => { return ( info.AXTextStateSync && info.AXTextStateChangeType == AXTextStateChangeTypeSelectionMove && elem.getAttributeValue("AXRole") == "AXWebArea" ); }); await SpecialPowers.spawn(browser, [], () => { let s = content.getSelection(); s.collapseToEnd(); }); await evt; }); /** * Test text selection events caused by focus change */ addAccessibleTask( `

Hello World, I love

`, async (browser, accDoc) => { // Set up an AXSelectedTextChanged listener here. It will get resolved // on the first non-root event it encounters, so if we test its data at the end // of this test it will show us the first text-selectable object that was focused, // which is "link". let selTextChanged = waitForMacEvent( "AXSelectedTextChanged", e => e.getAttributeValue("AXDOMIdentifier") != "body" ); let focusChanged = waitForMacEvent("AXFocusedUIElementChanged"); await SpecialPowers.spawn(browser, [], () => { content.document.getElementById("unselectable_link").focus(); }); let focusChangedTarget = await focusChanged; is( focusChangedTarget.getAttributeValue("AXDOMIdentifier"), "unselectable_link", "Correct event target" ); focusChanged = waitForMacEvent("AXFocusedUIElementChanged"); await SpecialPowers.spawn(browser, [], () => { content.document.getElementById("button").focus(); }); focusChangedTarget = await focusChanged; is( focusChangedTarget.getAttributeValue("AXDOMIdentifier"), "button", "Correct event target" ); focusChanged = waitForMacEvent("AXFocusedUIElementChanged"); await SpecialPowers.spawn(browser, [], () => { content.document.getElementById("link").focus(); }); focusChangedTarget = await focusChanged; is( focusChangedTarget.getAttributeValue("AXDOMIdentifier"), "link", "Correct event target" ); let selTextChangedTarget = await selTextChanged; is( selTextChangedTarget.getAttributeValue("AXDOMIdentifier"), "link", "Correct event target" ); } ); /** * Test text selection with focus change */ addAccessibleTask( `

Hello

`, async (browser, accDoc) => { let macDoc = accDoc.nativeInterface.QueryInterface( Ci.nsIAccessibleMacInterface ); let evt = waitForMacEventWithInfo("AXSelectedTextChanged", (elem, info) => { return ( !info.AXTextStateSync && info.AXTextStateChangeType == AXTextStateChangeTypeSelectionExtend && elem.getAttributeValue("AXRole") == "AXWebArea" ); }); await SpecialPowers.spawn(browser, [], () => { let p = content.document.getElementById("p"); let r = new content.Range(); r.setStart(p.firstChild, 1); r.setEnd(p.firstChild, 3); let s = content.getSelection(); s.addRange(r); }); await evt; let range = macDoc.getAttributeValue("AXSelectedTextMarkerRange"); is(stringForRange(macDoc, range), "el"); let events = Promise.all([ waitForMacEvent("AXFocusedUIElementChanged"), waitForMacEventWithInfo("AXSelectedTextChanged"), ]); await SpecialPowers.spawn(browser, [], () => { content.document.getElementById("input").focus(); }); let [, { data }] = await events; ok( data.AXTextSelectionChangedFocus, "have AXTextSelectionChangedFocus in event info" ); ok(!data.AXTextStateSync, "no AXTextStateSync in editables"); is( data.AXTextSelectionDirection, AXTextSelectionDirectionDiscontiguous, "discontigous direction" ); } );