Outlook_Addin_LLM/node_modules/keyborg/dist/esm/index.js

474 lines
14 KiB
JavaScript
Raw Normal View History

// src/WeakRefInstance.ts
var _canUseWeakRef = typeof WeakRef !== "undefined";
var WeakRefInstance = class {
constructor(instance) {
if (_canUseWeakRef && typeof instance === "object") {
this._weakRef = new WeakRef(instance);
} else {
this._instance = instance;
}
}
/**
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef/deref}
*/
deref() {
var _a, _b;
let instance;
if (this._weakRef) {
instance = (_a = this._weakRef) == null ? void 0 : _a.deref();
if (!instance) {
delete this._weakRef;
}
} else {
instance = this._instance;
if ((_b = instance == null ? void 0 : instance.isDisposed) == null ? void 0 : _b.call(instance)) {
delete this._instance;
}
}
return instance;
}
};
// src/FocusEvent.ts
var KEYBORG_FOCUSIN = "keyborg:focusin";
var KEYBORG_FOCUSOUT = "keyborg:focusout";
function canOverrideNativeFocus(win) {
const HTMLElement = win.HTMLElement;
const origFocus = HTMLElement.prototype.focus;
let isCustomFocusCalled = false;
HTMLElement.prototype.focus = function focus() {
isCustomFocusCalled = true;
};
const btn = win.document.createElement("button");
btn.focus();
HTMLElement.prototype.focus = origFocus;
return isCustomFocusCalled;
}
var _canOverrideNativeFocus = false;
function nativeFocus(element) {
const focus = element.focus;
if (focus.__keyborgNativeFocus) {
focus.__keyborgNativeFocus.call(element);
} else {
element.focus();
}
}
function setupFocusEvent(win) {
const kwin = win;
if (!_canOverrideNativeFocus) {
_canOverrideNativeFocus = canOverrideNativeFocus(kwin);
}
const origFocus = kwin.HTMLElement.prototype.focus;
if (origFocus.__keyborgNativeFocus) {
return;
}
kwin.HTMLElement.prototype.focus = focus;
const shadowTargets = /* @__PURE__ */ new Set();
const focusOutHandler = (e) => {
const target = e.target;
if (!target) {
return;
}
const event = new CustomEvent(KEYBORG_FOCUSOUT, {
cancelable: true,
bubbles: true,
// Allows the event to bubble past an open shadow root
composed: true,
detail: {
originalEvent: e
}
});
target.dispatchEvent(event);
};
const focusInHandler = (e) => {
const target = e.target;
if (!target) {
return;
}
let node = e.composedPath()[0];
const currentShadows = /* @__PURE__ */ new Set();
while (node) {
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
currentShadows.add(node);
node = node.host;
} else {
node = node.parentNode;
}
}
for (const shadowRootWeakRef of shadowTargets) {
const shadowRoot = shadowRootWeakRef.deref();
if (!shadowRoot || !currentShadows.has(shadowRoot)) {
shadowTargets.delete(shadowRootWeakRef);
if (shadowRoot) {
shadowRoot.removeEventListener("focusin", focusInHandler, true);
shadowRoot.removeEventListener("focusout", focusOutHandler, true);
}
}
}
onFocusIn(target, e.relatedTarget || void 0);
};
const onFocusIn = (target, relatedTarget, originalEvent) => {
var _a;
const shadowRoot = target.shadowRoot;
if (shadowRoot) {
for (const shadowRootWeakRef of shadowTargets) {
if (shadowRootWeakRef.deref() === shadowRoot) {
return;
}
}
shadowRoot.addEventListener("focusin", focusInHandler, true);
shadowRoot.addEventListener("focusout", focusOutHandler, true);
shadowTargets.add(new WeakRefInstance(shadowRoot));
return;
}
const details = {
relatedTarget,
originalEvent
};
const event = new CustomEvent(KEYBORG_FOCUSIN, {
cancelable: true,
bubbles: true,
// Allows the event to bubble past an open shadow root
composed: true,
detail: details
});
event.details = details;
if (_canOverrideNativeFocus || data.lastFocusedProgrammatically) {
details.isFocusedProgrammatically = target === ((_a = data.lastFocusedProgrammatically) == null ? void 0 : _a.deref());
data.lastFocusedProgrammatically = void 0;
}
target.dispatchEvent(event);
};
const data = kwin.__keyborgData = {
focusInHandler,
focusOutHandler,
shadowTargets
};
kwin.document.addEventListener(
"focusin",
kwin.__keyborgData.focusInHandler,
true
);
kwin.document.addEventListener(
"focusout",
kwin.__keyborgData.focusOutHandler,
true
);
function focus() {
const keyborgNativeFocusEvent = kwin.__keyborgData;
if (keyborgNativeFocusEvent) {
keyborgNativeFocusEvent.lastFocusedProgrammatically = new WeakRefInstance(
this
);
}
return origFocus.apply(this, arguments);
}
let activeElement = kwin.document.activeElement;
while (activeElement && activeElement.shadowRoot) {
onFocusIn(activeElement);
activeElement = activeElement.shadowRoot.activeElement;
}
focus.__keyborgNativeFocus = origFocus;
}
function disposeFocusEvent(win) {
const kwin = win;
const proto = kwin.HTMLElement.prototype;
const origFocus = proto.focus.__keyborgNativeFocus;
const keyborgNativeFocusEvent = kwin.__keyborgData;
if (keyborgNativeFocusEvent) {
kwin.document.removeEventListener(
"focusin",
keyborgNativeFocusEvent.focusInHandler,
true
);
kwin.document.removeEventListener(
"focusout",
keyborgNativeFocusEvent.focusOutHandler,
true
);
for (const shadowRootWeakRef of keyborgNativeFocusEvent.shadowTargets) {
const shadowRoot = shadowRootWeakRef.deref();
if (shadowRoot) {
shadowRoot.removeEventListener(
"focusin",
keyborgNativeFocusEvent.focusInHandler,
true
);
shadowRoot.removeEventListener(
"focusout",
keyborgNativeFocusEvent.focusOutHandler,
true
);
}
}
keyborgNativeFocusEvent.shadowTargets.clear();
delete kwin.__keyborgData;
}
if (origFocus) {
proto.focus = origFocus;
}
}
function getLastFocusedProgrammatically(win) {
var _a;
const keyborgNativeFocusEvent = win.__keyborgData;
return keyborgNativeFocusEvent ? ((_a = keyborgNativeFocusEvent.lastFocusedProgrammatically) == null ? void 0 : _a.deref()) || null : void 0;
}
// src/Keyborg.ts
var _dismissTimeout = 500;
var _lastId = 0;
var KeyborgCore = class {
constructor(win, props) {
this._isNavigatingWithKeyboard_DO_NOT_USE = false;
this._onFocusIn = (e) => {
if (this._isMouseOrTouchUsedTimer) {
return;
}
if (this.isNavigatingWithKeyboard) {
return;
}
const details = e.detail;
if (!details.relatedTarget) {
return;
}
if (details.isFocusedProgrammatically || details.isFocusedProgrammatically === void 0) {
return;
}
this.isNavigatingWithKeyboard = true;
};
this._onMouseDown = (e) => {
if (e.buttons === 0 || e.clientX === 0 && e.clientY === 0 && e.screenX === 0 && e.screenY === 0) {
return;
}
this._onMouseOrTouch();
};
this._onMouseOrTouch = () => {
const win = this._win;
if (win) {
if (this._isMouseOrTouchUsedTimer) {
win.clearTimeout(this._isMouseOrTouchUsedTimer);
}
this._isMouseOrTouchUsedTimer = win.setTimeout(() => {
delete this._isMouseOrTouchUsedTimer;
}, 1e3);
}
this.isNavigatingWithKeyboard = false;
};
this._onKeyDown = (e) => {
const isNavigatingWithKeyboard = this.isNavigatingWithKeyboard;
if (isNavigatingWithKeyboard) {
if (this._shouldDismissKeyboardNavigation(e)) {
this._scheduleDismiss();
}
} else {
if (this._shouldTriggerKeyboardNavigation(e)) {
this.isNavigatingWithKeyboard = true;
}
}
};
this.id = "c" + ++_lastId;
this._win = win;
const doc = win.document;
if (props) {
const triggerKeys = props.triggerKeys;
const dismissKeys = props.dismissKeys;
if (triggerKeys == null ? void 0 : triggerKeys.length) {
this._triggerKeys = new Set(triggerKeys);
}
if (dismissKeys == null ? void 0 : dismissKeys.length) {
this._dismissKeys = new Set(dismissKeys);
}
}
doc.addEventListener(KEYBORG_FOCUSIN, this._onFocusIn, true);
doc.addEventListener("mousedown", this._onMouseDown, true);
win.addEventListener("keydown", this._onKeyDown, true);
doc.addEventListener("touchstart", this._onMouseOrTouch, true);
doc.addEventListener("touchend", this._onMouseOrTouch, true);
doc.addEventListener("touchcancel", this._onMouseOrTouch, true);
setupFocusEvent(win);
}
get isNavigatingWithKeyboard() {
return this._isNavigatingWithKeyboard_DO_NOT_USE;
}
set isNavigatingWithKeyboard(val) {
if (this._isNavigatingWithKeyboard_DO_NOT_USE !== val) {
this._isNavigatingWithKeyboard_DO_NOT_USE = val;
this.update();
}
}
dispose() {
const win = this._win;
if (win) {
if (this._isMouseOrTouchUsedTimer) {
win.clearTimeout(this._isMouseOrTouchUsedTimer);
this._isMouseOrTouchUsedTimer = void 0;
}
if (this._dismissTimer) {
win.clearTimeout(this._dismissTimer);
this._dismissTimer = void 0;
}
disposeFocusEvent(win);
const doc = win.document;
doc.removeEventListener(KEYBORG_FOCUSIN, this._onFocusIn, true);
doc.removeEventListener("mousedown", this._onMouseDown, true);
win.removeEventListener("keydown", this._onKeyDown, true);
doc.removeEventListener("touchstart", this._onMouseOrTouch, true);
doc.removeEventListener("touchend", this._onMouseOrTouch, true);
doc.removeEventListener("touchcancel", this._onMouseOrTouch, true);
delete this._win;
}
}
isDisposed() {
return !!this._win;
}
/**
* Updates all keyborg instances with the keyboard navigation state
*/
update() {
var _a, _b;
const keyborgs = (_b = (_a = this._win) == null ? void 0 : _a.__keyborg) == null ? void 0 : _b.refs;
if (keyborgs) {
for (const id of Object.keys(keyborgs)) {
Keyborg.update(keyborgs[id], this.isNavigatingWithKeyboard);
}
}
}
/**
* @returns whether the keyboard event should trigger keyboard navigation mode
*/
_shouldTriggerKeyboardNavigation(e) {
var _a;
if (e.key === "Tab") {
return true;
}
const activeElement = (_a = this._win) == null ? void 0 : _a.document.activeElement;
const isTriggerKey = !this._triggerKeys || this._triggerKeys.has(e.keyCode);
const isEditable = activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA" || activeElement.isContentEditable);
return isTriggerKey && !isEditable;
}
/**
* @returns whether the keyboard event should dismiss keyboard navigation mode
*/
_shouldDismissKeyboardNavigation(e) {
var _a;
return (_a = this._dismissKeys) == null ? void 0 : _a.has(e.keyCode);
}
_scheduleDismiss() {
const win = this._win;
if (win) {
if (this._dismissTimer) {
win.clearTimeout(this._dismissTimer);
this._dismissTimer = void 0;
}
const was = win.document.activeElement;
this._dismissTimer = win.setTimeout(() => {
this._dismissTimer = void 0;
const cur = win.document.activeElement;
if (was && cur && was === cur) {
this.isNavigatingWithKeyboard = false;
}
}, _dismissTimeout);
}
}
};
var Keyborg = class _Keyborg {
constructor(win, props) {
this._cb = [];
this._id = "k" + ++_lastId;
this._win = win;
const current = win.__keyborg;
if (current) {
this._core = current.core;
current.refs[this._id] = this;
} else {
this._core = new KeyborgCore(win, props);
win.__keyborg = {
core: this._core,
refs: { [this._id]: this }
};
}
}
static create(win, props) {
return new _Keyborg(win, props);
}
static dispose(instance) {
instance.dispose();
}
/**
* Updates all subscribed callbacks with the keyboard navigation state
*/
static update(instance, isNavigatingWithKeyboard) {
instance._cb.forEach((callback) => callback(isNavigatingWithKeyboard));
}
dispose() {
var _a;
const current = (_a = this._win) == null ? void 0 : _a.__keyborg;
if (current == null ? void 0 : current.refs[this._id]) {
delete current.refs[this._id];
if (Object.keys(current.refs).length === 0) {
current.core.dispose();
delete this._win.__keyborg;
}
} else if (process.env.NODE_ENV !== "production") {
console.error(
`Keyborg instance ${this._id} is being disposed incorrectly.`
);
}
this._cb = [];
delete this._core;
delete this._win;
}
/**
* @returns Whether the user is navigating with keyboard
*/
isNavigatingWithKeyboard() {
var _a;
return !!((_a = this._core) == null ? void 0 : _a.isNavigatingWithKeyboard);
}
/**
* @param callback - Called when the keyboard navigation state changes
*/
subscribe(callback) {
this._cb.push(callback);
}
/**
* @param callback - Registered with subscribe
*/
unsubscribe(callback) {
const index = this._cb.indexOf(callback);
if (index >= 0) {
this._cb.splice(index, 1);
}
}
/**
* Manually set the keyboard navigtion state
*/
setVal(isNavigatingWithKeyboard) {
if (this._core) {
this._core.isNavigatingWithKeyboard = isNavigatingWithKeyboard;
}
}
};
function createKeyborg(win, props) {
return Keyborg.create(win, props);
}
function disposeKeyborg(instance) {
Keyborg.dispose(instance);
}
// src/index.ts
var version = "2.6.0";
export {
KEYBORG_FOCUSIN,
KEYBORG_FOCUSOUT,
createKeyborg,
disposeKeyborg,
getLastFocusedProgrammatically,
nativeFocus,
version
};
/*!
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
//# sourceMappingURL=index.js.map