textbrowser 0.41.2 → 0.42.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/dist/index-umd.js CHANGED
@@ -4884,979 +4884,6 @@
4884
4884
  });
4885
4885
  }
4886
4886
 
4887
- // nb. This is for IE10 and lower _only_.
4888
- var supportCustomEvent = window.CustomEvent;
4889
-
4890
- if (!supportCustomEvent || typeof supportCustomEvent === 'object') {
4891
- supportCustomEvent = function CustomEvent(event, x) {
4892
- x = x || {};
4893
- var ev = document.createEvent('CustomEvent');
4894
- ev.initCustomEvent(event, !!x.bubbles, !!x.cancelable, x.detail || null);
4895
- return ev;
4896
- };
4897
-
4898
- supportCustomEvent.prototype = window.Event.prototype;
4899
- }
4900
- /**
4901
- * Dispatches the passed event to both an "on<type>" handler as well as via the
4902
- * normal dispatch operation. Does not bubble.
4903
- *
4904
- * @param {!EventTarget} target
4905
- * @param {!Event} event
4906
- * @return {boolean}
4907
- */
4908
-
4909
-
4910
- function safeDispatchEvent(target, event) {
4911
- var check = 'on' + event.type.toLowerCase();
4912
-
4913
- if (typeof target[check] === 'function') {
4914
- target[check](event);
4915
- }
4916
-
4917
- return target.dispatchEvent(event);
4918
- }
4919
- /**
4920
- * @param {Element} el to check for stacking context
4921
- * @return {boolean} whether this el or its parents creates a stacking context
4922
- */
4923
-
4924
-
4925
- function createsStackingContext(el) {
4926
- while (el && el !== document.body) {
4927
- var s = window.getComputedStyle(el);
4928
-
4929
- var invalid = function (k, ok) {
4930
- return !(s[k] === undefined || s[k] === ok);
4931
- };
4932
-
4933
- 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') {
4934
- return true;
4935
- }
4936
-
4937
- el = el.parentElement;
4938
- }
4939
-
4940
- return false;
4941
- }
4942
- /**
4943
- * Finds the nearest <dialog> from the passed element.
4944
- *
4945
- * @param {Element} el to search from
4946
- * @return {HTMLDialogElement} dialog found
4947
- */
4948
-
4949
-
4950
- function findNearestDialog(el) {
4951
- while (el) {
4952
- if (el.localName === 'dialog') {
4953
- return (
4954
- /** @type {HTMLDialogElement} */
4955
- el
4956
- );
4957
- }
4958
-
4959
- if (el.parentElement) {
4960
- el = el.parentElement;
4961
- } else if (el.parentNode) {
4962
- el = el.parentNode.host;
4963
- } else {
4964
- el = null;
4965
- }
4966
- }
4967
-
4968
- return null;
4969
- }
4970
- /**
4971
- * Blur the specified element, as long as it's not the HTML body element.
4972
- * This works around an IE9/10 bug - blurring the body causes Windows to
4973
- * blur the whole application.
4974
- *
4975
- * @param {Element} el to blur
4976
- */
4977
-
4978
-
4979
- function safeBlur(el) {
4980
- // Find the actual focused element when the active element is inside a shadow root
4981
- while (el && el.shadowRoot && el.shadowRoot.activeElement) {
4982
- el = el.shadowRoot.activeElement;
4983
- }
4984
-
4985
- if (el && el.blur && el !== document.body) {
4986
- el.blur();
4987
- }
4988
- }
4989
- /**
4990
- * @param {!NodeList} nodeList to search
4991
- * @param {Node} node to find
4992
- * @return {boolean} whether node is inside nodeList
4993
- */
4994
-
4995
-
4996
- function inNodeList(nodeList, node) {
4997
- for (var i = 0; i < nodeList.length; ++i) {
4998
- if (nodeList[i] === node) {
4999
- return true;
5000
- }
5001
- }
5002
-
5003
- return false;
5004
- }
5005
- /**
5006
- * @param {HTMLFormElement} el to check
5007
- * @return {boolean} whether this form has method="dialog"
5008
- */
5009
-
5010
-
5011
- function isFormMethodDialog(el) {
5012
- if (!el || !el.hasAttribute('method')) {
5013
- return false;
5014
- }
5015
-
5016
- return el.getAttribute('method').toLowerCase() === 'dialog';
5017
- }
5018
- /**
5019
- * @param {!DocumentFragment|!Element} hostElement
5020
- * @return {?Element}
5021
- */
5022
-
5023
-
5024
- function findFocusableElementWithin(hostElement) {
5025
- // Note that this is 'any focusable area'. This list is probably not exhaustive, but the
5026
- // alternative involves stepping through and trying to focus everything.
5027
- var opts = ['button', 'input', 'keygen', 'select', 'textarea'];
5028
- var query = opts.map(function (el) {
5029
- return el + ':not([disabled])';
5030
- }); // TODO(samthor): tabindex values that are not numeric are not focusable.
5031
-
5032
- query.push('[tabindex]:not([disabled]):not([tabindex=""])'); // tabindex != "", not disabled
5033
-
5034
- var target = hostElement.querySelector(query.join(', '));
5035
-
5036
- if (!target && 'attachShadow' in Element.prototype) {
5037
- // If we haven't found a focusable target, see if the host element contains an element
5038
- // which has a shadowRoot.
5039
- // Recursively search for the first focusable item in shadow roots.
5040
- var elems = hostElement.querySelectorAll('*');
5041
-
5042
- for (var i = 0; i < elems.length; i++) {
5043
- if (elems[i].tagName && elems[i].shadowRoot) {
5044
- target = findFocusableElementWithin(elems[i].shadowRoot);
5045
-
5046
- if (target) {
5047
- break;
5048
- }
5049
- }
5050
- }
5051
- }
5052
-
5053
- return target;
5054
- }
5055
- /**
5056
- * Determines if an element is attached to the DOM.
5057
- * @param {Element} element to check
5058
- * @return {boolean} whether the element is in DOM
5059
- */
5060
-
5061
-
5062
- function isConnected(element) {
5063
- return element.isConnected || document.body.contains(element);
5064
- }
5065
- /**
5066
- * @param {!Event} event
5067
- * @return {?Element}
5068
- */
5069
-
5070
-
5071
- function findFormSubmitter(event) {
5072
- if (event.submitter) {
5073
- return event.submitter;
5074
- }
5075
-
5076
- var form = event.target;
5077
-
5078
- if (!(form instanceof HTMLFormElement)) {
5079
- return null;
5080
- }
5081
-
5082
- var submitter = dialogPolyfill.formSubmitter;
5083
-
5084
- if (!submitter) {
5085
- var target = event.target;
5086
- var root = 'getRootNode' in target && target.getRootNode() || document;
5087
- submitter = root.activeElement;
5088
- }
5089
-
5090
- if (!submitter || submitter.form !== form) {
5091
- return null;
5092
- }
5093
-
5094
- return submitter;
5095
- }
5096
- /**
5097
- * @param {!Event} event
5098
- */
5099
-
5100
-
5101
- function maybeHandleSubmit(event) {
5102
- if (event.defaultPrevented) {
5103
- return;
5104
- }
5105
-
5106
- var form =
5107
- /** @type {!HTMLFormElement} */
5108
- event.target; // We'd have a value if we clicked on an imagemap.
5109
-
5110
- var value = dialogPolyfill.imagemapUseValue;
5111
- var submitter = findFormSubmitter(event);
5112
-
5113
- if (value === null && submitter) {
5114
- value = submitter.value;
5115
- } // There should always be a dialog as this handler is added specifically on them, but check just
5116
- // in case.
5117
-
5118
-
5119
- var dialog = findNearestDialog(form);
5120
-
5121
- if (!dialog) {
5122
- return;
5123
- } // Prefer formmethod on the button.
5124
-
5125
-
5126
- var formmethod = submitter && submitter.getAttribute('formmethod') || form.getAttribute('method');
5127
-
5128
- if (formmethod !== 'dialog') {
5129
- return;
5130
- }
5131
-
5132
- event.preventDefault();
5133
-
5134
- if (value != null) {
5135
- // nb. we explicitly check against null/undefined
5136
- dialog.close(value);
5137
- } else {
5138
- dialog.close();
5139
- }
5140
- }
5141
- /**
5142
- * @param {!HTMLDialogElement} dialog to upgrade
5143
- * @constructor
5144
- */
5145
-
5146
-
5147
- function dialogPolyfillInfo(dialog) {
5148
- this.dialog_ = dialog;
5149
- this.replacedStyleTop_ = false;
5150
- this.openAsModal_ = false; // Set a11y role. Browsers that support dialog implicitly know this already.
5151
-
5152
- if (!dialog.hasAttribute('role')) {
5153
- dialog.setAttribute('role', 'dialog');
5154
- }
5155
-
5156
- dialog.show = this.show.bind(this);
5157
- dialog.showModal = this.showModal.bind(this);
5158
- dialog.close = this.close.bind(this);
5159
- dialog.addEventListener('submit', maybeHandleSubmit, false);
5160
-
5161
- if (!('returnValue' in dialog)) {
5162
- dialog.returnValue = '';
5163
- }
5164
-
5165
- if ('MutationObserver' in window) {
5166
- var mo = new MutationObserver(this.maybeHideModal.bind(this));
5167
- mo.observe(dialog, {
5168
- attributes: true,
5169
- attributeFilter: ['open']
5170
- });
5171
- } else {
5172
- // IE10 and below support. Note that DOMNodeRemoved etc fire _before_ removal. They also
5173
- // seem to fire even if the element was removed as part of a parent removal. Use the removed
5174
- // events to force downgrade (useful if removed/immediately added).
5175
- var removed = false;
5176
-
5177
- var cb = function () {
5178
- removed ? this.downgradeModal() : this.maybeHideModal();
5179
- removed = false;
5180
- }.bind(this);
5181
-
5182
- var timeout;
5183
-
5184
- var delayModel = function (ev) {
5185
- if (ev.target !== dialog) {
5186
- return;
5187
- } // not for a child element
5188
-
5189
-
5190
- var cand = 'DOMNodeRemoved';
5191
- removed |= ev.type.substr(0, cand.length) === cand;
5192
- window.clearTimeout(timeout);
5193
- timeout = window.setTimeout(cb, 0);
5194
- };
5195
-
5196
- ['DOMAttrModified', 'DOMNodeRemoved', 'DOMNodeRemovedFromDocument'].forEach(function (name) {
5197
- dialog.addEventListener(name, delayModel);
5198
- });
5199
- } // Note that the DOM is observed inside DialogManager while any dialog
5200
- // is being displayed as a modal, to catch modal removal from the DOM.
5201
-
5202
-
5203
- Object.defineProperty(dialog, 'open', {
5204
- set: this.setOpen.bind(this),
5205
- get: dialog.hasAttribute.bind(dialog, 'open')
5206
- });
5207
- this.backdrop_ = document.createElement('div');
5208
- this.backdrop_.className = 'backdrop';
5209
- this.backdrop_.addEventListener('mouseup', this.backdropMouseEvent_.bind(this));
5210
- this.backdrop_.addEventListener('mousedown', this.backdropMouseEvent_.bind(this));
5211
- this.backdrop_.addEventListener('click', this.backdropMouseEvent_.bind(this));
5212
- }
5213
-
5214
- dialogPolyfillInfo.prototype =
5215
- /** @type {HTMLDialogElement.prototype} */
5216
- {
5217
- get dialog() {
5218
- return this.dialog_;
5219
- },
5220
-
5221
- /**
5222
- * Maybe remove this dialog from the modal top layer. This is called when
5223
- * a modal dialog may no longer be tenable, e.g., when the dialog is no
5224
- * longer open or is no longer part of the DOM.
5225
- */
5226
- maybeHideModal: function () {
5227
- if (this.dialog_.hasAttribute('open') && isConnected(this.dialog_)) {
5228
- return;
5229
- }
5230
-
5231
- this.downgradeModal();
5232
- },
5233
-
5234
- /**
5235
- * Remove this dialog from the modal top layer, leaving it as a non-modal.
5236
- */
5237
- downgradeModal: function () {
5238
- if (!this.openAsModal_) {
5239
- return;
5240
- }
5241
-
5242
- this.openAsModal_ = false;
5243
- this.dialog_.style.zIndex = ''; // This won't match the native <dialog> exactly because if the user set top on a centered
5244
- // polyfill dialog, that top gets thrown away when the dialog is closed. Not sure it's
5245
- // possible to polyfill this perfectly.
5246
-
5247
- if (this.replacedStyleTop_) {
5248
- this.dialog_.style.top = '';
5249
- this.replacedStyleTop_ = false;
5250
- } // Clear the backdrop and remove from the manager.
5251
-
5252
-
5253
- this.backdrop_.parentNode && this.backdrop_.parentNode.removeChild(this.backdrop_);
5254
- dialogPolyfill.dm.removeDialog(this);
5255
- },
5256
-
5257
- /**
5258
- * @param {boolean} value whether to open or close this dialog
5259
- */
5260
- setOpen: function (value) {
5261
- if (value) {
5262
- this.dialog_.hasAttribute('open') || this.dialog_.setAttribute('open', '');
5263
- } else {
5264
- this.dialog_.removeAttribute('open');
5265
- this.maybeHideModal(); // nb. redundant with MutationObserver
5266
- }
5267
- },
5268
-
5269
- /**
5270
- * Handles mouse events ('mouseup', 'mousedown', 'click') on the fake .backdrop element, redirecting them as if
5271
- * they were on the dialog itself.
5272
- *
5273
- * @param {!Event} e to redirect
5274
- */
5275
- backdropMouseEvent_: function (e) {
5276
- if (!this.dialog_.hasAttribute('tabindex')) {
5277
- // Clicking on the backdrop should move the implicit cursor, even if dialog cannot be
5278
- // focused. Create a fake thing to focus on. If the backdrop was _before_ the dialog, this
5279
- // would not be needed - clicks would move the implicit cursor there.
5280
- var fake = document.createElement('div');
5281
- this.dialog_.insertBefore(fake, this.dialog_.firstChild);
5282
- fake.tabIndex = -1;
5283
- fake.focus();
5284
- this.dialog_.removeChild(fake);
5285
- } else {
5286
- this.dialog_.focus();
5287
- }
5288
-
5289
- var redirectedEvent = document.createEvent('MouseEvents');
5290
- 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);
5291
- this.dialog_.dispatchEvent(redirectedEvent);
5292
- e.stopPropagation();
5293
- },
5294
-
5295
- /**
5296
- * Focuses on the first focusable element within the dialog. This will always blur the current
5297
- * focus, even if nothing within the dialog is found.
5298
- */
5299
- focus_: function () {
5300
- // Find element with `autofocus` attribute, or fall back to the first form/tabindex control.
5301
- var target = this.dialog_.querySelector('[autofocus]:not([disabled])');
5302
-
5303
- if (!target && this.dialog_.tabIndex >= 0) {
5304
- target = this.dialog_;
5305
- }
5306
-
5307
- if (!target) {
5308
- target = findFocusableElementWithin(this.dialog_);
5309
- }
5310
-
5311
- safeBlur(document.activeElement);
5312
- target && target.focus();
5313
- },
5314
-
5315
- /**
5316
- * Sets the zIndex for the backdrop and dialog.
5317
- *
5318
- * @param {number} dialogZ
5319
- * @param {number} backdropZ
5320
- */
5321
- updateZIndex: function (dialogZ, backdropZ) {
5322
- if (dialogZ < backdropZ) {
5323
- throw new Error('dialogZ should never be < backdropZ');
5324
- }
5325
-
5326
- this.dialog_.style.zIndex = dialogZ;
5327
- this.backdrop_.style.zIndex = backdropZ;
5328
- },
5329
-
5330
- /**
5331
- * Shows the dialog. If the dialog is already open, this does nothing.
5332
- */
5333
- show: function () {
5334
- if (!this.dialog_.open) {
5335
- this.setOpen(true);
5336
- this.focus_();
5337
- }
5338
- },
5339
-
5340
- /**
5341
- * Show this dialog modally.
5342
- */
5343
- showModal: function () {
5344
- if (this.dialog_.hasAttribute('open')) {
5345
- throw new Error('Failed to execute \'showModal\' on dialog: The element is already open, and therefore cannot be opened modally.');
5346
- }
5347
-
5348
- if (!isConnected(this.dialog_)) {
5349
- throw new Error('Failed to execute \'showModal\' on dialog: The element is not in a Document.');
5350
- }
5351
-
5352
- if (!dialogPolyfill.dm.pushDialog(this)) {
5353
- throw new Error('Failed to execute \'showModal\' on dialog: There are too many open modal dialogs.');
5354
- }
5355
-
5356
- if (createsStackingContext(this.dialog_.parentElement)) {
5357
- 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');
5358
- }
5359
-
5360
- this.setOpen(true);
5361
- this.openAsModal_ = true; // Optionally center vertically, relative to the current viewport.
5362
-
5363
- if (dialogPolyfill.needsCentering(this.dialog_)) {
5364
- dialogPolyfill.reposition(this.dialog_);
5365
- this.replacedStyleTop_ = true;
5366
- } else {
5367
- this.replacedStyleTop_ = false;
5368
- } // Insert backdrop.
5369
-
5370
-
5371
- this.dialog_.parentNode.insertBefore(this.backdrop_, this.dialog_.nextSibling); // Focus on whatever inside the dialog.
5372
-
5373
- this.focus_();
5374
- },
5375
-
5376
- /**
5377
- * Closes this HTMLDialogElement. This is optional vs clearing the open
5378
- * attribute, however this fires a 'close' event.
5379
- *
5380
- * @param {string=} opt_returnValue to use as the returnValue
5381
- */
5382
- close: function (opt_returnValue) {
5383
- if (!this.dialog_.hasAttribute('open')) {
5384
- throw new Error('Failed to execute \'close\' on dialog: The element does not have an \'open\' attribute, and therefore cannot be closed.');
5385
- }
5386
-
5387
- this.setOpen(false); // Leave returnValue untouched in case it was set directly on the element
5388
-
5389
- if (opt_returnValue !== undefined) {
5390
- this.dialog_.returnValue = opt_returnValue;
5391
- } // Triggering "close" event for any attached listeners on the <dialog>.
5392
-
5393
-
5394
- var closeEvent = new supportCustomEvent('close', {
5395
- bubbles: false,
5396
- cancelable: false
5397
- });
5398
- safeDispatchEvent(this.dialog_, closeEvent);
5399
- }
5400
- };
5401
- var dialogPolyfill = {};
5402
-
5403
- dialogPolyfill.reposition = function (element) {
5404
- var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
5405
- var topValue = scrollTop + (window.innerHeight - element.offsetHeight) / 2;
5406
- element.style.top = Math.max(scrollTop, topValue) + 'px';
5407
- };
5408
-
5409
- dialogPolyfill.isInlinePositionSetByStylesheet = function (element) {
5410
- for (var i = 0; i < document.styleSheets.length; ++i) {
5411
- var styleSheet = document.styleSheets[i];
5412
- var cssRules = null; // Some browsers throw on cssRules.
5413
-
5414
- try {
5415
- cssRules = styleSheet.cssRules;
5416
- } catch (e) {}
5417
-
5418
- if (!cssRules) {
5419
- continue;
5420
- }
5421
-
5422
- for (var j = 0; j < cssRules.length; ++j) {
5423
- var rule = cssRules[j];
5424
- var selectedNodes = null; // Ignore errors on invalid selector texts.
5425
-
5426
- try {
5427
- selectedNodes = document.querySelectorAll(rule.selectorText);
5428
- } catch (e) {}
5429
-
5430
- if (!selectedNodes || !inNodeList(selectedNodes, element)) {
5431
- continue;
5432
- }
5433
-
5434
- var cssTop = rule.style.getPropertyValue('top');
5435
- var cssBottom = rule.style.getPropertyValue('bottom');
5436
-
5437
- if (cssTop && cssTop !== 'auto' || cssBottom && cssBottom !== 'auto') {
5438
- return true;
5439
- }
5440
- }
5441
- }
5442
-
5443
- return false;
5444
- };
5445
-
5446
- dialogPolyfill.needsCentering = function (dialog) {
5447
- var computedStyle = window.getComputedStyle(dialog);
5448
-
5449
- if (computedStyle.position !== 'absolute') {
5450
- return false;
5451
- } // We must determine whether the top/bottom specified value is non-auto. In
5452
- // WebKit/Blink, checking computedStyle.top == 'auto' is sufficient, but
5453
- // Firefox returns the used value. So we do this crazy thing instead: check
5454
- // the inline style and then go through CSS rules.
5455
-
5456
-
5457
- if (dialog.style.top !== 'auto' && dialog.style.top !== '' || dialog.style.bottom !== 'auto' && dialog.style.bottom !== '') {
5458
- return false;
5459
- }
5460
-
5461
- return !dialogPolyfill.isInlinePositionSetByStylesheet(dialog);
5462
- };
5463
- /**
5464
- * @param {!Element} element to force upgrade
5465
- */
5466
-
5467
-
5468
- dialogPolyfill.forceRegisterDialog = function (element) {
5469
- if (window.HTMLDialogElement || element.showModal) {
5470
- console.warn('This browser already supports <dialog>, the polyfill ' + 'may not work correctly', element);
5471
- }
5472
-
5473
- if (element.localName !== 'dialog') {
5474
- throw new Error('Failed to register dialog: The element is not a dialog.');
5475
- }
5476
-
5477
- new dialogPolyfillInfo(
5478
- /** @type {!HTMLDialogElement} */
5479
- element);
5480
- };
5481
- /**
5482
- * @param {!Element} element to upgrade, if necessary
5483
- */
5484
-
5485
-
5486
- dialogPolyfill.registerDialog = function (element) {
5487
- if (!element.showModal) {
5488
- dialogPolyfill.forceRegisterDialog(element);
5489
- }
5490
- };
5491
- /**
5492
- * @constructor
5493
- */
5494
-
5495
-
5496
- dialogPolyfill.DialogManager = function () {
5497
- /** @type {!Array<!dialogPolyfillInfo>} */
5498
- this.pendingDialogStack = [];
5499
- var checkDOM = this.checkDOM_.bind(this); // The overlay is used to simulate how a modal dialog blocks the document.
5500
- // The blocking dialog is positioned on top of the overlay, and the rest of
5501
- // the dialogs on the pending dialog stack are positioned below it. In the
5502
- // actual implementation, the modal dialog stacking is controlled by the
5503
- // top layer, where z-index has no effect.
5504
-
5505
- this.overlay = document.createElement('div');
5506
- this.overlay.className = '_dialog_overlay';
5507
- this.overlay.addEventListener('click', function (e) {
5508
- this.forwardTab_ = undefined;
5509
- e.stopPropagation();
5510
- checkDOM([]); // sanity-check DOM
5511
- }.bind(this));
5512
- this.handleKey_ = this.handleKey_.bind(this);
5513
- this.handleFocus_ = this.handleFocus_.bind(this);
5514
- this.zIndexLow_ = 100000;
5515
- this.zIndexHigh_ = 100000 + 150;
5516
- this.forwardTab_ = undefined;
5517
-
5518
- if ('MutationObserver' in window) {
5519
- this.mo_ = new MutationObserver(function (records) {
5520
- var removed = [];
5521
- records.forEach(function (rec) {
5522
- for (var i = 0, c; c = rec.removedNodes[i]; ++i) {
5523
- if (!(c instanceof Element)) {
5524
- continue;
5525
- } else if (c.localName === 'dialog') {
5526
- removed.push(c);
5527
- }
5528
-
5529
- removed = removed.concat(c.querySelectorAll('dialog'));
5530
- }
5531
- });
5532
- removed.length && checkDOM(removed);
5533
- });
5534
- }
5535
- };
5536
- /**
5537
- * Called on the first modal dialog being shown. Adds the overlay and related
5538
- * handlers.
5539
- */
5540
-
5541
-
5542
- dialogPolyfill.DialogManager.prototype.blockDocument = function () {
5543
- document.documentElement.addEventListener('focus', this.handleFocus_, true);
5544
- document.addEventListener('keydown', this.handleKey_);
5545
- this.mo_ && this.mo_.observe(document, {
5546
- childList: true,
5547
- subtree: true
5548
- });
5549
- };
5550
- /**
5551
- * Called on the first modal dialog being removed, i.e., when no more modal
5552
- * dialogs are visible.
5553
- */
5554
-
5555
-
5556
- dialogPolyfill.DialogManager.prototype.unblockDocument = function () {
5557
- document.documentElement.removeEventListener('focus', this.handleFocus_, true);
5558
- document.removeEventListener('keydown', this.handleKey_);
5559
- this.mo_ && this.mo_.disconnect();
5560
- };
5561
- /**
5562
- * Updates the stacking of all known dialogs.
5563
- */
5564
-
5565
-
5566
- dialogPolyfill.DialogManager.prototype.updateStacking = function () {
5567
- var zIndex = this.zIndexHigh_;
5568
-
5569
- for (var i = 0, dpi; dpi = this.pendingDialogStack[i]; ++i) {
5570
- dpi.updateZIndex(--zIndex, --zIndex);
5571
-
5572
- if (i === 0) {
5573
- this.overlay.style.zIndex = --zIndex;
5574
- }
5575
- } // Make the overlay a sibling of the dialog itself.
5576
-
5577
-
5578
- var last = this.pendingDialogStack[0];
5579
-
5580
- if (last) {
5581
- var p = last.dialog.parentNode || document.body;
5582
- p.appendChild(this.overlay);
5583
- } else if (this.overlay.parentNode) {
5584
- this.overlay.parentNode.removeChild(this.overlay);
5585
- }
5586
- };
5587
- /**
5588
- * @param {Element} candidate to check if contained or is the top-most modal dialog
5589
- * @return {boolean} whether candidate is contained in top dialog
5590
- */
5591
-
5592
-
5593
- dialogPolyfill.DialogManager.prototype.containedByTopDialog_ = function (candidate) {
5594
- while (candidate = findNearestDialog(candidate)) {
5595
- for (var i = 0, dpi; dpi = this.pendingDialogStack[i]; ++i) {
5596
- if (dpi.dialog === candidate) {
5597
- return i === 0; // only valid if top-most
5598
- }
5599
- }
5600
-
5601
- candidate = candidate.parentElement;
5602
- }
5603
-
5604
- return false;
5605
- };
5606
-
5607
- dialogPolyfill.DialogManager.prototype.handleFocus_ = function (event) {
5608
- var target = event.composedPath ? event.composedPath()[0] : event.target;
5609
-
5610
- if (this.containedByTopDialog_(target)) {
5611
- return;
5612
- }
5613
-
5614
- if (document.activeElement === document.documentElement) {
5615
- return;
5616
- }
5617
-
5618
- event.preventDefault();
5619
- event.stopPropagation();
5620
- safeBlur(
5621
- /** @type {Element} */
5622
- target);
5623
-
5624
- if (this.forwardTab_ === undefined) {
5625
- return;
5626
- } // move focus only from a tab key
5627
-
5628
-
5629
- var dpi = this.pendingDialogStack[0];
5630
- var dialog = dpi.dialog;
5631
- var position = dialog.compareDocumentPosition(target);
5632
-
5633
- if (position & Node.DOCUMENT_POSITION_PRECEDING) {
5634
- if (this.forwardTab_) {
5635
- // forward
5636
- dpi.focus_();
5637
- } else if (target !== document.documentElement) {
5638
- // backwards if we're not already focused on <html>
5639
- document.documentElement.focus();
5640
- }
5641
- }
5642
-
5643
- return false;
5644
- };
5645
-
5646
- dialogPolyfill.DialogManager.prototype.handleKey_ = function (event) {
5647
- this.forwardTab_ = undefined;
5648
-
5649
- if (event.keyCode === 27) {
5650
- event.preventDefault();
5651
- event.stopPropagation();
5652
- var cancelEvent = new supportCustomEvent('cancel', {
5653
- bubbles: false,
5654
- cancelable: true
5655
- });
5656
- var dpi = this.pendingDialogStack[0];
5657
-
5658
- if (dpi && safeDispatchEvent(dpi.dialog, cancelEvent)) {
5659
- dpi.dialog.close();
5660
- }
5661
- } else if (event.keyCode === 9) {
5662
- this.forwardTab_ = !event.shiftKey;
5663
- }
5664
- };
5665
- /**
5666
- * Finds and downgrades any known modal dialogs that are no longer displayed. Dialogs that are
5667
- * removed and immediately readded don't stay modal, they become normal.
5668
- *
5669
- * @param {!Array<!HTMLDialogElement>} removed that have definitely been removed
5670
- */
5671
-
5672
-
5673
- dialogPolyfill.DialogManager.prototype.checkDOM_ = function (removed) {
5674
- // This operates on a clone because it may cause it to change. Each change also calls
5675
- // updateStacking, which only actually needs to happen once. But who removes many modal dialogs
5676
- // at a time?!
5677
- var clone = this.pendingDialogStack.slice();
5678
- clone.forEach(function (dpi) {
5679
- if (removed.indexOf(dpi.dialog) !== -1) {
5680
- dpi.downgradeModal();
5681
- } else {
5682
- dpi.maybeHideModal();
5683
- }
5684
- });
5685
- };
5686
- /**
5687
- * @param {!dialogPolyfillInfo} dpi
5688
- * @return {boolean} whether the dialog was allowed
5689
- */
5690
-
5691
-
5692
- dialogPolyfill.DialogManager.prototype.pushDialog = function (dpi) {
5693
- var allowed = (this.zIndexHigh_ - this.zIndexLow_) / 2 - 1;
5694
-
5695
- if (this.pendingDialogStack.length >= allowed) {
5696
- return false;
5697
- }
5698
-
5699
- if (this.pendingDialogStack.unshift(dpi) === 1) {
5700
- this.blockDocument();
5701
- }
5702
-
5703
- this.updateStacking();
5704
- return true;
5705
- };
5706
- /**
5707
- * @param {!dialogPolyfillInfo} dpi
5708
- */
5709
-
5710
-
5711
- dialogPolyfill.DialogManager.prototype.removeDialog = function (dpi) {
5712
- var index = this.pendingDialogStack.indexOf(dpi);
5713
-
5714
- if (index === -1) {
5715
- return;
5716
- }
5717
-
5718
- this.pendingDialogStack.splice(index, 1);
5719
-
5720
- if (this.pendingDialogStack.length === 0) {
5721
- this.unblockDocument();
5722
- }
5723
-
5724
- this.updateStacking();
5725
- };
5726
-
5727
- dialogPolyfill.dm = new dialogPolyfill.DialogManager();
5728
- dialogPolyfill.formSubmitter = null;
5729
- dialogPolyfill.imagemapUseValue = null;
5730
- /**
5731
- * Installs global handlers, such as click listers and native method overrides. These are needed
5732
- * even if a no dialog is registered, as they deal with <form method="dialog">.
5733
- */
5734
-
5735
- if (window.HTMLDialogElement === undefined) {
5736
- /**
5737
- * If HTMLFormElement translates method="DIALOG" into 'get', then replace the descriptor with
5738
- * one that returns the correct value.
5739
- */
5740
- var testForm = document.createElement('form');
5741
- testForm.setAttribute('method', 'dialog');
5742
-
5743
- if (testForm.method !== 'dialog') {
5744
- var methodDescriptor = Object.getOwnPropertyDescriptor(HTMLFormElement.prototype, 'method');
5745
-
5746
- if (methodDescriptor) {
5747
- // nb. Some older iOS and older PhantomJS fail to return the descriptor. Don't do anything
5748
- // and don't bother to update the element.
5749
- var realGet = methodDescriptor.get;
5750
-
5751
- methodDescriptor.get = function () {
5752
- if (isFormMethodDialog(this)) {
5753
- return 'dialog';
5754
- }
5755
-
5756
- return realGet.call(this);
5757
- };
5758
-
5759
- var realSet = methodDescriptor.set;
5760
- /** @this {HTMLElement} */
5761
-
5762
- methodDescriptor.set = function (v) {
5763
- if (typeof v === 'string' && v.toLowerCase() === 'dialog') {
5764
- return this.setAttribute('method', v);
5765
- }
5766
-
5767
- return realSet.call(this, v);
5768
- };
5769
-
5770
- Object.defineProperty(HTMLFormElement.prototype, 'method', methodDescriptor);
5771
- }
5772
- }
5773
- /**
5774
- * Global 'click' handler, to capture the <input type="submit"> or <button> element which has
5775
- * submitted a <form method="dialog">. Needed as Safari and others don't report this inside
5776
- * document.activeElement.
5777
- */
5778
-
5779
-
5780
- document.addEventListener('click', function (ev) {
5781
- dialogPolyfill.formSubmitter = null;
5782
- dialogPolyfill.imagemapUseValue = null;
5783
-
5784
- if (ev.defaultPrevented) {
5785
- return;
5786
- } // e.g. a submit which prevents default submission
5787
-
5788
-
5789
- var target =
5790
- /** @type {Element} */
5791
- ev.target;
5792
-
5793
- if ('composedPath' in ev) {
5794
- var path = ev.composedPath();
5795
- target = path.shift() || target;
5796
- }
5797
-
5798
- if (!target || !isFormMethodDialog(target.form)) {
5799
- return;
5800
- }
5801
-
5802
- var valid = target.type === 'submit' && ['button', 'input'].indexOf(target.localName) > -1;
5803
-
5804
- if (!valid) {
5805
- if (!(target.localName === 'input' && target.type === 'image')) {
5806
- return;
5807
- } // this is a <input type="image">, which can submit forms
5808
-
5809
-
5810
- dialogPolyfill.imagemapUseValue = ev.offsetX + ',' + ev.offsetY;
5811
- }
5812
-
5813
- var dialog = findNearestDialog(target);
5814
-
5815
- if (!dialog) {
5816
- return;
5817
- }
5818
-
5819
- dialogPolyfill.formSubmitter = target;
5820
- }, false);
5821
- /**
5822
- * Global 'submit' handler. This handles submits of `method="dialog"` which are invalid, i.e.,
5823
- * outside a dialog. They get prevented.
5824
- */
5825
-
5826
- document.addEventListener('submit', function (ev) {
5827
- var form = ev.target;
5828
- var dialog = findNearestDialog(form);
5829
-
5830
- if (dialog) {
5831
- return; // ignore, handle there
5832
- }
5833
-
5834
- var submitter = findFormSubmitter(ev);
5835
- var formmethod = submitter && submitter.getAttribute('formmethod') || form.getAttribute('method');
5836
-
5837
- if (formmethod === 'dialog') {
5838
- ev.preventDefault();
5839
- }
5840
- });
5841
- /**
5842
- * Replace the native HTMLFormElement.submit() method, as it won't fire the
5843
- * submit event and give us a chance to respond.
5844
- */
5845
-
5846
- var nativeFormSubmit = HTMLFormElement.prototype.submit;
5847
-
5848
- var replacementFormSubmit = function () {
5849
- if (!isFormMethodDialog(this)) {
5850
- return nativeFormSubmit.call(this);
5851
- }
5852
-
5853
- var dialog = findNearestDialog(this);
5854
- dialog && dialog.close();
5855
- };
5856
-
5857
- HTMLFormElement.prototype.submit = replacementFormSubmit;
5858
- }
5859
-
5860
4887
  /*
5861
4888
  Possible todos:
5862
4889
  0. Add XSLT to JML-string stylesheet (or even vice versa)
@@ -7807,7 +6834,6 @@
7807
6834
  }
7808
6835
 
7809
6836
  const dialog = jml('dialog', atts, children, $$1('#main'));
7810
- dialogPolyfill.registerDialog(dialog);
7811
6837
  dialog.showModal();
7812
6838
 
7813
6839
  if (remove) {
@@ -7902,7 +6928,6 @@
7902
6928
 
7903
6929
  }
7904
6930
  }, [this.localeStrings.ok]]]]] : [])], $$1('#main'));
7905
- dialogPolyfill.registerDialog(dialog);
7906
6931
  dialog.showModal();
7907
6932
  });
7908
6933
  }
@@ -7976,7 +7001,6 @@
7976
7001
 
7977
7002
  }
7978
7003
  }, [this.localeStrings.cancel]]]]], $$1('#main'));
7979
- dialogPolyfill.registerDialog(dialog);
7980
7004
  dialog.showModal();
7981
7005
  });
7982
7006
  }
@@ -15478,15 +14502,6 @@
15478
14502
 
15479
14503
  }
15480
14504
 
15481
- let path, babelRegister;
15482
-
15483
- if (typeof process !== 'undefined') {
15484
- /* eslint-disable node/global-require */
15485
- path = require('path');
15486
- babelRegister = require('@babel/register');
15487
- /* eslint-enable node/global-require */
15488
- }
15489
-
15490
14505
  const getWorkFiles = async function getWorkFiles(files = this.files) {
15491
14506
  const filesObj = await getJSON$1(files);
15492
14507
  const dataFiles = [];
@@ -15631,20 +14646,7 @@
15631
14646
 
15632
14647
  const pluginFieldMappings = pluginFieldMappingForWork;
15633
14648
  const [schemaObj, pluginObjects] = await Promise.all([getMetadata(schemaFile, schemaProperty, basePath), getPlugins ? Promise.all(pluginPaths.map(pluginPath => {
15634
- if (typeof process !== 'undefined') {
15635
- pluginPath = path.resolve(path.join(process.cwd(), 'node_modules/textbrowser/server', pluginPath));
15636
- babelRegister({
15637
- presets: ['@babel/env']
15638
- });
15639
- return Promise.resolve().then(() => {
15640
- return require(pluginPath); // eslint-disable-line node/global-require, import/no-dynamic-require
15641
- }).catch(err => {
15642
- // E.g., with tooltips plugin
15643
- console.log('err', err);
15644
- });
15645
- } // eslint-disable-next-line no-unsanitized/method
15646
-
15647
-
14649
+ // eslint-disable-next-line no-unsanitized/method
15648
14650
  return import(pluginPath);
15649
14651
  })) : null]);
15650
14652
  const pluginsForWork = new PluginsForWork({
@@ -18294,6 +17296,9 @@ body {
18294
17296
  getLangDir: rtlDetect.getLangDir
18295
17297
  };
18296
17298
 
17299
+ const {
17300
+ getLangDir
17301
+ } = rtlDetect_1;
18297
17302
  const fieldValueAliasRegex = /^.* \((.*?)\)$/;
18298
17303
 
18299
17304
  const getRawFieldValue = v => {
@@ -19194,7 +18199,7 @@ body {
19194
18199
  applicableFieldIdx,
19195
18200
  applicableFieldText,
19196
18201
  fieldLang,
19197
- getLangDir: rtlDetect_1.getLangDir,
18202
+ getLangDir,
19198
18203
  meta,
19199
18204
  metaApplicableField,
19200
18205
  $p,
@@ -19205,13 +18210,13 @@ body {
19205
18210
  });
19206
18211
  }
19207
18212
 
19208
- const localeDir = rtlDetect_1.getLangDir(preferredLocale);
18213
+ const localeDir = getLangDir(preferredLocale);
19209
18214
  const fieldDirs = fieldLangs.map(langCode => {
19210
18215
  if (!langCode) {
19211
18216
  return null;
19212
18217
  }
19213
18218
 
19214
- const langDir = rtlDetect_1.getLangDir(langCode);
18219
+ const langDir = getLangDir(langCode);
19215
18220
  return langDir !== localeDir ? langDir : null;
19216
18221
  });
19217
18222
  const templateArgs = {
@@ -19433,7 +18438,7 @@ body {
19433
18438
  const builtinIndex = stylesheets.indexOf('@builtin');
19434
18439
 
19435
18440
  if (builtinIndex !== -1) {
19436
- stylesheets.splice(builtinIndex, 1, new URL('index.css', moduleURL).href, new URL('../../dialog-polyfill/dist/dialog-polyfill.css', moduleURL).href);
18441
+ stylesheets.splice(builtinIndex, 1, new URL('index.css', moduleURL).href);
19437
18442
  }
19438
18443
 
19439
18444
  this.stylesheets = stylesheets;