@nordcraft/runtime 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/custom-element.main.esm.js +27 -27
- package/dist/custom-element.main.esm.js.map +3 -3
- package/dist/editor/drag-drop/dragEnded.js +0 -5
- package/dist/editor/drag-drop/dragEnded.js.map +1 -1
- package/dist/editor/drag-drop/dragStarted.js +2 -2
- package/dist/editor/drag-drop/dragStarted.js.map +1 -1
- package/dist/editor-preview.main.d.ts +0 -11
- package/dist/editor-preview.main.js +80 -115
- package/dist/editor-preview.main.js.map +1 -1
- package/dist/page.main.esm.js +3 -3
- package/dist/page.main.esm.js.map +3 -3
- package/package.json +3 -3
- package/src/editor/drag-drop/dragEnded.ts +0 -8
- package/src/editor/drag-drop/dragStarted.ts +2 -2
- package/src/editor-preview.main.ts +101 -166
package/package.json
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
"type": "module",
|
|
5
5
|
"homepage": "https://github.com/nordcraftengine/nordcraft",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@nordcraft/core": "1.0.
|
|
8
|
-
"@nordcraft/std-lib": "1.0.
|
|
7
|
+
"@nordcraft/core": "1.0.2",
|
|
8
|
+
"@nordcraft/std-lib": "1.0.2",
|
|
9
9
|
"fast-deep-equal": "3.1.3",
|
|
10
10
|
"path-to-regexp": "6.3.0"
|
|
11
11
|
},
|
|
@@ -21,5 +21,5 @@
|
|
|
21
21
|
"files": ["dist", "src"],
|
|
22
22
|
"main": "dist/page.main.js",
|
|
23
23
|
"types": "dist/page.main.d.ts",
|
|
24
|
-
"version": "1.0.
|
|
24
|
+
"version": "1.0.2"
|
|
25
25
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { getRectData } from '../../editor-preview.main'
|
|
2
1
|
import { tryStartViewTransition } from '../../utils/tryStartViewTransition'
|
|
3
2
|
import type { DragState } from '../types'
|
|
4
3
|
import { DRAG_MOVE_CLASSNAME } from './dragMove'
|
|
@@ -57,13 +56,6 @@ export async function dragEnded(dragState: DragState, canceled: boolean) {
|
|
|
57
56
|
node.style.removeProperty('--drag-repeat-node-opacity')
|
|
58
57
|
})
|
|
59
58
|
removeDropHighlight()
|
|
60
|
-
window.parent.postMessage(
|
|
61
|
-
{
|
|
62
|
-
type: 'selectionRect',
|
|
63
|
-
rect: getRectData(dragState.element),
|
|
64
|
-
},
|
|
65
|
-
'*',
|
|
66
|
-
)
|
|
67
59
|
}).finished.then(() => {
|
|
68
60
|
dragState.element.style.removeProperty('view-transition-name')
|
|
69
61
|
siblings.forEach((node) => {
|
|
@@ -99,14 +99,14 @@ export function dragStarted({
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
const followRect = dragState.element.getBoundingClientRect()
|
|
102
|
-
dragState.repeatedNodes.forEach((node
|
|
102
|
+
dragState.repeatedNodes.forEach((node) => {
|
|
103
103
|
// Calculate rect without rotation as it expands the rect and makes it difficult to calculate the correct position
|
|
104
104
|
node.style.setProperty('rotate', '0deg')
|
|
105
105
|
const fromRect = node.getBoundingClientRect()
|
|
106
106
|
node.style.removeProperty('rotate')
|
|
107
107
|
const toX = followRect.left + followRect.width / 2 - fromRect.width / 2
|
|
108
108
|
const toY = followRect.top + followRect.height / 2 - fromRect.height / 2
|
|
109
|
-
const interpolation = 0.4
|
|
109
|
+
const interpolation = 0.4
|
|
110
110
|
const x = fromRect.left + (toX - fromRect.left) * interpolation
|
|
111
111
|
const y = fromRect.top + (toY - fromRect.top) * interpolation
|
|
112
112
|
node.style.setProperty('--drag-repeat-node-translate', `${x}px ${y}px`)
|
|
@@ -61,9 +61,6 @@ type ToddlePreviewEvent =
|
|
|
61
61
|
type: 'style_variant_changed'
|
|
62
62
|
variantIndex: number | null
|
|
63
63
|
}
|
|
64
|
-
| {
|
|
65
|
-
type: 'update'
|
|
66
|
-
}
|
|
67
64
|
| {
|
|
68
65
|
type: 'component'
|
|
69
66
|
component: Component
|
|
@@ -319,6 +316,7 @@ export const createRoot = (
|
|
|
319
316
|
let altKey = false
|
|
320
317
|
let metaKey = false
|
|
321
318
|
let previewStyleAnimationFrame = -1
|
|
319
|
+
let timelineTimeAnimationFrame = -1
|
|
322
320
|
|
|
323
321
|
/**
|
|
324
322
|
* Modifies all link nodes on a component
|
|
@@ -341,34 +339,6 @@ export const createRoot = (
|
|
|
341
339
|
console.error('UNTRUSTED MESSAGE')
|
|
342
340
|
}
|
|
343
341
|
switch (message.data?.type) {
|
|
344
|
-
case 'update':
|
|
345
|
-
{
|
|
346
|
-
if (highlightedNodeId) {
|
|
347
|
-
const highlightedNode = getDOMNodeFromNodeId(highlightedNodeId)
|
|
348
|
-
if (highlightedNode) {
|
|
349
|
-
window.parent?.postMessage(
|
|
350
|
-
{
|
|
351
|
-
type: 'highlightRect',
|
|
352
|
-
rect: getRectData(highlightedNode),
|
|
353
|
-
},
|
|
354
|
-
'*',
|
|
355
|
-
)
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
if (selectedNodeId) {
|
|
359
|
-
const selectedNode = getDOMNodeFromNodeId(selectedNodeId)
|
|
360
|
-
if (selectedNode) {
|
|
361
|
-
window.parent?.postMessage(
|
|
362
|
-
{
|
|
363
|
-
type: 'selectionRect',
|
|
364
|
-
rect: getRectData(selectedNode),
|
|
365
|
-
},
|
|
366
|
-
'*',
|
|
367
|
-
)
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
break
|
|
372
342
|
case 'component': {
|
|
373
343
|
if (!message.data.component) {
|
|
374
344
|
return
|
|
@@ -413,34 +383,12 @@ export const createRoot = (
|
|
|
413
383
|
|
|
414
384
|
update()
|
|
415
385
|
|
|
416
|
-
if (highlightedNodeId) {
|
|
417
|
-
const highlightedNode = getDOMNodeFromNodeId(highlightedNodeId)
|
|
418
|
-
if (highlightedNode) {
|
|
419
|
-
window.parent?.postMessage(
|
|
420
|
-
{
|
|
421
|
-
type: 'highlightRect',
|
|
422
|
-
rect: getRectData(highlightedNode),
|
|
423
|
-
},
|
|
424
|
-
'*',
|
|
425
|
-
)
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
386
|
if (selectedNodeId) {
|
|
429
387
|
if (styleVariantSelection) {
|
|
430
388
|
updateSelectedStyleVariant(
|
|
431
389
|
styleVariantSelection.styleVariantIndex,
|
|
432
390
|
)
|
|
433
391
|
}
|
|
434
|
-
const selectedNode = getDOMNodeFromNodeId(selectedNodeId)
|
|
435
|
-
if (selectedNode) {
|
|
436
|
-
window.parent?.postMessage(
|
|
437
|
-
{
|
|
438
|
-
type: 'selectionRect',
|
|
439
|
-
rect: getRectData(selectedNode),
|
|
440
|
-
},
|
|
441
|
-
'*',
|
|
442
|
-
)
|
|
443
|
-
}
|
|
444
392
|
}
|
|
445
393
|
|
|
446
394
|
break
|
|
@@ -527,15 +475,6 @@ export const createRoot = (
|
|
|
527
475
|
|
|
528
476
|
updateConditionalElements()
|
|
529
477
|
|
|
530
|
-
const selectedNode = getDOMNodeFromNodeId(selectedNodeId)
|
|
531
|
-
window.parent?.postMessage(
|
|
532
|
-
{
|
|
533
|
-
type: 'selectionRect',
|
|
534
|
-
rect: getRectData(selectedNode),
|
|
535
|
-
},
|
|
536
|
-
'*',
|
|
537
|
-
)
|
|
538
|
-
|
|
539
478
|
const node = getDOMNodeFromNodeId(selectedNodeId)
|
|
540
479
|
const element =
|
|
541
480
|
component?.nodes[node?.getAttribute('data-node-id') ?? '']
|
|
@@ -579,28 +518,11 @@ export const createRoot = (
|
|
|
579
518
|
selectedNode.getAttribute('data-node-type') === 'text'
|
|
580
519
|
) {
|
|
581
520
|
;(selectedNode as HTMLElement).innerText = innerText
|
|
582
|
-
window.parent?.postMessage(
|
|
583
|
-
{
|
|
584
|
-
type: 'selectionRect',
|
|
585
|
-
rect: getRectData(selectedNode),
|
|
586
|
-
},
|
|
587
|
-
'*',
|
|
588
|
-
)
|
|
589
521
|
}
|
|
590
522
|
return
|
|
591
523
|
}
|
|
592
524
|
case 'highlight': {
|
|
593
|
-
|
|
594
|
-
highlightedNodeId = message.data.highlightedNodeId ?? null
|
|
595
|
-
const highlightedNode = getDOMNodeFromNodeId(highlightedNodeId)
|
|
596
|
-
window.parent?.postMessage(
|
|
597
|
-
{
|
|
598
|
-
type: 'highlightRect',
|
|
599
|
-
rect: getRectData(highlightedNode),
|
|
600
|
-
},
|
|
601
|
-
'*',
|
|
602
|
-
)
|
|
603
|
-
}
|
|
525
|
+
highlightedNodeId = message.data.highlightedNodeId ?? null
|
|
604
526
|
return
|
|
605
527
|
}
|
|
606
528
|
case 'mousemove':
|
|
@@ -967,41 +889,35 @@ export const createRoot = (
|
|
|
967
889
|
)
|
|
968
890
|
styleElem.setAttribute('data-timeline-keyframes', '')
|
|
969
891
|
document.head.appendChild(styleElem)
|
|
970
|
-
window.parent?.postMessage(
|
|
971
|
-
{
|
|
972
|
-
type: 'selectionRect',
|
|
973
|
-
rect: getRectData(
|
|
974
|
-
getDOMNodeFromNodeId(selectedNodeId) ?? document.body,
|
|
975
|
-
),
|
|
976
|
-
},
|
|
977
|
-
'*',
|
|
978
|
-
)
|
|
979
892
|
break
|
|
980
893
|
|
|
981
894
|
case 'set_timeline_time':
|
|
982
895
|
const { time, timingFunction, fillMode } = message.data
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
896
|
+
cancelAnimationFrame(timelineTimeAnimationFrame)
|
|
897
|
+
timelineTimeAnimationFrame = requestAnimationFrame(() => {
|
|
898
|
+
const animatedElementChanged =
|
|
899
|
+
animationState?.animatedElementId !== selectedNodeId
|
|
900
|
+
animationState = {
|
|
901
|
+
animatedElementId: time !== null ? selectedNodeId : null,
|
|
902
|
+
time,
|
|
903
|
+
timingFunction,
|
|
904
|
+
fillMode,
|
|
905
|
+
}
|
|
992
906
|
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
907
|
+
// Cleanup on null
|
|
908
|
+
if (time === null) {
|
|
909
|
+
document.head
|
|
910
|
+
.querySelector('[data-id="preview-animation-styles"]')
|
|
911
|
+
?.remove()
|
|
912
|
+
document.body.style.removeProperty('--editor-timeline-position')
|
|
913
|
+
document.body.style.removeProperty(
|
|
914
|
+
'--editor-timeline-timing-function',
|
|
915
|
+
)
|
|
916
|
+
document.body.style.removeProperty('--editor-timeline-fill-mode')
|
|
917
|
+
update()
|
|
918
|
+
return
|
|
919
|
+
}
|
|
1002
920
|
|
|
1003
|
-
if (animatedElement && time !== null) {
|
|
1004
|
-
animatedElement.classList.add('editor-preview-timeline')
|
|
1005
921
|
document.body.style.setProperty(
|
|
1006
922
|
'--editor-timeline-position',
|
|
1007
923
|
`${time}s`,
|
|
@@ -1014,22 +930,31 @@ export const createRoot = (
|
|
|
1014
930
|
'--editor-timeline-fill-mode',
|
|
1015
931
|
fillMode ?? 'none',
|
|
1016
932
|
)
|
|
1017
|
-
} else {
|
|
1018
|
-
document.body.style.removeProperty('--editor-timeline-position')
|
|
1019
|
-
document.body.style.removeProperty(
|
|
1020
|
-
'--editor-timeline-timing-function',
|
|
1021
|
-
)
|
|
1022
|
-
document.body.style.removeProperty('--editor-timeline-fill-mode')
|
|
1023
|
-
update()
|
|
1024
|
-
}
|
|
1025
933
|
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
934
|
+
if (animatedElementChanged) {
|
|
935
|
+
let styleTag = document.head.querySelector(
|
|
936
|
+
'[data-id="preview-animation-styles"]',
|
|
937
|
+
)
|
|
938
|
+
if (!styleTag) {
|
|
939
|
+
styleTag = document.createElement('style')
|
|
940
|
+
styleTag.setAttribute('data-id', 'preview-animation-styles')
|
|
941
|
+
document.head.appendChild(styleTag)
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
// Set the animation styles for self and repeated nodes, but pause for all others
|
|
945
|
+
// TODO: Consider if we should set all other animations to follow the current timeline time, by setting animation-delay with paused
|
|
946
|
+
styleTag.innerHTML = `
|
|
947
|
+
[data-id] {
|
|
948
|
+
animation-play-state: paused !important;
|
|
949
|
+
}
|
|
950
|
+
[data-id="${animationState.animatedElementId}"], [data-id="${animationState.animatedElementId}"] ~ [data-id^="${animationState.animatedElementId}("] {
|
|
951
|
+
animation: preview_timeline 1s paused normal !important;
|
|
952
|
+
animation-fill-mode: var(--editor-timeline-fill-mode) !important;
|
|
953
|
+
animation-timing-function: var(--editor-timeline-timing-function) !important;
|
|
954
|
+
animation-delay: calc(0s - var(--editor-timeline-position)) !important;
|
|
955
|
+
}`
|
|
956
|
+
}
|
|
957
|
+
})
|
|
1033
958
|
break
|
|
1034
959
|
case 'preview_style':
|
|
1035
960
|
const { styles: previewStyleStyles } = message.data
|
|
@@ -1059,14 +984,6 @@ export const createRoot = (
|
|
|
1059
984
|
${previewStyles}
|
|
1060
985
|
transition: none !important;
|
|
1061
986
|
}`
|
|
1062
|
-
|
|
1063
|
-
window.parent?.postMessage(
|
|
1064
|
-
{
|
|
1065
|
-
type: 'selectionRect',
|
|
1066
|
-
rect: getRectData(getDOMNodeFromNodeId(selectedNodeId)),
|
|
1067
|
-
},
|
|
1068
|
-
'*',
|
|
1069
|
-
)
|
|
1070
987
|
})
|
|
1071
988
|
break
|
|
1072
989
|
}
|
|
@@ -1156,14 +1073,6 @@ export const createRoot = (
|
|
|
1156
1073
|
}
|
|
1157
1074
|
}
|
|
1158
1075
|
}
|
|
1159
|
-
const selectedNode = getDOMNodeFromNodeId(selectedNodeId)
|
|
1160
|
-
window.parent?.postMessage(
|
|
1161
|
-
{
|
|
1162
|
-
type: 'selectionRect',
|
|
1163
|
-
rect: getRectData(selectedNode),
|
|
1164
|
-
},
|
|
1165
|
-
'*',
|
|
1166
|
-
)
|
|
1167
1076
|
}
|
|
1168
1077
|
|
|
1169
1078
|
const update = () => {
|
|
@@ -1481,10 +1390,6 @@ export const createRoot = (
|
|
|
1481
1390
|
)
|
|
1482
1391
|
}
|
|
1483
1392
|
}
|
|
1484
|
-
// Rerendering may clear editor-preview-only styles, so we need to reapply them
|
|
1485
|
-
getDOMNodeFromNodeId(animationState?.animatedElementId)?.classList.add(
|
|
1486
|
-
'editor-preview-timeline',
|
|
1487
|
-
)
|
|
1488
1393
|
|
|
1489
1394
|
ctx = newCtx
|
|
1490
1395
|
}
|
|
@@ -1661,6 +1566,58 @@ export const createRoot = (
|
|
|
1661
1566
|
testMode: mode === 'test',
|
|
1662
1567
|
})
|
|
1663
1568
|
}
|
|
1569
|
+
|
|
1570
|
+
// Animations are first class citizens in Nordcraft, so we sync their overlay positions on each frame
|
|
1571
|
+
;(function syncOverlayRects(
|
|
1572
|
+
prevSelectionRect?: ReturnType<typeof getRectData>,
|
|
1573
|
+
prevHighlightedRect?: ReturnType<typeof getRectData>,
|
|
1574
|
+
) {
|
|
1575
|
+
const selectionRect = getRectData(getDOMNodeFromNodeId(selectedNodeId))
|
|
1576
|
+
if (!fastDeepEqual(prevSelectionRect, selectionRect)) {
|
|
1577
|
+
window.parent?.postMessage(
|
|
1578
|
+
{
|
|
1579
|
+
type: 'selectionRect',
|
|
1580
|
+
rect: selectionRect,
|
|
1581
|
+
},
|
|
1582
|
+
'*',
|
|
1583
|
+
)
|
|
1584
|
+
}
|
|
1585
|
+
|
|
1586
|
+
const highlightRect = getRectData(getDOMNodeFromNodeId(highlightedNodeId))
|
|
1587
|
+
if (!fastDeepEqual(prevHighlightedRect, highlightRect)) {
|
|
1588
|
+
window.parent?.postMessage(
|
|
1589
|
+
{
|
|
1590
|
+
type: 'highlightRect',
|
|
1591
|
+
rect: highlightRect,
|
|
1592
|
+
},
|
|
1593
|
+
'*',
|
|
1594
|
+
)
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
requestAnimationFrame(() => syncOverlayRects(selectionRect, highlightRect))
|
|
1598
|
+
})()
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
function getRectData(selectedNode: Element | null | undefined) {
|
|
1602
|
+
if (!selectedNode) {
|
|
1603
|
+
return null
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
const rect = selectedNode.getBoundingClientRect()
|
|
1607
|
+
return {
|
|
1608
|
+
left: rect.left,
|
|
1609
|
+
right: rect.right,
|
|
1610
|
+
top: rect.top,
|
|
1611
|
+
bottom: rect.bottom,
|
|
1612
|
+
width: rect.width,
|
|
1613
|
+
height: rect.height,
|
|
1614
|
+
x: rect.x,
|
|
1615
|
+
y: rect.y,
|
|
1616
|
+
borderRadius: window
|
|
1617
|
+
.getComputedStyle(selectedNode)
|
|
1618
|
+
.borderRadius.split(' ')
|
|
1619
|
+
.map(parseFloat),
|
|
1620
|
+
}
|
|
1664
1621
|
}
|
|
1665
1622
|
|
|
1666
1623
|
const insertOrReplaceHeadNode = (id: string, node: Node) => {
|
|
@@ -1724,28 +1681,6 @@ export function getDOMNodeFromNodeId(
|
|
|
1724
1681
|
)
|
|
1725
1682
|
}
|
|
1726
1683
|
|
|
1727
|
-
export function getRectData(selectedNode: Element | null | undefined) {
|
|
1728
|
-
if (!selectedNode) {
|
|
1729
|
-
return null
|
|
1730
|
-
}
|
|
1731
|
-
|
|
1732
|
-
const rect = selectedNode.getBoundingClientRect()
|
|
1733
|
-
return {
|
|
1734
|
-
left: rect.left,
|
|
1735
|
-
right: rect.right,
|
|
1736
|
-
top: rect.top,
|
|
1737
|
-
bottom: rect.bottom,
|
|
1738
|
-
width: rect.width,
|
|
1739
|
-
height: rect.height,
|
|
1740
|
-
x: rect.x,
|
|
1741
|
-
y: rect.y,
|
|
1742
|
-
borderRadius: window
|
|
1743
|
-
.getComputedStyle(selectedNode)
|
|
1744
|
-
.borderRadius.split(' ')
|
|
1745
|
-
.map(parseFloat),
|
|
1746
|
-
}
|
|
1747
|
-
}
|
|
1748
|
-
|
|
1749
1684
|
function getNodeId(component: Component, path: string[]) {
|
|
1750
1685
|
function getId(
|
|
1751
1686
|
[nextChild, ...path]: string[],
|