@yaronelh/accessibilitytool 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/CHANGELOG.md +162 -0
  2. package/LICENSE +21 -0
  3. package/README.md +373 -0
  4. package/dist/common.d.ts +22 -0
  5. package/dist/common.js +215 -0
  6. package/dist/common.js.map +1 -0
  7. package/dist/core/event-utils.d.ts +2 -0
  8. package/dist/core/event-utils.js +15 -0
  9. package/dist/core/event-utils.js.map +1 -0
  10. package/dist/core/hotkeys.d.ts +3 -0
  11. package/dist/core/hotkeys.js +35 -0
  12. package/dist/core/hotkeys.js.map +1 -0
  13. package/dist/core/icon-assets.d.ts +13 -0
  14. package/dist/core/icon-assets.js +148 -0
  15. package/dist/core/icon-assets.js.map +1 -0
  16. package/dist/core/options.d.ts +6 -0
  17. package/dist/core/options.js +58 -0
  18. package/dist/core/options.js.map +1 -0
  19. package/dist/core/security.d.ts +3 -0
  20. package/dist/core/security.js +45 -0
  21. package/dist/core/security.js.map +1 -0
  22. package/dist/core/session.d.ts +14 -0
  23. package/dist/core/session.js +43 -0
  24. package/dist/core/session.js.map +1 -0
  25. package/dist/interfaces/accessibility.interface.d.ts +208 -0
  26. package/dist/interfaces/accessibility.interface.js +23 -0
  27. package/dist/interfaces/accessibility.interface.js.map +1 -0
  28. package/dist/interfaces/common.interface.d.ts +39 -0
  29. package/dist/interfaces/common.interface.js +3 -0
  30. package/dist/interfaces/common.interface.js.map +1 -0
  31. package/dist/interfaces/menu.interface.d.ts +18 -0
  32. package/dist/interfaces/menu.interface.js +3 -0
  33. package/dist/interfaces/menu.interface.js.map +1 -0
  34. package/dist/main.d.ts +84 -0
  35. package/dist/main.js +1771 -0
  36. package/dist/main.js.map +1 -0
  37. package/dist/menu-interface.d.ts +24 -0
  38. package/dist/menu-interface.js +561 -0
  39. package/dist/menu-interface.js.map +1 -0
  40. package/dist/storage.d.ts +9 -0
  41. package/dist/storage.js +40 -0
  42. package/dist/storage.js.map +1 -0
  43. package/dist-cjs/common.d.ts +22 -0
  44. package/dist-cjs/common.js +215 -0
  45. package/dist-cjs/common.js.map +1 -0
  46. package/dist-cjs/core/event-utils.d.ts +2 -0
  47. package/dist-cjs/core/event-utils.js +15 -0
  48. package/dist-cjs/core/event-utils.js.map +1 -0
  49. package/dist-cjs/core/hotkeys.d.ts +3 -0
  50. package/dist-cjs/core/hotkeys.js +35 -0
  51. package/dist-cjs/core/hotkeys.js.map +1 -0
  52. package/dist-cjs/core/icon-assets.d.ts +13 -0
  53. package/dist-cjs/core/icon-assets.js +148 -0
  54. package/dist-cjs/core/icon-assets.js.map +1 -0
  55. package/dist-cjs/core/options.d.ts +6 -0
  56. package/dist-cjs/core/options.js +58 -0
  57. package/dist-cjs/core/options.js.map +1 -0
  58. package/dist-cjs/core/security.d.ts +3 -0
  59. package/dist-cjs/core/security.js +45 -0
  60. package/dist-cjs/core/security.js.map +1 -0
  61. package/dist-cjs/core/session.d.ts +14 -0
  62. package/dist-cjs/core/session.js +43 -0
  63. package/dist-cjs/core/session.js.map +1 -0
  64. package/dist-cjs/interfaces/accessibility.interface.d.ts +208 -0
  65. package/dist-cjs/interfaces/accessibility.interface.js +23 -0
  66. package/dist-cjs/interfaces/accessibility.interface.js.map +1 -0
  67. package/dist-cjs/interfaces/common.interface.d.ts +39 -0
  68. package/dist-cjs/interfaces/common.interface.js +3 -0
  69. package/dist-cjs/interfaces/common.interface.js.map +1 -0
  70. package/dist-cjs/interfaces/menu.interface.d.ts +18 -0
  71. package/dist-cjs/interfaces/menu.interface.js +3 -0
  72. package/dist-cjs/interfaces/menu.interface.js.map +1 -0
  73. package/dist-cjs/main.d.ts +84 -0
  74. package/dist-cjs/main.js +1771 -0
  75. package/dist-cjs/main.js.map +1 -0
  76. package/dist-cjs/menu-interface.d.ts +24 -0
  77. package/dist-cjs/menu-interface.js +561 -0
  78. package/dist-cjs/menu-interface.js.map +1 -0
  79. package/dist-cjs/storage.d.ts +9 -0
  80. package/dist-cjs/storage.js +40 -0
  81. package/dist-cjs/storage.js.map +1 -0
  82. package/package.json +82 -0
