diff --git a/apps/common/main/lib/component/HintManager.js b/apps/common/main/lib/component/HintManager.js
new file mode 100644
index 000000000..c06dba5aa
--- /dev/null
+++ b/apps/common/main/lib/component/HintManager.js
@@ -0,0 +1,154 @@
+/*
+ *
+ * (c) Copyright Ascensio System SIA 2010-2021
+ *
+ * This program is a free software product. You can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License (AGPL)
+ * version 3 as published by the Free Software Foundation. In accordance with
+ * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
+ * that Ascensio System SIA expressly excludes the warranty of non-infringement
+ * of any third-party rights.
+ *
+ * This program is distributed WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
+ * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
+ *
+ * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
+ * street, Riga, Latvia, EU, LV-1050.
+ *
+ * The interactive user interfaces in modified source and object code versions
+ * of the Program must display Appropriate Legal Notices, as required under
+ * Section 5 of the GNU AGPL version 3.
+ *
+ * Pursuant to Section 7(b) of the License you must retain the original Product
+ * logo when distributing the program. Pursuant to Section 7(e) we decline to
+ * grant you any rights under trademark law for use of our trademarks.
+ *
+ * All the Product's GUI elements, including illustrations and icon sets, as
+ * well as technical writing content are licensed under the terms of the
+ * Creative Commons Attribution-ShareAlike 4.0 International. See the License
+ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
+ *
+ */
+/**
+ * HintManager.js
+ *
+ * Created by Julia Radzhabova on 21.04.2021
+ * Copyright (c) 2021 Ascensio System SIA. All rights reserved.
+ *
+ */
+
+
+if (Common === undefined)
+ var Common = {};
+
+if (Common.UI === undefined) {
+ Common.UI = {};
+}
+
+Common.UI.HintManager = new(function() {
+ var _isAlt = false,
+ _hintVisible = false,
+ _currentLevel = -1,
+ _controls = [],
+ _currentControls = [],
+ _currentHints = [];
+
+ var _showHints = function() {
+ _hintVisible = !_hintVisible;
+ if (_hintVisible) {
+ _currentLevel++;
+ _getHints();
+ } else {
+ _removeHints();
+ _currentLevel--;
+ }
+ };
+
+ var _getControls = function() {
+ if (!_controls[_currentLevel + 1]) {
+ _controls[_currentLevel + 1] = $('[data-hint=' + (_currentLevel + 1) + ']').toArray();
+ if (_currentLevel==0 && !_controls[_currentLevel])
+ _controls[_currentLevel] = $('[data-hint=0]').toArray();
+ }
+
+ _currentControls = [];
+ var arr = [];
+ if (_currentLevel==0) {
+ arr = arr.concat(_controls[_currentLevel]);
+ !$('.toolbar-fullview-panel').is(':visible') && (arr = arr.concat(_controls[_currentLevel+1]));
+ } else
+ arr = _controls[_currentLevel+1];
+ arr.forEach(function(item, index) {
+ var el = $(item);
+ if (el.is(':visible')) {
+ el.attr('data-hint-title', String.fromCharCode(65 + index));
+ _currentControls.push(el);
+ }
+ });
+ return _currentControls;
+ };
+
+ var _getHints = function() {
+ _removeHints();
+ _getControls();
+ _currentControls.forEach(function(item, index) {
+ var offset = item.offset();
+ var hint = $('
' + item.attr('data-hint-title') + '
');
+ var direction = item.attr('data-hint-direction');
+ if (direction=='right')
+ hint.css({left: offset.left + item.outerWidth(), top: offset.top + (item.outerHeight()-20)/2});
+ else
+ hint.css({left: offset.left + (item.outerWidth() - 20)/2, top: offset.top + item.outerHeight()});
+ $(document.body).append(hint);
+
+ _currentHints.push(hint);
+ });
+ };
+
+ var _removeHints = function() {
+ _currentHints && _currentHints.forEach(function(item) {
+ item.remove()
+ });
+ };
+
+ var _init = function() {
+ $(document).on('keyup', function(e) {
+ if (e.keyCode == Common.UI.Keys.ALT &&_isAlt) {
+ console.log(' keyup ALT');
+ e.preventDefault();
+ _showHints();
+ }
+ _isAlt = false;
+ });
+ $(document).on('keydown', function(e) {
+ console.log('keydown ' + e.keyCode);
+ if (_hintVisible) {
+ if (e.keyCode == Common.UI.Keys.ESC ) {
+ _showHints();
+ } else if ((e.keyCode > 47 && e.keyCode < 58 || e.keyCode > 64 && e.keyCode < 91) && e.key) {
+ var curr;
+ for (var i = 0; i < _currentControls.length; i++) {
+ var item = _currentControls[i];
+ if (item.attr('data-hint-title').charCodeAt(0) == e.keyCode) { // for latin chars
+ // if (item.attr('data-hint-title').charAt(0) == e.key.toUpperCase()) { // for all chars
+ curr = item;
+ break;
+ }
+ }
+ if (curr) {
+ _showHints();
+ curr && curr.trigger(jQuery.Event('click', {which: 1}));
+ }
+ }
+ e.preventDefault();
+ }
+
+ _isAlt = (e.keyCode == Common.UI.Keys.ALT);
+ });
+ };
+
+ return {
+ init: _init
+ }
+})();
\ No newline at end of file
diff --git a/apps/common/main/lib/component/Mixtbar.js b/apps/common/main/lib/component/Mixtbar.js
index e166d79f1..165a1c653 100644
--- a/apps/common/main/lib/component/Mixtbar.js
+++ b/apps/common/main/lib/component/Mixtbar.js
@@ -100,7 +100,7 @@ define([
'' +
'<% if (items[i].extcls) print(\' \' + items[i].extcls) %>">' +
- '<%= items[i].caption %>' +
+ '<%= items[i].caption %>' +
'' +
'<% } %>' +
'<% } %>' +
@@ -316,7 +316,7 @@ define([
return config.tabs[index].action;
}
- var _tabTemplate = _.template('<%= caption %>');
+ var _tabTemplate = _.template('<%= caption %>');
config.tabs[after + 1] = tab;
var _after_action = _get_tab_action(after);
diff --git a/apps/common/main/resources/less/hint-manager.less b/apps/common/main/resources/less/hint-manager.less
new file mode 100644
index 000000000..7f61ca418
--- /dev/null
+++ b/apps/common/main/resources/less/hint-manager.less
@@ -0,0 +1,12 @@
+.hint-div {
+ position: absolute;
+ z-index: @zindex-navbar + 3;
+ width: 20px;
+ text-align: center;
+ background-color: @background-notification-popover-ie;
+ background-color: @background-notification-popover;
+ color: @text-normal;
+ .box-shadow(0 4px 15px -2px rgba(0, 0, 0, 0.5));
+ font-size: 12px;
+ line-height: 18px;
+}
\ No newline at end of file
diff --git a/apps/documenteditor/main/app/controller/Main.js b/apps/documenteditor/main/app/controller/Main.js
index d83c38d90..dcf97d45a 100644
--- a/apps/documenteditor/main/app/controller/Main.js
+++ b/apps/documenteditor/main/app/controller/Main.js
@@ -52,7 +52,8 @@ define([
'common/main/lib/view/UserNameDialog',
'common/main/lib/util/LocalStorage',
'documenteditor/main/app/collection/ShapeGroups',
- 'documenteditor/main/app/collection/EquationGroups'
+ 'documenteditor/main/app/collection/EquationGroups',
+ 'common/main/lib/component/HintManager'
], function () {
'use strict';
@@ -174,6 +175,7 @@ define([
this.api = this.getApplication().getController('Viewport').getApi();
Common.UI.FocusManager.init();
+ Common.UI.HintManager.init();
Common.UI.Themes.init(this.api);
if (this.api){
diff --git a/apps/documenteditor/main/app/template/LeftMenu.template b/apps/documenteditor/main/app/template/LeftMenu.template
index 96827d295..18e31b081 100644
--- a/apps/documenteditor/main/app/template/LeftMenu.template
+++ b/apps/documenteditor/main/app/template/LeftMenu.template
@@ -1,14 +1,14 @@