@shgysk8zer0/polyfills 0.3.0 → 0.3.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/CHANGELOG.md +19 -0
- package/README.md +1 -1
- package/all.min.js +14 -14
- package/all.min.js.map +1 -1
- package/array.js +336 -234
- package/assets/SanitizerConfigW3C.js +215 -631
- package/assets/sanitizerUtils.js +17 -4
- package/element.js +117 -0
- package/iterator.js +39 -0
- package/math.js +61 -56
- package/package.json +1 -1
- package/popover.css +25 -0
- package/popover.js +118 -0
package/assets/sanitizerUtils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @copyright 2023 Chris Zuber <admin@kernvalley.us>
|
|
2
|
+
* @copyright 2023-2024 Chris Zuber <admin@kernvalley.us>
|
|
3
3
|
*/
|
|
4
4
|
import { SanitizerConfig as defaultConfig } from './SanitizerConfigW3C.js';
|
|
5
5
|
import { createPolicy } from './trust.js';
|
|
@@ -9,16 +9,21 @@ import { urls } from './attributes.js';
|
|
|
9
9
|
export const supported = () => 'Sanitizer' in globalThis;
|
|
10
10
|
export const nativeSupport = supported();
|
|
11
11
|
|
|
12
|
+
const isDataAttr = name => name.length > 5 && name.substring(0, 5) === 'data-';
|
|
13
|
+
|
|
12
14
|
export const setHTML = function setHTML(el, input, opts = defaultConfig) {
|
|
13
15
|
const doc = safeParseHTML(input, opts);
|
|
14
16
|
el.replaceChildren(documentToFragment(doc));
|
|
15
17
|
};
|
|
16
18
|
|
|
17
|
-
const allowProtocols = ['https:'];
|
|
19
|
+
const allowProtocols = ['https:', 'blob:'];
|
|
20
|
+
|
|
21
|
+
const HTML_NS = 'http://www.w3.org/1999/xhtml';
|
|
18
22
|
|
|
19
23
|
if (! allowProtocols.includes(location.protocol)) {
|
|
20
24
|
allowProtocols.push(location.protocol);
|
|
21
25
|
}
|
|
26
|
+
|
|
22
27
|
const policyName = 'sanitizer-raw#html';
|
|
23
28
|
const getPolicy = callOnce(() => createPolicy(policyName, { createHTML: input => input }));
|
|
24
29
|
const createHTML = input => getPolicy().createHTML(input);
|
|
@@ -30,6 +35,12 @@ export function documentToFragment(doc) {
|
|
|
30
35
|
return frag;
|
|
31
36
|
}
|
|
32
37
|
|
|
38
|
+
export function addNamesapces(list) {
|
|
39
|
+
const mapped = list.map(allow => typeof allow === 'string' ? ({ name: allow, namespace: HTML_NS }) : allow);
|
|
40
|
+
|
|
41
|
+
return Object.groupBy(mapped, ({ namespace = HTML_NS }) => namespace);
|
|
42
|
+
}
|
|
43
|
+
|
|
33
44
|
/**
|
|
34
45
|
* Helper function to adapt to changes in spec
|
|
35
46
|
*/
|
|
@@ -170,8 +181,10 @@ export function sanitizeNode(root, opts = defaultConfig) {
|
|
|
170
181
|
}
|
|
171
182
|
} else if (isObject(allowAttributes)) {
|
|
172
183
|
if (
|
|
173
|
-
! (
|
|
174
|
-
|
|
184
|
+
! ((
|
|
185
|
+
name in allowAttributes
|
|
186
|
+
&& ['*', tag].some(sel => allowAttributes[name].includes(sel))
|
|
187
|
+
) || isDataAttr(name))
|
|
175
188
|
) {
|
|
176
189
|
node.removeAttributeNode(attr);
|
|
177
190
|
}
|
package/element.js
CHANGED
|
@@ -3,6 +3,123 @@ import { overwriteMethod, polyfillGetterSetter } from './utils.js';
|
|
|
3
3
|
import { SanitizerConfig as defaultConfig } from './assets/SanitizerConfigW3C.js';
|
|
4
4
|
import { setHTML as safeSetHTML, convertToSanitizerConfig } from './assets/sanitizerUtils.js';
|
|
5
5
|
|
|
6
|
+
function handlePopover({ currentTarget }) {
|
|
7
|
+
switch(currentTarget.popoverTargetAction) {
|
|
8
|
+
case 'show':
|
|
9
|
+
currentTarget.popoverTargetElement.showPopover();
|
|
10
|
+
break;
|
|
11
|
+
|
|
12
|
+
case 'hide':
|
|
13
|
+
currentTarget.popoverTargetElement.hidePopover();
|
|
14
|
+
break;
|
|
15
|
+
|
|
16
|
+
default:
|
|
17
|
+
currentTarget.popoverTargetElement.togglePopover();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function initPopover(target = document.body) {
|
|
22
|
+
target.querySelectorAll('button[popovertarget], input[type="button"][popovertarget]')
|
|
23
|
+
.forEach(el => el.addEventListener('click', handlePopover));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if ((globalThis.ToggleEvent instanceof Function)) {
|
|
27
|
+
class ToggleEvent extends Event {
|
|
28
|
+
#newState;
|
|
29
|
+
#oldState;
|
|
30
|
+
|
|
31
|
+
constructor(type, { newState, oldState }) {
|
|
32
|
+
super(type, { bubbles: true });
|
|
33
|
+
this.#newState = newState;
|
|
34
|
+
this.#oldState = oldState;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
get newState() {
|
|
38
|
+
return this.#newState;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get oldState() {
|
|
42
|
+
return this.#oldState;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
globalThis.ToggleEvent = ToggleEvent;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (! (HTMLElement.prototype.showPopover instanceof Function)) {
|
|
50
|
+
const isPopoverOpen = el => el.classList.contains('_popover-open');
|
|
51
|
+
|
|
52
|
+
Object.defineProperties(HTMLElement.prototype, {
|
|
53
|
+
showPopover: {
|
|
54
|
+
value: function showPopover() {
|
|
55
|
+
if (! isPopoverOpen(this)) {
|
|
56
|
+
this.dispatchEvent(new ToggleEvent('beforetoggle', { oldState: 'closed', newState: 'open' }));
|
|
57
|
+
|
|
58
|
+
if (this.getAttribute('popover') === 'auto') {
|
|
59
|
+
const controller = new AbortController();
|
|
60
|
+
|
|
61
|
+
document.body.addEventListener('click', ({ target }) => {
|
|
62
|
+
if (! this.contains(target) && ! this.isSameNode(target.popoverTargetElement)) {
|
|
63
|
+
controller.abort();
|
|
64
|
+
this.hidePopover();
|
|
65
|
+
}
|
|
66
|
+
}, { signal: controller.signal, capture: true });
|
|
67
|
+
|
|
68
|
+
document.body.addEventListener('keydown', ({ key }) => {
|
|
69
|
+
if (key === 'Escape') {
|
|
70
|
+
controller.abort();
|
|
71
|
+
this.hidePopover();
|
|
72
|
+
}
|
|
73
|
+
}, { signal: controller.signal, capture: true });
|
|
74
|
+
|
|
75
|
+
document.addEventListener('beforetoggle', ({ target }) => {
|
|
76
|
+
if (! target.isSameNode(this) && target.getAttribute('popover') === 'auto') {
|
|
77
|
+
controller.abort();
|
|
78
|
+
this.hidePopover();
|
|
79
|
+
}
|
|
80
|
+
}, { signal: controller.signal });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
this.classList.add('_popover-open');
|
|
84
|
+
this.dispatchEvent(new ToggleEvent('toggle', { oldState: 'closed', newState: 'open' }));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
hidePopover: {
|
|
89
|
+
value: function hidePopover() {
|
|
90
|
+
if (isPopoverOpen(this)) {
|
|
91
|
+
this.dispatchEvent(new ToggleEvent('beforetoggle', { oldState: 'open', newState: 'closed' }));
|
|
92
|
+
queueMicrotask(() => this.classList.remove('_popover-open'));
|
|
93
|
+
this.dispatchEvent(new ToggleEvent('toggle', { oldState: 'open', newState: 'closed' }));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
togglePopover: {
|
|
98
|
+
value: function togglePopover() {
|
|
99
|
+
isPopoverOpen(this) ? this.hidePopover() : this.showPopover();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
Object.defineProperties(HTMLButtonElement.prototype, {
|
|
105
|
+
popoverTargetElement: {
|
|
106
|
+
get() {
|
|
107
|
+
return document.getElementById(this.getAttribute('popovertarget'));
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
popoverTargetAction: {
|
|
111
|
+
get() {
|
|
112
|
+
return this.getAttribute('popovertargetaction') || 'toggle';
|
|
113
|
+
},
|
|
114
|
+
set(val) {
|
|
115
|
+
this.setAttribute('popovertargetaction', val);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
initPopover();
|
|
121
|
+
}
|
|
122
|
+
|
|
6
123
|
if (! (HTMLScriptElement.supports instanceof Function)) {
|
|
7
124
|
HTMLScriptElement.supports = function supports(type) {
|
|
8
125
|
switch(type.toLowerCase()) {
|
package/iterator.js
CHANGED
|
@@ -287,6 +287,45 @@ if (! (IteratorPrototype.indexed instanceof Function)) {
|
|
|
287
287
|
};
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
+
if (! (IteratorPrototype.chunks instanceof Function)) {
|
|
291
|
+
IteratorPrototype.chunks = function(size) {
|
|
292
|
+
if (! Number.isSafeInteger(size) || size < 1) {
|
|
293
|
+
throw new TypeError('Size must be a positive integer.');
|
|
294
|
+
} else {
|
|
295
|
+
const iter = this;
|
|
296
|
+
let done = false;
|
|
297
|
+
|
|
298
|
+
return Iterator.from({
|
|
299
|
+
next() {
|
|
300
|
+
if (done) {
|
|
301
|
+
return { done };
|
|
302
|
+
} else {
|
|
303
|
+
const items = [];
|
|
304
|
+
let i = 0;
|
|
305
|
+
|
|
306
|
+
while(i++ < size && ! done) {
|
|
307
|
+
const next = iter.next();
|
|
308
|
+
|
|
309
|
+
if (next.done) {
|
|
310
|
+
done = true;
|
|
311
|
+
|
|
312
|
+
if (typeof next.value !== 'undefined') {
|
|
313
|
+
items.push(next.value);
|
|
314
|
+
}
|
|
315
|
+
break;
|
|
316
|
+
} else {
|
|
317
|
+
items.push(next.value);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return { value: items, done: false };
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
290
329
|
if (! (Iterator.from instanceof Function)) {
|
|
291
330
|
Iterator.from = function from(obj) {
|
|
292
331
|
if (typeof obj !== 'object' || obj === null) {
|
package/math.js
CHANGED
|
@@ -1,69 +1,74 @@
|
|
|
1
|
-
(
|
|
2
|
-
|
|
1
|
+
if (! Number.hasOwnProperty('isSafeInteger')) {
|
|
2
|
+
Number.MAX_SAFE_INTEGER = 2**53 -1;
|
|
3
|
+
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;
|
|
4
|
+
Number.isSafeInteger = num => num <= Number.MAX_SAFE_INTEGER && num >= Number.MIN_SAFE_INTEGER;
|
|
5
|
+
}
|
|
3
6
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Number.isSafeInteger = num => num <= Number.MAX_SAFE_INTEGER && num >= Number.MIN_SAFE_INTEGER;
|
|
8
|
-
}
|
|
7
|
+
if (! Number.hasOwnProperty('EPSILON')) {
|
|
8
|
+
Number.EPSILON = 2**-52;
|
|
9
|
+
}
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
if (! Math.hasOwnProperty('sign')) {
|
|
12
|
+
Math.sign = x => ((x > 0) - (x < 0)) || +x;
|
|
13
|
+
}
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
if (! Math.hasOwnProperty('trunc')) {
|
|
16
|
+
Math.trunc = x => {
|
|
17
|
+
const n = x - x%1;
|
|
18
|
+
return n===0 && (x<0 || (x===0 && (1/x !== 1/0))) ? -0 : n;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return n===0 && (x<0 || (x===0 && (1/x !== 1/0))) ? -0 : n;
|
|
22
|
-
};
|
|
23
|
-
}
|
|
22
|
+
if (! Math.hasOwnProperty('expm1')) {
|
|
23
|
+
Math.expm1 = x => Math.exp(x) - 1;
|
|
24
|
+
}
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
if (! Math.hasOwnProperty('hypot')) {
|
|
27
|
+
Math.hypot = (...nums) => Math.sqrt(nums.reduce((sum, num) => sum + num**2, 0));
|
|
28
|
+
}
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
if (! Math.hasOwnProperty('cbrt')) {
|
|
31
|
+
Math.cbrt = x => x**(1/3);
|
|
32
|
+
}
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
if (! Math.hasOwnProperty('log10')) {
|
|
35
|
+
Math.log10 = x => Math.log(x) * Math.LOG10E;
|
|
36
|
+
}
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
if (! Math.hasOwnProperty('log2')) {
|
|
39
|
+
Math.log2 = x => Math.log(x) * Math.LOG2E;
|
|
40
|
+
}
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
if (! Math.hasOwnProperty('log1p')) {
|
|
43
|
+
Math.log1p = x => Math.log(1 + x);
|
|
44
|
+
}
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
if (! Math.hasOwnProperty('fround')) {
|
|
47
|
+
Math.fround = (function (array) {
|
|
48
|
+
return function(x) {
|
|
49
|
+
return array[0] = x, array[0];
|
|
50
|
+
};
|
|
51
|
+
})(new Float32Array(1));
|
|
52
|
+
}
|
|
48
53
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
})(new Float32Array(1));
|
|
55
|
-
}
|
|
54
|
+
if (! (Math.clamp instanceof Function)) {
|
|
55
|
+
Math.clamp = function(value, min, max) {
|
|
56
|
+
return Math.min(Math.max(value, min), max);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
/*
|
|
61
|
+
* Question of if it will be `Math.clamp` or `Math.constrain`
|
|
62
|
+
*/
|
|
63
|
+
if (! (Math.constrain instanceof Function)) {
|
|
64
|
+
Math.constrain = Math.clamp;
|
|
65
|
+
}
|
|
62
66
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
67
|
+
/**
|
|
68
|
+
* @see https://github.com/tc39/proposal-math-sum
|
|
69
|
+
*/
|
|
70
|
+
if(! (Math.sum instanceof Function)) {
|
|
71
|
+
Math.sum = function(...nums) {
|
|
72
|
+
return nums.map(num => parseFloat(num)).reduce((sum, num) => sum + num);
|
|
73
|
+
};
|
|
74
|
+
}
|
package/package.json
CHANGED
package/popover.css
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
@supports not selector(:popover-open) {
|
|
2
|
+
:is([popover]:not(._popover-open)) {
|
|
3
|
+
display: none;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
:is([popover]._popover-open) {
|
|
7
|
+
position: fixed;
|
|
8
|
+
z-index: 2147483647;
|
|
9
|
+
margin: auto;
|
|
10
|
+
inset: 0;
|
|
11
|
+
border: 3px solid currentColor;
|
|
12
|
+
height: fit-content;
|
|
13
|
+
width: fit-content;
|
|
14
|
+
padding: 0.25em;
|
|
15
|
+
background-color: #ffffff;
|
|
16
|
+
color: #070707;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@media (prefers-color-scheme: dark) {
|
|
20
|
+
:is([popover]._popover-open) {
|
|
21
|
+
background-color: #1c1b22;
|
|
22
|
+
color: #fbfbfe;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
package/popover.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// function handlePopover({ currentTarget }) {
|
|
2
|
+
// currentTarget.addEventListener('click', ({ currentTarget }) => {
|
|
3
|
+
// switch(currentTarget.popoverTargetAction) {
|
|
4
|
+
// case 'show':
|
|
5
|
+
// currentTarget.popoverTargetElement.showPopover();
|
|
6
|
+
// break;
|
|
7
|
+
|
|
8
|
+
// case 'hide':
|
|
9
|
+
// currentTarget.popoverTargetElement.hidePopover();
|
|
10
|
+
// break;
|
|
11
|
+
|
|
12
|
+
// default:
|
|
13
|
+
// currentTarget.popoverTargetElement.togglePopover();
|
|
14
|
+
// }
|
|
15
|
+
// }, { capture: true });
|
|
16
|
+
// }
|
|
17
|
+
|
|
18
|
+
// export function initPopover(target = document.body) {
|
|
19
|
+
// target.querySelectorAll('button[popovertarget], input[type="button"][popovertarget]')
|
|
20
|
+
// .forEach(el => el.addEventListener('click', handlePopover));
|
|
21
|
+
// }
|
|
22
|
+
|
|
23
|
+
// if ((globalThis.ToggleEvent instanceof Function)) {
|
|
24
|
+
// class ToggleEvent extends Event {
|
|
25
|
+
// #newState;
|
|
26
|
+
// #oldState;
|
|
27
|
+
|
|
28
|
+
// constructor(type, { newState, oldState }) {
|
|
29
|
+
// super(type, { bubbles: true });
|
|
30
|
+
// this.#newState = newState;
|
|
31
|
+
// this.#oldState = oldState;
|
|
32
|
+
// }
|
|
33
|
+
|
|
34
|
+
// get newState() {
|
|
35
|
+
// return this.#newState;
|
|
36
|
+
// }
|
|
37
|
+
|
|
38
|
+
// get oldState() {
|
|
39
|
+
// return this.#oldState;
|
|
40
|
+
// }
|
|
41
|
+
// }
|
|
42
|
+
|
|
43
|
+
// globalThis.ToggleEvent = ToggleEvent;
|
|
44
|
+
// }
|
|
45
|
+
|
|
46
|
+
// if (! (HTMLElement.prototype.showPopover instanceof Function)) {
|
|
47
|
+
// const isPopoverOpen = el => el.classList.contains('_popover-open');
|
|
48
|
+
|
|
49
|
+
// Object.defineProperties(HTMLElement.prototype, {
|
|
50
|
+
// showPopover: {
|
|
51
|
+
// value: function showPopover() {
|
|
52
|
+
// if (! isPopoverOpen(this)) {
|
|
53
|
+
// this.dispatchEvent(new ToggleEvent('beforetoggle', { oldState: 'closed', newState: 'open' }));
|
|
54
|
+
|
|
55
|
+
// if (this.getAttribute('popover') === 'auto') {
|
|
56
|
+
// const controller = new AbortController();
|
|
57
|
+
|
|
58
|
+
// document.body.addEventListener('click', ({ target }) => {
|
|
59
|
+
// if (! this.contains(target) && ! this.isSameNode(target.popoverTargetElement)) {
|
|
60
|
+
// controller.abort();
|
|
61
|
+
// this.hidePopover();
|
|
62
|
+
// }
|
|
63
|
+
// }, { signal: controller.signal, capture: true });
|
|
64
|
+
|
|
65
|
+
// document.body.addEventListener('keydown', ({ key }) => {
|
|
66
|
+
// if (key === 'Escape') {
|
|
67
|
+
// controller.abort();
|
|
68
|
+
// this.hidePopover();
|
|
69
|
+
// }
|
|
70
|
+
// }, { signal: controller.signal, capture: true });
|
|
71
|
+
|
|
72
|
+
// document.addEventListener('beforetoggle', ({ target }) => {
|
|
73
|
+
// if (! target.isSameNode(this) && target.getAttribute('popover') === 'auto') {
|
|
74
|
+
// controller.abort();
|
|
75
|
+
// this.hidePopover();
|
|
76
|
+
// }
|
|
77
|
+
// }, { signal: controller.signal });
|
|
78
|
+
// }
|
|
79
|
+
|
|
80
|
+
// this.classList.add('_popover-open');
|
|
81
|
+
// this.dispatchEvent(new ToggleEvent('toggle', { oldState: 'closed', newState: 'open' }));
|
|
82
|
+
// }
|
|
83
|
+
// }
|
|
84
|
+
// },
|
|
85
|
+
// hidePopover: {
|
|
86
|
+
// value: function hidePopover() {
|
|
87
|
+
// if (isPopoverOpen(this)) {
|
|
88
|
+
// this.dispatchEvent(new ToggleEvent('beforetoggle', { oldState: 'open', newState: 'closed' }));
|
|
89
|
+
// queueMicrotask(() => this.classList.remove('_popover-open'));
|
|
90
|
+
// this.dispatchEvent(new ToggleEvent('toggle', { oldState: 'open', newState: 'closed' }));
|
|
91
|
+
// }
|
|
92
|
+
// }
|
|
93
|
+
// },
|
|
94
|
+
// togglePopover: {
|
|
95
|
+
// value: function togglePopover() {
|
|
96
|
+
// isPopoverOpen(this) ? this.hidePopover() : this.showPopover();
|
|
97
|
+
// }
|
|
98
|
+
// }
|
|
99
|
+
// });
|
|
100
|
+
|
|
101
|
+
// Object.defineProperties(HTMLButtonElement.prototype, {
|
|
102
|
+
// popoverTargetElement: {
|
|
103
|
+
// get() {
|
|
104
|
+
// return document.getElementById(this.getAttribute('popovertarget'));
|
|
105
|
+
// }
|
|
106
|
+
// },
|
|
107
|
+
// popoverTargetAction: {
|
|
108
|
+
// get() {
|
|
109
|
+
// return this.getAttribute('popovertargetaction') || 'toggle';
|
|
110
|
+
// },
|
|
111
|
+
// set(val) {
|
|
112
|
+
// this.setAttribute('popovertargetaction', val);
|
|
113
|
+
// }
|
|
114
|
+
// }
|
|
115
|
+
// });
|
|
116
|
+
|
|
117
|
+
// initPopover();
|
|
118
|
+
// }
|