package/dist/main.js ADDED
@@ -0,0 +1,1771 @@
1
+ 'use strict';
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.Accessibility = void 0;
18
+ const common_js_1 = require("./common.js");
19
+ const event_utils_js_1 = require("./core/event-utils.js");
20
+ const hotkeys_js_1 = require("./core/hotkeys.js");
21
+ const options_js_1 = require("./core/options.js");
22
+ const icon_assets_js_1 = require("./core/icon-assets.js");
23
+ const security_js_1 = require("./core/security.js");
24
+ const session_js_1 = require("./core/session.js");
25
+ const accessibility_interface_js_1 = require("./interfaces/accessibility.interface.js");
26
+ const menu_interface_js_1 = require("./menu-interface.js");
27
+ const storage_js_1 = require("./storage.js");
28
+ class Accessibility {
29
+ static CSS_CLASS_NAME = '_access-main-css';
30
+ static MENU_WIDTH = 'clamp(18rem, 30vw, 22rem)';
31
+ static MENU_ID = '_access-menu-panel';
32
+ static MENU_LABEL_ID = '_access-menu-title';
33
+ _isReading;
34
+ _common;
35
+ _storage;
36
+ _options;
37
+ _sessionState;
38
+ _htmlInitFS;
39
+ _body;
40
+ _html;
41
+ _icon;
42
+ _menu;
43
+ _htmlOrgFontSize;
44
+ _stateValues;
45
+ _recognition; // SpeechRecognition;
46
+ _speechToTextTarget;
47
+ _onKeyDownBind;
48
+ _fixedDefaultFont;
49
+ menuInterface;
50
+ options;
51
+ constructor(options = {}) {
52
+ this._common = new common_js_1.Common();
53
+ this._storage = new storage_js_1.Storage();
54
+ this.menuInterface = new menu_interface_js_1.MenuInterface(this);
55
+ this._fixedDefaultFont = this._common.getFixedFont('Material Icons');
56
+ this._options = this.defaultOptions;
57
+ this.options = this._common.extend(this._options, options);
58
+ this.addModuleOrderIfNotDefined();
59
+ this.addDefaultOptions(options);
60
+ // Consider adding this:
61
+ // if (options) {
62
+ // if (!options.textToSpeechLang && document.querySelector('html').getAttribute('lang')) {
63
+ // this.options.textToSpeechLang = document.querySelector('html').getAttribute('lang')
64
+ // }
65
+ // }
66
+ this.disabledUnsupportedFeatures();
67
+ this._onKeyDownBind = this.onKeyDown.bind(this);
68
+ this._sessionState = {
69
+ textSize: 0,
70
+ textSpace: 0,
71
+ lineHeight: 0,
72
+ invertColors: false,
73
+ grayHues: false,
74
+ underlineLinks: false,
75
+ bigCursor: false,
76
+ readingGuide: false
77
+ };
78
+ if (this.shouldUseEmojiIcons()) {
79
+ this.fontFallback();
80
+ this.build();
81
+ }
82
+ else if ((this.options.icon.fontFaceSrc || []).length === 0) {
83
+ this.build();
84
+ }
85
+ else {
86
+ this._common.injectIconsFont(this.options.icon.fontFaceSrc, (hasError) => {
87
+ this.build();
88
+ if (this.options.icon.fontFamilyValidation) {
89
+ setTimeout(() => {
90
+ this._common.isFontLoaded(this.options.icon.fontFamilyValidation, (isLoaded) => {
91
+ if (!isLoaded || hasError) {
92
+ console.log('!isLoaded || hasError', !isLoaded || hasError);
93
+ this._common.warn(`${this.options.icon.fontFamilyValidation} font was not loaded, using emojis instead`);
94
+ this.fontFallback();
95
+ this.destroy();
96
+ this.build();
97
+ }
98
+ });
99
+ });
100
+ }
101
+ });
102
+ }
103
+ if (this.options.modules.speechToText) {
104
+ window.addEventListener('beforeunload', () => {
105
+ if (this._isReading) {
106
+ window.speechSynthesis.cancel();
107
+ this._isReading = false;
108
+ }
109
+ });
110
+ }
111
+ }
112
+ hasRemoteFontSources() {
113
+ return (this.options.icon.fontFaceSrc || []).some((src) => /^https?:\/\//i.test(src));
114
+ }
115
+ shouldUseEmojiIcons() {
116
+ if (this.options.icon.useEmojis)
117
+ return true;
118
+ const hasRemoteFontSources = this.hasRemoteFontSources();
119
+ if (hasRemoteFontSources && !this.options.icon.allowRemoteFonts) {
120
+ this._common.warn('remote icon font loading is disabled by default; set icon.allowRemoteFonts to true to opt in');
121
+ return true;
122
+ }
123
+ const hasFontSources = (this.options.icon.fontFaceSrc || []).length > 0;
124
+ const hasLocalFontClass = typeof this.options.icon.fontClass === 'string' && this.options.icon.fontClass !== '';
125
+ if (!hasFontSources && !hasLocalFontClass)
126
+ return true;
127
+ return false;
128
+ }
129
+ get stateValues() {
130
+ return this._stateValues;
131
+ }
132
+ set stateValues(value) {
133
+ this._stateValues = value;
134
+ }
135
+ get html() {
136
+ return this._html;
137
+ }
138
+ get body() {
139
+ return this._body;
140
+ }
141
+ get sessionState() {
142
+ return this._sessionState;
143
+ }
144
+ set sessionState(value) {
145
+ this._sessionState = value;
146
+ }
147
+ get common() {
148
+ return this._common;
149
+ }
150
+ get recognition() {
151
+ return this._recognition;
152
+ }
153
+ get isReading() {
154
+ return this._isReading;
155
+ }
156
+ set isReading(value) {
157
+ this._isReading = value;
158
+ }
159
+ get fixedDefaultFont() {
160
+ return this._fixedDefaultFont;
161
+ }
162
+ // Default options
163
+ get defaultOptions() {
164
+ const res = {
165
+ icon: {
166
+ img: '♿',
167
+ fontFaceSrc: [],
168
+ fontClass: '',
169
+ useEmojis: true,
170
+ allowRemoteFonts: false,
171
+ closeIcon: 'close',
172
+ resetIcon: 'refresh'
173
+ },
174
+ hotkeys: {
175
+ enabled: false,
176
+ helpTitles: true,
177
+ keys: {
178
+ toggleMenu: ['ctrlKey', 'altKey', 65],
179
+ invertColors: ['ctrlKey', 'altKey', 73],
180
+ grayHues: ['ctrlKey', 'altKey', 71],
181
+ underlineLinks: ['ctrlKey', 'altKey', 85],
182
+ bigCursor: ['ctrlKey', 'altKey', 67],
183
+ readingGuide: ['ctrlKey', 'altKey', 82],
184
+ textToSpeech: ['ctrlKey', 'altKey', 84],
185
+ speechToText: ['ctrlKey', 'altKey', 83],
186
+ disableAnimations: ['ctrlKey', 'altKey', 81]
187
+ }
188
+ },
189
+ guide: {
190
+ cBorder: '#20ff69',
191
+ cBackground: '#000000',
192
+ height: '12px'
193
+ },
194
+ suppressCssInjection: false,
195
+ suppressDomInjection: false,
196
+ labels: {
197
+ resetTitle: 'Reset',
198
+ closeTitle: 'Close',
199
+ menuTitle: 'Accessibility Options',
200
+ increaseText: 'increase text size',
201
+ decreaseText: 'decrease text size',
202
+ increaseTextSpacing: 'increase text spacing',
203
+ decreaseTextSpacing: 'decrease text spacing',
204
+ invertColors: 'invert colors',
205
+ grayHues: 'gray hues',
206
+ bigCursor: 'big cursor',
207
+ readingGuide: 'reading guide',
208
+ underlineLinks: 'underline links',
209
+ textToSpeech: 'text to speech',
210
+ speechToText: 'speech to text',
211
+ disableAnimations: 'disable animations',
212
+ increaseLineHeight: 'increase line height',
213
+ decreaseLineHeight: 'decrease line height',
214
+ hotkeyPrefix: 'Hotkey: '
215
+ },
216
+ textPixelMode: false,
217
+ textEmlMode: true,
218
+ textSizeFactor: 12.5,
219
+ animations: {
220
+ buttons: true
221
+ },
222
+ modules: {
223
+ increaseText: true,
224
+ decreaseText: true,
225
+ increaseTextSpacing: true,
226
+ decreaseTextSpacing: true,
227
+ increaseLineHeight: true,
228
+ decreaseLineHeight: true,
229
+ invertColors: true,
230
+ grayHues: true,
231
+ bigCursor: true,
232
+ readingGuide: true,
233
+ underlineLinks: true,
234
+ textToSpeech: true,
235
+ speechToText: true,
236
+ disableAnimations: true,
237
+ iframeModals: true,
238
+ customFunctions: true
239
+ },
240
+ modulesOrder: (0, options_js_1.buildDefaultModuleOrder)(),
241
+ session: {
242
+ persistent: true
243
+ },
244
+ iframeModals: [],
245
+ customFunctions: [],
246
+ statement: {
247
+ url: ''
248
+ },
249
+ feedback: {
250
+ url: ''
251
+ },
252
+ language: {
253
+ textToSpeechLang: '',
254
+ speechToTextLang: ''
255
+ }
256
+ };
257
+ return res;
258
+ }
259
+ initFontSize() {
260
+ // store this values only once.
261
+ if (!this._htmlInitFS) {
262
+ let htmlInitFS = this._common.getFormattedDim(getComputedStyle(this._html).fontSize);
263
+ let bodyInitFS = this._common.getFormattedDim(getComputedStyle(this._body).fontSize);
264
+ this._html.style.fontSize = (htmlInitFS.size / 16) * 100 + '%';
265
+ this._htmlOrgFontSize = this._html.style.fontSize;
266
+ this._body.style.fontSize = bodyInitFS.size / htmlInitFS.size + 'em';
267
+ }
268
+ }
269
+ fontFallback() {
270
+ const previousImg = this.options.icon.img;
271
+ const previousCloseIcon = this.options.icon.closeIcon;
272
+ const previousResetIcon = this.options.icon.resetIcon;
273
+ this.options.icon.useEmojis = true;
274
+ this.options.icon.img = '♿';
275
+ this.options.icon.fontClass = '';
276
+ if (this.options.icon.imgElem?.type === '#text' &&
277
+ (this.options.icon.imgElem.text === previousImg || this.options.icon.imgElem.text === 'accessibility')) {
278
+ this.options.icon.imgElem = {
279
+ type: '#text',
280
+ text: '♿'
281
+ };
282
+ }
283
+ if (this.options.icon.closeIconElem?.type === '#text' &&
284
+ (this.options.icon.closeIconElem.text === previousCloseIcon || this.options.icon.closeIconElem.text === 'close')) {
285
+ this.options.icon.closeIconElem = {
286
+ type: '#text',
287
+ text: 'X'
288
+ };
289
+ }
290
+ if (this.options.icon.resetIconElem?.type === '#text' &&
291
+ (this.options.icon.resetIconElem.text === previousResetIcon || this.options.icon.resetIconElem.text === 'refresh')) {
292
+ this.options.icon.resetIconElem = {
293
+ type: '#text',
294
+ text: '♲'
295
+ };
296
+ }
297
+ }
298
+ addDefaultOptions(options) {
299
+ (0, options_js_1.addDefaultIconOptions)(this.options, options);
300
+ }
301
+ addModuleOrderIfNotDefined() {
302
+ (0, options_js_1.ensureModuleOrder)(this.defaultOptions.modulesOrder, this.options.modulesOrder);
303
+ }
304
+ disabledUnsupportedFeatures() {
305
+ (0, options_js_1.disableUnsupportedFeatures)(this._common, this.options);
306
+ }
307
+ injectCss(injectFull) {
308
+ let css;
309
+ const mandatory = `
310
+ html._access_cursor * {
311
+ cursor: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSIyOS4xODhweCIgaGVpZ2h0PSI0My42MjVweCIgdmlld0JveD0iMCAwIDI5LjE4OCA0My42MjUiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDI5LjE4OCA0My42MjUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxnPjxwb2x5Z29uIGZpbGw9IiNGRkZGRkYiIHN0cm9rZT0iI0Q5REFEOSIgc3Ryb2tlLXdpZHRoPSIxLjE0MDYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRzPSIyLjgsNC41NDkgMjYuODQ3LDE5LjkwMiAxNi45NjQsMjIuNzAxIDI0LjIzOSwzNy43NDkgMTguMjc4LDQyLjAxNyA5Ljc0MSwzMC43MjQgMS4xMzgsMzUuODA5ICIvPjxnPjxnPjxnPjxwYXRoIGZpbGw9IiMyMTI2MjciIGQ9Ik0yOS4xNzUsMjEuMTU1YzAuMDcxLTAuNjEzLTAuMTY1LTEuMjUzLTAuNjM1LTEuNTczTDIuMTY1LDAuMjU4Yy0wLjQyNC0wLjMyLTAuOTg4LTAuMzQ2LTEuNDM1LTAuMDUzQzAuMjgyLDAuNDk3LDAsMS4wMywwLDEuNjE3djM0LjE3MWMwLDAuNjEzLDAuMzA2LDEuMTQ2LDAuNzc2LDEuNDM5YzAuNDcxLDAuMjY3LDEuMDU5LDAuMjEzLDEuNDgyLTAuMTZsNy40ODItNi4zNDRsNi44NDcsMTIuMTU1YzAuMjU5LDAuNDgsMC43MjksMC43NDYsMS4yLDAuNzQ2YzAuMjM1LDAsMC40OTQtMC4wOCwwLjcwNi0wLjIxM2w2Ljk4OC00LjU4NWMwLjMyOS0wLjIxMywwLjU2NS0wLjU4NiwwLjY1OS0xLjAxM2MwLjA5NC0wLjQyNiwwLjAyNC0wLjg4LTAuMTg4LTEuMjI2bC02LjM3Ni0xMS4zODJsOC42MTEtMi43NDVDMjguNzA1LDIyLjI3NCwyOS4xMDUsMjEuNzY4LDI5LjE3NSwyMS4xNTV6IE0xNi45NjQsMjIuNzAxYy0wLjQyNCwwLjEzMy0wLjc3NiwwLjUwNi0wLjk0MSwwLjk2Yy0wLjE2NSwwLjQ4LTAuMTE4LDEuMDEzLDAuMTE4LDEuNDM5bDYuNTg4LDExLjc4MWwtNC41NDEsMi45ODVsLTYuODk0LTEyLjMxNWMtMC4yMTItMC4zNzMtMC41NDEtMC42NC0wLjk0MS0wLjcyYy0wLjA5NC0wLjAyNy0wLjE2NS0wLjAyNy0wLjI1OS0wLjAyN2MtMC4zMDYsMC0wLjU4OCwwLjEwNy0wLjg0NywwLjMyTDIuOCwzMi41OVY0LjU0OWwyMS41OTksMTUuODA2TDE2Ljk2NCwyMi43MDF6Ii8+PC9nPjwvZz48L2c+PC9nPjwvc3ZnPg==),auto!important;
312
+ }
313
+ @keyframes _access-dialog-backdrop {
314
+ 0% {
315
+ background: var(--_access-menu-dialog-backdrop-background-start, rgba(0, 0, 0, 0.1))
316
+ }
317
+ 100% {
318
+ background: var(--_access-menu-dialog-backdrop-background-end, rgba(0, 0, 0, 0.5))
319
+ }
320
+ }
321
+ dialog._access::backdrop, dialog._access {
322
+ transition-duration: var(--_access-menu-dialog-backdrop-transition-duration, 0.35s);
323
+ transition-timing-function: var(--_access-menu-dialog-backdrop-transition-timing-function, ease-in-out);
324
+ }
325
+ dialog._access:modal {
326
+ border-color: transparent;
327
+ border-width: 0;
328
+ padding: 0;
329
+ }
330
+ dialog._access[open]::backdrop {
331
+ background: var(--_access-menu-dialog-backdrop-background-end, rgba(0, 0, 0, 0.5));
332
+ animation: _access-dialog-backdrop var(--_access-menu-dialog-backdrop-transition-duration, 0.35s) ease-in-out;
333
+ }
334
+ dialog._access.closing[open]::backdrop {
335
+ background: var(--_access-menu-dialog-backdrop-background-start, rgba(0, 0, 0, 0.1));
336
+ }
337
+ dialog._access.closing[open] {
338
+ opacity: 0;
339
+ }
340
+ .screen-reader-wrapper {
341
+ margin: 0;
342
+ position: absolute;
343
+ bottom: -4px;
344
+ width: calc(100% - 2px);
345
+ left: 1px;
346
+ }
347
+ .screen-reader-wrapper-step-1, .screen-reader-wrapper-step-2,.screen-reader-wrapper-step-3 {
348
+ float: left;
349
+ background: var(--_access-menu-background-color, #fff);
350
+ width: 33.33%;
351
+ height: 3px;
352
+ border-radius: 10px;
353
+ }
354
+ .screen-reader-wrapper-step-1.active, .screen-reader-wrapper-step-2.active,.screen-reader-wrapper-step-3.active {
355
+ background: var(--_access-menu-item-button-background, #f9f9f9);
356
+ }
357
+ .access_read_guide_bar {
358
+ box-sizing: border-box;
359
+ background: var(--_access-menu-read-guide-bg, ${this.options.guide.cBackground});
360
+ width: 100%!important;
361
+ min-width: 100%!important;
362
+ position: fixed!important;
363
+ height: var(--_access-menu-read-guide-height, ${this.options.guide.height}) !important;
364
+ border: var(--_access-menu-read-guide-border, solid 3px ${this.options.guide.cBorder});
365
+ border-radius: 5px;
366
+ top: 15px;
367
+ z-index: 2147483647;
368
+ }`;
369
+ if (injectFull) {
370
+ css = `
371
+ ._access-scrollbar::-webkit-scrollbar-track, .mat-autocomplete-panel::-webkit-scrollbar-track, .mat-tab-body-content::-webkit-scrollbar-track, .mat-select-panel:not([class*='mat-elevation-z'])::-webkit-scrollbar-track, .mat-menu-panel::-webkit-scrollbar-track {
372
+ -webkit-box-shadow: var(--_access-scrollbar-track-box-shadow, inset 0 0 6px rgba(0,0,0,0.3));
373
+ background-color: var(--_access-scrollbar-track-background-color, #F5F5F5);
374
+ }
375
+ ._access-scrollbar::-webkit-scrollbar, .mat-autocomplete-panel::-webkit-scrollbar, .mat-tab-body-content::-webkit-scrollbar, .mat-select-panel:not([class*='mat-elevation-z'])::-webkit-scrollbar, .mat-menu-panel::-webkit-scrollbar {
376
+ width: var(--_access-scrollbar-width, 6px);
377
+ background-color: var(--_access-scrollbar-background-color, #F5F5F5);
378
+ }
379
+ ._access-scrollbar::-webkit-scrollbar-thumb, .mat-autocomplete-panel::-webkit-scrollbar-thumb, .mat-tab-body-content::-webkit-scrollbar-thumb, .mat-select-panel:not([class*='mat-elevation-z'])::-webkit-scrollbar-thumb, .mat-menu-panel::-webkit-scrollbar-thumb {
380
+ background-color: var(--_access-scrollbar-thumb-background-color, #999999);
381
+ }
382
+ ._access-icon {
383
+ position: var(--_access-icon-position, fixed);
384
+ width: var(--_access-icon-width, 58px);
385
+ height: var(--_access-icon-height, 58px);
386
+ bottom: var(--_access-icon-bottom, 18px);
387
+ top: var(--_access-icon-top, unset);
388
+ left: var(--_access-icon-left, unset);
389
+ right: var(--_access-icon-right, 18px);
390
+ z-index: var(--_access-icon-z-index, 9999);
391
+ display: flex;
392
+ align-items: center;
393
+ justify-content: center;
394
+ background: var(--_access-icon-bg, transparent);
395
+ color: var(--_access-icon-color, #fff);
396
+ background-repeat: no-repeat;
397
+ background-size: contain;
398
+ cursor: pointer;
399
+ opacity: 0;
400
+ transition: transform .25s ease, box-shadow .25s ease, opacity .35s ease;
401
+ -moz-user-select: none;
402
+ -webkit-user-select: none;
403
+ -ms-user-select: none;
404
+ user-select: none;
405
+ box-shadow: var(--_access-icon-box-shadow, none);
406
+ transform: ${!this.options.icon.useEmojis ? 'translateY(0)' : 'translateY(0)'};
407
+ border-radius: var(--_access-icon-border-radius, 0);
408
+ border: var(--_access-icon-border, none);
409
+ text-align: var(--_access-icon-text-align, center);
410
+ backdrop-filter: none;
411
+ }
412
+ ._access-icon img {
413
+ width: 58px;
414
+ height: 58px;
415
+ display: block;
416
+ }
417
+ ._access-icon:hover {
418
+ transform: var(--_access-icon-transform-hover, translateY(-1px) scale(1.02));
419
+ vertical-align: var(--_access-icon-vertical-align-hover);
420
+ }
421
+ ._access-icon:focus-visible {
422
+ outline: none;
423
+ box-shadow: var(--_access-icon-focus-shadow, 0 0 0 4px rgba(91, 147, 255, 0.28));
424
+ }
425
+ ._access-menu {
426
+ -moz-user-select: none;
427
+ -webkit-user-select: none;
428
+ -ms-user-select: none;
429
+ user-select: none;
430
+ position: fixed;
431
+ width: var(--_access-menu-width, ${Accessibility.MENU_WIDTH});
432
+ height: var(--_access-menu-height, auto);
433
+ max-width: var(--_access-menu-max-width, calc(100vw - 1rem));
434
+ transition-duration: var(--_access-menu-transition-duration, .35s);
435
+ transition-property: opacity, transform;
436
+ z-index: var(--_access-menu-z-index, 99991);
437
+ opacity: 1;
438
+ transform: translateY(0);
439
+ background: var(--_access-menu-background-color, linear-gradient(180deg, rgba(255,255,255,0.96) 0%, rgba(248,250,252,0.98) 100%));
440
+ color: var(--_access-menu-color, #0f172a);
441
+ border-radius: var(--_access-menu-border-radius, 18px);
442
+ border: var(--_access-menu-border, 1px solid rgba(148,163,184,0.28));
443
+ font-family: var(--_access-menu-font-family, "Segoe UI", "Helvetica Neue", Arial, sans-serif);
444
+ min-width: var(--_access-menu-min-width, 0);
445
+ box-shadow: var(--_access-menu-box-shadow, 0 20px 60px rgba(15, 23, 42, 0.18));
446
+ max-height: calc(100vh - 24px);
447
+ overflow: hidden;
448
+ backdrop-filter: blur(14px);
449
+ ${getComputedStyle(this._body).direction === 'rtl' ? 'text-indent: -5px' : ''}
450
+ top: var(--_access-menu-top, unset);
451
+ left: var(--_access-menu-left, unset);
452
+ bottom: var(--_access-menu-bottom, 12px);
453
+ right: var(--_access-menu-right, 12px);
454
+ }
455
+ ._access-menu.close {
456
+ z-index: -1;
457
+ width: 0;
458
+ opacity: 0;
459
+ background-color: transparent;
460
+ transform: translateY(12px);
461
+ pointer-events: none;
462
+ }
463
+ ._access-menu ._text-center {
464
+ font-size: var(--_access-menu-header-font-size, 1.05rem);
465
+ font-weight: var(--_access-menu-header-font-weight, 700);
466
+ margin: var(--_access-menu-header-margin, 0);
467
+ padding: 0.7rem 0.85rem 0.6rem;
468
+ color: var(--_access-menu-header-color, #0f172a);
469
+ letter-spacing: var(--_access-menu-header-letter-spacing, initial);
470
+ word-spacing: var(--_access-menu-header-word-spacing, initial);
471
+ text-align: var(--_access-menu-header-text-align, center);
472
+ position: sticky;
473
+ top: 0;
474
+ background: inherit;
475
+ z-index: 1;
476
+ border-bottom: 1px solid rgba(148,163,184,0.18);
477
+ }
478
+ ._access-menu ._menu-close-btn {
479
+ left: 8px;
480
+ color: var(--_access-menu-close-btn-color, #b91c1c);
481
+ transition: .3s ease;
482
+ transform: rotate(0deg);
483
+ font-style: normal !important;
484
+ }
485
+ ._access-menu ._menu-reset-btn:hover,._access-menu ._menu-close-btn:hover {
486
+ transform: var(--_access-menu-header-btn-hover-rotate, scale(1.08));
487
+ }
488
+ ._access-menu ._menu-reset-btn {
489
+ right: 8px;
490
+ color: var(--_access-menu-reset-btn-color, #0f766e);
491
+ transition: .3s ease;
492
+ transform: rotate(0deg);
493
+ font-style: normal !important;
494
+ }
495
+ ._access-menu ._menu-btn {
496
+ position: absolute;
497
+ top: 7px;
498
+ cursor: pointer;
499
+ background: rgba(255,255,255,0.72);
500
+ border: 1px solid rgba(148,163,184,0.24);
501
+ border-radius: 999px;
502
+ width: 28px;
503
+ height: 28px;
504
+ display: inline-flex;
505
+ align-items: center;
506
+ justify-content: center;
507
+ padding: 0;
508
+ }
509
+ ._access-menu ._menu-btn img {
510
+ width: 14px;
511
+ height: 14px;
512
+ display: block;
513
+ }
514
+ ._access-menu ul {
515
+ padding: 0.55rem;
516
+ position: relative;
517
+ font-size: var(--_access-menu-font-size, 15px);
518
+ margin: 0;
519
+ overflow: auto;
520
+ max-height: var(--_access-menu-max-height, calc(100vh - 72px));
521
+ display: flex;
522
+ flex-flow: column;
523
+ gap: 0.45rem;
524
+ overscroll-behavior: contain;
525
+ }
526
+ ${mandatory}
527
+ ._access-menu ul li {
528
+ position: relative;
529
+ list-style-type: none;
530
+ -ms-user-select: none;
531
+ -moz-user-select: none;
532
+ -webkit-user-select: none;
533
+ user-select: none;
534
+ margin: 0;
535
+ font: { size: 18, units: 'px' }
536
+ font-size: var(--_access-menu-item-font-size, 14px) !important;
537
+ line-height: var(--_access-menu-item-line-height, 18px) !important;
538
+ color: var(--_access-menu-item-color, rgba(15,23,42,.82));
539
+ letter-spacing: var(--_access-menu-item-letter-spacing, initial);
540
+ word-spacing: var(--_access-menu-item-word-spacing, initial);
541
+ width: 100%;
542
+ }
543
+ ._access-menu ul li button {
544
+ background: var(--_access-menu-item-button-background, rgba(255,255,255,0.78));
545
+ padding: var(--_access-menu-item-button-padding, 0.72rem 0.8rem 0.72rem 0);
546
+ width: 100%;
547
+ min-height: 42px;
548
+ text-indent: var(--_access-menu-item-button-text-indent, 34px);
549
+ text-align: start;
550
+ position: relative;
551
+ transition-duration: var(--_access-menu-item-button-transition-duration, .35s);
552
+ transition-timing-function: var(--_access-menu-item-button-transition-timing-function, ease-in-out);
553
+ border: var(--_access-menu-item-button-border, 1px solid rgba(148,163,184,0.2));
554
+ border-radius: var(--_access-menu-item-button-border-radius, 14px);
555
+ cursor: pointer;
556
+ box-shadow: var(--_access-menu-item-button-box-shadow, 0 6px 16px rgba(15, 23, 42, 0.05));
557
+ }
558
+ ._access-menu ul li.position {
559
+ display: inline-block;
560
+ width: auto;
561
+ }
562
+ ._access-menu ul.before-collapse li button {
563
+ opacity: var(--_access-menu-item-button-before-collapse-opacity, 0.05);
564
+ }
565
+ ._access-menu ul li button.active, ._access-menu ul li button.active:hover {
566
+ background: var(--_access-menu-item-button-active-background-color, linear-gradient(135deg, #0f766e 0%, #115e59 100%));
567
+ }
568
+ ._access-menu div.active {
569
+ color: var(--_access-menu-div-active-color, #fff);
570
+ background-color: var(--_access-menu-div-active-background-color, #000);
571
+ }
572
+ ._access-menu ul li button.active, ._access-menu ul li button.active:hover, ._access-menu ul li button.active:before, ._access-menu ul li button.active:hover:before {
573
+ color: var(--_access-menu-item-button-active-color, #fff);
574
+ }
575
+ ._access-menu ul li button:hover {
576
+ color: var(--_access-menu-item-button-hover-color, rgba(15,23,42,.92));
577
+ background: var(--_access-menu-item-button-hover-background-color, rgba(241,245,249,0.96));
578
+ transform: translateY(-1px);
579
+ }
580
+ ._access-menu ul li.not-supported {
581
+ display: none;
582
+ }
583
+ ._access-menu ._menu-btn:focus-visible,
584
+ ._access-menu ul li button:focus-visible {
585
+ outline: none;
586
+ box-shadow: 0 0 0 4px rgba(15, 118, 110, 0.18);
587
+ }
588
+ ._access-menu ul li button:before {
589
+ content: ' ';
590
+ line-height: 1;
591
+ font-size: 16px !important;
592
+ width: 18px;
593
+ height: 18px;
594
+ display: inline-block;
595
+ overflow: hidden;
596
+ top: 12px;
597
+ left: 10px;
598
+ position: absolute;
599
+ color: var(--_access-menu-item-icon-color, rgba(15,23,42,.72));
600
+ direction: ltr;
601
+ text-indent: 0;
602
+ transition-duration: .35s;
603
+ transition-timing-function: ease-in-out;
604
+ }
605
+ ._access-menu ul li button svg path {
606
+ fill: var(--_access-menu-item-icon-color, rgba(15,23,42,.72));
607
+ transition-duration: .35s;
608
+ transition-timing-function: ease-in-out;
609
+ }
610
+ ._access-menu ul li button:hover svg path {
611
+ fill: var(--_access-menu-item-hover-icon-color, rgba(15,23,42,.9));
612
+ }
613
+ ._access-menu ul li button.active svg path {
614
+ fill: var(--_access-menu-item-active-icon-color, #fff);
615
+ }
616
+ ._access-menu ul li:hover button:before {
617
+ color: var(--_access-menu-item-hover-icon-color, rgba(15,23,42,.9));
618
+ }
619
+ ._access-menu ul li button.active button:before {
620
+ color: var(--_access-menu-item-active-icon-color, #fff);
621
+ }
622
+ ${(0, icon_assets_js_1.buildBuiltinActionIconCss)()}
623
+ @media (max-width: 768px) {
624
+ ._access-icon {
625
+ right: var(--_access-icon-right-mobile, 12px);
626
+ bottom: var(--_access-icon-bottom-mobile, 12px);
627
+ }
628
+ ._access-menu {
629
+ width: calc(100vw - 1rem);
630
+ min-width: unset;
631
+ max-width: unset;
632
+ right: 0.5rem;
633
+ left: 0.5rem;
634
+ bottom: 0.5rem;
635
+ max-height: calc(100vh - 1rem);
636
+ }
637
+ }
638
+ @media (max-width: 480px) {
639
+ ._access-menu {
640
+ border-radius: 16px;
641
+ }
642
+ ._access-menu ._text-center {
643
+ font-size: 1rem;
644
+ padding: 0.7rem 2.5rem 0.55rem;
645
+ }
646
+ ._access-menu ._menu-btn {
647
+ top: 8px;
648
+ width: 26px;
649
+ height: 26px;
650
+ }
651
+ ._access-menu ._menu-btn img {
652
+ width: 13px;
653
+ height: 13px;
654
+ }
655
+ ._access-menu ul {
656
+ padding: 0.45rem;
657
+ gap: 0.35rem;
658
+ max-height: calc(100vh - 4.75rem);
659
+ }
660
+ ._access-menu ul li {
661
+ font-size: 13px !important;
662
+ line-height: 17px !important;
663
+ }
664
+ ._access-menu ul li button {
665
+ min-height: 40px;
666
+ padding: 0.68rem 0.7rem 0.68rem 0;
667
+ text-indent: 32px;
668
+ }
669
+ ._access-menu ul li button:before {
670
+ width: 17px;
671
+ height: 17px;
672
+ top: 11px;
673
+ left: 9px;
674
+ }
675
+ }
676
+ @media (prefers-reduced-motion: reduce) {
677
+ ._access-icon,
678
+ ._access-menu,
679
+ ._access-menu ._menu-btn,
680
+ ._access-menu ul li button,
681
+ ._access-menu ul li button:before,
682
+ ._access-menu ul li button svg path {
683
+ transition-duration: 0.01ms !important;
684
+ animation-duration: 0.01ms !important;
685
+ }
686
+ }`;
687
+ }
688
+ else {
689
+ css = mandatory;
690
+ }
691
+ const className = Accessibility.CSS_CLASS_NAME;
692
+ this._common.injectStyle(css, { className: className });
693
+ this._common.deployedObjects.set(`.${className}`, false);
694
+ }
695
+ removeCSS() {
696
+ const existing = document.querySelector(`.${Accessibility.CSS_CLASS_NAME}`);
697
+ if (existing)
698
+ existing.remove();
699
+ }
700
+ injectIcon() {
701
+ // let fontSize = (this.options.icon.dimensions.width.size as number) * 0.8;
702
+ // let lineHeight = (this.options.icon.dimensions.width.size as number) * 0.9;
703
+ // let textIndent = (this.options.icon.dimensions.width.size as number) * 0.1;
704
+ // let iStyle = `width: ${this.options.icon.dimensions.width.size + this.options.icon.dimensions.width.units}
705
+ // ;height: ${this.options.icon.dimensions.height.size + this.options.icon.dimensions.height.units}
706
+ // ;font-size: ${fontSize + this.options.icon.dimensions.width.units}
707
+ // ;line-height: ${lineHeight + this.options.icon.dimensions.width.units}
708
+ // ;text-indent: ${textIndent + this.options.icon.dimensions.width.units}
709
+ // ;background-color: ${!this.options.icon.useEmojis ? this.options.icon.backgroundColor : 'transparent'};color: ${this.options.icon.color}`;
710
+ // for (let i in this.options.icon.position) {
711
+ // let pos = this.options.icon.position as any;
712
+ // pos = pos[i];
713
+ // iStyle += ';' + i + ':' + pos.size + pos.units;
714
+ // }
715
+ // iStyle += `;z-index: ${this.options.icon.zIndex}`;
716
+ let className = `_access-icon ${this.options.icon.fontClass} _access`;
717
+ let iconElem = this._common.jsonToHtml({
718
+ type: 'i',
719
+ attrs: {
720
+ class: className,
721
+ title: this.options.hotkeys.enabled
722
+ ? this.parseKeys(this.options.hotkeys.keys.toggleMenu)
723
+ : this.options.labels.menuTitle,
724
+ tabIndex: 0,
725
+ role: 'button',
726
+ 'aria-controls': Accessibility.MENU_ID,
727
+ 'aria-haspopup': 'dialog',
728
+ 'aria-expanded': 'false',
729
+ 'aria-label': this.options.labels.menuTitle
730
+ },
731
+ children: [this.options.icon.imgElem]
732
+ });
733
+ this._body.appendChild(iconElem);
734
+ this._common.deployedObjects.set('._access-icon', false);
735
+ return iconElem;
736
+ }
737
+ parseKeys(arr) {
738
+ return (0, hotkeys_js_1.parseHotkeyLabel)(this.options.hotkeys, this.options.labels.hotkeyPrefix, arr);
739
+ }
740
+ syncMenuState(isOpen) {
741
+ if (this._icon) {
742
+ this._icon.setAttribute('aria-expanded', String(isOpen));
743
+ this._icon.setAttribute('aria-label', this.options.labels.menuTitle);
744
+ this._icon.tabIndex = isOpen ? -1 : 0;
745
+ }
746
+ if (!this._menu)
747
+ return;
748
+ this._menu.setAttribute('aria-hidden', String(!isOpen));
749
+ if (isOpen) {
750
+ const firstButton = this._menu.querySelector('button');
751
+ if (firstButton instanceof HTMLElement)
752
+ firstButton.focus();
753
+ }
754
+ }
755
+ injectMenu() {
756
+ const json = {
757
+ type: 'div',
758
+ attrs: {
759
+ class: '_access-menu close _access',
760
+ id: Accessibility.MENU_ID,
761
+ role: 'dialog',
762
+ 'aria-modal': 'false',
763
+ 'aria-labelledby': Accessibility.MENU_LABEL_ID,
764
+ 'aria-hidden': 'true'
765
+ },
766
+ children: [
767
+ {
768
+ type: 'p',
769
+ attrs: {
770
+ class: '_text-center',
771
+ role: 'presentation',
772
+ id: Accessibility.MENU_LABEL_ID
773
+ },
774
+ children: [
775
+ {
776
+ type: 'button',
777
+ attrs: {
778
+ class: `_menu-close-btn _menu-btn ${this.options.icon.fontClass}`,
779
+ style: `font-family: var(--_access-menu-close-btn-font-family, ${this._fixedDefaultFont})`,
780
+ title: this.options.hotkeys.enabled
781
+ ? this.parseKeys(this.options.hotkeys.keys.toggleMenu)
782
+ : this.options.labels.closeTitle,
783
+ 'aria-label': this.options.labels.closeTitle,
784
+ type: 'button'
785
+ },
786
+ children: [this.options.icon.closeIconElem]
787
+ },
788
+ {
789
+ type: '#text',
790
+ text: this.options.labels.menuTitle
791
+ },
792
+ {
793
+ type: 'button',
794
+ attrs: {
795
+ class: `_menu-reset-btn _menu-btn ${this.options.icon.fontClass}`,
796
+ style: `font-family: var(--_access-menu-reset-btn-font-family, ${this._fixedDefaultFont})`,
797
+ title: this.options.labels.resetTitle,
798
+ 'aria-label': this.options.labels.resetTitle,
799
+ type: 'button'
800
+ },
801
+ children: [this.options.icon.resetIconElem]
802
+ }
803
+ ]
804
+ },
805
+ {
806
+ type: 'ul',
807
+ attrs: {
808
+ class: 'before-collapse _access-scrollbar',
809
+ role: 'list'
810
+ },
811
+ children: [
812
+ {
813
+ type: 'li',
814
+ children: [
815
+ {
816
+ type: 'button',
817
+ attrs: {
818
+ 'data-access-action': 'increaseText'
819
+ },
820
+ children: [
821
+ {
822
+ type: '#text',
823
+ text: this.options.labels.increaseText
824
+ }
825
+ ]
826
+ }
827
+ ]
828
+ },
829
+ {
830
+ type: 'li',
831
+ children: [
832
+ {
833
+ type: 'button',
834
+ attrs: {
835
+ 'data-access-action': 'decreaseText'
836
+ },
837
+ children: [
838
+ {
839
+ type: '#text',
840
+ text: this.options.labels.decreaseText
841
+ }
842
+ ]
843
+ }
844
+ ]
845
+ },
846
+ {
847
+ type: 'li',
848
+ children: [
849
+ {
850
+ type: 'button',
851
+ attrs: {
852
+ 'data-access-action': 'increaseTextSpacing'
853
+ },
854
+ children: [
855
+ {
856
+ type: '#text',
857
+ text: this.options.labels.increaseTextSpacing
858
+ }
859
+ ]
860
+ }
861
+ ]
862
+ },
863
+ {
864
+ type: 'li',
865
+ children: [
866
+ {
867
+ type: 'button',
868
+ attrs: {
869
+ 'data-access-action': 'decreaseTextSpacing'
870
+ },
871
+ children: [
872
+ {
873
+ type: '#text',
874
+ text: this.options.labels.decreaseTextSpacing
875
+ }
876
+ ]
877
+ }
878
+ ]
879
+ },
880
+ {
881
+ type: 'li',
882
+ children: [
883
+ {
884
+ type: 'button',
885
+ attrs: {
886
+ 'data-access-action': 'increaseLineHeight'
887
+ },
888
+ children: [
889
+ {
890
+ type: '#text',
891
+ text: this.options.labels.increaseLineHeight
892
+ }
893
+ ]
894
+ }
895
+ ]
896
+ },
897
+ {
898
+ type: 'li',
899
+ children: [
900
+ {
901
+ type: 'button',
902
+ attrs: {
903
+ 'data-access-action': 'decreaseLineHeight'
904
+ },
905
+ children: [
906
+ {
907
+ type: '#text',
908
+ text: this.options.labels.decreaseLineHeight
909
+ }
910
+ ]
911
+ }
912
+ ]
913
+ },
914
+ {
915
+ type: 'li',
916
+ children: [
917
+ {
918
+ type: 'button',
919
+ attrs: {
920
+ 'data-access-action': 'invertColors',
921
+ title: this.parseKeys(this.options.hotkeys.keys.invertColors)
922
+ },
923
+ children: [
924
+ {
925
+ type: '#text',
926
+ text: this.options.labels.invertColors
927
+ }
928
+ ]
929
+ }
930
+ ]
931
+ },
932
+ {
933
+ type: 'li',
934
+ children: [
935
+ {
936
+ type: 'button',
937
+ attrs: {
938
+ 'data-access-action': 'grayHues',
939
+ title: this.parseKeys(this.options.hotkeys.keys.grayHues)
940
+ },
941
+ children: [
942
+ {
943
+ type: '#text',
944
+ text: this.options.labels.grayHues
945
+ }
946
+ ]
947
+ }
948
+ ]
949
+ },
950
+ {
951
+ type: 'li',
952
+ children: [
953
+ {
954
+ type: 'button',
955
+ attrs: {
956
+ 'data-access-action': 'underlineLinks',
957
+ title: this.parseKeys(this.options.hotkeys.keys.underlineLinks)
958
+ },
959
+ children: [
960
+ {
961
+ type: '#text',
962
+ text: this.options.labels.underlineLinks
963
+ }
964
+ ]
965
+ }
966
+ ]
967
+ },
968
+ {
969
+ type: 'li',
970
+ children: [
971
+ {
972
+ type: 'button',
973
+ attrs: {
974
+ 'data-access-action': 'bigCursor',
975
+ title: this.parseKeys(this.options.hotkeys.keys.bigCursor)
976
+ },
977
+ children: [
978
+ {
979
+ type: '#text',
980
+ text: this.options.labels.bigCursor
981
+ }
982
+ ]
983
+ }
984
+ ]
985
+ },
986
+ {
987
+ type: 'li',
988
+ children: [
989
+ {
990
+ type: 'button',
991
+ attrs: {
992
+ 'data-access-action': 'readingGuide',
993
+ title: this.parseKeys(this.options.hotkeys.keys.readingGuide)
994
+ },
995
+ children: [
996
+ {
997
+ type: '#text',
998
+ text: this.options.labels.readingGuide
999
+ }
1000
+ ]
1001
+ }
1002
+ ]
1003
+ },
1004
+ {
1005
+ type: 'li',
1006
+ children: [
1007
+ {
1008
+ type: 'button',
1009
+ attrs: {
1010
+ 'data-access-action': 'disableAnimations',
1011
+ title: this.parseKeys(this.options.hotkeys.keys.disableAnimations)
1012
+ },
1013
+ children: [
1014
+ {
1015
+ type: '#text',
1016
+ text: this.options.labels.disableAnimations
1017
+ }
1018
+ ]
1019
+ }
1020
+ ]
1021
+ }
1022
+ ]
1023
+ }
1024
+ ]
1025
+ };
1026
+ if (this.options.iframeModals) {
1027
+ this.options.iframeModals.forEach((im, i) => {
1028
+ const btn = {
1029
+ type: 'li',
1030
+ children: [
1031
+ {
1032
+ type: 'button',
1033
+ attrs: {
1034
+ 'data-access-action': 'iframeModals',
1035
+ 'data-access-url': im.iframeUrl
1036
+ },
1037
+ children: [
1038
+ {
1039
+ type: '#text',
1040
+ text: im.buttonText
1041
+ }
1042
+ ]
1043
+ }
1044
+ ]
1045
+ };
1046
+ let icon = null;
1047
+ if (im.icon && !this.options.icon.useEmojis)
1048
+ icon = im.icon;
1049
+ else if (im.emoji && this.options.icon.useEmojis)
1050
+ icon = im.emoji;
1051
+ if (icon) {
1052
+ btn.children[0].attrs['data-access-iframe-index'] = i;
1053
+ const css = `._access-menu ul li button[data-access-action="iframeModals"][data-access-iframe-index="${i}"]:before {
1054
+ content: "${(0, security_js_1.escapeCssString)(icon)}";
1055
+ }`;
1056
+ let className = '_data-access-iframe-index-' + i;
1057
+ this._common.injectStyle(css, { className: className });
1058
+ this._common.deployedObjects.set('.' + className, false);
1059
+ }
1060
+ if (this.options.modules.textToSpeech)
1061
+ json.children[1].children.splice(json.children[1].children.length - 2, 0, btn);
1062
+ else
1063
+ json.children[1].children.push(btn);
1064
+ });
1065
+ }
1066
+ if (this.options.customFunctions) {
1067
+ this.options.customFunctions.forEach((cf, i) => {
1068
+ const btn = {
1069
+ type: 'li',
1070
+ children: [
1071
+ {
1072
+ type: 'button',
1073
+ attrs: {
1074
+ 'data-access-action': 'customFunctions',
1075
+ 'data-access-custom-id': cf.id,
1076
+ 'data-access-custom-index': i
1077
+ },
1078
+ children: [
1079
+ {
1080
+ type: '#text',
1081
+ text: cf.buttonText
1082
+ }
1083
+ ]
1084
+ }
1085
+ ]
1086
+ };
1087
+ let icon = null;
1088
+ if (cf.icon && !this.options.icon.useEmojis)
1089
+ icon = cf.icon;
1090
+ else if (cf.emoji && this.options.icon.useEmojis)
1091
+ icon = cf.emoji;
1092
+ if (icon) {
1093
+ const css = `._access-menu ul li button[data-access-action="customFunctions"][data-access-custom-index="${i}"]:before {
1094
+ content: "${(0, security_js_1.escapeCssString)(icon)}";
1095
+ }`;
1096
+ let className = '_data-access-custom-index-' + i;
1097
+ this._common.injectStyle(css, { className: className });
1098
+ this._common.deployedObjects.set('.' + className, false);
1099
+ }
1100
+ if (this.options.modules.textToSpeech)
1101
+ json.children[1].children.splice(json.children[1].children.length - 2, 0, btn);
1102
+ else
1103
+ json.children[1].children.push(btn);
1104
+ });
1105
+ }
1106
+ let menuElem = this._common.jsonToHtml(json);
1107
+ this._body.appendChild(menuElem);
1108
+ this._common.deployedObjects.set('._access-menu', false);
1109
+ let closeBtn = document.querySelector('._access-menu ._menu-close-btn');
1110
+ ['click', 'keyup'].forEach((evt) => {
1111
+ closeBtn.addEventListener(evt, (e) => {
1112
+ if (!(0, event_utils_js_1.isActivationEvent)(e))
1113
+ return;
1114
+ this.toggleMenu();
1115
+ }, false);
1116
+ });
1117
+ let resetBtn = document.querySelector('._access-menu ._menu-reset-btn');
1118
+ ['click', 'keyup'].forEach((evt) => {
1119
+ resetBtn.addEventListener(evt, (e) => {
1120
+ if (!(0, event_utils_js_1.isActivationEvent)(e))
1121
+ return;
1122
+ this.resetAll();
1123
+ }, false);
1124
+ });
1125
+ return menuElem;
1126
+ }
1127
+ getVoices() {
1128
+ return new Promise((resolve) => {
1129
+ let synth = window.speechSynthesis;
1130
+ let id;
1131
+ id = setInterval(() => {
1132
+ if (synth.getVoices().length !== 0) {
1133
+ resolve(synth.getVoices());
1134
+ clearInterval(id);
1135
+ }
1136
+ }, 10);
1137
+ });
1138
+ }
1139
+ async injectTts() {
1140
+ let voices = await this.getVoices();
1141
+ let isLngSupported = false;
1142
+ for (let i = 0; i < voices.length; i++) {
1143
+ if (voices[i].lang === this.options.language.textToSpeechLang) {
1144
+ isLngSupported = true;
1145
+ break;
1146
+ }
1147
+ }
1148
+ if (isLngSupported) {
1149
+ let tts = this.common.jsonToHtml({
1150
+ type: 'li',
1151
+ children: [
1152
+ {
1153
+ type: 'button',
1154
+ attrs: {
1155
+ 'data-access-action': 'textToSpeech',
1156
+ title: this.parseKeys(this.options.hotkeys.keys.textToSpeech)
1157
+ },
1158
+ children: [
1159
+ {
1160
+ type: '#text',
1161
+ text: this.options.labels.textToSpeech
1162
+ }
1163
+ ]
1164
+ },
1165
+ {
1166
+ type: 'div',
1167
+ attrs: {
1168
+ class: 'screen-reader-wrapper'
1169
+ },
1170
+ children: [
1171
+ {
1172
+ type: 'div',
1173
+ attrs: {
1174
+ class: 'screen-reader-wrapper-step-1',
1175
+ tabIndex: '-1'
1176
+ }
1177
+ },
1178
+ {
1179
+ type: 'div',
1180
+ attrs: {
1181
+ class: 'screen-reader-wrapper-step-2',
1182
+ tabIndex: '-1'
1183
+ }
1184
+ },
1185
+ {
1186
+ type: 'div',
1187
+ attrs: {
1188
+ class: 'screen-reader-wrapper-step-3',
1189
+ tabIndex: '-1'
1190
+ }
1191
+ }
1192
+ ]
1193
+ }
1194
+ ]
1195
+ });
1196
+ let sts = this.common.jsonToHtml({
1197
+ type: 'li',
1198
+ children: [
1199
+ {
1200
+ type: 'button',
1201
+ attrs: {
1202
+ 'data-access-action': 'speechToText',
1203
+ title: this.parseKeys(this.options.hotkeys.keys.speechToText)
1204
+ },
1205
+ children: [
1206
+ {
1207
+ type: '#text',
1208
+ text: this.options.labels.speechToText
1209
+ }
1210
+ ]
1211
+ }
1212
+ ]
1213
+ });
1214
+ let ul = document.querySelector('._access-menu ul');
1215
+ ul.appendChild(sts);
1216
+ ul.appendChild(tts);
1217
+ }
1218
+ }
1219
+ addListeners() {
1220
+ let lis = document.querySelectorAll('._access-menu ul li');
1221
+ let step1 = document.getElementsByClassName('screen-reader-wrapper-step-1');
1222
+ let step2 = document.getElementsByClassName('screen-reader-wrapper-step-2');
1223
+ let step3 = document.getElementsByClassName('screen-reader-wrapper-step-3');
1224
+ for (let i = 0; i < lis.length; i++) {
1225
+ ['click', 'keyup'].forEach((evt) => lis[i].addEventListener(evt, (e) => {
1226
+ if (!(0, event_utils_js_1.isActivationEvent)(e))
1227
+ return;
1228
+ const target = (0, event_utils_js_1.getEventTarget)(e)?.closest('[data-access-action]') ?? null;
1229
+ if (!target)
1230
+ return;
1231
+ this.invoke(target.getAttribute('data-access-action'), target);
1232
+ }));
1233
+ }
1234
+ [...Array.from(step1), ...Array.from(step2), ...Array.from(step3)].forEach((el) => el.addEventListener('click', (e) => {
1235
+ const target = (0, event_utils_js_1.getEventTarget)(e);
1236
+ if (!target || !target.parentElement || !target.parentElement.parentElement)
1237
+ return;
1238
+ this.invoke(target.parentElement.parentElement.getAttribute('data-access-action'), target);
1239
+ }, false));
1240
+ }
1241
+ sortModuleTypes() {
1242
+ this.options.modulesOrder.sort((a, b) => {
1243
+ return a.order - b.order;
1244
+ });
1245
+ }
1246
+ disableUnsupportedModulesAndSort() {
1247
+ this.sortModuleTypes();
1248
+ let ul = document.querySelector('._access-menu ul');
1249
+ this.options.modulesOrder.forEach((item) => {
1250
+ const i = item.type;
1251
+ const module = accessibility_interface_js_1.AccessibilityModulesType[i];
1252
+ let m = this.options.modules;
1253
+ m = m[module];
1254
+ let moduleLi = document.querySelector('button[data-access-action="' + module + '"]');
1255
+ if (moduleLi) {
1256
+ moduleLi.parentElement.remove();
1257
+ ul.appendChild(moduleLi.parentElement);
1258
+ if (!m)
1259
+ moduleLi.parentElement.classList.add('not-supported');
1260
+ }
1261
+ });
1262
+ }
1263
+ resetAll() {
1264
+ this.menuInterface.textToSpeech(true);
1265
+ this.menuInterface.speechToText(true);
1266
+ this.menuInterface.disableAnimations(true);
1267
+ this.menuInterface.underlineLinks(true);
1268
+ this.menuInterface.grayHues(true);
1269
+ this.menuInterface.invertColors(true);
1270
+ this.menuInterface.bigCursor(true);
1271
+ this.menuInterface.readingGuide(true);
1272
+ this.resetTextSize();
1273
+ this.resetTextSpace();
1274
+ this.resetLineHeight();
1275
+ }
1276
+ resetTextSize() {
1277
+ this.resetIfDefined(this._stateValues.body.fontSize, this._body.style, 'fontSize');
1278
+ if (typeof this._htmlOrgFontSize !== 'undefined')
1279
+ this._html.style.fontSize = this._htmlOrgFontSize;
1280
+ let all = document.querySelectorAll('[data-init-font-size]');
1281
+ for (let i = 0; i < all.length; i++) {
1282
+ all[i].style.fontSize = all[i].getAttribute('data-init-font-size');
1283
+ all[i].removeAttribute('data-init-font-size');
1284
+ }
1285
+ this._sessionState.textSize = 0;
1286
+ this.onChange(true);
1287
+ }
1288
+ resetLineHeight() {
1289
+ this.resetIfDefined(this._stateValues.body.lineHeight, this.body.style, 'lineHeight');
1290
+ let all = document.querySelectorAll('[data-init-line-height]');
1291
+ for (let i = 0; i < all.length; i++) {
1292
+ all[i].style.lineHeight = all[i].getAttribute('data-init-line-height');
1293
+ all[i].removeAttribute('data-init-line-height');
1294
+ }
1295
+ this.sessionState.lineHeight = 0;
1296
+ this.onChange(true);
1297
+ }
1298
+ resetTextSpace() {
1299
+ this.resetIfDefined(this._stateValues.body.wordSpacing, this._body.style, 'wordSpacing');
1300
+ this.resetIfDefined(this._stateValues.body.letterSpacing, this._body.style, 'letterSpacing');
1301
+ let all = document.querySelectorAll('[data-init-word-spacing]');
1302
+ let all2 = document.querySelectorAll('[data-init-letter-spacing]');
1303
+ for (let i = 0; i < all.length; i++) {
1304
+ all[i].style.wordSpacing = all[i].getAttribute('data-init-word-spacing');
1305
+ all[i].removeAttribute('data-init-word-spacing');
1306
+ }
1307
+ for (let i = 0; i < all2.length; i++) {
1308
+ all[i].style.letterSpacing = all[i].getAttribute('data-init-letter-spacing');
1309
+ all[i].removeAttribute('data-init-letter-spacing');
1310
+ }
1311
+ this._sessionState.textSpace = 0;
1312
+ this.onChange(true);
1313
+ }
1314
+ alterTextSize(isIncrease) {
1315
+ this._sessionState.textSize += isIncrease ? 1 : -1;
1316
+ this.onChange(true);
1317
+ let factor = this.options.textSizeFactor;
1318
+ if (!isIncrease)
1319
+ factor *= -1;
1320
+ if (this.options.textPixelMode) {
1321
+ let all = document.querySelectorAll('*:not(._access)');
1322
+ for (let i = 0; i < all.length; i++) {
1323
+ let fSize = getComputedStyle(all[i]).fontSize;
1324
+ if (fSize && fSize.indexOf('px') > -1) {
1325
+ if (!all[i].getAttribute('data-init-font-size'))
1326
+ all[i].setAttribute('data-init-font-size', fSize);
1327
+ }
1328
+ }
1329
+ for (let i = 0; i < all.length; i++) {
1330
+ let fSize = getComputedStyle(all[i]).fontSize;
1331
+ if (fSize && fSize.indexOf('px') > -1) {
1332
+ fSize = (parseInt(fSize.replace('px', '')) + factor);
1333
+ all[i].style.fontSize = fSize + 'px';
1334
+ }
1335
+ if (this._stateValues.textToSpeech)
1336
+ this.textToSpeech(`Text Size ${isIncrease ? 'Increased' : 'Decreased'}`);
1337
+ }
1338
+ // Also adjust the body font size
1339
+ let bodyFontSize = getComputedStyle(this._body).fontSize;
1340
+ if (bodyFontSize && bodyFontSize.indexOf('px') > -1) {
1341
+ if (!this._body.getAttribute('data-init-font-size'))
1342
+ this._body.setAttribute('data-init-font-size', bodyFontSize);
1343
+ bodyFontSize = (parseInt(bodyFontSize.replace('px', '')) + factor);
1344
+ this._body.style.fontSize = bodyFontSize + 'px';
1345
+ }
1346
+ }
1347
+ else if (this.options.textEmlMode) {
1348
+ let fp = this._html.style.fontSize;
1349
+ if (fp.indexOf('%')) {
1350
+ fp = parseInt(fp.replace('%', ''));
1351
+ this._html.style.fontSize = fp + factor + '%';
1352
+ if (this._stateValues.textToSpeech)
1353
+ this.textToSpeech(`Text Size ${isIncrease ? 'Increased' : 'Decreased'}`);
1354
+ }
1355
+ else {
1356
+ this._common.warn('Accessibility.textEmlMode, html element is not set in %.');
1357
+ }
1358
+ }
1359
+ else {
1360
+ let fSize = this._common.getFormattedDim(getComputedStyle(this._body).fontSize);
1361
+ if (typeof this._stateValues.body.fontSize === 'undefined')
1362
+ this._stateValues.body.fontSize = fSize.size + fSize.suffix;
1363
+ if (fSize && fSize.suffix && !isNaN(fSize.size * 1)) {
1364
+ this._body.style.fontSize = fSize.size * 1 + factor + fSize.suffix;
1365
+ }
1366
+ }
1367
+ }
1368
+ alterLineHeight(isIncrease) {
1369
+ this.sessionState.lineHeight += isIncrease ? 1 : -1;
1370
+ this.onChange(true);
1371
+ let factor = 2;
1372
+ if (!isIncrease)
1373
+ factor *= -1;
1374
+ if (this.options.textEmlMode)
1375
+ factor *= 10;
1376
+ let all = document.querySelectorAll('*:not(._access)');
1377
+ let exclude = Array.prototype.slice.call(document.querySelectorAll('._access-menu *'));
1378
+ for (let i = 0; i < all.length; i++) {
1379
+ if (exclude.includes(all[i])) {
1380
+ continue;
1381
+ }
1382
+ if (this.options.textPixelMode) {
1383
+ let lHeight = getComputedStyle(all[i]).lineHeight;
1384
+ if (lHeight && lHeight.indexOf('px') > -1) {
1385
+ if (!all[i].getAttribute('data-init-line-height'))
1386
+ all[i].setAttribute('data-init-line-height', lHeight);
1387
+ const newPixel = parseInt(lHeight.replace('px', '')) + factor;
1388
+ all[i].style.lineHeight = `${newPixel}px`;
1389
+ }
1390
+ if (this._stateValues.textToSpeech)
1391
+ this.textToSpeech(`Line Height ${isIncrease ? 'Increased' : 'Decreased'}`);
1392
+ }
1393
+ else if (this.options.textEmlMode) {
1394
+ let lTextSize = getComputedStyle(all[i]).fontSize;
1395
+ let lHeight = getComputedStyle(all[i]).lineHeight;
1396
+ if (lHeight === 'normal')
1397
+ lHeight = (parseInt(lTextSize.replace('px', '')) * 1.2).toString() + 'px';
1398
+ let lHeight2 = lHeight.replace('px', '');
1399
+ let lTextSize2 = lTextSize.replace('px', '');
1400
+ let inPercent = (parseInt(lHeight2) * 100) / parseInt(lTextSize2);
1401
+ if (lHeight && lHeight.indexOf('px') > -1) {
1402
+ if (!all[i].getAttribute('data-init-line-height'))
1403
+ all[i].setAttribute('data-init-line-height', inPercent + '%');
1404
+ inPercent = inPercent + factor;
1405
+ all[i].style.lineHeight = inPercent + '%';
1406
+ }
1407
+ if (typeof this._stateValues.body.lineHeight === 'undefined')
1408
+ this._stateValues.body.lineHeight = '';
1409
+ if (this._stateValues.textToSpeech)
1410
+ this.textToSpeech(`Line height ${isIncrease ? 'Increased' : 'Decreased'}`);
1411
+ }
1412
+ }
1413
+ }
1414
+ alterTextSpace(isIncrease) {
1415
+ this._sessionState.textSpace += isIncrease ? 1 : -1;
1416
+ this.onChange(true);
1417
+ let factor = 2;
1418
+ if (!isIncrease)
1419
+ factor *= -1;
1420
+ if (this.options.textPixelMode) {
1421
+ let all = document.querySelectorAll('*:not(._access)');
1422
+ let exclude = Array.prototype.slice.call(document.querySelectorAll('._access-menu *'));
1423
+ for (let i = 0; i < all.length; i++) {
1424
+ if (exclude.includes(all[i])) {
1425
+ continue;
1426
+ }
1427
+ // wordSpacing
1428
+ let fSpacing = all[i].style.wordSpacing;
1429
+ if (fSpacing && fSpacing.indexOf('px') > -1) {
1430
+ if (!all[i].getAttribute('data-init-word-spacing'))
1431
+ all[i].setAttribute('data-init-word-spacing', fSpacing);
1432
+ fSpacing = fSpacing.replace('px', '') * 1 + factor;
1433
+ all[i].style.wordSpacing = fSpacing + 'px';
1434
+ }
1435
+ else {
1436
+ all[i].setAttribute('data-init-word-spacing', fSpacing);
1437
+ all[i].style.wordSpacing = factor + 'px';
1438
+ }
1439
+ // letterSpacing
1440
+ let fSpacing2 = all[i].style.letterSpacing;
1441
+ if (fSpacing2 && fSpacing2.indexOf('px') > -1) {
1442
+ if (!all[i].getAttribute('data-init-letter-spacing'))
1443
+ all[i].setAttribute('data-init-letter-spacing', fSpacing2);
1444
+ fSpacing2 = fSpacing2.replace('px', '') * 1 + factor;
1445
+ all[i].style.letterSpacing = fSpacing2 + 'px';
1446
+ }
1447
+ else {
1448
+ all[i].setAttribute('data-init-letter-spacing', fSpacing2);
1449
+ all[i].style.letterSpacing = factor + 'px';
1450
+ }
1451
+ }
1452
+ if (this._stateValues.textToSpeech)
1453
+ this.textToSpeech(`Text Spacing ${isIncrease ? 'Increased' : 'Decreased'}`);
1454
+ }
1455
+ else {
1456
+ // wordSpacing
1457
+ let fSpacing = this._common.getFormattedDim(getComputedStyle(this._body).wordSpacing);
1458
+ if (typeof this._stateValues.body.wordSpacing === 'undefined')
1459
+ this._stateValues.body.wordSpacing = '';
1460
+ if (fSpacing && fSpacing.suffix && !isNaN(fSpacing.size * 1)) {
1461
+ this._body.style.wordSpacing = fSpacing.size * 1 + factor + fSpacing.suffix;
1462
+ }
1463
+ // letterSpacing
1464
+ let fSpacing2 = this._common.getFormattedDim(getComputedStyle(this._body).letterSpacing);
1465
+ if (typeof this._stateValues.body.letterSpacing === 'undefined')
1466
+ this._stateValues.body.letterSpacing = '';
1467
+ if (fSpacing2 && fSpacing2.sufix && !isNaN(fSpacing2.size * 1)) {
1468
+ this._body.style.letterSpacing = fSpacing2.size * 1 + factor + fSpacing2.sufix;
1469
+ }
1470
+ if (this._stateValues.textToSpeech)
1471
+ this.textToSpeech(`Text Spacing ${isIncrease ? 'Increased' : 'Decreased'}`);
1472
+ }
1473
+ }
1474
+ speechToText() {
1475
+ if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) {
1476
+ this._recognition = new (window.SpeechRecognition ||
1477
+ window.webkitSpeechRecognition)();
1478
+ this._recognition.continuous = true;
1479
+ this._recognition.interimResults = true;
1480
+ this._recognition.onstart = () => {
1481
+ // TODO red color on mic icon
1482
+ // console.log('listening . . .');
1483
+ // if (this.speechToTextTarget)
1484
+ // this.speechToTextTarget.parentElement.classList.add('_access-listening');
1485
+ this._body.classList.add('_access-listening');
1486
+ };
1487
+ this._recognition.onend = () => {
1488
+ this._body.classList.remove('_access-listening');
1489
+ };
1490
+ this._recognition.onresult = (event) => {
1491
+ let finalTranscript = '';
1492
+ if (typeof event.results === 'undefined') {
1493
+ return;
1494
+ }
1495
+ for (let i = event.resultIndex; i < event.results.length; ++i) {
1496
+ if (event.results[i].isFinal) {
1497
+ finalTranscript += event.results[i][0].transcript;
1498
+ }
1499
+ }
1500
+ if (finalTranscript && this._speechToTextTarget) {
1501
+ this._speechToTextTarget.parentElement.classList.remove('_access-listening');
1502
+ if (this._speechToTextTarget.tagName.toLowerCase() === 'input' ||
1503
+ this._speechToTextTarget.tagName.toLowerCase() === 'textarea') {
1504
+ this._speechToTextTarget.value = finalTranscript;
1505
+ }
1506
+ else if (this._speechToTextTarget.getAttribute('contenteditable') !== null) {
1507
+ this._speechToTextTarget.innerText = finalTranscript;
1508
+ }
1509
+ }
1510
+ };
1511
+ this._recognition.lang = this.options.language.speechToTextLang;
1512
+ this._recognition.start();
1513
+ }
1514
+ }
1515
+ textToSpeech(text) {
1516
+ const windowAny = window;
1517
+ if (!windowAny.SpeechSynthesisUtterance || !windowAny.speechSynthesis)
1518
+ return;
1519
+ let msg = new windowAny.SpeechSynthesisUtterance(text);
1520
+ msg.lang = this.options.language.textToSpeechLang;
1521
+ msg.lang = this.options.textToSpeechLang;
1522
+ msg.rate = this._stateValues.speechRate;
1523
+ msg.onend = () => {
1524
+ this._isReading = false;
1525
+ };
1526
+ let voices = windowAny.speechSynthesis.getVoices();
1527
+ let isLngSupported = false;
1528
+ for (let i = 0; i < voices.length; i++) {
1529
+ if (voices[i].lang === msg.lang) {
1530
+ msg.voice = voices[i];
1531
+ isLngSupported = true;
1532
+ break;
1533
+ }
1534
+ }
1535
+ if (!isLngSupported) {
1536
+ this._common.warn('text to speech language not supported!');
1537
+ }
1538
+ if (window.speechSynthesis.pending || window.speechSynthesis.speaking) {
1539
+ window.speechSynthesis.pause;
1540
+ window.speechSynthesis.cancel();
1541
+ }
1542
+ window.speechSynthesis.speak(msg);
1543
+ this._isReading = true;
1544
+ }
1545
+ createScreenShot(url) {
1546
+ return new Promise((resolve) => {
1547
+ let canvas = document.createElement('canvas');
1548
+ let img = new Image();
1549
+ canvas.style.position = 'fixed';
1550
+ canvas.style.top = '0';
1551
+ canvas.style.left = '0';
1552
+ canvas.style.opacity = '0';
1553
+ canvas.style.transform = 'scale(0.05)';
1554
+ img.crossOrigin = 'anonymous';
1555
+ img.onload = async () => {
1556
+ document.body.appendChild(canvas);
1557
+ const ctx = canvas.getContext('2d');
1558
+ canvas.width = img.naturalWidth;
1559
+ canvas.height = img.naturalHeight;
1560
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
1561
+ ctx.drawImage(img, 0, 0);
1562
+ let res;
1563
+ try {
1564
+ res = canvas.toDataURL('image/png');
1565
+ }
1566
+ catch (e) { }
1567
+ resolve(res);
1568
+ canvas.remove();
1569
+ };
1570
+ img.onerror = () => {
1571
+ resolve(common_js_1.Common.DEFAULT_PIXEL);
1572
+ };
1573
+ img.src = url;
1574
+ });
1575
+ }
1576
+ listen(e) {
1577
+ if (typeof this._recognition === 'object' && typeof this._recognition.stop === 'function')
1578
+ this._recognition.stop();
1579
+ const target = (0, event_utils_js_1.getEventTarget)(e);
1580
+ if (!target)
1581
+ return;
1582
+ this._speechToTextTarget = target;
1583
+ this.speechToText();
1584
+ }
1585
+ read(e) {
1586
+ if (!e)
1587
+ return;
1588
+ try {
1589
+ e.preventDefault();
1590
+ e.stopPropagation();
1591
+ }
1592
+ catch (ex) { }
1593
+ const target = (0, event_utils_js_1.getEventTarget)(e);
1594
+ if (!target)
1595
+ return;
1596
+ let allContent = Array.prototype.slice.call(document.querySelectorAll('._access-menu *'));
1597
+ for (const key in allContent) {
1598
+ if (allContent[key] === target && e instanceof MouseEvent)
1599
+ return;
1600
+ }
1601
+ if (e instanceof KeyboardEvent && ((e.shiftKey && e.key === 'Tab') || e.key === 'Tab')) {
1602
+ this.textToSpeech(target.innerText);
1603
+ return;
1604
+ }
1605
+ if (this._isReading) {
1606
+ window.speechSynthesis.cancel();
1607
+ this._isReading = false;
1608
+ }
1609
+ else
1610
+ this.textToSpeech(target.innerText);
1611
+ }
1612
+ runHotkey(name) {
1613
+ switch (name) {
1614
+ case 'toggleMenu':
1615
+ this.toggleMenu();
1616
+ break;
1617
+ default:
1618
+ if (typeof this.menuInterface[name] === 'function') {
1619
+ if (this._options.modules[name]) {
1620
+ this.menuInterface[name](false);
1621
+ }
1622
+ }
1623
+ break;
1624
+ }
1625
+ }
1626
+ toggleMenu() {
1627
+ const shouldClose = this._menu.classList.contains('close');
1628
+ const isOpening = shouldClose;
1629
+ setTimeout(() => {
1630
+ this._menu.querySelector('ul').classList.toggle('before-collapse');
1631
+ }, shouldClose ? 500 : 10);
1632
+ this._menu.classList.toggle('close');
1633
+ this.syncMenuState(isOpening);
1634
+ this._menu.childNodes.forEach((child) => {
1635
+ if (child.hasChildNodes()) {
1636
+ if (child.nodeType === Node.ELEMENT_NODE && child.tagName === 'P') {
1637
+ child.tabIndex = -1;
1638
+ }
1639
+ }
1640
+ });
1641
+ }
1642
+ invoke(action, button) {
1643
+ if (typeof this.menuInterface[action] === 'function')
1644
+ this.menuInterface[action](undefined, button);
1645
+ }
1646
+ onKeyDown(e) {
1647
+ const act = (0, hotkeys_js_1.findMatchingHotkey)(this.options.hotkeys.keys, e);
1648
+ if (act !== undefined) {
1649
+ this.runHotkey(act[0]);
1650
+ }
1651
+ }
1652
+ build() {
1653
+ this._stateValues = {
1654
+ underlineLinks: false,
1655
+ textToSpeech: false,
1656
+ bigCursor: false,
1657
+ readingGuide: false,
1658
+ speechRate: 1,
1659
+ body: {},
1660
+ html: {}
1661
+ };
1662
+ this._body = document.body || document.getElementsByTagName('body')[0];
1663
+ this._html = document.documentElement || document.getElementsByTagName('html')[0];
1664
+ if (this.options.textEmlMode)
1665
+ this.initFontSize();
1666
+ this.injectCss(!this.options.suppressCssInjection && !this.options.suppressDomInjection);
1667
+ if (!this.options.suppressDomInjection) {
1668
+ this._icon = this.injectIcon();
1669
+ this._menu = this.injectMenu();
1670
+ this.syncMenuState(false);
1671
+ this.injectTts();
1672
+ setTimeout(() => {
1673
+ this.addListeners();
1674
+ this.disableUnsupportedModulesAndSort();
1675
+ }, 10);
1676
+ if (this.options.hotkeys.enabled) {
1677
+ document.addEventListener('keydown', this._onKeyDownBind, false);
1678
+ }
1679
+ this._icon.addEventListener('click', (event) => {
1680
+ if (!(0, event_utils_js_1.isActivationEvent)(event))
1681
+ return;
1682
+ this.toggleMenu();
1683
+ }, false);
1684
+ this._icon.addEventListener('keyup', (event) => {
1685
+ if (!(0, event_utils_js_1.isActivationEvent)(event))
1686
+ return;
1687
+ this.toggleMenu();
1688
+ }, false);
1689
+ this._menu.addEventListener('keydown', (event) => {
1690
+ if (event.key !== 'Escape')
1691
+ return;
1692
+ event.preventDefault();
1693
+ this.toggleMenu();
1694
+ this._icon.focus();
1695
+ }, false);
1696
+ setTimeout(() => {
1697
+ this._icon.style.opacity = '1';
1698
+ }, 10);
1699
+ }
1700
+ this.updateReadGuide = (e) => {
1701
+ let newPos = 0;
1702
+ if (e.type === 'touchmove') {
1703
+ newPos = e.changedTouches[0].clientY;
1704
+ }
1705
+ else {
1706
+ newPos = e.y;
1707
+ }
1708
+ document.getElementById('access_read_guide_bar').style.top =
1709
+ newPos - (parseInt(this.options.guide.height.replace('px', '')) + 5) + 'px';
1710
+ };
1711
+ if (this.options.session.persistent)
1712
+ this.setSessionFromCache();
1713
+ }
1714
+ updateReadGuide(e) {
1715
+ let newPos = 0;
1716
+ if (e.type === 'touchmove') {
1717
+ newPos = e.changedTouches[0].clientY;
1718
+ }
1719
+ else {
1720
+ newPos = e.y;
1721
+ }
1722
+ document.getElementById('access_read_guide_bar').style.top =
1723
+ newPos - (parseInt(this.options.guide.height.replace('px', '')) + 5) + 'px';
1724
+ }
1725
+ resetIfDefined(src, dest, prop) {
1726
+ if (typeof src !== 'undefined')
1727
+ dest[prop] = src;
1728
+ }
1729
+ onChange(updateSession) {
1730
+ if (updateSession && this.options.session.persistent)
1731
+ this.saveSession();
1732
+ }
1733
+ saveSession() {
1734
+ (0, session_js_1.saveSessionState)(this._storage, this.sessionState);
1735
+ }
1736
+ setSessionFromCache() {
1737
+ (0, session_js_1.restoreSessionState)(this._storage, {
1738
+ applyTextSize: (isIncrease) => this.alterTextSize(isIncrease),
1739
+ applyTextSpace: (isIncrease) => this.alterTextSpace(isIncrease),
1740
+ applyLineHeight: (isIncrease) => this.alterLineHeight(isIncrease),
1741
+ enableInvertColors: () => this.menuInterface.invertColors(),
1742
+ enableGrayHues: () => this.menuInterface.grayHues(),
1743
+ enableUnderlineLinks: () => this.menuInterface.underlineLinks(),
1744
+ enableBigCursor: () => this.menuInterface.bigCursor(),
1745
+ enableReadingGuide: () => this.menuInterface.readingGuide(),
1746
+ assignSessionState: (sessionState) => {
1747
+ this.sessionState = sessionState;
1748
+ }
1749
+ });
1750
+ }
1751
+ destroy() {
1752
+ const allSelectors = this._common.deployedObjects.getAll();
1753
+ allSelectors.forEach((value, key) => {
1754
+ const elem = document.querySelector(key);
1755
+ if (elem)
1756
+ elem.parentElement.removeChild(elem);
1757
+ });
1758
+ document.removeEventListener('keydown', this._onKeyDownBind, false);
1759
+ }
1760
+ }
1761
+ exports.Accessibility = Accessibility;
1762
+ Accessibility.init = (opt) => {
1763
+ console.warn('"Accessibility.init()" is deprecated! Please use "new Accessibility()" instead');
1764
+ new Accessibility(opt);
1765
+ };
1766
+ if (typeof window !== 'undefined')
1767
+ window.Accessibility = Accessibility;
1768
+ __exportStar(require("./interfaces/accessibility.interface.js"), exports);
1769
+ __exportStar(require("./interfaces/menu.interface.js"), exports);
1770
+ exports.default = Accessibility;
1771
+ //# sourceMappingURL=main.js.map