Restore read-only chalkboard textarea
This commit is contained in:
+37
-89
@@ -2650,7 +2650,6 @@ function flushLiveRegion(elementId) {
|
||||
|
||||
let text = state.queue.shift();
|
||||
if(text === undefined) {
|
||||
announcement.replaceChildren();
|
||||
state.active = false;
|
||||
return;
|
||||
}
|
||||
@@ -2679,41 +2678,6 @@ 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');
|
||||
}
|
||||
|
||||
function getChalkboardViewText() {
|
||||
return document.getElementById('chalkboard-view-text');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
*/
|
||||
function setChalkboardText(text) {
|
||||
chalkboardText = text;
|
||||
|
||||
let editor = getChalkboardEditor();
|
||||
if(editor && editor.value !== text)
|
||||
editor.value = text;
|
||||
|
||||
let viewText = getChalkboardViewText();
|
||||
if(viewText && viewText.textContent !== text)
|
||||
viewText.textContent = text;
|
||||
}
|
||||
|
||||
function chalkboardHasFocus() {
|
||||
let active = document.activeElement;
|
||||
return active === getChalkboardEditor() || active === getChalkboardView();
|
||||
}
|
||||
|
||||
function clearChalkboardAnnouncementTimer() {
|
||||
if(chalkboardAnnouncementTimer) {
|
||||
@@ -2731,29 +2695,28 @@ function canEditChalkboard() {
|
||||
}
|
||||
|
||||
function updateChalkboardAccess() {
|
||||
let editor = getChalkboardEditor();
|
||||
let view = getChalkboardView();
|
||||
if(!editor || !view)
|
||||
let chalkboard = /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
if(!chalkboard)
|
||||
return;
|
||||
let canEdit = canEditChalkboard();
|
||||
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();
|
||||
chalkboard.readOnly = !canEdit;
|
||||
chalkboard.setAttribute('aria-readonly', canEdit ? 'false' : 'true');
|
||||
chalkboard.setAttribute(
|
||||
'aria-label',
|
||||
canEdit ? 'Virtual chalkboard' : 'Virtual chalkboard, read only',
|
||||
);
|
||||
updateChalkboardCopyButton();
|
||||
}
|
||||
|
||||
function updateChalkboardCopyButton() {
|
||||
let chalkboard = /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
let copyButton = /** @type {HTMLButtonElement} */
|
||||
(document.getElementById('chalkboard-copy'));
|
||||
if(!copyButton)
|
||||
if(!chalkboard || !copyButton)
|
||||
return;
|
||||
copyButton.disabled = chalkboardText.length === 0;
|
||||
copyButton.disabled = chalkboard.value.length === 0;
|
||||
}
|
||||
|
||||
function resetChalkboard() {
|
||||
@@ -2766,38 +2729,26 @@ function resetChalkboard() {
|
||||
clearTimeout(chalkboardSendTimer);
|
||||
chalkboardSendTimer = null;
|
||||
}
|
||||
setChalkboardText('');
|
||||
let chalkboard = /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
if(chalkboard)
|
||||
chalkboard.value = '';
|
||||
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() {
|
||||
if(chalkboardText.length === 0)
|
||||
let chalkboard = /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
if(!chalkboard || chalkboard.value.length === 0)
|
||||
return;
|
||||
try {
|
||||
if(navigator.clipboard && navigator.clipboard.writeText) {
|
||||
await navigator.clipboard.writeText(chalkboardText);
|
||||
} else if(!copyTextWithExecCommand(chalkboardText)) {
|
||||
throw new Error('copy command failed');
|
||||
await navigator.clipboard.writeText(chalkboard.value);
|
||||
} else {
|
||||
chalkboard.focus();
|
||||
chalkboard.select();
|
||||
if(!document.execCommand('copy'))
|
||||
throw new Error('copy command failed');
|
||||
}
|
||||
announceChat('Chalkboard copied to clipboard');
|
||||
} catch(e) {
|
||||
@@ -2820,12 +2771,14 @@ function announcePendingChalkboardUpdate() {
|
||||
}
|
||||
|
||||
function scheduleChalkboardUpdateAnnouncement(hasText) {
|
||||
if(!getChalkboardEditor() || !getChalkboardView())
|
||||
let chalkboard = /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
if(!chalkboard)
|
||||
return;
|
||||
|
||||
chalkboardHasPendingAnnouncement = true;
|
||||
chalkboardPendingHasText = hasText;
|
||||
if(chalkboardHasFocus())
|
||||
if(document.activeElement === chalkboard)
|
||||
return;
|
||||
|
||||
clearChalkboardAnnouncementTimer();
|
||||
@@ -2849,14 +2802,16 @@ function applyChalkboardUpdate(message) {
|
||||
return;
|
||||
|
||||
chalkboardRevision = revision;
|
||||
if(!getChalkboardEditor() || !getChalkboardView())
|
||||
let chalkboard = /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
if(!chalkboard)
|
||||
return;
|
||||
let isLocalEcho =
|
||||
chalkboardLocalTextPending !== null &&
|
||||
text === chalkboardLocalTextPending;
|
||||
if(chalkboardText !== text) {
|
||||
if(chalkboard.value !== text) {
|
||||
applyingChalkboardUpdate = true;
|
||||
setChalkboardText(text);
|
||||
chalkboard.value = text;
|
||||
applyingChalkboardUpdate = false;
|
||||
if(isLocalEcho) {
|
||||
chalkboardLocalTextPending = null;
|
||||
@@ -2876,10 +2831,10 @@ function scheduleChalkboardSend() {
|
||||
clearTimeout(chalkboardSendTimer);
|
||||
chalkboardSendTimer = setTimeout(() => {
|
||||
chalkboardSendTimer = null;
|
||||
let chalkboard = getChalkboardEditor();
|
||||
let chalkboard = /** @type {HTMLTextAreaElement} */
|
||||
(document.getElementById('chalkboard'));
|
||||
if(!chalkboard || !serverConnection || !serverConnection.socket)
|
||||
return;
|
||||
chalkboardText = chalkboard.value;
|
||||
chalkboardLocalTextPending = chalkboard.value;
|
||||
serverConnection.hallAction('chalkboard', {
|
||||
text: chalkboard.value,
|
||||
@@ -3871,9 +3826,6 @@ 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();
|
||||
});
|
||||
@@ -3887,10 +3839,6 @@ 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