@antv/infographic 0.2.17 → 0.2.18
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/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/infographic.min.js +99 -99
- package/dist/infographic.min.js.map +1 -1
- package/esm/constants/service.d.ts +1 -1
- package/esm/constants/service.js +1 -1
- package/esm/designs/structures/chart-line.js +5 -3
- package/esm/editor/interactions/dblclick-edit-text.js +3 -3
- package/esm/editor/managers/interaction.js +6 -4
- package/esm/editor/plugins/components/button.d.ts +2 -1
- package/esm/editor/plugins/components/button.js +4 -4
- package/esm/editor/plugins/components/color-picker.d.ts +1 -0
- package/esm/editor/plugins/components/color-picker.js +3 -3
- package/esm/editor/plugins/components/popover.d.ts +3 -1
- package/esm/editor/plugins/components/popover.js +29 -9
- package/esm/editor/plugins/edit-bar/edit-bar.d.ts +3 -1
- package/esm/editor/plugins/edit-bar/edit-bar.js +17 -7
- package/esm/editor/plugins/edit-bar/edit-items/align-elements.js +6 -4
- package/esm/editor/plugins/edit-bar/edit-items/font-align.js +8 -5
- package/esm/editor/plugins/edit-bar/edit-items/font-color.js +7 -4
- package/esm/editor/plugins/edit-bar/edit-items/font-family.js +11 -9
- package/esm/editor/plugins/edit-bar/edit-items/font-size.js +8 -5
- package/esm/editor/plugins/edit-bar/edit-items/icon-color.js +7 -4
- package/esm/editor/plugins/edit-bar/edit-items/types.d.ts +5 -1
- package/esm/editor/plugins/reset-viewbox.d.ts +4 -1
- package/esm/editor/plugins/reset-viewbox.js +12 -6
- package/esm/editor/utils/index.d.ts +1 -0
- package/esm/editor/utils/index.js +1 -0
- package/esm/editor/utils/root.d.ts +3 -0
- package/esm/editor/utils/root.js +18 -0
- package/esm/exporter/svg.js +63 -3
- package/esm/resource/loaders/search.js +0 -3
- package/esm/templates/utils.js +11 -6
- package/esm/utils/padding.js +1 -1
- package/esm/utils/style.d.ts +3 -1
- package/esm/utils/style.js +27 -4
- package/esm/version.d.ts +1 -1
- package/esm/version.js +1 -1
- package/lib/constants/service.d.ts +1 -1
- package/lib/constants/service.js +1 -1
- package/lib/designs/structures/chart-line.js +5 -3
- package/lib/editor/interactions/dblclick-edit-text.js +3 -3
- package/lib/editor/managers/interaction.js +7 -5
- package/lib/editor/plugins/components/button.d.ts +2 -1
- package/lib/editor/plugins/components/button.js +4 -4
- package/lib/editor/plugins/components/color-picker.d.ts +1 -0
- package/lib/editor/plugins/components/color-picker.js +3 -3
- package/lib/editor/plugins/components/popover.d.ts +3 -1
- package/lib/editor/plugins/components/popover.js +32 -12
- package/lib/editor/plugins/edit-bar/edit-bar.d.ts +3 -1
- package/lib/editor/plugins/edit-bar/edit-bar.js +17 -7
- package/lib/editor/plugins/edit-bar/edit-items/align-elements.js +6 -4
- package/lib/editor/plugins/edit-bar/edit-items/font-align.js +8 -5
- package/lib/editor/plugins/edit-bar/edit-items/font-color.js +7 -4
- package/lib/editor/plugins/edit-bar/edit-items/font-family.js +11 -9
- package/lib/editor/plugins/edit-bar/edit-items/font-size.js +8 -5
- package/lib/editor/plugins/edit-bar/edit-items/icon-color.js +7 -4
- package/lib/editor/plugins/edit-bar/edit-items/types.d.ts +5 -1
- package/lib/editor/plugins/reset-viewbox.d.ts +4 -1
- package/lib/editor/plugins/reset-viewbox.js +12 -6
- package/lib/editor/utils/index.d.ts +1 -0
- package/lib/editor/utils/index.js +1 -0
- package/lib/editor/utils/root.d.ts +3 -0
- package/lib/editor/utils/root.js +22 -0
- package/lib/exporter/svg.js +63 -3
- package/lib/resource/loaders/search.js +0 -3
- package/lib/templates/utils.js +11 -6
- package/lib/utils/padding.js +1 -1
- package/lib/utils/style.d.ts +3 -1
- package/lib/utils/style.js +27 -4
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/src/constants/service.ts +1 -1
- package/src/designs/structures/chart-line.tsx +5 -3
- package/src/editor/interactions/dblclick-edit-text.ts +3 -2
- package/src/editor/managers/interaction.ts +9 -7
- package/src/editor/plugins/components/button.ts +5 -2
- package/src/editor/plugins/components/color-picker.ts +4 -2
- package/src/editor/plugins/components/popover.ts +31 -12
- package/src/editor/plugins/edit-bar/edit-bar.ts +26 -11
- package/src/editor/plugins/edit-bar/edit-items/align-elements.ts +7 -2
- package/src/editor/plugins/edit-bar/edit-items/font-align.ts +8 -3
- package/src/editor/plugins/edit-bar/edit-items/font-color.ts +7 -2
- package/src/editor/plugins/edit-bar/edit-items/font-family.ts +11 -7
- package/src/editor/plugins/edit-bar/edit-items/font-size.ts +8 -3
- package/src/editor/plugins/edit-bar/edit-items/icon-color.ts +7 -2
- package/src/editor/plugins/edit-bar/edit-items/types.ts +6 -1
- package/src/editor/plugins/reset-viewbox.ts +17 -8
- package/src/editor/utils/index.ts +1 -0
- package/src/editor/utils/root.ts +26 -0
- package/src/exporter/svg.ts +80 -3
- package/src/resource/loaders/search.ts +0 -3
- package/src/templates/utils.ts +30 -6
- package/src/utils/padding.ts +1 -1
- package/src/utils/style.ts +31 -4
- package/src/version.ts +1 -1
|
@@ -12,8 +12,10 @@ export const IconColor: EditItem<IconAttributes> = (
|
|
|
12
12
|
selection,
|
|
13
13
|
attrs,
|
|
14
14
|
commander,
|
|
15
|
+
options,
|
|
15
16
|
) => {
|
|
16
|
-
|
|
17
|
+
const root = options?.root;
|
|
18
|
+
ensureIconColorStyles(root);
|
|
17
19
|
|
|
18
20
|
const color = normalizeColor(attrs.fill);
|
|
19
21
|
const isMixed = attrs.fill === undefined && selection.length > 1;
|
|
@@ -24,6 +26,7 @@ export const IconColor: EditItem<IconAttributes> = (
|
|
|
24
26
|
setButtonColor(button, color ?? DEFAULT_COLOR, isMixed);
|
|
25
27
|
|
|
26
28
|
const picker = ColorPicker({
|
|
29
|
+
root,
|
|
27
30
|
value: color ?? DEFAULT_COLOR,
|
|
28
31
|
onChange: (nextColor) => {
|
|
29
32
|
setButtonColor(button, nextColor, false);
|
|
@@ -41,6 +44,7 @@ export const IconColor: EditItem<IconAttributes> = (
|
|
|
41
44
|
return Popover({
|
|
42
45
|
target: button,
|
|
43
46
|
content: picker,
|
|
47
|
+
getContainer: root,
|
|
44
48
|
placement: ['top', 'bottom'],
|
|
45
49
|
offset: 12,
|
|
46
50
|
trigger: 'hover',
|
|
@@ -65,7 +69,7 @@ function setButtonColor(
|
|
|
65
69
|
else button.removeAttribute('data-mixed');
|
|
66
70
|
}
|
|
67
71
|
|
|
68
|
-
function ensureIconColorStyles() {
|
|
72
|
+
function ensureIconColorStyles(target?: Node) {
|
|
69
73
|
injectStyleOnce(
|
|
70
74
|
ICON_COLOR_STYLE_ID,
|
|
71
75
|
`
|
|
@@ -97,5 +101,6 @@ function ensureIconColorStyles() {
|
|
|
97
101
|
);
|
|
98
102
|
}
|
|
99
103
|
`,
|
|
104
|
+
target,
|
|
100
105
|
);
|
|
101
106
|
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { BaseAttributes } from '../../../../types';
|
|
2
2
|
import type { ICommandManager, Selection } from '../../../types';
|
|
3
3
|
|
|
4
|
+
export type EditItemOptions = {
|
|
5
|
+
root?: HTMLElement | ShadowRoot;
|
|
6
|
+
[key: string]: any;
|
|
7
|
+
};
|
|
8
|
+
|
|
4
9
|
export type EditItem<T extends BaseAttributes = BaseAttributes> = (
|
|
5
10
|
selection: Selection,
|
|
6
11
|
attrs: T,
|
|
7
12
|
commander: ICommandManager,
|
|
8
|
-
options?:
|
|
13
|
+
options?: EditItemOptions,
|
|
9
14
|
) => HTMLElement;
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from '../../utils';
|
|
10
10
|
import { UpdateOptionsCommand } from '../commands';
|
|
11
11
|
import type { IPlugin, PluginInitOptions } from '../types';
|
|
12
|
+
import { getOverlayContainer } from '../utils';
|
|
12
13
|
import { Plugin } from './base';
|
|
13
14
|
import { IconButton } from './components';
|
|
14
15
|
import { RESET_ICON } from './components/icons';
|
|
@@ -19,9 +20,11 @@ const BUTTON_SIZE = 40;
|
|
|
19
20
|
export interface ResetViewBoxOptions {
|
|
20
21
|
style?: Partial<CSSStyleDeclaration>;
|
|
21
22
|
className?: string;
|
|
22
|
-
getContainer?:
|
|
23
|
+
getContainer?: OverlayRoot | (() => OverlayRoot);
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
type OverlayRoot = HTMLElement | ShadowRoot;
|
|
27
|
+
|
|
25
28
|
export class ResetViewBox extends Plugin implements IPlugin {
|
|
26
29
|
name = 'reset-viewBox';
|
|
27
30
|
|
|
@@ -38,7 +41,7 @@ export class ResetViewBox extends Plugin implements IPlugin {
|
|
|
38
41
|
super.init(options);
|
|
39
42
|
|
|
40
43
|
// Initialize originViewBox
|
|
41
|
-
this.ensureButtonStyle();
|
|
44
|
+
this.ensureButtonStyle(this.resolveOverlayRoot());
|
|
42
45
|
this.updateOriginViewBox();
|
|
43
46
|
|
|
44
47
|
this.unregisterSync = this.editor.registerSync(
|
|
@@ -91,10 +94,13 @@ export class ResetViewBox extends Plugin implements IPlugin {
|
|
|
91
94
|
if (this.resetButton) return this.resetButton;
|
|
92
95
|
|
|
93
96
|
const { style, className } = this.options || {};
|
|
97
|
+
const containerParent = this.resolveOverlayRoot();
|
|
98
|
+
this.ensureButtonStyle(containerParent);
|
|
94
99
|
|
|
95
100
|
const button = IconButton({
|
|
96
101
|
icon: RESET_ICON,
|
|
97
102
|
onClick: this.resetViewBox,
|
|
103
|
+
root: containerParent,
|
|
98
104
|
});
|
|
99
105
|
|
|
100
106
|
button.classList.add(RESET_BUTTON_CLASS);
|
|
@@ -111,11 +117,6 @@ export class ResetViewBox extends Plugin implements IPlugin {
|
|
|
111
117
|
|
|
112
118
|
this.resetButton = button;
|
|
113
119
|
|
|
114
|
-
const { getContainer } = this.options || {};
|
|
115
|
-
const resolvedContainer =
|
|
116
|
-
typeof getContainer === 'function' ? getContainer() : getContainer;
|
|
117
|
-
const containerParent = resolvedContainer ?? document.body;
|
|
118
|
-
|
|
119
120
|
containerParent?.appendChild(button);
|
|
120
121
|
|
|
121
122
|
return button;
|
|
@@ -229,7 +230,14 @@ export class ResetViewBox extends Plugin implements IPlugin {
|
|
|
229
230
|
this.resetButton = undefined;
|
|
230
231
|
};
|
|
231
232
|
|
|
232
|
-
private
|
|
233
|
+
private resolveOverlayRoot(): OverlayRoot {
|
|
234
|
+
const { getContainer } = this.options || {};
|
|
235
|
+
const resolvedContainer =
|
|
236
|
+
typeof getContainer === 'function' ? getContainer() : getContainer;
|
|
237
|
+
return resolvedContainer ?? getOverlayContainer(this.editor.getDocument());
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
private ensureButtonStyle(target?: Node) {
|
|
233
241
|
injectStyleOnce(
|
|
234
242
|
RESET_BUTTON_STYLE_ID,
|
|
235
243
|
`
|
|
@@ -250,6 +258,7 @@ export class ResetViewBox extends Plugin implements IPlugin {
|
|
|
250
258
|
cursor: pointer;
|
|
251
259
|
}
|
|
252
260
|
`,
|
|
261
|
+
target,
|
|
253
262
|
);
|
|
254
263
|
}
|
|
255
264
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type OverlayContainer = HTMLElement | ShadowRoot;
|
|
2
|
+
|
|
3
|
+
function getConnectedRoot(node?: Node | null): Document | ShadowRoot {
|
|
4
|
+
if (!node?.isConnected) return document;
|
|
5
|
+
|
|
6
|
+
const root = node.getRootNode();
|
|
7
|
+
return root instanceof ShadowRoot ? root : document;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function getOverlayContainer(node?: Node | null): OverlayContainer {
|
|
11
|
+
const root = getConnectedRoot(node);
|
|
12
|
+
return root instanceof ShadowRoot ? root : document.body;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function eventPathContains(event: Event, node: Node) {
|
|
16
|
+
const path = typeof event.composedPath === 'function' ? event.composedPath() : [];
|
|
17
|
+
if (path.length > 0) {
|
|
18
|
+
return path.some(
|
|
19
|
+
(current) =>
|
|
20
|
+
current === node || (current instanceof Node && node.contains(current)),
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const target = event.target;
|
|
25
|
+
return target instanceof Node && (target === node || node.contains(target));
|
|
26
|
+
}
|
package/src/exporter/svg.ts
CHANGED
|
@@ -26,7 +26,12 @@ function getExportViewBox(svg: SVGSVGElement) {
|
|
|
26
26
|
|
|
27
27
|
const width = parseAbsoluteLength(svg.getAttribute('width'));
|
|
28
28
|
const height = parseAbsoluteLength(svg.getAttribute('height'));
|
|
29
|
-
if (
|
|
29
|
+
if (
|
|
30
|
+
!Number.isNaN(width) &&
|
|
31
|
+
width > 0 &&
|
|
32
|
+
!Number.isNaN(height) &&
|
|
33
|
+
height > 0
|
|
34
|
+
) {
|
|
30
35
|
return { x: 0, y: 0, width, height };
|
|
31
36
|
}
|
|
32
37
|
|
|
@@ -253,7 +258,9 @@ async function embedIcons(svg: SVGSVGElement) {
|
|
|
253
258
|
|
|
254
259
|
if (!existsSymbol) {
|
|
255
260
|
const symbolElement = document.querySelector(href);
|
|
256
|
-
if (symbolElement)
|
|
261
|
+
if (symbolElement) {
|
|
262
|
+
defs.appendChild(symbolElement.cloneNode(true));
|
|
263
|
+
}
|
|
257
264
|
}
|
|
258
265
|
});
|
|
259
266
|
}
|
|
@@ -487,6 +494,7 @@ function collectDefElements(svg: SVGSVGElement, ids: Set<string>) {
|
|
|
487
494
|
|
|
488
495
|
while (queue.length) {
|
|
489
496
|
const id = queue.shift()!;
|
|
497
|
+
if (!id) continue;
|
|
490
498
|
if (visited.has(id)) continue;
|
|
491
499
|
visited.add(id);
|
|
492
500
|
|
|
@@ -503,11 +511,80 @@ function collectDefElements(svg: SVGSVGElement, ids: Set<string>) {
|
|
|
503
511
|
return collected;
|
|
504
512
|
}
|
|
505
513
|
|
|
514
|
+
// Fallback implementation based on the CSS.escape algorithm
|
|
515
|
+
function cssEscape(value: string): string {
|
|
516
|
+
const string = String(value);
|
|
517
|
+
const length = string.length;
|
|
518
|
+
let result = '';
|
|
519
|
+
|
|
520
|
+
if (length === 0) {
|
|
521
|
+
return '';
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
for (let i = 0; i < length; i++) {
|
|
525
|
+
const codeUnit = string.charCodeAt(i);
|
|
526
|
+
|
|
527
|
+
// Null character
|
|
528
|
+
if (codeUnit === 0x0000) {
|
|
529
|
+
result += '\uFFFD';
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// Control characters or DEL
|
|
534
|
+
if ((codeUnit >= 0x0001 && codeUnit <= 0x001f) || codeUnit === 0x007f) {
|
|
535
|
+
result += '\\' + codeUnit.toString(16) + ' ';
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// Escape if first character is a digit
|
|
540
|
+
if (i === 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) {
|
|
541
|
+
result += '\\' + codeUnit.toString(16) + ' ';
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// Escape if second character is a digit and first is a hyphen
|
|
546
|
+
if (
|
|
547
|
+
i === 1 &&
|
|
548
|
+
codeUnit >= 0x0030 &&
|
|
549
|
+
codeUnit <= 0x0039 &&
|
|
550
|
+
string.charCodeAt(0) === 0x002d
|
|
551
|
+
) {
|
|
552
|
+
result += '\\' + codeUnit.toString(16) + ' ';
|
|
553
|
+
continue;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// If the character is the first and is a hyphen followed by end of string, escape it
|
|
557
|
+
if (i === 0 && length === 1 && codeUnit === 0x002d) {
|
|
558
|
+
result += '\\' + string.charAt(i);
|
|
559
|
+
continue;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// Characters that are safe to use unescaped
|
|
563
|
+
if (
|
|
564
|
+
codeUnit >= 0x0080 ||
|
|
565
|
+
(codeUnit >= 0x0030 && codeUnit <= 0x0039) || // 0-9
|
|
566
|
+
(codeUnit >= 0x0041 && codeUnit <= 0x005a) || // A-Z
|
|
567
|
+
(codeUnit >= 0x0061 && codeUnit <= 0x007a) || // a-z
|
|
568
|
+
codeUnit === 0x002d || // -
|
|
569
|
+
codeUnit === 0x005f // _
|
|
570
|
+
) {
|
|
571
|
+
result += string.charAt(i);
|
|
572
|
+
continue;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// All other characters
|
|
576
|
+
result += '\\' + string.charAt(i);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
return result;
|
|
580
|
+
}
|
|
581
|
+
|
|
506
582
|
function escapeCssId(id: string) {
|
|
507
583
|
if (globalThis.CSS && typeof globalThis.CSS.escape === 'function') {
|
|
508
584
|
return globalThis.CSS.escape(id);
|
|
509
585
|
}
|
|
510
|
-
|
|
586
|
+
|
|
587
|
+
return cssEscape(id);
|
|
511
588
|
}
|
|
512
589
|
|
|
513
590
|
function removeDefs(svg: SVGSVGElement) {
|
|
@@ -43,9 +43,6 @@ export async function loadSearchResource(query: string, format?: string) {
|
|
|
43
43
|
const svgText = commaIndex >= 0 ? result.slice(commaIndex + 1) : result;
|
|
44
44
|
return loadSVGResource(svgText);
|
|
45
45
|
}
|
|
46
|
-
if (mimeType === 'image/svg+xml' && format === 'svg' && isBase64) {
|
|
47
|
-
return loadImageBase64Resource(result);
|
|
48
|
-
}
|
|
49
46
|
return loadImageBase64Resource(result);
|
|
50
47
|
}
|
|
51
48
|
|
package/src/templates/utils.ts
CHANGED
|
@@ -43,13 +43,34 @@ function getCommonPrefixLength(source: string, target: string): number {
|
|
|
43
43
|
const limit = Math.min(source.length, target.length);
|
|
44
44
|
let index = 0;
|
|
45
45
|
|
|
46
|
-
while (
|
|
46
|
+
while (
|
|
47
|
+
index < limit &&
|
|
48
|
+
source.charCodeAt(index) === target.charCodeAt(index)
|
|
49
|
+
) {
|
|
47
50
|
index += 1;
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
return index;
|
|
51
54
|
}
|
|
52
55
|
|
|
56
|
+
function isBetterMatch(
|
|
57
|
+
bestMatch: string | undefined,
|
|
58
|
+
bestDistance: number,
|
|
59
|
+
bestPrefixLength: number,
|
|
60
|
+
candidateKey: string,
|
|
61
|
+
candidateDistance: number,
|
|
62
|
+
candidatePrefixLength: number,
|
|
63
|
+
): boolean {
|
|
64
|
+
return (
|
|
65
|
+
candidateDistance < bestDistance ||
|
|
66
|
+
(candidateDistance === bestDistance &&
|
|
67
|
+
candidatePrefixLength > bestPrefixLength) ||
|
|
68
|
+
(candidateDistance === bestDistance &&
|
|
69
|
+
candidatePrefixLength === bestPrefixLength &&
|
|
70
|
+
(!bestMatch || candidateKey < bestMatch))
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
53
74
|
export function findClosestTemplateKey(
|
|
54
75
|
type: string,
|
|
55
76
|
keys: Iterable<string>,
|
|
@@ -71,11 +92,14 @@ export function findClosestTemplateKey(
|
|
|
71
92
|
const prefixLength = getCommonPrefixLength(normalizedType, normalizedKey);
|
|
72
93
|
|
|
73
94
|
if (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
95
|
+
isBetterMatch(
|
|
96
|
+
bestMatch,
|
|
97
|
+
bestDistance,
|
|
98
|
+
bestPrefixLength,
|
|
99
|
+
key,
|
|
100
|
+
distance,
|
|
101
|
+
prefixLength,
|
|
102
|
+
)
|
|
79
103
|
) {
|
|
80
104
|
bestMatch = key;
|
|
81
105
|
bestDistance = distance;
|
package/src/utils/padding.ts
CHANGED
|
@@ -27,7 +27,7 @@ export function setSVGPadding(svg: SVGSVGElement, padding: ParsedPadding) {
|
|
|
27
27
|
if (isNode) {
|
|
28
28
|
setSVGPaddingInNode(svg, padding);
|
|
29
29
|
} else {
|
|
30
|
-
if (
|
|
30
|
+
if (svg.isConnected) {
|
|
31
31
|
setSVGPaddingInBrowser(svg, padding);
|
|
32
32
|
} else {
|
|
33
33
|
try {
|
package/src/utils/style.ts
CHANGED
|
@@ -1,8 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
if (document.getElementById(id)) return;
|
|
1
|
+
type StyleTarget = Document | ShadowRoot | Node | null | undefined;
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
function resolveStyleRoot(target?: StyleTarget): Document | ShadowRoot {
|
|
4
|
+
if (!target) return document;
|
|
5
|
+
if (target instanceof Document || target instanceof ShadowRoot) return target;
|
|
6
|
+
if (!target.isConnected) return document;
|
|
7
|
+
|
|
8
|
+
const root = target.getRootNode();
|
|
9
|
+
return root instanceof ShadowRoot ? root : document;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function hasStyle(root: Document | ShadowRoot, id: string) {
|
|
13
|
+
if (root instanceof Document) return Boolean(root.getElementById(id));
|
|
14
|
+
return Boolean(root.querySelector(`#${id}`));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function injectStyleOnce(
|
|
18
|
+
id: string,
|
|
19
|
+
styles: string,
|
|
20
|
+
target?: StyleTarget,
|
|
21
|
+
) {
|
|
22
|
+
const root = resolveStyleRoot(target);
|
|
23
|
+
if (hasStyle(root, id)) return;
|
|
24
|
+
|
|
25
|
+
const doc = root instanceof Document ? root : (root.ownerDocument ?? document);
|
|
26
|
+
const style = doc.createElement('style');
|
|
5
27
|
style.id = id;
|
|
6
28
|
style.textContent = styles;
|
|
7
|
-
|
|
29
|
+
|
|
30
|
+
if (root instanceof Document) {
|
|
31
|
+
root.head.appendChild(style);
|
|
32
|
+
} else {
|
|
33
|
+
root.appendChild(style);
|
|
34
|
+
}
|
|
8
35
|
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.2.
|
|
1
|
+
export const VERSION = '0.2.18';
|