textbrowser 0.41.2 → 0.42.2
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/.eslintignore +0 -1
- package/{.eslintrc.js → .eslintrc.cjs} +0 -0
- package/CHANGES.md +15 -0
- package/README.md +23 -19
- package/dist/WorkInfo-es.js +26 -95
- package/dist/index-es.js +233 -1276
- package/dist/index-es.min.js +3 -3
- package/dist/index-umd.js +8 -1003
- package/dist/index-umd.min.js +3 -3
- package/package.json +35 -35
- package/resources/index.js +1 -2
- package/resources/resultsDisplay.js +3 -2
- package/resources/utils/Metadata.js +1 -1
- package/resources/utils/WorkInfo.js +0 -22
- package/resources/utils/dialogs.js +0 -4
- package/server/main.js +14 -12
- package/sw-sample.js +0 -2
- package/server/main-cjs.js +0 -4052
package/dist/index-es.js
CHANGED
|
@@ -75,57 +75,6 @@ function _objectWithoutProperties(source, excluded) {
|
|
|
75
75
|
return target;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
function _getRequireWildcardCache$1() {
|
|
79
|
-
if (typeof WeakMap !== "function") return null;
|
|
80
|
-
var cache = new WeakMap();
|
|
81
|
-
|
|
82
|
-
_getRequireWildcardCache$1 = function () {
|
|
83
|
-
return cache;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
return cache;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function _interopRequireWildcard$1(obj) {
|
|
90
|
-
if (obj && obj.__esModule) {
|
|
91
|
-
return obj;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
95
|
-
return {
|
|
96
|
-
default: obj
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
var cache = _getRequireWildcardCache$1();
|
|
101
|
-
|
|
102
|
-
if (cache && cache.has(obj)) {
|
|
103
|
-
return cache.get(obj);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
var newObj = {};
|
|
107
|
-
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
108
|
-
|
|
109
|
-
for (var key in obj) {
|
|
110
|
-
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
111
|
-
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
112
|
-
|
|
113
|
-
if (desc && (desc.get || desc.set)) {
|
|
114
|
-
Object.defineProperty(newObj, key, desc);
|
|
115
|
-
} else {
|
|
116
|
-
newObj[key] = obj[key];
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
newObj.default = obj;
|
|
122
|
-
|
|
123
|
-
if (cache) {
|
|
124
|
-
cache.set(obj, newObj);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return newObj;
|
|
128
|
-
}
|
|
129
78
|
/* eslint-disable node/no-unsupported-features/es-syntax */
|
|
130
79
|
|
|
131
80
|
/**
|
|
@@ -141,9 +90,7 @@ function _interopRequireWildcard$1(obj) {
|
|
|
141
90
|
* @param {fetch} cfg.fetch
|
|
142
91
|
* @returns {getJSONCallback}
|
|
143
92
|
*/
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
function _await$3(value, then, direct) {
|
|
93
|
+
function _await$2$1(value, then, direct) {
|
|
147
94
|
if (direct) {
|
|
148
95
|
return then ? then(value) : value;
|
|
149
96
|
}
|
|
@@ -155,7 +102,7 @@ function _await$3(value, then, direct) {
|
|
|
155
102
|
return then ? value.then(then) : value;
|
|
156
103
|
}
|
|
157
104
|
|
|
158
|
-
function _invoke$
|
|
105
|
+
function _invoke$1$1(body, then) {
|
|
159
106
|
var result = body();
|
|
160
107
|
|
|
161
108
|
if (result && result.then) {
|
|
@@ -202,10 +149,10 @@ function buildGetJSONWithFetch$1({
|
|
|
202
149
|
return function getJSON(jsonURL, cb, errBack) {
|
|
203
150
|
try {
|
|
204
151
|
let _exit = false;
|
|
205
|
-
return _catch$1(function () {
|
|
206
|
-
return _invoke$
|
|
152
|
+
return _await$2$1(_catch$1(function () {
|
|
153
|
+
return _invoke$1$1(function () {
|
|
207
154
|
if (Array.isArray(jsonURL)) {
|
|
208
|
-
return _await$
|
|
155
|
+
return _await$2$1(Promise.all(jsonURL.map(url => {
|
|
209
156
|
return getJSON(url);
|
|
210
157
|
})), function (arrResult) {
|
|
211
158
|
if (cb) {
|
|
@@ -218,8 +165,8 @@ function buildGetJSONWithFetch$1({
|
|
|
218
165
|
});
|
|
219
166
|
}
|
|
220
167
|
}, function (_result) {
|
|
221
|
-
return _exit ? _result : _await$
|
|
222
|
-
return _await$
|
|
168
|
+
return _exit ? _result : _await$2$1(fetch(jsonURL), function (resp) {
|
|
169
|
+
return _await$2$1(resp.json(), function (result) {
|
|
223
170
|
return typeof cb === 'function' // eslint-disable-next-line promise/prefer-await-to-callbacks
|
|
224
171
|
? cb(result) : result; // https://github.com/bcoe/c8/issues/135
|
|
225
172
|
|
|
@@ -237,7 +184,7 @@ function buildGetJSONWithFetch$1({
|
|
|
237
184
|
throw e; // https://github.com/bcoe/c8/issues/135
|
|
238
185
|
|
|
239
186
|
/* c8 ignore next */
|
|
240
|
-
});
|
|
187
|
+
}));
|
|
241
188
|
/* c8 ignore next */
|
|
242
189
|
} catch (e) {
|
|
243
190
|
return Promise.reject(e);
|
|
@@ -282,7 +229,7 @@ function _invokeIgnored$1(body) {
|
|
|
282
229
|
}
|
|
283
230
|
}
|
|
284
231
|
|
|
285
|
-
function _async$
|
|
232
|
+
function _async$1$1(f) {
|
|
286
233
|
return function () {
|
|
287
234
|
for (var args = [], i = 0; i < arguments.length; i++) {
|
|
288
235
|
args[i] = arguments[i];
|
|
@@ -296,10 +243,10 @@ function _async$2(f) {
|
|
|
296
243
|
};
|
|
297
244
|
}
|
|
298
245
|
|
|
299
|
-
const setDirname$1 = _async$
|
|
246
|
+
const setDirname$1 = _async$1$1(function () {
|
|
300
247
|
return _invokeIgnored$1(function () {
|
|
301
248
|
if (!dirname$1) {
|
|
302
|
-
return _await$1$1(
|
|
249
|
+
return _await$1$1(import('path'), function (_import) {
|
|
303
250
|
({
|
|
304
251
|
dirname: dirname$1
|
|
305
252
|
} = _import);
|
|
@@ -331,8 +278,10 @@ function getDirectoryForURL$1(url) {
|
|
|
331
278
|
// "file://" +
|
|
332
279
|
return fixWindowsPath$1(dirname$1(new URL(url).pathname));
|
|
333
280
|
}
|
|
281
|
+
/* eslint-disable node/no-unsupported-features/es-syntax */
|
|
334
282
|
|
|
335
|
-
|
|
283
|
+
|
|
284
|
+
function _await$3(value, then, direct) {
|
|
336
285
|
if (direct) {
|
|
337
286
|
return then ? then(value) : value;
|
|
338
287
|
}
|
|
@@ -352,7 +301,7 @@ let nodeFetch$1;
|
|
|
352
301
|
* @returns {getJSONCallback}
|
|
353
302
|
*/
|
|
354
303
|
|
|
355
|
-
function _invoke$
|
|
304
|
+
function _invoke$2(body, then) {
|
|
356
305
|
var result = body();
|
|
357
306
|
|
|
358
307
|
if (result && result.then) {
|
|
@@ -375,7 +324,7 @@ function _call$1(body, then, direct) {
|
|
|
375
324
|
}
|
|
376
325
|
}
|
|
377
326
|
|
|
378
|
-
function _async$
|
|
327
|
+
function _async$2(f) {
|
|
379
328
|
return function () {
|
|
380
329
|
for (var args = [], i = 0; i < arguments.length; i++) {
|
|
381
330
|
args[i] = arguments[i];
|
|
@@ -393,23 +342,25 @@ function buildGetJSON$1({
|
|
|
393
342
|
baseURL,
|
|
394
343
|
cwd: basePath
|
|
395
344
|
} = {}) {
|
|
396
|
-
const _fetch = typeof fetch !== 'undefined' ? fetch : _async$
|
|
345
|
+
const _fetch = typeof fetch !== 'undefined' ? fetch : _async$2(function (jsonURL) {
|
|
397
346
|
let _exit = false;
|
|
398
|
-
return _invoke$
|
|
347
|
+
return _invoke$2(function () {
|
|
399
348
|
if (/^https?:/u.test(jsonURL)) {
|
|
400
|
-
return _invoke$
|
|
349
|
+
return _invoke$2(function () {
|
|
401
350
|
if (!nodeFetch$1) {
|
|
402
|
-
return _await$
|
|
351
|
+
return _await$3(import('node-fetch'), function (_import) {
|
|
403
352
|
nodeFetch$1 = _import;
|
|
404
353
|
});
|
|
405
354
|
}
|
|
406
355
|
}, function () {
|
|
356
|
+
const _nodeFetch$default = nodeFetch$1.default(jsonURL);
|
|
357
|
+
|
|
407
358
|
_exit = true;
|
|
408
|
-
return
|
|
359
|
+
return _nodeFetch$default;
|
|
409
360
|
});
|
|
410
361
|
}
|
|
411
362
|
}, function (_result) {
|
|
412
|
-
return _exit ? _result : _invoke$
|
|
363
|
+
return _exit ? _result : _invoke$2(function () {
|
|
413
364
|
if (!basePath) {
|
|
414
365
|
return _call$1(setDirname$1, function () {
|
|
415
366
|
basePath = baseURL ? getDirectoryForURL$1(baseURL) : typeof fetch === 'undefined' && process.cwd();
|
|
@@ -419,7 +370,7 @@ function buildGetJSON$1({
|
|
|
419
370
|
// Filed https://github.com/bergos/file-fetch/issues/12 to see
|
|
420
371
|
// about getting relative basePaths in `file-fetch` and using
|
|
421
372
|
// that better-tested package instead
|
|
422
|
-
return _await$
|
|
373
|
+
return _await$3(import('local-xmlhttprequest'), function (localXMLHttpRequest) {
|
|
423
374
|
// eslint-disable-next-line no-shadow
|
|
424
375
|
const XMLHttpRequest = localXMLHttpRequest.default({
|
|
425
376
|
basePath
|
|
@@ -429,6 +380,7 @@ function buildGetJSON$1({
|
|
|
429
380
|
return new Promise((resolve, reject) => {
|
|
430
381
|
const r = new XMLHttpRequest();
|
|
431
382
|
r.open('GET', jsonURL, true); // r.responseType = 'json';
|
|
383
|
+
// eslint-disable-next-line unicorn/prefer-add-event-listener -- May not be available
|
|
432
384
|
|
|
433
385
|
r.onreadystatechange = function () {
|
|
434
386
|
// Not sure how to simulate `if`
|
|
@@ -4618,1237 +4570,264 @@ function hashAssign(result, keys, value) {
|
|
|
4618
4570
|
return value;
|
|
4619
4571
|
}
|
|
4620
4572
|
|
|
4621
|
-
var key = keys.shift();
|
|
4622
|
-
var between = key.match(/^\[(.+?)]$/);
|
|
4623
|
-
|
|
4624
|
-
if (key === '[]') {
|
|
4625
|
-
result = result || [];
|
|
4626
|
-
|
|
4627
|
-
if (Array.isArray(result)) {
|
|
4628
|
-
result.push(hashAssign(null, keys, value));
|
|
4629
|
-
} else {
|
|
4630
|
-
// This might be the result of bad name attributes like "[][foo]",
|
|
4631
|
-
// in this case the original `result` object will already be
|
|
4632
|
-
// assigned to an object literal. Rather than coerce the object to
|
|
4633
|
-
// an array, or cause an exception the attribute "_values" is
|
|
4634
|
-
// assigned as an array.
|
|
4635
|
-
result._values = result._values || [];
|
|
4636
|
-
|
|
4637
|
-
result._values.push(hashAssign(null, keys, value));
|
|
4638
|
-
}
|
|
4639
|
-
|
|
4640
|
-
return result;
|
|
4641
|
-
} // Key is an attribute name and can be assigned directly.
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
if (!between) {
|
|
4645
|
-
result[key] = hashAssign(result[key], keys, value);
|
|
4646
|
-
} else {
|
|
4647
|
-
var string = between[1]; // +var converts the variable into a number
|
|
4648
|
-
// better than parseInt because it doesn't truncate away trailing
|
|
4649
|
-
// letters and actually fails if whole thing is not a number
|
|
4650
|
-
|
|
4651
|
-
var index = Number(string); // If the characters between the brackets is not a number it is an
|
|
4652
|
-
// attribute name and can be assigned directly.
|
|
4653
|
-
// Switching to Number.isNaN would require a polyfill for IE11
|
|
4654
|
-
// eslint-disable-next-line unicorn/prefer-number-properties
|
|
4655
|
-
|
|
4656
|
-
if (isNaN(index)) {
|
|
4657
|
-
result = result || {};
|
|
4658
|
-
result[string] = hashAssign(result[string], keys, value);
|
|
4659
|
-
} else {
|
|
4660
|
-
result = result || [];
|
|
4661
|
-
result[index] = hashAssign(result[index], keys, value);
|
|
4662
|
-
}
|
|
4663
|
-
}
|
|
4664
|
-
|
|
4665
|
-
return result;
|
|
4666
|
-
}
|
|
4667
|
-
/**
|
|
4668
|
-
* Object/hash encoding serializer.
|
|
4669
|
-
* @param {PlainObject} result
|
|
4670
|
-
* @param {string} key
|
|
4671
|
-
* @param {string} value
|
|
4672
|
-
* @returns {PlainObject}
|
|
4673
|
-
*/
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
function hashSerializer(result, key, value) {
|
|
4677
|
-
var hasBrackets = key.match(brackets); // Has brackets? Use the recursive assignment function to walk the keys,
|
|
4678
|
-
// construct any missing objects in the result tree and make the assignment
|
|
4679
|
-
// at the end of the chain.
|
|
4680
|
-
|
|
4681
|
-
if (hasBrackets) {
|
|
4682
|
-
var keys = parseKeys(key);
|
|
4683
|
-
hashAssign(result, keys, value);
|
|
4684
|
-
} else {
|
|
4685
|
-
// Non bracket notation can make assignments directly.
|
|
4686
|
-
var existing = result[key]; // If the value has been assigned already (for instance when a radio and
|
|
4687
|
-
// a checkbox have the same name attribute) convert the previous value
|
|
4688
|
-
// into an array before pushing into it.
|
|
4689
|
-
//
|
|
4690
|
-
// NOTE: If this requirement were removed all hash creation and
|
|
4691
|
-
// assignment could go through `hashAssign`.
|
|
4692
|
-
|
|
4693
|
-
if (existing) {
|
|
4694
|
-
if (!Array.isArray(existing)) {
|
|
4695
|
-
result[key] = [existing];
|
|
4696
|
-
}
|
|
4697
|
-
|
|
4698
|
-
result[key].push(value);
|
|
4699
|
-
} else {
|
|
4700
|
-
result[key] = value;
|
|
4701
|
-
}
|
|
4702
|
-
}
|
|
4703
|
-
|
|
4704
|
-
return result;
|
|
4705
|
-
}
|
|
4706
|
-
/**
|
|
4707
|
-
* URL form encoding serializer.
|
|
4708
|
-
* @param {string} result
|
|
4709
|
-
* @param {string} key
|
|
4710
|
-
* @param {string} value
|
|
4711
|
-
* @returns {string} New result
|
|
4712
|
-
*/
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
function strSerialize(result, key, value) {
|
|
4716
|
-
// encode newlines as \r\n cause the html spec says so
|
|
4717
|
-
value = value.replace(/(\r)?\n/g, '\r\n');
|
|
4718
|
-
value = encodeURIComponent(value); // spaces should be '+' rather than '%20'.
|
|
4719
|
-
|
|
4720
|
-
value = value.replace(/%20/g, '+');
|
|
4721
|
-
return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + value;
|
|
4722
|
-
}
|
|
4723
|
-
/**
|
|
4724
|
-
* @function module:FormSerialization.deserialize
|
|
4725
|
-
* @param {HTMLFormElement} form
|
|
4726
|
-
* @param {PlainObject} hash
|
|
4727
|
-
* @returns {void}
|
|
4728
|
-
*/
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
function deserialize(form, hash) {
|
|
4732
|
-
// input(text|radio|checkbox)|select(multiple)|textarea|keygen
|
|
4733
|
-
Object.entries(hash).forEach(function (_ref3) {
|
|
4734
|
-
var _ref4 = _slicedToArray(_ref3, 2),
|
|
4735
|
-
name = _ref4[0],
|
|
4736
|
-
value = _ref4[1];
|
|
4737
|
-
|
|
4738
|
-
var control = form[name];
|
|
4739
|
-
var hasBrackets = false; // istanbul ignore else
|
|
4740
|
-
|
|
4741
|
-
if (!control) {
|
|
4742
|
-
// Try again for jsdom
|
|
4743
|
-
control = form.querySelector("[name=\"".concat(name, "\"]"));
|
|
4744
|
-
|
|
4745
|
-
if (!control) {
|
|
4746
|
-
// We want this for `RadioNodeList` so setting value
|
|
4747
|
-
// auto-disables other boxes
|
|
4748
|
-
control = form[name + '[]']; // istanbul ignore next
|
|
4749
|
-
|
|
4750
|
-
if (!control || _typeof(control) !== 'object' || !('length' in control)) {
|
|
4751
|
-
// The latter query would only get a single
|
|
4752
|
-
// element, so if not a `RadioNodeList`, we get
|
|
4753
|
-
// all values here
|
|
4754
|
-
control = form.querySelectorAll("[name=\"".concat(name, "[]\"]"));
|
|
4755
|
-
|
|
4756
|
-
if (!control.length) {
|
|
4757
|
-
throw new Error("Name not found ".concat(name));
|
|
4758
|
-
}
|
|
4759
|
-
}
|
|
4760
|
-
|
|
4761
|
-
hasBrackets = true;
|
|
4762
|
-
}
|
|
4763
|
-
}
|
|
4764
|
-
|
|
4765
|
-
var _control = control,
|
|
4766
|
-
type = _control.type;
|
|
4767
|
-
|
|
4768
|
-
if (type === 'checkbox') {
|
|
4769
|
-
control.checked = value !== '';
|
|
4770
|
-
}
|
|
4771
|
-
|
|
4772
|
-
if (type === 'radio' || control[0] && control[0].type === 'radio') {
|
|
4773
|
-
_toConsumableArray(form.querySelectorAll("[name=\"".concat(name + (hasBrackets ? '[]' : ''), "\"]"))).forEach(function (radio) {
|
|
4774
|
-
radio.checked = value === radio.value;
|
|
4775
|
-
});
|
|
4776
|
-
}
|
|
4777
|
-
|
|
4778
|
-
if (control[0] && control[0].type === 'select-multiple') {
|
|
4779
|
-
_toConsumableArray(control[0].options).forEach(function (o) {
|
|
4780
|
-
if (value.includes(o.value)) {
|
|
4781
|
-
o.selected = true;
|
|
4782
|
-
}
|
|
4783
|
-
});
|
|
4784
|
-
|
|
4785
|
-
return;
|
|
4786
|
-
}
|
|
4787
|
-
|
|
4788
|
-
if (Array.isArray(value)) {
|
|
4789
|
-
// options on a multiple select
|
|
4790
|
-
if (type === 'select-multiple') {
|
|
4791
|
-
_toConsumableArray(control.options).forEach(function (o) {
|
|
4792
|
-
if (value.includes(o.value)) {
|
|
4793
|
-
o.selected = true;
|
|
4794
|
-
}
|
|
4795
|
-
});
|
|
4796
|
-
|
|
4797
|
-
return;
|
|
4798
|
-
}
|
|
4799
|
-
|
|
4800
|
-
value.forEach(function (v, i) {
|
|
4801
|
-
var c = control[i];
|
|
4802
|
-
|
|
4803
|
-
if (c.type === 'checkbox') {
|
|
4804
|
-
var isMatch = c.value === v || v === 'on';
|
|
4805
|
-
c.checked = isMatch;
|
|
4806
|
-
return;
|
|
4807
|
-
}
|
|
4808
|
-
|
|
4809
|
-
if (c.type === 'select-multiple') {
|
|
4810
|
-
_toConsumableArray(c.options).forEach(function (o) {
|
|
4811
|
-
if (v.includes(o.value)) {
|
|
4812
|
-
o.selected = true;
|
|
4813
|
-
}
|
|
4814
|
-
});
|
|
4815
|
-
|
|
4816
|
-
return;
|
|
4817
|
-
}
|
|
4818
|
-
|
|
4819
|
-
c.value = v;
|
|
4820
|
-
});
|
|
4821
|
-
} else {
|
|
4822
|
-
control.value = value;
|
|
4823
|
-
}
|
|
4824
|
-
});
|
|
4825
|
-
}
|
|
4826
|
-
|
|
4827
|
-
function getIMFFallbackResults({
|
|
4828
|
-
$p,
|
|
4829
|
-
lang,
|
|
4830
|
-
langs,
|
|
4831
|
-
langData,
|
|
4832
|
-
fallbackLanguages,
|
|
4833
|
-
resultsDisplay,
|
|
4834
|
-
basePath = '',
|
|
4835
|
-
localeCallback = false
|
|
4836
|
-
}) {
|
|
4837
|
-
return new Promise((resolve, reject) => {
|
|
4838
|
-
const resultsCallback = (...args) => {
|
|
4839
|
-
const [l10n] = args;
|
|
4840
|
-
|
|
4841
|
-
if (!$p.l10n) {
|
|
4842
|
-
$p.l10n = l10n;
|
|
4843
|
-
}
|
|
4844
|
-
|
|
4845
|
-
return resultsDisplay({
|
|
4846
|
-
l: l10n,
|
|
4847
|
-
lang,
|
|
4848
|
-
fallbackLanguages,
|
|
4849
|
-
imfLocales: imf.locales,
|
|
4850
|
-
$p,
|
|
4851
|
-
basePath
|
|
4852
|
-
}, ...args);
|
|
4853
|
-
};
|
|
4854
|
-
|
|
4855
|
-
const imf = IMF({
|
|
4856
|
-
languages: lang,
|
|
4857
|
-
fallbackLanguages,
|
|
4858
|
-
|
|
4859
|
-
localeFileResolver(code) {
|
|
4860
|
-
// Todo: For editing of locales, we might instead resolve all
|
|
4861
|
-
// `$ref` (as with <https://github.com/whitlockjc/json-refs>) and
|
|
4862
|
-
// replace IMF() loadLocales behavior with our own now resolved
|
|
4863
|
-
// locales; see https://github.com/jdorn/json-editor/issues/132
|
|
4864
|
-
return basePath + langData.localeFileBasePath + langs.find(l => l.code === code).locale.$ref;
|
|
4865
|
-
},
|
|
4866
|
-
|
|
4867
|
-
async callback(...args) {
|
|
4868
|
-
if (localeCallback && localeCallback(...args)) {
|
|
4869
|
-
resolve();
|
|
4870
|
-
return;
|
|
4871
|
-
}
|
|
4872
|
-
|
|
4873
|
-
await resultsCallback(...args);
|
|
4874
|
-
resolve();
|
|
4875
|
-
}
|
|
4876
|
-
|
|
4877
|
-
});
|
|
4878
|
-
});
|
|
4879
|
-
}
|
|
4880
|
-
|
|
4881
|
-
// nb. This is for IE10 and lower _only_.
|
|
4882
|
-
var supportCustomEvent = window.CustomEvent;
|
|
4883
|
-
|
|
4884
|
-
if (!supportCustomEvent || typeof supportCustomEvent === 'object') {
|
|
4885
|
-
supportCustomEvent = function CustomEvent(event, x) {
|
|
4886
|
-
x = x || {};
|
|
4887
|
-
var ev = document.createEvent('CustomEvent');
|
|
4888
|
-
ev.initCustomEvent(event, !!x.bubbles, !!x.cancelable, x.detail || null);
|
|
4889
|
-
return ev;
|
|
4890
|
-
};
|
|
4891
|
-
|
|
4892
|
-
supportCustomEvent.prototype = window.Event.prototype;
|
|
4893
|
-
}
|
|
4894
|
-
/**
|
|
4895
|
-
* Dispatches the passed event to both an "on<type>" handler as well as via the
|
|
4896
|
-
* normal dispatch operation. Does not bubble.
|
|
4897
|
-
*
|
|
4898
|
-
* @param {!EventTarget} target
|
|
4899
|
-
* @param {!Event} event
|
|
4900
|
-
* @return {boolean}
|
|
4901
|
-
*/
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
function safeDispatchEvent(target, event) {
|
|
4905
|
-
var check = 'on' + event.type.toLowerCase();
|
|
4906
|
-
|
|
4907
|
-
if (typeof target[check] === 'function') {
|
|
4908
|
-
target[check](event);
|
|
4909
|
-
}
|
|
4910
|
-
|
|
4911
|
-
return target.dispatchEvent(event);
|
|
4912
|
-
}
|
|
4913
|
-
/**
|
|
4914
|
-
* @param {Element} el to check for stacking context
|
|
4915
|
-
* @return {boolean} whether this el or its parents creates a stacking context
|
|
4916
|
-
*/
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
function createsStackingContext(el) {
|
|
4920
|
-
while (el && el !== document.body) {
|
|
4921
|
-
var s = window.getComputedStyle(el);
|
|
4922
|
-
|
|
4923
|
-
var invalid = function (k, ok) {
|
|
4924
|
-
return !(s[k] === undefined || s[k] === ok);
|
|
4925
|
-
};
|
|
4926
|
-
|
|
4927
|
-
if (s.opacity < 1 || invalid('zIndex', 'auto') || invalid('transform', 'none') || invalid('mixBlendMode', 'normal') || invalid('filter', 'none') || invalid('perspective', 'none') || s['isolation'] === 'isolate' || s.position === 'fixed' || s.webkitOverflowScrolling === 'touch') {
|
|
4928
|
-
return true;
|
|
4929
|
-
}
|
|
4930
|
-
|
|
4931
|
-
el = el.parentElement;
|
|
4932
|
-
}
|
|
4933
|
-
|
|
4934
|
-
return false;
|
|
4935
|
-
}
|
|
4936
|
-
/**
|
|
4937
|
-
* Finds the nearest <dialog> from the passed element.
|
|
4938
|
-
*
|
|
4939
|
-
* @param {Element} el to search from
|
|
4940
|
-
* @return {HTMLDialogElement} dialog found
|
|
4941
|
-
*/
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
function findNearestDialog(el) {
|
|
4945
|
-
while (el) {
|
|
4946
|
-
if (el.localName === 'dialog') {
|
|
4947
|
-
return (
|
|
4948
|
-
/** @type {HTMLDialogElement} */
|
|
4949
|
-
el
|
|
4950
|
-
);
|
|
4951
|
-
}
|
|
4952
|
-
|
|
4953
|
-
if (el.parentElement) {
|
|
4954
|
-
el = el.parentElement;
|
|
4955
|
-
} else if (el.parentNode) {
|
|
4956
|
-
el = el.parentNode.host;
|
|
4957
|
-
} else {
|
|
4958
|
-
el = null;
|
|
4959
|
-
}
|
|
4960
|
-
}
|
|
4961
|
-
|
|
4962
|
-
return null;
|
|
4963
|
-
}
|
|
4964
|
-
/**
|
|
4965
|
-
* Blur the specified element, as long as it's not the HTML body element.
|
|
4966
|
-
* This works around an IE9/10 bug - blurring the body causes Windows to
|
|
4967
|
-
* blur the whole application.
|
|
4968
|
-
*
|
|
4969
|
-
* @param {Element} el to blur
|
|
4970
|
-
*/
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
function safeBlur(el) {
|
|
4974
|
-
// Find the actual focused element when the active element is inside a shadow root
|
|
4975
|
-
while (el && el.shadowRoot && el.shadowRoot.activeElement) {
|
|
4976
|
-
el = el.shadowRoot.activeElement;
|
|
4977
|
-
}
|
|
4978
|
-
|
|
4979
|
-
if (el && el.blur && el !== document.body) {
|
|
4980
|
-
el.blur();
|
|
4981
|
-
}
|
|
4982
|
-
}
|
|
4983
|
-
/**
|
|
4984
|
-
* @param {!NodeList} nodeList to search
|
|
4985
|
-
* @param {Node} node to find
|
|
4986
|
-
* @return {boolean} whether node is inside nodeList
|
|
4987
|
-
*/
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
function inNodeList(nodeList, node) {
|
|
4991
|
-
for (var i = 0; i < nodeList.length; ++i) {
|
|
4992
|
-
if (nodeList[i] === node) {
|
|
4993
|
-
return true;
|
|
4994
|
-
}
|
|
4995
|
-
}
|
|
4996
|
-
|
|
4997
|
-
return false;
|
|
4998
|
-
}
|
|
4999
|
-
/**
|
|
5000
|
-
* @param {HTMLFormElement} el to check
|
|
5001
|
-
* @return {boolean} whether this form has method="dialog"
|
|
5002
|
-
*/
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
function isFormMethodDialog(el) {
|
|
5006
|
-
if (!el || !el.hasAttribute('method')) {
|
|
5007
|
-
return false;
|
|
5008
|
-
}
|
|
5009
|
-
|
|
5010
|
-
return el.getAttribute('method').toLowerCase() === 'dialog';
|
|
5011
|
-
}
|
|
5012
|
-
/**
|
|
5013
|
-
* @param {!DocumentFragment|!Element} hostElement
|
|
5014
|
-
* @return {?Element}
|
|
5015
|
-
*/
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
function findFocusableElementWithin(hostElement) {
|
|
5019
|
-
// Note that this is 'any focusable area'. This list is probably not exhaustive, but the
|
|
5020
|
-
// alternative involves stepping through and trying to focus everything.
|
|
5021
|
-
var opts = ['button', 'input', 'keygen', 'select', 'textarea'];
|
|
5022
|
-
var query = opts.map(function (el) {
|
|
5023
|
-
return el + ':not([disabled])';
|
|
5024
|
-
}); // TODO(samthor): tabindex values that are not numeric are not focusable.
|
|
5025
|
-
|
|
5026
|
-
query.push('[tabindex]:not([disabled]):not([tabindex=""])'); // tabindex != "", not disabled
|
|
5027
|
-
|
|
5028
|
-
var target = hostElement.querySelector(query.join(', '));
|
|
5029
|
-
|
|
5030
|
-
if (!target && 'attachShadow' in Element.prototype) {
|
|
5031
|
-
// If we haven't found a focusable target, see if the host element contains an element
|
|
5032
|
-
// which has a shadowRoot.
|
|
5033
|
-
// Recursively search for the first focusable item in shadow roots.
|
|
5034
|
-
var elems = hostElement.querySelectorAll('*');
|
|
5035
|
-
|
|
5036
|
-
for (var i = 0; i < elems.length; i++) {
|
|
5037
|
-
if (elems[i].tagName && elems[i].shadowRoot) {
|
|
5038
|
-
target = findFocusableElementWithin(elems[i].shadowRoot);
|
|
5039
|
-
|
|
5040
|
-
if (target) {
|
|
5041
|
-
break;
|
|
5042
|
-
}
|
|
5043
|
-
}
|
|
5044
|
-
}
|
|
5045
|
-
}
|
|
5046
|
-
|
|
5047
|
-
return target;
|
|
5048
|
-
}
|
|
5049
|
-
/**
|
|
5050
|
-
* Determines if an element is attached to the DOM.
|
|
5051
|
-
* @param {Element} element to check
|
|
5052
|
-
* @return {boolean} whether the element is in DOM
|
|
5053
|
-
*/
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
function isConnected(element) {
|
|
5057
|
-
return element.isConnected || document.body.contains(element);
|
|
5058
|
-
}
|
|
5059
|
-
/**
|
|
5060
|
-
* @param {!Event} event
|
|
5061
|
-
* @return {?Element}
|
|
5062
|
-
*/
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
function findFormSubmitter(event) {
|
|
5066
|
-
if (event.submitter) {
|
|
5067
|
-
return event.submitter;
|
|
5068
|
-
}
|
|
5069
|
-
|
|
5070
|
-
var form = event.target;
|
|
5071
|
-
|
|
5072
|
-
if (!(form instanceof HTMLFormElement)) {
|
|
5073
|
-
return null;
|
|
5074
|
-
}
|
|
5075
|
-
|
|
5076
|
-
var submitter = dialogPolyfill.formSubmitter;
|
|
5077
|
-
|
|
5078
|
-
if (!submitter) {
|
|
5079
|
-
var target = event.target;
|
|
5080
|
-
var root = 'getRootNode' in target && target.getRootNode() || document;
|
|
5081
|
-
submitter = root.activeElement;
|
|
5082
|
-
}
|
|
5083
|
-
|
|
5084
|
-
if (!submitter || submitter.form !== form) {
|
|
5085
|
-
return null;
|
|
5086
|
-
}
|
|
5087
|
-
|
|
5088
|
-
return submitter;
|
|
5089
|
-
}
|
|
5090
|
-
/**
|
|
5091
|
-
* @param {!Event} event
|
|
5092
|
-
*/
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
function maybeHandleSubmit(event) {
|
|
5096
|
-
if (event.defaultPrevented) {
|
|
5097
|
-
return;
|
|
5098
|
-
}
|
|
5099
|
-
|
|
5100
|
-
var form =
|
|
5101
|
-
/** @type {!HTMLFormElement} */
|
|
5102
|
-
event.target; // We'd have a value if we clicked on an imagemap.
|
|
5103
|
-
|
|
5104
|
-
var value = dialogPolyfill.imagemapUseValue;
|
|
5105
|
-
var submitter = findFormSubmitter(event);
|
|
5106
|
-
|
|
5107
|
-
if (value === null && submitter) {
|
|
5108
|
-
value = submitter.value;
|
|
5109
|
-
} // There should always be a dialog as this handler is added specifically on them, but check just
|
|
5110
|
-
// in case.
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
var dialog = findNearestDialog(form);
|
|
5114
|
-
|
|
5115
|
-
if (!dialog) {
|
|
5116
|
-
return;
|
|
5117
|
-
} // Prefer formmethod on the button.
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
var formmethod = submitter && submitter.getAttribute('formmethod') || form.getAttribute('method');
|
|
5121
|
-
|
|
5122
|
-
if (formmethod !== 'dialog') {
|
|
5123
|
-
return;
|
|
5124
|
-
}
|
|
5125
|
-
|
|
5126
|
-
event.preventDefault();
|
|
5127
|
-
|
|
5128
|
-
if (value != null) {
|
|
5129
|
-
// nb. we explicitly check against null/undefined
|
|
5130
|
-
dialog.close(value);
|
|
5131
|
-
} else {
|
|
5132
|
-
dialog.close();
|
|
5133
|
-
}
|
|
5134
|
-
}
|
|
5135
|
-
/**
|
|
5136
|
-
* @param {!HTMLDialogElement} dialog to upgrade
|
|
5137
|
-
* @constructor
|
|
5138
|
-
*/
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
function dialogPolyfillInfo(dialog) {
|
|
5142
|
-
this.dialog_ = dialog;
|
|
5143
|
-
this.replacedStyleTop_ = false;
|
|
5144
|
-
this.openAsModal_ = false; // Set a11y role. Browsers that support dialog implicitly know this already.
|
|
5145
|
-
|
|
5146
|
-
if (!dialog.hasAttribute('role')) {
|
|
5147
|
-
dialog.setAttribute('role', 'dialog');
|
|
5148
|
-
}
|
|
5149
|
-
|
|
5150
|
-
dialog.show = this.show.bind(this);
|
|
5151
|
-
dialog.showModal = this.showModal.bind(this);
|
|
5152
|
-
dialog.close = this.close.bind(this);
|
|
5153
|
-
dialog.addEventListener('submit', maybeHandleSubmit, false);
|
|
5154
|
-
|
|
5155
|
-
if (!('returnValue' in dialog)) {
|
|
5156
|
-
dialog.returnValue = '';
|
|
5157
|
-
}
|
|
5158
|
-
|
|
5159
|
-
if ('MutationObserver' in window) {
|
|
5160
|
-
var mo = new MutationObserver(this.maybeHideModal.bind(this));
|
|
5161
|
-
mo.observe(dialog, {
|
|
5162
|
-
attributes: true,
|
|
5163
|
-
attributeFilter: ['open']
|
|
5164
|
-
});
|
|
5165
|
-
} else {
|
|
5166
|
-
// IE10 and below support. Note that DOMNodeRemoved etc fire _before_ removal. They also
|
|
5167
|
-
// seem to fire even if the element was removed as part of a parent removal. Use the removed
|
|
5168
|
-
// events to force downgrade (useful if removed/immediately added).
|
|
5169
|
-
var removed = false;
|
|
5170
|
-
|
|
5171
|
-
var cb = function () {
|
|
5172
|
-
removed ? this.downgradeModal() : this.maybeHideModal();
|
|
5173
|
-
removed = false;
|
|
5174
|
-
}.bind(this);
|
|
5175
|
-
|
|
5176
|
-
var timeout;
|
|
5177
|
-
|
|
5178
|
-
var delayModel = function (ev) {
|
|
5179
|
-
if (ev.target !== dialog) {
|
|
5180
|
-
return;
|
|
5181
|
-
} // not for a child element
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
var cand = 'DOMNodeRemoved';
|
|
5185
|
-
removed |= ev.type.substr(0, cand.length) === cand;
|
|
5186
|
-
window.clearTimeout(timeout);
|
|
5187
|
-
timeout = window.setTimeout(cb, 0);
|
|
5188
|
-
};
|
|
5189
|
-
|
|
5190
|
-
['DOMAttrModified', 'DOMNodeRemoved', 'DOMNodeRemovedFromDocument'].forEach(function (name) {
|
|
5191
|
-
dialog.addEventListener(name, delayModel);
|
|
5192
|
-
});
|
|
5193
|
-
} // Note that the DOM is observed inside DialogManager while any dialog
|
|
5194
|
-
// is being displayed as a modal, to catch modal removal from the DOM.
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
Object.defineProperty(dialog, 'open', {
|
|
5198
|
-
set: this.setOpen.bind(this),
|
|
5199
|
-
get: dialog.hasAttribute.bind(dialog, 'open')
|
|
5200
|
-
});
|
|
5201
|
-
this.backdrop_ = document.createElement('div');
|
|
5202
|
-
this.backdrop_.className = 'backdrop';
|
|
5203
|
-
this.backdrop_.addEventListener('mouseup', this.backdropMouseEvent_.bind(this));
|
|
5204
|
-
this.backdrop_.addEventListener('mousedown', this.backdropMouseEvent_.bind(this));
|
|
5205
|
-
this.backdrop_.addEventListener('click', this.backdropMouseEvent_.bind(this));
|
|
5206
|
-
}
|
|
5207
|
-
|
|
5208
|
-
dialogPolyfillInfo.prototype =
|
|
5209
|
-
/** @type {HTMLDialogElement.prototype} */
|
|
5210
|
-
{
|
|
5211
|
-
get dialog() {
|
|
5212
|
-
return this.dialog_;
|
|
5213
|
-
},
|
|
5214
|
-
|
|
5215
|
-
/**
|
|
5216
|
-
* Maybe remove this dialog from the modal top layer. This is called when
|
|
5217
|
-
* a modal dialog may no longer be tenable, e.g., when the dialog is no
|
|
5218
|
-
* longer open or is no longer part of the DOM.
|
|
5219
|
-
*/
|
|
5220
|
-
maybeHideModal: function () {
|
|
5221
|
-
if (this.dialog_.hasAttribute('open') && isConnected(this.dialog_)) {
|
|
5222
|
-
return;
|
|
5223
|
-
}
|
|
5224
|
-
|
|
5225
|
-
this.downgradeModal();
|
|
5226
|
-
},
|
|
5227
|
-
|
|
5228
|
-
/**
|
|
5229
|
-
* Remove this dialog from the modal top layer, leaving it as a non-modal.
|
|
5230
|
-
*/
|
|
5231
|
-
downgradeModal: function () {
|
|
5232
|
-
if (!this.openAsModal_) {
|
|
5233
|
-
return;
|
|
5234
|
-
}
|
|
5235
|
-
|
|
5236
|
-
this.openAsModal_ = false;
|
|
5237
|
-
this.dialog_.style.zIndex = ''; // This won't match the native <dialog> exactly because if the user set top on a centered
|
|
5238
|
-
// polyfill dialog, that top gets thrown away when the dialog is closed. Not sure it's
|
|
5239
|
-
// possible to polyfill this perfectly.
|
|
5240
|
-
|
|
5241
|
-
if (this.replacedStyleTop_) {
|
|
5242
|
-
this.dialog_.style.top = '';
|
|
5243
|
-
this.replacedStyleTop_ = false;
|
|
5244
|
-
} // Clear the backdrop and remove from the manager.
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
this.backdrop_.parentNode && this.backdrop_.parentNode.removeChild(this.backdrop_);
|
|
5248
|
-
dialogPolyfill.dm.removeDialog(this);
|
|
5249
|
-
},
|
|
5250
|
-
|
|
5251
|
-
/**
|
|
5252
|
-
* @param {boolean} value whether to open or close this dialog
|
|
5253
|
-
*/
|
|
5254
|
-
setOpen: function (value) {
|
|
5255
|
-
if (value) {
|
|
5256
|
-
this.dialog_.hasAttribute('open') || this.dialog_.setAttribute('open', '');
|
|
5257
|
-
} else {
|
|
5258
|
-
this.dialog_.removeAttribute('open');
|
|
5259
|
-
this.maybeHideModal(); // nb. redundant with MutationObserver
|
|
5260
|
-
}
|
|
5261
|
-
},
|
|
5262
|
-
|
|
5263
|
-
/**
|
|
5264
|
-
* Handles mouse events ('mouseup', 'mousedown', 'click') on the fake .backdrop element, redirecting them as if
|
|
5265
|
-
* they were on the dialog itself.
|
|
5266
|
-
*
|
|
5267
|
-
* @param {!Event} e to redirect
|
|
5268
|
-
*/
|
|
5269
|
-
backdropMouseEvent_: function (e) {
|
|
5270
|
-
if (!this.dialog_.hasAttribute('tabindex')) {
|
|
5271
|
-
// Clicking on the backdrop should move the implicit cursor, even if dialog cannot be
|
|
5272
|
-
// focused. Create a fake thing to focus on. If the backdrop was _before_ the dialog, this
|
|
5273
|
-
// would not be needed - clicks would move the implicit cursor there.
|
|
5274
|
-
var fake = document.createElement('div');
|
|
5275
|
-
this.dialog_.insertBefore(fake, this.dialog_.firstChild);
|
|
5276
|
-
fake.tabIndex = -1;
|
|
5277
|
-
fake.focus();
|
|
5278
|
-
this.dialog_.removeChild(fake);
|
|
5279
|
-
} else {
|
|
5280
|
-
this.dialog_.focus();
|
|
5281
|
-
}
|
|
5282
|
-
|
|
5283
|
-
var redirectedEvent = document.createEvent('MouseEvents');
|
|
5284
|
-
redirectedEvent.initMouseEvent(e.type, e.bubbles, e.cancelable, window, e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);
|
|
5285
|
-
this.dialog_.dispatchEvent(redirectedEvent);
|
|
5286
|
-
e.stopPropagation();
|
|
5287
|
-
},
|
|
5288
|
-
|
|
5289
|
-
/**
|
|
5290
|
-
* Focuses on the first focusable element within the dialog. This will always blur the current
|
|
5291
|
-
* focus, even if nothing within the dialog is found.
|
|
5292
|
-
*/
|
|
5293
|
-
focus_: function () {
|
|
5294
|
-
// Find element with `autofocus` attribute, or fall back to the first form/tabindex control.
|
|
5295
|
-
var target = this.dialog_.querySelector('[autofocus]:not([disabled])');
|
|
5296
|
-
|
|
5297
|
-
if (!target && this.dialog_.tabIndex >= 0) {
|
|
5298
|
-
target = this.dialog_;
|
|
5299
|
-
}
|
|
5300
|
-
|
|
5301
|
-
if (!target) {
|
|
5302
|
-
target = findFocusableElementWithin(this.dialog_);
|
|
5303
|
-
}
|
|
5304
|
-
|
|
5305
|
-
safeBlur(document.activeElement);
|
|
5306
|
-
target && target.focus();
|
|
5307
|
-
},
|
|
5308
|
-
|
|
5309
|
-
/**
|
|
5310
|
-
* Sets the zIndex for the backdrop and dialog.
|
|
5311
|
-
*
|
|
5312
|
-
* @param {number} dialogZ
|
|
5313
|
-
* @param {number} backdropZ
|
|
5314
|
-
*/
|
|
5315
|
-
updateZIndex: function (dialogZ, backdropZ) {
|
|
5316
|
-
if (dialogZ < backdropZ) {
|
|
5317
|
-
throw new Error('dialogZ should never be < backdropZ');
|
|
5318
|
-
}
|
|
5319
|
-
|
|
5320
|
-
this.dialog_.style.zIndex = dialogZ;
|
|
5321
|
-
this.backdrop_.style.zIndex = backdropZ;
|
|
5322
|
-
},
|
|
5323
|
-
|
|
5324
|
-
/**
|
|
5325
|
-
* Shows the dialog. If the dialog is already open, this does nothing.
|
|
5326
|
-
*/
|
|
5327
|
-
show: function () {
|
|
5328
|
-
if (!this.dialog_.open) {
|
|
5329
|
-
this.setOpen(true);
|
|
5330
|
-
this.focus_();
|
|
5331
|
-
}
|
|
5332
|
-
},
|
|
5333
|
-
|
|
5334
|
-
/**
|
|
5335
|
-
* Show this dialog modally.
|
|
5336
|
-
*/
|
|
5337
|
-
showModal: function () {
|
|
5338
|
-
if (this.dialog_.hasAttribute('open')) {
|
|
5339
|
-
throw new Error('Failed to execute \'showModal\' on dialog: The element is already open, and therefore cannot be opened modally.');
|
|
5340
|
-
}
|
|
5341
|
-
|
|
5342
|
-
if (!isConnected(this.dialog_)) {
|
|
5343
|
-
throw new Error('Failed to execute \'showModal\' on dialog: The element is not in a Document.');
|
|
5344
|
-
}
|
|
5345
|
-
|
|
5346
|
-
if (!dialogPolyfill.dm.pushDialog(this)) {
|
|
5347
|
-
throw new Error('Failed to execute \'showModal\' on dialog: There are too many open modal dialogs.');
|
|
5348
|
-
}
|
|
5349
|
-
|
|
5350
|
-
if (createsStackingContext(this.dialog_.parentElement)) {
|
|
5351
|
-
console.warn('A dialog is being shown inside a stacking context. ' + 'This may cause it to be unusable. For more information, see this link: ' + 'https://github.com/GoogleChrome/dialog-polyfill/#stacking-context');
|
|
5352
|
-
}
|
|
5353
|
-
|
|
5354
|
-
this.setOpen(true);
|
|
5355
|
-
this.openAsModal_ = true; // Optionally center vertically, relative to the current viewport.
|
|
5356
|
-
|
|
5357
|
-
if (dialogPolyfill.needsCentering(this.dialog_)) {
|
|
5358
|
-
dialogPolyfill.reposition(this.dialog_);
|
|
5359
|
-
this.replacedStyleTop_ = true;
|
|
5360
|
-
} else {
|
|
5361
|
-
this.replacedStyleTop_ = false;
|
|
5362
|
-
} // Insert backdrop.
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
this.dialog_.parentNode.insertBefore(this.backdrop_, this.dialog_.nextSibling); // Focus on whatever inside the dialog.
|
|
5366
|
-
|
|
5367
|
-
this.focus_();
|
|
5368
|
-
},
|
|
5369
|
-
|
|
5370
|
-
/**
|
|
5371
|
-
* Closes this HTMLDialogElement. This is optional vs clearing the open
|
|
5372
|
-
* attribute, however this fires a 'close' event.
|
|
5373
|
-
*
|
|
5374
|
-
* @param {string=} opt_returnValue to use as the returnValue
|
|
5375
|
-
*/
|
|
5376
|
-
close: function (opt_returnValue) {
|
|
5377
|
-
if (!this.dialog_.hasAttribute('open')) {
|
|
5378
|
-
throw new Error('Failed to execute \'close\' on dialog: The element does not have an \'open\' attribute, and therefore cannot be closed.');
|
|
5379
|
-
}
|
|
5380
|
-
|
|
5381
|
-
this.setOpen(false); // Leave returnValue untouched in case it was set directly on the element
|
|
5382
|
-
|
|
5383
|
-
if (opt_returnValue !== undefined) {
|
|
5384
|
-
this.dialog_.returnValue = opt_returnValue;
|
|
5385
|
-
} // Triggering "close" event for any attached listeners on the <dialog>.
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
var closeEvent = new supportCustomEvent('close', {
|
|
5389
|
-
bubbles: false,
|
|
5390
|
-
cancelable: false
|
|
5391
|
-
});
|
|
5392
|
-
safeDispatchEvent(this.dialog_, closeEvent);
|
|
5393
|
-
}
|
|
5394
|
-
};
|
|
5395
|
-
var dialogPolyfill = {};
|
|
5396
|
-
|
|
5397
|
-
dialogPolyfill.reposition = function (element) {
|
|
5398
|
-
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
|
|
5399
|
-
var topValue = scrollTop + (window.innerHeight - element.offsetHeight) / 2;
|
|
5400
|
-
element.style.top = Math.max(scrollTop, topValue) + 'px';
|
|
5401
|
-
};
|
|
5402
|
-
|
|
5403
|
-
dialogPolyfill.isInlinePositionSetByStylesheet = function (element) {
|
|
5404
|
-
for (var i = 0; i < document.styleSheets.length; ++i) {
|
|
5405
|
-
var styleSheet = document.styleSheets[i];
|
|
5406
|
-
var cssRules = null; // Some browsers throw on cssRules.
|
|
5407
|
-
|
|
5408
|
-
try {
|
|
5409
|
-
cssRules = styleSheet.cssRules;
|
|
5410
|
-
} catch (e) {}
|
|
5411
|
-
|
|
5412
|
-
if (!cssRules) {
|
|
5413
|
-
continue;
|
|
5414
|
-
}
|
|
5415
|
-
|
|
5416
|
-
for (var j = 0; j < cssRules.length; ++j) {
|
|
5417
|
-
var rule = cssRules[j];
|
|
5418
|
-
var selectedNodes = null; // Ignore errors on invalid selector texts.
|
|
5419
|
-
|
|
5420
|
-
try {
|
|
5421
|
-
selectedNodes = document.querySelectorAll(rule.selectorText);
|
|
5422
|
-
} catch (e) {}
|
|
5423
|
-
|
|
5424
|
-
if (!selectedNodes || !inNodeList(selectedNodes, element)) {
|
|
5425
|
-
continue;
|
|
5426
|
-
}
|
|
5427
|
-
|
|
5428
|
-
var cssTop = rule.style.getPropertyValue('top');
|
|
5429
|
-
var cssBottom = rule.style.getPropertyValue('bottom');
|
|
5430
|
-
|
|
5431
|
-
if (cssTop && cssTop !== 'auto' || cssBottom && cssBottom !== 'auto') {
|
|
5432
|
-
return true;
|
|
5433
|
-
}
|
|
5434
|
-
}
|
|
5435
|
-
}
|
|
5436
|
-
|
|
5437
|
-
return false;
|
|
5438
|
-
};
|
|
5439
|
-
|
|
5440
|
-
dialogPolyfill.needsCentering = function (dialog) {
|
|
5441
|
-
var computedStyle = window.getComputedStyle(dialog);
|
|
5442
|
-
|
|
5443
|
-
if (computedStyle.position !== 'absolute') {
|
|
5444
|
-
return false;
|
|
5445
|
-
} // We must determine whether the top/bottom specified value is non-auto. In
|
|
5446
|
-
// WebKit/Blink, checking computedStyle.top == 'auto' is sufficient, but
|
|
5447
|
-
// Firefox returns the used value. So we do this crazy thing instead: check
|
|
5448
|
-
// the inline style and then go through CSS rules.
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
if (dialog.style.top !== 'auto' && dialog.style.top !== '' || dialog.style.bottom !== 'auto' && dialog.style.bottom !== '') {
|
|
5452
|
-
return false;
|
|
5453
|
-
}
|
|
5454
|
-
|
|
5455
|
-
return !dialogPolyfill.isInlinePositionSetByStylesheet(dialog);
|
|
5456
|
-
};
|
|
5457
|
-
/**
|
|
5458
|
-
* @param {!Element} element to force upgrade
|
|
5459
|
-
*/
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
dialogPolyfill.forceRegisterDialog = function (element) {
|
|
5463
|
-
if (window.HTMLDialogElement || element.showModal) {
|
|
5464
|
-
console.warn('This browser already supports <dialog>, the polyfill ' + 'may not work correctly', element);
|
|
5465
|
-
}
|
|
5466
|
-
|
|
5467
|
-
if (element.localName !== 'dialog') {
|
|
5468
|
-
throw new Error('Failed to register dialog: The element is not a dialog.');
|
|
5469
|
-
}
|
|
5470
|
-
|
|
5471
|
-
new dialogPolyfillInfo(
|
|
5472
|
-
/** @type {!HTMLDialogElement} */
|
|
5473
|
-
element);
|
|
5474
|
-
};
|
|
5475
|
-
/**
|
|
5476
|
-
* @param {!Element} element to upgrade, if necessary
|
|
5477
|
-
*/
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
dialogPolyfill.registerDialog = function (element) {
|
|
5481
|
-
if (!element.showModal) {
|
|
5482
|
-
dialogPolyfill.forceRegisterDialog(element);
|
|
5483
|
-
}
|
|
5484
|
-
};
|
|
5485
|
-
/**
|
|
5486
|
-
* @constructor
|
|
5487
|
-
*/
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
dialogPolyfill.DialogManager = function () {
|
|
5491
|
-
/** @type {!Array<!dialogPolyfillInfo>} */
|
|
5492
|
-
this.pendingDialogStack = [];
|
|
5493
|
-
var checkDOM = this.checkDOM_.bind(this); // The overlay is used to simulate how a modal dialog blocks the document.
|
|
5494
|
-
// The blocking dialog is positioned on top of the overlay, and the rest of
|
|
5495
|
-
// the dialogs on the pending dialog stack are positioned below it. In the
|
|
5496
|
-
// actual implementation, the modal dialog stacking is controlled by the
|
|
5497
|
-
// top layer, where z-index has no effect.
|
|
5498
|
-
|
|
5499
|
-
this.overlay = document.createElement('div');
|
|
5500
|
-
this.overlay.className = '_dialog_overlay';
|
|
5501
|
-
this.overlay.addEventListener('click', function (e) {
|
|
5502
|
-
this.forwardTab_ = undefined;
|
|
5503
|
-
e.stopPropagation();
|
|
5504
|
-
checkDOM([]); // sanity-check DOM
|
|
5505
|
-
}.bind(this));
|
|
5506
|
-
this.handleKey_ = this.handleKey_.bind(this);
|
|
5507
|
-
this.handleFocus_ = this.handleFocus_.bind(this);
|
|
5508
|
-
this.zIndexLow_ = 100000;
|
|
5509
|
-
this.zIndexHigh_ = 100000 + 150;
|
|
5510
|
-
this.forwardTab_ = undefined;
|
|
5511
|
-
|
|
5512
|
-
if ('MutationObserver' in window) {
|
|
5513
|
-
this.mo_ = new MutationObserver(function (records) {
|
|
5514
|
-
var removed = [];
|
|
5515
|
-
records.forEach(function (rec) {
|
|
5516
|
-
for (var i = 0, c; c = rec.removedNodes[i]; ++i) {
|
|
5517
|
-
if (!(c instanceof Element)) {
|
|
5518
|
-
continue;
|
|
5519
|
-
} else if (c.localName === 'dialog') {
|
|
5520
|
-
removed.push(c);
|
|
5521
|
-
}
|
|
5522
|
-
|
|
5523
|
-
removed = removed.concat(c.querySelectorAll('dialog'));
|
|
5524
|
-
}
|
|
5525
|
-
});
|
|
5526
|
-
removed.length && checkDOM(removed);
|
|
5527
|
-
});
|
|
5528
|
-
}
|
|
5529
|
-
};
|
|
5530
|
-
/**
|
|
5531
|
-
* Called on the first modal dialog being shown. Adds the overlay and related
|
|
5532
|
-
* handlers.
|
|
5533
|
-
*/
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
dialogPolyfill.DialogManager.prototype.blockDocument = function () {
|
|
5537
|
-
document.documentElement.addEventListener('focus', this.handleFocus_, true);
|
|
5538
|
-
document.addEventListener('keydown', this.handleKey_);
|
|
5539
|
-
this.mo_ && this.mo_.observe(document, {
|
|
5540
|
-
childList: true,
|
|
5541
|
-
subtree: true
|
|
5542
|
-
});
|
|
5543
|
-
};
|
|
5544
|
-
/**
|
|
5545
|
-
* Called on the first modal dialog being removed, i.e., when no more modal
|
|
5546
|
-
* dialogs are visible.
|
|
5547
|
-
*/
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
dialogPolyfill.DialogManager.prototype.unblockDocument = function () {
|
|
5551
|
-
document.documentElement.removeEventListener('focus', this.handleFocus_, true);
|
|
5552
|
-
document.removeEventListener('keydown', this.handleKey_);
|
|
5553
|
-
this.mo_ && this.mo_.disconnect();
|
|
5554
|
-
};
|
|
5555
|
-
/**
|
|
5556
|
-
* Updates the stacking of all known dialogs.
|
|
5557
|
-
*/
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
dialogPolyfill.DialogManager.prototype.updateStacking = function () {
|
|
5561
|
-
var zIndex = this.zIndexHigh_;
|
|
5562
|
-
|
|
5563
|
-
for (var i = 0, dpi; dpi = this.pendingDialogStack[i]; ++i) {
|
|
5564
|
-
dpi.updateZIndex(--zIndex, --zIndex);
|
|
5565
|
-
|
|
5566
|
-
if (i === 0) {
|
|
5567
|
-
this.overlay.style.zIndex = --zIndex;
|
|
5568
|
-
}
|
|
5569
|
-
} // Make the overlay a sibling of the dialog itself.
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
var last = this.pendingDialogStack[0];
|
|
5573
|
-
|
|
5574
|
-
if (last) {
|
|
5575
|
-
var p = last.dialog.parentNode || document.body;
|
|
5576
|
-
p.appendChild(this.overlay);
|
|
5577
|
-
} else if (this.overlay.parentNode) {
|
|
5578
|
-
this.overlay.parentNode.removeChild(this.overlay);
|
|
5579
|
-
}
|
|
5580
|
-
};
|
|
5581
|
-
/**
|
|
5582
|
-
* @param {Element} candidate to check if contained or is the top-most modal dialog
|
|
5583
|
-
* @return {boolean} whether candidate is contained in top dialog
|
|
5584
|
-
*/
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
dialogPolyfill.DialogManager.prototype.containedByTopDialog_ = function (candidate) {
|
|
5588
|
-
while (candidate = findNearestDialog(candidate)) {
|
|
5589
|
-
for (var i = 0, dpi; dpi = this.pendingDialogStack[i]; ++i) {
|
|
5590
|
-
if (dpi.dialog === candidate) {
|
|
5591
|
-
return i === 0; // only valid if top-most
|
|
5592
|
-
}
|
|
5593
|
-
}
|
|
5594
|
-
|
|
5595
|
-
candidate = candidate.parentElement;
|
|
5596
|
-
}
|
|
5597
|
-
|
|
5598
|
-
return false;
|
|
5599
|
-
};
|
|
5600
|
-
|
|
5601
|
-
dialogPolyfill.DialogManager.prototype.handleFocus_ = function (event) {
|
|
5602
|
-
var target = event.composedPath ? event.composedPath()[0] : event.target;
|
|
5603
|
-
|
|
5604
|
-
if (this.containedByTopDialog_(target)) {
|
|
5605
|
-
return;
|
|
5606
|
-
}
|
|
5607
|
-
|
|
5608
|
-
if (document.activeElement === document.documentElement) {
|
|
5609
|
-
return;
|
|
5610
|
-
}
|
|
5611
|
-
|
|
5612
|
-
event.preventDefault();
|
|
5613
|
-
event.stopPropagation();
|
|
5614
|
-
safeBlur(
|
|
5615
|
-
/** @type {Element} */
|
|
5616
|
-
target);
|
|
5617
|
-
|
|
5618
|
-
if (this.forwardTab_ === undefined) {
|
|
5619
|
-
return;
|
|
5620
|
-
} // move focus only from a tab key
|
|
4573
|
+
var key = keys.shift();
|
|
4574
|
+
var between = key.match(/^\[(.+?)]$/);
|
|
5621
4575
|
|
|
4576
|
+
if (key === '[]') {
|
|
4577
|
+
result = result || [];
|
|
5622
4578
|
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
4579
|
+
if (Array.isArray(result)) {
|
|
4580
|
+
result.push(hashAssign(null, keys, value));
|
|
4581
|
+
} else {
|
|
4582
|
+
// This might be the result of bad name attributes like "[][foo]",
|
|
4583
|
+
// in this case the original `result` object will already be
|
|
4584
|
+
// assigned to an object literal. Rather than coerce the object to
|
|
4585
|
+
// an array, or cause an exception the attribute "_values" is
|
|
4586
|
+
// assigned as an array.
|
|
4587
|
+
result._values = result._values || [];
|
|
5626
4588
|
|
|
5627
|
-
|
|
5628
|
-
if (this.forwardTab_) {
|
|
5629
|
-
// forward
|
|
5630
|
-
dpi.focus_();
|
|
5631
|
-
} else if (target !== document.documentElement) {
|
|
5632
|
-
// backwards if we're not already focused on <html>
|
|
5633
|
-
document.documentElement.focus();
|
|
4589
|
+
result._values.push(hashAssign(null, keys, value));
|
|
5634
4590
|
}
|
|
5635
|
-
}
|
|
5636
|
-
|
|
5637
|
-
return false;
|
|
5638
|
-
};
|
|
5639
4591
|
|
|
5640
|
-
|
|
5641
|
-
|
|
4592
|
+
return result;
|
|
4593
|
+
} // Key is an attribute name and can be assigned directly.
|
|
5642
4594
|
|
|
5643
|
-
if (event.keyCode === 27) {
|
|
5644
|
-
event.preventDefault();
|
|
5645
|
-
event.stopPropagation();
|
|
5646
|
-
var cancelEvent = new supportCustomEvent('cancel', {
|
|
5647
|
-
bubbles: false,
|
|
5648
|
-
cancelable: true
|
|
5649
|
-
});
|
|
5650
|
-
var dpi = this.pendingDialogStack[0];
|
|
5651
4595
|
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
};
|
|
5659
|
-
/**
|
|
5660
|
-
* Finds and downgrades any known modal dialogs that are no longer displayed. Dialogs that are
|
|
5661
|
-
* removed and immediately readded don't stay modal, they become normal.
|
|
5662
|
-
*
|
|
5663
|
-
* @param {!Array<!HTMLDialogElement>} removed that have definitely been removed
|
|
5664
|
-
*/
|
|
4596
|
+
if (!between) {
|
|
4597
|
+
result[key] = hashAssign(result[key], keys, value);
|
|
4598
|
+
} else {
|
|
4599
|
+
var string = between[1]; // +var converts the variable into a number
|
|
4600
|
+
// better than parseInt because it doesn't truncate away trailing
|
|
4601
|
+
// letters and actually fails if whole thing is not a number
|
|
5665
4602
|
|
|
4603
|
+
var index = Number(string); // If the characters between the brackets is not a number it is an
|
|
4604
|
+
// attribute name and can be assigned directly.
|
|
4605
|
+
// Switching to Number.isNaN would require a polyfill for IE11
|
|
4606
|
+
// eslint-disable-next-line unicorn/prefer-number-properties
|
|
5666
4607
|
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
// at a time?!
|
|
5671
|
-
var clone = this.pendingDialogStack.slice();
|
|
5672
|
-
clone.forEach(function (dpi) {
|
|
5673
|
-
if (removed.indexOf(dpi.dialog) !== -1) {
|
|
5674
|
-
dpi.downgradeModal();
|
|
4608
|
+
if (isNaN(index)) {
|
|
4609
|
+
result = result || {};
|
|
4610
|
+
result[string] = hashAssign(result[string], keys, value);
|
|
5675
4611
|
} else {
|
|
5676
|
-
|
|
4612
|
+
result = result || [];
|
|
4613
|
+
result[index] = hashAssign(result[index], keys, value);
|
|
5677
4614
|
}
|
|
5678
|
-
}
|
|
5679
|
-
|
|
4615
|
+
}
|
|
4616
|
+
|
|
4617
|
+
return result;
|
|
4618
|
+
}
|
|
5680
4619
|
/**
|
|
5681
|
-
*
|
|
5682
|
-
* @
|
|
4620
|
+
* Object/hash encoding serializer.
|
|
4621
|
+
* @param {PlainObject} result
|
|
4622
|
+
* @param {string} key
|
|
4623
|
+
* @param {string} value
|
|
4624
|
+
* @returns {PlainObject}
|
|
5683
4625
|
*/
|
|
5684
4626
|
|
|
5685
4627
|
|
|
5686
|
-
|
|
5687
|
-
var
|
|
4628
|
+
function hashSerializer(result, key, value) {
|
|
4629
|
+
var hasBrackets = key.match(brackets); // Has brackets? Use the recursive assignment function to walk the keys,
|
|
4630
|
+
// construct any missing objects in the result tree and make the assignment
|
|
4631
|
+
// at the end of the chain.
|
|
5688
4632
|
|
|
5689
|
-
if (
|
|
5690
|
-
|
|
5691
|
-
|
|
4633
|
+
if (hasBrackets) {
|
|
4634
|
+
var keys = parseKeys(key);
|
|
4635
|
+
hashAssign(result, keys, value);
|
|
4636
|
+
} else {
|
|
4637
|
+
// Non bracket notation can make assignments directly.
|
|
4638
|
+
var existing = result[key]; // If the value has been assigned already (for instance when a radio and
|
|
4639
|
+
// a checkbox have the same name attribute) convert the previous value
|
|
4640
|
+
// into an array before pushing into it.
|
|
4641
|
+
//
|
|
4642
|
+
// NOTE: If this requirement were removed all hash creation and
|
|
4643
|
+
// assignment could go through `hashAssign`.
|
|
4644
|
+
|
|
4645
|
+
if (existing) {
|
|
4646
|
+
if (!Array.isArray(existing)) {
|
|
4647
|
+
result[key] = [existing];
|
|
4648
|
+
}
|
|
5692
4649
|
|
|
5693
|
-
|
|
5694
|
-
|
|
4650
|
+
result[key].push(value);
|
|
4651
|
+
} else {
|
|
4652
|
+
result[key] = value;
|
|
4653
|
+
}
|
|
5695
4654
|
}
|
|
5696
4655
|
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
};
|
|
4656
|
+
return result;
|
|
4657
|
+
}
|
|
5700
4658
|
/**
|
|
5701
|
-
*
|
|
4659
|
+
* URL form encoding serializer.
|
|
4660
|
+
* @param {string} result
|
|
4661
|
+
* @param {string} key
|
|
4662
|
+
* @param {string} value
|
|
4663
|
+
* @returns {string} New result
|
|
5702
4664
|
*/
|
|
5703
4665
|
|
|
5704
4666
|
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
return;
|
|
5710
|
-
}
|
|
5711
|
-
|
|
5712
|
-
this.pendingDialogStack.splice(index, 1);
|
|
5713
|
-
|
|
5714
|
-
if (this.pendingDialogStack.length === 0) {
|
|
5715
|
-
this.unblockDocument();
|
|
5716
|
-
}
|
|
5717
|
-
|
|
5718
|
-
this.updateStacking();
|
|
5719
|
-
};
|
|
4667
|
+
function strSerialize(result, key, value) {
|
|
4668
|
+
// encode newlines as \r\n cause the html spec says so
|
|
4669
|
+
value = value.replace(/(\r)?\n/g, '\r\n');
|
|
4670
|
+
value = encodeURIComponent(value); // spaces should be '+' rather than '%20'.
|
|
5720
4671
|
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
4672
|
+
value = value.replace(/%20/g, '+');
|
|
4673
|
+
return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + value;
|
|
4674
|
+
}
|
|
5724
4675
|
/**
|
|
5725
|
-
*
|
|
5726
|
-
*
|
|
4676
|
+
* @function module:FormSerialization.deserialize
|
|
4677
|
+
* @param {HTMLFormElement} form
|
|
4678
|
+
* @param {PlainObject} hash
|
|
4679
|
+
* @returns {void}
|
|
5727
4680
|
*/
|
|
5728
4681
|
|
|
5729
|
-
if (window.HTMLDialogElement === undefined) {
|
|
5730
|
-
/**
|
|
5731
|
-
* If HTMLFormElement translates method="DIALOG" into 'get', then replace the descriptor with
|
|
5732
|
-
* one that returns the correct value.
|
|
5733
|
-
*/
|
|
5734
|
-
var testForm = document.createElement('form');
|
|
5735
|
-
testForm.setAttribute('method', 'dialog');
|
|
5736
4682
|
|
|
5737
|
-
|
|
5738
|
-
|
|
4683
|
+
function deserialize(form, hash) {
|
|
4684
|
+
// input(text|radio|checkbox)|select(multiple)|textarea|keygen
|
|
4685
|
+
Object.entries(hash).forEach(function (_ref3) {
|
|
4686
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
4687
|
+
name = _ref4[0],
|
|
4688
|
+
value = _ref4[1];
|
|
5739
4689
|
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
// and don't bother to update the element.
|
|
5743
|
-
var realGet = methodDescriptor.get;
|
|
4690
|
+
var control = form[name];
|
|
4691
|
+
var hasBrackets = false; // istanbul ignore else
|
|
5744
4692
|
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
}
|
|
4693
|
+
if (!control) {
|
|
4694
|
+
// Try again for jsdom
|
|
4695
|
+
control = form.querySelector("[name=\"".concat(name, "\"]"));
|
|
5749
4696
|
|
|
5750
|
-
|
|
5751
|
-
|
|
4697
|
+
if (!control) {
|
|
4698
|
+
// We want this for `RadioNodeList` so setting value
|
|
4699
|
+
// auto-disables other boxes
|
|
4700
|
+
control = form[name + '[]']; // istanbul ignore next
|
|
5752
4701
|
|
|
5753
|
-
|
|
5754
|
-
|
|
4702
|
+
if (!control || _typeof(control) !== 'object' || !('length' in control)) {
|
|
4703
|
+
// The latter query would only get a single
|
|
4704
|
+
// element, so if not a `RadioNodeList`, we get
|
|
4705
|
+
// all values here
|
|
4706
|
+
control = form.querySelectorAll("[name=\"".concat(name, "[]\"]"));
|
|
5755
4707
|
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
4708
|
+
if (!control.length) {
|
|
4709
|
+
throw new Error("Name not found ".concat(name));
|
|
4710
|
+
}
|
|
5759
4711
|
}
|
|
5760
4712
|
|
|
5761
|
-
|
|
5762
|
-
}
|
|
5763
|
-
|
|
5764
|
-
Object.defineProperty(HTMLFormElement.prototype, 'method', methodDescriptor);
|
|
4713
|
+
hasBrackets = true;
|
|
4714
|
+
}
|
|
5765
4715
|
}
|
|
5766
|
-
}
|
|
5767
|
-
/**
|
|
5768
|
-
* Global 'click' handler, to capture the <input type="submit"> or <button> element which has
|
|
5769
|
-
* submitted a <form method="dialog">. Needed as Safari and others don't report this inside
|
|
5770
|
-
* document.activeElement.
|
|
5771
|
-
*/
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
document.addEventListener('click', function (ev) {
|
|
5775
|
-
dialogPolyfill.formSubmitter = null;
|
|
5776
|
-
dialogPolyfill.imagemapUseValue = null;
|
|
5777
|
-
|
|
5778
|
-
if (ev.defaultPrevented) {
|
|
5779
|
-
return;
|
|
5780
|
-
} // e.g. a submit which prevents default submission
|
|
5781
4716
|
|
|
4717
|
+
var _control = control,
|
|
4718
|
+
type = _control.type;
|
|
5782
4719
|
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
4720
|
+
if (type === 'checkbox') {
|
|
4721
|
+
control.checked = value !== '';
|
|
4722
|
+
}
|
|
5786
4723
|
|
|
5787
|
-
if ('
|
|
5788
|
-
|
|
5789
|
-
|
|
4724
|
+
if (type === 'radio' || control[0] && control[0].type === 'radio') {
|
|
4725
|
+
_toConsumableArray(form.querySelectorAll("[name=\"".concat(name + (hasBrackets ? '[]' : ''), "\"]"))).forEach(function (radio) {
|
|
4726
|
+
radio.checked = value === radio.value;
|
|
4727
|
+
});
|
|
5790
4728
|
}
|
|
5791
4729
|
|
|
5792
|
-
if (
|
|
4730
|
+
if (control[0] && control[0].type === 'select-multiple') {
|
|
4731
|
+
_toConsumableArray(control[0].options).forEach(function (o) {
|
|
4732
|
+
if (value.includes(o.value)) {
|
|
4733
|
+
o.selected = true;
|
|
4734
|
+
}
|
|
4735
|
+
});
|
|
4736
|
+
|
|
5793
4737
|
return;
|
|
5794
4738
|
}
|
|
5795
4739
|
|
|
5796
|
-
|
|
4740
|
+
if (Array.isArray(value)) {
|
|
4741
|
+
// options on a multiple select
|
|
4742
|
+
if (type === 'select-multiple') {
|
|
4743
|
+
_toConsumableArray(control.options).forEach(function (o) {
|
|
4744
|
+
if (value.includes(o.value)) {
|
|
4745
|
+
o.selected = true;
|
|
4746
|
+
}
|
|
4747
|
+
});
|
|
5797
4748
|
|
|
5798
|
-
if (!valid) {
|
|
5799
|
-
if (!(target.localName === 'input' && target.type === 'image')) {
|
|
5800
4749
|
return;
|
|
5801
|
-
}
|
|
4750
|
+
}
|
|
5802
4751
|
|
|
4752
|
+
value.forEach(function (v, i) {
|
|
4753
|
+
var c = control[i];
|
|
5803
4754
|
|
|
5804
|
-
|
|
5805
|
-
|
|
4755
|
+
if (c.type === 'checkbox') {
|
|
4756
|
+
var isMatch = c.value === v || v === 'on';
|
|
4757
|
+
c.checked = isMatch;
|
|
4758
|
+
return;
|
|
4759
|
+
}
|
|
5806
4760
|
|
|
5807
|
-
|
|
4761
|
+
if (c.type === 'select-multiple') {
|
|
4762
|
+
_toConsumableArray(c.options).forEach(function (o) {
|
|
4763
|
+
if (v.includes(o.value)) {
|
|
4764
|
+
o.selected = true;
|
|
4765
|
+
}
|
|
4766
|
+
});
|
|
5808
4767
|
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
}
|
|
4768
|
+
return;
|
|
4769
|
+
}
|
|
5812
4770
|
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
4771
|
+
c.value = v;
|
|
4772
|
+
});
|
|
4773
|
+
} else {
|
|
4774
|
+
control.value = value;
|
|
4775
|
+
}
|
|
4776
|
+
});
|
|
4777
|
+
}
|
|
5819
4778
|
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
4779
|
+
function getIMFFallbackResults({
|
|
4780
|
+
$p,
|
|
4781
|
+
lang,
|
|
4782
|
+
langs,
|
|
4783
|
+
langData,
|
|
4784
|
+
fallbackLanguages,
|
|
4785
|
+
resultsDisplay,
|
|
4786
|
+
basePath = '',
|
|
4787
|
+
localeCallback = false
|
|
4788
|
+
}) {
|
|
4789
|
+
return new Promise((resolve, reject) => {
|
|
4790
|
+
const resultsCallback = (...args) => {
|
|
4791
|
+
const [l10n] = args;
|
|
5823
4792
|
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
|
|
4793
|
+
if (!$p.l10n) {
|
|
4794
|
+
$p.l10n = l10n;
|
|
4795
|
+
}
|
|
5827
4796
|
|
|
5828
|
-
|
|
5829
|
-
|
|
4797
|
+
return resultsDisplay({
|
|
4798
|
+
l: l10n,
|
|
4799
|
+
lang,
|
|
4800
|
+
fallbackLanguages,
|
|
4801
|
+
imfLocales: imf.locales,
|
|
4802
|
+
$p,
|
|
4803
|
+
basePath
|
|
4804
|
+
}, ...args);
|
|
4805
|
+
};
|
|
5830
4806
|
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
});
|
|
5835
|
-
/**
|
|
5836
|
-
* Replace the native HTMLFormElement.submit() method, as it won't fire the
|
|
5837
|
-
* submit event and give us a chance to respond.
|
|
5838
|
-
*/
|
|
4807
|
+
const imf = IMF({
|
|
4808
|
+
languages: lang,
|
|
4809
|
+
fallbackLanguages,
|
|
5839
4810
|
|
|
5840
|
-
|
|
4811
|
+
localeFileResolver(code) {
|
|
4812
|
+
// Todo: For editing of locales, we might instead resolve all
|
|
4813
|
+
// `$ref` (as with <https://github.com/whitlockjc/json-refs>) and
|
|
4814
|
+
// replace IMF() loadLocales behavior with our own now resolved
|
|
4815
|
+
// locales; see https://github.com/jdorn/json-editor/issues/132
|
|
4816
|
+
return basePath + langData.localeFileBasePath + langs.find(l => l.code === code).locale.$ref;
|
|
4817
|
+
},
|
|
5841
4818
|
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
4819
|
+
async callback(...args) {
|
|
4820
|
+
if (localeCallback && localeCallback(...args)) {
|
|
4821
|
+
resolve();
|
|
4822
|
+
return;
|
|
4823
|
+
}
|
|
5846
4824
|
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
4825
|
+
await resultsCallback(...args);
|
|
4826
|
+
resolve();
|
|
4827
|
+
}
|
|
5850
4828
|
|
|
5851
|
-
|
|
4829
|
+
});
|
|
4830
|
+
});
|
|
5852
4831
|
}
|
|
5853
4832
|
|
|
5854
4833
|
/*
|
|
@@ -7801,7 +6780,6 @@ class Dialog {
|
|
|
7801
6780
|
}
|
|
7802
6781
|
|
|
7803
6782
|
const dialog = jml('dialog', atts, children, $$1('#main'));
|
|
7804
|
-
dialogPolyfill.registerDialog(dialog);
|
|
7805
6783
|
dialog.showModal();
|
|
7806
6784
|
|
|
7807
6785
|
if (remove) {
|
|
@@ -7896,7 +6874,6 @@ class Dialog {
|
|
|
7896
6874
|
|
|
7897
6875
|
}
|
|
7898
6876
|
}, [this.localeStrings.ok]]]]] : [])], $$1('#main'));
|
|
7899
|
-
dialogPolyfill.registerDialog(dialog);
|
|
7900
6877
|
dialog.showModal();
|
|
7901
6878
|
});
|
|
7902
6879
|
}
|
|
@@ -7970,7 +6947,6 @@ class Dialog {
|
|
|
7970
6947
|
|
|
7971
6948
|
}
|
|
7972
6949
|
}, [this.localeStrings.cancel]]]]], $$1('#main'));
|
|
7973
|
-
dialogPolyfill.registerDialog(dialog);
|
|
7974
6950
|
dialog.showModal();
|
|
7975
6951
|
});
|
|
7976
6952
|
}
|
|
@@ -15472,15 +14448,6 @@ class PluginsForWork {
|
|
|
15472
14448
|
|
|
15473
14449
|
}
|
|
15474
14450
|
|
|
15475
|
-
let path, babelRegister;
|
|
15476
|
-
|
|
15477
|
-
if (typeof process !== 'undefined') {
|
|
15478
|
-
/* eslint-disable node/global-require */
|
|
15479
|
-
path = require('path');
|
|
15480
|
-
babelRegister = require('@babel/register');
|
|
15481
|
-
/* eslint-enable node/global-require */
|
|
15482
|
-
}
|
|
15483
|
-
|
|
15484
14451
|
const getWorkFiles = async function getWorkFiles(files = this.files) {
|
|
15485
14452
|
const filesObj = await getJSON$1(files);
|
|
15486
14453
|
const dataFiles = [];
|
|
@@ -15625,20 +14592,7 @@ const getWorkData = async function ({
|
|
|
15625
14592
|
|
|
15626
14593
|
const pluginFieldMappings = pluginFieldMappingForWork;
|
|
15627
14594
|
const [schemaObj, pluginObjects] = await Promise.all([getMetadata(schemaFile, schemaProperty, basePath), getPlugins ? Promise.all(pluginPaths.map(pluginPath => {
|
|
15628
|
-
|
|
15629
|
-
pluginPath = path.resolve(path.join(process.cwd(), 'node_modules/textbrowser/server', pluginPath));
|
|
15630
|
-
babelRegister({
|
|
15631
|
-
presets: ['@babel/env']
|
|
15632
|
-
});
|
|
15633
|
-
return Promise.resolve().then(() => {
|
|
15634
|
-
return require(pluginPath); // eslint-disable-line node/global-require, import/no-dynamic-require
|
|
15635
|
-
}).catch(err => {
|
|
15636
|
-
// E.g., with tooltips plugin
|
|
15637
|
-
console.log('err', err);
|
|
15638
|
-
});
|
|
15639
|
-
} // eslint-disable-next-line no-unsanitized/method
|
|
15640
|
-
|
|
15641
|
-
|
|
14595
|
+
// eslint-disable-next-line no-unsanitized/method
|
|
15642
14596
|
return import(pluginPath);
|
|
15643
14597
|
})) : null]);
|
|
15644
14598
|
const pluginsForWork = new PluginsForWork({
|
|
@@ -18288,6 +17242,9 @@ var rtlDetect_1 = {
|
|
|
18288
17242
|
getLangDir: rtlDetect.getLangDir
|
|
18289
17243
|
};
|
|
18290
17244
|
|
|
17245
|
+
const {
|
|
17246
|
+
getLangDir
|
|
17247
|
+
} = rtlDetect_1;
|
|
18291
17248
|
const fieldValueAliasRegex = /^.* \((.*?)\)$/;
|
|
18292
17249
|
|
|
18293
17250
|
const getRawFieldValue = v => {
|
|
@@ -19188,7 +18145,7 @@ const resultsDisplayServerOrClient = async function resultsDisplayServerOrClient
|
|
|
19188
18145
|
applicableFieldIdx,
|
|
19189
18146
|
applicableFieldText,
|
|
19190
18147
|
fieldLang,
|
|
19191
|
-
getLangDir
|
|
18148
|
+
getLangDir,
|
|
19192
18149
|
meta,
|
|
19193
18150
|
metaApplicableField,
|
|
19194
18151
|
$p,
|
|
@@ -19199,13 +18156,13 @@ const resultsDisplayServerOrClient = async function resultsDisplayServerOrClient
|
|
|
19199
18156
|
});
|
|
19200
18157
|
}
|
|
19201
18158
|
|
|
19202
|
-
const localeDir =
|
|
18159
|
+
const localeDir = getLangDir(preferredLocale);
|
|
19203
18160
|
const fieldDirs = fieldLangs.map(langCode => {
|
|
19204
18161
|
if (!langCode) {
|
|
19205
18162
|
return null;
|
|
19206
18163
|
}
|
|
19207
18164
|
|
|
19208
|
-
const langDir =
|
|
18165
|
+
const langDir = getLangDir(langCode);
|
|
19209
18166
|
return langDir !== localeDir ? langDir : null;
|
|
19210
18167
|
});
|
|
19211
18168
|
const templateArgs = {
|
|
@@ -19427,7 +18384,7 @@ class TextBrowser {
|
|
|
19427
18384
|
const builtinIndex = stylesheets.indexOf('@builtin');
|
|
19428
18385
|
|
|
19429
18386
|
if (builtinIndex !== -1) {
|
|
19430
|
-
stylesheets.splice(builtinIndex, 1, new URL('index.css', moduleURL).href
|
|
18387
|
+
stylesheets.splice(builtinIndex, 1, new URL('index.css', moduleURL).href);
|
|
19431
18388
|
}
|
|
19432
18389
|
|
|
19433
18390
|
this.stylesheets = stylesheets;
|