@nordcraft/runtime 1.0.57 → 1.0.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/createComponent.js +12 -13
- package/dist/components/createComponent.js.map +1 -1
- package/dist/components/createElement.js +9 -7
- package/dist/components/createElement.js.map +1 -1
- package/dist/components/createNode.js.map +1 -1
- package/dist/custom-element.main.esm.js +27 -27
- package/dist/custom-element.main.esm.js.map +4 -4
- package/dist/editor/input.d.ts +1 -0
- package/dist/editor/input.js +16 -0
- package/dist/editor/input.js.map +1 -0
- package/dist/editor/links.d.ts +6 -0
- package/dist/editor/links.js +15 -0
- package/dist/editor/links.js.map +1 -0
- package/dist/editor/overlay.d.ts +12 -0
- package/dist/editor/overlay.js +20 -0
- package/dist/editor/overlay.js.map +1 -0
- package/dist/editor/types.d.ts +254 -0
- package/dist/editor/types.js +42 -0
- package/dist/editor/types.js.map +1 -0
- package/dist/editor-preview.main.js +147 -198
- package/dist/editor-preview.main.js.map +1 -1
- package/dist/page.main.esm.js +3 -3
- package/dist/page.main.esm.js.map +4 -4
- package/dist/page.main.js +20 -0
- package/dist/page.main.js.map +1 -1
- package/dist/styles/CustomPropertyStyleSheet.test.js +12 -3
- package/dist/styles/CustomPropertyStyleSheet.test.js.map +1 -1
- package/package.json +4 -4
- package/src/components/createComponent.ts +27 -20
- package/src/components/createElement.ts +29 -21
- package/src/components/createNode.ts +0 -1
- package/src/editor/input.ts +17 -0
- package/src/editor/links.ts +16 -0
- package/src/editor/overlay.ts +21 -0
- package/src/editor/types.ts +271 -0
- package/src/editor-preview.main.ts +180 -411
- package/src/page.main.ts +23 -0
- package/src/styles/CustomPropertyStyleSheet.test.ts +12 -3
- package/src/editor/types.d.ts +0 -36
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
/* eslint-disable no-case-declarations */
|
|
4
4
|
/* eslint-disable no-fallthrough */
|
|
5
5
|
import { isLegacyApi } from '@nordcraft/core/dist/api/api'
|
|
6
|
+
import { isLegacyPluginAction } from '@nordcraft/core/dist/component/actionUtils'
|
|
6
7
|
import {
|
|
7
8
|
HeadTagTypes,
|
|
8
|
-
type AnimationKeyframe,
|
|
9
9
|
type Component,
|
|
10
10
|
type ComponentData,
|
|
11
11
|
type MetaEntry,
|
|
@@ -24,8 +24,8 @@ import {
|
|
|
24
24
|
type PluginFormula,
|
|
25
25
|
type ToddleFormula,
|
|
26
26
|
} from '@nordcraft/core/dist/formula/formulaTypes'
|
|
27
|
-
import { valueFormula } from '@nordcraft/core/dist/formula/formulaUtils'
|
|
28
27
|
import { getClassName } from '@nordcraft/core/dist/styling/className'
|
|
28
|
+
import { appendUnit } from '@nordcraft/core/dist/styling/customProperty'
|
|
29
29
|
import type { OldTheme, Theme } from '@nordcraft/core/dist/styling/theme'
|
|
30
30
|
import { getThemeCss, renderTheme } from '@nordcraft/core/dist/styling/theme'
|
|
31
31
|
import type { StyleVariant } from '@nordcraft/core/dist/styling/variantSelector'
|
|
@@ -41,6 +41,7 @@ import type {
|
|
|
41
41
|
} from '@nordcraft/core/dist/types'
|
|
42
42
|
import { mapObject, omitKeys } from '@nordcraft/core/dist/utils/collections'
|
|
43
43
|
import { safeFunctionName } from '@nordcraft/core/dist/utils/handlerUtils'
|
|
44
|
+
import { isDefined } from '@nordcraft/core/dist/utils/util'
|
|
44
45
|
import * as libActions from '@nordcraft/std-lib/dist/actions'
|
|
45
46
|
import * as libFormulas from '@nordcraft/std-lib/dist/formulas'
|
|
46
47
|
import fastDeepEqual from 'fast-deep-equal'
|
|
@@ -55,7 +56,15 @@ import { dragMove } from './editor/drag-drop/dragMove'
|
|
|
55
56
|
import { dragReorder } from './editor/drag-drop/dragReorder'
|
|
56
57
|
import { dragStarted } from './editor/drag-drop/dragStarted'
|
|
57
58
|
import { introspectApiRequest } from './editor/graphql'
|
|
58
|
-
import
|
|
59
|
+
import { isInputTarget } from './editor/input'
|
|
60
|
+
import { updateComponentLinks } from './editor/links'
|
|
61
|
+
import { getRectData } from './editor/overlay'
|
|
62
|
+
import {
|
|
63
|
+
TextNodeComputedStyles,
|
|
64
|
+
type DragState,
|
|
65
|
+
type EditorPostMessageType,
|
|
66
|
+
type NordcraftPreviewEvent,
|
|
67
|
+
} from './editor/types'
|
|
59
68
|
import { handleAction } from './events/handleAction'
|
|
60
69
|
import type { Signal } from './signal/signal'
|
|
61
70
|
import { signal } from './signal/signal'
|
|
@@ -75,130 +84,6 @@ import {
|
|
|
75
84
|
storeScrollState,
|
|
76
85
|
} from './utils/storeScrollState'
|
|
77
86
|
|
|
78
|
-
type ToddlePreviewEvent =
|
|
79
|
-
| {
|
|
80
|
-
type: 'style_variant_changed'
|
|
81
|
-
variantIndex: number | null
|
|
82
|
-
}
|
|
83
|
-
| {
|
|
84
|
-
type: 'component'
|
|
85
|
-
component: Component
|
|
86
|
-
}
|
|
87
|
-
| { type: 'components'; components: Component[] }
|
|
88
|
-
| {
|
|
89
|
-
type: 'packages'
|
|
90
|
-
packages: Record<
|
|
91
|
-
string,
|
|
92
|
-
{
|
|
93
|
-
components: Record<string, Component>
|
|
94
|
-
formulas: Record<
|
|
95
|
-
string,
|
|
96
|
-
PluginFormula<FormulaHandlerV2> | PluginFormula<string>
|
|
97
|
-
>
|
|
98
|
-
actions: Record<string, PluginActionV2 | PluginAction>
|
|
99
|
-
manifest: {
|
|
100
|
-
name: string
|
|
101
|
-
// commit represents the commit hash (version) of the package
|
|
102
|
-
commit: string
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
>
|
|
106
|
-
}
|
|
107
|
-
| {
|
|
108
|
-
type: 'global_formulas'
|
|
109
|
-
formulas: Record<
|
|
110
|
-
string,
|
|
111
|
-
PluginFormula<FormulaHandlerV2> | PluginFormula<string>
|
|
112
|
-
>
|
|
113
|
-
}
|
|
114
|
-
| {
|
|
115
|
-
type: 'global_actions'
|
|
116
|
-
actions: Record<string, PluginActionV2 | PluginAction>
|
|
117
|
-
}
|
|
118
|
-
| { type: 'theme'; theme: Record<string, OldTheme | Theme> }
|
|
119
|
-
| { type: 'mode'; mode: 'design' | 'test' }
|
|
120
|
-
| { type: 'attrs'; attrs: Record<string, unknown> }
|
|
121
|
-
| { type: 'selection'; selectedNodeId: string | null }
|
|
122
|
-
| { type: 'highlight'; highlightedNodeId: string | null }
|
|
123
|
-
| {
|
|
124
|
-
type: 'click' | 'mousemove' | 'dblclick'
|
|
125
|
-
metaKey: boolean
|
|
126
|
-
x: number
|
|
127
|
-
y: number
|
|
128
|
-
}
|
|
129
|
-
| { type: 'report_document_scroll_size' }
|
|
130
|
-
| { type: 'update_inner_text'; innerText: string }
|
|
131
|
-
| { type: 'reload' }
|
|
132
|
-
| { type: 'fetch_api'; apiKey: string }
|
|
133
|
-
| { type: 'introspect_qraphql_api'; apiKey: string }
|
|
134
|
-
| { type: 'drag-started'; x: number; y: number }
|
|
135
|
-
| { type: 'drag-ended'; canceled?: true }
|
|
136
|
-
| { type: 'keydown'; key: string; altKey: boolean; metaKey: boolean }
|
|
137
|
-
| { type: 'keyup'; key: string; altKey: boolean; metaKey: boolean }
|
|
138
|
-
| {
|
|
139
|
-
type: 'get_computed_style'
|
|
140
|
-
styles?: string[]
|
|
141
|
-
}
|
|
142
|
-
| {
|
|
143
|
-
type: 'set_timeline_keyframes'
|
|
144
|
-
keyframes: Record<string, AnimationKeyframe> | null
|
|
145
|
-
}
|
|
146
|
-
| {
|
|
147
|
-
type: 'set_timeline_time'
|
|
148
|
-
time: number | null
|
|
149
|
-
timingFunction:
|
|
150
|
-
| 'linear'
|
|
151
|
-
| 'ease'
|
|
152
|
-
| 'ease-in'
|
|
153
|
-
| 'ease-out'
|
|
154
|
-
| 'ease-in-out'
|
|
155
|
-
| 'step-start'
|
|
156
|
-
| 'step-end'
|
|
157
|
-
| string
|
|
158
|
-
| undefined
|
|
159
|
-
fillMode: 'none' | 'forwards' | 'backwards' | 'both' | undefined
|
|
160
|
-
}
|
|
161
|
-
| {
|
|
162
|
-
type: 'preview_style'
|
|
163
|
-
styles: Record<string, string> | null
|
|
164
|
-
theme?: {
|
|
165
|
-
key: string
|
|
166
|
-
value: Theme
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
| {
|
|
170
|
-
type: 'preview_theme'
|
|
171
|
-
theme: string | null
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Styles required for rendering the same exact text again somewhere else (on a overlay rect in the editor)
|
|
176
|
-
*/
|
|
177
|
-
enum TextNodeComputedStyles {
|
|
178
|
-
// Caret color is important as it is the only visible part of the text node (when text is not highlighted)
|
|
179
|
-
CARET_COLOR = 'caret-color',
|
|
180
|
-
FONT_FAMILY = 'font-family',
|
|
181
|
-
FONT_SIZE = 'font-size',
|
|
182
|
-
FONT_WEIGHT = 'font-weight',
|
|
183
|
-
FONT_STYLE = 'font-style',
|
|
184
|
-
FONT_VARIANT = 'font-variant',
|
|
185
|
-
FONT_STRETCH = 'font-stretch',
|
|
186
|
-
LINE_HEIGHT = 'line-height',
|
|
187
|
-
TEXT_ALIGN = 'text-align',
|
|
188
|
-
TEXT_TRANSFORM = 'text-transform',
|
|
189
|
-
LETTER_SPACING = 'letter-spacing',
|
|
190
|
-
WHITE_SPACE = 'white-space',
|
|
191
|
-
WORD_SPACING = 'word-spacing',
|
|
192
|
-
TEXT_INDENT = 'text-indent',
|
|
193
|
-
TEXT_OVERFLOW = 'text-overflow',
|
|
194
|
-
TEXT_RENDERING = 'text-rendering',
|
|
195
|
-
WORD_BREAK = 'word-break',
|
|
196
|
-
WORD_WRAP = 'word-wrap',
|
|
197
|
-
DIRECTION = 'direction',
|
|
198
|
-
UNICODE_BIDI = 'unicode-bidi',
|
|
199
|
-
VERTICAL_ALIGN = 'vertical-align',
|
|
200
|
-
}
|
|
201
|
-
|
|
202
87
|
let env: ToddleEnv
|
|
203
88
|
|
|
204
89
|
export const initGlobalObject = () => {
|
|
@@ -297,6 +182,18 @@ export const initGlobalObject = () => {
|
|
|
297
182
|
)
|
|
298
183
|
}
|
|
299
184
|
|
|
185
|
+
const EMPTY_COMPONENT_DATA: ComponentData = {
|
|
186
|
+
Location: {
|
|
187
|
+
query: {},
|
|
188
|
+
params: {},
|
|
189
|
+
page: '/',
|
|
190
|
+
path: '/',
|
|
191
|
+
hash: '',
|
|
192
|
+
},
|
|
193
|
+
Attributes: {},
|
|
194
|
+
Variables: {},
|
|
195
|
+
}
|
|
196
|
+
|
|
300
197
|
// imported by "/.toddle/preview" (see worker/src/preview.ts)
|
|
301
198
|
export const createRoot = (
|
|
302
199
|
domNode: HTMLElement | null = document.getElementById('App'),
|
|
@@ -304,35 +201,8 @@ export const createRoot = (
|
|
|
304
201
|
if (!domNode) {
|
|
305
202
|
throw new Error('Cant find root domNode')
|
|
306
203
|
}
|
|
307
|
-
const isInputTarget = (event: Event) => {
|
|
308
|
-
const target = event.target
|
|
309
|
-
if (target instanceof HTMLElement) {
|
|
310
|
-
if (
|
|
311
|
-
target.tagName === 'INPUT' ||
|
|
312
|
-
target.tagName === 'TEXTAREA' ||
|
|
313
|
-
target.tagName === 'SELECT' ||
|
|
314
|
-
target.tagName === 'STYLE-EDITOR'
|
|
315
|
-
) {
|
|
316
|
-
return true
|
|
317
|
-
}
|
|
318
|
-
if (target.contentEditable?.toLocaleLowerCase() === 'true') {
|
|
319
|
-
return true
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
return false
|
|
323
|
-
}
|
|
324
204
|
|
|
325
|
-
const dataSignal = signal
|
|
326
|
-
Location: {
|
|
327
|
-
query: {},
|
|
328
|
-
params: {},
|
|
329
|
-
page: '/',
|
|
330
|
-
path: '/',
|
|
331
|
-
hash: '',
|
|
332
|
-
},
|
|
333
|
-
Attributes: {},
|
|
334
|
-
Variables: {},
|
|
335
|
-
})
|
|
205
|
+
const dataSignal = signal(EMPTY_COMPONENT_DATA)
|
|
336
206
|
let ctxDataSignal: Signal<ComponentData> | undefined
|
|
337
207
|
|
|
338
208
|
let ctx: ComponentContext | null = null
|
|
@@ -372,87 +242,26 @@ export const createRoot = (
|
|
|
372
242
|
let previewStyleAnimationFrame = -1
|
|
373
243
|
let timelineTimeAnimationFrame = -1
|
|
374
244
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
return component
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
const registerActions = (
|
|
390
|
-
allActions: Record<string, PluginActionV2 | PluginAction>,
|
|
391
|
-
packageName?: string,
|
|
392
|
-
) => {
|
|
393
|
-
const actions: Record<string, PluginActionV2> = {}
|
|
394
|
-
Object.entries(allActions ?? {}).forEach(([name, action]) => {
|
|
395
|
-
if (typeof action.name === 'string' && action.version === undefined) {
|
|
396
|
-
// Legacy actions are self-registering. We need to execute them to register them
|
|
397
|
-
Function(action.handler)()
|
|
398
|
-
return
|
|
399
|
-
}
|
|
400
|
-
// We need to convert the handler string into a real function
|
|
401
|
-
actions[name] = {
|
|
402
|
-
...(action as PluginActionV2),
|
|
403
|
-
handler:
|
|
404
|
-
typeof action.handler === 'string'
|
|
405
|
-
? (new Function(
|
|
406
|
-
'args, ctx',
|
|
407
|
-
`${action.handler}
|
|
408
|
-
return ${safeFunctionName(action.name)}(args, ctx)`,
|
|
409
|
-
) as ActionHandlerV2)
|
|
410
|
-
: action.handler,
|
|
411
|
-
}
|
|
412
|
-
})
|
|
413
|
-
window.toddle.actions[packageName ?? window.__toddle.project] = actions
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
const registerFormulas = (
|
|
417
|
-
allFormulas: Record<
|
|
418
|
-
string,
|
|
419
|
-
ToddleFormula | CodeFormula<FormulaHandlerV2> | CodeFormula<string>
|
|
420
|
-
>,
|
|
421
|
-
packageName?: string,
|
|
422
|
-
) => {
|
|
423
|
-
const formulas: Record<string, PluginFormula<FormulaHandlerV2>> = {}
|
|
424
|
-
Object.entries(allFormulas ?? {}).forEach(([name, formula]) => {
|
|
425
|
-
if (
|
|
426
|
-
!isToddleFormula<FormulaHandlerV2 | string>(formula) &&
|
|
427
|
-
typeof formula.name === 'string' &&
|
|
428
|
-
formula.version === undefined
|
|
429
|
-
) {
|
|
430
|
-
// Legacy formulas are self-registering. We need to execute them to register them
|
|
431
|
-
Function(formula.handler as unknown as string)()
|
|
432
|
-
return
|
|
433
|
-
} else if (!isToddleFormula<FormulaHandlerV2 | string>(formula)) {
|
|
434
|
-
// For code formulas we need to convert the handler string into a real function
|
|
435
|
-
formulas[name] = {
|
|
436
|
-
...formula,
|
|
437
|
-
handler:
|
|
438
|
-
typeof formula.handler === 'string'
|
|
439
|
-
? (new Function(
|
|
440
|
-
'args, ctx',
|
|
441
|
-
`${formula.handler}
|
|
442
|
-
return ${safeFunctionName(formula.name)}(args, ctx)`,
|
|
443
|
-
) as FormulaHandlerV2)
|
|
444
|
-
: formula.handler,
|
|
245
|
+
const setupDataSignalSubscribers = () => {
|
|
246
|
+
dataSignal.subscribe((data) => {
|
|
247
|
+
if (component && components && packageComponents && data) {
|
|
248
|
+
try {
|
|
249
|
+
postMessageToEditor({ type: 'data', data })
|
|
250
|
+
} catch {
|
|
251
|
+
// If we're unable to send the data, let's try to JSON serialize it
|
|
252
|
+
postMessageToEditor({
|
|
253
|
+
type: 'data',
|
|
254
|
+
data: JSON.parse(JSON.stringify(data)),
|
|
255
|
+
})
|
|
445
256
|
}
|
|
446
|
-
return
|
|
447
257
|
}
|
|
448
|
-
formulas[name] = formula as PluginFormula<FormulaHandlerV2>
|
|
449
258
|
})
|
|
450
|
-
window.toddle.formulas[packageName ?? window.__toddle.project] = formulas
|
|
451
259
|
}
|
|
260
|
+
setupDataSignalSubscribers()
|
|
452
261
|
|
|
453
262
|
window.addEventListener(
|
|
454
263
|
'message',
|
|
455
|
-
async (message: MessageEvent<
|
|
264
|
+
async (message: MessageEvent<NordcraftPreviewEvent>) => {
|
|
456
265
|
if (!message.isTrusted) {
|
|
457
266
|
console.error('UNTRUSTED MESSAGE')
|
|
458
267
|
}
|
|
@@ -466,11 +275,22 @@ export const createRoot = (
|
|
|
466
275
|
| undefined
|
|
467
276
|
|
|
468
277
|
if (message.data.component.name !== component?.name) {
|
|
278
|
+
// Store scroll state for the previous component
|
|
469
279
|
storeScrollState(component?.name)
|
|
280
|
+
// Remove all subscribers from the previous showSignal
|
|
470
281
|
showSignal.cleanSubscribers()
|
|
282
|
+
// Clear any previously overridden conditional elements
|
|
283
|
+
showSignal.set({ displayedNodes: [], testMode: mode === 'test' })
|
|
284
|
+
// Restore scroll state for the new component
|
|
471
285
|
scrollStateRestorer = getScrollStateRestorer(
|
|
472
286
|
message.data.component.name,
|
|
473
287
|
)
|
|
288
|
+
// Destroy the dataSignal (including subscribers) for the previous component
|
|
289
|
+
dataSignal.destroy()
|
|
290
|
+
// Re-subscribe all dataSignal subscribers
|
|
291
|
+
setupDataSignalSubscribers()
|
|
292
|
+
// Re-initialize the data signal for the new component
|
|
293
|
+
ctxDataSignal?.destroy()
|
|
474
294
|
}
|
|
475
295
|
|
|
476
296
|
component = updateComponentLinks(message.data.component)
|
|
@@ -1249,26 +1069,31 @@ export const createRoot = (
|
|
|
1249
1069
|
] ?? ({ style: {} } as StyleVariant)
|
|
1250
1070
|
// Add a style element specific to the selected element which
|
|
1251
1071
|
// is only applied when the preview is in design mode
|
|
1252
|
-
const styleVariantCustomProperties = Object.
|
|
1253
|
-
(
|
|
1072
|
+
const styleVariantCustomProperties = Object.fromEntries(
|
|
1073
|
+
Object.entries(
|
|
1074
|
+
(selectedStyleVariant as StyleVariant).customProperties ?? {},
|
|
1075
|
+
)
|
|
1076
|
+
.map(([customPropertyName, customProperty]) => [
|
|
1077
|
+
customPropertyName,
|
|
1078
|
+
appendUnit(
|
|
1079
|
+
applyFormula(customProperty.formula, {
|
|
1080
|
+
data: {
|
|
1081
|
+
Attributes: dataSignal.get().Attributes,
|
|
1082
|
+
Variables: dataSignal.get().Variables,
|
|
1083
|
+
Contexts: ctxDataSignal?.get().Contexts ?? {},
|
|
1084
|
+
},
|
|
1085
|
+
component: getCurrentComponent(),
|
|
1086
|
+
root: ctx?.root,
|
|
1087
|
+
formulaCache: {},
|
|
1088
|
+
package: ctx?.package,
|
|
1089
|
+
toddle: window.toddle,
|
|
1090
|
+
env,
|
|
1091
|
+
} as FormulaContext),
|
|
1092
|
+
customProperty.unit,
|
|
1093
|
+
),
|
|
1094
|
+
])
|
|
1095
|
+
.filter(([, value]) => isDefined(value)),
|
|
1254
1096
|
)
|
|
1255
|
-
.map(([customPropertyName, customProperty]) => ({
|
|
1256
|
-
name: customPropertyName,
|
|
1257
|
-
value: applyFormula(customProperty.formula, {
|
|
1258
|
-
data: {
|
|
1259
|
-
Attributes: dataSignal.get().Attributes,
|
|
1260
|
-
Variables: dataSignal.get().Variables,
|
|
1261
|
-
Contexts: ctxDataSignal?.get().Contexts ?? {},
|
|
1262
|
-
},
|
|
1263
|
-
component: getCurrentComponent(),
|
|
1264
|
-
root: ctx?.root,
|
|
1265
|
-
formulaCache: {},
|
|
1266
|
-
package: ctx?.package,
|
|
1267
|
-
toddle: window.toddle,
|
|
1268
|
-
env,
|
|
1269
|
-
} as FormulaContext),
|
|
1270
|
-
}))
|
|
1271
|
-
.filter(({ value }) => value !== undefined)
|
|
1272
1097
|
|
|
1273
1098
|
const styleElem = document.createElement('style')
|
|
1274
1099
|
const pseudoElement = selectedStyleVariant.pseudoElement
|
|
@@ -1281,11 +1106,7 @@ export const createRoot = (
|
|
|
1281
1106
|
${styleToCss({
|
|
1282
1107
|
...(!pseudoElement && nodeLookup.node.style),
|
|
1283
1108
|
...selectedStyleVariant.style,
|
|
1284
|
-
...
|
|
1285
|
-
styleVariantCustomProperties.map(
|
|
1286
|
-
({ name, value }) => [name, value],
|
|
1287
|
-
),
|
|
1288
|
-
),
|
|
1109
|
+
...styleVariantCustomProperties,
|
|
1289
1110
|
})}
|
|
1290
1111
|
}
|
|
1291
1112
|
`),
|
|
@@ -1742,68 +1563,7 @@ export const createRoot = (
|
|
|
1742
1563
|
return ctx
|
|
1743
1564
|
}
|
|
1744
1565
|
|
|
1745
|
-
|
|
1746
|
-
if (isInputTarget(event)) {
|
|
1747
|
-
return
|
|
1748
|
-
}
|
|
1749
|
-
switch (event.key) {
|
|
1750
|
-
case 'k':
|
|
1751
|
-
if (event.metaKey) {
|
|
1752
|
-
event.preventDefault()
|
|
1753
|
-
}
|
|
1754
|
-
}
|
|
1755
|
-
postMessageToEditor({
|
|
1756
|
-
type: 'keydown',
|
|
1757
|
-
event: {
|
|
1758
|
-
key: event.key,
|
|
1759
|
-
metaKey: event.metaKey,
|
|
1760
|
-
shiftKey: event.shiftKey,
|
|
1761
|
-
altKey: event.altKey,
|
|
1762
|
-
},
|
|
1763
|
-
})
|
|
1764
|
-
})
|
|
1765
|
-
document.addEventListener('keyup', (event) => {
|
|
1766
|
-
if (isInputTarget(event)) {
|
|
1767
|
-
return
|
|
1768
|
-
}
|
|
1769
|
-
postMessageToEditor({
|
|
1770
|
-
type: 'keyup',
|
|
1771
|
-
event: {
|
|
1772
|
-
key: event.key,
|
|
1773
|
-
metaKey: event.metaKey,
|
|
1774
|
-
shiftKey: event.shiftKey,
|
|
1775
|
-
altKey: event.altKey,
|
|
1776
|
-
},
|
|
1777
|
-
})
|
|
1778
|
-
})
|
|
1779
|
-
document.addEventListener('keypress', (event) => {
|
|
1780
|
-
if (isInputTarget(event)) {
|
|
1781
|
-
return
|
|
1782
|
-
}
|
|
1783
|
-
postMessageToEditor({
|
|
1784
|
-
type: 'keypress',
|
|
1785
|
-
event: {
|
|
1786
|
-
key: event.key,
|
|
1787
|
-
metaKey: event.metaKey,
|
|
1788
|
-
shiftKey: event.shiftKey,
|
|
1789
|
-
altKey: event.altKey,
|
|
1790
|
-
},
|
|
1791
|
-
})
|
|
1792
|
-
})
|
|
1793
|
-
|
|
1794
|
-
dataSignal.subscribe((data) => {
|
|
1795
|
-
if (component && components && packageComponents && data) {
|
|
1796
|
-
try {
|
|
1797
|
-
postMessageToEditor({ type: 'data', data })
|
|
1798
|
-
} catch {
|
|
1799
|
-
// If we're unable to send the data, let's try to JSON serialize it
|
|
1800
|
-
postMessageToEditor({
|
|
1801
|
-
type: 'data',
|
|
1802
|
-
data: JSON.parse(JSON.stringify(data)),
|
|
1803
|
-
})
|
|
1804
|
-
}
|
|
1805
|
-
}
|
|
1806
|
-
})
|
|
1566
|
+
initKeyListeners()
|
|
1807
1567
|
|
|
1808
1568
|
const clearSelectedStyleVariant = () => {
|
|
1809
1569
|
if (styleVariantSelection) {
|
|
@@ -1864,28 +1624,6 @@ export const createRoot = (
|
|
|
1864
1624
|
})()
|
|
1865
1625
|
}
|
|
1866
1626
|
|
|
1867
|
-
function getRectData(selectedNode: Element | null | undefined) {
|
|
1868
|
-
if (!selectedNode) {
|
|
1869
|
-
return null
|
|
1870
|
-
}
|
|
1871
|
-
|
|
1872
|
-
const { borderRadius, rotate } = window.getComputedStyle(selectedNode)
|
|
1873
|
-
const rect: DOMRect = selectedNode.getBoundingClientRect()
|
|
1874
|
-
|
|
1875
|
-
return {
|
|
1876
|
-
left: rect.left,
|
|
1877
|
-
right: rect.right,
|
|
1878
|
-
top: rect.top,
|
|
1879
|
-
bottom: rect.bottom,
|
|
1880
|
-
width: rect.width,
|
|
1881
|
-
height: rect.height,
|
|
1882
|
-
x: rect.x,
|
|
1883
|
-
y: rect.y,
|
|
1884
|
-
borderRadius: borderRadius.split(' '),
|
|
1885
|
-
rotate,
|
|
1886
|
-
}
|
|
1887
|
-
}
|
|
1888
|
-
|
|
1889
1627
|
const insertOrReplaceHeadNode = (id: string, node: Node) => {
|
|
1890
1628
|
const existing = document.head.querySelector(`[data-meta-id="${id}"]`)
|
|
1891
1629
|
if (existing) {
|
|
@@ -1988,90 +1726,121 @@ const insertTheme = (
|
|
|
1988
1726
|
parent.appendChild(styleElem)
|
|
1989
1727
|
}
|
|
1990
1728
|
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
}
|
|
1996
|
-
| {
|
|
1997
|
-
type: 'selection'
|
|
1998
|
-
selectedNodeId: string | null
|
|
1999
|
-
}
|
|
2000
|
-
| {
|
|
2001
|
-
type: 'highlight'
|
|
2002
|
-
highlightedNodeId: string | null
|
|
2003
|
-
}
|
|
2004
|
-
| {
|
|
2005
|
-
type: 'navigate'
|
|
2006
|
-
name: string
|
|
2007
|
-
}
|
|
2008
|
-
| {
|
|
2009
|
-
type: 'documentScrollSize'
|
|
2010
|
-
scrollHeight: number
|
|
2011
|
-
scrollWidth: number
|
|
2012
|
-
}
|
|
2013
|
-
| {
|
|
2014
|
-
type: 'nodeMoved'
|
|
2015
|
-
copy: boolean
|
|
2016
|
-
parent?: string | null
|
|
2017
|
-
index?: number
|
|
2018
|
-
}
|
|
2019
|
-
| {
|
|
2020
|
-
type: 'computedStyle'
|
|
2021
|
-
computedStyle: Record<string, string>
|
|
2022
|
-
}
|
|
2023
|
-
| {
|
|
2024
|
-
type: 'style'
|
|
2025
|
-
time: string
|
|
1729
|
+
const initKeyListeners = () => {
|
|
1730
|
+
document.addEventListener('keydown', (event) => {
|
|
1731
|
+
if (isInputTarget(event)) {
|
|
1732
|
+
return
|
|
2026
1733
|
}
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
1734
|
+
switch (event.key) {
|
|
1735
|
+
case 'k':
|
|
1736
|
+
if (event.metaKey) {
|
|
1737
|
+
event.preventDefault()
|
|
1738
|
+
}
|
|
2032
1739
|
}
|
|
2033
|
-
|
|
2034
|
-
type: 'keydown'
|
|
1740
|
+
postMessageToEditor({
|
|
1741
|
+
type: 'keydown',
|
|
2035
1742
|
event: {
|
|
2036
|
-
key:
|
|
2037
|
-
metaKey:
|
|
2038
|
-
shiftKey:
|
|
2039
|
-
altKey:
|
|
2040
|
-
}
|
|
1743
|
+
key: event.key,
|
|
1744
|
+
metaKey: event.metaKey,
|
|
1745
|
+
shiftKey: event.shiftKey,
|
|
1746
|
+
altKey: event.altKey,
|
|
1747
|
+
},
|
|
1748
|
+
})
|
|
1749
|
+
})
|
|
1750
|
+
document.addEventListener('keyup', (event) => {
|
|
1751
|
+
if (isInputTarget(event)) {
|
|
1752
|
+
return
|
|
2041
1753
|
}
|
|
2042
|
-
|
|
2043
|
-
type: 'keyup'
|
|
1754
|
+
postMessageToEditor({
|
|
1755
|
+
type: 'keyup',
|
|
2044
1756
|
event: {
|
|
2045
|
-
key:
|
|
2046
|
-
metaKey:
|
|
2047
|
-
shiftKey:
|
|
2048
|
-
altKey:
|
|
2049
|
-
}
|
|
1757
|
+
key: event.key,
|
|
1758
|
+
metaKey: event.metaKey,
|
|
1759
|
+
shiftKey: event.shiftKey,
|
|
1760
|
+
altKey: event.altKey,
|
|
1761
|
+
},
|
|
1762
|
+
})
|
|
1763
|
+
})
|
|
1764
|
+
document.addEventListener('keypress', (event) => {
|
|
1765
|
+
if (isInputTarget(event)) {
|
|
1766
|
+
return
|
|
2050
1767
|
}
|
|
2051
|
-
|
|
2052
|
-
type: 'keypress'
|
|
1768
|
+
postMessageToEditor({
|
|
1769
|
+
type: 'keypress',
|
|
2053
1770
|
event: {
|
|
2054
|
-
key:
|
|
2055
|
-
metaKey:
|
|
2056
|
-
shiftKey:
|
|
2057
|
-
altKey:
|
|
2058
|
-
}
|
|
2059
|
-
}
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
1771
|
+
key: event.key,
|
|
1772
|
+
metaKey: event.metaKey,
|
|
1773
|
+
shiftKey: event.shiftKey,
|
|
1774
|
+
altKey: event.altKey,
|
|
1775
|
+
},
|
|
1776
|
+
})
|
|
1777
|
+
})
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
const registerActions = (
|
|
1781
|
+
allActions: Record<string, PluginAction>,
|
|
1782
|
+
packageName?: string,
|
|
1783
|
+
) => {
|
|
1784
|
+
const actions: Record<string, PluginActionV2> = {}
|
|
1785
|
+
Object.entries(allActions ?? {}).forEach(([name, action]) => {
|
|
1786
|
+
if (isLegacyPluginAction(action)) {
|
|
1787
|
+
// Legacy actions are self-registering. We need to execute them to register them
|
|
1788
|
+
Function(action.handler)()
|
|
1789
|
+
return
|
|
2064
1790
|
}
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
1791
|
+
// We need to convert the handler string into a real function
|
|
1792
|
+
actions[name] = {
|
|
1793
|
+
...(action as PluginActionV2),
|
|
1794
|
+
handler:
|
|
1795
|
+
typeof action.handler === 'string'
|
|
1796
|
+
? (new Function(
|
|
1797
|
+
'args, ctx',
|
|
1798
|
+
`${action.handler}
|
|
1799
|
+
return ${safeFunctionName(action.name)}(args, ctx)`,
|
|
1800
|
+
) as ActionHandlerV2)
|
|
1801
|
+
: action.handler,
|
|
2068
1802
|
}
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
1803
|
+
})
|
|
1804
|
+
window.toddle.actions[packageName ?? window.__toddle.project] = actions
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
const registerFormulas = (
|
|
1808
|
+
allFormulas: Record<
|
|
1809
|
+
string,
|
|
1810
|
+
ToddleFormula | CodeFormula<FormulaHandlerV2> | CodeFormula<string>
|
|
1811
|
+
>,
|
|
1812
|
+
packageName?: string,
|
|
1813
|
+
) => {
|
|
1814
|
+
const formulas: Record<string, PluginFormula<FormulaHandlerV2>> = {}
|
|
1815
|
+
Object.entries(allFormulas ?? {}).forEach(([name, formula]) => {
|
|
1816
|
+
if (
|
|
1817
|
+
!isToddleFormula<FormulaHandlerV2 | string>(formula) &&
|
|
1818
|
+
typeof formula.name === 'string' &&
|
|
1819
|
+
formula.version === undefined
|
|
1820
|
+
) {
|
|
1821
|
+
// Legacy formulas are self-registering. We need to execute them to register them
|
|
1822
|
+
Function(formula.handler as unknown as string)()
|
|
1823
|
+
return
|
|
1824
|
+
} else if (!isToddleFormula<FormulaHandlerV2 | string>(formula)) {
|
|
1825
|
+
// For code formulas we need to convert the handler string into a real function
|
|
1826
|
+
formulas[name] = {
|
|
1827
|
+
...formula,
|
|
1828
|
+
handler:
|
|
1829
|
+
typeof formula.handler === 'string'
|
|
1830
|
+
? (new Function(
|
|
1831
|
+
'args, ctx',
|
|
1832
|
+
`${formula.handler}
|
|
1833
|
+
return ${safeFunctionName(formula.name)}(args, ctx)`,
|
|
1834
|
+
) as FormulaHandlerV2)
|
|
1835
|
+
: formula.handler,
|
|
1836
|
+
}
|
|
1837
|
+
return
|
|
2073
1838
|
}
|
|
1839
|
+
formulas[name] = formula as PluginFormula<FormulaHandlerV2>
|
|
1840
|
+
})
|
|
1841
|
+
window.toddle.formulas[packageName ?? window.__toddle.project] = formulas
|
|
1842
|
+
}
|
|
2074
1843
|
|
|
2075
|
-
const postMessageToEditor = (message:
|
|
1844
|
+
const postMessageToEditor = (message: EditorPostMessageType) => {
|
|
2076
1845
|
window.parent?.postMessage(message, '*')
|
|
2077
1846
|
}
|