You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
devdocs/assets/javascripts/views/list/list_focus.js

198 lines
4.7 KiB

// TODO: This file was created by bulk-decaffeinate.
// Sanity-check the conversion and remove this comment.
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS206: Consider reworking classes to avoid initClass
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
app.views.ListFocus = class ListFocus extends app.View {
static initClass() {
1 year ago
this.activeClass = "focus";
this.events = { click: "onClick" };
this.shortcuts = {
1 year ago
up: "onUp",
down: "onDown",
left: "onLeft",
enter: "onEnter",
superEnter: "onSuperEnter",
escape: "blur",
};
}
constructor(el) {
super(el);
this.focusOnNextFrame = $.framify(this.focus, this);
}
focus(el, options) {
1 year ago
if (options == null) {
options = {};
}
if (el && !el.classList.contains(this.constructor.activeClass)) {
this.blur();
el.classList.add(this.constructor.activeClass);
1 year ago
if (options.silent !== true) {
$.trigger(el, "focus");
}
}
}
blur() {
let cursor;
1 year ago
if ((cursor = this.getCursor())) {
cursor.classList.remove(this.constructor.activeClass);
1 year ago
$.trigger(cursor, "blur");
}
}
getCursor() {
1 year ago
return (
this.findByClass(this.constructor.activeClass) ||
this.findByClass(app.views.ListSelect.activeClass)
);
}
findNext(cursor) {
let next;
1 year ago
if ((next = cursor.nextSibling)) {
if (next.tagName === "A") {
return next;
1 year ago
} else if (next.tagName === "SPAN") {
// pagination link
$.click(next);
return this.findNext(cursor);
1 year ago
} else if (next.tagName === "DIV") {
// sub-list
if (cursor.className.indexOf(" open") >= 0) {
return this.findFirst(next) || this.findNext(next);
} else {
return this.findNext(next);
}
1 year ago
} else if (next.tagName === "H6") {
// title
return this.findNext(next);
}
} else if (cursor.parentNode !== this.el) {
return this.findNext(cursor.parentNode);
}
}
findFirst(cursor) {
let first;
1 year ago
if (!(first = cursor.firstChild)) {
return;
}
1 year ago
if (first.tagName === "A") {
return first;
1 year ago
} else if (first.tagName === "SPAN") {
// pagination link
$.click(first);
return this.findFirst(cursor);
}
}
findPrev(cursor) {
let prev;
1 year ago
if ((prev = cursor.previousSibling)) {
if (prev.tagName === "A") {
return prev;
1 year ago
} else if (prev.tagName === "SPAN") {
// pagination link
$.click(prev);
return this.findPrev(cursor);
1 year ago
} else if (prev.tagName === "DIV") {
// sub-list
if (prev.previousSibling.className.indexOf("open") >= 0) {
return this.findLast(prev) || this.findPrev(prev);
} else {
return this.findPrev(prev);
}
1 year ago
} else if (prev.tagName === "H6") {
// title
return this.findPrev(prev);
}
} else if (cursor.parentNode !== this.el) {
return this.findPrev(cursor.parentNode);
}
}
findLast(cursor) {
let last;
1 year ago
if (!(last = cursor.lastChild)) {
return;
}
1 year ago
if (last.tagName === "A") {
return last;
1 year ago
} else if (last.tagName === "SPAN" || last.tagName === "H6") {
// pagination link or title
return this.findPrev(last);
1 year ago
} else if (last.tagName === "DIV") {
// sub-list
return this.findLast(last);
}
}
onDown() {
let cursor;
if ((cursor = this.getCursor())) {
this.focusOnNextFrame(this.findNext(cursor));
} else {
1 year ago
this.focusOnNextFrame(this.findByTag("a"));
}
}
onUp() {
let cursor;
if ((cursor = this.getCursor())) {
this.focusOnNextFrame(this.findPrev(cursor));
} else {
1 year ago
this.focusOnNextFrame(this.findLastByTag("a"));
}
}
onLeft() {
const cursor = this.getCursor();
1 year ago
if (
cursor &&
!cursor.classList.contains(app.views.ListFold.activeClass) &&
cursor.parentNode !== this.el
) {
const prev = cursor.parentNode.previousSibling;
1 year ago
if (prev && prev.classList.contains(app.views.ListFold.targetClass)) {
this.focusOnNextFrame(cursor.parentNode.previousSibling);
}
}
}
onEnter() {
let cursor;
1 year ago
if ((cursor = this.getCursor())) {
$.click(cursor);
}
}
onSuperEnter() {
let cursor;
1 year ago
if ((cursor = this.getCursor())) {
$.popup(cursor);
}
}
onClick(event) {
1 year ago
if (event.which !== 1 || event.metaKey || event.ctrlKey) {
return;
}
const target = $.eventTarget(event);
1 year ago
if (target.tagName === "A") {
this.focus(target, { silent: true });
}
}
};
app.views.ListFocus.initClass();