unicode-input-toolconverter 0.2.0

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 (123) hide show
  1. package/.babelrc.json +3 -0
  2. package/.editorconfig +16 -0
  3. package/.nojekyll +0 -0
  4. package/.nyc_output/out.json +173804 -0
  5. package/.nyc_output/processinfo/index.json +1 -0
  6. package/CHANGES.md +11 -0
  7. package/COPYING.LESSER.txt +180 -0
  8. package/COPYING.txt +687 -0
  9. package/README.md +65 -0
  10. package/_locales/en-US/messages.json +3126 -0
  11. package/_locales/hu-HU/messages.json +3126 -0
  12. package/_locales/pt-BR/messages.json +3126 -0
  13. package/_locales/sv-SE/messages.json +3126 -0
  14. package/babel.config.json +5 -0
  15. package/browser_action/characterSelection.js +91 -0
  16. package/browser_action/charrefConverters.js +389 -0
  17. package/browser_action/chartBuild.js +155 -0
  18. package/browser_action/encodingBehaviors.js +72 -0
  19. package/browser_action/encodings.js +97 -0
  20. package/browser_action/entities.js +12 -0
  21. package/browser_action/entityBehaviors.js +96 -0
  22. package/browser_action/index-es.html +15 -0
  23. package/browser_action/index-instrumented.html +16 -0
  24. package/browser_action/index-pages.html +16 -0
  25. package/browser_action/index.html +16 -0
  26. package/browser_action/index.iife.min.js +2 -0
  27. package/browser_action/index.iife.min.js.map +1 -0
  28. package/browser_action/index.instrumented.iife.min.js +2 -0
  29. package/browser_action/index.instrumented.iife.min.js.map +1 -0
  30. package/browser_action/index.js +95 -0
  31. package/browser_action/preferences/prefDefaults.js +52 -0
  32. package/browser_action/service-worker/sw-activateCallback.js +53 -0
  33. package/browser_action/service-worker/sw-locales.json +6 -0
  34. package/browser_action/service-worker/sw-resources.json +73 -0
  35. package/browser_action/service-worker/sw-unicode-data.json +3 -0
  36. package/browser_action/styles/unicode-dialog.css +391 -0
  37. package/browser_action/templateUtils/elements.js +12 -0
  38. package/browser_action/templateUtils/fill.js +3 -0
  39. package/browser_action/templateUtils/validation.js +6 -0
  40. package/browser_action/templates/chartBuild.js +185 -0
  41. package/browser_action/templates/index.js +1304 -0
  42. package/browser_action/templatesElementCustomization/widgets.js +56 -0
  43. package/browser_action/unicode/UnicodeConverter.js +793 -0
  44. package/browser_action/unicode/charrefunicodeDb.js +258 -0
  45. package/browser_action/unicode/getScriptInfoForCodePoint.js +646 -0
  46. package/browser_action/unicode/hangul.js +253 -0
  47. package/browser_action/unicode/lastScriptNames.json +5 -0
  48. package/browser_action/unicode/parseUnihanFromTextFileStrings.js +56 -0
  49. package/browser_action/unicode/unicodeFieldInfo.js +120 -0
  50. package/browser_action/unicode/unicodeScripts.js +4912 -0
  51. package/browser_action/unicode/unihan.js +129 -0
  52. package/browser_action/unicode/unihanDbPopulate.js +26 -0
  53. package/browser_action/unicodecharref.js +1480 -0
  54. package/browser_action/utils/DOMUtils.js +122 -0
  55. package/browser_action/utils/FetchUtils.js +19 -0
  56. package/browser_action/utils/TextUtils.js +28 -0
  57. package/browser_action/utils/TypedArrayUtils.js +21 -0
  58. package/browser_action/utils/semicolonSeparatedToArray.js +12 -0
  59. package/browser_action/utils/setupServiceWorker.js +193 -0
  60. package/cypress.config.js +21 -0
  61. package/download/entities/copyright-software-20021231.html +70 -0
  62. package/download/entities/html5-uppercase.ent +54 -0
  63. package/download/entities/htmlmathml-f.ent +2164 -0
  64. package/download/entities/isoamsa.ent +201 -0
  65. package/download/entities/isoamsb.ent +177 -0
  66. package/download/entities/isoamsc.ent +77 -0
  67. package/download/entities/isoamsn.ent +148 -0
  68. package/download/entities/isoamso.ent +107 -0
  69. package/download/entities/isoamsr.ent +238 -0
  70. package/download/entities/isobox.ent +95 -0
  71. package/download/entities/isocyr1.ent +122 -0
  72. package/download/entities/isocyr2.ent +81 -0
  73. package/download/entities/isodia.ent +69 -0
  74. package/download/entities/isogrk1.ent +104 -0
  75. package/download/entities/isogrk2.ent +75 -0
  76. package/download/entities/isogrk3.ent +98 -0
  77. package/download/entities/isogrk4.ent +98 -0
  78. package/download/entities/isolat1.ent +117 -0
  79. package/download/entities/isolat2.ent +176 -0
  80. package/download/entities/isomfrk.ent +107 -0
  81. package/download/entities/isomopf.ent +81 -0
  82. package/download/entities/isomscr.ent +107 -0
  83. package/download/entities/isonum.ent +131 -0
  84. package/download/entities/isopub.ent +140 -0
  85. package/download/entities/isotech.ent +216 -0
  86. package/download/entities/mmlalias.ent +598 -0
  87. package/download/entities/mmlextra.ent +154 -0
  88. package/download/entities/predefined.ent +52 -0
  89. package/download/entities/w3centities-f.ent +2276 -0
  90. package/download/entities/xhtml1-lat1.ent +143 -0
  91. package/download/entities/xhtml1-special.ent +78 -0
  92. package/download/entities/xhtml1-symbol.ent +171 -0
  93. package/eslint.config.js +66 -0
  94. package/icons/openWindow16.png +0 -0
  95. package/icons/openWindow24.png +0 -0
  96. package/lgtm.yml +5 -0
  97. package/lib/background.html +11 -0
  98. package/lib/background.js +13 -0
  99. package/lib/overlay.css +6 -0
  100. package/manifest.json +37 -0
  101. package/package.json +121 -0
  102. package/polyfills/browser-polyfill.min.js +8 -0
  103. package/polyfills/browser-polyfill.min.js.map +1 -0
  104. package/server.js +61 -0
  105. package/sw.js +259 -0
  106. package/tools/entities-import.js +62 -0
  107. package/tools/findEsResources.js +30 -0
  108. package/tools/list-locales.js +17 -0
  109. package/tools/parseUnicodeCharts.js +428 -0
  110. package/tools/ucd-import.js +24 -0
  111. package/tools/unicode-charts.html +596 -0
  112. package/tools/unihan-import.js +72 -0
  113. package/unicode_copyright.txt +46 -0
  114. package/vendor/camelcase/index.js +110 -0
  115. package/vendor/fflate/esm/browser.js +2665 -0
  116. package/vendor/intl-dom/dist/index.esm.js +2962 -0
  117. package/vendor/jamilih/dist/jml-es.js +2359 -0
  118. package/vendor/jquery/dist/jquery.js +10716 -0
  119. package/vendor/json-6/dist/index.mjs +1783 -0
  120. package/vendor/miller-columns/dist/index-es.min.js +1 -0
  121. package/vendor/miller-columns/miller-columns.css +75 -0
  122. package/vendor/simple-prefs/dist/index.esm.js +286 -0
  123. package/web-ext-config.cjs +13 -0
