a11y: Setup observers for element roles (#4469)
* a11y: Setup observers for element roles * Reuse a function * Add error handling
This commit is contained in:
+1
-1
@@ -84,7 +84,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="lib/jquery-3.5.1.min.js"></script>
|
<script src="lib/jquery-3.5.1.min.js"></script>
|
||||||
<script src="scripts/login.js"></script>
|
<script src="scripts/login.js" type="module"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -266,6 +266,7 @@ import { initDataMaid } from './scripts/data-maid.js';
|
|||||||
import { clearItemizedPrompts, deleteItemizedPrompts, findItemizedPromptSet, initItemizedPrompts, itemizedParams, itemizedPrompts, loadItemizedPrompts, promptItemize, replaceItemizedPromptText, saveItemizedPrompts } from './scripts/itemized-prompts.js';
|
import { clearItemizedPrompts, deleteItemizedPrompts, findItemizedPromptSet, initItemizedPrompts, itemizedParams, itemizedPrompts, loadItemizedPrompts, promptItemize, replaceItemizedPromptText, saveItemizedPrompts } from './scripts/itemized-prompts.js';
|
||||||
import { getSystemMessageByType, initSystemMessages, SAFETY_CHAT, sendSystemMessage, system_message_types, system_messages } from './scripts/system-messages.js';
|
import { getSystemMessageByType, initSystemMessages, SAFETY_CHAT, sendSystemMessage, system_message_types, system_messages } from './scripts/system-messages.js';
|
||||||
import { event_types, eventSource } from './scripts/events.js';
|
import { event_types, eventSource } from './scripts/events.js';
|
||||||
|
import { initAccessibility } from './scripts/a11y.js';
|
||||||
|
|
||||||
// API OBJECT FOR EXTERNAL WIRING
|
// API OBJECT FOR EXTERNAL WIRING
|
||||||
globalThis.SillyTavern = {
|
globalThis.SillyTavern = {
|
||||||
@@ -687,6 +688,7 @@ async function firstLoadInit() {
|
|||||||
initCustomSelectedSamplers();
|
initCustomSelectedSamplers();
|
||||||
initDataMaid();
|
initDataMaid();
|
||||||
initItemizedPrompts();
|
initItemizedPrompts();
|
||||||
|
initAccessibility();
|
||||||
addDebugFunctions();
|
addDebugFunctions();
|
||||||
doDailyExtensionUpdatesCheck();
|
doDailyExtensionUpdatesCheck();
|
||||||
await hideLoader();
|
await hideLoader();
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/**
|
||||||
|
* Shared module between login and main app.
|
||||||
|
* Be careful what you import!
|
||||||
|
*/
|
||||||
|
|
||||||
|
const buttonSelectors = [
|
||||||
|
'.menu_button',
|
||||||
|
'.right_menu_button',
|
||||||
|
'.mes_button',
|
||||||
|
'.drawer-icon',
|
||||||
|
'.inline-drawer-icon',
|
||||||
|
'.swipe_left',
|
||||||
|
'.swipe_right',
|
||||||
|
'.character_select',
|
||||||
|
'.tags .tag',
|
||||||
|
].join(', ');
|
||||||
|
|
||||||
|
const listSelectors = [
|
||||||
|
'.options-content',
|
||||||
|
'.list-group',
|
||||||
|
'#rm_print_characters_block',
|
||||||
|
'#rm_group_members',
|
||||||
|
'#rm_group_add_members',
|
||||||
|
'.tag_view_list_tags',
|
||||||
|
'.secretKeyManagerList',
|
||||||
|
'.recentChatList',
|
||||||
|
'.dataMaidCategoryContent',
|
||||||
|
'#userList',
|
||||||
|
].join(', ');
|
||||||
|
|
||||||
|
const listItemSelectors = [
|
||||||
|
'.options-content .interactable',
|
||||||
|
'.list-group .list-group-item',
|
||||||
|
'#rm_print_characters_block .entity_block',
|
||||||
|
'#rm_group_members .group_member',
|
||||||
|
'#rm_group_add_members .group_member',
|
||||||
|
'.tag_view_list_tags .tag_view_item',
|
||||||
|
'.secretKeyManagerList .secretKeyManagerItem',
|
||||||
|
'.recentChatList .recentChat',
|
||||||
|
'.dataMaidCategoryContent .dataMaidItem',
|
||||||
|
'#userList .userSelect',
|
||||||
|
].join(', ');
|
||||||
|
|
||||||
|
/** @type {Record<string, (element: Element) => void>} */
|
||||||
|
const a11yRules = {
|
||||||
|
[buttonSelectors]: (element) => {
|
||||||
|
element.setAttribute('role', 'button');
|
||||||
|
},
|
||||||
|
[listSelectors]: (element) => {
|
||||||
|
element.setAttribute('role', 'list');
|
||||||
|
},
|
||||||
|
[listItemSelectors]: (element) => {
|
||||||
|
element.setAttribute('role', 'listitem');
|
||||||
|
},
|
||||||
|
'#toast-container .toast-message': (element) => {
|
||||||
|
element.setAttribute('role', 'alert');
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply accessibility rules to an element.
|
||||||
|
* @param {Element} element Element to process.
|
||||||
|
*/
|
||||||
|
function applyA11yRules(element) {
|
||||||
|
try {
|
||||||
|
for (const [selector, rule] of Object.entries(a11yRules)) {
|
||||||
|
// Apply if the element directly matches the selector
|
||||||
|
if (element.matches(selector)) {
|
||||||
|
rule(element);
|
||||||
|
}
|
||||||
|
// Apply the rule to descendants
|
||||||
|
element.querySelectorAll(selector).forEach(rule);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error applying accessibility rules to element:', element, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setAccessibilityObserver() {
|
||||||
|
// Apply for existing elements
|
||||||
|
applyA11yRules(document.body);
|
||||||
|
|
||||||
|
// Setup observer for dynamic content
|
||||||
|
const observer = new MutationObserver((mutationsList) => {
|
||||||
|
for (const mutation of mutationsList) {
|
||||||
|
if (mutation.type === 'childList') {
|
||||||
|
for (const addedNode of mutation.addedNodes) {
|
||||||
|
if (addedNode instanceof Element && addedNode.nodeType === Node.ELEMENT_NODE) {
|
||||||
|
applyA11yRules(addedNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
observer.observe(document.body, {
|
||||||
|
childList: true,
|
||||||
|
subtree: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initAccessibility() {
|
||||||
|
setAccessibilityObserver();
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { initAccessibility } from './a11y.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CRSF token for requests.
|
* CRSF token for requests.
|
||||||
*/
|
*/
|
||||||
@@ -265,6 +267,8 @@ function configureDiscreetLogin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(async function () {
|
(async function () {
|
||||||
|
initAccessibility();
|
||||||
|
|
||||||
csrfToken = await getCsrfToken();
|
csrfToken = await getCsrfToken();
|
||||||
const userList = await getUserList();
|
const userList = await getUserList();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user