jvetrau-ds 0.2.16 → 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/components/choice-group/choice-group.cjs +34 -0
- package/components/choice-group/choice-group.cjs.map +1 -0
- package/components/choice-group/choice-group.css +50 -0
- package/components/choice-group/choice-group.d.ts +8 -0
- package/components/choice-group/choice-group.js +32 -0
- package/components/choice-group/choice-group.js.map +1 -0
- package/components/choice-group/choice-group.meta.d.ts +2 -0
- package/components/choice-group/index.cjs +22 -0
- package/components/choice-group/index.cjs.map +1 -0
- package/components/choice-group/index.d.ts +3 -0
- package/components/choice-group/index.js +3 -0
- package/components/choice-group/index.js.map +1 -0
- package/components/embed-viewer/embed-viewer.cjs +91 -3
- package/components/embed-viewer/embed-viewer.cjs.map +1 -1
- package/components/embed-viewer/embed-viewer.d.ts +3 -0
- package/components/embed-viewer/embed-viewer.js +86 -3
- package/components/embed-viewer/embed-viewer.js.map +1 -1
- package/components/embed-viewer/open-graph.cjs +61 -0
- package/components/embed-viewer/open-graph.cjs.map +1 -0
- package/components/embed-viewer/open-graph.d.ts +5 -0
- package/components/embed-viewer/open-graph.js +59 -0
- package/components/embed-viewer/open-graph.js.map +1 -0
- package/components/embed-viewer/providers/figma.cjs +44 -0
- package/components/embed-viewer/providers/figma.cjs.map +1 -0
- package/components/embed-viewer/providers/figma.d.ts +4 -0
- package/components/embed-viewer/providers/figma.js +42 -0
- package/components/embed-viewer/providers/figma.js.map +1 -0
- package/components/embed-viewer/providers/google.cjs +78 -0
- package/components/embed-viewer/providers/google.cjs.map +1 -0
- package/components/embed-viewer/providers/google.d.ts +5 -0
- package/components/embed-viewer/providers/google.js +76 -0
- package/components/embed-viewer/providers/google.js.map +1 -0
- package/components/embed-viewer/providers/miro.cjs +37 -0
- package/components/embed-viewer/providers/miro.cjs.map +1 -0
- package/components/embed-viewer/providers/miro.d.ts +4 -0
- package/components/embed-viewer/providers/miro.js +35 -0
- package/components/embed-viewer/providers/miro.js.map +1 -0
- package/components/embed-viewer/resolver.cjs +64 -0
- package/components/embed-viewer/resolver.cjs.map +1 -0
- package/components/embed-viewer/resolver.d.ts +15 -0
- package/components/embed-viewer/resolver.js +62 -0
- package/components/embed-viewer/resolver.js.map +1 -0
- package/components/index.cjs +6 -0
- package/components/index.d.ts +2 -0
- package/components/index.js +1 -0
- package/index.cjs +6 -0
- package/index.d.ts +2 -0
- package/index.js +1 -0
- package/package.json +1 -1
- package/styles.css +52 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
require('./choice-group.css');
|
|
5
|
+
var classnames = require('../helpers/classnames');
|
|
6
|
+
|
|
7
|
+
const ChoiceGroup = ({
|
|
8
|
+
direction = "column",
|
|
9
|
+
className = "",
|
|
10
|
+
children,
|
|
11
|
+
...props
|
|
12
|
+
}) => {
|
|
13
|
+
const classes = classnames.classnames(
|
|
14
|
+
"choice-group",
|
|
15
|
+
className,
|
|
16
|
+
{
|
|
17
|
+
"choice-group--row": direction === "row",
|
|
18
|
+
"choice-group--column": direction === "column"
|
|
19
|
+
}
|
|
20
|
+
);
|
|
21
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
22
|
+
"div",
|
|
23
|
+
{
|
|
24
|
+
className: classes,
|
|
25
|
+
...props,
|
|
26
|
+
children
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
var choice_group_default = ChoiceGroup;
|
|
31
|
+
|
|
32
|
+
module.exports = choice_group_default;
|
|
33
|
+
//# sourceMappingURL=choice-group.cjs.map
|
|
34
|
+
//# sourceMappingURL=choice-group.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/choice-group/choice-group.tsx"],"names":["classnames","jsx"],"mappings":";;;;;;AAcA,MAAM,cAEF,CAAC;AAAA,EACH,SAAA,GAAY,QAAA;AAAA,EACZ,SAAA,GAAY,EAAA;AAAA,EACZ,QAAA;AAAA,EACA,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,OAAA,GAAUA,qBAAA;AAAA,IACd,cAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,MACE,qBACE,SAAA,KAAc,KAAA;AAAA,MAChB,wBACE,SAAA,KAAc;AAAA;AAClB,GACF;AAEA,EAAA,uBACEC,cAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,OAAA;AAAA,MACV,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ,CAAA;AAEA,IAAO,oBAAA,GAAQ","file":"choice-group.cjs","sourcesContent":["import React from 'react';\n\nimport './choice-group.css';\nimport { classnames } from '../helpers/classnames';\n\nexport type ChoiceGroupDirection =\n | 'column'\n | 'row';\n\nexport interface ChoiceGroupProps\n extends React.HTMLAttributes<HTMLDivElement> {\n direction?: ChoiceGroupDirection;\n}\n\nconst ChoiceGroup: React.FC<\n ChoiceGroupProps\n> = ({\n direction = 'column',\n className = '',\n children,\n ...props\n}) => {\n const classes = classnames(\n 'choice-group',\n className,\n {\n 'choice-group--row':\n direction === 'row',\n 'choice-group--column':\n direction === 'column',\n },\n );\n\n return (\n <div\n className={classes}\n {...props}\n >\n {children}\n </div>\n );\n};\n\nexport default ChoiceGroup;\n"]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
.choice-group {
|
|
2
|
+
/* color */
|
|
3
|
+
|
|
4
|
+
/* typography */
|
|
5
|
+
|
|
6
|
+
/* size */
|
|
7
|
+
display: flex;
|
|
8
|
+
gap: var(--margin-choice);
|
|
9
|
+
|
|
10
|
+
min-width: 0;
|
|
11
|
+
|
|
12
|
+
/* border */
|
|
13
|
+
|
|
14
|
+
/* depth */
|
|
15
|
+
|
|
16
|
+
/* motion */
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.choice-group--column {
|
|
20
|
+
/* color */
|
|
21
|
+
|
|
22
|
+
/* typography */
|
|
23
|
+
|
|
24
|
+
/* size */
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
align-items: flex-start;
|
|
27
|
+
|
|
28
|
+
/* border */
|
|
29
|
+
|
|
30
|
+
/* depth */
|
|
31
|
+
|
|
32
|
+
/* motion */
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.choice-group--row {
|
|
36
|
+
/* color */
|
|
37
|
+
|
|
38
|
+
/* typography */
|
|
39
|
+
|
|
40
|
+
/* size */
|
|
41
|
+
flex-direction: row;
|
|
42
|
+
flex-wrap: wrap;
|
|
43
|
+
align-items: center;
|
|
44
|
+
|
|
45
|
+
/* border */
|
|
46
|
+
|
|
47
|
+
/* depth */
|
|
48
|
+
|
|
49
|
+
/* motion */
|
|
50
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import './choice-group.css';
|
|
3
|
+
export type ChoiceGroupDirection = 'column' | 'row';
|
|
4
|
+
export interface ChoiceGroupProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
direction?: ChoiceGroupDirection;
|
|
6
|
+
}
|
|
7
|
+
declare const ChoiceGroup: React.FC<ChoiceGroupProps>;
|
|
8
|
+
export default ChoiceGroup;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import './choice-group.css';
|
|
3
|
+
import { classnames } from '../helpers/classnames';
|
|
4
|
+
|
|
5
|
+
const ChoiceGroup = ({
|
|
6
|
+
direction = "column",
|
|
7
|
+
className = "",
|
|
8
|
+
children,
|
|
9
|
+
...props
|
|
10
|
+
}) => {
|
|
11
|
+
const classes = classnames(
|
|
12
|
+
"choice-group",
|
|
13
|
+
className,
|
|
14
|
+
{
|
|
15
|
+
"choice-group--row": direction === "row",
|
|
16
|
+
"choice-group--column": direction === "column"
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
return /* @__PURE__ */ jsx(
|
|
20
|
+
"div",
|
|
21
|
+
{
|
|
22
|
+
className: classes,
|
|
23
|
+
...props,
|
|
24
|
+
children
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
var choice_group_default = ChoiceGroup;
|
|
29
|
+
|
|
30
|
+
export { choice_group_default as default };
|
|
31
|
+
//# sourceMappingURL=choice-group.js.map
|
|
32
|
+
//# sourceMappingURL=choice-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/choice-group/choice-group.tsx"],"names":[],"mappings":";;;;AAcA,MAAM,cAEF,CAAC;AAAA,EACH,SAAA,GAAY,QAAA;AAAA,EACZ,SAAA,GAAY,EAAA;AAAA,EACZ,QAAA;AAAA,EACA,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,OAAA,GAAU,UAAA;AAAA,IACd,cAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,MACE,qBACE,SAAA,KAAc,KAAA;AAAA,MAChB,wBACE,SAAA,KAAc;AAAA;AAClB,GACF;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,OAAA;AAAA,MACV,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ,CAAA;AAEA,IAAO,oBAAA,GAAQ","file":"choice-group.js","sourcesContent":["import React from 'react';\n\nimport './choice-group.css';\nimport { classnames } from '../helpers/classnames';\n\nexport type ChoiceGroupDirection =\n | 'column'\n | 'row';\n\nexport interface ChoiceGroupProps\n extends React.HTMLAttributes<HTMLDivElement> {\n direction?: ChoiceGroupDirection;\n}\n\nconst ChoiceGroup: React.FC<\n ChoiceGroupProps\n> = ({\n direction = 'column',\n className = '',\n children,\n ...props\n}) => {\n const classes = classnames(\n 'choice-group',\n className,\n {\n 'choice-group--row':\n direction === 'row',\n 'choice-group--column':\n direction === 'column',\n },\n );\n\n return (\n <div\n className={classes}\n {...props}\n >\n {children}\n </div>\n );\n};\n\nexport default ChoiceGroup;\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var choiceGroup = require('./choice-group');
|
|
6
|
+
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var choiceGroup__default = /*#__PURE__*/_interopDefault(choiceGroup);
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
Object.defineProperty(exports, "ChoiceGroup", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return choiceGroup__default.default; }
|
|
16
|
+
});
|
|
17
|
+
Object.defineProperty(exports, "default", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: function () { return choiceGroup__default.default; }
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=index.cjs.map
|
|
22
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs","sourcesContent":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
|
@@ -1,13 +1,33 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var react = require('react');
|
|
4
5
|
require('./embed-viewer.css');
|
|
6
|
+
var ActionGroup = require('../action-group');
|
|
7
|
+
var Button = require('../button');
|
|
5
8
|
var classnames = require('../helpers/classnames');
|
|
9
|
+
var openGraph = require('./open-graph');
|
|
10
|
+
var resolver = require('./resolver');
|
|
6
11
|
|
|
12
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
+
|
|
14
|
+
var ActionGroup__default = /*#__PURE__*/_interopDefault(ActionGroup);
|
|
15
|
+
var Button__default = /*#__PURE__*/_interopDefault(Button);
|
|
16
|
+
|
|
17
|
+
function openUrl(url) {
|
|
18
|
+
window.open(
|
|
19
|
+
url,
|
|
20
|
+
"_blank",
|
|
21
|
+
"noopener,noreferrer"
|
|
22
|
+
);
|
|
23
|
+
}
|
|
7
24
|
const EmbedViewer = ({
|
|
8
25
|
src,
|
|
26
|
+
embedSrc,
|
|
9
27
|
iframeTitle,
|
|
10
28
|
description,
|
|
29
|
+
showTemplateAction = false,
|
|
30
|
+
showOpenAction = false,
|
|
11
31
|
actions,
|
|
12
32
|
className = "",
|
|
13
33
|
...props
|
|
@@ -17,6 +37,43 @@ const EmbedViewer = ({
|
|
|
17
37
|
className,
|
|
18
38
|
{}
|
|
19
39
|
);
|
|
40
|
+
const resolvedResource = resolver.resolveEmbedResource({
|
|
41
|
+
src,
|
|
42
|
+
embedSrc
|
|
43
|
+
});
|
|
44
|
+
const [
|
|
45
|
+
previewImageUrl,
|
|
46
|
+
setPreviewImageUrl
|
|
47
|
+
] = react.useState(
|
|
48
|
+
null
|
|
49
|
+
);
|
|
50
|
+
react.useEffect(() => {
|
|
51
|
+
setPreviewImageUrl(null);
|
|
52
|
+
if (resolvedResource.embedUrl || !resolvedResource.sourceUrl) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const controller = new AbortController();
|
|
56
|
+
void openGraph.resolveOpenGraphImage(
|
|
57
|
+
resolvedResource.sourceUrl,
|
|
58
|
+
controller.signal
|
|
59
|
+
).then((imageUrl) => {
|
|
60
|
+
if (!controller.signal.aborted) {
|
|
61
|
+
setPreviewImageUrl(
|
|
62
|
+
imageUrl
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
return () => {
|
|
67
|
+
controller.abort();
|
|
68
|
+
};
|
|
69
|
+
}, [
|
|
70
|
+
resolvedResource.embedUrl,
|
|
71
|
+
resolvedResource.sourceUrl
|
|
72
|
+
]);
|
|
73
|
+
const templateActionUrl = showTemplateAction && resolvedResource.sourceUrl ? resolvedResource.copyUrl ?? resolvedResource.sourceUrl : null;
|
|
74
|
+
const openActionUrl = showOpenAction && resolvedResource.sourceUrl ? resolvedResource.sourceUrl : null;
|
|
75
|
+
const hasStandardActions = templateActionUrl !== null || openActionUrl !== null;
|
|
76
|
+
const hasActions = hasStandardActions || Boolean(actions);
|
|
20
77
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21
78
|
"div",
|
|
22
79
|
{
|
|
@@ -24,15 +81,46 @@ const EmbedViewer = ({
|
|
|
24
81
|
...props,
|
|
25
82
|
children: [
|
|
26
83
|
description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "embed-viewer__description", children: description }),
|
|
27
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
84
|
+
resolvedResource.embedUrl && /* @__PURE__ */ jsxRuntime.jsx(
|
|
28
85
|
"iframe",
|
|
29
86
|
{
|
|
30
87
|
className: "embed-viewer__frame",
|
|
31
|
-
src,
|
|
88
|
+
src: resolvedResource.embedUrl,
|
|
32
89
|
title: iframeTitle
|
|
33
90
|
}
|
|
34
91
|
),
|
|
35
|
-
|
|
92
|
+
!resolvedResource.embedUrl && previewImageUrl && /* @__PURE__ */ jsxRuntime.jsx(
|
|
93
|
+
"img",
|
|
94
|
+
{
|
|
95
|
+
className: "embed-viewer__preview",
|
|
96
|
+
src: previewImageUrl,
|
|
97
|
+
alt: ""
|
|
98
|
+
}
|
|
99
|
+
),
|
|
100
|
+
hasActions && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "embed-viewer__actions", children: [
|
|
101
|
+
hasStandardActions && /* @__PURE__ */ jsxRuntime.jsxs(ActionGroup__default.default, { children: [
|
|
102
|
+
templateActionUrl && /* @__PURE__ */ jsxRuntime.jsx(
|
|
103
|
+
Button__default.default,
|
|
104
|
+
{
|
|
105
|
+
onClick: () => openUrl(
|
|
106
|
+
templateActionUrl
|
|
107
|
+
),
|
|
108
|
+
children: "\u0421\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0448\u0430\u0431\u043B\u043E\u043D"
|
|
109
|
+
}
|
|
110
|
+
),
|
|
111
|
+
openActionUrl && /* @__PURE__ */ jsxRuntime.jsx(
|
|
112
|
+
Button__default.default,
|
|
113
|
+
{
|
|
114
|
+
rank: "link",
|
|
115
|
+
onClick: () => openUrl(
|
|
116
|
+
openActionUrl
|
|
117
|
+
),
|
|
118
|
+
children: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0432\u043E \u0432\u0435\u0441\u044C \u044D\u043A\u0440\u0430\u043D"
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
] }),
|
|
122
|
+
actions
|
|
123
|
+
] })
|
|
36
124
|
]
|
|
37
125
|
}
|
|
38
126
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/embed-viewer/embed-viewer.tsx"],"names":["classnames","jsxs","jsx"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/components/embed-viewer/embed-viewer.tsx"],"names":["classnames","resolveEmbedResource","useState","useEffect","resolveOpenGraphImage","jsxs","jsx","ActionGroup","Button"],"mappings":"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","file":"embed-viewer.cjs","sourcesContent":["import React, {\n useEffect,\n useState,\n} from 'react';\n\nimport './embed-viewer.css';\nimport ActionGroup from '../action-group';\nimport Button from '../button';\nimport { classnames } from '../helpers/classnames';\nimport {\n resolveOpenGraphImage,\n} from './open-graph';\nimport {\n resolveEmbedResource,\n} from './resolver';\n\nexport interface EmbedViewerProps\n extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n > {\n src: string;\n embedSrc?: string;\n iframeTitle: string;\n description?: React.ReactNode;\n showTemplateAction?: boolean;\n showOpenAction?: boolean;\n actions?: React.ReactNode;\n}\n\nfunction openUrl(url: string) {\n window.open(\n url,\n '_blank',\n 'noopener,noreferrer',\n );\n}\n\nconst EmbedViewer: React.FC<\n EmbedViewerProps\n> = ({\n src,\n embedSrc,\n iframeTitle,\n description,\n showTemplateAction = false,\n showOpenAction = false,\n actions,\n className = '',\n ...props\n}) => {\n const classes = classnames(\n 'embed-viewer',\n className,\n {},\n );\n\n const resolvedResource =\n resolveEmbedResource({\n src,\n embedSrc,\n });\n\n const [\n previewImageUrl,\n setPreviewImageUrl,\n ] = useState<string | null>(\n null,\n );\n\n useEffect(() => {\n setPreviewImageUrl(null);\n\n if (\n resolvedResource.embedUrl ||\n !resolvedResource.sourceUrl\n ) {\n return;\n }\n\n const controller =\n new AbortController();\n\n void resolveOpenGraphImage(\n resolvedResource.sourceUrl,\n controller.signal,\n ).then((imageUrl) => {\n if (\n !controller.signal.aborted\n ) {\n setPreviewImageUrl(\n imageUrl,\n );\n }\n });\n\n return () => {\n controller.abort();\n };\n }, [\n resolvedResource.embedUrl,\n resolvedResource.sourceUrl,\n ]);\n\n const templateActionUrl =\n showTemplateAction &&\n resolvedResource.sourceUrl\n ? (\n resolvedResource.copyUrl ??\n resolvedResource.sourceUrl\n )\n : null;\n\n const openActionUrl =\n showOpenAction &&\n resolvedResource.sourceUrl\n ? resolvedResource.sourceUrl\n : null;\n\n const hasStandardActions =\n templateActionUrl !== null ||\n openActionUrl !== null;\n\n const hasActions =\n hasStandardActions ||\n Boolean(actions);\n\n return (\n <div\n className={classes}\n {...props}\n >\n {description && (\n <div className=\"embed-viewer__description\">\n {description}\n </div>\n )}\n\n {resolvedResource.embedUrl && (\n <iframe\n className=\"embed-viewer__frame\"\n src={\n resolvedResource.embedUrl\n }\n title={iframeTitle}\n />\n )}\n\n {!resolvedResource.embedUrl &&\n previewImageUrl && (\n <img\n className=\"embed-viewer__preview\"\n src={previewImageUrl}\n alt=\"\"\n />\n )}\n\n {hasActions && (\n <div className=\"embed-viewer__actions\">\n {hasStandardActions && (\n <ActionGroup>\n {templateActionUrl && (\n <Button\n onClick={() =>\n openUrl(\n templateActionUrl,\n )\n }\n >\n Скопировать шаблон\n </Button>\n )}\n\n {openActionUrl && (\n <Button\n rank=\"link\"\n onClick={() =>\n openUrl(\n openActionUrl,\n )\n }\n >\n Открыть во весь экран\n </Button>\n )}\n </ActionGroup>\n )}\n\n {actions}\n </div>\n )}\n </div>\n );\n};\n\nexport default EmbedViewer;\n"]}
|
|
@@ -2,8 +2,11 @@ import React from 'react';
|
|
|
2
2
|
import './embed-viewer.css';
|
|
3
3
|
export interface EmbedViewerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
4
4
|
src: string;
|
|
5
|
+
embedSrc?: string;
|
|
5
6
|
iframeTitle: string;
|
|
6
7
|
description?: React.ReactNode;
|
|
8
|
+
showTemplateAction?: boolean;
|
|
9
|
+
showOpenAction?: boolean;
|
|
7
10
|
actions?: React.ReactNode;
|
|
8
11
|
}
|
|
9
12
|
declare const EmbedViewer: React.FC<EmbedViewerProps>;
|
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
2
3
|
import './embed-viewer.css';
|
|
4
|
+
import ActionGroup from '../action-group';
|
|
5
|
+
import Button from '../button';
|
|
3
6
|
import { classnames } from '../helpers/classnames';
|
|
7
|
+
import { resolveOpenGraphImage } from './open-graph';
|
|
8
|
+
import { resolveEmbedResource } from './resolver';
|
|
4
9
|
|
|
10
|
+
function openUrl(url) {
|
|
11
|
+
window.open(
|
|
12
|
+
url,
|
|
13
|
+
"_blank",
|
|
14
|
+
"noopener,noreferrer"
|
|
15
|
+
);
|
|
16
|
+
}
|
|
5
17
|
const EmbedViewer = ({
|
|
6
18
|
src,
|
|
19
|
+
embedSrc,
|
|
7
20
|
iframeTitle,
|
|
8
21
|
description,
|
|
22
|
+
showTemplateAction = false,
|
|
23
|
+
showOpenAction = false,
|
|
9
24
|
actions,
|
|
10
25
|
className = "",
|
|
11
26
|
...props
|
|
@@ -15,6 +30,43 @@ const EmbedViewer = ({
|
|
|
15
30
|
className,
|
|
16
31
|
{}
|
|
17
32
|
);
|
|
33
|
+
const resolvedResource = resolveEmbedResource({
|
|
34
|
+
src,
|
|
35
|
+
embedSrc
|
|
36
|
+
});
|
|
37
|
+
const [
|
|
38
|
+
previewImageUrl,
|
|
39
|
+
setPreviewImageUrl
|
|
40
|
+
] = useState(
|
|
41
|
+
null
|
|
42
|
+
);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
setPreviewImageUrl(null);
|
|
45
|
+
if (resolvedResource.embedUrl || !resolvedResource.sourceUrl) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const controller = new AbortController();
|
|
49
|
+
void resolveOpenGraphImage(
|
|
50
|
+
resolvedResource.sourceUrl,
|
|
51
|
+
controller.signal
|
|
52
|
+
).then((imageUrl) => {
|
|
53
|
+
if (!controller.signal.aborted) {
|
|
54
|
+
setPreviewImageUrl(
|
|
55
|
+
imageUrl
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return () => {
|
|
60
|
+
controller.abort();
|
|
61
|
+
};
|
|
62
|
+
}, [
|
|
63
|
+
resolvedResource.embedUrl,
|
|
64
|
+
resolvedResource.sourceUrl
|
|
65
|
+
]);
|
|
66
|
+
const templateActionUrl = showTemplateAction && resolvedResource.sourceUrl ? resolvedResource.copyUrl ?? resolvedResource.sourceUrl : null;
|
|
67
|
+
const openActionUrl = showOpenAction && resolvedResource.sourceUrl ? resolvedResource.sourceUrl : null;
|
|
68
|
+
const hasStandardActions = templateActionUrl !== null || openActionUrl !== null;
|
|
69
|
+
const hasActions = hasStandardActions || Boolean(actions);
|
|
18
70
|
return /* @__PURE__ */ jsxs(
|
|
19
71
|
"div",
|
|
20
72
|
{
|
|
@@ -22,15 +74,46 @@ const EmbedViewer = ({
|
|
|
22
74
|
...props,
|
|
23
75
|
children: [
|
|
24
76
|
description && /* @__PURE__ */ jsx("div", { className: "embed-viewer__description", children: description }),
|
|
25
|
-
/* @__PURE__ */ jsx(
|
|
77
|
+
resolvedResource.embedUrl && /* @__PURE__ */ jsx(
|
|
26
78
|
"iframe",
|
|
27
79
|
{
|
|
28
80
|
className: "embed-viewer__frame",
|
|
29
|
-
src,
|
|
81
|
+
src: resolvedResource.embedUrl,
|
|
30
82
|
title: iframeTitle
|
|
31
83
|
}
|
|
32
84
|
),
|
|
33
|
-
|
|
85
|
+
!resolvedResource.embedUrl && previewImageUrl && /* @__PURE__ */ jsx(
|
|
86
|
+
"img",
|
|
87
|
+
{
|
|
88
|
+
className: "embed-viewer__preview",
|
|
89
|
+
src: previewImageUrl,
|
|
90
|
+
alt: ""
|
|
91
|
+
}
|
|
92
|
+
),
|
|
93
|
+
hasActions && /* @__PURE__ */ jsxs("div", { className: "embed-viewer__actions", children: [
|
|
94
|
+
hasStandardActions && /* @__PURE__ */ jsxs(ActionGroup, { children: [
|
|
95
|
+
templateActionUrl && /* @__PURE__ */ jsx(
|
|
96
|
+
Button,
|
|
97
|
+
{
|
|
98
|
+
onClick: () => openUrl(
|
|
99
|
+
templateActionUrl
|
|
100
|
+
),
|
|
101
|
+
children: "\u0421\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0448\u0430\u0431\u043B\u043E\u043D"
|
|
102
|
+
}
|
|
103
|
+
),
|
|
104
|
+
openActionUrl && /* @__PURE__ */ jsx(
|
|
105
|
+
Button,
|
|
106
|
+
{
|
|
107
|
+
rank: "link",
|
|
108
|
+
onClick: () => openUrl(
|
|
109
|
+
openActionUrl
|
|
110
|
+
),
|
|
111
|
+
children: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0432\u043E \u0432\u0435\u0441\u044C \u044D\u043A\u0440\u0430\u043D"
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
] }),
|
|
115
|
+
actions
|
|
116
|
+
] })
|
|
34
117
|
]
|
|
35
118
|
}
|
|
36
119
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/embed-viewer/embed-viewer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/components/embed-viewer/embed-viewer.tsx"],"names":[],"mappings":"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","file":"embed-viewer.js","sourcesContent":["import React, {\n useEffect,\n useState,\n} from 'react';\n\nimport './embed-viewer.css';\nimport ActionGroup from '../action-group';\nimport Button from '../button';\nimport { classnames } from '../helpers/classnames';\nimport {\n resolveOpenGraphImage,\n} from './open-graph';\nimport {\n resolveEmbedResource,\n} from './resolver';\n\nexport interface EmbedViewerProps\n extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n > {\n src: string;\n embedSrc?: string;\n iframeTitle: string;\n description?: React.ReactNode;\n showTemplateAction?: boolean;\n showOpenAction?: boolean;\n actions?: React.ReactNode;\n}\n\nfunction openUrl(url: string) {\n window.open(\n url,\n '_blank',\n 'noopener,noreferrer',\n );\n}\n\nconst EmbedViewer: React.FC<\n EmbedViewerProps\n> = ({\n src,\n embedSrc,\n iframeTitle,\n description,\n showTemplateAction = false,\n showOpenAction = false,\n actions,\n className = '',\n ...props\n}) => {\n const classes = classnames(\n 'embed-viewer',\n className,\n {},\n );\n\n const resolvedResource =\n resolveEmbedResource({\n src,\n embedSrc,\n });\n\n const [\n previewImageUrl,\n setPreviewImageUrl,\n ] = useState<string | null>(\n null,\n );\n\n useEffect(() => {\n setPreviewImageUrl(null);\n\n if (\n resolvedResource.embedUrl ||\n !resolvedResource.sourceUrl\n ) {\n return;\n }\n\n const controller =\n new AbortController();\n\n void resolveOpenGraphImage(\n resolvedResource.sourceUrl,\n controller.signal,\n ).then((imageUrl) => {\n if (\n !controller.signal.aborted\n ) {\n setPreviewImageUrl(\n imageUrl,\n );\n }\n });\n\n return () => {\n controller.abort();\n };\n }, [\n resolvedResource.embedUrl,\n resolvedResource.sourceUrl,\n ]);\n\n const templateActionUrl =\n showTemplateAction &&\n resolvedResource.sourceUrl\n ? (\n resolvedResource.copyUrl ??\n resolvedResource.sourceUrl\n )\n : null;\n\n const openActionUrl =\n showOpenAction &&\n resolvedResource.sourceUrl\n ? resolvedResource.sourceUrl\n : null;\n\n const hasStandardActions =\n templateActionUrl !== null ||\n openActionUrl !== null;\n\n const hasActions =\n hasStandardActions ||\n Boolean(actions);\n\n return (\n <div\n className={classes}\n {...props}\n >\n {description && (\n <div className=\"embed-viewer__description\">\n {description}\n </div>\n )}\n\n {resolvedResource.embedUrl && (\n <iframe\n className=\"embed-viewer__frame\"\n src={\n resolvedResource.embedUrl\n }\n title={iframeTitle}\n />\n )}\n\n {!resolvedResource.embedUrl &&\n previewImageUrl && (\n <img\n className=\"embed-viewer__preview\"\n src={previewImageUrl}\n alt=\"\"\n />\n )}\n\n {hasActions && (\n <div className=\"embed-viewer__actions\">\n {hasStandardActions && (\n <ActionGroup>\n {templateActionUrl && (\n <Button\n onClick={() =>\n openUrl(\n templateActionUrl,\n )\n }\n >\n Скопировать шаблон\n </Button>\n )}\n\n {openActionUrl && (\n <Button\n rank=\"link\"\n onClick={() =>\n openUrl(\n openActionUrl,\n )\n }\n >\n Открыть во весь экран\n </Button>\n )}\n </ActionGroup>\n )}\n\n {actions}\n </div>\n )}\n </div>\n );\n};\n\nexport default EmbedViewer;\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const defaultFetchResource = async (url, init) => fetch(
|
|
4
|
+
url,
|
|
5
|
+
init
|
|
6
|
+
);
|
|
7
|
+
function isHtmlResponse(response) {
|
|
8
|
+
const contentType = response.headers.get(
|
|
9
|
+
"content-type"
|
|
10
|
+
);
|
|
11
|
+
return contentType === null || contentType.includes("text/html");
|
|
12
|
+
}
|
|
13
|
+
function parseOpenGraphImage(html, sourceUrl) {
|
|
14
|
+
const document = new DOMParser().parseFromString(
|
|
15
|
+
html,
|
|
16
|
+
"text/html"
|
|
17
|
+
);
|
|
18
|
+
const image = document.head.querySelector(
|
|
19
|
+
'meta[property="og:image"]'
|
|
20
|
+
);
|
|
21
|
+
const content = image?.getAttribute("content");
|
|
22
|
+
if (!content) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const url = new URL(
|
|
27
|
+
content,
|
|
28
|
+
sourceUrl
|
|
29
|
+
);
|
|
30
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return url.toString();
|
|
34
|
+
} catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function resolveOpenGraphImage(sourceUrl, signal, fetchResource = defaultFetchResource) {
|
|
39
|
+
try {
|
|
40
|
+
const response = await fetchResource(
|
|
41
|
+
sourceUrl,
|
|
42
|
+
{
|
|
43
|
+
signal
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
if (!response.ok || !isHtmlResponse(response)) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const html = await response.text();
|
|
50
|
+
return parseOpenGraphImage(
|
|
51
|
+
html,
|
|
52
|
+
sourceUrl
|
|
53
|
+
);
|
|
54
|
+
} catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
exports.resolveOpenGraphImage = resolveOpenGraphImage;
|
|
60
|
+
//# sourceMappingURL=open-graph.cjs.map
|
|
61
|
+
//# sourceMappingURL=open-graph.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/embed-viewer/open-graph.ts"],"names":[],"mappings":";;AAOA,MAAM,oBAAA,GACJ,OACE,GAAA,EACA,IAAA,KAEA,KAAA;AAAA,EACE,GAAA;AAAA,EACA;AACF,CAAA;AAEJ,SAAS,eACP,QAAA,EACS;AACT,EAAA,MAAM,WAAA,GACJ,SAAS,OAAA,CAAQ,GAAA;AAAA,IACf;AAAA,GACF;AAEF,EAAA,OACE,WAAA,KAAgB,IAAA,IAChB,WAAA,CAAY,QAAA,CAAS,WAAW,CAAA;AAEpC;AAEA,SAAS,mBAAA,CACP,MACA,SAAA,EACe;AACf,EAAA,MAAM,QAAA,GACJ,IAAI,SAAA,EAAU,CAAE,eAAA;AAAA,IACd,IAAA;AAAA,IACA;AAAA,GACF;AAEF,EAAA,MAAM,KAAA,GACJ,SAAS,IAAA,CAAK,aAAA;AAAA,IACZ;AAAA,GACF;AAEF,EAAA,MAAM,OAAA,GACJ,KAAA,EAAO,YAAA,CAAa,SAAS,CAAA;AAE/B,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,MACJ,IAAI,GAAA;AAAA,MACF,OAAA;AAAA,MACA;AAAA,KACF;AAEF,IAAA,IACE,GAAA,CAAI,QAAA,KAAa,OAAA,IACjB,GAAA,CAAI,aAAa,QAAA,EACjB;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,eAAsB,qBAAA,CACpB,SAAA,EACA,MAAA,EACA,aAAA,GACE,oBAAA,EACsB;AACxB,EAAA,IAAI;AACF,IAAA,MAAM,WACJ,MAAM,aAAA;AAAA,MACJ,SAAA;AAAA,MACA;AAAA,QACE;AAAA;AACF,KACF;AAEF,IAAA,IACE,CAAC,QAAA,CAAS,EAAA,IACV,CAAC,cAAA,CAAe,QAAQ,CAAA,EACxB;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,IAAA,GACJ,MAAM,QAAA,CAAS,IAAA,EAAK;AAEtB,IAAA,OAAO,mBAAA;AAAA,MACL,IAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF","file":"open-graph.cjs","sourcesContent":["type FetchResource = (\n url: string,\n init?: {\n signal?: AbortSignal;\n },\n) => Promise<Response>;\n\nconst defaultFetchResource: FetchResource =\n async (\n url,\n init,\n ) =>\n fetch(\n url,\n init,\n );\n\nfunction isHtmlResponse(\n response: Response,\n): boolean {\n const contentType =\n response.headers.get(\n 'content-type',\n );\n\n return (\n contentType === null ||\n contentType.includes('text/html')\n );\n}\n\nfunction parseOpenGraphImage(\n html: string,\n sourceUrl: string,\n): string | null {\n const document =\n new DOMParser().parseFromString(\n html,\n 'text/html',\n );\n\n const image =\n document.head.querySelector(\n 'meta[property=\"og:image\"]',\n );\n\n const content =\n image?.getAttribute('content');\n\n if (!content) {\n return null;\n }\n\n try {\n const url =\n new URL(\n content,\n sourceUrl,\n );\n\n if (\n url.protocol !== 'http:' &&\n url.protocol !== 'https:'\n ) {\n return null;\n }\n\n return url.toString();\n } catch {\n return null;\n }\n}\n\nexport async function resolveOpenGraphImage(\n sourceUrl: string,\n signal?: AbortSignal,\n fetchResource: FetchResource =\n defaultFetchResource,\n): Promise<string | null> {\n try {\n const response =\n await fetchResource(\n sourceUrl,\n {\n signal,\n },\n );\n\n if (\n !response.ok ||\n !isHtmlResponse(response)\n ) {\n return null;\n }\n\n const html =\n await response.text();\n\n return parseOpenGraphImage(\n html,\n sourceUrl,\n );\n } catch {\n return null;\n }\n}\n"]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const defaultFetchResource = async (url, init) => fetch(
|
|
2
|
+
url,
|
|
3
|
+
init
|
|
4
|
+
);
|
|
5
|
+
function isHtmlResponse(response) {
|
|
6
|
+
const contentType = response.headers.get(
|
|
7
|
+
"content-type"
|
|
8
|
+
);
|
|
9
|
+
return contentType === null || contentType.includes("text/html");
|
|
10
|
+
}
|
|
11
|
+
function parseOpenGraphImage(html, sourceUrl) {
|
|
12
|
+
const document = new DOMParser().parseFromString(
|
|
13
|
+
html,
|
|
14
|
+
"text/html"
|
|
15
|
+
);
|
|
16
|
+
const image = document.head.querySelector(
|
|
17
|
+
'meta[property="og:image"]'
|
|
18
|
+
);
|
|
19
|
+
const content = image?.getAttribute("content");
|
|
20
|
+
if (!content) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const url = new URL(
|
|
25
|
+
content,
|
|
26
|
+
sourceUrl
|
|
27
|
+
);
|
|
28
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return url.toString();
|
|
32
|
+
} catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function resolveOpenGraphImage(sourceUrl, signal, fetchResource = defaultFetchResource) {
|
|
37
|
+
try {
|
|
38
|
+
const response = await fetchResource(
|
|
39
|
+
sourceUrl,
|
|
40
|
+
{
|
|
41
|
+
signal
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
if (!response.ok || !isHtmlResponse(response)) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const html = await response.text();
|
|
48
|
+
return parseOpenGraphImage(
|
|
49
|
+
html,
|
|
50
|
+
sourceUrl
|
|
51
|
+
);
|
|
52
|
+
} catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export { resolveOpenGraphImage };
|
|
58
|
+
//# sourceMappingURL=open-graph.js.map
|
|
59
|
+
//# sourceMappingURL=open-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/embed-viewer/open-graph.ts"],"names":[],"mappings":"AAOA,MAAM,oBAAA,GACJ,OACE,GAAA,EACA,IAAA,KAEA,KAAA;AAAA,EACE,GAAA;AAAA,EACA;AACF,CAAA;AAEJ,SAAS,eACP,QAAA,EACS;AACT,EAAA,MAAM,WAAA,GACJ,SAAS,OAAA,CAAQ,GAAA;AAAA,IACf;AAAA,GACF;AAEF,EAAA,OACE,WAAA,KAAgB,IAAA,IAChB,WAAA,CAAY,QAAA,CAAS,WAAW,CAAA;AAEpC;AAEA,SAAS,mBAAA,CACP,MACA,SAAA,EACe;AACf,EAAA,MAAM,QAAA,GACJ,IAAI,SAAA,EAAU,CAAE,eAAA;AAAA,IACd,IAAA;AAAA,IACA;AAAA,GACF;AAEF,EAAA,MAAM,KAAA,GACJ,SAAS,IAAA,CAAK,aAAA;AAAA,IACZ;AAAA,GACF;AAEF,EAAA,MAAM,OAAA,GACJ,KAAA,EAAO,YAAA,CAAa,SAAS,CAAA;AAE/B,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,MACJ,IAAI,GAAA;AAAA,MACF,OAAA;AAAA,MACA;AAAA,KACF;AAEF,IAAA,IACE,GAAA,CAAI,QAAA,KAAa,OAAA,IACjB,GAAA,CAAI,aAAa,QAAA,EACjB;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,eAAsB,qBAAA,CACpB,SAAA,EACA,MAAA,EACA,aAAA,GACE,oBAAA,EACsB;AACxB,EAAA,IAAI;AACF,IAAA,MAAM,WACJ,MAAM,aAAA;AAAA,MACJ,SAAA;AAAA,MACA;AAAA,QACE;AAAA;AACF,KACF;AAEF,IAAA,IACE,CAAC,QAAA,CAAS,EAAA,IACV,CAAC,cAAA,CAAe,QAAQ,CAAA,EACxB;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,IAAA,GACJ,MAAM,QAAA,CAAS,IAAA,EAAK;AAEtB,IAAA,OAAO,mBAAA;AAAA,MACL,IAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF","file":"open-graph.js","sourcesContent":["type FetchResource = (\n url: string,\n init?: {\n signal?: AbortSignal;\n },\n) => Promise<Response>;\n\nconst defaultFetchResource: FetchResource =\n async (\n url,\n init,\n ) =>\n fetch(\n url,\n init,\n );\n\nfunction isHtmlResponse(\n response: Response,\n): boolean {\n const contentType =\n response.headers.get(\n 'content-type',\n );\n\n return (\n contentType === null ||\n contentType.includes('text/html')\n );\n}\n\nfunction parseOpenGraphImage(\n html: string,\n sourceUrl: string,\n): string | null {\n const document =\n new DOMParser().parseFromString(\n html,\n 'text/html',\n );\n\n const image =\n document.head.querySelector(\n 'meta[property=\"og:image\"]',\n );\n\n const content =\n image?.getAttribute('content');\n\n if (!content) {\n return null;\n }\n\n try {\n const url =\n new URL(\n content,\n sourceUrl,\n );\n\n if (\n url.protocol !== 'http:' &&\n url.protocol !== 'https:'\n ) {\n return null;\n }\n\n return url.toString();\n } catch {\n return null;\n }\n}\n\nexport async function resolveOpenGraphImage(\n sourceUrl: string,\n signal?: AbortSignal,\n fetchResource: FetchResource =\n defaultFetchResource,\n): Promise<string | null> {\n try {\n const response =\n await fetchResource(\n sourceUrl,\n {\n signal,\n },\n );\n\n if (\n !response.ok ||\n !isHtmlResponse(response)\n ) {\n return null;\n }\n\n const html =\n await response.text();\n\n return parseOpenGraphImage(\n html,\n sourceUrl,\n );\n } catch {\n return null;\n }\n}\n"]}
|