RTL: Use direction-aware arrow key handling
This commit is contained in:
parent
ea2d4417e1
commit
043c6e1795
9 changed files with 55 additions and 49 deletions
|
@ -630,7 +630,7 @@ class VirtualizedTable extends React.Component {
|
||||||
if (shiftSelect || moveFocused) return;
|
if (shiftSelect || moveFocused) return;
|
||||||
|
|
||||||
switch (e.key) {
|
switch (e.key) {
|
||||||
case "ArrowLeft":
|
case Zotero.arrowPreviousKey:
|
||||||
const parentIndex = this.props.getParentIndex(this.selection.focused);
|
const parentIndex = this.props.getParentIndex(this.selection.focused);
|
||||||
if (this.props.isContainer(this.selection.focused)
|
if (this.props.isContainer(this.selection.focused)
|
||||||
&& !this.props.isContainerEmpty(this.selection.focused)
|
&& !this.props.isContainerEmpty(this.selection.focused)
|
||||||
|
@ -642,7 +642,7 @@ class VirtualizedTable extends React.Component {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ArrowRight":
|
case Zotero.arrowNextKey:
|
||||||
if (this.props.isContainer(this.selection.focused)
|
if (this.props.isContainer(this.selection.focused)
|
||||||
&& !this.props.isContainerEmpty(this.selection.focused)) {
|
&& !this.props.isContainerEmpty(this.selection.focused)) {
|
||||||
if (!this.props.isContainerOpen(this.selection.focused)) {
|
if (!this.props.isContainerOpen(this.selection.focused)) {
|
||||||
|
|
|
@ -519,8 +519,8 @@
|
||||||
}
|
}
|
||||||
else if (this.isPaginatedType && ["ArrowLeft", "ArrowRight"].includes(e.key)) {
|
else if (this.isPaginatedType && ["ArrowLeft", "ArrowRight"].includes(e.key)) {
|
||||||
let gotoType = {
|
let gotoType = {
|
||||||
ArrowLeft: "prev",
|
[Zotero.arrowPreviousKey]: "prev",
|
||||||
ArrowRight: "next"
|
[Zotero.arrowNextKey]: "next"
|
||||||
};
|
};
|
||||||
this.goto(gotoType[e.key]);
|
this.goto(gotoType[e.key]);
|
||||||
stopEvent = true;
|
stopEvent = true;
|
||||||
|
|
|
@ -353,10 +353,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Space/Enter toggle section open/closed.
|
// Space/Enter toggle section open/closed.
|
||||||
// ArrowLeft/ArrowRight on actual header will close/open
|
// ArrowLeft/ArrowRight on actual header will close/open (depending on locale direction)
|
||||||
if (["ArrowLeft", "ArrowRight", " ", "Enter"].includes(event.key)) {
|
if (["ArrowLeft", "ArrowRight", " ", "Enter"].includes(event.key)) {
|
||||||
stopEvent();
|
stopEvent();
|
||||||
this.open = ([" ", "Enter"].includes(event.key)) ? !this.open : (event.key == "ArrowRight");
|
this.open = ([" ", "Enter"].includes(event.key)) ? !this.open : (event.key == Zotero.arrowNextKey);
|
||||||
event.target.focus();
|
event.target.focus();
|
||||||
}
|
}
|
||||||
if (["ArrowUp", "ArrowDown"].includes(event.key)) {
|
if (["ArrowUp", "ArrowDown"].includes(event.key)) {
|
||||||
|
|
|
@ -195,10 +195,10 @@
|
||||||
});
|
});
|
||||||
tile.addEventListener('keydown', (event) => {
|
tile.addEventListener('keydown', (event) => {
|
||||||
switch (event.key) {
|
switch (event.key) {
|
||||||
case 'ArrowLeft':
|
case Zotero.arrowPreviousKey:
|
||||||
(tile.previousElementSibling || tile.parentElement.lastElementChild).focus();
|
(tile.previousElementSibling || tile.parentElement.lastElementChild).focus();
|
||||||
break;
|
break;
|
||||||
case 'ArrowRight':
|
case Zotero.arrowNextKey:
|
||||||
(tile.nextElementSibling || tile.parentElement.firstElementChild).focus();
|
(tile.nextElementSibling || tile.parentElement.firstElementChild).focus();
|
||||||
break;
|
break;
|
||||||
case 'ArrowUp': {
|
case 'ArrowUp': {
|
||||||
|
|
|
@ -54,11 +54,11 @@
|
||||||
|
|
||||||
// Select pane with left/right arrow key
|
// Select pane with left/right arrow key
|
||||||
this.addEventListener('keypress', (event) => {
|
this.addEventListener('keypress', (event) => {
|
||||||
if (event.key == "ArrowRight" && !this._rightPane.hasAttribute("selected")) {
|
if (event.key == Zotero.arrowNextKey && !this._rightPane.hasAttribute("selected")) {
|
||||||
this.choosePane(this._rightPane);
|
this.choosePane(this._rightPane);
|
||||||
this.rightPane.groupbox.focus();
|
this.rightPane.groupbox.focus();
|
||||||
}
|
}
|
||||||
else if (event.key == "ArrowLeft" && !this._leftPane.hasAttribute("selected")) {
|
else if (event.key == Zotero.arrowPreviousKey && !this._leftPane.hasAttribute("selected")) {
|
||||||
this.choosePane(this._leftPane);
|
this.choosePane(this._leftPane);
|
||||||
this._leftPane.groupbox.focus();
|
this._leftPane.groupbox.focus();
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,11 +133,11 @@ var Zotero_QuickFormat = new function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Right/Left arrow will hide ref panel and move focus to the previour/next element
|
// Right/Left arrow will hide ref panel and move focus to the previour/next element
|
||||||
else if ("ArrowLeft" == event.key) {
|
else if (event.key == Zotero.arrowPreviousKey) {
|
||||||
_lastFocusedInput.focus();
|
_lastFocusedInput.focus();
|
||||||
moveFocusBack(_lastFocusedInput);
|
moveFocusBack(_lastFocusedInput);
|
||||||
}
|
}
|
||||||
else if ("ArrowRight" == event.key) {
|
else if (event.key == Zotero.arrowNextKey) {
|
||||||
_lastFocusedInput.focus();
|
_lastFocusedInput.focus();
|
||||||
moveFocusForward(_lastFocusedInput);
|
moveFocusForward(_lastFocusedInput);
|
||||||
}
|
}
|
||||||
|
@ -1879,13 +1879,13 @@ var Zotero_QuickFormat = new function () {
|
||||||
Zotero_QuickFormat._bubbleizeSelected();
|
Zotero_QuickFormat._bubbleizeSelected();
|
||||||
}
|
}
|
||||||
else if (["ArrowLeft", "ArrowRight"].includes(event.key) && !event.shiftKey) {
|
else if (["ArrowLeft", "ArrowRight"].includes(event.key) && !event.shiftKey) {
|
||||||
// On arrow left from the beginning of the input, move to previous bubble
|
// On arrow left (right in RTL) from the beginning of the input, move to previous bubble
|
||||||
if (event.key === "ArrowLeft" && this.selectionStart === 0) {
|
if (event.key === Zotero.arrowPreviousKey && this.selectionStart === 0) {
|
||||||
moveFocusBack(this);
|
moveFocusBack(this);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
// On arrow right from the end of the input, move to next bubble
|
// On arrow right (left in RTL) from the end of the input, move to next bubble
|
||||||
else if (event.key === "ArrowRight" && this.selectionStart === this.value.length) {
|
else if (event.key === Zotero.arrowNextKey && this.selectionStart === this.value.length) {
|
||||||
moveFocusForward(this);
|
moveFocusForward(this);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
@ -1940,7 +1940,7 @@ var Zotero_QuickFormat = new function () {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
let newInput = _createInputField();
|
let newInput = _createInputField();
|
||||||
|
|
||||||
if (["ArrowLeft"].includes(event.key)) {
|
if (event.key === Zotero.arrowPreviousKey) {
|
||||||
if (isInput(this.previousElementSibling)) {
|
if (isInput(this.previousElementSibling)) {
|
||||||
moveFocusBack(this);
|
moveFocusBack(this);
|
||||||
}
|
}
|
||||||
|
@ -1949,7 +1949,7 @@ var Zotero_QuickFormat = new function () {
|
||||||
newInput.focus();
|
newInput.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (["ArrowRight"].includes(event.key)) {
|
else if (event.key === Zotero.arrowNextKey) {
|
||||||
if (isInput(this.nextElementSibling)) {
|
if (isInput(this.nextElementSibling)) {
|
||||||
moveFocusForward(this);
|
moveFocusForward(this);
|
||||||
}
|
}
|
||||||
|
@ -1965,13 +1965,13 @@ var Zotero_QuickFormat = new function () {
|
||||||
let findNextBubble = () => {
|
let findNextBubble = () => {
|
||||||
let node = event.target;
|
let node = event.target;
|
||||||
do {
|
do {
|
||||||
node = event.key == "ArrowLeft" ? node.previousElementSibling : node.nextElementSibling;
|
node = event.key == Zotero.arrowPreviousKey ? node.previousElementSibling : node.nextElementSibling;
|
||||||
} while (node && !(node.classList.contains("bubble") || node.classList.contains("zotero-bubble-input")));
|
} while (node && !(node.classList.contains("bubble") || node.classList.contains("zotero-bubble-input")));
|
||||||
return node;
|
return node;
|
||||||
};
|
};
|
||||||
let nextBubble = findNextBubble();
|
let nextBubble = findNextBubble();
|
||||||
if (nextBubble) {
|
if (nextBubble) {
|
||||||
if (event.key == "ArrowLeft") {
|
if (event.key === Zotero.arrowPreviousKey) {
|
||||||
nextBubble.before(this);
|
nextBubble.before(this);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -910,7 +910,7 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
// Handle arrow keys specially on multiple selection, since
|
// Handle arrow keys specially on multiple selection, since
|
||||||
// otherwise the tree just applies it to the last-selected row
|
// otherwise the tree just applies it to the last-selected row
|
||||||
if (this.selection.count > 1 && ["ArrowLeft", "ArrowRight"].includes(event.key)) {
|
if (this.selection.count > 1 && ["ArrowLeft", "ArrowRight"].includes(event.key)) {
|
||||||
if (event.key == "ArrowRight") {
|
if (event.key == Zotero.arrowNextKey) {
|
||||||
this.expandSelectedRows();
|
this.expandSelectedRows();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -599,8 +599,8 @@ var Zotero_Tabs = new function () {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves focus to a tab in the specified direction.
|
* Moves focus to a tab in the specified direction.
|
||||||
* @param {String} direction. "first", "last", "left", "right", or "current"
|
* @param {String} direction. "first", "last", "previous", "next", or "current"
|
||||||
* If document.activeElement is a tab, "left" or "right" direction moves focus from that tab.
|
* If document.activeElement is a tab, "previous" or "next" direction moves focus from that tab.
|
||||||
* Otherwise, focus is moved in the given direction from the currently selected tab.
|
* Otherwise, focus is moved in the given direction from the currently selected tab.
|
||||||
*/
|
*/
|
||||||
this.moveFocus = function (direction) {
|
this.moveFocus = function (direction) {
|
||||||
|
@ -627,10 +627,10 @@ var Zotero_Tabs = new function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case "left":
|
case "previous":
|
||||||
tabIndexToFocus = focusedTabIndex > 0 ? focusedTabIndex - 1 : null;
|
tabIndexToFocus = focusedTabIndex > 0 ? focusedTabIndex - 1 : null;
|
||||||
break;
|
break;
|
||||||
case "right":
|
case "next":
|
||||||
tabIndexToFocus = focusedTabIndex < this._tabs.length - 1 ? focusedTabIndex + 1 : null;
|
tabIndexToFocus = focusedTabIndex < this._tabs.length - 1 ? focusedTabIndex + 1 : null;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -195,6 +195,12 @@ var ZoteroPane = new function()
|
||||||
else if (verticalArrowIsTab && key == 'ArrowDown' && !onInput) {
|
else if (verticalArrowIsTab && key == 'ArrowDown' && !onInput) {
|
||||||
key = 'Tab';
|
key = 'Tab';
|
||||||
}
|
}
|
||||||
|
if (key == Zotero.arrowPreviousKey) {
|
||||||
|
key = 'ArrowPrevious';
|
||||||
|
}
|
||||||
|
else if (key == Zotero.arrowNextKey) {
|
||||||
|
key = 'ArrowNext';
|
||||||
|
}
|
||||||
// Fetch the focusFunction by target id
|
// Fetch the focusFunction by target id
|
||||||
let focusFunction = actionsMap[event.target.id]?.[key];
|
let focusFunction = actionsMap[event.target.id]?.[key];
|
||||||
// If no function found by target id, try to search by class names
|
// If no function found by target id, try to search by class names
|
||||||
|
@ -246,16 +252,16 @@ var ZoteroPane = new function()
|
||||||
// Mapping of target ids and possible key presses to desired focus outcomes
|
// Mapping of target ids and possible key presses to desired focus outcomes
|
||||||
let actionsMap = {
|
let actionsMap = {
|
||||||
'zotero-tb-tabs-menu': {
|
'zotero-tb-tabs-menu': {
|
||||||
ArrowRight: () => null,
|
ArrowNext: () => null,
|
||||||
ArrowLeft: () => null,
|
ArrowPrevious: () => null,
|
||||||
Tab: () => document.getElementById('zotero-tb-sync-error'),
|
Tab: () => document.getElementById('zotero-tb-sync-error'),
|
||||||
ShiftTab: () => {
|
ShiftTab: () => {
|
||||||
Zotero_Tabs.moveFocus("current");
|
Zotero_Tabs.moveFocus("current");
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'zotero-tb-sync': {
|
'zotero-tb-sync': {
|
||||||
ArrowRight: () => null,
|
ArrowNext: () => null,
|
||||||
ArrowLeft: () => null,
|
ArrowPrevious: () => null,
|
||||||
Tab: () => {
|
Tab: () => {
|
||||||
if (Zotero_Tabs.selectedIndex > 0) {
|
if (Zotero_Tabs.selectedIndex > 0) {
|
||||||
let reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
|
let reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
|
||||||
|
@ -274,8 +280,8 @@ var ZoteroPane = new function()
|
||||||
ShiftTab: () => document.getElementById('zotero-tb-sync-error')
|
ShiftTab: () => document.getElementById('zotero-tb-sync-error')
|
||||||
},
|
},
|
||||||
'zotero-tb-sync-error': {
|
'zotero-tb-sync-error': {
|
||||||
ArrowRight: () => null,
|
ArrowNext: () => null,
|
||||||
ArrowLeft: () => null,
|
ArrowPrevious: () => null,
|
||||||
Tab: () => document.getElementById('zotero-tb-sync'),
|
Tab: () => document.getElementById('zotero-tb-sync'),
|
||||||
ShiftTab: () => document.getElementById('zotero-tb-tabs-menu'),
|
ShiftTab: () => document.getElementById('zotero-tb-tabs-menu'),
|
||||||
Enter: () => document.getElementById("zotero-tb-sync-error")
|
Enter: () => document.getElementById("zotero-tb-sync-error")
|
||||||
|
@ -287,17 +293,17 @@ var ZoteroPane = new function()
|
||||||
// keyboard navigation for tabs. 'tab' is the class, not the id
|
// keyboard navigation for tabs. 'tab' is the class, not the id
|
||||||
Tab: () => document.getElementById('zotero-tb-tabs-menu'),
|
Tab: () => document.getElementById('zotero-tb-tabs-menu'),
|
||||||
ShiftTab: Zotero_Tabs.focusWrapAround,
|
ShiftTab: Zotero_Tabs.focusWrapAround,
|
||||||
ArrowRight: (e) => {
|
ArrowNext: (e) => {
|
||||||
if (cmdOrCtrlOnly(e)) {
|
if (cmdOrCtrlOnly(e)) {
|
||||||
Zotero_Tabs.moveFocus("right");
|
Zotero_Tabs.moveFocus("next");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Zotero_Tabs.selectNext({ keepTabFocused: true });
|
Zotero_Tabs.selectNext({ keepTabFocused: true });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ArrowLeft: (e) => {
|
ArrowPrevious: (e) => {
|
||||||
if (cmdOrCtrlOnly(e)) {
|
if (cmdOrCtrlOnly(e)) {
|
||||||
Zotero_Tabs.moveFocus("left");
|
Zotero_Tabs.moveFocus("previous");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Zotero_Tabs.selectPrev({ keepTabFocused: true });
|
Zotero_Tabs.selectPrev({ keepTabFocused: true });
|
||||||
|
@ -345,8 +351,8 @@ var ZoteroPane = new function()
|
||||||
collectionTreeToolbar.addEventListener("keydown", (event) => {
|
collectionTreeToolbar.addEventListener("keydown", (event) => {
|
||||||
let actionsMap = {
|
let actionsMap = {
|
||||||
'zotero-tb-collection-add': {
|
'zotero-tb-collection-add': {
|
||||||
ArrowRight: () => null,
|
ArrowNext: () => null,
|
||||||
ArrowLeft: () => null,
|
ArrowPrevious: () => null,
|
||||||
Tab: () => document.getElementById('zotero-tb-collections-search').click(),
|
Tab: () => document.getElementById('zotero-tb-collections-search').click(),
|
||||||
ShiftTab: () => document.getElementById('zotero-tb-sync')
|
ShiftTab: () => document.getElementById('zotero-tb-sync')
|
||||||
},
|
},
|
||||||
|
@ -363,8 +369,8 @@ var ZoteroPane = new function()
|
||||||
itemTreeToolbar.addEventListener("keydown", (event) => {
|
itemTreeToolbar.addEventListener("keydown", (event) => {
|
||||||
let actionsMap = {
|
let actionsMap = {
|
||||||
'zotero-tb-add': {
|
'zotero-tb-add': {
|
||||||
ArrowRight: () => document.getElementById("zotero-tb-lookup"),
|
ArrowNext: () => document.getElementById("zotero-tb-lookup"),
|
||||||
ArrowLeft: () => null,
|
ArrowPrevious: () => null,
|
||||||
Tab: () => document.getElementById("zotero-tb-search")._searchModePopup.flattenedTreeParentNode.focus(),
|
Tab: () => document.getElementById("zotero-tb-search")._searchModePopup.flattenedTreeParentNode.focus(),
|
||||||
ShiftTab: () => {
|
ShiftTab: () => {
|
||||||
if (collectionsPane.getAttribute("collapsed")) {
|
if (collectionsPane.getAttribute("collapsed")) {
|
||||||
|
@ -377,22 +383,22 @@ var ZoteroPane = new function()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'zotero-tb-lookup': {
|
'zotero-tb-lookup': {
|
||||||
ArrowRight: () => document.getElementById("zotero-tb-attachment-add"),
|
ArrowNext: () => document.getElementById("zotero-tb-attachment-add"),
|
||||||
ArrowLeft: () => document.getElementById("zotero-tb-add"),
|
ArrowPrevious: () => document.getElementById("zotero-tb-add"),
|
||||||
Tab: () => document.getElementById("zotero-tb-search")._searchModePopup.flattenedTreeParentNode.focus(),
|
Tab: () => document.getElementById("zotero-tb-search")._searchModePopup.flattenedTreeParentNode.focus(),
|
||||||
ShiftTab: () => document.getElementById('zotero-tb-collections-search').click(),
|
ShiftTab: () => document.getElementById('zotero-tb-collections-search').click(),
|
||||||
Enter: () => Zotero_Lookup.showPanel(event.target),
|
Enter: () => Zotero_Lookup.showPanel(event.target),
|
||||||
' ': () => Zotero_Lookup.showPanel(event.target)
|
' ': () => Zotero_Lookup.showPanel(event.target)
|
||||||
},
|
},
|
||||||
'zotero-tb-attachment-add': {
|
'zotero-tb-attachment-add': {
|
||||||
ArrowRight: () => document.getElementById("zotero-tb-note-add"),
|
ArrowNext: () => document.getElementById("zotero-tb-note-add"),
|
||||||
ArrowLeft: () => document.getElementById("zotero-tb-lookup"),
|
ArrowPrevious: () => document.getElementById("zotero-tb-lookup"),
|
||||||
Tab: () => document.getElementById("zotero-tb-search")._searchModePopup.flattenedTreeParentNode.focus(),
|
Tab: () => document.getElementById("zotero-tb-search")._searchModePopup.flattenedTreeParentNode.focus(),
|
||||||
ShiftTab: () => document.getElementById('zotero-tb-collections-search').click()
|
ShiftTab: () => document.getElementById('zotero-tb-collections-search').click()
|
||||||
},
|
},
|
||||||
'zotero-tb-note-add': {
|
'zotero-tb-note-add': {
|
||||||
ArrowRight: () => null,
|
ArrowNext: () => null,
|
||||||
ArrowLeft: () => document.getElementById("zotero-tb-attachment-add"),
|
ArrowPrevious: () => document.getElementById("zotero-tb-attachment-add"),
|
||||||
Tab: () => document.getElementById("zotero-tb-search")._searchModePopup.flattenedTreeParentNode.focus(),
|
Tab: () => document.getElementById("zotero-tb-search")._searchModePopup.flattenedTreeParentNode.focus(),
|
||||||
ShiftTab: () => document.getElementById('zotero-tb-collections-search').click()
|
ShiftTab: () => document.getElementById('zotero-tb-collections-search').click()
|
||||||
},
|
},
|
||||||
|
@ -403,8 +409,8 @@ var ZoteroPane = new function()
|
||||||
Tab: () => document.getElementById('item-tree-main-default')
|
Tab: () => document.getElementById('item-tree-main-default')
|
||||||
},
|
},
|
||||||
'zotero-tb-search-dropmarker': {
|
'zotero-tb-search-dropmarker': {
|
||||||
ArrowRight: () => null,
|
ArrowNext: () => null,
|
||||||
ArrowLeft: () => null,
|
ArrowPrevious: () => null,
|
||||||
Tab: () => document.getElementById("zotero-tb-search-textbox"),
|
Tab: () => document.getElementById("zotero-tb-search-textbox"),
|
||||||
ShiftTab: () => document.getElementById('zotero-tb-add')
|
ShiftTab: () => document.getElementById('zotero-tb-add')
|
||||||
}
|
}
|
||||||
|
@ -951,13 +957,13 @@ var ZoteroPane = new function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (event.metaKey && event.altKey) {
|
else if (event.metaKey && event.altKey) {
|
||||||
if (event.key == 'ArrowLeft') {
|
if (event.key == Zotero.arrowPreviousKey) {
|
||||||
Zotero_Tabs.selectPrev();
|
Zotero_Tabs.selectPrev();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (event.key == 'ArrowRight') {
|
else if (event.key == Zotero.arrowNextKey) {
|
||||||
Zotero_Tabs.selectNext();
|
Zotero_Tabs.selectNext();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
Loading…
Reference in a new issue