@@ -0,0 +1,1480 @@
1
+ /* eslint-disable camelcase -- Temporary */
2
+ // See https://unicode.org/Public/UNIDATA/ for data use
3
+
4
+ import {$, $$, jml} from '../vendor/jamilih/dist/jml-es.js';
5
+ // Todo: Filed the following to avoid both sync and callbacks:
6
+ // https://github.com/101arrowz/fflate/issues/70
7
+ import {strFromU8} from '../vendor/fflate/esm/browser.js'; // unzipSync,
8
+ import {
9
+ getUnicodeDefaults, getPrefDefaults
10
+ } from './preferences/prefDefaults.js';
11
+ import {chartBuild, lastStartCharCode} from './chartBuild.js';
12
+
13
+ import camelCase from '../vendor/camelcase/index.js';
14
+ import {insertIntoOrOverExisting} from './utils/TextUtils.js';
15
+ import {joinChunks} from './utils/TypedArrayUtils.js';
16
+ import {
17
+ placeItem, removeViewChildren, createHTMLElement,
18
+ showProgress
19
+ } from './utils/DOMUtils.js';
20
+ import getScriptInfoForCodePoint from './unicode/getScriptInfoForCodePoint.js';
21
+ import charrefunicodeDb, {UnihanDatabase} from './unicode/charrefunicodeDb.js';
22
+ import {getCJKTypeFromHexString} from './unicode/unihan.js';
23
+ import unihanDbPopulate from './unicode/unihanDbPopulate.js';
24
+ // import parseUnihanFromTextFileStrings from
25
+ // './unicode/parseUnihanFromTextFileStrings.js';
26
+ import {registerDTD} from './entityBehaviors.js';
27
+ import {entities, numericCharacterReferences} from './entities.js';
28
+ import {findBridgeForTargetID} from './charrefConverters.js';
29
+
30
+ let _, charrefunicodeConverter, getPref, setPref;
31
+ export const shareVars = ({_: l10n, charrefunicodeConverter: _uc}) => {
32
+ _ = l10n;
33
+ charrefunicodeConverter = _uc;
34
+ ({getPref, setPref} = getUnicodeDefaults());
35
+ };
36
+
37
+ /**
38
+ * @returns {Promise<Object<string,string[]>>}
39
+ */
40
+ async function getDownloadResults () {
41
+ const receivedInfo = await showProgress({
42
+ // 6747669; // 39.5 MB unzipped;
43
+ // url: '/download/unihan/Unihan.zip',
44
+ url: location.href.includes('index-pages')
45
+ /* istanbul ignore next -- For GitHub Pages only */
46
+ ? '/unicode-input-toolconverter/download/unihan/unihan.json'
47
+ : '/download/unihan/unihan.json',
48
+ progressElement: $('#progress_element'),
49
+ progress (percentComplete) {
50
+ return `${_('download_progress')} ${
51
+ percentComplete.toFixed(2)
52
+ }${_('percentSign')}`;
53
+ }
54
+ });
55
+ const compressed = joinChunks(receivedInfo);
56
+
57
+ return JSON.parse(strFromU8(compressed));
58
+
59
+ /*
60
+ // Works but easier to work with generated file over zip
61
+
62
+ const decompressedObj = unzipSync(compressed);
63
+ const scriptFileAsStrings = Object.values(decompressedObj).map(
64
+ (decompressed) => {
65
+ return strFromU8(decompressed);
66
+ }
67
+ );
68
+
69
+ return parseUnihanFromTextFileStrings(scriptFileAsStrings);
70
+ */
71
+ }
72
+
73
+ const unicodecharref = {
74
+ async downloadUnihan () {
75
+ $('#DownloadButtonBox').hidden = true;
76
+ $('#DownloadProgressBox').hidden = false;
77
+
78
+ try {
79
+ const parsed = await getDownloadResults();
80
+
81
+ this.unihanDatabase?.close();
82
+ this.unihanDatabase = await unihanDbPopulate(parsed);
83
+
84
+ // Confirm it worked
85
+ await this.unihanDatabase.getUnicodeFields('3400');
86
+
87
+ alert(_('Finished_download'));
88
+ this.unihanDb_exists = true;
89
+ $('#closeDownloadProgressBox').hidden = false;
90
+ $('#UnihanInstalled').hidden = false;
91
+ } catch (e) {
92
+ $('#closeDownloadProgressBox').hidden = true;
93
+ $('#UnihanInstalled').hidden = true;
94
+ $('#DownloadProgressBox').hidden = true;
95
+ $('#DownloadButtonBox').hidden = false;
96
+ alert(_('Problem_downloading'));
97
+
98
+ // eslint-disable-next-line no-console -- Debug
99
+ console.error(e);
100
+ }
101
+ },
102
+ closeDownloadProgressBox () {
103
+ $('#closeDownloadProgressBox').hidden = false;
104
+ $('#DownloadProgressBox').hidden = true;
105
+ },
106
+ /**
107
+ * Unused.
108
+ */
109
+ /*
110
+ makeDropMenuRows (type) {
111
+ const prefix = (type === 'Unihan') ? 'searchk' : 'search';
112
+ try {
113
+ for (const i=0; i < this[type].length; i++) {
114
+ const row = createXULElement('row');
115
+ const label = createXULElement('label');
116
+
117
+ label.setAttribute('value', _(prefix + this[type][i]));
118
+ label.setAttribute('control', prefix + this[type][i]);
119
+ const textbox = createXULElement('textbox');
120
+ textbox.setAttribute('id', prefix + this[type][i]);
121
+ textbox.setAttribute('rows', '1');
122
+ textbox.setAttribute('cols', '2');
123
+ textbox.addEventListener(
124
+ 'change', function (e) {unicodecharref['search' + type](e);}
125
+ );
126
+ textbox.addEventListener(
127
+ 'input', function (e) {unicodecharref['search' + type](e);}
128
+ );
129
+ row.append(label);
130
+ row.append(textbox);
131
+ $(type+'Search').append(row);
132
+ }
133
+ }
134
+ catch(e) {
135
+ alert(this[type][i])
136
+ }
137
+ },
138
+
139
+ makeRows (type) {
140
+ const prefix = (type === 'Unihan') ? 'searchk' : 'search';
141
+ let i;
142
+ try {
143
+ for (i = 0; i < this[type].length; i++) {
144
+ const row = createXULElement('row');
145
+ const label = createXULElement('label');
146
+ label.setAttribute('value', _(prefix + this[type][i]));
147
+ label.setAttribute('control', prefix + this[type][i]);
148
+ row.append(label);
149
+ if (type === 'Unicode') { // Fix: make block for Unihan if need that
150
+ const menuIdx = this.UnicodeMenus.indexOf(this[type][i]);
151
+ if (menuIdx !== -1) {
152
+ const match = this.UnicodeMenus[menuIdx];
153
+ switch (match) {
154
+ case 'Decimal':
155
+ // Fallthrough
156
+ case 'Digit':
157
+ // Fallthrough
158
+ case 'Canonical_Combining_Class':
159
+ // Fallthrough
160
+ case 'General_Category':
161
+ // Fallthrough
162
+ case 'Bidi_Mirrored': // 'Y'/'N'
163
+ // Fallthrough
164
+ case 'Bidi_Class': {
165
+ const menulist = createXULElement('menulist');
166
+ menulist.className = 'searchMenu';
167
+ const menupopup = createXULElement('menupopup');
168
+ for (let j = 0; j < this['UnicodeMenu' + match].length; j++) {
169
+ const menuitem = createXULElement('menuitem');
170
+ menuitem.setAttribute(
171
+ 'label', _(match + this['UnicodeMenu' + match][j])
172
+ );
173
+ menuitem.setAttribute(
174
+ 'tooltiptext', _(match + this['UnicodeMenu' + match][j])
175
+ );
176
+ menuitem.setAttribute(
177
+ 'value', this['UnicodeMenu' + match][j]
178
+ );
179
+ menupopup.append(menuitem);
180
+ }
181
+ if (match === 'Canonical_Combining_Class') {
182
+ for (let j = 11; j <= 36; j++) {
183
+ // Other Non-Numeric not listed in UnicodeMenuCCVNumericOnly
184
+ const menuitem = createXULElement('menuitem');
185
+ menuitem.setAttribute('label', j);
186
+ menuitem.setAttribute('tooltiptext', j);
187
+ menuitem.setAttribute('value', j);
188
+ menupopup.append(menuitem);
189
+ }
190
+ for (
191
+ let j = 0;
192
+ j < this['UnicodeMenu' + 'CCVNumericOnly'].length;
193
+ j++
194
+ ) {
195
+ const menuitem = createXULElement('menuitem');
196
+ menuitem.setAttribute(
197
+ 'label', this['UnicodeMenu' + 'CCVNumericOnly'][j]
198
+ );
199
+ menuitem.setAttribute(
200
+ 'tooltiptext', this['UnicodeMenu' + 'CCVNumericOnly'][j]
201
+ );
202
+ menuitem.setAttribute(
203
+ 'value', this['UnicodeMenu' + 'CCVNumericOnly'][j]
204
+ );
205
+ menupopup.append(menuitem);
206
+ }
207
+ }
208
+ menulist.append(menupopup);
209
+ menulist.setAttribute('id', prefix + this[type][i]);
210
+ row.append(menulist);
211
+ $('#' + type + 'Search').append(row);
212
+ continue;
213
+ } default:
214
+ break;
215
+ }
216
+ }
217
+ }
218
+ const textbox = createXULElement('textbox');
219
+ textbox.setAttribute('id', prefix + this[type][i]);
220
+ textbox.setAttribute('rows', '1');
221
+ textbox.setAttribute('cols', '2');
222
+ row.append(textbox);
223
+ $('#' + type + 'Search').append(row);
224
+ }
225
+ } catch (e) {
226
+ alert('1:' + type + i + e + this[type][i]);
227
+ }
228
+ // Add handlers for textboxes
229
+ // let tabpanel = type === 'Unicode' ? '#regularSearch' : '#cjkSearch';
230
+ const tabpanel = '#tabboxSearch';
231
+
232
+ $(tabpanel).addEventListener('change', function (e) {
233
+ unicodecharref['search' + type](e.target);
234
+ });
235
+ $(tabpanel).addEventListener('input', function (e) {
236
+ unicodecharref['search' + type](e.target);
237
+ });
238
+ $(tabpanel).addEventListener('select', function (e) {
239
+ if (
240
+ e.target.nodeName !== 'menulist' &&
241
+ e.target.nodeName !== 'textbox'
242
+ ) { return; }
243
+ unicodecharref['search' + type](e.target);
244
+ }); // Triggered initially which sets preference to "Lu"
245
+ },
246
+ */
247
+ // Fix: Should also create the detailedView and detailedCJKView's
248
+ // content dynamically (and thus fully conditionally rather than hiding)
249
+ /*
250
+ async testIfComplexWindow () {
251
+ if (await getPref('showComplexWindow')) {
252
+ $('#specializedSearch').hidden = false;
253
+ this.makeRows('Unihan');
254
+ this.makeRows('Unicode');
255
+ $('#detailedView').collapsed = false;
256
+ $('#detailedCJKView').collapsed = false;
257
+ } else {
258
+ $('#specializedSearch').hidden = true;
259
+ $('#detailedView').collapsed = true;
260
+ $('#detailedCJKView').collapsed = true;
261
+ }
262
+ },
263
+ */
264
+ setupBoolChecked (...els) {
265
+ els.forEach(async (el) => {
266
+ $('#' + el).checked = await getPref(el);
267
+ });
268
+ },
269
+ /**
270
+ * @param {PlainObject} cfg
271
+ * @param {boolean} [cfg.customProtocol]
272
+ * @param {boolean} [cfg.options]
273
+ * @param {string} [cfg.convert]
274
+ * @param {string} [cfg.targetid]
275
+ * @param {string} [cfg.selection]
276
+ * @returns {Promise<void>}
277
+ */
278
+ async initialize (cfg) {
279
+ // this.refreshToolbarDropdown(); // redundant?
280
+
281
+ this.unihanDb_exists = false;
282
+ try {
283
+ const namespace = 'unicode-input-toolconverter-Unihan';
284
+ this.unihanDatabase = new UnihanDatabase({
285
+ name: namespace,
286
+ // We don't peg to package major version as database version may vary
287
+ // independently
288
+ version: 1
289
+ });
290
+ // Do not update here; just checking if already downloaded
291
+ await this.unihanDatabase.connect();
292
+
293
+ // Test Unihan value
294
+ await this.unihanDatabase.getUnicodeFields('3400');
295
+
296
+ this.unihanDb_exists = true;
297
+ $('#DownloadButtonBox').hidden = true;
298
+ $('#UnihanInstalled').hidden = false;
299
+ } catch (e) {
300
+ /* istanbul ignore if -- Only expected for transactions */
301
+ if (!e.message.includes('ransaction')) {
302
+ // eslint-disable-next-line no-console -- Debug
303
+ console.error(e);
304
+ }
305
+ $('#DownloadButtonBox').hidden = false;
306
+ $('#UnihanInstalled').hidden = true;
307
+ }
308
+
309
+ // document.documentElement.maxWidth =
310
+ // window.screen.availWidth-(window.screen.availWidth*1/100);
311
+ $('#unicodeTabBox').style.maxWidth = window.screen.availWidth -
312
+ (window.screen.availWidth * 3 / 100);
313
+ $('#unicodeTabBox > .tabs').style.maxWidth =
314
+ window.screen.availWidth - (window.screen.availWidth * 3 / 100);
315
+ /*
316
+ $('#unicodeTabBox').style.maxHeight =
317
+ window.screen.availHeight-(window.screen.availHeight*5/100);
318
+ $('#conversionhbox').style.maxHeight =
319
+ window.screen.availHeight-(window.screen.availHeight*13/100);
320
+
321
+ $('#noteDescriptionBox2').height =
322
+ $('#noteDescriptionBox2').height =
323
+ window.screen.availHeight-(window.screen.availHeight*25/100);
324
+ $('#unicodeTabBox').style.maxWidth =
325
+ window.screen.availWidth-(window.screen.availWidth*1/100);
326
+ $('#unicodetabs').style.maxWidth =
327
+ window.screen.availWidth-(window.screen.availWidth*2/100);
328
+ $('#unicodeTabBox').style.maxWidth =
329
+ window.screen.availWidth-(window.screen.availWidth*2/100);
330
+ $('#chartcontent').style.maxWidth =
331
+ window.screen.availWidth-(window.screen.availWidth*25/100);
332
+ $('#chart_selectchar_persist_vbox').maxWidth =
333
+ window.screen.availWidth-(window.screen.availWidth*25/100);
334
+ */
335
+ // $('#tableholder').maxWidth =
336
+ // window.screen.availWidth-(window.screen.availWidth*50/100);
337
+ // $('#tableholder').width = window.screen.availWidth -
338
+ // (window.screen.availWidth*50/100);
339
+ // window.sizeToContent();
340
+
341
+ // await this.testIfComplexWindow();
342
+
343
+ const [
344
+ lang, font, initialTab, multiline,
345
+ cssWhitespace, tblrowsset, tblcolsset, ampspace,
346
+ DTDtxtbxval
347
+ // outerh, outerw
348
+ ] = await Promise.all([
349
+ getPref('lang'),
350
+ getPref('font'),
351
+ getPref('initialTab'),
352
+ getPref('multiline'),
353
+ getPref('cssWhitespace'),
354
+ getPref('tblrowsset'),
355
+ getPref('tblcolsset'),
356
+ getPref('ampspace'),
357
+ getPref('DTDtextbox')
358
+ // getPref('outerHeight'),
359
+ // getPref('outerWidth')
360
+ ]);
361
+
362
+ if (multiline) {
363
+ const display = $('#displayUnicodeDesc');
364
+ display.replaceWith(jml('textarea', {
365
+ id: 'displayUnicodeDesc',
366
+ rows: 3
367
+ }));
368
+ }
369
+
370
+ this.setupBoolChecked(...Object.entries(getPrefDefaults()).filter((
371
+ [, value]
372
+ ) => {
373
+ return typeof value === 'boolean';
374
+ }).map(([key]) => key));
375
+ switch (cssWhitespace) {
376
+ case ' ':
377
+ $('#CSSWhitespace').selectedIndex = 0;
378
+ break;
379
+ /*
380
+ // Carriage returns shouldn't survive
381
+ case '\r\n':
382
+ $('#CSSWhitespace').selectedIndex = 1;
383
+ break;
384
+ case '\r':
385
+ $('#CSSWhitespace').selectedIndex = 2;
386
+ break;
387
+ */
388
+ case '\n':
389
+ $('#CSSWhitespace').selectedIndex = 1;
390
+ break;
391
+ case '\t':
392
+ $('#CSSWhitespace').selectedIndex = 2;
393
+ break;
394
+ case '\f':
395
+ $('#CSSWhitespace').selectedIndex = 3;
396
+ break;
397
+ /* istanbul ignore next -- Unexpected value */
398
+ default:
399
+ /* istanbul ignore next -- Unexpected value */
400
+ throw new Error('Unexpected whitespace preference value');
401
+ }
402
+
403
+ /* if (await getPref('hexstyleLwr')) {
404
+ $(EXT_BASE + 'hexstyleLwr').selectedIndex = 0;
405
+ }
406
+ else {
407
+ $(EXT_BASE + 'hexstyleLwr').selectedIndex = 1;
408
+ } */
409
+ /* if ((await getPref('xstyle')) === 'x') {
410
+ $(EXT_BASE + 'xstyle').checked = true;
411
+ } */
412
+
413
+ // Set the size per the prefs (don't increase or decrease the value)
414
+ await this.resizecells();
415
+
416
+ $('#rowsset').value = tblrowsset;
417
+ $('#colsset').value = tblcolsset;
418
+
419
+ // Save copies in case decide to reset later (i.e., not append to
420
+ // HTML entities, then wish to append to them again)
421
+ this.origents = [];
422
+ this.origcharrefs = [];
423
+ this.orignewents = [];
424
+ this.orignewcharrefs = [];
425
+
426
+ this.origents = [...entities];
427
+ this.origcharrefs = [...numericCharacterReferences];
428
+ this.orignewents = [...charrefunicodeConverter.newents];
429
+ this.orignewcharrefs = [...charrefunicodeConverter.newcharrefs];
430
+
431
+ $('#lang').value = lang;
432
+ $('#font').value = font;
433
+ $('#initialTab').value = $('#mi_' + initialTab).value;
434
+
435
+ $('#DTDtextbox').value = DTDtxtbxval;
436
+ await registerDTD();
437
+
438
+ // These defaults are necessary for the sake of the options URL
439
+ // (when called from addons menu)
440
+ let toconvert = null;
441
+ let targetid = '';
442
+ // const targetid = 'context-launchunicode';
443
+
444
+ // Todo: Check first for our custom protocol
445
+ const {customProtocol} = cfg;
446
+ // Fix: the initial portion of this handling really should be inside
447
+ // the protocol handler, but that requires implementing the object to
448
+ // add arguments
449
+ let unicodeQueryObj;
450
+ let chr;
451
+ let bridgeResult;
452
+ // Will be passed a query string if a protocol handler has been triggered
453
+ if (customProtocol) {
454
+ // Skip over the initial question mark too
455
+ const req = new URL(customProtocol);
456
+ const queryType = req.pathname;
457
+ unicodeQueryObj = req.searchParams;
458
+ switch (queryType) {
459
+ case 'find':
460
+ chr = unicodeQueryObj.get('char');
461
+ targetid = 'context-unicodechart';
462
+ break;
463
+ case 'searchName':
464
+ targetid = 'searchName';
465
+ break;
466
+ case 'searchkDefinition':
467
+ targetid = 'searchkDefinition';
468
+ break;
469
+ // Could also add 'define', 'convert', etc.
470
+ default:
471
+ alert(
472
+ _('Unrecognized_query_type')
473
+ );
474
+ }
475
+ } else if (!cfg.options) {
476
+ // Do nothing here for options dialog
477
+ toconvert = cfg.convert || '';
478
+ ({targetid} = cfg);
479
+ // toconvert = charreftoconvert.replace(/\n/g, ' ');
480
+ $('#toconvert').value = toconvert;
481
+
482
+ if (ampspace) {
483
+ toconvert = toconvert.replaceAll(/&([^;\s]*\s)/gu, '&amp;$1');
484
+ }
485
+
486
+ if (targetid) {
487
+ bridgeResult = await findBridgeForTargetID({toconvert, targetid, _});
488
+ }
489
+ }
490
+
491
+ // Detect which context menu item was selected:
492
+ let out = ''; // converttypeid;
493
+
494
+ if (bridgeResult !== false && bridgeResult !== undefined) {
495
+ out = bridgeResult;
496
+ } else {
497
+ switch (targetid) {
498
+ case 'context-unicodechart':
499
+ await this.disableEnts();
500
+ $('#startset').value = chr;
501
+ $('#unicodeTabBox').$selectTabForTabPanel($('#charts'));
502
+ // Fallthrough
503
+ case 'context-launchunicode':
504
+ case 'tools-charrefunicode':
505
+ out = '';
506
+ break;
507
+ case 'searchName':
508
+ $('#' + targetid).value = unicodeQueryObj.get('string');
509
+ $('#' + targetid).focus();
510
+ await this.searchUnicode({
511
+ id: targetid, value: unicodeQueryObj.get('string')
512
+ }); // Assume non-CJK
513
+ break;
514
+ case 'searchkDefinition':
515
+ $('#' + targetid).value = unicodeQueryObj.get('string');
516
+ $('#' + targetid).focus();
517
+ await this.searchUnihan({
518
+ id: targetid, value: unicodeQueryObj.get('string')
519
+ });
520
+ break;
521
+ default:
522
+ out = ''; // Plain launcher with no values sent
523
+ // const prefstab = true;
524
+ break;
525
+ }
526
+ }
527
+ $('#converted').value = out;
528
+
529
+ if (!customProtocol) {
530
+ if (cfg.options) { // options menu
531
+ $('#unicodeTabBox').$selectTabForTabPanel($('#prefs'));
532
+ } else if (toconvert !== null && targetid) {
533
+ // Keyboard invocation or button
534
+ // $('#unicodetabs').selectedIndex = 0; // Fix: set by preference
535
+ $('#unicodeTabBox').$selectTabForTabPanel($('#conversion'));
536
+ } else if (
537
+ targetid !== 'context-unicodechart' &&
538
+ targetid !== 'tools-charrefunicode'
539
+ ) {
540
+ $('#unicodeTabBox').$selectTabForTabPanel(
541
+ $('#' + initialTab)
542
+ );
543
+ }
544
+ }
545
+
546
+ if (targetid !== 'searchName' && targetid !== 'searchkDefinition') {
547
+ if (toconvert || chr) { // Seemed to become necessarily suddenly
548
+ await this.setCurrstartset((toconvert || chr).codePointAt() - 1);
549
+ }
550
+ await chartBuild();
551
+ }
552
+ this.tblfontsize(0); // Draw with the preferences value
553
+
554
+ /*
555
+ if (converttypeid != 0) {
556
+ $(converttypeid).className='buttonactive';
557
+ }
558
+ */
559
+
560
+ /*
561
+ // Disabling for now
562
+ // Set window size to that set last time hit "ok"
563
+ if (outerh > 0) {
564
+ window.resizeTo(window.outerWidth, outerh);
565
+ }
566
+ if (outerw > 0) {
567
+ window.resizeTo(outerw, window.outerHeight);
568
+ }
569
+
570
+ window.addEventListener('resize', async (e) => {
571
+ await setPref('outerHeight', window.outerHeight);
572
+ await setPref('outerWidth', window.outerWidth);
573
+ });
574
+ */
575
+ },
576
+ async copyToClipboard (id) {
577
+ const text = $(id).value;
578
+ await navigator.clipboard.writeText(text);
579
+ alert(_('copiedToClipboard'));
580
+ },
581
+ async setprefs (e) {
582
+ switch (e.target.type) {
583
+ case 'select-one': case 'text':
584
+ return await setPref(
585
+ e.target.id,
586
+ e.target.value
587
+ );
588
+ case 'checkbox':
589
+ return await setPref(e.target.id, Boolean(e.target.checked));
590
+ /*
591
+ // Should work but not in use
592
+ case 'radio': {
593
+ let radioid;
594
+ const result = e.target.id.match(/^_(\d)+-(.*)$/u);
595
+ if (result !== null) {
596
+ radioid = result[2]; // Extract preference name
597
+ return await setPref(radioid, result[1] === '1');
598
+ }
599
+ break;
600
+ }
601
+ */
602
+ /* istanbul ignore next -- Just a guard */
603
+ default:
604
+ /* istanbul ignore next -- Just a guard */
605
+ break;
606
+ }
607
+ /* istanbul ignore next -- Just a guard */
608
+ return undefined;
609
+ },
610
+ async resetdefaults () {
611
+ // Todo: Change to programmatic setting
612
+ // If make changes here, also change the default/preferences
613
+ // charrefunicode.js file
614
+ await this.setBoolChecked([
615
+ 'asciiLt128', 'showImg', 'xhtmlentmode', 'hexLettersUpper', 'multiline'
616
+ ], false);
617
+ await this.setBoolChecked([
618
+ 'xmlentkeep', 'ampkeep', 'appendtohtmldtd', 'cssUnambiguous'
619
+ ], true);
620
+
621
+ $('#ampspace').checked = false;
622
+ // $('#showComplexWindow').checked = false;
623
+ $('#showAllDetailedView').checked = true;
624
+ $('#showAllDetailedCJKView').checked = true;
625
+
626
+ /**
627
+ * @param {string} langOrFont
628
+ * @returns {string}
629
+ */
630
+ async function langFont (langOrFont) { // Fix: needs to get default!
631
+ const deflt = await getPref(langOrFont);
632
+ $('#' + langOrFont).value = deflt;
633
+ await setPref(langOrFont, deflt);
634
+ return deflt;
635
+ }
636
+ $('#chart_table').lang = await langFont('lang');
637
+
638
+ $('#insertText').style.fontFamily = await langFont('font');
639
+ // Form elements don't inherit, so find these manually
640
+ $$('#chart_table button[name="unicode"]').forEach(async (button) => {
641
+ button.style.fontFamily = await langFont('font');
642
+ });
643
+
644
+ // await setPref('hexstyleLwr', true);
645
+ // $(EXT_BASE + 'hexstyleLwr').selectedIndex = 0;
646
+
647
+ await setPref('fontsizetextbox', 13);
648
+ this.fontsizetextbox(0);
649
+
650
+ /*
651
+ Easy enough to manually remove DTD -- wouldn't want to lose that data
652
+ await setPref('DTDtextbox', '');
653
+ $('#DTDtextbox').value = '';
654
+ */
655
+
656
+ // Don't really need to reset since user can't currently change
657
+ // this (only for blank string entry)
658
+ await setPref(
659
+ 'startset', 'a'.codePointAt() - 1
660
+ );
661
+
662
+ await this.setCurrstartset(await getPref('startset'));
663
+
664
+ // These get activated in chartBuild(); below
665
+ await setPref('tblrowsset', 4);
666
+ $('#rowsset').value = 4;
667
+ await setPref('tblcolsset', 3);
668
+ $('#colsset').value = 3;
669
+
670
+ await this.setBoolChecked([
671
+ 'entyes', 'hexyes', 'decyes', 'unicodeyes', 'buttonyes'
672
+ ], true);
673
+ await this.setBoolChecked([
674
+ 'onlyentsyes', 'startCharInMiddleOfChart'
675
+ ], false);
676
+
677
+ // await setPref('xstyle', 'x');
678
+ // $('#xstyle').checked = true;
679
+
680
+ await setPref('initialTab', 'charts');
681
+ $('#initialTab').value = $('#mi_charts').value;
682
+
683
+ await setPref('tblfontsize', 13);
684
+ await this.resizecells();
685
+
686
+ await chartBuild();
687
+ await Promise.all([
688
+ setPref('outerHeight', 0),
689
+ setPref('outerWidth', 0)
690
+ ]);
691
+ },
692
+
693
+ /**
694
+ * Set a boolean preference (and its checked state in the interface) to
695
+ * a given boolean value.
696
+ * @param {string|string[]} els The element ID string or strings which
697
+ * should have their values set
698
+ * @param {boolean} value The value for the preference and checked state
699
+ */
700
+ async setBoolChecked (els, value) {
701
+ els = typeof els === 'string' ? [els] : els;
702
+ return await Promise.all(els.map(async (el) => {
703
+ await setPref(el, value);
704
+ $('#' + el).checked = value;
705
+ }));
706
+ },
707
+
708
+ // End UI bridges
709
+
710
+ async setImagePref (ev) {
711
+ await this.setprefs(ev);
712
+ if ($('#unicodeImg').firstChild) {
713
+ $('#unicodeImg').firstChild.remove();
714
+ }
715
+ return false;
716
+ },
717
+
718
+ async getUnicodeDescription (kent, khextemp) {
719
+ const hideMissing = !(await getPref('showAllDetailedView'));
720
+ const hideMissingUnihan = !(await getPref('showAllDetailedCJKView'));
721
+ const {
722
+ unihanType, hangul, cjkText, searchValue
723
+ } = getCJKTypeFromHexString({khextemp, _});
724
+
725
+ if (
726
+ !unihanType && !hangul &&
727
+ $('#viewTabs').$selectedTab() === $('#detailedCJKView')
728
+ ) {
729
+ $('#viewTabs').$selectTabForTabPanel($('#detailedView'));
730
+ }
731
+
732
+ const kdectemp = Number.parseInt(khextemp, 16);
733
+ const {
734
+ codePointStart, script, plane, privateuse, surrogate
735
+ } = getScriptInfoForCodePoint(kdectemp, _);
736
+
737
+ // Todo: Make reactive!
738
+ if (!unihanType) {
739
+ for (
740
+ let i = 0;
741
+ i < unicodecharref.Unihan.length;
742
+ i++
743
+ ) {
744
+ if (i === this.kDefinitionIndex) {
745
+ continue;
746
+ }
747
+ $('#_detailedCJKView' + i).value = '';
748
+ }
749
+ for (const prop of this.Unihan) {
750
+ // eslint-disable-next-line @stylistic/max-len -- Long
751
+ /* istanbul ignore next -- May not be generated based on `showComplexWindow` */
752
+ if ($('#searchk' + prop)) {
753
+ $('#searchk' + prop).value = '';
754
+ }
755
+ }
756
+ }
757
+
758
+ let result;
759
+ try {
760
+ await charrefunicodeDb.connect();
761
+
762
+ const results = await charrefunicodeDb.getUnicodeFields(searchValue);
763
+
764
+ /* istanbul ignore else -- Should have thrown if no result */
765
+ if (results) {
766
+ result = cjkText ||
767
+ // We had obtained Jamo from Jamo.txt and showed it in parentheses,
768
+ // but it seems this is now included in UnicodeData.txt as we
769
+ // import into our database.
770
+ // if (kdectemp >= 0x1100 && kdectemp < 0x1200) {
771
+ results.name;
772
+ for (const [i, unicodeField] of unicodecharref.Unicode.entries()) {
773
+ // Fix: display data more readably, etc.
774
+ const camelizedField = camelCase(unicodeField);
775
+ // console.log('camelizedField', camelizedField);
776
+ let temp = results[camelizedField];
777
+ if (unicodeField === 'Unicode_1_Name') {
778
+ if (temp) {
779
+ result += ';\u00A0\u00A0\u00A0\u00A0\n' +
780
+ _('searchUnicode_1_Name') + _('colon') + ' ' + temp;
781
+ }
782
+ continue;
783
+ }
784
+ if (temp) {
785
+ if (hideMissing) {
786
+ $('#_detailedView' + i).parentNode.hidden = false;
787
+ }
788
+ switch (unicodeField) {
789
+ case 'General_Category':
790
+ temp = _('General_Category' + temp);
791
+ break;
792
+ case 'Canonical_Combining_Class':
793
+ if (temp < 11 || temp > 132) {
794
+ // 199, 200, 204, 208, 210, 212 do not have members yet and
795
+ // others from 11 to 132 do not have name listed
796
+ temp = _('Canonical_Combining_Class' + temp);
797
+ }
798
+ break;
799
+ case 'Bidi_Class':
800
+ temp = _('Bidi_Class' + temp);
801
+ break;
802
+ case 'Bidi_Mirrored':
803
+ temp = (temp === 'Y')
804
+ ? _('Bidi_MirroredY')
805
+ : _('Bidi_MirroredN'); // Only two choices
806
+ break;
807
+ case 'numericType': {
808
+ const view = $('#_detailedView' + i);
809
+ removeViewChildren(i);
810
+ jml('select', [
811
+ 'None',
812
+ 'Decimal',
813
+ 'Digit',
814
+ 'Numeric'
815
+ // eslint-disable-next-line no-loop-func -- Not an issue
816
+ ].map((value) => {
817
+ return [
818
+ 'option',
819
+ temp === value
820
+ ? {
821
+ selected: true
822
+ }
823
+ : {},
824
+ [
825
+ _(value)
826
+ ]
827
+ ];
828
+ }), view);
829
+ break;
830
+ }
831
+ case 'decompositionMapping':
832
+ case 'Simple_Uppercase_Mapping':
833
+ case 'Simple_Lowercase_Mapping':
834
+ case 'Simple_Titlecase_Mapping': {
835
+ const a = createHTMLElement('a');
836
+ // eslint-disable-next-line no-script-url -- This is controlled
837
+ a.href = 'javascript:void(0)';
838
+
839
+ a.addEventListener('click', async (e) => {
840
+ await unicodecharref.startset({
841
+ value: e.target.textContent
842
+ });
843
+ // Probably want to start checking again since move to new page
844
+ // that.noGetDescripts = false;
845
+ });
846
+ const tempno = Number.parseInt(temp, 16);
847
+ a.textContent = String.fromCodePoint(tempno);
848
+ a.className = 'text-link';
849
+ const view = $('#_detailedView' + i);
850
+ removeViewChildren(i);
851
+
852
+ const box = createHTMLElement('span');
853
+ box.append(a);
854
+ box.append(' (' + temp + ')');
855
+ view.append(box);
856
+
857
+ // alert(new XMLSerializer().serializeToString(view));
858
+ break;
859
+ } default:
860
+ break;
861
+ }
862
+ // Not casing
863
+ if (
864
+ !unicodeField.includes('case_Mapping') &&
865
+ unicodeField !== 'decompositionMapping'
866
+ ) {
867
+ $('#_detailedView' + i).value = temp;
868
+ }
869
+ // Not casing
870
+ } else if (
871
+ !unicodeField.includes('case_Mapping') &&
872
+ unicodeField !== 'decompositionMapping'
873
+ ) {
874
+ $('#_detailedView' + i).parentNode.hidden = hideMissing;
875
+ $('#_detailedView' + i).value = '';
876
+ } else {
877
+ $('#_detailedView' + i).parentNode.hidden = hideMissing;
878
+ removeViewChildren(i);
879
+ }
880
+ }
881
+ }
882
+
883
+ if (!unihanType) {
884
+ $('#displayUnicodeDesc').value = kent +
885
+ 'U+' + khextemp + _('colon') + ' ' + result;
886
+ $('#displayUnicodeDesc2').value = kent +
887
+ 'U+' + khextemp + _('colon') + ' ' + result;
888
+ }
889
+ } catch {
890
+ if (surrogate) {
891
+ $('#displayUnicodeDesc').value = kent +
892
+ 'U+' + khextemp + _('colon') + ' ' + surrogate;
893
+ $('#displayUnicodeDesc2').value = kent +
894
+ 'U+' + khextemp + _('colon') + ' ' + surrogate;
895
+ } else if (privateuse) {
896
+ $('#displayUnicodeDesc').value = kent +
897
+ 'U+' + khextemp + _('colon') + ' ' + _('Private_use_character');
898
+ $('#displayUnicodeDesc2').value = kent +
899
+ 'U+' + khextemp + _('colon') + ' ' + _('Private_use_character');
900
+ } else if ( // Catch noncharacters
901
+ (kdectemp >= 0xFDD0 && kdectemp <= 0xFDEF) ||
902
+ (kdectemp >= 0xFFFE && kdectemp <= 0xFFFF) ||
903
+ (kdectemp >= 0x1FFFE && kdectemp <= 0x1FFFF) ||
904
+ (kdectemp >= 0x2FFFE && kdectemp <= 0x2FFFF) ||
905
+ (kdectemp >= 0x3FFFE && kdectemp <= 0x3FFFF) ||
906
+ (kdectemp >= 0x4FFFE && kdectemp <= 0x4FFFF) ||
907
+ (kdectemp >= 0x5FFFE && kdectemp <= 0x5FFFF) ||
908
+ (kdectemp >= 0x6FFFE && kdectemp <= 0x6FFFF) ||
909
+ (kdectemp >= 0x7FFFE && kdectemp <= 0x7FFFF) ||
910
+ (kdectemp >= 0x8FFFE && kdectemp <= 0x8FFFF) ||
911
+ (kdectemp >= 0x9FFFE && kdectemp <= 0x9FFFF) ||
912
+ (kdectemp >= 0xAFFFE && kdectemp <= 0xAFFFF) ||
913
+ (kdectemp >= 0xBFFFE && kdectemp <= 0xBFFFF) ||
914
+ (kdectemp >= 0xCFFFE && kdectemp <= 0xCFFFF) ||
915
+ (kdectemp >= 0xDFFFE && kdectemp <= 0xDFFFF) ||
916
+ (kdectemp >= 0xEFFFE && kdectemp <= 0xEFFFF)
917
+ /*
918
+ // Also surrogates
919
+ (kdectemp >= 0xFFFFE && kdectemp <= 0xFFFFF) ||
920
+ (kdectemp >= 0x10FFFE && kdectemp <= 0x10FFFF)
921
+ */
922
+ ) {
923
+ $('#displayUnicodeDesc').value = kent +
924
+ 'U+' + khextemp + _('colon') + ' ' + _('Noncharacter');
925
+ $('#displayUnicodeDesc2').value = kent +
926
+ 'U+' + khextemp + _('colon') + ' ' + _('Noncharacter');
927
+ } else {
928
+ const notfoundval = 'U+' + khextemp + _('colon') + ' ' + _('Not_found');
929
+ $('#displayUnicodeDesc').value = notfoundval;
930
+ $('#displayUnicodeDesc2').value = notfoundval;
931
+ }
932
+ for (const [j, unicodeField] of unicodecharref.Unicode.entries()) {
933
+ if (unicodeField === 'Unicode_1_Name') {
934
+ continue;
935
+ }
936
+ try {
937
+ $('#_detailedView' + j).value = '';
938
+ $('#_detailedView' + j).parentNode.hidden = hideMissing;
939
+ removeViewChildren(j);
940
+ /* istanbul ignore next -- Debugging */
941
+ } catch (err) {
942
+ /* eslint-disable no-console -- Debugging */
943
+ /* istanbul ignore next -- Debugging */
944
+ console.log('3' + err + j);
945
+ /* eslint-enable no-console -- Debugging */
946
+ }
947
+ }
948
+ }
949
+ // const canreturn = true;
950
+
951
+ if (this.unihanDb_exists) {
952
+ try {
953
+ // $('#displayUnicodeDesc').value= _('retrieving_description');
954
+ const results = await this.unihanDatabase.getUnicodeFields(khextemp);
955
+ if (results) {
956
+ // Fix: display data more readably, with heading, etc. (and
957
+ // conditional)
958
+ result = results[this.kDefinitionIndex];
959
+
960
+ // Fix: Display meta-data in table (get to be stable by
961
+ // right-clicking)
962
+ for (
963
+ let i = 0;
964
+ i < unicodecharref.Unihan.length;
965
+ i++
966
+ ) {
967
+ if (i === this.kDefinitionIndex) {
968
+ continue;
969
+ }
970
+ let temp;
971
+ try {
972
+ // Fix: display data more readably, etc.
973
+ temp = results[i];
974
+ /* istanbul ignore next -- Debugging */
975
+ } catch {
976
+ /* istanbul ignore next -- Debugging */
977
+ alert(i);
978
+ }
979
+ if (temp) {
980
+ if (hideMissingUnihan) {
981
+ $('#_detailedCJKView' + i).parentNode.hidden = false;
982
+ }
983
+ /*
984
+ switch (i) {
985
+ case 4:
986
+ // Optional code to transform output into something
987
+ // more readable
988
+ break;
989
+ case 5:
990
+ break;
991
+ default:
992
+ break;
993
+ }
994
+ */
995
+ $('#_detailedCJKView' + i).value = temp;
996
+ } else {
997
+ $('#_detailedCJKView' + i).parentNode.hidden = hideMissingUnihan;
998
+ $('#_detailedCJKView' + i).value = '';
999
+ }
1000
+ }
1001
+ }
1002
+
1003
+ if (result !== '' && result !== null && result !== undefined) {
1004
+ // Commenting out to show general category under definition
1005
+ // $('#displayUnicodeDesc2').value = kent +
1006
+ // 'U+' + khextemp + _('colon')+' ' + result;
1007
+ $('#displayUnicodeDescUnihan').value = kent +
1008
+ 'U+' + khextemp + _('colon') + ' ' + result;
1009
+ $('#displayUnicodeDesc').value = kent +
1010
+ 'U+' + khextemp + _('colon') + ' ' + result;
1011
+ $('#displayUnicodeDesc2').value = kent +
1012
+ 'U+' + khextemp + _('colon') + ' ' + result;
1013
+ } else {
1014
+ const notfoundval = 'U+' + khextemp + _('colon') + ' ' +
1015
+ _('Not_found');
1016
+
1017
+ if (!cjkText || hangul) {
1018
+ for (const [j, unicodeField] of unicodecharref.Unicode.entries()) {
1019
+ if (unicodeField === 'Unicode_1_Name') {
1020
+ continue;
1021
+ }
1022
+ try {
1023
+ $('#_detailedView' + j).value = '';
1024
+ $('#_detailedView' + j).parentNode.hidden = hideMissing;
1025
+ removeViewChildren(j);
1026
+ /* istanbul ignore next -- Debugging */
1027
+ } catch (e) {
1028
+ /* istanbul ignore next -- Debugging */
1029
+ alert('1' + e + j);
1030
+ }
1031
+ }
1032
+ for (
1033
+ let i = 0;
1034
+ i < unicodecharref.Unihan.length;
1035
+ i++
1036
+ ) {
1037
+ if (i === this.kDefinitionIndex) {
1038
+ continue;
1039
+ }
1040
+ $('#_detailedCJKView' + i).parentNode.hidden = hideMissingUnihan;
1041
+ $('#_detailedCJKView' + i).value = '';
1042
+ }
1043
+ }
1044
+
1045
+ if (!cjkText) {
1046
+ $('#displayUnicodeDesc').value = notfoundval;
1047
+ $('#displayUnicodeDescUnihan').value = notfoundval;
1048
+ $('#displayUnicodeDesc2').value = notfoundval;
1049
+ } else {
1050
+ const finalval = kent +
1051
+ 'U+' + khextemp + _('colon') + ' ' + cjkText +
1052
+ (hangul
1053
+ ? ''
1054
+ : ' ' + _('left_parenth') + _('No_definition') +
1055
+ _('right_parenth'));
1056
+ $('#displayUnicodeDesc').value = finalval;
1057
+ $('#displayUnicodeDesc2').value = finalval;
1058
+ $('#displayUnicodeDescUnihan').value = finalval;
1059
+ // $('#displayUnicodeDesc2').value = notfoundval;
1060
+ }
1061
+ }
1062
+ /* istanbul ignore next -- Debugging */
1063
+ } catch (e) {
1064
+ /* istanbul ignore next -- Debugging */
1065
+ alert(e);
1066
+ }
1067
+ // return;
1068
+ } // Excised Ajax code...
1069
+
1070
+ if (
1071
+ this.unihanDb_exists && unihanType &&
1072
+ $('#viewTabs').$selectedTab() === $('#detailedView')
1073
+ ) {
1074
+ $('#viewTabs').$selectTabForTabPanel($('#detailedCJKView'));
1075
+ }
1076
+
1077
+ const alink = createHTMLElement('a');
1078
+ alink.target = '_blank';
1079
+ alink.className = 'text-link';
1080
+ alink.href = `https://unicode.org/charts/PDF/U${codePointStart}.pdf`;
1081
+ alink.textContent = script + ' (PDF)';
1082
+
1083
+ // Handle PDF link
1084
+ placeItem('#pdflink', alink);
1085
+
1086
+ // Handle plane #
1087
+ const planeText = _('plane_num', {plane}) + '\u00A0';
1088
+ placeItem('#plane', planeText);
1089
+
1090
+ if (await getPref('showImg')) {
1091
+ const img = createHTMLElement('img');
1092
+ // img.width = '80';
1093
+ // img.height = '80';
1094
+ img.setAttribute('src', 'https://unicode.org/cgi-bin/refglyph?1-' + Number(kdectemp).toString(16));
1095
+ placeItem('#unicodeImg', img);
1096
+ }
1097
+ },
1098
+ async fontsizetextbox (size) { // Changes font-size
1099
+ const txtbxsize = await getPref('fontsizetextbox') + size;
1100
+ await setPref('fontsizetextbox', txtbxsize);
1101
+
1102
+ $('#toconvert').style.fontSize = txtbxsize + 'px';
1103
+ $('#converted').style.fontSize = txtbxsize + 'px';
1104
+
1105
+ /* istanbul ignore next -- Firefox only */
1106
+ if (size > 0 && window.sizeToContent) {
1107
+ // On Mac at least, resizing for reducing font size, causes button to
1108
+ // go off screen
1109
+ window.sizeToContent();
1110
+ }
1111
+ },
1112
+ async tblfontsize (size) { // Changes font-size of chart table cells
1113
+ const fsize = await getPref('tblfontsize') + size;
1114
+ // const tds = createHTMLElement('td');
1115
+ await setPref('tblfontsize', fsize);
1116
+ await this.resizecells({sizeToContent: size > 0});
1117
+ },
1118
+ async resizecells ({sizeToContent} = {}) {
1119
+ await Promise.all($$(
1120
+ "*[name='dec'],*[name='hex'],*[name='unicode']"
1121
+ ).map(async (control) => {
1122
+ control.style.fontSize =
1123
+ await getPref('tblfontsize') + 'px';
1124
+ }));
1125
+ $('#insertText').style.fontSize =
1126
+ await getPref('tblfontsize') + 'px';
1127
+ // $('#displayUnicodeDesc').style.fontSize =
1128
+ // await getPref('tblfontsize') + 'px';
1129
+
1130
+ /* istanbul ignore next -- Firefox only */
1131
+ if (sizeToContent && window.sizeToContent) {
1132
+ // On Mac at least, resizing for reducing font size, causes button to
1133
+ // go off screen
1134
+ window.sizeToContent();
1135
+ }
1136
+ },
1137
+ async hexLettersCasing (e) {
1138
+ await this.setprefs(e);
1139
+ await chartBuild();
1140
+ return await this.resizecells();
1141
+ },
1142
+ async flip (e) {
1143
+ await this.setCurrstartset(lastStartCharCode);
1144
+ await this.setprefs(e);
1145
+ await chartBuild();
1146
+ return await this.resizecells();
1147
+ },
1148
+ async onlyentsyesflip (e) {
1149
+ return await this.flip(e);
1150
+ },
1151
+ async hexflip (e) {
1152
+ return await this.flip(e);
1153
+ },
1154
+ async decflip (e) {
1155
+ return await this.flip(e);
1156
+ },
1157
+ async unicodeflip (e) {
1158
+ return await this.flip(e);
1159
+ },
1160
+ async middleflip (e) {
1161
+ return await this.flip(e);
1162
+ },
1163
+ async buttonflip (e) {
1164
+ return await this.flip(e);
1165
+ },
1166
+ async entflip (e) {
1167
+ return await this.flip(e);
1168
+ },
1169
+ async cssWhitespace (e) {
1170
+ let {value} = e.target;
1171
+ // Escape \r since \r may be lost?
1172
+ switch (value) {
1173
+ case 'space':
1174
+ value = ' ';
1175
+ break;
1176
+ /*
1177
+ case 'rn':
1178
+ value = '\r\n';
1179
+ break;
1180
+ case 'r':
1181
+ value = '\r';
1182
+ break;
1183
+ */
1184
+ case 'n':
1185
+ value = '\n';
1186
+ break;
1187
+ case 't':
1188
+ value = '\t';
1189
+ break;
1190
+ case 'f':
1191
+ value = '\f';
1192
+ break;
1193
+ /* istanbul ignore next -- Guard */
1194
+ default:
1195
+ /* istanbul ignore next -- Guard */
1196
+ throw new Error('Unexpected menu value');
1197
+ }
1198
+ await setPref('cssWhitespace', value);
1199
+ },
1200
+ /* async xstyleflip () {
1201
+ await this.setCurrstartset(lastStartCharCode);
1202
+ const currxstyle = 'x';
1203
+ const prevxstyle = await getPref('xstyle');
1204
+ if (prevxstyle === 'x') {
1205
+ currxstyle = 'X';
1206
+ }
1207
+ await setPref('xstyle', currxstyle);
1208
+ return await chartBuild();
1209
+ }, */
1210
+ async rowsset (e) {
1211
+ await this.setCurrstartset(lastStartCharCode);
1212
+ if (e.target.value !== null && e.target.value !== '') {
1213
+ await setPref('tblrowsset', e.target.value);
1214
+ }
1215
+ await chartBuild();
1216
+ return await this.resizecells();
1217
+ },
1218
+ async colsset (e) {
1219
+ await this.setCurrstartset(lastStartCharCode);
1220
+ if (e.target.value !== null && e.target.value !== '') {
1221
+ await setPref('tblcolsset', e.target.value);
1222
+ }
1223
+ await chartBuild();
1224
+ return await this.resizecells();
1225
+ },
1226
+
1227
+ /**
1228
+ * @param {{value: string}} tbx
1229
+ * @param {boolean} descripts
1230
+ * @returns {Promise<void>}
1231
+ */
1232
+ async startset (tbx, descripts) {
1233
+ /**
1234
+ * @param {string} str
1235
+ * @returns {Integer}
1236
+ */
1237
+ function convert (str) {
1238
+ str = str.replace(/;$/u, '');
1239
+ const hexInit = str.match(/^&?#?x/u);
1240
+ if (hexInit) {
1241
+ return Number.parseInt(str.slice(hexInit[0].length), 16) - 1;
1242
+ }
1243
+ const decInit = str.match(/^&?#/u);
1244
+ if (decInit) {
1245
+ return Number.parseInt(str.slice(decInit[0].length)) - 1;
1246
+ }
1247
+ return str.codePointAt() - 1;
1248
+ }
1249
+ await this.disableEnts();
1250
+ const data = tbx.value !== null &&
1251
+ tbx.value !== undefined &&
1252
+ tbx.value !== ''
1253
+ ? convert(tbx.value)
1254
+ : (await getPref('startset') || 'a').codePointAt() - 1;
1255
+ await this.setCurrstartset(data);
1256
+
1257
+ await chartBuild({descripts});
1258
+ return await this.resizecells();
1259
+ },
1260
+ /**
1261
+ * Sets a value in preferences at which the Unicode chart view will
1262
+ * begin on next start-up.
1263
+ * @param {Integer} value The value to which to set the current
1264
+ * starting value
1265
+ */
1266
+ async setCurrstartset (value) {
1267
+ /* istanbul ignore if -- Guard */
1268
+ if (typeof value !== 'number') {
1269
+ const err = new Error('Bad value');
1270
+ err.value = value;
1271
+ // eslint-disable-next-line no-console -- Debugging
1272
+ console.error(err);
1273
+ alert(
1274
+ 'Look at trace to see where setting ' +
1275
+ '`currentStartCharCode` as undefined'
1276
+ );
1277
+ }
1278
+
1279
+ return await setPref('currentStartCharCode', value);
1280
+ },
1281
+ // Unused
1282
+ // Some of these defaults may become irrelevant due to the
1283
+ // /default/preferences/charrefunicode.js file's settings
1284
+ /*
1285
+ async k (setval) {
1286
+ return await this.setCurrstartset(setval);
1287
+ },
1288
+ */
1289
+ async chartBuildResize () {
1290
+ await chartBuild();
1291
+ return await this.resizecells();
1292
+ },
1293
+ async searchUnihan (obj) {
1294
+ return await this.searchUnicode(obj, 'Unihan');
1295
+ },
1296
+ async disableEnts () {
1297
+ return await this.setBoolChecked('onlyentsyes', false);
1298
+ },
1299
+ async searchUnicode (obj, table, nochart, strict) { // Fix: allow Jamo!
1300
+ await charrefunicodeConverter.searchUnicode(obj, table, nochart, strict);
1301
+ if (!nochart) {
1302
+ const tmp = await getPref('currentStartCharCode');
1303
+ this.startset(obj, true); // Could remember last description (?)
1304
+ // Set it back as it was before the search
1305
+ await this.setCurrstartset(tmp);
1306
+ this.resizecells();
1307
+ }
1308
+ // Doesn't work since name_desc_val is search value, not first
1309
+ // result value (we could remember the last search and whether it
1310
+ // were a search, however); we need to be careful, however, since
1311
+ // some searches run automatically on start-up
1312
+ /* if (name_desc === 'Name' || name_desc === 'kDefinition') {
1313
+ await this.setCurrstartset(name_desc_val.codePointAt() - 1);
1314
+ } */
1315
+ },
1316
+ moveoutput (movedid) {
1317
+ const insertText = $(movedid);
1318
+ $('#unicodeTabBox').$selectTabForTabPanel($('#conversion'));
1319
+ $('#toconvert').value = insertText.value;
1320
+ },
1321
+ async append2htmlflip (e) {
1322
+ await this.setprefs(e);
1323
+ await registerDTD(); // (in case DTD not also changed, still need to reset)
1324
+ await chartBuild();
1325
+ await this.resizecells();
1326
+ },
1327
+ /**
1328
+ * @todo Unused
1329
+ * Sets the preference for whether to display the chosen character
1330
+ * in the middle of the chart (or beginning).
1331
+ * @param {boolean} bool Whether to set to true or not
1332
+ */
1333
+ /*
1334
+ async startCharInMiddleOfChart (bool) {
1335
+ // Commented this out because while it will always change (unlike
1336
+ // now), the value will be misleading
1337
+ // $(EXT_BASE + 'startCharInMiddleOfChart').checked = bool;
1338
+ return await setPref('startCharInMiddleOfChart', bool);
1339
+ },
1340
+ */
1341
+ insertent () {
1342
+ insertIntoOrOverExisting({
1343
+ textReceptacle: $('#DTDtextbox'),
1344
+ value: '<!ENTITY "">\n'
1345
+ });
1346
+ // The following works but may be annoying if trying to insert
1347
+ // multiple entities at a time (thus the addition of the newline)
1348
+ // Bring cursor back a little
1349
+ // textarea.selectionStart = this.selst - 5;
1350
+ // textarea.selectionEnd = this.selend - 5;
1351
+ },
1352
+ /**
1353
+ * Display the Unicode description box size (multline or not) according
1354
+ * to user preferences.
1355
+ */
1356
+ async multiline () {
1357
+ const display = $('#displayUnicodeDesc');
1358
+ if (await getPref('multiline') === false) {
1359
+ await setPref('multiline', true);
1360
+ display.replaceWith(jml('textarea', {
1361
+ id: 'displayUnicodeDesc',
1362
+ rows: 3
1363
+ }));
1364
+ } else {
1365
+ await setPref('multiline', false);
1366
+ display.replaceWith(jml('input', {
1367
+ id: 'displayUnicodeDesc',
1368
+ rows: 1
1369
+ }));
1370
+ }
1371
+ },
1372
+ /*
1373
+ async addToToolbar () {
1374
+ const dropdownArr = await getPref('dropdownArr');
1375
+ dropdownArr.push($('#insertText').value);
1376
+ await setPref('dropdownArr', dropdownArr);
1377
+ if (await this.refreshToolbarDropdown()) {
1378
+ alert(_('yourItemAdded'));
1379
+ } else {
1380
+ alert(_('problemAddingToolbarItem'));
1381
+ }
1382
+ },
1383
+ async refreshToolbarDropdown () {
1384
+ // SETUP
1385
+ const dropdownArr = await getPref('dropdownArr');
1386
+ const toolbarbuttonPopup = $('#charrefunicode-toolbar-chars');
1387
+ if (!toolbarbuttonPopup) {
1388
+ return false;
1389
+ }
1390
+
1391
+ // EMPTY OLD CONTENTS
1392
+ while (toolbarbuttonPopup.firstChild) {
1393
+ toolbarbuttonPopup.firstChild.remove();
1394
+ }
1395
+
1396
+ // ADD NEW CONTENTS
1397
+ for (const item of dropdownArr) {
1398
+ jml('option', {
1399
+ value: item
1400
+ }, [item], toolbarbuttonPopup);
1401
+ }
1402
+ return true;
1403
+ },
1404
+ */
1405
+ idgen: 0,
1406
+ prefs: null,
1407
+
1408
+ // Build these programmatically? (and in UI?)
1409
+ /* Pseudo-constants */
1410
+ Unihan: [ // Ordered by database array; todo: rpplace above `Unihan`?
1411
+ 'kAccountingNumeric', 'kAlternateTotalStrokes', 'kBigFive', 'kCangjie',
1412
+ 'kCantonese', 'kCCCII', 'kCheungBauer', 'kCheungBauerIndex', 'kCihaiT',
1413
+ 'kCNS1986', 'kCNS1992', 'kCompatibilityVariant', 'kCowles', 'kDaeJaweon',
1414
+ 'kDefinition', 'kEACC', 'kFenn', 'kFennIndex', 'kFourCornerCode',
1415
+ 'kFrequency', 'kGB0', 'kGB1', 'kGB3', 'kGB5', 'kGB7', 'kGB8',
1416
+ 'kGradeLevel', 'kGSR', 'kHangul', 'kHanYu', 'kHanyuPinlu',
1417
+ 'kHanyuPinyin', 'kHDZRadBreak', 'kHKGlyph', 'kHKSCS', 'kIBMJapan',
1418
+ 'kIICore', 'kIRG_GSource', 'kIRG_HSource', 'kIRG_JSource',
1419
+ 'kIRG_KPSource', 'kIRG_KSource', 'kIRG_MSource', 'kIRG_SSource',
1420
+ 'kIRG_TSource', 'kIRG_UKSource', 'kIRG_USource', 'kIRG_VSource',
1421
+ 'kIRGDaeJaweon', 'kIRGDaiKanwaZiten', 'kIRGHanyuDaZidian',
1422
+ 'kIRGKangXi', 'kJa', 'kJapaneseKun', 'kJapaneseOn', 'kJinmeiyoKanji',
1423
+ 'kJis0', 'kJis1', 'kJIS0213', 'kJoyoKanji', 'kKangXi', 'kKarlgren',
1424
+ 'kKorean', 'kKoreanEducationHanja', 'kKoreanName', 'kKPS0', 'kKPS1',
1425
+ 'kKSC0', 'kKSC1', 'kLau', 'kMainlandTelegraph', 'kMandarin',
1426
+ 'kMatthews', 'kMeyerWempe', 'kMorohashi', 'kNelson', 'kOtherNumeric',
1427
+ 'kPhonetic', 'kPrimaryNumeric', 'kPseudoGB1', 'kRSAdobe_Japan1_6',
1428
+ 'kRSKangXi', 'kRSUnicode', 'kSBGY', 'kSemanticVariant',
1429
+ 'kSimplifiedVariant', 'kSpecializedSemanticVariant', 'kSpoofingVariant',
1430
+ 'kStrange', 'kTaiwanTelegraph', 'kTang', 'kTGH', 'kTGHZ2013',
1431
+ 'kTotalStrokes', 'kTraditionalVariant', 'kUnihanCore2020',
1432
+ 'kVietnamese', 'kXerox', 'kXHC1983', 'kZVariant'
1433
+ ],
1434
+ UnihanMenus: [], // Unused
1435
+ Unicode: [
1436
+ 'General_Category', 'Canonical_Combining_Class', 'Bidi_Class',
1437
+ // We broke it up into two parts for easier viewing
1438
+ // 'Decomposition_Type_and_Mapping',
1439
+ 'decompositionMapping',
1440
+ 'decompositionType',
1441
+ // We broke this up for more convenient querying/display
1442
+ /*
1443
+ 'Decimal',
1444
+ 'Digit',
1445
+ 'Numeric',
1446
+ */
1447
+ 'numericType',
1448
+ 'numericValue',
1449
+ 'Bidi_Mirrored', 'Unicode_1_Name', 'ISO_Comment',
1450
+ 'Simple_Uppercase_Mapping', 'Simple_Lowercase_Mapping',
1451
+ 'Simple_Titlecase_Mapping'
1452
+ ],
1453
+ UnicodeMenus: [
1454
+ 'General_Category', 'Canonical_Combining_Class', 'Bidi_Class',
1455
+ 'Bidi_Mirrored', 'Digit', 'Decimal'
1456
+ ],
1457
+
1458
+ UnicodeMenuBidi_Class: [
1459
+ 'L', 'LRE', 'LRO', 'R', 'AL', 'RLE', 'RLO', 'PDF', 'EN', 'ES', 'ET',
1460
+ 'AN', 'CS', 'NSM', 'BN', 'B', 'S', 'WS', 'ON'
1461
+ ],
1462
+ // Also 11-36 are automated above
1463
+ UnicodeMenuCanonical_Combining_Class: [
1464
+ 0, 1, 7, 8, 9, 10, 199, 200, 202, 204, 208, 210, 212, 214, 216, 218,
1465
+ 220, 222, 224, 226, 228, 230, 232, 233, 234, 240
1466
+ ],
1467
+ UnicodeMenuCCVNumericOnly: [84, 91, 103, 107, 118, 122, 129, 130, 132],
1468
+ UnicodeMenuGeneral_Category: [
1469
+ 'Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Mn', 'Mc', 'Me', 'Nd', 'Nl', 'No',
1470
+ 'Pc', 'Pd', 'Ps', 'Pe', 'Pi', 'Pf', 'Po', 'Sm', 'Sc', 'Sk', 'So',
1471
+ 'Zs', 'Zl', 'Zp', 'Cc', 'Cf', 'Cs', 'Co', 'Cn'
1472
+ ],
1473
+ UnicodeMenuBidi_Mirrored: ['Y', 'N'],
1474
+ UnicodeMenuDigit: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
1475
+ UnicodeMenuDecimal: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1476
+ };
1477
+
1478
+ unicodecharref.kDefinitionIndex = unicodecharref.Unihan.indexOf('kDefinition');
1479
+
1480
+ export default unicodecharref;