verstak
Version:
Verstak - Front-End Library
185 lines (184 loc) • 8.53 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { options, atomic, LoggingLevel, Transaction } from "reactronic";
import { objectHasMember } from "../ElUtils.js";
import { grabElementDataList, SymDataForSensor } from "./DataForSensor.js";
import { HtmlElementSensor } from "./HtmlElementSensor.js";
export class FocusSensor extends HtmlElementSensor {
constructor(element, windowSensor) {
super(element, windowSensor);
this.activeData = undefined;
this.oldActiveData = undefined;
this.contextElementDataList = [];
}
setActiveData(data, debugHint = "") {
var _a, _b;
if (data !== this.activeData) {
const activeData = this.activeData;
if (activeData !== undefined && objectHasMember(activeData, "isEditMode")) {
activeData.isEditMode = false;
(_a = activeData.onFocusOut) === null || _a === void 0 ? void 0 : _a.call(activeData, this);
}
if (data !== undefined) {
if (objectHasMember(data, "isEditMode")) {
data.isEditMode = true;
(_b = data.onFocusIn) === null || _b === void 0 ? void 0 : _b.call(data, this);
}
}
this.oldActiveData = activeData;
this.activeData = data;
}
}
listen(enabled = true) {
const t = Transaction.current;
Transaction.outside(() => {
t.whenFinished(true).then(() => {
const element = this.sourceElement;
if (enabled) {
element.addEventListener("focusin", this.onFocusIn.bind(this), { capture: true });
element.addEventListener("focusout", this.onFocusOut.bind(this), { capture: true });
element.addEventListener("mousedown", this.onMouseDown.bind(this), { capture: true });
}
else {
element.removeEventListener("focusin", this.onFocusIn.bind(this), { capture: true });
element.removeEventListener("focusout", this.onFocusOut.bind(this), { capture: true });
element.removeEventListener("mousedown", this.onMouseDown.bind(this), { capture: true });
}
}, e => { });
});
}
reset() {
this.preventDefault = false;
this.stopPropagation = false;
this.revision++;
}
onFocusIn(e) {
this.doFocusIn(e);
this.setPreventDefaultAndStopPropagation(e);
}
onFocusOut(e) {
this.doFocusOut(e);
this.setPreventDefaultAndStopPropagation(e);
}
onMouseDown(e) {
this.doMouseDown(e);
}
doFocusIn(e) {
var _a;
const path = e.composedPath();
const { dataList: focusDataList, activeData: focusActiveData, window } = grabElementDataList(path, SymDataForSensor, "focus", this.elementDataList, false, e => document.activeElement === e);
this.elementDataList = focusDataList;
this.setActiveData(focusActiveData);
(_a = this.windowSensor) === null || _a === void 0 ? void 0 : _a.setActiveWindow(window);
const { dataList: contextDataList } = grabElementDataList(path, SymDataForSensor, "context", this.contextElementDataList, true);
this.contextElementDataList = toggleContextRefs(this, this.contextElementDataList, contextDataList);
this.reset();
}
doFocusOut(e) {
var _a;
const isLosingFocus = e.relatedTarget === null;
if (isLosingFocus) {
const path = e.composedPath();
const { dataList } = grabElementDataList(path, SymDataForSensor, "focus", this.elementDataList, true);
this.elementDataList = dataList;
const filteredElementDataList = dataList.filter(x => x !== this.activeData);
if (filteredElementDataList.length > 0) {
this.trySetEditMode(filteredElementDataList[0], " └─");
}
else {
const defaultData = this.getDefaultSensorData();
if ((defaultData === null || defaultData === void 0 ? void 0 : defaultData.focus) !== undefined) {
this.trySetEditMode(defaultData.focus, " └─");
}
else {
this.setActiveData(undefined);
}
(_a = this.windowSensor) === null || _a === void 0 ? void 0 : _a.setActiveWindow(defaultData === null || defaultData === void 0 ? void 0 : defaultData.window);
}
this.contextElementDataList = toggleContextRefs(this, this.contextElementDataList, []);
this.reset();
}
else {
}
}
doMouseDown(e) {
const path = e.composedPath();
const isClickInsideTabIndexedElement = path.find(el => el !== document.body && el.tabIndex >= 0) !== undefined;
if (path.length > 0 && !isClickInsideTabIndexedElement) {
const { dataList } = grabElementDataList(path, SymDataForSensor, "focus", this.elementDataList, true);
this.elementDataList = dataList;
if (dataList.length > 0) {
this.trySetEditMode(dataList[0], "└─");
e.preventDefault();
}
const { dataList: contextDataList } = grabElementDataList(path, SymDataForSensor, "context", this.contextElementDataList, true);
this.contextElementDataList = toggleContextRefs(this, this.contextElementDataList, contextDataList);
this.reset();
}
else {
}
}
trySetEditMode(candidateData, indent = "") {
if (candidateData !== undefined && objectHasMember(candidateData, "isEditMode")) {
candidateData.isEditMode = true;
}
}
}
__decorate([
atomic,
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, String]),
__metadata("design:returntype", void 0)
], FocusSensor.prototype, "setActiveData", null);
__decorate([
atomic,
__metadata("design:type", Function),
__metadata("design:paramtypes", [Boolean]),
__metadata("design:returntype", void 0)
], FocusSensor.prototype, "listen", null);
__decorate([
atomic,
options({ logging: LoggingLevel.Off }),
__metadata("design:type", Function),
__metadata("design:paramtypes", [FocusEvent]),
__metadata("design:returntype", void 0)
], FocusSensor.prototype, "doFocusIn", null);
__decorate([
atomic,
__metadata("design:type", Function),
__metadata("design:paramtypes", [FocusEvent]),
__metadata("design:returntype", void 0)
], FocusSensor.prototype, "doFocusOut", null);
__decorate([
atomic,
options({ logging: LoggingLevel.Off }),
__metadata("design:type", Function),
__metadata("design:paramtypes", [MouseEvent]),
__metadata("design:returntype", void 0)
], FocusSensor.prototype, "doMouseDown", null);
function toggleContextRefs(focusSensor, existing, updated) {
if (updated !== existing) {
existing.forEach(x => {
var _a;
if (objectHasMember(x, "contextToggle") && x.contextToggle && x.contextToggle.valueOn !== x.contextToggle.valueOff)
x.contextToggle.variable = x.contextToggle.valueOff;
if (objectHasMember(x, "onContextOut"))
(_a = x.onContextOut) === null || _a === void 0 ? void 0 : _a.call(x, focusSensor);
});
updated.forEach(x => {
var _a;
if (objectHasMember(x, "contextToggle") && x.contextToggle)
x.contextToggle.variable = x.contextToggle.valueOn;
if (objectHasMember(x, "onContextIn"))
(_a = x.onContextIn) === null || _a === void 0 ? void 0 : _a.call(x, focusSensor);
});
}
return updated;
}