From 422b92ba7ae05873d092e8f62984fdbbdf4a54f2 Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Wed, 26 Mar 2025 13:55:56 +0200 Subject: [PATCH 01/16] add tabindex to clickable elements (dismiss notification/s & go to profile link) #1781 --- customize.dist/messages.js | 2 +- www/common/sframe-common-mailbox.js | 11 ++++++++++- www/notifications/inner.js | 7 ++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/customize.dist/messages.js b/customize.dist/messages.js index a28190005..467b6dcca 100755 --- a/customize.dist/messages.js +++ b/customize.dist/messages.js @@ -135,7 +135,7 @@ define(req, function(AppConfig, Default, Language) { }; - + Messages.user_profile = 'Go to user profile'; return Messages; }); diff --git a/www/common/sframe-common-mailbox.js b/www/common/sframe-common-mailbox.js index bf05bdd18..9800e6124 100644 --- a/www/common/sframe-common-mailbox.js +++ b/www/common/sframe-common-mailbox.js @@ -81,8 +81,16 @@ define([ Common.openURL(Hash.hashToHref('', 'calendar')); }); } else if (userData && typeof(userData) === "object" && userData.profile) { - avatar = h('span.cp-avatar'); + avatar = h('span.cp-avatar',{ + tabindex: 0, + title: Messages.user_profile + }); Common.displayAvatar($(avatar), userData.avatar, userData.displayName || userData.name); + $(avatar).keydown(function (e) { + if (e.which === 13 || e.which === 32) { + $(avatar).click(); + } + }); $(avatar).click(function (e) { e.stopPropagation(); Common.openURL(Hash.hashToHref(userData.profile, 'profile')); @@ -136,6 +144,7 @@ define([ if (data.content.isDismissible) { var dismissIcon = h('span.fa.fa-times'); var dismiss = h('div.cp-notification-dismiss', { + tabindex: 0, title: Messages.notifications_dismiss, }, dismissIcon); $(dismiss).addClass("cp-clickable") diff --git a/www/notifications/inner.js b/www/notifications/inner.js index 8228f73c5..50eac3b5d 100644 --- a/www/notifications/inner.js +++ b/www/notifications/inner.js @@ -74,7 +74,7 @@ define([ h("h5.cp-app-notifications-panel-title", (Messages.notificationsPage || "Notifications") + " - " + categoryName), h("div.cp-app-notifications-panel-titlebar-buttons", [ - dismissAll = h("div.cp-app-notifications-dismissall.cp-clickable", { title: Messages.notifications_dismissAll || "Dismiss All" }, h("span.fa.fa-trash")), + dismissAll = h("div.cp-app-notifications-dismissall.cp-clickable", { tabindex: 0, title: Messages.notifications_dismissAll || "Dismiss All" }, h("span.fa.fa-trash")), ]), ]), notifsList = h("div.cp-app-notifications-panel-list", [ @@ -154,6 +154,11 @@ define([ } }); + $(dismissAll).keydown(function (e) { + if (e.keyCode === 13 || e.keyCode === 32) { + $(dismissAll).click(); + } + }); $(dismissAll).click(function () { notifsData.forEach(function (data) { if (data.content.isDismissible) { From 681fd4854a40eb50a8f5313be54b70afda1c8372 Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Wed, 26 Mar 2025 14:15:15 +0200 Subject: [PATCH 02/16] add tabindex to clickable notifications #1781 --- www/common/sframe-common-mailbox.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/common/sframe-common-mailbox.js b/www/common/sframe-common-mailbox.js index 9800e6124..4e8b62b05 100644 --- a/www/common/sframe-common-mailbox.js +++ b/www/common/sframe-common-mailbox.js @@ -99,7 +99,7 @@ define([ avatar = h('span.cp-avatar-image', h('img', { src:'/customize/CryptPad_logo.svg' })); } var order = -Math.floor((Util.find(data, ['content', 'msg', 'ctime']) || 0) / 1000); - const tabIndexValue = undefined;//data.content.isDismissible ? undefined : '0'; + const tabIndexValue = data.content.isClickable ? '0': 'undefined'; notif = h('li.cp-notification', { role: 'menuitem', tabindex: '0', From aac051d79baacc251a1be0cbc897215dac7b05e6 Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Wed, 26 Mar 2025 15:31:16 +0200 Subject: [PATCH 03/16] refine notification UI for keyboard users #1781 --- www/common/sframe-common-mailbox.js | 4 +++- www/notifications/app-notifications.less | 18 +++++++++++++++++- www/notifications/inner.js | 2 ++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/www/common/sframe-common-mailbox.js b/www/common/sframe-common-mailbox.js index 4e8b62b05..d475a1ab6 100644 --- a/www/common/sframe-common-mailbox.js +++ b/www/common/sframe-common-mailbox.js @@ -131,7 +131,9 @@ define([ $(notif).mouseenter((e) => { e.stopPropagation(); - $(notif).focus(); + if($(notif).find('li[tabindex="0"]').length) { + $(notif).focus(); + }; }); if (data.content.isClickable) { diff --git a/www/notifications/app-notifications.less b/www/notifications/app-notifications.less index b3dcf439c..c7a040a81 100644 --- a/www/notifications/app-notifications.less +++ b/www/notifications/app-notifications.less @@ -21,6 +21,10 @@ &:hover { background-color: @cp_notif-hover; } + &:focus-visible { + outline: @variables_focus_style; + border-radius: @variables_radius; + } } .cp-app-notifications-panel { @@ -59,6 +63,8 @@ justify-content: center; align-items: center; width: 3rem; + border-radius: @variables_radius; + margin: 0.2rem; } } } @@ -90,11 +96,16 @@ } .cp-avatar { .avatar_main(48px); - padding: 0 10px; + padding: 5px; + margin: 0.2rem; cursor: pointer; &:hover { background-color: @cp_notif-hover; } + &:focus-visible { + outline: @variables_focus_style; + border-radius: @variables_radius; + } } .cp-avatar-calendar { font-size: 45px; @@ -114,6 +125,7 @@ flex-direction: row; justify-content: flex-start; align-items: center; + margin: 0.2rem; p { display: inline-block; margin: 1rem 1rem; @@ -136,6 +148,10 @@ align-items: center; border-left: 1px solid @cp_notif-table-border; width: 3rem; + margin: 0.2rem; + &:focus-visible{ + border-radius: @variables_radius; + } } } } diff --git a/www/notifications/inner.js b/www/notifications/inner.js index 50eac3b5d..2ecec5a31 100644 --- a/www/notifications/inner.js +++ b/www/notifications/inner.js @@ -89,6 +89,7 @@ define([ notifsData.push(data); var icon = $(el).find(".cp-reminder"); $(icon).addClass('cp-avatar-calendar'); + $(el).attr('tabindex', -1); $(notifsList).prepend(el); } }; @@ -107,6 +108,7 @@ define([ var time = new Date(data.content.time); $(el).find(".cp-notification-content").append(h("span.notification-time", time.toLocaleString())); $(el).addClass("cp-app-notification-archived"); + $(el).attr('tabindex', -1); if (isDataUnread) { $(el).hide(); } else { From f3d63c252413e15a9ecf9885161f2ff499e58cca Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Wed, 26 Mar 2025 15:49:25 +0200 Subject: [PATCH 04/16] change div to button #1781 --- www/notifications/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/notifications/inner.js b/www/notifications/inner.js index 2ecec5a31..04969969c 100644 --- a/www/notifications/inner.js +++ b/www/notifications/inner.js @@ -124,7 +124,7 @@ define([ var loadmore; var lastKnownHash; $(dismissAll).remove(); - loadmore = h("div.cp-app-notification-loadmore.cp-clickable", Messages.history_loadMore); + loadmore = h("button.cp-app-notification-loadmore.cp-clickable", Messages.history_loadMore); $(loadmore).click(function () { common.mailbox.getNotificationsHistory('notifications', 10, lastKnownHash, function (err, messages, end) { if (!Array.isArray(messages)) { return; } From 92f3c1399f11fccff696b2dd4ab30f8318cbe729 Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Thu, 27 Mar 2025 11:46:10 +0200 Subject: [PATCH 05/16] fix notifications responsiveness #1781 --- customize.dist/src/less2/include/avatar.less | 1 - www/notifications/app-notifications.less | 8 ++------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/customize.dist/src/less2/include/avatar.less b/customize.dist/src/less2/include/avatar.less index 7b7b35986..1cdf0cb52 100644 --- a/customize.dist/src/less2/include/avatar.less +++ b/customize.dist/src/less2/include/avatar.less @@ -26,7 +26,6 @@ & { .avatar_vars(); &.cp-avatar { - overflow: hidden; text-overflow: ellipsis; font-size: 16px; display: flex; diff --git a/www/notifications/app-notifications.less b/www/notifications/app-notifications.less index c7a040a81..ab7d9560c 100644 --- a/www/notifications/app-notifications.less +++ b/www/notifications/app-notifications.less @@ -109,8 +109,7 @@ } .cp-avatar-calendar { font-size: 45px; - padding: 0 12px; - overflow: hidden; + padding: 12px; } &.cp-app-notification-archived { background-color: @cp_notif-bg; @@ -125,17 +124,14 @@ flex-direction: row; justify-content: flex-start; align-items: center; - margin: 0.2rem; p { display: inline-block; margin: 1rem 1rem; flex: 1; - min-width: 0; } .notification-time { - margin: 1rem 1rem; color: grey; - margin-left: auto; + margin: 1rem 1rem 1rem auto; } } From 9f11a1301e4424e65be44142afadeb9bec743dc5 Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Thu, 27 Mar 2025 11:57:29 +0200 Subject: [PATCH 06/16] add margin for notification content #1781 --- www/notifications/app-notifications.less | 1 + 1 file changed, 1 insertion(+) diff --git a/www/notifications/app-notifications.less b/www/notifications/app-notifications.less index ab7d9560c..338773867 100644 --- a/www/notifications/app-notifications.less +++ b/www/notifications/app-notifications.less @@ -124,6 +124,7 @@ flex-direction: row; justify-content: flex-start; align-items: center; + margin: 0.1rem; p { display: inline-block; margin: 1rem 1rem; From 94a4a445670769a96f1204b759980e2b5401c327 Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Fri, 25 Apr 2025 14:00:01 +0300 Subject: [PATCH 07/16] add `aria-label` to focusable elements --- www/common/sframe-common-mailbox.js | 4 +++- www/notifications/inner.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/www/common/sframe-common-mailbox.js b/www/common/sframe-common-mailbox.js index d475a1ab6..f80434e9a 100644 --- a/www/common/sframe-common-mailbox.js +++ b/www/common/sframe-common-mailbox.js @@ -83,7 +83,8 @@ define([ } else if (userData && typeof(userData) === "object" && userData.profile) { avatar = h('span.cp-avatar',{ tabindex: 0, - title: Messages.user_profile + title: Messages.user_profile, + 'aria-label': Messages.user_profile }); Common.displayAvatar($(avatar), userData.avatar, userData.displayName || userData.name); $(avatar).keydown(function (e) { @@ -148,6 +149,7 @@ define([ var dismiss = h('div.cp-notification-dismiss', { tabindex: 0, title: Messages.notifications_dismiss, + 'aria-label': Messages.notifications_dismiss }, dismissIcon); $(dismiss).addClass("cp-clickable") .on('click keypress', function (event) { diff --git a/www/notifications/inner.js b/www/notifications/inner.js index 04969969c..d4991406a 100644 --- a/www/notifications/inner.js +++ b/www/notifications/inner.js @@ -74,7 +74,7 @@ define([ h("h5.cp-app-notifications-panel-title", (Messages.notificationsPage || "Notifications") + " - " + categoryName), h("div.cp-app-notifications-panel-titlebar-buttons", [ - dismissAll = h("div.cp-app-notifications-dismissall.cp-clickable", { tabindex: 0, title: Messages.notifications_dismissAll || "Dismiss All" }, h("span.fa.fa-trash")), + dismissAll = h("div.cp-app-notifications-dismissall.cp-clickable", { tabindex: 0, title: Messages.notifications_dismissAll || "Dismiss All", 'aria-label': Messages.notifications_dismissAll || "Dismiss All" }, h("span.fa.fa-trash")), ]), ]), notifsList = h("div.cp-app-notifications-panel-list", [ From 29f6706a50d62287c754f696b692c33f386fa2da Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Fri, 25 Apr 2025 14:14:44 +0300 Subject: [PATCH 08/16] add `aria-hidden` to icons --- www/notifications/inner.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/www/notifications/inner.js b/www/notifications/inner.js index d4991406a..887f821d0 100644 --- a/www/notifications/inner.js +++ b/www/notifications/inner.js @@ -213,10 +213,10 @@ define([ common.setHash(active); Object.keys(categories).forEach(function (key) { var $category = $('
', {'class': 'cp-sidebarlayout-category', 'tabindex': 0}).appendTo($categories); - if (key === 'all') { $category.append($('', {'class': 'fa fa-bars'})); } - if (key === 'friends') { $category.append($('', {'class': 'fa fa-user'})); } - if (key === 'pads') { $category.append($('', {'class': 'cptools cptools-richtext'})); } - if (key === 'archived') { $category.append($('', {'class': 'fa fa-archive'})); } + if (key === 'all') { $category.append($('', {'class': 'fa fa-bars', 'aria-hidden': 'true'})); } + if (key === 'friends') { $category.append($('', {'class': 'fa fa-user', 'aria-hidden': 'true'})); } + if (key === 'pads') { $category.append($('', {'class': 'cptools cptools-richtext', 'aria-hidden': 'true'})); } + if (key === 'archived') { $category.append($('', {'class': 'fa fa-archive', 'aria-hidden': 'true'})); } if (key === active) { $category.addClass('cp-leftside-active'); From 5cfe9dc363511bc6f2a1b532e99db1e37e18b834 Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Fri, 25 Apr 2025 14:46:56 +0300 Subject: [PATCH 09/16] add `aria-label` to notification content + fix notification outline --- www/common/sframe-common-mailbox.js | 3 ++- www/notifications/app-notifications.less | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/www/common/sframe-common-mailbox.js b/www/common/sframe-common-mailbox.js index f80434e9a..0b114023e 100644 --- a/www/common/sframe-common-mailbox.js +++ b/www/common/sframe-common-mailbox.js @@ -100,7 +100,7 @@ define([ avatar = h('span.cp-avatar-image', h('img', { src:'/customize/CryptPad_logo.svg' })); } var order = -Math.floor((Util.find(data, ['content', 'msg', 'ctime']) || 0) / 1000); - const tabIndexValue = data.content.isClickable ? '0': 'undefined'; + const tabIndexValue = 0; //data.content.isClickable ? '0': 'undefined'; notif = h('li.cp-notification', { role: 'menuitem', tabindex: '0', @@ -128,6 +128,7 @@ define([ $(notif).find('.cp-notification-content p').html(data.content.getFormatText()); }, 60000); } + $(notif).find('.cp-notification-content').attr('aria-label', data.content.getFormatText().replace(/<[^>]*>/g, '')); // removes html tags from the text } $(notif).mouseenter((e) => { diff --git a/www/notifications/app-notifications.less b/www/notifications/app-notifications.less index 338773867..57d38936f 100644 --- a/www/notifications/app-notifications.less +++ b/www/notifications/app-notifications.less @@ -125,6 +125,10 @@ justify-content: flex-start; align-items: center; margin: 0.1rem; + &:focus-visible { + outline: @variables_focus_style; + border-radius: @variables_radius; + } p { display: inline-block; margin: 1rem 1rem; From 902aaccc5225754f8d7ec4ff62340bc50861c068 Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Fri, 25 Apr 2025 15:50:31 +0300 Subject: [PATCH 10/16] add roles --- www/common/sframe-common-mailbox.js | 8 +++++--- www/notifications/inner.js | 7 ++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/www/common/sframe-common-mailbox.js b/www/common/sframe-common-mailbox.js index 0b114023e..2a5b3f384 100644 --- a/www/common/sframe-common-mailbox.js +++ b/www/common/sframe-common-mailbox.js @@ -84,7 +84,8 @@ define([ avatar = h('span.cp-avatar',{ tabindex: 0, title: Messages.user_profile, - 'aria-label': Messages.user_profile + 'aria-label': Messages.user_profile, + role: 'button' }); Common.displayAvatar($(avatar), userData.avatar, userData.displayName || userData.name); $(avatar).keydown(function (e) { @@ -139,7 +140,7 @@ define([ }); if (data.content.isClickable) { - $(notif).find('.cp-notification-content').addClass("cp-clickable").on('click keypress', function (event) { + $(notif).find('.cp-notification-content').addClass("cp-clickable").attr('role', 'link').on('click keypress', function (event) { if (event.type === 'click' || (event.type === 'keypress' && event.which === 13)) { data.content.handler(); } @@ -150,7 +151,8 @@ define([ var dismiss = h('div.cp-notification-dismiss', { tabindex: 0, title: Messages.notifications_dismiss, - 'aria-label': Messages.notifications_dismiss + 'aria-label': Messages.notifications_dismiss, + role: 'button' }, dismissIcon); $(dismiss).addClass("cp-clickable") .on('click keypress', function (event) { diff --git a/www/notifications/inner.js b/www/notifications/inner.js index 887f821d0..545f14c59 100644 --- a/www/notifications/inner.js +++ b/www/notifications/inner.js @@ -74,7 +74,7 @@ define([ h("h5.cp-app-notifications-panel-title", (Messages.notificationsPage || "Notifications") + " - " + categoryName), h("div.cp-app-notifications-panel-titlebar-buttons", [ - dismissAll = h("div.cp-app-notifications-dismissall.cp-clickable", { tabindex: 0, title: Messages.notifications_dismissAll || "Dismiss All", 'aria-label': Messages.notifications_dismissAll || "Dismiss All" }, h("span.fa.fa-trash")), + dismissAll = h("div.cp-app-notifications-dismissall.cp-clickable", { tabindex: 0, title: Messages.notifications_dismissAll || "Dismiss All", 'aria-label': Messages.notifications_dismissAll || "Dismiss All", role: 'button' }, h("span.fa.fa-trash")), ]), ]), notifsList = h("div.cp-app-notifications-panel-list", [ @@ -205,14 +205,14 @@ define([ }); }; var createLeftside = function () { - var $categories = $('
', {'class': 'cp-sidebarlayout-categories'}) + var $categories = $('
', {'class': 'cp-sidebarlayout-categories', 'role': 'menu' }) .appendTo(APP.$leftside); var metadataMgr = common.getMetadataMgr(); var privateData = metadataMgr.getPrivateData(); var active = privateData.category || 'all'; common.setHash(active); Object.keys(categories).forEach(function (key) { - var $category = $('
', {'class': 'cp-sidebarlayout-category', 'tabindex': 0}).appendTo($categories); + var $category = $('
', {'class': 'cp-sidebarlayout-category', 'tabindex': 0, 'role': 'menuitem'}).appendTo($categories); if (key === 'all') { $category.append($('', {'class': 'fa fa-bars', 'aria-hidden': 'true'})); } if (key === 'friends') { $category.append($('', {'class': 'fa fa-user', 'aria-hidden': 'true'})); } if (key === 'pads') { $category.append($('', {'class': 'cptools cptools-richtext', 'aria-hidden': 'true'})); } @@ -240,6 +240,7 @@ define([ }); $category.append(Messages['notifications_cat_'+key] || key); + $category.attr('role', 'menuitem'); }); showCategories(categories[active]); }; From f29effbb9156ec717647303b7c9bb34187fda157 Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Fri, 25 Apr 2025 16:04:30 +0300 Subject: [PATCH 11/16] add role --- www/notifications/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/notifications/inner.js b/www/notifications/inner.js index 545f14c59..208138d5f 100644 --- a/www/notifications/inner.js +++ b/www/notifications/inner.js @@ -77,7 +77,7 @@ define([ dismissAll = h("div.cp-app-notifications-dismissall.cp-clickable", { tabindex: 0, title: Messages.notifications_dismissAll || "Dismiss All", 'aria-label': Messages.notifications_dismissAll || "Dismiss All", role: 'button' }, h("span.fa.fa-trash")), ]), ]), - notifsList = h("div.cp-app-notifications-panel-list", [ + notifsList = h("div.cp-app-notifications-panel-list", {'role': 'menu'},[ h("div.cp-notification.no-notifications", Messages.notifications_empty), ]), ]); From c2ee9ad58334b2cc36f754df93af30e8b9c41ff2 Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Fri, 25 Apr 2025 16:05:00 +0300 Subject: [PATCH 12/16] change date & time color --- www/notifications/app-notifications.less | 1 - 1 file changed, 1 deletion(-) diff --git a/www/notifications/app-notifications.less b/www/notifications/app-notifications.less index 57d38936f..56c784f8b 100644 --- a/www/notifications/app-notifications.less +++ b/www/notifications/app-notifications.less @@ -135,7 +135,6 @@ flex: 1; } .notification-time { - color: grey; margin: 1rem 1rem 1rem auto; } } From e061f639a881a068f3458a7dade2185c08063641 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 4 Jun 2025 15:17:34 +0200 Subject: [PATCH 13/16] Make reorderDOM from toolbar reusable for notifications --- www/common/common-ui-elements.js | 56 +++++++++++++++++++++++++ www/common/toolbar.js | 70 ++++---------------------------- www/notifications/inner.js | 4 ++ 3 files changed, 68 insertions(+), 62 deletions(-) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index c3de21053..1700fc5e0 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -4368,5 +4368,61 @@ define([ return container; }; + UIElements.reorderDOM = function ($content, isDrawer) { + var reorderDOM = Util.throttle(function ($content, observer) { + if (!$content.length) { return; } + + // List all children based on their "order" property + var map = {}; + $content[0].childNodes.forEach((node) => { + try { + if (!node.attributes) { return; } + let nodeWithOrder; + if (isDrawer) { // HACK: the order is set on their inner "a" tag + let $n = $(node); + if (!$n.attr('class') && + ($n.find('.fa').length || $n.find('.cptools').length)) { + nodeWithOrder = $n.find('.fa')[0] || $n.find('.cptools')[0]; + } + } + var order = getComputedStyle(nodeWithOrder || node).getPropertyValue("order"); + var a = map[order] = map[order] || []; + a.push(node); + } catch (e) { console.error(e, node); } + }); + + // Disconnect the observer while we're reordering to avoid infinite loop + observer.disconnect(); + Object.keys(map).sort(function (a, b) { + return Number(a) - Number(b); + }).forEach(function (k) { + var arr = map[k]; + if (!Number(k)) { return; } // No need to "append" if order is -1 + // Reorder + arr.forEach(function (node) { + $content.append(node); + }); + }); + observer.start(); + }, 100); + + let observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.addedNodes.length) { + reorderDOM($content, observer); + } + }); + }); + observer.start = function () { + if (!$content.length) { return; } + observer.observe($content[0], { + childList: true + }); + }; + observer.start(); + }; + + + return UIElements; }); diff --git a/www/common/toolbar.js b/www/common/toolbar.js index d5e6f34e7..48d080051 100644 --- a/www/common/toolbar.js +++ b/www/common/toolbar.js @@ -65,60 +65,6 @@ MessengerUI, Messages, Pages, PadTypes) { return 'cp-toolbar-uid-' + String(Math.random()).substring(2); }; - var observeChildren = function ($content, isDrawer) { - var reorderDOM = Util.throttle(function ($content, observer) { - if (!$content.length) { return; } - - // List all children based on their "order" property - var map = {}; - $content[0].childNodes.forEach((node) => { - try { - if (!node.attributes) { return; } - let nodeWithOrder; - if (isDrawer) { // HACK: the order is set on their inner "a" tag - let $n = $(node); - if (!$n.attr('class') && - ($n.find('.fa').length || $n.find('.cptools').length)) { - nodeWithOrder = $n.find('.fa')[0] || $n.find('.cptools')[0]; - } - } - var order = getComputedStyle(nodeWithOrder || node).getPropertyValue("order"); - var a = map[order] = map[order] || []; - a.push(node); - } catch (e) { console.error(e, node); } - }); - - // Disconnect the observer while we're reordering to avoid infinite loop - observer.disconnect(); - Object.keys(map).sort(function (a, b) { - return Number(a) - Number(b); - }).forEach(function (k) { - var arr = map[k]; - if (!Number(k)) { return; } // No need to "append" if order is 0 - // Reorder - arr.forEach(function (node) { - $content.append(node); - }); - }); - observer.start(); - }, 100); - - let observer = new MutationObserver(function(mutations) { - mutations.forEach(function(mutation) { - if (mutation.addedNodes.length) { - reorderDOM($content, observer); - } - }); - }); - observer.start = function () { - if (!$content.length) { return; } - observer.observe($content[0], { - childList: true - }); - }; - observer.start(); - }; - var createRealtimeToolbar = function (config) { if (!config.$container) { return; } var $container = config.$container; @@ -1226,7 +1172,7 @@ MessengerUI, Messages, Pages, PadTypes) { $button.attr('aria-label', Messages.notificationsPage); var $n = $button.find('.cp-dropdown-button-title').hide(); var $empty = $(div).find('.cp-notifications-empty'); - observeChildren($(div)); + UIElements.reorderDOM($(div)); var refresh = function () { updateUserList(toolbar, config); @@ -1452,14 +1398,14 @@ MessengerUI, Messages, Pages, PadTypes) { toolbar.$history = $toolbar.find('.'+Bar.constants.history); toolbar.$user = $toolbar.find('.'+Bar.constants.userAdmin); - observeChildren(toolbar.$drawer, true); - observeChildren(toolbar.$bottomL); - observeChildren(toolbar.$bottomM); - observeChildren(toolbar.$bottomR); - observeChildren(toolbar.$top); - observeChildren(toolbar.$user); + UIElements.reorderDOM(toolbar.$drawer, true); + UIElements.reorderDOM(toolbar.$bottomL); + UIElements.reorderDOM(toolbar.$bottomM); + UIElements.reorderDOM(toolbar.$bottomR); + UIElements.reorderDOM(toolbar.$top); + UIElements.reorderDOM(toolbar.$user); if (config.$contentContainer) { - observeChildren(config.$contentContainer); + UIElements.reorderDOM(config.$contentContainer); } toolbar.$userAdmin = $toolbar.find('.'+Bar.constants.userAdmin); diff --git a/www/notifications/inner.js b/www/notifications/inner.js index 208138d5f..efc0f375d 100644 --- a/www/notifications/inner.js +++ b/www/notifications/inner.js @@ -12,6 +12,7 @@ define([ '/common/hyperscript.js', '/customize/messages.js', '/common/common-interface.js', + '/common/common-ui-elements.js', '/common/notifications.js', 'css!/components/bootstrap/dist/css/bootstrap.min.css', @@ -27,6 +28,7 @@ define([ h, Messages, UI, + UIElements, Notifications ) { @@ -82,6 +84,8 @@ define([ ]), ]); + UIElements.reorderDOM($(notifsList)); + // add notification var addNotification = function (data, el) { // if the type of notification correspond From 4aad4836a724d340821fd9458f8c2685381c8581 Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Thu, 5 Jun 2025 01:17:52 -0700 Subject: [PATCH 14/16] change element role --- www/notifications/inner.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/notifications/inner.js b/www/notifications/inner.js index efc0f375d..43a7a8e65 100644 --- a/www/notifications/inner.js +++ b/www/notifications/inner.js @@ -79,7 +79,7 @@ define([ dismissAll = h("div.cp-app-notifications-dismissall.cp-clickable", { tabindex: 0, title: Messages.notifications_dismissAll || "Dismiss All", 'aria-label': Messages.notifications_dismissAll || "Dismiss All", role: 'button' }, h("span.fa.fa-trash")), ]), ]), - notifsList = h("div.cp-app-notifications-panel-list", {'role': 'menu'},[ + notifsList = h("div.cp-app-notifications-panel-list", {'role': 'list', 'aria-label': (Messages.notificationsPage || "Notifications") + " " + categoryName }, [ h("div.cp-notification.no-notifications", Messages.notifications_empty), ]), ]); @@ -94,6 +94,7 @@ define([ var icon = $(el).find(".cp-reminder"); $(icon).addClass('cp-avatar-calendar'); $(el).attr('tabindex', -1); + $(el).attr('role', 'listitem'); $(notifsList).prepend(el); } }; @@ -244,7 +245,6 @@ define([ }); $category.append(Messages['notifications_cat_'+key] || key); - $category.attr('role', 'menuitem'); }); showCategories(categories[active]); }; From b52da4c6643834ad9dfd1866bab72db6fab1b4c4 Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Tue, 10 Jun 2025 10:43:22 +0300 Subject: [PATCH 15/16] remove variable --- www/common/sframe-common-mailbox.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/www/common/sframe-common-mailbox.js b/www/common/sframe-common-mailbox.js index 2a5b3f384..3f8b238f9 100644 --- a/www/common/sframe-common-mailbox.js +++ b/www/common/sframe-common-mailbox.js @@ -101,7 +101,6 @@ define([ avatar = h('span.cp-avatar-image', h('img', { src:'/customize/CryptPad_logo.svg' })); } var order = -Math.floor((Util.find(data, ['content', 'msg', 'ctime']) || 0) / 1000); - const tabIndexValue = 0; //data.content.isClickable ? '0': 'undefined'; notif = h('li.cp-notification', { role: 'menuitem', tabindex: '0', @@ -110,7 +109,7 @@ define([ }, [ avatar, h('div.cp-notification-content', { - tabindex: tabIndexValue + tabindex: 0 }, [ h('p', data.content.msg.type + ' - ' +formatData(data)) ]) From 7f55741b1b05b4a2bc20c411fa4762529eaa4b58 Mon Sep 17 00:00:00 2001 From: daria <95225431+dariiing@users.noreply.github.com> Date: Tue, 10 Jun 2025 11:12:54 +0300 Subject: [PATCH 16/16] clean code --- www/common/sframe-common-mailbox.js | 13 +++++-------- www/notifications/inner.js | 16 ++++++++-------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/www/common/sframe-common-mailbox.js b/www/common/sframe-common-mailbox.js index 3f8b238f9..d84ea457a 100644 --- a/www/common/sframe-common-mailbox.js +++ b/www/common/sframe-common-mailbox.js @@ -88,15 +88,11 @@ define([ role: 'button' }); Common.displayAvatar($(avatar), userData.avatar, userData.displayName || userData.name); - $(avatar).keydown(function (e) { - if (e.which === 13 || e.which === 32) { - $(avatar).click(); - } - }); - $(avatar).click(function (e) { + const handler = function (e) { e.stopPropagation(); Common.openURL(Hash.hashToHref(userData.profile, 'profile')); - }); + }; + Util.onClickEnter($(avatar), handler, { space: true }); } else if (userData && userData.supportTeam) { avatar = h('span.cp-avatar-image', h('img', { src:'/customize/CryptPad_logo.svg' })); } @@ -128,7 +124,8 @@ define([ $(notif).find('.cp-notification-content p').html(data.content.getFormatText()); }, 60000); } - $(notif).find('.cp-notification-content').attr('aria-label', data.content.getFormatText().replace(/<[^>]*>/g, '')); // removes html tags from the text + const label = $(notif).find('.cp-notification-content p').text(); + $(notif).find('.cp-notification-content').attr('aria-label', label); } $(notif).mouseenter((e) => { diff --git a/www/notifications/inner.js b/www/notifications/inner.js index 43a7a8e65..dfde1dd67 100644 --- a/www/notifications/inner.js +++ b/www/notifications/inner.js @@ -14,6 +14,7 @@ define([ '/common/common-interface.js', '/common/common-ui-elements.js', '/common/notifications.js', + '/common/common-util.js', 'css!/components/bootstrap/dist/css/bootstrap.min.css', 'css!/components/components-font-awesome/css/font-awesome.min.css', @@ -29,7 +30,8 @@ define([ Messages, UI, UIElements, - Notifications + Notifications, + Util, ) { var APP = {}; @@ -160,19 +162,17 @@ define([ $('.cp-app-notification-archived[data-hash="' + data.hash + '"]').css('display', 'flex'); } }); - - $(dismissAll).keydown(function (e) { - if (e.keyCode === 13 || e.keyCode === 32) { - $(dismissAll).click(); + const handler = function (e) { + if (!notifsData) { + return; } - }); - $(dismissAll).click(function () { notifsData.forEach(function (data) { if (data.content.isDismissible) { data.content.dismissHandler(); } }); - }); + }; + Util.onClickEnter($(dismissAll), handler, { space: true }); return $div; };