browser_text_selection.js (5934B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 /** 8 * Test simple text selection 9 */ 10 addAccessibleTask(`<p id="p">Hello World</p>`, async (browser, accDoc) => { 11 let macDoc = accDoc.nativeInterface.QueryInterface( 12 Ci.nsIAccessibleMacInterface 13 ); 14 15 let startMarker = macDoc.getAttributeValue("AXStartTextMarker"); 16 let endMarker = macDoc.getAttributeValue("AXEndTextMarker"); 17 let range = macDoc.getParameterizedAttributeValue( 18 "AXTextMarkerRangeForUnorderedTextMarkers", 19 [startMarker, endMarker] 20 ); 21 is(stringForRange(macDoc, range), "Hello World"); 22 23 let evt = waitForMacEventWithInfo("AXSelectedTextChanged", (elem, info) => { 24 return ( 25 !info.AXTextStateSync && 26 info.AXTextStateChangeType == AXTextStateChangeTypeSelectionExtend && 27 elem.getAttributeValue("AXRole") == "AXWebArea" 28 ); 29 }); 30 await SpecialPowers.spawn(browser, [], () => { 31 let p = content.document.getElementById("p"); 32 let r = new content.Range(); 33 r.setStart(p.firstChild, 1); 34 r.setEnd(p.firstChild, 8); 35 36 let s = content.getSelection(); 37 s.addRange(r); 38 }); 39 await evt; 40 41 range = macDoc.getAttributeValue("AXSelectedTextMarkerRange"); 42 is(stringForRange(macDoc, range), "ello Wo"); 43 44 let firstWordRange = macDoc.getParameterizedAttributeValue( 45 "AXRightWordTextMarkerRangeForTextMarker", 46 startMarker 47 ); 48 is(stringForRange(macDoc, firstWordRange), "Hello"); 49 50 evt = waitForMacEventWithInfo("AXSelectedTextChanged", (elem, info) => { 51 return ( 52 !info.AXTextStateSync && 53 info.AXTextStateChangeType == AXTextStateChangeTypeSelectionExtend && 54 elem.getAttributeValue("AXRole") == "AXWebArea" 55 ); 56 }); 57 macDoc.setAttributeValue("AXSelectedTextMarkerRange", firstWordRange); 58 await evt; 59 range = macDoc.getAttributeValue("AXSelectedTextMarkerRange"); 60 is(stringForRange(macDoc, range), "Hello"); 61 62 // Collapse selection 63 evt = waitForMacEventWithInfo("AXSelectedTextChanged", (elem, info) => { 64 return ( 65 info.AXTextStateSync && 66 info.AXTextStateChangeType == AXTextStateChangeTypeSelectionMove && 67 elem.getAttributeValue("AXRole") == "AXWebArea" 68 ); 69 }); 70 await SpecialPowers.spawn(browser, [], () => { 71 let s = content.getSelection(); 72 s.collapseToEnd(); 73 }); 74 await evt; 75 }); 76 77 /** 78 * Test text selection events caused by focus change 79 */ 80 addAccessibleTask( 81 `<p> 82 Hello <a href="#" id="link">World</a>, 83 I <a href="#" style="user-select: none;" id="unselectable_link">love</a> 84 <button id="button">you</button></p>`, 85 async browser => { 86 // Set up an AXSelectedTextChanged listener here. It will get resolved 87 // on the first non-root event it encounters, so if we test its data at the end 88 // of this test it will show us the first text-selectable object that was focused, 89 // which is "link". 90 let selTextChanged = waitForMacEvent( 91 "AXSelectedTextChanged", 92 e => e.getAttributeValue("AXDOMIdentifier") != "body" 93 ); 94 95 let focusChanged = waitForMacEvent("AXFocusedUIElementChanged"); 96 await SpecialPowers.spawn(browser, [], () => { 97 content.document.getElementById("unselectable_link").focus(); 98 }); 99 let focusChangedTarget = await focusChanged; 100 is( 101 focusChangedTarget.getAttributeValue("AXDOMIdentifier"), 102 "unselectable_link", 103 "Correct event target" 104 ); 105 106 focusChanged = waitForMacEvent("AXFocusedUIElementChanged"); 107 await SpecialPowers.spawn(browser, [], () => { 108 content.document.getElementById("button").focus(); 109 }); 110 focusChangedTarget = await focusChanged; 111 is( 112 focusChangedTarget.getAttributeValue("AXDOMIdentifier"), 113 "button", 114 "Correct event target" 115 ); 116 117 focusChanged = waitForMacEvent("AXFocusedUIElementChanged"); 118 await SpecialPowers.spawn(browser, [], () => { 119 content.document.getElementById("link").focus(); 120 }); 121 focusChangedTarget = await focusChanged; 122 is( 123 focusChangedTarget.getAttributeValue("AXDOMIdentifier"), 124 "link", 125 "Correct event target" 126 ); 127 128 let selTextChangedTarget = await selTextChanged; 129 is( 130 selTextChangedTarget.getAttributeValue("AXDOMIdentifier"), 131 "link", 132 "Correct event target" 133 ); 134 } 135 ); 136 137 /** 138 * Test text selection with focus change 139 */ 140 addAccessibleTask( 141 `<p id="p">Hello <input id="input"></p>`, 142 async (browser, accDoc) => { 143 let macDoc = accDoc.nativeInterface.QueryInterface( 144 Ci.nsIAccessibleMacInterface 145 ); 146 147 let evt = waitForMacEventWithInfo("AXSelectedTextChanged", (elem, info) => { 148 return ( 149 !info.AXTextStateSync && 150 info.AXTextStateChangeType == AXTextStateChangeTypeSelectionExtend && 151 elem.getAttributeValue("AXRole") == "AXWebArea" 152 ); 153 }); 154 await SpecialPowers.spawn(browser, [], () => { 155 let p = content.document.getElementById("p"); 156 let r = new content.Range(); 157 r.setStart(p.firstChild, 1); 158 r.setEnd(p.firstChild, 3); 159 160 let s = content.getSelection(); 161 s.addRange(r); 162 }); 163 await evt; 164 165 let range = macDoc.getAttributeValue("AXSelectedTextMarkerRange"); 166 is(stringForRange(macDoc, range), "el"); 167 168 let events = Promise.all([ 169 waitForMacEvent("AXFocusedUIElementChanged"), 170 waitForMacEventWithInfo("AXSelectedTextChanged"), 171 ]); 172 await SpecialPowers.spawn(browser, [], () => { 173 content.document.getElementById("input").focus(); 174 }); 175 let [, { data }] = await events; 176 ok( 177 data.AXTextSelectionChangedFocus, 178 "have AXTextSelectionChangedFocus in event info" 179 ); 180 ok(!data.AXTextStateSync, "no AXTextStateSync in editables"); 181 is( 182 data.AXTextSelectionDirection, 183 AXTextSelectionDirectionDiscontiguous, 184 "discontigous direction" 185 ); 186 } 187 );