Change chalkboard to pre tag for people who do not have write access because some screen readers seem to have problems with read only edit boxes.
This commit is contained in:
+83
-37
@@ -2678,6 +2678,36 @@ let chalkboardAnnouncementTimer = null;
|
||||
let chalkboardHasPendingAnnouncement = false;
|
||||
let chalkboardPendingHasText = false;
|
||||
let chalkboardLocalTextPending = null;
|
||||
let chalkboardText = '';
|
||||
|
||||
function getChalkboardEditor() {
|
||||
return /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
}
|
||||
|
||||
function getChalkboardView() {
|
||||
return document.getElementById('chalkboard-view');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
*/
|
||||
function setChalkboardText(text) {
|
||||
chalkboardText = text;
|
||||
|
||||
let editor = getChalkboardEditor();
|
||||
if(editor && editor.value !== text)
|
||||
editor.value = text;
|
||||
|
||||
let view = getChalkboardView();
|
||||
if(view && view.textContent !== text)
|
||||
view.textContent = text;
|
||||
}
|
||||
|
||||
function chalkboardHasFocus() {
|
||||
let active = document.activeElement;
|
||||
return active === getChalkboardEditor() || active === getChalkboardView();
|
||||
}
|
||||
|
||||
function clearChalkboardAnnouncementTimer() {
|
||||
if(chalkboardAnnouncementTimer) {
|
||||
@@ -2695,28 +2725,29 @@ function canEditChalkboard() {
|
||||
}
|
||||
|
||||
function updateChalkboardAccess() {
|
||||
let chalkboard = /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
if(!chalkboard)
|
||||
let editor = getChalkboardEditor();
|
||||
let view = getChalkboardView();
|
||||
if(!editor || !view)
|
||||
return;
|
||||
let canEdit = canEditChalkboard();
|
||||
chalkboard.readOnly = !canEdit;
|
||||
chalkboard.setAttribute('aria-readonly', canEdit ? 'false' : 'true');
|
||||
chalkboard.setAttribute(
|
||||
'aria-label',
|
||||
canEdit ? 'Virtual chalkboard' : 'Virtual chalkboard, read only',
|
||||
);
|
||||
let active = document.activeElement;
|
||||
editor.hidden = !canEdit;
|
||||
view.hidden = canEdit;
|
||||
editor.setAttribute('aria-label', 'Virtual chalkboard');
|
||||
view.setAttribute('aria-label', 'Virtual chalkboard, read only');
|
||||
if(active === editor && !canEdit)
|
||||
view.focus();
|
||||
else if(active === view && canEdit)
|
||||
editor.focus();
|
||||
updateChalkboardCopyButton();
|
||||
}
|
||||
|
||||
function updateChalkboardCopyButton() {
|
||||
let chalkboard = /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
let copyButton = /** @type {HTMLButtonElement} */
|
||||
(document.getElementById('chalkboard-copy'));
|
||||
if(!chalkboard || !copyButton)
|
||||
if(!copyButton)
|
||||
return;
|
||||
copyButton.disabled = chalkboard.value.length === 0;
|
||||
copyButton.disabled = chalkboardText.length === 0;
|
||||
}
|
||||
|
||||
function resetChalkboard() {
|
||||
@@ -2729,26 +2760,38 @@ function resetChalkboard() {
|
||||
clearTimeout(chalkboardSendTimer);
|
||||
chalkboardSendTimer = null;
|
||||
}
|
||||
let chalkboard = /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
if(chalkboard)
|
||||
chalkboard.value = '';
|
||||
setChalkboardText('');
|
||||
updateChalkboardAccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
*/
|
||||
function copyTextWithExecCommand(text) {
|
||||
let fallback = document.createElement('textarea');
|
||||
fallback.value = text;
|
||||
fallback.readOnly = true;
|
||||
fallback.style.position = 'fixed';
|
||||
fallback.style.left = '-9999px';
|
||||
fallback.style.top = '0';
|
||||
document.body.appendChild(fallback);
|
||||
try {
|
||||
fallback.focus();
|
||||
fallback.select();
|
||||
return document.execCommand('copy');
|
||||
} finally {
|
||||
document.body.removeChild(fallback);
|
||||
}
|
||||
}
|
||||
|
||||
async function copyChalkboardToClipboard() {
|
||||
let chalkboard = /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
if(!chalkboard || chalkboard.value.length === 0)
|
||||
if(chalkboardText.length === 0)
|
||||
return;
|
||||
try {
|
||||
if(navigator.clipboard && navigator.clipboard.writeText) {
|
||||
await navigator.clipboard.writeText(chalkboard.value);
|
||||
} else {
|
||||
chalkboard.focus();
|
||||
chalkboard.select();
|
||||
if(!document.execCommand('copy'))
|
||||
throw new Error('copy command failed');
|
||||
await navigator.clipboard.writeText(chalkboardText);
|
||||
} else if(!copyTextWithExecCommand(chalkboardText)) {
|
||||
throw new Error('copy command failed');
|
||||
}
|
||||
announceChat('Chalkboard copied to clipboard');
|
||||
} catch(e) {
|
||||
@@ -2771,14 +2814,12 @@ function announcePendingChalkboardUpdate() {
|
||||
}
|
||||
|
||||
function scheduleChalkboardUpdateAnnouncement(hasText) {
|
||||
let chalkboard = /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
if(!chalkboard)
|
||||
if(!getChalkboardEditor() || !getChalkboardView())
|
||||
return;
|
||||
|
||||
chalkboardHasPendingAnnouncement = true;
|
||||
chalkboardPendingHasText = hasText;
|
||||
if(document.activeElement === chalkboard)
|
||||
if(chalkboardHasFocus())
|
||||
return;
|
||||
|
||||
clearChalkboardAnnouncementTimer();
|
||||
@@ -2802,16 +2843,14 @@ function applyChalkboardUpdate(message) {
|
||||
return;
|
||||
|
||||
chalkboardRevision = revision;
|
||||
let chalkboard = /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
if(!chalkboard)
|
||||
if(!getChalkboardEditor() || !getChalkboardView())
|
||||
return;
|
||||
let isLocalEcho =
|
||||
chalkboardLocalTextPending !== null &&
|
||||
text === chalkboardLocalTextPending;
|
||||
if(chalkboard.value !== text) {
|
||||
if(chalkboardText !== text) {
|
||||
applyingChalkboardUpdate = true;
|
||||
chalkboard.value = text;
|
||||
setChalkboardText(text);
|
||||
applyingChalkboardUpdate = false;
|
||||
if(isLocalEcho) {
|
||||
chalkboardLocalTextPending = null;
|
||||
@@ -2831,10 +2870,10 @@ function scheduleChalkboardSend() {
|
||||
clearTimeout(chalkboardSendTimer);
|
||||
chalkboardSendTimer = setTimeout(() => {
|
||||
chalkboardSendTimer = null;
|
||||
let chalkboard = /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
let chalkboard = getChalkboardEditor();
|
||||
if(!chalkboard || !serverConnection || !serverConnection.socket)
|
||||
return;
|
||||
chalkboardText = chalkboard.value;
|
||||
chalkboardLocalTextPending = chalkboard.value;
|
||||
serverConnection.hallAction('chalkboard', {
|
||||
text: chalkboard.value,
|
||||
@@ -3826,6 +3865,9 @@ document.getElementById('input').onkeypress = function(e) {
|
||||
document.getElementById('chalkboard').addEventListener('input', function(e) {
|
||||
if(applyingChalkboardUpdate)
|
||||
return;
|
||||
let chalkboard = getChalkboardEditor();
|
||||
if(chalkboard)
|
||||
setChalkboardText(chalkboard.value);
|
||||
updateChalkboardCopyButton();
|
||||
scheduleChalkboardSend();
|
||||
});
|
||||
@@ -3839,6 +3881,10 @@ document.getElementById('chalkboard').addEventListener('focus', function(e) {
|
||||
announcePendingChalkboardUpdate();
|
||||
});
|
||||
|
||||
document.getElementById('chalkboard-view').addEventListener('focus', function(e) {
|
||||
announcePendingChalkboardUpdate();
|
||||
});
|
||||
|
||||
document.getElementById('chalkboard-copy').addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
copyChalkboardToClipboard();
|
||||
|
||||
Reference in New Issue
Block a user