@openui5/sap.ui.core
Version:
OpenUI5 Core Library sap.ui.core
174 lines (134 loc) • 4.86 kB
JavaScript
/*!
* OpenUI5
* (c) Copyright 2009-2023 SAP SE or an SAP affiliate company.
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
*/
sap.ui.define([
"sap/ui/core/Core",
"sap/ui/base/Object",
'sap/ui/Device'
],
function(Core, BaseObject, Device) {
"use strict";
var AccessKeysEnablement = BaseObject.extend("sap.ui.core.AccessKeysEnablement", /** @lends sap.ui.core.AccessKeysEnablement.prototype */ {});
AccessKeysEnablement.controlRegistry = new Set();
AccessKeysEnablement.CSS_CLASS = "sapUiAccKeysHighlighDom";
AccessKeysEnablement.bListenersAttached = false;
var fnHighLightControls = function () {
var fnHLStart = function(oControl) {
var bDisabled = oControl.getEnabled && !oControl.getEnabled();
// disabled controls should not be highlighted
if (bDisabled) {
return;
}
if (oControl) {
oControl.setProperty("highlightAccKeysRef", true);
oControl.onAccKeysHighlightStart && oControl.onAccKeysHighlightStart();
}
};
AccessKeysEnablement.controlRegistry.forEach(function(oElement) {
fnHLStart(oElement);
});
};
var fnStopHighlight = function () {
var fnHLEnd = function(oControl) {
if (oControl) {
oControl.setProperty("highlightAccKeysRef", false);
oControl.onAccKeysHighlightStart && oControl.onAccKeysHighlightEnd();
}
};
AccessKeysEnablement.controlRegistry.forEach(function (oElement) {
fnHLEnd(oElement);
});
};
AccessKeysEnablement.attachKeydownListeners = function () {
document.addEventListener("keydown", function(initialKeydownEvent) {
if (this.hasHighlightedElements()) {
initialKeydownEvent.preventDefault();
}
this.handleHighlightStart(initialKeydownEvent);
document.addEventListener("keydown", function(postKeydownEvent) {
if (this.hasHighlightedElements()) {
postKeydownEvent.preventDefault();
}
}.bind(this), { once: true });
}.bind(this));
document.addEventListener("keyup", function(event) {
this.handleHighlightEnd(event);
}.bind(this));
window.addEventListener("blur", function() {
this.handleHighlightEnd(true);
}.bind(this));
};
AccessKeysEnablement.handleHighlightStart = function (oEvent) {
var bTriggerHighlight = oEvent.altKey;
var sCharFromKey = oEvent.key;
if (bTriggerHighlight) {
fnHighLightControls();
if (this.hasHighlightedElements()) {
var aElements = this.getElementToBeFocused(sCharFromKey);
if (!aElements.length) {
return;
}
var oFocusedElement = document.activeElement;
var bBackNavigation = oEvent.shiftKey;
var iCurrentFocusedItemIndex = aElements.indexOf(oFocusedElement);
if (bBackNavigation) {
var oPreviousFocusableElement = aElements[iCurrentFocusedItemIndex - 1];
if (oPreviousFocusableElement) {
oPreviousFocusableElement.focus();
} else if (iCurrentFocusedItemIndex === 0) {
aElements[aElements.length - 1].focus();
}
} else {
var oNextFocusableElement = aElements[iCurrentFocusedItemIndex + 1];
if (oNextFocusableElement) {
oNextFocusableElement.focus();
} else if (iCurrentFocusedItemIndex === (aElements.length - 1)) {
aElements[0].focus();
}
}
}
}
};
AccessKeysEnablement.hasHighlightedElements = function () {
return document.getElementsByClassName(AccessKeysEnablement.CSS_CLASS).length;
};
AccessKeysEnablement.handleHighlightEnd = function (oEvent, bWindowBlur) {
if (!oEvent.altKey || bWindowBlur) {
fnStopHighlight();
}
};
AccessKeysEnablement.getElementToBeFocused = function (sText) {
return [].filter.call(document.querySelectorAll("[data-ui5-accesskey='" + sText.toLowerCase() + "']"), function(oDom) {
var oControl = sap.ui.getCore().byId(oDom.getAttribute("id"));
var bEnabled = oControl.getEnabled ? oControl.getEnabled() : true;
var bVisible = oControl.getVisible();
return bEnabled && bVisible;
}).map(function(oElement) {
oElement = sap.ui.getCore().byId(oElement.getAttribute("id"));
return oElement.getAccessKeysFocusTarget ? oElement.getAccessKeysFocusTarget() : oElement.getFocusDomRef();
});
};
AccessKeysEnablement.registerControl = function (oControl) {
var bEnableAccKeys = Core.getConfiguration().getAccKeys();
/* Disable the feature for Mac OS due to depreacated KeyCode API */
if (Device.os.macintosh) {
return;
}
this.controlRegistry.add(oControl);
if (bEnableAccKeys && !this.bListenersAttached) {
this.attachKeydownListeners();
AccessKeysEnablement.bListenersAttached = true;
}
var fnExit = oControl.exit;
oControl.exit = function () {
AccessKeysEnablement.controlRegistry.delete(oControl);
fnExit && fnExit.call(oControl);
};
};
AccessKeysEnablement.deregisterControl = function (oControl) {
AccessKeysEnablement.registerControl.delete();
};
return AccessKeysEnablement;
});