/* 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"; /* import-globals-from ../../mochitest/role.js */ /* import-globals-from ../../mochitest/states.js */ loadScripts( { name: "role.js", dir: MOCHITESTS_DIR }, { name: "states.js", dir: MOCHITESTS_DIR } ); async function synthFocus(browser, container, item) { let focusPromise = waitForEvent(EVENT_FOCUS, item); await invokeContentTask(browser, [container], _container => { let elm = ( content.document._testGetElementById || content.document.getElementById ).bind(content.document)(_container); elm.focus(); }); await focusPromise; } async function changeARIAActiveDescendant( browser, container, itemId, prevItemId, elementReflection ) { let expectedEvents = [[EVENT_FOCUS, itemId]]; if (prevItemId) { info("A state change of the previous item precedes the new one."); expectedEvents.push( stateChangeEventArgs(prevItemId, EXT_STATE_ACTIVE, false, true) ); } expectedEvents.push( stateChangeEventArgs(itemId, EXT_STATE_ACTIVE, true, true) ); let expectedPromise = waitForEvents(expectedEvents); await invokeContentTask( browser, [container, itemId, elementReflection], (_container, _itemId, _elementReflection) => { let getElm = ( content.document._testGetElementById || content.document.getElementById ).bind(content.document); let elm = getElm(_container); if (_elementReflection) { elm.ariaActiveDescendantElement = getElm(_itemId); } else { elm.setAttribute("aria-activedescendant", _itemId); } } ); await expectedPromise; } async function clearARIAActiveDescendant( browser, container, prevItemId, defaultId, elementReflection ) { let expectedEvents = [[EVENT_FOCUS, defaultId || container]]; if (prevItemId) { expectedEvents.push( stateChangeEventArgs(prevItemId, EXT_STATE_ACTIVE, false, true) ); } if (defaultId) { expectedEvents.push( stateChangeEventArgs(defaultId, EXT_STATE_ACTIVE, true, true) ); } let expectedPromise = waitForEvents(expectedEvents); await invokeContentTask( browser, [container, elementReflection], (_container, _elementReflection) => { let elm = ( content.document._testGetElementById || content.document.getElementById ).bind(content.document)(_container); if (_elementReflection) { elm.ariaActiveDescendantElement = null; } else { elm.removeAttribute("aria-activedescendant"); } } ); await expectedPromise; } async function insertItemNFocus( browser, container, newItemID, prevItemId, elementReflection ) { let expectedEvents = [ [EVENT_SHOW, newItemID], [EVENT_FOCUS, newItemID], ]; if (prevItemId) { info("A state change of the previous item precedes the new one."); expectedEvents.push( stateChangeEventArgs(prevItemId, EXT_STATE_ACTIVE, false, true) ); } expectedEvents.push( stateChangeEventArgs(newItemID, EXT_STATE_ACTIVE, true, true) ); let expectedPromise = waitForEvents(expectedEvents); await invokeContentTask( browser, [container, newItemID, elementReflection], (_container, _newItemID, _elementReflection) => { let elm = ( content.document._testGetElementById || content.document.getElementById ).bind(content.document)(_container); let itemElm = content.document.createElement("div"); itemElm.setAttribute("id", _newItemID); itemElm.setAttribute("role", "listitem"); itemElm.textContent = _newItemID; elm.appendChild(itemElm); if (_elementReflection) { elm.ariaActiveDescendantElement = itemElm; } else { elm.setAttribute("aria-activedescendant", _newItemID); } } ); await expectedPromise; } async function moveARIAActiveDescendantID(browser, fromID, toID) { let expectedEvents = [ [EVENT_FOCUS, toID], stateChangeEventArgs(toID, EXT_STATE_ACTIVE, true, true), ]; let expectedPromise = waitForEvents(expectedEvents); await invokeContentTask(browser, [fromID, toID], (_fromID, _toID) => { let orig = ( content.document._testGetElementById || content.document.getElementById ).bind(content.document)(_toID); if (orig) { orig.id = ""; } ( content.document._testGetElementById || content.document.getElementById ).bind(content.document)(_fromID).id = _toID; }); await expectedPromise; } async function changeARIAActiveDescendantInvalid( browser, container, invalidID = "invalid", prevItemId = null ) { let expectedEvents = [[EVENT_FOCUS, container]]; if (prevItemId) { expectedEvents.push( stateChangeEventArgs(prevItemId, EXT_STATE_ACTIVE, false, true) ); } let expectedPromise = waitForEvents(expectedEvents); await invokeContentTask( browser, [container, invalidID], (_container, _invalidID) => { let elm = ( content.document._testGetElementById || content.document.getElementById ).bind(content.document)(_container); elm.setAttribute("aria-activedescendant", _invalidID); } ); await expectedPromise; } const LISTBOX_MARKUP = `