mirror of
https://github.com/HeyPuter/puter
synced 2024-11-14 22:06:00 +00:00
fix multiple issues with ctx menu event delegation and keyboard navigation
This commit is contained in:
parent
b78c83a4ab
commit
8a763eab6f
@ -154,14 +154,14 @@
|
||||
/**
|
||||
* Trigger a possible row activation whenever entering a new row.
|
||||
*/
|
||||
var mouseenterRow = function () {
|
||||
var mouseenterRow = function (e, data) {
|
||||
if (timeoutId) {
|
||||
// Cancel any previous activation delays
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
|
||||
options.enter(this);
|
||||
possiblyActivate(this);
|
||||
possiblyActivate(this, e, data);
|
||||
},
|
||||
mouseleaveRow = function () {
|
||||
options.exit(this);
|
||||
@ -177,7 +177,12 @@
|
||||
/**
|
||||
* Activate a menu row.
|
||||
*/
|
||||
var activate = function (row) {
|
||||
var activate = function (row, e, data) {
|
||||
if(mouseLocs[mouseLocs.length - 1]?.x !== undefined && mouseLocs[mouseLocs.length - 1]?.y !== undefined){
|
||||
row.pageX = mouseLocs[mouseLocs.length - 1].x;
|
||||
row.pageY = mouseLocs[mouseLocs.length - 1].y;
|
||||
}
|
||||
|
||||
if (row == activeRow) {
|
||||
return;
|
||||
}
|
||||
@ -187,7 +192,7 @@
|
||||
}
|
||||
|
||||
|
||||
options.activate(row);
|
||||
options.activate(row, e, data);
|
||||
activeRow = row;
|
||||
};
|
||||
|
||||
@ -196,15 +201,15 @@
|
||||
* shouldn't activate yet because user may be trying to enter
|
||||
* a submenu's content, then delay and check again later.
|
||||
*/
|
||||
var possiblyActivate = function (row) {
|
||||
var possiblyActivate = function (row, e, data) {
|
||||
var delay = activationDelay();
|
||||
|
||||
if (delay) {
|
||||
timeoutId = setTimeout(function () {
|
||||
possiblyActivate(row);
|
||||
possiblyActivate(row, e, data);
|
||||
}, delay);
|
||||
} else {
|
||||
activate(row);
|
||||
activate(row, e, data);
|
||||
}
|
||||
};
|
||||
|
||||
@ -327,7 +332,7 @@
|
||||
return 0;
|
||||
};
|
||||
|
||||
$menu.on('mouseenter', function(e) {
|
||||
$menu.on('mouseenter', function(e, data) {
|
||||
if($menu.find('.context-menu-item-active').length === 0 && $menu.find('.has-open-context-menu-submenu').length === 0)
|
||||
activeRow = null;
|
||||
})
|
||||
@ -395,7 +400,8 @@ function UIContextMenu(options){
|
||||
h += `<span class="context-menu-item-icon">${options.items[i].icon ?? ''}</span>`;
|
||||
h += `<span class="context-menu-item-icon-active">${options.items[i].icon_active ?? (options.items[i].icon ?? '')}</span>`;
|
||||
// label
|
||||
h += `${html_encode(options.items[i].html)}`;
|
||||
h += `<span class="contextmenu-label">${html_encode(options.items[i].html)}</span>`;
|
||||
h += `<span class="contextmenu-label-active">${html_encode(options.items[i].html_active ?? options.items[i].html)}</span>`;
|
||||
// arrow
|
||||
h += `<img class="submenu-arrow" src="${html_encode(window.icons['chevron-right.svg'])}"><img class="submenu-arrow submenu-arrow-active" src="${html_encode(window.icons['chevron-right-active.svg'])}">`;
|
||||
h += `</li>`;
|
||||
@ -533,7 +539,12 @@ function UIContextMenu(options){
|
||||
// this.activate(e);
|
||||
},
|
||||
// activates item when mouse enters depending on mouse position and direction
|
||||
activate: function (e) {
|
||||
activate: function (e, event, data) {
|
||||
// make sure last recorded mouse position is the same as the current one before activating
|
||||
// this is because switching contexts from iframe to window can cause the mouse position to be off
|
||||
if(!data?.keyboard && (e.pageX !== window.mouseX || e.pageY !== window.mouseY)){
|
||||
return;
|
||||
}
|
||||
// activate items
|
||||
let item = $(e).closest('.context-menu-item');
|
||||
// mark other menu items as inactive
|
||||
@ -686,8 +697,7 @@ $(document).on('mouseenter', '.context-menu', function(e){
|
||||
})
|
||||
})
|
||||
|
||||
$(document).on('mouseenter', '.context-menu-item', function(e){
|
||||
// select_ctxmenu_item(this);
|
||||
$(document).on('mouseenter', '.context-menu-item', function(e, data){
|
||||
})
|
||||
|
||||
$(document).on('mouseenter', '.context-menu-divider', function(e){
|
||||
@ -695,6 +705,4 @@ $(document).on('mouseenter', '.context-menu-divider', function(e){
|
||||
$(this).siblings('.context-menu-item:not(.has-open-context-menu-submenu)').removeClass('context-menu-item-active');
|
||||
})
|
||||
|
||||
$(document)
|
||||
|
||||
export default UIContextMenu;
|
@ -161,9 +161,9 @@ $(document).bind('keydown', async function(e){
|
||||
return false;
|
||||
}
|
||||
// if right arrow is pressed, open the submenu by triggering a mouseover event
|
||||
else if($('.context-menu-active .context-menu-item-active').length > 0 && (e.which === 39)){
|
||||
else if($('.context-menu-active .context-menu-item-active').length > 0 && e.which === 39){
|
||||
const selected_item = $('.context-menu-active .context-menu-item-active').get(0);
|
||||
$(selected_item).trigger('mouseover');
|
||||
$(selected_item).trigger('mouseover', {keyboard: true});
|
||||
// if the submenu is open, select the first item in the submenu
|
||||
if($(selected_item).hasClass('context-menu-item-submenu') === true){
|
||||
$(selected_item).removeClass('context-menu-item-active');
|
||||
@ -184,6 +184,7 @@ $(document).bind('keydown', async function(e){
|
||||
// select the item that opened the submenu
|
||||
let selected_item = $('.context-menu-active .context-menu-item-active-blurred').get(0);
|
||||
$(selected_item).removeClass('context-menu-item-active-blurred');
|
||||
$(selected_item).removeClass('has-open-context-menu-submenu');
|
||||
$(selected_item).addClass('context-menu-item-active');
|
||||
|
||||
return false;
|
||||
@ -191,7 +192,7 @@ $(document).bind('keydown', async function(e){
|
||||
// if enter is pressed, trigger a click event on the selected item
|
||||
else if($('.context-menu-active .context-menu-item-active').length > 0 && (e.which === 13)){
|
||||
let selected_item = $('.context-menu-active .context-menu-item-active').get(0);
|
||||
$(selected_item).trigger('click');
|
||||
$(selected_item).trigger('click', {keyboard: true});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -482,10 +483,10 @@ $(document).bind('keydown', async function(e){
|
||||
}
|
||||
|
||||
// search for matches
|
||||
let haystack = $('.context-menu-active').find(`.context-menu-item`);
|
||||
let haystack = $('.context-menu-active').find(`.context-menu-item > .contextmenu-label`);
|
||||
for(let j=0; j < haystack.length; j++){
|
||||
if($(haystack[j]).text().toLowerCase().startsWith(window.keypress_item_seach_term)){
|
||||
matches.push(haystack[j])
|
||||
matches.push(haystack[j].closest('.context-menu-item'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -640,15 +641,11 @@ $(document).bind("keyup keydown", async function(e){
|
||||
// if this is a selected context menu item, open it
|
||||
// ---------------------------------------------
|
||||
else if($('.context-menu-active .context-menu-item-active').length > 0 && (e.which === 13)){
|
||||
// let selected_item = $('.context-menu-active .context-menu-item-active').get(0);
|
||||
// $(selected_item).trigger('mouseover');
|
||||
// $(selected_item).trigger('click');
|
||||
|
||||
let selected_item = $('.context-menu-active .context-menu-item-active').get(0);
|
||||
$(selected_item).removeClass('context-menu-item-active');
|
||||
$(selected_item).addClass('context-menu-item-active-blurred');
|
||||
$(selected_item).trigger('mouseover');
|
||||
$(selected_item).trigger('click');
|
||||
$(selected_item).trigger('mouseover', {keyboard: true});
|
||||
$(selected_item).trigger('click', {keyboard: true});
|
||||
if($('.context-menu[data-is-submenu="true"]').length > 0){
|
||||
let selected_item = $('.context-menu[data-is-submenu="true"] .context-menu-item').get(0);
|
||||
window.select_ctxmenu_item(selected_item);
|
||||
|
Loading…
Reference in New Issue
Block a user