textbrowser 0.50.0 → 0.51.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.
- package/.ncurc.cjs +3 -0
- package/CHANGES.md +8 -0
- package/dist/WorkInfo-es.js +361 -111
- package/dist/activateCallback-es.js +72 -10
- package/dist/dist/WorkInfo-es.d.ts +331 -0
- package/dist/dist/WorkInfo-es.d.ts.map +1 -0
- package/dist/dist/activateCallback-es.d.ts +17 -0
- package/dist/dist/activateCallback-es.d.ts.map +1 -0
- package/dist/dist/index-es.d.ts +619 -0
- package/dist/dist/index-es.d.ts.map +1 -0
- package/dist/dist/sw-helper.d.ts +3 -0
- package/dist/dist/sw-helper.d.ts.map +1 -0
- package/dist/eslint.config.d.ts +126 -0
- package/dist/eslint.config.d.ts.map +1 -0
- package/dist/index-es.js +959 -195
- package/dist/index-es.min.js +2 -2
- package/dist/resources/activateCallback.d.ts +23 -0
- package/dist/resources/activateCallback.d.ts.map +1 -0
- package/dist/resources/index.d.ts +128 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/resultsDisplay.d.ts +110 -0
- package/dist/resources/resultsDisplay.d.ts.map +1 -0
- package/dist/resources/templates/index.d.ts +59 -0
- package/dist/resources/templates/index.d.ts.map +1 -0
- package/dist/resources/templates/languageSelect.d.ts +18 -0
- package/dist/resources/templates/languageSelect.d.ts.map +1 -0
- package/dist/resources/templates/resultsDisplayClient.d.ts +26 -0
- package/dist/resources/templates/resultsDisplayClient.d.ts.map +1 -0
- package/dist/resources/templates/resultsDisplayServerOrClient.d.ts +131 -0
- package/dist/resources/templates/resultsDisplayServerOrClient.d.ts.map +1 -0
- package/dist/resources/templates/utils/dom.d.ts +15 -0
- package/dist/resources/templates/utils/dom.d.ts.map +1 -0
- package/dist/resources/templates/utils/html.d.ts +3 -0
- package/dist/resources/templates/utils/html.d.ts.map +1 -0
- package/dist/resources/templates/workDisplay.d.ts +183 -0
- package/dist/resources/templates/workDisplay.d.ts.map +1 -0
- package/dist/resources/templates/workSelect.d.ts +18 -0
- package/dist/resources/templates/workSelect.d.ts.map +1 -0
- package/dist/resources/user-sample.d.ts +2 -0
- package/dist/resources/user-sample.d.ts.map +1 -0
- package/dist/resources/user.d.ts +2 -0
- package/dist/resources/user.d.ts.map +1 -0
- package/dist/resources/utils/IntlURLSearchParams.d.ts +56 -0
- package/dist/resources/utils/IntlURLSearchParams.d.ts.map +1 -0
- package/dist/resources/utils/Languages.d.ts +81 -0
- package/dist/resources/utils/Languages.d.ts.map +1 -0
- package/dist/resources/utils/Metadata.d.ts +133 -0
- package/dist/resources/utils/Metadata.d.ts.map +1 -0
- package/dist/resources/utils/Params.d.ts +30 -0
- package/dist/resources/utils/Params.d.ts.map +1 -0
- package/dist/resources/utils/Plugin.d.ts +274 -0
- package/dist/resources/utils/Plugin.d.ts.map +1 -0
- package/dist/resources/utils/ServiceWorker.d.ts +26 -0
- package/dist/resources/utils/ServiceWorker.d.ts.map +1 -0
- package/dist/resources/utils/WorkInfo.d.ts +104 -0
- package/dist/resources/utils/WorkInfo.d.ts.map +1 -0
- package/dist/resources/utils/dialogs.d.ts +155 -0
- package/dist/resources/utils/dialogs.d.ts.map +1 -0
- package/dist/resources/utils/getLocaleFallbackResults.d.ts +19 -0
- package/dist/resources/utils/getLocaleFallbackResults.d.ts.map +1 -0
- package/dist/resources/utils/sanitize.d.ts +6 -0
- package/dist/resources/utils/sanitize.d.ts.map +1 -0
- package/dist/resources/vendor/json-refs-min.d.ts +3 -0
- package/dist/resources/vendor/json-refs-min.d.ts.map +1 -0
- package/dist/resources/workDisplay.d.ts +81 -0
- package/dist/resources/workDisplay.d.ts.map +1 -0
- package/dist/resources/workSelect.d.ts +17 -0
- package/dist/resources/workSelect.d.ts.map +1 -0
- package/dist/rollup.config.d.ts +19 -0
- package/dist/rollup.config.d.ts.map +1 -0
- package/dist/server/main.d.ts +46 -0
- package/dist/server/main.d.ts.map +1 -0
- package/dist/sw-helper.d.ts +3 -0
- package/dist/sw-helper.d.ts.map +1 -0
- package/dist/sw-helper.js +52 -12
- package/dist/sw-sample.d.ts +2 -0
- package/dist/sw-sample.d.ts.map +1 -0
- package/general-schemas/files.jsonschema +6 -0
- package/package.json +21 -8
- package/resources/activateCallback.js +75 -10
- package/resources/index.js +161 -49
- package/resources/resultsDisplay.js +517 -152
- package/resources/templates/index.js +39 -16
- package/resources/templates/languageSelect.js +14 -1
- package/resources/templates/resultsDisplayClient.js +22 -3
- package/resources/templates/resultsDisplayServerOrClient.js +188 -49
- package/resources/templates/utils/dom.js +13 -2
- package/resources/templates/workDisplay.js +299 -75
- package/resources/templates/workSelect.js +16 -3
- package/resources/utils/IntlURLSearchParams.js +46 -4
- package/resources/utils/Languages.js +71 -4
- package/resources/utils/Metadata.js +219 -22
- package/resources/utils/Params.js +70 -23
- package/resources/utils/Plugin.js +169 -1
- package/resources/utils/ServiceWorker.js +48 -19
- package/resources/utils/WorkInfo.js +255 -43
- package/resources/utils/dialogs.js +105 -7
- package/resources/utils/getLocaleFallbackResults.js +12 -2
- package/resources/utils/sanitize.js +4 -0
- package/resources/workDisplay.js +151 -25
- package/resources/workSelect.js +37 -17
- package/server/main.js +111 -19
- package/tsconfig.json +30 -0
- package/resources/user.js +0 -20
|
@@ -1,19 +1,58 @@
|
|
|
1
1
|
// Todo: Reimplement this with `formSerialize.deserialize` as possible
|
|
2
|
+
|
|
3
|
+
// @ts-expect-error Todo: Add types
|
|
2
4
|
import {serialize as formSerialize} from 'form-serialization';
|
|
3
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @param {URLSearchParams} paramsCopy
|
|
8
|
+
*/
|
|
4
9
|
export const replaceHash = (paramsCopy) => {
|
|
5
10
|
return location.href.replace(/#.*$/, '') + '#' + paramsCopy.toString();
|
|
6
11
|
};
|
|
7
12
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
/**
|
|
14
|
+
* @param {{
|
|
15
|
+
* l: import('intl-dom').I18NCallback,
|
|
16
|
+
* lParam: (key: string) => string,
|
|
17
|
+
* $p: import('./IntlURLSearchParams.js').default
|
|
18
|
+
* }} args
|
|
19
|
+
*/
|
|
20
|
+
export const getSerializeParamsAsURL = function (args) {
|
|
21
|
+
const setter = getParamsSetter(args);
|
|
22
|
+
/**
|
|
23
|
+
* @param {{
|
|
24
|
+
* form: HTMLFormElement,
|
|
25
|
+
* random: {checked: boolean},
|
|
26
|
+
* checkboxes: HTMLInputElement[],
|
|
27
|
+
* type: string,
|
|
28
|
+
* fieldAliasOrNames?: string[],
|
|
29
|
+
* workName?: string
|
|
30
|
+
* }} innerArg
|
|
31
|
+
*/
|
|
32
|
+
return function (innerArg) {
|
|
33
|
+
const paramsCopy = setter(innerArg);
|
|
12
34
|
return replaceHash(paramsCopy);
|
|
13
35
|
};
|
|
14
36
|
};
|
|
15
37
|
|
|
38
|
+
/**
|
|
39
|
+
* @param {{
|
|
40
|
+
* l: import('intl-dom').I18NCallback,
|
|
41
|
+
* lParam: (key: string) => string,
|
|
42
|
+
* $p: import('./IntlURLSearchParams.js').default
|
|
43
|
+
* }} cfg
|
|
44
|
+
*/
|
|
16
45
|
export const getParamsSetter = function ({l, lParam, $p}) {
|
|
46
|
+
/**
|
|
47
|
+
* @param {{
|
|
48
|
+
* form: HTMLFormElement,
|
|
49
|
+
* random: {checked: boolean},
|
|
50
|
+
* checkboxes: HTMLInputElement[],
|
|
51
|
+
* type: string,
|
|
52
|
+
* fieldAliasOrNames?: string[],
|
|
53
|
+
* workName?: string
|
|
54
|
+
* }} cfg
|
|
55
|
+
*/
|
|
17
56
|
return function ({form, random = {
|
|
18
57
|
checked: false
|
|
19
58
|
}, checkboxes, type, fieldAliasOrNames = [], workName}) {
|
|
@@ -26,7 +65,11 @@ export const getParamsSetter = function ({l, lParam, $p}) {
|
|
|
26
65
|
|
|
27
66
|
// Follow the same style (and order) for checkboxes
|
|
28
67
|
paramsCopy.delete(lParam('rand'));
|
|
29
|
-
paramsCopy.set(
|
|
68
|
+
paramsCopy.set(
|
|
69
|
+
lParam('rand'), /** @type {string} */ (
|
|
70
|
+
random.checked ? l('yes') : l('no')
|
|
71
|
+
)
|
|
72
|
+
);
|
|
30
73
|
|
|
31
74
|
// We want checkboxes to typically show by default, so we cannot use the
|
|
32
75
|
// standard serialization
|
|
@@ -34,7 +77,11 @@ export const getParamsSetter = function ({l, lParam, $p}) {
|
|
|
34
77
|
// Let's ensure the checked items are all together (at the end)
|
|
35
78
|
paramsCopy.delete(checkbox.name);
|
|
36
79
|
if (checkbox.name) { // We don't want, e.g., preference controls added to URL
|
|
37
|
-
paramsCopy.set(
|
|
80
|
+
paramsCopy.set(
|
|
81
|
+
checkbox.name,
|
|
82
|
+
/** @type {string} */
|
|
83
|
+
(checkbox.checked ? l('yes') : l('no'))
|
|
84
|
+
);
|
|
38
85
|
}
|
|
39
86
|
});
|
|
40
87
|
|
|
@@ -45,11 +92,11 @@ export const getParamsSetter = function ({l, lParam, $p}) {
|
|
|
45
92
|
function removeStartsEndsAndAnchors () {
|
|
46
93
|
let num = 1;
|
|
47
94
|
let num2 = 1;
|
|
48
|
-
while (paramsCopy.has(`${workName}-start${num}-${num2}
|
|
49
|
-
while (paramsCopy.has(`${workName}-start${num}-${num2}
|
|
50
|
-
paramsCopy.delete(`${workName}-start${num}-${num2}
|
|
51
|
-
paramsCopy.delete(`${workName}-end${num}-${num2}
|
|
52
|
-
paramsCopy.delete(`${workName}-anchor${num}-${num2}
|
|
95
|
+
while (paramsCopy.has(`${workName}-start${num}-${num2}`)) {
|
|
96
|
+
while (paramsCopy.has(`${workName}-start${num}-${num2}`)) {
|
|
97
|
+
paramsCopy.delete(`${workName}-start${num}-${num2}`);
|
|
98
|
+
paramsCopy.delete(`${workName}-end${num}-${num2}`);
|
|
99
|
+
paramsCopy.delete(`${workName}-anchor${num}-${num2}`);
|
|
53
100
|
num2++;
|
|
54
101
|
}
|
|
55
102
|
num2 = 1;
|
|
@@ -67,29 +114,29 @@ export const getParamsSetter = function ({l, lParam, $p}) {
|
|
|
67
114
|
case 'shortcutResult': {
|
|
68
115
|
paramsCopy.delete(lParam('rand'));
|
|
69
116
|
let num = 1;
|
|
70
|
-
while (paramsCopy.has(`anchorfield${num}
|
|
71
|
-
paramsCopy.delete(`anchorfield${num}
|
|
117
|
+
while (paramsCopy.has(`anchorfield${num}`)) {
|
|
118
|
+
paramsCopy.delete(`anchorfield${num}`);
|
|
72
119
|
num++;
|
|
73
120
|
}
|
|
74
121
|
removeStartsEndsAndAnchors();
|
|
75
122
|
|
|
76
123
|
num = 1;
|
|
77
124
|
// Delete field-specific so we can add our own
|
|
78
|
-
while (paramsCopy.has(`field${num}
|
|
79
|
-
paramsCopy.delete(`field${num}
|
|
80
|
-
paramsCopy.delete(`checked${num}
|
|
81
|
-
paramsCopy.delete(`interlin${num}
|
|
82
|
-
paramsCopy.delete(`css${num}
|
|
125
|
+
while (paramsCopy.has(`field${num}`)) {
|
|
126
|
+
paramsCopy.delete(`field${num}`);
|
|
127
|
+
paramsCopy.delete(`checked${num}`);
|
|
128
|
+
paramsCopy.delete(`interlin${num}`);
|
|
129
|
+
paramsCopy.delete(`css${num}`);
|
|
83
130
|
num++;
|
|
84
131
|
}
|
|
85
132
|
fieldAliasOrNames.forEach((fieldAliasOrName, i) => {
|
|
86
|
-
paramsCopy.set(`field${i + 1}`, fieldAliasOrName
|
|
133
|
+
paramsCopy.set(`field${i + 1}`, fieldAliasOrName);
|
|
87
134
|
// Todo: Restrict by content locale?
|
|
88
|
-
paramsCopy.set(`checked${i + 1}`, l('yes')
|
|
135
|
+
paramsCopy.set(`checked${i + 1}`, /** @type {string} */ (l('yes')));
|
|
89
136
|
paramsCopy.set(`interlin${i + 1}`, '');
|
|
90
137
|
paramsCopy.set(`css${i + 1}`, '');
|
|
91
138
|
});
|
|
92
|
-
paramsCopy.delete('work'
|
|
139
|
+
paramsCopy.delete('work');
|
|
93
140
|
}
|
|
94
141
|
// Fallthrough
|
|
95
142
|
case 'startEndResult':
|
|
@@ -102,9 +149,9 @@ export const getParamsSetter = function ({l, lParam, $p}) {
|
|
|
102
149
|
// let's put random again toward the end.
|
|
103
150
|
if (type === 'randomResult' || random.checked) {
|
|
104
151
|
paramsCopy.delete(lParam('rand'));
|
|
105
|
-
paramsCopy.set(lParam('rand'), l('yes'));
|
|
152
|
+
paramsCopy.set(lParam('rand'), /** @type {string} */ (l('yes')));
|
|
106
153
|
}
|
|
107
|
-
paramsCopy.set(lParam('result'), l('yes'));
|
|
154
|
+
paramsCopy.set(lParam('result'), /** @type {string} */ (l('yes')));
|
|
108
155
|
break;
|
|
109
156
|
}
|
|
110
157
|
default: {
|
|
@@ -1,8 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {number} Integer
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {string} pluginName
|
|
7
|
+
*/
|
|
1
8
|
export const escapePluginComponent = (pluginName) => {
|
|
2
9
|
return pluginName.replaceAll('^', '^^'). // Escape our escape
|
|
3
10
|
replaceAll('-', '^0');
|
|
4
11
|
};
|
|
5
12
|
|
|
13
|
+
/**
|
|
14
|
+
* @param {string|undefined} pluginName
|
|
15
|
+
*/
|
|
6
16
|
export const unescapePluginComponent = (pluginName) => {
|
|
7
17
|
if (!pluginName) {
|
|
8
18
|
return pluginName;
|
|
@@ -17,18 +27,120 @@ export const unescapePluginComponent = (pluginName) => {
|
|
|
17
27
|
).replaceAll('^^', '^');
|
|
18
28
|
};
|
|
19
29
|
|
|
30
|
+
/**
|
|
31
|
+
* @param {{
|
|
32
|
+
* pluginName: string,
|
|
33
|
+
* applicableField: string,
|
|
34
|
+
* targetLanguage: string
|
|
35
|
+
* }} cfg
|
|
36
|
+
*/
|
|
20
37
|
export const escapePlugin = ({pluginName, applicableField, targetLanguage}) => {
|
|
21
38
|
return escapePluginComponent(pluginName) +
|
|
22
39
|
(applicableField ? '-' + escapePluginComponent(applicableField) : '-') +
|
|
23
40
|
(targetLanguage ? '-' + escapePluginComponent(targetLanguage) : '');
|
|
24
41
|
};
|
|
25
42
|
|
|
43
|
+
/**
|
|
44
|
+
* @todo Complete
|
|
45
|
+
* @typedef {{
|
|
46
|
+
* path: string,
|
|
47
|
+
* onByDefault?: boolean,
|
|
48
|
+
* lang?: string,
|
|
49
|
+
* meta?: {[key: string]: string}
|
|
50
|
+
* getCellData?: (info: {
|
|
51
|
+
* tr: (string|Integer)[],
|
|
52
|
+
* tableData: (string|Integer)[][],
|
|
53
|
+
* i: number,
|
|
54
|
+
* j: number,
|
|
55
|
+
* applicableField?: string,
|
|
56
|
+
* fieldInfo: import('../resultsDisplay.js').FieldInfo,
|
|
57
|
+
* applicableFieldIdx: number,
|
|
58
|
+
* applicableFieldText: string|Integer,
|
|
59
|
+
* fieldLang: string,
|
|
60
|
+
* getLangDir: (locale: string) => string,
|
|
61
|
+
* meta: {
|
|
62
|
+
* [key: string]: string
|
|
63
|
+
* }|undefined,
|
|
64
|
+
* metaApplicableField?: {
|
|
65
|
+
* [key: string]: string
|
|
66
|
+
* },
|
|
67
|
+
* $p: import('./IntlURLSearchParams.js').default,
|
|
68
|
+
* thisObj: import('../index.js').default|import('../../server/main.js').ResultsDisplayServerContext
|
|
69
|
+
* }) => void,
|
|
70
|
+
* done: (info: {
|
|
71
|
+
* $p: import('./IntlURLSearchParams.js').default,
|
|
72
|
+
* applicableField: string|undefined,
|
|
73
|
+
* meta?: {[key: string]: string}
|
|
74
|
+
* thisObj: import('../index.js').default
|
|
75
|
+
* j?: number
|
|
76
|
+
* }) => void,
|
|
77
|
+
* getTargetLanguage: (info: {
|
|
78
|
+
* applicableField: string,
|
|
79
|
+
* targetLanguage?: string,
|
|
80
|
+
* pluginLang: string,
|
|
81
|
+
* applicableFieldLang?: string
|
|
82
|
+
* }) => string,
|
|
83
|
+
* escapeColumn?: boolean,
|
|
84
|
+
* getFieldAliasOrName: (info: {
|
|
85
|
+
* locales: string[],
|
|
86
|
+
* workI18n: import('intl-dom').I18NCallback,
|
|
87
|
+
* targetLanguage: string,
|
|
88
|
+
* applicableField: string,
|
|
89
|
+
* applicableFieldI18N: string|string[]|import("../../server/main.js").LocalizationStrings,
|
|
90
|
+
* meta: any,
|
|
91
|
+
* metaApplicableField: {
|
|
92
|
+
* [key: string]: string
|
|
93
|
+
* },
|
|
94
|
+
* targetLanguageI18N: string
|
|
95
|
+
* }) => string
|
|
96
|
+
* }} PluginObject
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @typedef {{
|
|
101
|
+
* path: string,
|
|
102
|
+
* lang: string,
|
|
103
|
+
* meta: any,
|
|
104
|
+
* onByDefault: boolean
|
|
105
|
+
* }} PluginInfo
|
|
106
|
+
*/
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @typedef {{
|
|
110
|
+
* placement: "end"|number,
|
|
111
|
+
* 'applicable-fields': {
|
|
112
|
+
* [field: string]: {
|
|
113
|
+
* targetLanguage: string|string[],
|
|
114
|
+
* onByDefault: boolean,
|
|
115
|
+
* meta: {
|
|
116
|
+
* [key: string]: string
|
|
117
|
+
* },
|
|
118
|
+
* [args: string]: {}
|
|
119
|
+
* }
|
|
120
|
+
* },
|
|
121
|
+
* [fieldArgs: string]: {
|
|
122
|
+
* }
|
|
123
|
+
* }} PluginFieldMappingForWork
|
|
124
|
+
*/
|
|
125
|
+
|
|
26
126
|
export class PluginsForWork {
|
|
127
|
+
/**
|
|
128
|
+
* @param {{
|
|
129
|
+
* pluginsInWork: [string, PluginInfo][],
|
|
130
|
+
* pluginFieldMappings: PluginFieldMappingForWork[],
|
|
131
|
+
* pluginObjects: PluginObject[]
|
|
132
|
+
* }} cfg
|
|
133
|
+
*/
|
|
27
134
|
constructor ({pluginsInWork, pluginFieldMappings, pluginObjects}) {
|
|
28
135
|
this.pluginsInWork = pluginsInWork;
|
|
29
136
|
this.pluginFieldMappings = pluginFieldMappings;
|
|
30
137
|
this.pluginObjects = pluginObjects;
|
|
31
138
|
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @param {string} pluginName
|
|
142
|
+
* @returns {PluginObject}
|
|
143
|
+
*/
|
|
32
144
|
getPluginObject (pluginName) {
|
|
33
145
|
const idx = this.pluginsInWork.findIndex(([name]) => {
|
|
34
146
|
return name === pluginName;
|
|
@@ -36,6 +148,25 @@ export class PluginsForWork {
|
|
|
36
148
|
const plugin = this.pluginObjects[idx];
|
|
37
149
|
return plugin;
|
|
38
150
|
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @param {(cfg: {
|
|
154
|
+
* plugin: PluginObject,
|
|
155
|
+
* placement: "end"|number,
|
|
156
|
+
* applicableFields: {
|
|
157
|
+
* [applicableField: string]: {
|
|
158
|
+
* targetLanguage: string|string[],
|
|
159
|
+
* onByDefault: boolean,
|
|
160
|
+
* meta: any
|
|
161
|
+
* }
|
|
162
|
+
* },
|
|
163
|
+
* pluginName: string,
|
|
164
|
+
* pluginLang: string,
|
|
165
|
+
* onByDefaultDefault: boolean,
|
|
166
|
+
* meta: {}
|
|
167
|
+
* }) => void} cb
|
|
168
|
+
* @returns {void}
|
|
169
|
+
*/
|
|
39
170
|
iterateMappings (cb) {
|
|
40
171
|
this.pluginFieldMappings.forEach(({
|
|
41
172
|
placement,
|
|
@@ -62,6 +193,25 @@ export class PluginsForWork {
|
|
|
62
193
|
});
|
|
63
194
|
});
|
|
64
195
|
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @param {{
|
|
199
|
+
* [applicableField: string]: {
|
|
200
|
+
* targetLanguage: string|string[],
|
|
201
|
+
* onByDefault: boolean,
|
|
202
|
+
* meta: any
|
|
203
|
+
* }
|
|
204
|
+
* }} applicableFields
|
|
205
|
+
* @param {(cfg: {
|
|
206
|
+
* applicableField: string,
|
|
207
|
+
* targetLanguage: string,
|
|
208
|
+
* onByDefault: boolean,
|
|
209
|
+
* metaApplicableField: {
|
|
210
|
+
* [key: string]: string
|
|
211
|
+
* }
|
|
212
|
+
* }) => void} cb
|
|
213
|
+
* @returns {boolean}
|
|
214
|
+
*/
|
|
65
215
|
processTargetLanguages (applicableFields, cb) {
|
|
66
216
|
if (!applicableFields) {
|
|
67
217
|
return false;
|
|
@@ -79,9 +229,25 @@ export class PluginsForWork {
|
|
|
79
229
|
});
|
|
80
230
|
return true;
|
|
81
231
|
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* @param {{
|
|
235
|
+
* namespace: string,
|
|
236
|
+
* field: string
|
|
237
|
+
* }} cfg
|
|
238
|
+
* @returns {boolean}
|
|
239
|
+
*/
|
|
82
240
|
isPluginField ({namespace, field}) {
|
|
83
241
|
return field.startsWith(`${namespace}-plugin-`);
|
|
84
242
|
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* @param {{
|
|
246
|
+
* namespace: string,
|
|
247
|
+
* field: string
|
|
248
|
+
* }} cfg
|
|
249
|
+
* @returns {[string, string|undefined, string|undefined]}
|
|
250
|
+
*/
|
|
85
251
|
getPluginFieldParts ({namespace, field}) {
|
|
86
252
|
field = field.replace(`${namespace}-plugin-`, '');
|
|
87
253
|
let pluginName, applicableField, targetLanguage;
|
|
@@ -90,6 +256,8 @@ export class PluginsForWork {
|
|
|
90
256
|
} else {
|
|
91
257
|
pluginName = field;
|
|
92
258
|
}
|
|
93
|
-
return [
|
|
259
|
+
return /** @type {[string, string|undefined, string|undefined]} */ (
|
|
260
|
+
[pluginName, applicableField, targetLanguage].map(unescapePluginComponent)
|
|
261
|
+
);
|
|
94
262
|
}
|
|
95
263
|
}
|
|
@@ -2,16 +2,21 @@
|
|
|
2
2
|
import {dialogs} from './dialogs.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* @param {PlainObject} target
|
|
7
|
-
* @param {PlainObject} source
|
|
8
|
-
* @returns {{
|
|
5
|
+
* @typedef {{
|
|
9
6
|
* userJSON: string,
|
|
10
7
|
* languages: string,
|
|
11
8
|
* serviceWorkerPath: string,
|
|
12
9
|
* files: string,
|
|
13
|
-
* namespace: string
|
|
14
|
-
*
|
|
10
|
+
* namespace: string,
|
|
11
|
+
* stylesheets?: string[]
|
|
12
|
+
* }} ServiceWorkerConfig
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Note that this function be kept as a polyglot client-server file.
|
|
17
|
+
* @param {Partial<ServiceWorkerConfig>} target
|
|
18
|
+
* @param {Partial<ServiceWorkerConfig>} source
|
|
19
|
+
* @returns {ServiceWorkerConfig}
|
|
15
20
|
*/
|
|
16
21
|
export const setServiceWorkerDefaults = (target, source) => {
|
|
17
22
|
target.userJSON = source.userJSON || 'resources/user.json';
|
|
@@ -27,13 +32,18 @@ export const setServiceWorkerDefaults = (target, source) => {
|
|
|
27
32
|
}`;
|
|
28
33
|
target.files = source.files || 'files.json';
|
|
29
34
|
target.namespace = source.namespace || 'textbrowser';
|
|
30
|
-
return target;
|
|
35
|
+
return /** @type {ServiceWorkerConfig} */ (target);
|
|
31
36
|
};
|
|
32
37
|
|
|
33
38
|
// (Unless skipped in code, will wait between install
|
|
34
39
|
// of new and activation of new or existing if still
|
|
35
40
|
// some tabs open)
|
|
36
41
|
|
|
42
|
+
/**
|
|
43
|
+
* @param {{
|
|
44
|
+
* r: ServiceWorkerRegistration
|
|
45
|
+
* }} cfg
|
|
46
|
+
*/
|
|
37
47
|
export const listenForWorkerUpdate = ({
|
|
38
48
|
r
|
|
39
49
|
// logger
|
|
@@ -43,7 +53,7 @@ export const listenForWorkerUpdate = ({
|
|
|
43
53
|
// r.installing now available (though r.active is also,
|
|
44
54
|
// apparently due to prior activation; but not r.waiting)
|
|
45
55
|
console.log('update found', e);
|
|
46
|
-
const newWorker = r.installing;
|
|
56
|
+
const newWorker = /** @type {ServiceWorker} */ (r.installing);
|
|
47
57
|
|
|
48
58
|
// statechange won't catch this installing event as already installing
|
|
49
59
|
|
|
@@ -97,6 +107,18 @@ for offline installation.
|
|
|
97
107
|
});
|
|
98
108
|
};
|
|
99
109
|
|
|
110
|
+
/**
|
|
111
|
+
* @typedef {{
|
|
112
|
+
* addLogEntry: (entry: {text: string}) => void,
|
|
113
|
+
* }} Logger
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @param {{
|
|
118
|
+
* r: ServiceWorkerRegistration,
|
|
119
|
+
* logger: Logger
|
|
120
|
+
* }} cfg
|
|
121
|
+
*/
|
|
100
122
|
export const respondToState = async ({
|
|
101
123
|
r, logger
|
|
102
124
|
}) => {
|
|
@@ -157,20 +179,20 @@ export const respondToState = async ({
|
|
|
157
179
|
}; trying again...`
|
|
158
180
|
});
|
|
159
181
|
/*
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
182
|
+
if (errorType === 'dbError') {
|
|
183
|
+
logger.dbError({
|
|
184
|
+
type: name || errorType,
|
|
185
|
+
escapedErrorMessage: escapeHTML(message)
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
*/
|
|
167
189
|
// Todo: auto-close any dbError dialog if retrying
|
|
168
190
|
// No longer rejecting as should auto-retry
|
|
169
191
|
/*
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
192
|
+
const err = new Error(message);
|
|
193
|
+
err.type = type;
|
|
194
|
+
reject(err);
|
|
195
|
+
*/
|
|
174
196
|
break;
|
|
175
197
|
default:
|
|
176
198
|
console.error('Unexpected type', type);
|
|
@@ -219,6 +241,13 @@ any indication it is installing.
|
|
|
219
241
|
|
|
220
242
|
// Keep in this file as may wish to avoid using for server (while still
|
|
221
243
|
// doing other service worker work)
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* @param {{
|
|
247
|
+
* serviceWorkerPath: string,
|
|
248
|
+
* logger: Logger
|
|
249
|
+
* }} cfg
|
|
250
|
+
*/
|
|
222
251
|
export const registerServiceWorker = async ({
|
|
223
252
|
serviceWorkerPath,
|
|
224
253
|
logger
|