@teleporthq/teleport-shared 0.43.67 → 0.43.69
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/__tests__/_helpers/embed-runtime-emitter.ts +197 -0
- package/__tests__/utils/discount-engine.ts +1548 -0
- package/__tests__/utils/product-options.ts +2458 -0
- package/__tests__/utils/rich-text-embeds-runtime-module.ts +34 -0
- package/__tests__/utils/subscription-access.ts +37 -0
- package/dist/cjs/index.d.ts +9 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +17 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils/cart-currency.d.ts +27 -0
- package/dist/cjs/utils/cart-currency.d.ts.map +1 -0
- package/dist/cjs/utils/cart-currency.js +31 -0
- package/dist/cjs/utils/cart-currency.js.map +1 -0
- package/dist/cjs/utils/cart-line-pricing.d.ts +25 -0
- package/dist/cjs/utils/cart-line-pricing.d.ts.map +1 -0
- package/dist/cjs/utils/cart-line-pricing.js +29 -0
- package/dist/cjs/utils/cart-line-pricing.js.map +1 -0
- package/dist/cjs/utils/discount-engine.d.ts +74 -0
- package/dist/cjs/utils/discount-engine.d.ts.map +1 -0
- package/dist/cjs/utils/discount-engine.js +435 -0
- package/dist/cjs/utils/discount-engine.js.map +1 -0
- package/dist/cjs/utils/product-options.d.ts +25 -0
- package/dist/cjs/utils/product-options.d.ts.map +1 -0
- package/dist/cjs/utils/product-options.js +1155 -0
- package/dist/cjs/utils/product-options.js.map +1 -0
- package/dist/cjs/utils/rich-text-embeds-codegen.d.ts +13 -0
- package/dist/cjs/utils/rich-text-embeds-codegen.d.ts.map +1 -1
- package/dist/cjs/utils/rich-text-embeds-codegen.js +15 -104
- package/dist/cjs/utils/rich-text-embeds-codegen.js.map +1 -1
- package/dist/cjs/utils/rich-text-embeds-runtime-source.d.ts +2 -0
- package/dist/cjs/utils/rich-text-embeds-runtime-source.d.ts.map +1 -0
- package/dist/cjs/utils/rich-text-embeds-runtime-source.js +409 -0
- package/dist/cjs/utils/rich-text-embeds-runtime-source.js.map +1 -0
- package/dist/cjs/utils/session-cookie-resolver.d.ts +85 -0
- package/dist/cjs/utils/session-cookie-resolver.d.ts.map +1 -0
- package/dist/cjs/utils/session-cookie-resolver.js +108 -0
- package/dist/cjs/utils/session-cookie-resolver.js.map +1 -0
- package/dist/cjs/utils/subscription-access.d.ts +36 -0
- package/dist/cjs/utils/subscription-access.d.ts.map +1 -0
- package/dist/cjs/utils/subscription-access.js +61 -0
- package/dist/cjs/utils/subscription-access.js.map +1 -0
- package/dist/cjs/utils/table-access.d.ts +114 -0
- package/dist/cjs/utils/table-access.d.ts.map +1 -0
- package/dist/cjs/utils/table-access.js +238 -0
- package/dist/cjs/utils/table-access.js.map +1 -0
- package/dist/cjs/utils/web-push.d.ts +43 -0
- package/dist/cjs/utils/web-push.d.ts.map +1 -0
- package/dist/cjs/utils/web-push.js +62 -0
- package/dist/cjs/utils/web-push.js.map +1 -0
- package/dist/esm/index.d.ts +9 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +9 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/utils/cart-currency.d.ts +27 -0
- package/dist/esm/utils/cart-currency.d.ts.map +1 -0
- package/dist/esm/utils/cart-currency.js +27 -0
- package/dist/esm/utils/cart-currency.js.map +1 -0
- package/dist/esm/utils/cart-line-pricing.d.ts +25 -0
- package/dist/esm/utils/cart-line-pricing.d.ts.map +1 -0
- package/dist/esm/utils/cart-line-pricing.js +25 -0
- package/dist/esm/utils/cart-line-pricing.js.map +1 -0
- package/dist/esm/utils/discount-engine.d.ts +74 -0
- package/dist/esm/utils/discount-engine.d.ts.map +1 -0
- package/dist/esm/utils/discount-engine.js +431 -0
- package/dist/esm/utils/discount-engine.js.map +1 -0
- package/dist/esm/utils/product-options.d.ts +25 -0
- package/dist/esm/utils/product-options.d.ts.map +1 -0
- package/dist/esm/utils/product-options.js +1151 -0
- package/dist/esm/utils/product-options.js.map +1 -0
- package/dist/esm/utils/rich-text-embeds-codegen.d.ts +13 -0
- package/dist/esm/utils/rich-text-embeds-codegen.d.ts.map +1 -1
- package/dist/esm/utils/rich-text-embeds-codegen.js +16 -105
- package/dist/esm/utils/rich-text-embeds-codegen.js.map +1 -1
- package/dist/esm/utils/rich-text-embeds-runtime-source.d.ts +2 -0
- package/dist/esm/utils/rich-text-embeds-runtime-source.d.ts.map +1 -0
- package/dist/esm/utils/rich-text-embeds-runtime-source.js +406 -0
- package/dist/esm/utils/rich-text-embeds-runtime-source.js.map +1 -0
- package/dist/esm/utils/session-cookie-resolver.d.ts +85 -0
- package/dist/esm/utils/session-cookie-resolver.d.ts.map +1 -0
- package/dist/esm/utils/session-cookie-resolver.js +103 -0
- package/dist/esm/utils/session-cookie-resolver.js.map +1 -0
- package/dist/esm/utils/subscription-access.d.ts +36 -0
- package/dist/esm/utils/subscription-access.d.ts.map +1 -0
- package/dist/esm/utils/subscription-access.js +57 -0
- package/dist/esm/utils/subscription-access.js.map +1 -0
- package/dist/esm/utils/table-access.d.ts +114 -0
- package/dist/esm/utils/table-access.d.ts.map +1 -0
- package/dist/esm/utils/table-access.js +233 -0
- package/dist/esm/utils/table-access.js.map +1 -0
- package/dist/esm/utils/web-push.d.ts +43 -0
- package/dist/esm/utils/web-push.d.ts.map +1 -0
- package/dist/esm/utils/web-push.js +59 -0
- package/dist/esm/utils/web-push.js.map +1 -0
- package/package.json +3 -3
- package/src/index.ts +16 -0
- package/src/utils/cart-currency.ts +76 -0
- package/src/utils/cart-line-pricing.ts +151 -0
- package/src/utils/discount-engine.ts +437 -0
- package/src/utils/product-options.ts +1150 -0
- package/src/utils/rich-text-embeds-codegen.ts +16 -183
- package/src/utils/rich-text-embeds-runtime-source.ts +405 -0
- package/src/utils/session-cookie-resolver.ts +305 -0
- package/src/utils/subscription-access.ts +59 -0
- package/src/utils/table-access.ts +516 -0
- package/src/utils/web-push.ts +61 -0
|
@@ -2,59 +2,11 @@
|
|
|
2
2
|
* Code-generation helpers for the rich-text embed contract.
|
|
3
3
|
*
|
|
4
4
|
* Kept apart from `rich-text-embeds.ts` on purpose: that module is imported by
|
|
5
|
-
* the studio editor and the canvas renderer, which are BROWSER bundles
|
|
6
|
-
*
|
|
7
|
-
* of them can be tree-shaken. Only the project generator imports this file.
|
|
5
|
+
* the studio editor and the canvas renderer, which are BROWSER bundles. Only
|
|
6
|
+
* the project generator imports this file.
|
|
8
7
|
*/
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
DEFAULT_EMBED_ALIGN,
|
|
12
|
-
DEFAULT_EMBED_SANDBOX_LEVEL,
|
|
13
|
-
DEFAULT_EMBED_WIDTH,
|
|
14
|
-
EMBED_ALIGNMENTS,
|
|
15
|
-
EMBED_ATTR,
|
|
16
|
-
EMBED_BLOT_NAME,
|
|
17
|
-
EMBED_CAPTION_CLASS_NAME,
|
|
18
|
-
EMBED_CAPTION_STYLE,
|
|
19
|
-
EMBED_CLASS_NAME,
|
|
20
|
-
EMBED_FRAME_CLASS_NAME,
|
|
21
|
-
EMBED_HEIGHT_MESSAGE_TYPE,
|
|
22
|
-
EMBED_INITIAL_HEIGHT,
|
|
23
|
-
EMBED_MAX_HEIGHT,
|
|
24
|
-
EMBED_MIN_HEIGHT,
|
|
25
|
-
EMBED_PROVIDERS,
|
|
26
|
-
EMBED_SANDBOX_DOC_HEAD,
|
|
27
|
-
EMBED_SANDBOX_DOC_TAIL,
|
|
28
|
-
EMBED_SANDBOX_FLAGS_STRICT,
|
|
29
|
-
EMBED_SANDBOX_FLAGS_TRUSTED,
|
|
30
|
-
EMBED_TOKEN_PLACEHOLDER,
|
|
31
|
-
GENERIC_EMBED_PROVIDER_ID,
|
|
32
|
-
WIDESCREEN_EMBED_RATIO,
|
|
33
|
-
applyEmbedTemplate,
|
|
34
|
-
buildEmbedElementHtml,
|
|
35
|
-
buildEmbedFrameChildren,
|
|
36
|
-
buildEmbedHtmlFromUrl,
|
|
37
|
-
buildEmbedSandboxDocument,
|
|
38
|
-
clampEmbedWidth,
|
|
39
|
-
createEmbedToken,
|
|
40
|
-
createEmbedValue,
|
|
41
|
-
decodeEmbedCode,
|
|
42
|
-
embedBlockStyle,
|
|
43
|
-
embedFrameStyle,
|
|
44
|
-
encodeEmbedCode,
|
|
45
|
-
escapeEmbedAttribute,
|
|
46
|
-
escapeEmbedText,
|
|
47
|
-
findEmbedFrame,
|
|
48
|
-
isSafeEmbedUrl,
|
|
49
|
-
normalizeEmbedAlign,
|
|
50
|
-
normalizeEmbedsForStorage,
|
|
51
|
-
parseEmbedHeightMessage,
|
|
52
|
-
readEmbedValueFromElement,
|
|
53
|
-
readEncodedEmbedCode,
|
|
54
|
-
resolveEmbedMode,
|
|
55
|
-
resolveEmbedProvider,
|
|
56
|
-
resolveEmbedSandboxFlags,
|
|
57
|
-
} from './rich-text-embeds'
|
|
8
|
+
import { EMBED_PROVIDERS } from './rich-text-embeds'
|
|
9
|
+
import { EMBED_RUNTIME_MODULE_SOURCE } from './rich-text-embeds-runtime-source'
|
|
58
10
|
|
|
59
11
|
/**
|
|
60
12
|
* The provider registry as a JavaScript literal, so the component the Next
|
|
@@ -79,138 +31,19 @@ export function serializeEmbedProvidersForRuntime(): string {
|
|
|
79
31
|
return `[\n ${entries.join(',\n ')}\n]`
|
|
80
32
|
}
|
|
81
33
|
|
|
82
|
-
/* ── The generated runtime module ───────────────────────────────────────────
|
|
83
|
-
*
|
|
84
|
-
* The exported project needs these same helpers at runtime: its rich-text
|
|
85
|
-
* editor builds embeds with them and its activator mounts them. Rather than
|
|
86
|
-
* hand-copying the logic into a code-generator template — where it would drift
|
|
87
|
-
* from this file the first time a provider is added — the module is EMITTED
|
|
88
|
-
* from the very functions above: the constants are serialized, the functions
|
|
89
|
-
* are printed with `Function.prototype.toString`, and the result is written to
|
|
90
|
-
* the generated project as `components/embed-runtime.js`.
|
|
91
|
-
*
|
|
92
|
-
* Two rules keep that safe, and `__tests__/utils/rich-text-embeds.ts` pins both:
|
|
93
|
-
* - every emitted function may only reference other emitted functions and the
|
|
94
|
-
* constants below, never a module-private helper or an import;
|
|
95
|
-
* - the emitted module must parse and behave identically to this one.
|
|
96
|
-
*/
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Every function the generated editor and activator reach — the ones they
|
|
100
|
-
* import, plus everything those call in turn. Deliberately not the whole of
|
|
101
|
-
* `rich-text-embeds`: the editor overlay helpers belong to the studio, and an
|
|
102
|
-
* export nothing calls is dead weight in every generated project.
|
|
103
|
-
*/
|
|
104
|
-
const RUNTIME_EXPORTS: Array<(...args: never[]) => unknown> = [
|
|
105
|
-
isSafeEmbedUrl,
|
|
106
|
-
resolveEmbedProvider,
|
|
107
|
-
applyEmbedTemplate,
|
|
108
|
-
buildEmbedHtmlFromUrl,
|
|
109
|
-
resolveEmbedMode,
|
|
110
|
-
clampEmbedWidth,
|
|
111
|
-
normalizeEmbedAlign,
|
|
112
|
-
escapeEmbedAttribute,
|
|
113
|
-
escapeEmbedText,
|
|
114
|
-
encodeEmbedCode,
|
|
115
|
-
decodeEmbedCode,
|
|
116
|
-
createEmbedValue,
|
|
117
|
-
embedBlockStyle,
|
|
118
|
-
embedFrameStyle,
|
|
119
|
-
buildEmbedElementHtml,
|
|
120
|
-
buildEmbedFrameChildren,
|
|
121
|
-
findEmbedFrame,
|
|
122
|
-
readEmbedValueFromElement,
|
|
123
|
-
readEncodedEmbedCode,
|
|
124
|
-
normalizeEmbedsForStorage,
|
|
125
|
-
resolveEmbedSandboxFlags,
|
|
126
|
-
buildEmbedSandboxDocument,
|
|
127
|
-
parseEmbedHeightMessage,
|
|
128
|
-
createEmbedToken,
|
|
129
|
-
]
|
|
130
|
-
|
|
131
|
-
interface RuntimeConstant {
|
|
132
|
-
name: string
|
|
133
|
-
literal: string
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const runtimeConstant = (name: string, literal: string): RuntimeConstant => ({ name, literal })
|
|
137
|
-
|
|
138
34
|
/**
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
35
|
+
* `components/embed-runtime.js` for the generated project: the helpers its
|
|
36
|
+
* rich-text editor builds embeds with and its activator mounts them with.
|
|
37
|
+
*
|
|
38
|
+
* A STRING committed beside this file, not printed from the functions with
|
|
39
|
+
* `Function.prototype.toString` at generation time: teleport-gui runs this
|
|
40
|
+
* generator inside a minified bundle, where the minifier renames every one of
|
|
41
|
+
* those functions and the constants they read, so the emitted module exported
|
|
42
|
+
* none of the names the activator imports. A minifier never rewrites a string
|
|
43
|
+
* literal. `__tests__/utils/rich-text-embeds-runtime-module.ts` fails when the
|
|
44
|
+
* string drifts from `rich-text-embeds.ts` and regenerates it with
|
|
45
|
+
* UPDATE_EMBED_RUNTIME=1.
|
|
147
46
|
*/
|
|
148
|
-
const bindRuntimeConstantReferences = (source: string, names: string[]): string =>
|
|
149
|
-
names.reduce((acc, name) => acc.replace(new RegExp(`\\bexports\\.${name}\\b`, 'g'), name), source)
|
|
150
|
-
|
|
151
47
|
export function generateEmbedRuntimeModuleSource(): string {
|
|
152
|
-
|
|
153
|
-
runtimeConstant('EMBED_CLASS_NAME', JSON.stringify(EMBED_CLASS_NAME)),
|
|
154
|
-
runtimeConstant('EMBED_FRAME_CLASS_NAME', JSON.stringify(EMBED_FRAME_CLASS_NAME)),
|
|
155
|
-
runtimeConstant('EMBED_CAPTION_CLASS_NAME', JSON.stringify(EMBED_CAPTION_CLASS_NAME)),
|
|
156
|
-
runtimeConstant('EMBED_BLOT_NAME', JSON.stringify(EMBED_BLOT_NAME)),
|
|
157
|
-
runtimeConstant('EMBED_ATTR', JSON.stringify(EMBED_ATTR, null, 2)),
|
|
158
|
-
runtimeConstant('EMBED_ALIGNMENTS', JSON.stringify(EMBED_ALIGNMENTS)),
|
|
159
|
-
runtimeConstant('CUSTOM_EMBED_PROVIDER_ID', JSON.stringify(CUSTOM_EMBED_PROVIDER_ID)),
|
|
160
|
-
runtimeConstant('GENERIC_EMBED_PROVIDER_ID', JSON.stringify(GENERIC_EMBED_PROVIDER_ID)),
|
|
161
|
-
runtimeConstant('DEFAULT_EMBED_WIDTH', String(DEFAULT_EMBED_WIDTH)),
|
|
162
|
-
runtimeConstant('DEFAULT_EMBED_ALIGN', JSON.stringify(DEFAULT_EMBED_ALIGN)),
|
|
163
|
-
runtimeConstant('DEFAULT_EMBED_SANDBOX_LEVEL', JSON.stringify(DEFAULT_EMBED_SANDBOX_LEVEL)),
|
|
164
|
-
runtimeConstant('WIDESCREEN_EMBED_RATIO', String(WIDESCREEN_EMBED_RATIO)),
|
|
165
|
-
runtimeConstant('EMBED_CAPTION_STYLE', JSON.stringify(EMBED_CAPTION_STYLE)),
|
|
166
|
-
runtimeConstant('EMBED_PROVIDERS', serializeEmbedProvidersForRuntime()),
|
|
167
|
-
runtimeConstant('EMBED_SANDBOX_FLAGS_STRICT', JSON.stringify(EMBED_SANDBOX_FLAGS_STRICT)),
|
|
168
|
-
runtimeConstant('EMBED_SANDBOX_FLAGS_TRUSTED', JSON.stringify(EMBED_SANDBOX_FLAGS_TRUSTED)),
|
|
169
|
-
runtimeConstant('EMBED_HEIGHT_MESSAGE_TYPE', JSON.stringify(EMBED_HEIGHT_MESSAGE_TYPE)),
|
|
170
|
-
runtimeConstant('EMBED_TOKEN_PLACEHOLDER', JSON.stringify(EMBED_TOKEN_PLACEHOLDER)),
|
|
171
|
-
runtimeConstant('EMBED_MIN_HEIGHT', String(EMBED_MIN_HEIGHT)),
|
|
172
|
-
runtimeConstant('EMBED_MAX_HEIGHT', String(EMBED_MAX_HEIGHT)),
|
|
173
|
-
runtimeConstant('EMBED_INITIAL_HEIGHT', String(EMBED_INITIAL_HEIGHT)),
|
|
174
|
-
runtimeConstant('EMBED_SANDBOX_DOC_HEAD', JSON.stringify(EMBED_SANDBOX_DOC_HEAD)),
|
|
175
|
-
runtimeConstant('EMBED_SANDBOX_DOC_TAIL', JSON.stringify(EMBED_SANDBOX_DOC_TAIL)),
|
|
176
|
-
// `createEmbedToken` closes over this counter.
|
|
177
|
-
runtimeConstant('embedTokenCounter', '0'),
|
|
178
|
-
]
|
|
179
|
-
|
|
180
|
-
const names = constants.map((entry) => entry.name)
|
|
181
|
-
const declarations = constants.map((entry) => `export var ${entry.name} = ${entry.literal}`)
|
|
182
|
-
const functions = RUNTIME_EXPORTS.map(
|
|
183
|
-
(fn) => `export ${bindRuntimeConstantReferences(fn.toString(), names)}`
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
const source = `${RUNTIME_MODULE_HEADER}\n${declarations.join('\n\n')}\n\n${functions.join(
|
|
187
|
-
'\n\n'
|
|
188
|
-
)}\n`
|
|
189
|
-
|
|
190
|
-
// An `exports.` reference that survived means a function reached for a
|
|
191
|
-
// constant left off the list above. That crashes every generated project at
|
|
192
|
-
// runtime, so it fails here instead. (Import leakage is covered by the
|
|
193
|
-
// emitted module being evaluated in this package's tests — this module has
|
|
194
|
-
// no imports, and must not gain any.)
|
|
195
|
-
const leaked = source.match(/\bexports\.[A-Za-z_$][\w$]*/g)
|
|
196
|
-
if (leaked) {
|
|
197
|
-
throw new Error(
|
|
198
|
-
`Embed runtime module cannot be emitted: unresolved module references ${leaked.join(', ')}`
|
|
199
|
-
)
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return source
|
|
48
|
+
return EMBED_RUNTIME_MODULE_SOURCE
|
|
203
49
|
}
|
|
204
|
-
|
|
205
|
-
const RUNTIME_MODULE_HEADER = `/**
|
|
206
|
-
* Code embeds inside rich-text content — the shape the editor writes and the
|
|
207
|
-
* page reads back. Generated from @teleporthq/teleport-shared; edit it there.
|
|
208
|
-
*
|
|
209
|
-
* An embed is stored inside the content HTML as a <figure class="tq-embed">.
|
|
210
|
-
* Passive markup (a provider iframe) lives in the figure as real children, so
|
|
211
|
-
* it renders server-side with no JavaScript. Markup that can execute — a
|
|
212
|
-
* <script>, an on* handler, a javascript: URL — is base64-encoded onto the
|
|
213
|
-
* element instead, and mounted at runtime inside a sandboxed iframe so it can
|
|
214
|
-
* never reach this page.
|
|
215
|
-
*/
|
|
216
|
-
`
|
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
// GENERATED from src/utils/rich-text-embeds.ts — do not edit by hand. Regenerate with
|
|
2
|
+
// UPDATE_EMBED_RUNTIME=1 npx jest packages/teleport-shared/__tests__/utils/rich-text-embeds-runtime-module.ts
|
|
3
|
+
// (see generateEmbedRuntimeModuleSource for why this is a string).
|
|
4
|
+
/* tslint:disable:no-invalid-template-strings -- the lines are JavaScript source */
|
|
5
|
+
export const EMBED_RUNTIME_MODULE_SOURCE = [
|
|
6
|
+
'/**',
|
|
7
|
+
' * Code embeds inside rich-text content — the shape the editor writes and the',
|
|
8
|
+
' * page reads back. Generated from @teleporthq/teleport-shared; edit it there.',
|
|
9
|
+
' *',
|
|
10
|
+
' * An embed is stored inside the content HTML as a <figure class="tq-embed">.',
|
|
11
|
+
' * Passive markup (a provider iframe) lives in the figure as real children, so',
|
|
12
|
+
' * it renders server-side with no JavaScript. Markup that can execute — a',
|
|
13
|
+
' * <script>, an on* handler, a javascript: URL — is base64-encoded onto the',
|
|
14
|
+
' * element instead, and mounted at runtime inside a sandboxed iframe so it can',
|
|
15
|
+
' * never reach this page.',
|
|
16
|
+
' */',
|
|
17
|
+
'',
|
|
18
|
+
'export var EMBED_CLASS_NAME = "tq-embed"',
|
|
19
|
+
'',
|
|
20
|
+
'export var EMBED_FRAME_CLASS_NAME = "tq-embed-frame"',
|
|
21
|
+
'',
|
|
22
|
+
'export var EMBED_CAPTION_CLASS_NAME = "tq-embed-caption"',
|
|
23
|
+
'',
|
|
24
|
+
'export var EMBED_BLOT_NAME = "tq-embed"',
|
|
25
|
+
'',
|
|
26
|
+
'export var EMBED_ATTR = {',
|
|
27
|
+
' "MARKER": "data-tq-embed",',
|
|
28
|
+
' "PROVIDER": "data-tq-embed-provider",',
|
|
29
|
+
' "URL": "data-tq-embed-url",',
|
|
30
|
+
' "MODE": "data-tq-embed-mode",',
|
|
31
|
+
' "CODE": "data-tq-embed-code",',
|
|
32
|
+
' "RATIO": "data-tq-embed-ratio",',
|
|
33
|
+
' "WIDTH": "data-tq-embed-width",',
|
|
34
|
+
' "ALIGN": "data-tq-embed-align",',
|
|
35
|
+
' "CAPTION": "data-tq-embed-caption",',
|
|
36
|
+
' "SANDBOX": "data-tq-embed-sandbox",',
|
|
37
|
+
' "ACTIVATED": "data-tq-embed-activated",',
|
|
38
|
+
' "PREVIEW": "data-tq-embed-preview"',
|
|
39
|
+
'}',
|
|
40
|
+
'',
|
|
41
|
+
'export var EMBED_ALIGNMENTS = ["center","float-left","float-right"]',
|
|
42
|
+
'',
|
|
43
|
+
'export var CUSTOM_EMBED_PROVIDER_ID = "custom"',
|
|
44
|
+
'',
|
|
45
|
+
'export var GENERIC_EMBED_PROVIDER_ID = "iframe-url"',
|
|
46
|
+
'',
|
|
47
|
+
'export var DEFAULT_EMBED_WIDTH = 100',
|
|
48
|
+
'',
|
|
49
|
+
'export var DEFAULT_EMBED_ALIGN = "center"',
|
|
50
|
+
'',
|
|
51
|
+
'export var DEFAULT_EMBED_SANDBOX_LEVEL = "strict"',
|
|
52
|
+
'',
|
|
53
|
+
'export var WIDESCREEN_EMBED_RATIO = 56.25',
|
|
54
|
+
'',
|
|
55
|
+
'export var EMBED_CAPTION_STYLE = "margin-top:8px;font-size:0.875em;line-height:1.5;opacity:0.75;text-align:center"',
|
|
56
|
+
'',
|
|
57
|
+
'export var EMBED_PROVIDERS = [',
|
|
58
|
+
' { id: "youtube", label: "YouTube", patterns: [new RegExp("^https?:\\\\/\\\\/(?:www\\\\.|m\\\\.)?youtube\\\\.com\\\\/watch\\\\?(?:[^#]*&)?v=([A-Za-z0-9_-]{6,})", "i"), new RegExp("^https?:\\\\/\\\\/youtu\\\\.be\\\\/([A-Za-z0-9_-]{6,})", "i"), new RegExp("^https?:\\\\/\\\\/(?:www\\\\.)?youtube\\\\.com\\\\/shorts\\\\/([A-Za-z0-9_-]{6,})", "i"), new RegExp("^https?:\\\\/\\\\/(?:www\\\\.)?youtube(?:-nocookie)?\\\\.com\\\\/embed\\\\/([A-Za-z0-9_-]{6,})", "i")], template: "<iframe src=\\"https://www.youtube.com/embed/$1\\" title=\\"YouTube video\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"position:absolute;top:0;left:0;width:100%;height:100%;border:0;border-radius:inherit\\"></iframe>", ratio: 56.25 },',
|
|
59
|
+
' { id: "vimeo", label: "Vimeo", patterns: [new RegExp("^https?:\\\\/\\\\/(?:www\\\\.)?vimeo\\\\.com\\\\/(\\\\d+)", "i"), new RegExp("^https?:\\\\/\\\\/player\\\\.vimeo\\\\.com\\\\/video\\\\/(\\\\d+)", "i")], template: "<iframe src=\\"https://player.vimeo.com/video/$1\\" title=\\"Vimeo video\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"position:absolute;top:0;left:0;width:100%;height:100%;border:0;border-radius:inherit\\"></iframe>", ratio: 56.25 },',
|
|
60
|
+
' { id: "loom", label: "Loom", patterns: [new RegExp("^https?:\\\\/\\\\/(?:www\\\\.)?loom\\\\.com\\\\/(?:share|embed)\\\\/([A-Za-z0-9]+)", "i")], template: "<iframe src=\\"https://www.loom.com/embed/$1\\" title=\\"Loom video\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"position:absolute;top:0;left:0;width:100%;height:100%;border:0;border-radius:inherit\\"></iframe>", ratio: 56.25 },',
|
|
61
|
+
' { id: "dailymotion", label: "Dailymotion", patterns: [new RegExp("^https?:\\\\/\\\\/(?:www\\\\.)?dailymotion\\\\.com\\\\/video\\\\/([A-Za-z0-9]+)", "i"), new RegExp("^https?:\\\\/\\\\/dai\\\\.ly\\\\/([A-Za-z0-9]+)", "i")], template: "<iframe src=\\"https://www.dailymotion.com/embed/video/$1\\" title=\\"Dailymotion video\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"position:absolute;top:0;left:0;width:100%;height:100%;border:0;border-radius:inherit\\"></iframe>", ratio: 56.25 },',
|
|
62
|
+
' { id: "spotify", label: "Spotify", patterns: [new RegExp("^https?:\\\\/\\\\/open\\\\.spotify\\\\.com\\\\/(?:embed\\\\/)?(track|album|playlist|episode|show|artist)\\\\/([A-Za-z0-9]+)", "i")], template: "<iframe src=\\"https://open.spotify.com/embed/$1/$2\\" title=\\"Spotify player\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"display:block;width:100%;border:0;border-radius:inherit;height:352px\\"></iframe>", ratio: null },',
|
|
63
|
+
' { id: "soundcloud", label: "SoundCloud", patterns: [new RegExp("^https?:\\\\/\\\\/soundcloud\\\\.com\\\\/[^?#]+", "i")], template: "<iframe src=\\"https://w.soundcloud.com/player/?url=$E&&color=%23ff5500&auto_play=false&show_teaser=false\\" title=\\"SoundCloud player\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"display:block;width:100%;border:0;border-radius:inherit;height:166px\\"></iframe>", ratio: null },',
|
|
64
|
+
' { id: "apple-podcasts", label: "Apple Podcasts", patterns: [new RegExp("^https?:\\\\/\\\\/podcasts\\\\.apple\\\\.com\\\\/(.+)$", "i")], template: "<iframe src=\\"https://embed.podcasts.apple.com/$1\\" title=\\"Apple Podcasts player\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"display:block;width:100%;border:0;border-radius:inherit;height:175px\\"></iframe>", ratio: null },',
|
|
65
|
+
' { id: "twitter", label: "X (Twitter)", patterns: [new RegExp("^https?:\\\\/\\\\/(?:www\\\\.)?(?:twitter|x)\\\\.com\\\\/[^/]+\\\\/status\\\\/(\\\\d+)", "i")], template: "<blockquote class=\\"twitter-tweet\\"><a href=\\"$&\\"></a></blockquote><script async src=\\"https://platform.twitter.com/widgets.js\\" charset=\\"utf-8\\"></script>", ratio: null },',
|
|
66
|
+
' { id: "instagram", label: "Instagram", patterns: [new RegExp("^https?:\\\\/\\\\/(?:www\\\\.)?instagram\\\\.com\\\\/(?:p|reel|tv)\\\\/([A-Za-z0-9_-]+)", "i")], template: "<blockquote class=\\"instagram-media\\" data-instgrm-permalink=\\"https://www.instagram.com/p/$1/\\" data-instgrm-version=\\"14\\"></blockquote><script async src=\\"https://www.instagram.com/embed.js\\"></script>", ratio: null },',
|
|
67
|
+
' { id: "tiktok", label: "TikTok", patterns: [new RegExp("^https?:\\\\/\\\\/(?:www\\\\.)?tiktok\\\\.com\\\\/@[^/]+\\\\/video\\\\/(\\\\d+)", "i")], template: "<blockquote class=\\"tiktok-embed\\" cite=\\"$&\\" data-video-id=\\"$1\\"><section></section></blockquote><script async src=\\"https://www.tiktok.com/embed.js\\"></script>", ratio: null },',
|
|
68
|
+
' { id: "reddit", label: "Reddit", patterns: [new RegExp("^https?:\\\\/\\\\/(?:www\\\\.)?reddit\\\\.com\\\\/r\\\\/[^/]+\\\\/comments\\\\/.+", "i")], template: "<blockquote class=\\"reddit-embed-bq\\"><a href=\\"$&\\"></a></blockquote><script async src=\\"https://embed.reddit.com/widgets.js\\" charset=\\"UTF-8\\"></script>", ratio: null },',
|
|
69
|
+
' { id: "pinterest", label: "Pinterest", patterns: [new RegExp("^https?:\\\\/\\\\/(?:[a-z]{2}\\\\.)?pinterest\\\\.[a-z.]+\\\\/pin\\\\/[0-9]+", "i")], template: "<a data-pin-do=\\"embedPin\\" href=\\"$&\\"></a><script async defer src=\\"https://assets.pinterest.com/js/pinit.js\\"></script>", ratio: null },',
|
|
70
|
+
' { id: "facebook", label: "Facebook", patterns: [new RegExp("^https?:\\\\/\\\\/(?:www\\\\.|web\\\\.)?facebook\\\\.com\\\\/.+\\\\/(?:posts|videos)\\\\/.+", "i")], template: "<iframe src=\\"https://www.facebook.com/plugins/post.php?href=$E&&show_text=true\\" title=\\"Facebook post\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"display:block;width:100%;border:0;border-radius:inherit;height:500px\\"></iframe>", ratio: null },',
|
|
71
|
+
' { id: "github-gist", label: "GitHub Gist", patterns: [new RegExp("^https?:\\\\/\\\\/gist\\\\.github\\\\.com\\\\/([^/]+\\\\/[a-f0-9]+)", "i")], template: "<script src=\\"https://gist.github.com/$1.js\\"></script>", ratio: null },',
|
|
72
|
+
' { id: "codepen", label: "CodePen", patterns: [new RegExp("^https?:\\\\/\\\\/codepen\\\\.io\\\\/([^/]+)\\\\/(?:pen|embed|details|full)\\\\/([A-Za-z0-9]+)", "i")], template: "<iframe src=\\"https://codepen.io/$1/embed/$2?default-tab=result\\" title=\\"CodePen\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"display:block;width:100%;border:0;border-radius:inherit;height:400px\\"></iframe>", ratio: null },',
|
|
73
|
+
' { id: "codesandbox", label: "CodeSandbox", patterns: [new RegExp("^https?:\\\\/\\\\/codesandbox\\\\.io\\\\/(?:s|embed)\\\\/([A-Za-z0-9_-]+)", "i"), new RegExp("^https?:\\\\/\\\\/codesandbox\\\\.io\\\\/p\\\\/(?:sandbox|devbox)\\\\/([A-Za-z0-9_-]+)", "i")], template: "<iframe src=\\"https://codesandbox.io/embed/$1\\" title=\\"CodeSandbox\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"display:block;width:100%;border:0;border-radius:inherit;height:500px\\"></iframe>", ratio: null },',
|
|
74
|
+
' { id: "jsfiddle", label: "JSFiddle", patterns: [new RegExp("^https?:\\\\/\\\\/(?:www\\\\.)?jsfiddle\\\\.net\\\\/((?:[^/]+\\\\/)?[A-Za-z0-9]+)\\\\/?", "i")], template: "<iframe src=\\"https://jsfiddle.net/$1/embedded/\\" title=\\"JSFiddle\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"display:block;width:100%;border:0;border-radius:inherit;height:400px\\"></iframe>", ratio: null },',
|
|
75
|
+
' { id: "figma", label: "Figma", patterns: [new RegExp("^https?:\\\\/\\\\/(?:www\\\\.)?figma\\\\.com\\\\/(?:file|design|proto|board|slides)\\\\/.+", "i")], template: "<iframe src=\\"https://www.figma.com/embed?embed_host=share&url=$E&\\" title=\\"Figma\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"position:absolute;top:0;left:0;width:100%;height:100%;border:0;border-radius:inherit\\"></iframe>", ratio: 56.25 },',
|
|
76
|
+
' { id: "canva", label: "Canva", patterns: [new RegExp("^https?:\\\\/\\\\/(?:www\\\\.)?canva\\\\.com\\\\/design\\\\/([A-Za-z0-9_-]+)\\\\/([A-Za-z0-9_-]+)\\\\/(?:view|watch)", "i")], template: "<iframe src=\\"https://www.canva.com/design/$1/$2/view?embed\\" title=\\"Canva design\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"position:absolute;top:0;left:0;width:100%;height:100%;border:0;border-radius:inherit\\"></iframe>", ratio: 56.25 },',
|
|
77
|
+
' { id: "miro", label: "Miro", patterns: [new RegExp("^https?:\\\\/\\\\/miro\\\\.com\\\\/app\\\\/(?:board|live-embed)\\\\/([A-Za-z0-9_=-]+)", "i")], template: "<iframe src=\\"https://miro.com/app/live-embed/$1/\\" title=\\"Miro board\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"position:absolute;top:0;left:0;width:100%;height:100%;border:0;border-radius:inherit\\"></iframe>", ratio: 56.25 },',
|
|
78
|
+
' { id: "google-maps", label: "Google Maps", patterns: [new RegExp("^https?:\\\\/\\\\/(?:www\\\\.)?google\\\\.[a-z.]+\\\\/maps\\\\/embed\\\\?(.+)$", "i")], template: "<iframe src=\\"https://www.google.com/maps/embed?$1\\" title=\\"Google Maps\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"position:absolute;top:0;left:0;width:100%;height:100%;border:0;border-radius:inherit\\"></iframe>", ratio: 56.25 },',
|
|
79
|
+
' { id: "google-maps-place", label: "Google Maps", patterns: [new RegExp("^https?:\\\\/\\\\/(?:(?:www\\\\.)?google\\\\.[a-z.]+\\\\/maps|maps\\\\.app\\\\.goo\\\\.gl)\\\\/.+", "i")], template: "<iframe src=\\"https://maps.google.com/maps?q=$E&&output=embed\\" title=\\"Google Maps\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"position:absolute;top:0;left:0;width:100%;height:100%;border:0;border-radius:inherit\\"></iframe>", ratio: 56.25 },',
|
|
80
|
+
' { id: "google-forms", label: "Google Forms", patterns: [new RegExp("^https?:\\\\/\\\\/docs\\\\.google\\\\.com\\\\/forms\\\\/d\\\\/(?:e\\\\/)?([A-Za-z0-9_-]+)", "i")], template: "<iframe src=\\"https://docs.google.com/forms/d/e/$1/viewform?embedded=true\\" title=\\"Google Form\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"display:block;width:100%;border:0;border-radius:inherit;height:700px\\"></iframe>", ratio: null },',
|
|
81
|
+
' { id: "google-docs", label: "Google Docs", patterns: [new RegExp("^https?:\\\\/\\\\/docs\\\\.google\\\\.com\\\\/(document|spreadsheets|presentation)\\\\/d\\\\/([A-Za-z0-9_-]+)", "i")], template: "<iframe src=\\"https://docs.google.com/$1/d/$2/preview\\" title=\\"Google Docs\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"display:block;width:100%;border:0;border-radius:inherit;height:600px\\"></iframe>", ratio: null },',
|
|
82
|
+
' { id: "airtable", label: "Airtable", patterns: [new RegExp("^https?:\\\\/\\\\/airtable\\\\.com\\\\/(?:embed\\\\/)?(app[A-Za-z0-9/?=&_-]+)", "i")], template: "<iframe src=\\"https://airtable.com/embed/$1\\" title=\\"Airtable\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"display:block;width:100%;border:0;border-radius:inherit;height:533px\\"></iframe>", ratio: null },',
|
|
83
|
+
' { id: "typeform", label: "Typeform", patterns: [new RegExp("^https?:\\\\/\\\\/(?:[A-Za-z0-9-]+\\\\.)?typeform\\\\.com\\\\/to\\\\/([A-Za-z0-9]+)", "i")], template: "<iframe src=\\"https://form.typeform.com/to/$1\\" title=\\"Typeform\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"display:block;width:100%;border:0;border-radius:inherit;height:500px\\"></iframe>", ratio: null },',
|
|
84
|
+
' { id: "calendly", label: "Calendly", patterns: [new RegExp("^https?:\\\\/\\\\/calendly\\\\.com\\\\/(.+)$", "i")], template: "<iframe src=\\"https://calendly.com/$1\\" title=\\"Calendly\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"display:block;width:100%;border:0;border-radius:inherit;height:700px\\"></iframe>", ratio: null },',
|
|
85
|
+
' { id: "iframe-url", label: "Web page", patterns: [new RegExp("^https:\\\\/\\\\/[^\\\\s\\"\'<>]+$", "i")], template: "<iframe src=\\"$&\\" title=\\"Embedded page\\" loading=\\"lazy\\" frameborder=\\"0\\" referrerpolicy=\\"strict-origin-when-cross-origin\\" allow=\\"accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share\\" allowfullscreen style=\\"position:absolute;top:0;left:0;width:100%;height:100%;border:0;border-radius:inherit\\"></iframe>", ratio: 56.25 }',
|
|
86
|
+
']',
|
|
87
|
+
'',
|
|
88
|
+
'export var EMBED_SANDBOX_FLAGS_STRICT = "allow-scripts allow-popups allow-popups-to-escape-sandbox allow-forms allow-presentation"',
|
|
89
|
+
'',
|
|
90
|
+
'export var EMBED_SANDBOX_FLAGS_TRUSTED = "allow-scripts allow-popups allow-popups-to-escape-sandbox allow-forms allow-presentation allow-same-origin"',
|
|
91
|
+
'',
|
|
92
|
+
'export var EMBED_HEIGHT_MESSAGE_TYPE = "tq-embed-height"',
|
|
93
|
+
'',
|
|
94
|
+
'export var EMBED_TOKEN_PLACEHOLDER = "__TQ_EMBED_TOKEN__"',
|
|
95
|
+
'',
|
|
96
|
+
'export var EMBED_MIN_HEIGHT = 80',
|
|
97
|
+
'',
|
|
98
|
+
'export var EMBED_MAX_HEIGHT = 6000',
|
|
99
|
+
'',
|
|
100
|
+
'export var EMBED_INITIAL_HEIGHT = 320',
|
|
101
|
+
'',
|
|
102
|
+
'export var EMBED_SANDBOX_DOC_HEAD = "<!doctype html><html><head><meta charset=\\"utf-8\\"><meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\"><base target=\\"_blank\\"><style>html,body{margin:0;padding:0;background:transparent}img,iframe,video,blockquote{max-width:100%}</style><script>(function(){var token=\\"__TQ_EMBED_TOKEN__\\";var last=0;function report(){try{var doc=document.documentElement;var body=document.body;var height=Math.max(doc?doc.scrollHeight:0,doc?doc.offsetHeight:0,body?body.scrollHeight:0,body?body.offsetHeight:0);if(!height||height===last){return;}last=height;parent.postMessage({type:\\"tq-embed-height\\",token:token,height:height},\\"*\\");}catch(e){}}function watch(){report();if(typeof ResizeObserver===\\"function\\"&&document.documentElement){new ResizeObserver(report).observe(document.documentElement);}if(typeof MutationObserver===\\"function\\"&&document.body){new MutationObserver(report).observe(document.body,{childList:true,subtree:true,attributes:true});}var delays=[150,400,900,1800,3500];for(var i=0;i<delays.length;i++){setTimeout(report,delays[i]);}}if(document.readyState===\\"loading\\"){document.addEventListener(\\"DOMContentLoaded\\",watch);}else{watch();}window.addEventListener(\\"load\\",report);})();</script></head><body>"',
|
|
103
|
+
'',
|
|
104
|
+
'export var EMBED_SANDBOX_DOC_TAIL = "</body></html>"',
|
|
105
|
+
'',
|
|
106
|
+
'export var embedTokenCounter = 0',
|
|
107
|
+
'',
|
|
108
|
+
'export function isSafeEmbedUrl(url) {',
|
|
109
|
+
" return /^https?:\\/\\/[^\\s\"'<>]+$/i.test((url || '').trim());",
|
|
110
|
+
'}',
|
|
111
|
+
'',
|
|
112
|
+
'export function resolveEmbedProvider(url) {',
|
|
113
|
+
" const trimmed = (url || '').trim();",
|
|
114
|
+
' if (!isSafeEmbedUrl(trimmed)) {',
|
|
115
|
+
' return null;',
|
|
116
|
+
' }',
|
|
117
|
+
' for (const provider of EMBED_PROVIDERS) {',
|
|
118
|
+
' for (const pattern of provider.patterns) {',
|
|
119
|
+
' const match = trimmed.match(pattern);',
|
|
120
|
+
' if (match) {',
|
|
121
|
+
' return { provider, match };',
|
|
122
|
+
' }',
|
|
123
|
+
' }',
|
|
124
|
+
' }',
|
|
125
|
+
' return null;',
|
|
126
|
+
'}',
|
|
127
|
+
'',
|
|
128
|
+
'export function applyEmbedTemplate(template, match, url) {',
|
|
129
|
+
' return template.replace(/\\$(\\$|E?(?:[1-9]|&))/g, (_token, spec) => {',
|
|
130
|
+
' var _a;',
|
|
131
|
+
" if (spec === '$') {",
|
|
132
|
+
" return '$';",
|
|
133
|
+
' }',
|
|
134
|
+
" const encoded = spec.charAt(0) === 'E';",
|
|
135
|
+
' const key = encoded ? spec.slice(1) : spec;',
|
|
136
|
+
" const raw = key === '&' ? url : (_a = match[Number(key)]) !== null && _a !== void 0 ? _a : '';",
|
|
137
|
+
' return encoded ? encodeURIComponent(raw) : raw;',
|
|
138
|
+
' });',
|
|
139
|
+
'}',
|
|
140
|
+
'',
|
|
141
|
+
'export function buildEmbedHtmlFromUrl(url) {',
|
|
142
|
+
' const resolved = resolveEmbedProvider(url);',
|
|
143
|
+
' if (!resolved) {',
|
|
144
|
+
' return null;',
|
|
145
|
+
' }',
|
|
146
|
+
' return {',
|
|
147
|
+
' provider: resolved.provider,',
|
|
148
|
+
' html: applyEmbedTemplate(resolved.provider.template, resolved.match, url.trim()),',
|
|
149
|
+
' };',
|
|
150
|
+
'}',
|
|
151
|
+
'',
|
|
152
|
+
'export function resolveEmbedMode(html) {',
|
|
153
|
+
" const markup = html || '';",
|
|
154
|
+
' const executes = /<script[\\s/>]/i.test(markup) ||',
|
|
155
|
+
' /\\son[a-z]+\\s*=/i.test(markup) ||',
|
|
156
|
+
' /(?:href|src|action|formaction)\\s*=\\s*["\']?\\s*javascript:/i.test(markup);',
|
|
157
|
+
" return executes ? 'sandbox' : 'inline';",
|
|
158
|
+
'}',
|
|
159
|
+
'',
|
|
160
|
+
'export function clampEmbedWidth(width) {',
|
|
161
|
+
' if (!isFinite(width)) {',
|
|
162
|
+
' return DEFAULT_EMBED_WIDTH;',
|
|
163
|
+
' }',
|
|
164
|
+
' return Math.max(10, Math.min(100, Math.round(width)));',
|
|
165
|
+
'}',
|
|
166
|
+
'',
|
|
167
|
+
'export function normalizeEmbedAlign(align) {',
|
|
168
|
+
' return EMBED_ALIGNMENTS.indexOf(align) !== -1',
|
|
169
|
+
' ? align',
|
|
170
|
+
' : DEFAULT_EMBED_ALIGN;',
|
|
171
|
+
'}',
|
|
172
|
+
'',
|
|
173
|
+
'export function escapeEmbedAttribute(value) {',
|
|
174
|
+
" return String(value !== null && value !== void 0 ? value : '')",
|
|
175
|
+
" .replace(/&/g, '&')",
|
|
176
|
+
" .replace(/\"/g, '"')",
|
|
177
|
+
" .replace(/</g, '<')",
|
|
178
|
+
" .replace(/>/g, '>');",
|
|
179
|
+
'}',
|
|
180
|
+
'',
|
|
181
|
+
'export function escapeEmbedText(value) {',
|
|
182
|
+
" return String(value !== null && value !== void 0 ? value : '')",
|
|
183
|
+
" .replace(/&/g, '&')",
|
|
184
|
+
" .replace(/</g, '<')",
|
|
185
|
+
" .replace(/>/g, '>');",
|
|
186
|
+
'}',
|
|
187
|
+
'',
|
|
188
|
+
'export function encodeEmbedCode(code) {',
|
|
189
|
+
' const binary = encodeURIComponent(code).replace(/%([0-9A-F]{2})/gi, (_m, hex) => String.fromCharCode(parseInt(hex, 16)));',
|
|
190
|
+
" if (typeof btoa === 'function') {",
|
|
191
|
+
' return btoa(binary);',
|
|
192
|
+
' }',
|
|
193
|
+
" if (typeof Buffer !== 'undefined') {",
|
|
194
|
+
" return Buffer.from(binary, 'binary').toString('base64');",
|
|
195
|
+
' }',
|
|
196
|
+
" throw new Error('No base64 encoder available');",
|
|
197
|
+
'}',
|
|
198
|
+
'',
|
|
199
|
+
'export function decodeEmbedCode(encoded) {',
|
|
200
|
+
' let binary;',
|
|
201
|
+
" if (typeof atob === 'function') {",
|
|
202
|
+
' binary = atob(encoded);',
|
|
203
|
+
' }',
|
|
204
|
+
" else if (typeof Buffer !== 'undefined') {",
|
|
205
|
+
" binary = Buffer.from(encoded, 'base64').toString('binary');",
|
|
206
|
+
' }',
|
|
207
|
+
' else {',
|
|
208
|
+
" throw new Error('No base64 decoder available');",
|
|
209
|
+
' }',
|
|
210
|
+
" let percent = '';",
|
|
211
|
+
' for (let index = 0; index < binary.length; index += 1) {',
|
|
212
|
+
' percent += `%${`00${binary.charCodeAt(index).toString(16)}`.slice(-2)}`;',
|
|
213
|
+
' }',
|
|
214
|
+
' return decodeURIComponent(percent);',
|
|
215
|
+
'}',
|
|
216
|
+
'',
|
|
217
|
+
'export function createEmbedValue(params) {',
|
|
218
|
+
' var _a, _b, _c;',
|
|
219
|
+
" const code = params.code || '';",
|
|
220
|
+
' return {',
|
|
221
|
+
' provider: params.provider || CUSTOM_EMBED_PROVIDER_ID,',
|
|
222
|
+
" url: params.url || '',",
|
|
223
|
+
' code,',
|
|
224
|
+
' mode: resolveEmbedMode(code),',
|
|
225
|
+
' ratio: (_a = params.ratio) !== null && _a !== void 0 ? _a : null,',
|
|
226
|
+
' width: clampEmbedWidth((_b = params.width) !== null && _b !== void 0 ? _b : DEFAULT_EMBED_WIDTH),',
|
|
227
|
+
' align: normalizeEmbedAlign((_c = params.align) !== null && _c !== void 0 ? _c : DEFAULT_EMBED_ALIGN),',
|
|
228
|
+
" caption: params.caption || '',",
|
|
229
|
+
" sandboxLevel: params.sandboxLevel === 'trusted' ? 'trusted' : DEFAULT_EMBED_SANDBOX_LEVEL,",
|
|
230
|
+
' };',
|
|
231
|
+
'}',
|
|
232
|
+
'',
|
|
233
|
+
'export function embedBlockStyle(value) {',
|
|
234
|
+
' const declarations = [',
|
|
235
|
+
" 'position:relative',",
|
|
236
|
+
' `width:${clampEmbedWidth(value.width)}%`,',
|
|
237
|
+
" 'max-width:100%',",
|
|
238
|
+
" 'margin:16px 0',",
|
|
239
|
+
' ];',
|
|
240
|
+
" if (value.align === 'center') {",
|
|
241
|
+
" declarations.push('margin-left:auto', 'margin-right:auto');",
|
|
242
|
+
' }',
|
|
243
|
+
" else if (value.align === 'float-left') {",
|
|
244
|
+
" declarations.push('float:left', 'margin-right:16px', 'margin-bottom:8px');",
|
|
245
|
+
' }',
|
|
246
|
+
" else if (value.align === 'float-right') {",
|
|
247
|
+
" declarations.push('float:right', 'margin-left:16px', 'margin-bottom:8px');",
|
|
248
|
+
' }',
|
|
249
|
+
" return declarations.join(';');",
|
|
250
|
+
'}',
|
|
251
|
+
'',
|
|
252
|
+
'export function embedFrameStyle(ratio) {',
|
|
253
|
+
' if (ratio === null || !isFinite(ratio) || ratio <= 0) {',
|
|
254
|
+
" return 'position:relative;width:100%';",
|
|
255
|
+
' }',
|
|
256
|
+
' return `position:relative;width:100%;padding-top:${ratio}%`;',
|
|
257
|
+
'}',
|
|
258
|
+
'',
|
|
259
|
+
'export function buildEmbedElementHtml(value) {',
|
|
260
|
+
' const attrs = [',
|
|
261
|
+
' `class="${EMBED_CLASS_NAME}"`,',
|
|
262
|
+
' `${EMBED_ATTR.MARKER}="1"`,',
|
|
263
|
+
' `${EMBED_ATTR.PROVIDER}="${escapeEmbedAttribute(value.provider)}"`,',
|
|
264
|
+
' `${EMBED_ATTR.MODE}="${value.mode}"`,',
|
|
265
|
+
' `${EMBED_ATTR.WIDTH}="${clampEmbedWidth(value.width)}"`,',
|
|
266
|
+
' `${EMBED_ATTR.ALIGN}="${value.align}"`,',
|
|
267
|
+
' `${EMBED_ATTR.SANDBOX}="${value.sandboxLevel}"`,',
|
|
268
|
+
' ];',
|
|
269
|
+
' if (value.url) {',
|
|
270
|
+
' attrs.push(`${EMBED_ATTR.URL}="${escapeEmbedAttribute(value.url)}"`);',
|
|
271
|
+
' }',
|
|
272
|
+
' if (value.ratio !== null) {',
|
|
273
|
+
' attrs.push(`${EMBED_ATTR.RATIO}="${value.ratio}"`);',
|
|
274
|
+
' }',
|
|
275
|
+
' if (value.caption) {',
|
|
276
|
+
' attrs.push(`${EMBED_ATTR.CAPTION}="${escapeEmbedAttribute(value.caption)}"`);',
|
|
277
|
+
' }',
|
|
278
|
+
" if (value.mode === 'sandbox') {",
|
|
279
|
+
' attrs.push(`${EMBED_ATTR.CODE}="${escapeEmbedAttribute(encodeEmbedCode(value.code))}"`);',
|
|
280
|
+
' }',
|
|
281
|
+
' attrs.push(\'contenteditable="false"\');',
|
|
282
|
+
' attrs.push(`style="${embedBlockStyle(value)}"`);',
|
|
283
|
+
' const caption = value.caption',
|
|
284
|
+
' ? `<figcaption class="${EMBED_CAPTION_CLASS_NAME}" style="${EMBED_CAPTION_STYLE}">${escapeEmbedText(value.caption)}</figcaption>`',
|
|
285
|
+
" : '';",
|
|
286
|
+
" return (`<figure ${attrs.join(' ')}>` +",
|
|
287
|
+
' `<div class="${EMBED_FRAME_CLASS_NAME}" style="${embedFrameStyle(value.ratio)}">` +',
|
|
288
|
+
' `${buildEmbedFrameChildren(value)}</div>${caption}</figure>`);',
|
|
289
|
+
'}',
|
|
290
|
+
'',
|
|
291
|
+
'export function buildEmbedFrameChildren(value) {',
|
|
292
|
+
" if (value.mode === 'inline') {",
|
|
293
|
+
' return value.code;',
|
|
294
|
+
' }',
|
|
295
|
+
' if (!value.url) {',
|
|
296
|
+
" return '';",
|
|
297
|
+
' }',
|
|
298
|
+
' return (`<noscript><a href="${escapeEmbedAttribute(value.url)}" rel="noopener noreferrer" ` +',
|
|
299
|
+
' `target="_blank">${escapeEmbedText(value.url)}</a></noscript>`);',
|
|
300
|
+
'}',
|
|
301
|
+
'',
|
|
302
|
+
'export function findEmbedFrame(element) {',
|
|
303
|
+
' return element.querySelector(`.${EMBED_FRAME_CLASS_NAME}`);',
|
|
304
|
+
'}',
|
|
305
|
+
'',
|
|
306
|
+
'export function readEmbedValueFromElement(element) {',
|
|
307
|
+
" const mode = element.getAttribute(EMBED_ATTR.MODE) === 'sandbox' ? 'sandbox' : 'inline';",
|
|
308
|
+
' const frame = findEmbedFrame(element);',
|
|
309
|
+
' const rawRatio = element.getAttribute(EMBED_ATTR.RATIO);',
|
|
310
|
+
' const parsedRatio = rawRatio === null ? NaN : parseFloat(rawRatio);',
|
|
311
|
+
" let code = '';",
|
|
312
|
+
" if (mode === 'sandbox') {",
|
|
313
|
+
' code = readEncodedEmbedCode(element);',
|
|
314
|
+
' }',
|
|
315
|
+
' else if (frame) {',
|
|
316
|
+
' code = frame.innerHTML;',
|
|
317
|
+
' }',
|
|
318
|
+
' return {',
|
|
319
|
+
' provider: element.getAttribute(EMBED_ATTR.PROVIDER) || CUSTOM_EMBED_PROVIDER_ID,',
|
|
320
|
+
" url: element.getAttribute(EMBED_ATTR.URL) || '',",
|
|
321
|
+
' code,',
|
|
322
|
+
' mode,',
|
|
323
|
+
' ratio: isFinite(parsedRatio) ? parsedRatio : null,',
|
|
324
|
+
" width: clampEmbedWidth(parseFloat(element.getAttribute(EMBED_ATTR.WIDTH) || '')),",
|
|
325
|
+
" align: normalizeEmbedAlign(element.getAttribute(EMBED_ATTR.ALIGN) || ''),",
|
|
326
|
+
" caption: element.getAttribute(EMBED_ATTR.CAPTION) || '',",
|
|
327
|
+
" sandboxLevel: element.getAttribute(EMBED_ATTR.SANDBOX) === 'trusted'",
|
|
328
|
+
" ? 'trusted'",
|
|
329
|
+
' : DEFAULT_EMBED_SANDBOX_LEVEL,',
|
|
330
|
+
' };',
|
|
331
|
+
'}',
|
|
332
|
+
'',
|
|
333
|
+
'export function readEncodedEmbedCode(element) {',
|
|
334
|
+
' const encoded = element.getAttribute(EMBED_ATTR.CODE);',
|
|
335
|
+
' if (!encoded) {',
|
|
336
|
+
" return '';",
|
|
337
|
+
' }',
|
|
338
|
+
' try {',
|
|
339
|
+
' return decodeEmbedCode(encoded);',
|
|
340
|
+
' }',
|
|
341
|
+
' catch (_a) {',
|
|
342
|
+
" return '';",
|
|
343
|
+
' }',
|
|
344
|
+
'}',
|
|
345
|
+
'',
|
|
346
|
+
'export function normalizeEmbedsForStorage(root) {',
|
|
347
|
+
' const previews = root.querySelectorAll(`[${EMBED_ATTR.PREVIEW}]`);',
|
|
348
|
+
' for (let index = previews.length - 1; index >= 0; index -= 1) {',
|
|
349
|
+
' const preview = previews[index];',
|
|
350
|
+
' if (preview.parentNode) {',
|
|
351
|
+
' preview.parentNode.removeChild(preview);',
|
|
352
|
+
' }',
|
|
353
|
+
' }',
|
|
354
|
+
' const blocks = root.querySelectorAll(`[${EMBED_ATTR.MARKER}]`);',
|
|
355
|
+
' for (let index = 0; index < blocks.length; index += 1) {',
|
|
356
|
+
' const block = blocks[index];',
|
|
357
|
+
' block.removeAttribute(EMBED_ATTR.ACTIVATED);',
|
|
358
|
+
' const frame = findEmbedFrame(block);',
|
|
359
|
+
' if (!frame) {',
|
|
360
|
+
' continue;',
|
|
361
|
+
' }',
|
|
362
|
+
' const value = readEmbedValueFromElement(block);',
|
|
363
|
+
" if (value.mode !== 'sandbox') {",
|
|
364
|
+
' continue;',
|
|
365
|
+
' }',
|
|
366
|
+
' frame.innerHTML = buildEmbedFrameChildren(value);',
|
|
367
|
+
' }',
|
|
368
|
+
'}',
|
|
369
|
+
'',
|
|
370
|
+
'export function resolveEmbedSandboxFlags(level) {',
|
|
371
|
+
" return level === 'trusted' ? EMBED_SANDBOX_FLAGS_TRUSTED : EMBED_SANDBOX_FLAGS_STRICT;",
|
|
372
|
+
'}',
|
|
373
|
+
'',
|
|
374
|
+
'export function buildEmbedSandboxDocument(code, token) {',
|
|
375
|
+
' return (EMBED_SANDBOX_DOC_HEAD.replace(EMBED_TOKEN_PLACEHOLDER, token) +',
|
|
376
|
+
" (code || '') +",
|
|
377
|
+
' EMBED_SANDBOX_DOC_TAIL);',
|
|
378
|
+
'}',
|
|
379
|
+
'',
|
|
380
|
+
'export function parseEmbedHeightMessage(data) {',
|
|
381
|
+
" if (!data || typeof data !== 'object') {",
|
|
382
|
+
' return null;',
|
|
383
|
+
' }',
|
|
384
|
+
' const message = data;',
|
|
385
|
+
" if (message.type !== EMBED_HEIGHT_MESSAGE_TYPE || typeof message.token !== 'string') {",
|
|
386
|
+
' return null;',
|
|
387
|
+
' }',
|
|
388
|
+
' const height = Number(message.height);',
|
|
389
|
+
' if (!isFinite(height) || height <= 0) {',
|
|
390
|
+
' return null;',
|
|
391
|
+
' }',
|
|
392
|
+
' return {',
|
|
393
|
+
' token: message.token,',
|
|
394
|
+
' height: Math.min(Math.max(Math.round(height), EMBED_MIN_HEIGHT), EMBED_MAX_HEIGHT),',
|
|
395
|
+
' };',
|
|
396
|
+
'}',
|
|
397
|
+
'',
|
|
398
|
+
'export function createEmbedToken() {',
|
|
399
|
+
' embedTokenCounter += 1;',
|
|
400
|
+
' return `tqe-${Date.now().toString(36)}-${embedTokenCounter.toString(36)}-${Math.random()',
|
|
401
|
+
' .toString(36)',
|
|
402
|
+
' .slice(2, 8)}`;',
|
|
403
|
+
'}',
|
|
404
|
+
'',
|
|
405
|
+
].join('\n')
|