@einblick/sdk 0.4.1 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/dist/next/edit-boot.d.ts +5 -1
- package/dist/next/edit-boot.d.ts.map +1 -1
- package/dist/next/edit-boot.js +2 -2
- package/dist/next/edit-boot.js.map +1 -1
- package/dist/react/i18n.d.ts +3 -0
- package/dist/react/i18n.d.ts.map +1 -1
- package/dist/react/i18n.js +6 -0
- package/dist/react/i18n.js.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/provider.d.ts +1 -1
- package/dist/react/provider.d.ts.map +1 -1
- package/dist/react/provider.js +11 -2
- package/dist/react/provider.js.map +1 -1
- package/dist/react/runtime.d.ts +3 -1
- package/dist/react/runtime.d.ts.map +1 -1
- package/dist/react/runtime.js +574 -8
- package/dist/react/runtime.js.map +1 -1
- package/dist/react/types.d.ts +3 -0
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react/types.js.map +1 -1
- package/package.json +1 -1
package/dist/react/runtime.js
CHANGED
|
@@ -5,6 +5,7 @@ const RELATIVE_POSITION_SENTINEL = '__einblick_runtime_original_static__';
|
|
|
5
5
|
const EINBLICK_ACCENT_RGB = '250, 105, 62';
|
|
6
6
|
const EINBLICK_ACCENT_COLOR = `rgb(${EINBLICK_ACCENT_RGB})`;
|
|
7
7
|
const EINBLICK_ACCENT_BORDER = `rgba(${EINBLICK_ACCENT_RGB}, 0.92)`;
|
|
8
|
+
const CONTROL_BAR_HEIGHT = 44;
|
|
8
9
|
const INLINE_EDITOR_SHADOW_STYLES = `
|
|
9
10
|
:host {
|
|
10
11
|
display: block;
|
|
@@ -105,6 +106,28 @@ function getBrandBadgeSvg(size) {
|
|
|
105
106
|
</svg>
|
|
106
107
|
`;
|
|
107
108
|
}
|
|
109
|
+
function getBrandMarkSvg(size) {
|
|
110
|
+
return `
|
|
111
|
+
<svg viewBox="0 0 22.11 22.11" width="${size}" height="${size}" aria-hidden="true" focusable="false">
|
|
112
|
+
<path
|
|
113
|
+
d="M22.11 9.96h-8.35l5.84-5.84.07-.07-1.49-1.48-.07-.07-5.97 5.97V0h-2.2v8.4L4.11 2.56l-.07-.07-1.48 1.49-.07.07 5.92 5.92H0v2.2h8.45l-5.9 5.9-.07.07 1.49 1.48.07.07 5.92-5.92v8.35h2.2v-8.79c0-.65.53-1.17 1.17-1.17h8.79v-2.2Z"
|
|
114
|
+
fill="currentColor"
|
|
115
|
+
/>
|
|
116
|
+
</svg>
|
|
117
|
+
`;
|
|
118
|
+
}
|
|
119
|
+
function getMoreActionsSvg(size) {
|
|
120
|
+
const dotRadius = size * 0.08;
|
|
121
|
+
const centerY = size / 2;
|
|
122
|
+
const centers = [size * 0.26, size * 0.5, size * 0.74];
|
|
123
|
+
return `
|
|
124
|
+
<svg viewBox="0 0 ${size} ${size}" width="${size}" height="${size}" aria-hidden="true" focusable="false">
|
|
125
|
+
${centers
|
|
126
|
+
.map((centerX) => `<circle cx="${centerX}" cy="${centerY}" r="${dotRadius}" fill="currentColor" />`)
|
|
127
|
+
.join('')}
|
|
128
|
+
</svg>
|
|
129
|
+
`;
|
|
130
|
+
}
|
|
108
131
|
function createRandomId() {
|
|
109
132
|
if (typeof crypto !== 'undefined' &&
|
|
110
133
|
typeof crypto.randomUUID === 'function') {
|
|
@@ -419,6 +442,8 @@ class EinblickEditRuntime {
|
|
|
419
442
|
siteKey;
|
|
420
443
|
appOrigin;
|
|
421
444
|
callbacks;
|
|
445
|
+
chrome;
|
|
446
|
+
reserveBottomSpace;
|
|
422
447
|
locale;
|
|
423
448
|
messages;
|
|
424
449
|
bridgeNonce = createRandomId();
|
|
@@ -442,6 +467,15 @@ class EinblickEditRuntime {
|
|
|
442
467
|
brandPopoverHint = null;
|
|
443
468
|
brandPopoverOpenAppButton = null;
|
|
444
469
|
brandPopoverLogoutButton = null;
|
|
470
|
+
bottomBarHost = null;
|
|
471
|
+
bottomBarSiteName = null;
|
|
472
|
+
bottomBarCmsButton = null;
|
|
473
|
+
bottomBarMoreButton = null;
|
|
474
|
+
bottomBarMoreMenu = null;
|
|
475
|
+
bottomBarOpenAppButton = null;
|
|
476
|
+
bottomBarLogoutButton = null;
|
|
477
|
+
originalBodyPaddingBottom = null;
|
|
478
|
+
hasReservedBodyPadding = false;
|
|
445
479
|
mutationObserver = null;
|
|
446
480
|
destroyed = false;
|
|
447
481
|
started = false;
|
|
@@ -452,11 +486,16 @@ class EinblickEditRuntime {
|
|
|
452
486
|
editorNonce = null;
|
|
453
487
|
editorTarget = null;
|
|
454
488
|
editorBinding = null;
|
|
489
|
+
navigatorPanel = null;
|
|
490
|
+
navigatorNonce = null;
|
|
455
491
|
pendingInlineSaves = new Map();
|
|
456
492
|
pendingLogin = null;
|
|
457
493
|
constructor(options) {
|
|
458
494
|
this.siteKey = options.siteKey;
|
|
459
495
|
this.appOrigin = resolveAppOrigin(options.appOrigin, options.appUrl);
|
|
496
|
+
this.chrome = options.chrome ?? 'bar';
|
|
497
|
+
this.reserveBottomSpace =
|
|
498
|
+
options.reserveBottomSpace ?? this.chrome === 'bar';
|
|
460
499
|
this.locale = resolveEinblickSdkLocale(options.locale);
|
|
461
500
|
this.messages = getEinblickSdkMessages(this.locale);
|
|
462
501
|
this.session =
|
|
@@ -488,7 +527,12 @@ class EinblickEditRuntime {
|
|
|
488
527
|
this.started = true;
|
|
489
528
|
injectRuntimeStyles();
|
|
490
529
|
this.ensureHoverButton();
|
|
491
|
-
this.
|
|
530
|
+
if (this.chrome === 'badge') {
|
|
531
|
+
this.ensureBrandBadge();
|
|
532
|
+
}
|
|
533
|
+
else if (this.chrome === 'bar') {
|
|
534
|
+
this.ensureBottomBar();
|
|
535
|
+
}
|
|
492
536
|
window.addEventListener('message', this.handleMessage);
|
|
493
537
|
window.addEventListener('pointerdown', this.handleGlobalPointerDown, true);
|
|
494
538
|
window.addEventListener('pointermove', this.handlePointerMove, true);
|
|
@@ -547,7 +591,17 @@ class EinblickEditRuntime {
|
|
|
547
591
|
this.brandPopoverHint = null;
|
|
548
592
|
this.brandPopoverOpenAppButton = null;
|
|
549
593
|
this.brandPopoverLogoutButton = null;
|
|
594
|
+
this.bottomBarHost?.remove();
|
|
595
|
+
this.bottomBarHost = null;
|
|
596
|
+
this.bottomBarSiteName = null;
|
|
597
|
+
this.bottomBarCmsButton = null;
|
|
598
|
+
this.bottomBarMoreButton = null;
|
|
599
|
+
this.bottomBarMoreMenu = null;
|
|
600
|
+
this.bottomBarOpenAppButton = null;
|
|
601
|
+
this.bottomBarLogoutButton = null;
|
|
602
|
+
this.applyBottomLayout(false);
|
|
550
603
|
this.closeInlineEditor();
|
|
604
|
+
this.closeNavigator();
|
|
551
605
|
this.closeDrawer();
|
|
552
606
|
if (this.pendingLogin) {
|
|
553
607
|
if (this.pendingLogin.closePollId !== null) {
|
|
@@ -593,6 +647,7 @@ class EinblickEditRuntime {
|
|
|
593
647
|
this.messages.actions.logout;
|
|
594
648
|
}
|
|
595
649
|
this.updateBrandPopover();
|
|
650
|
+
this.updateBottomBar();
|
|
596
651
|
}
|
|
597
652
|
async login(options) {
|
|
598
653
|
if (typeof window === 'undefined') {
|
|
@@ -641,6 +696,8 @@ class EinblickEditRuntime {
|
|
|
641
696
|
}
|
|
642
697
|
openEditor(binding, element) {
|
|
643
698
|
this.setBrandPopoverOpen(false);
|
|
699
|
+
this.setBottomBarMenuOpen(false);
|
|
700
|
+
this.closeNavigator();
|
|
644
701
|
const target = element ?? this.findElementForBinding(binding);
|
|
645
702
|
if (shouldUseInlineEditor(binding)) {
|
|
646
703
|
this.openInlineEditor(target, binding);
|
|
@@ -651,7 +708,9 @@ class EinblickEditRuntime {
|
|
|
651
708
|
handlePointerMove = (event) => {
|
|
652
709
|
if (!this.state.isAuthenticated ||
|
|
653
710
|
this.currentInlineTarget ||
|
|
654
|
-
this.editorBackdrop
|
|
711
|
+
this.editorBackdrop ||
|
|
712
|
+
this.navigatorPanel ||
|
|
713
|
+
this.isBottomBarMenuOpen()) {
|
|
655
714
|
this.setActiveElement(null);
|
|
656
715
|
return;
|
|
657
716
|
}
|
|
@@ -665,6 +724,7 @@ class EinblickEditRuntime {
|
|
|
665
724
|
};
|
|
666
725
|
handleWindowBlur = () => {
|
|
667
726
|
this.setBrandPopoverOpen(false);
|
|
727
|
+
this.setBottomBarMenuOpen(false);
|
|
668
728
|
if (!this.currentInlineTarget && !this.editorBackdrop) {
|
|
669
729
|
this.setActiveElement(null);
|
|
670
730
|
}
|
|
@@ -678,6 +738,16 @@ class EinblickEditRuntime {
|
|
|
678
738
|
this.setBrandPopoverOpen(false);
|
|
679
739
|
return;
|
|
680
740
|
}
|
|
741
|
+
if (this.isBottomBarMenuOpen()) {
|
|
742
|
+
event.preventDefault();
|
|
743
|
+
this.setBottomBarMenuOpen(false);
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
if (this.navigatorPanel) {
|
|
747
|
+
event.preventDefault();
|
|
748
|
+
this.closeNavigator();
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
681
751
|
if (this.currentInlineTarget) {
|
|
682
752
|
event.preventDefault();
|
|
683
753
|
this.closeInlineEditor();
|
|
@@ -715,15 +785,22 @@ class EinblickEditRuntime {
|
|
|
715
785
|
this.openDrawer(this.activeElement, binding, 'create');
|
|
716
786
|
};
|
|
717
787
|
handleGlobalPointerDown = (event) => {
|
|
718
|
-
if (!this.isBrandPopoverOpen()) {
|
|
719
|
-
return;
|
|
720
|
-
}
|
|
721
788
|
const target = event.target;
|
|
722
|
-
if (target instanceof Node
|
|
723
|
-
|
|
789
|
+
if (!(target instanceof Node)) {
|
|
790
|
+
this.setBrandPopoverOpen(false);
|
|
791
|
+
this.setBottomBarMenuOpen(false);
|
|
724
792
|
return;
|
|
725
793
|
}
|
|
726
|
-
this.
|
|
794
|
+
if (this.isBrandPopoverOpen() &&
|
|
795
|
+
!this.brandBadge?.contains(target) &&
|
|
796
|
+
!this.brandPopover?.contains(target)) {
|
|
797
|
+
this.setBrandPopoverOpen(false);
|
|
798
|
+
}
|
|
799
|
+
if (this.isBottomBarMenuOpen() &&
|
|
800
|
+
!this.bottomBarHost?.contains(target) &&
|
|
801
|
+
!this.bottomBarMoreMenu?.contains(target)) {
|
|
802
|
+
this.setBottomBarMenuOpen(false);
|
|
803
|
+
}
|
|
727
804
|
};
|
|
728
805
|
handleBrandBadgeClick = (event) => {
|
|
729
806
|
event.preventDefault();
|
|
@@ -845,6 +922,21 @@ class EinblickEditRuntime {
|
|
|
845
922
|
pending.resolve(false);
|
|
846
923
|
}
|
|
847
924
|
handleEditorMessage(message) {
|
|
925
|
+
if (this.navigatorNonce && message.nonce === this.navigatorNonce) {
|
|
926
|
+
if (message.type === 'navigator-closed') {
|
|
927
|
+
this.closeNavigator();
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
if (message.type === 'navigator-open-editor') {
|
|
931
|
+
this.openCollectionDrawer({
|
|
932
|
+
collectionId: message.collectionId,
|
|
933
|
+
intent: message.intent,
|
|
934
|
+
recordId: message.recordId,
|
|
935
|
+
resourceSlug: message.resourceSlug,
|
|
936
|
+
});
|
|
937
|
+
return;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
848
940
|
if (!this.editorNonce || message.nonce !== this.editorNonce) {
|
|
849
941
|
return;
|
|
850
942
|
}
|
|
@@ -864,6 +956,17 @@ class EinblickEditRuntime {
|
|
|
864
956
|
source: 'drawer',
|
|
865
957
|
});
|
|
866
958
|
}
|
|
959
|
+
else if (this.editorBinding) {
|
|
960
|
+
const nextBinding = {
|
|
961
|
+
...this.editorBinding,
|
|
962
|
+
recordId: message.recordId ?? this.editorBinding.recordId,
|
|
963
|
+
};
|
|
964
|
+
void this.callbacks.onSave?.({
|
|
965
|
+
binding: nextBinding,
|
|
966
|
+
value: message.fields,
|
|
967
|
+
source: 'drawer',
|
|
968
|
+
});
|
|
969
|
+
}
|
|
867
970
|
this.closeDrawer();
|
|
868
971
|
}
|
|
869
972
|
}
|
|
@@ -886,8 +989,10 @@ class EinblickEditRuntime {
|
|
|
886
989
|
this.callbacks.onStateChange(nextState);
|
|
887
990
|
this.updateBrandBadge();
|
|
888
991
|
this.updateBrandPopover();
|
|
992
|
+
this.updateBottomBar();
|
|
889
993
|
if (!nextState.isAuthenticated) {
|
|
890
994
|
this.setActiveElement(null);
|
|
995
|
+
this.closeNavigator();
|
|
891
996
|
}
|
|
892
997
|
}
|
|
893
998
|
ensureHoverButton() {
|
|
@@ -990,6 +1095,245 @@ class EinblickEditRuntime {
|
|
|
990
1095
|
this.updateBrandBadge();
|
|
991
1096
|
this.updateBrandPopover();
|
|
992
1097
|
}
|
|
1098
|
+
ensureBottomBar() {
|
|
1099
|
+
if (this.bottomBarHost || typeof document === 'undefined') {
|
|
1100
|
+
return;
|
|
1101
|
+
}
|
|
1102
|
+
const host = document.createElement('div');
|
|
1103
|
+
host.setAttribute('data-einblick-control-bar-host', 'true');
|
|
1104
|
+
host.hidden = true;
|
|
1105
|
+
host.style.position = 'fixed';
|
|
1106
|
+
host.style.left = '0';
|
|
1107
|
+
host.style.right = '0';
|
|
1108
|
+
host.style.bottom = '0';
|
|
1109
|
+
host.style.zIndex = '2147483644';
|
|
1110
|
+
host.style.height = `${CONTROL_BAR_HEIGHT}px`;
|
|
1111
|
+
const shadowRoot = host.attachShadow({ mode: 'open' });
|
|
1112
|
+
const style = document.createElement('style');
|
|
1113
|
+
style.textContent = `
|
|
1114
|
+
:host {
|
|
1115
|
+
all: initial;
|
|
1116
|
+
display: block;
|
|
1117
|
+
height: ${CONTROL_BAR_HEIGHT}px;
|
|
1118
|
+
color: rgb(255, 255, 255);
|
|
1119
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
*, *::before, *::after {
|
|
1123
|
+
box-sizing: border-box;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
.bar {
|
|
1127
|
+
position: relative;
|
|
1128
|
+
display: flex;
|
|
1129
|
+
align-items: center;
|
|
1130
|
+
justify-content: space-between;
|
|
1131
|
+
gap: 1rem;
|
|
1132
|
+
width: 100%;
|
|
1133
|
+
height: ${CONTROL_BAR_HEIGHT}px;
|
|
1134
|
+
padding: 0 0.75rem;
|
|
1135
|
+
background: ${EINBLICK_ACCENT_COLOR};
|
|
1136
|
+
border-top: 1px solid rgba(255, 255, 255, 0.24);
|
|
1137
|
+
box-shadow: 0 -8px 24px rgba(15, 23, 42, 0.18);
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
.brand,
|
|
1141
|
+
.actions {
|
|
1142
|
+
display: inline-flex;
|
|
1143
|
+
align-items: center;
|
|
1144
|
+
gap: 0.6rem;
|
|
1145
|
+
min-width: 0;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
.mark {
|
|
1149
|
+
display: inline-flex;
|
|
1150
|
+
align-items: center;
|
|
1151
|
+
justify-content: center;
|
|
1152
|
+
flex: none;
|
|
1153
|
+
width: 1.35rem;
|
|
1154
|
+
height: 1.35rem;
|
|
1155
|
+
color: rgb(255, 255, 255);
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
.site {
|
|
1159
|
+
min-width: 0;
|
|
1160
|
+
max-width: min(26rem, 40vw);
|
|
1161
|
+
overflow: hidden;
|
|
1162
|
+
text-overflow: ellipsis;
|
|
1163
|
+
white-space: nowrap;
|
|
1164
|
+
font: 700 0.84rem/1.1 system-ui, sans-serif;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
button {
|
|
1168
|
+
appearance: none;
|
|
1169
|
+
display: inline-flex;
|
|
1170
|
+
align-items: center;
|
|
1171
|
+
justify-content: center;
|
|
1172
|
+
gap: 0.35rem;
|
|
1173
|
+
min-width: 0;
|
|
1174
|
+
height: 2rem;
|
|
1175
|
+
margin: 0;
|
|
1176
|
+
border: 1px solid rgba(255, 255, 255, 0.36);
|
|
1177
|
+
border-radius: 0.35rem;
|
|
1178
|
+
background: rgba(255, 255, 255, 0.13);
|
|
1179
|
+
color: rgb(255, 255, 255);
|
|
1180
|
+
padding: 0 0.7rem;
|
|
1181
|
+
font: 700 0.78rem/1 system-ui, sans-serif;
|
|
1182
|
+
letter-spacing: 0;
|
|
1183
|
+
cursor: pointer;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
.icon-button {
|
|
1187
|
+
width: 2rem;
|
|
1188
|
+
padding: 0;
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
.icon-button svg {
|
|
1192
|
+
width: 1rem;
|
|
1193
|
+
height: 1rem;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
button:hover,
|
|
1197
|
+
button[aria-expanded="true"] {
|
|
1198
|
+
background: rgba(255, 255, 255, 0.23);
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
button:focus-visible {
|
|
1202
|
+
outline: 2px solid rgba(255, 255, 255, 0.72);
|
|
1203
|
+
outline-offset: 2px;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
.secondary {
|
|
1207
|
+
border-color: transparent;
|
|
1208
|
+
background: transparent;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
.menu {
|
|
1212
|
+
position: absolute;
|
|
1213
|
+
right: 0.5rem;
|
|
1214
|
+
bottom: calc(100% + 0.45rem);
|
|
1215
|
+
display: flex;
|
|
1216
|
+
min-width: 12rem;
|
|
1217
|
+
flex-direction: column;
|
|
1218
|
+
gap: 0;
|
|
1219
|
+
border: 1px solid rgba(255, 255, 255, 0.26);
|
|
1220
|
+
background: rgba(214, 78, 33, 0.98);
|
|
1221
|
+
box-shadow: 0 -12px 28px rgba(15, 23, 42, 0.16);
|
|
1222
|
+
overflow: hidden;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
.menu[hidden] {
|
|
1226
|
+
display: none;
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
.menu button {
|
|
1230
|
+
width: 100%;
|
|
1231
|
+
justify-content: flex-start;
|
|
1232
|
+
height: 2.35rem;
|
|
1233
|
+
border: 0;
|
|
1234
|
+
border-radius: 0;
|
|
1235
|
+
background: transparent;
|
|
1236
|
+
padding: 0 0.8rem;
|
|
1237
|
+
font-size: 0.78rem;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
.menu button + button {
|
|
1241
|
+
border-top: 1px solid rgba(255, 255, 255, 0.18);
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
@media (max-width: 640px) {
|
|
1245
|
+
.bar {
|
|
1246
|
+
gap: 0.4rem;
|
|
1247
|
+
padding: 0 0.5rem;
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
.site {
|
|
1251
|
+
max-width: 32vw;
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
button {
|
|
1255
|
+
padding: 0 0.55rem;
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
.menu {
|
|
1259
|
+
left: auto;
|
|
1260
|
+
right: 0.35rem;
|
|
1261
|
+
min-width: 10.5rem;
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
`;
|
|
1265
|
+
const bar = document.createElement('div');
|
|
1266
|
+
bar.className = 'bar';
|
|
1267
|
+
bar.setAttribute('role', 'toolbar');
|
|
1268
|
+
bar.setAttribute('aria-label', this.messages.brand.controlBarLabel);
|
|
1269
|
+
const brand = document.createElement('div');
|
|
1270
|
+
brand.className = 'brand';
|
|
1271
|
+
const mark = document.createElement('span');
|
|
1272
|
+
mark.className = 'mark';
|
|
1273
|
+
mark.innerHTML = getBrandMarkSvg(22);
|
|
1274
|
+
const siteName = document.createElement('span');
|
|
1275
|
+
siteName.className = 'site';
|
|
1276
|
+
brand.append(mark, siteName);
|
|
1277
|
+
const actions = document.createElement('div');
|
|
1278
|
+
actions.className = 'actions';
|
|
1279
|
+
const cmsButton = document.createElement('button');
|
|
1280
|
+
cmsButton.type = 'button';
|
|
1281
|
+
cmsButton.addEventListener('click', (event) => {
|
|
1282
|
+
event.preventDefault();
|
|
1283
|
+
event.stopPropagation();
|
|
1284
|
+
this.setBottomBarMenuOpen(false);
|
|
1285
|
+
this.setNavigatorOpen(!this.navigatorPanel);
|
|
1286
|
+
});
|
|
1287
|
+
const moreButton = document.createElement('button');
|
|
1288
|
+
moreButton.type = 'button';
|
|
1289
|
+
moreButton.className = 'secondary icon-button';
|
|
1290
|
+
moreButton.setAttribute('aria-haspopup', 'menu');
|
|
1291
|
+
moreButton.title = this.messages.actions.moreActions;
|
|
1292
|
+
moreButton.innerHTML = getMoreActionsSvg(20);
|
|
1293
|
+
moreButton.addEventListener('click', (event) => {
|
|
1294
|
+
event.preventDefault();
|
|
1295
|
+
event.stopPropagation();
|
|
1296
|
+
if (this.navigatorPanel) {
|
|
1297
|
+
this.closeNavigator();
|
|
1298
|
+
}
|
|
1299
|
+
this.setBottomBarMenuOpen(!this.isBottomBarMenuOpen());
|
|
1300
|
+
});
|
|
1301
|
+
const moreMenu = document.createElement('div');
|
|
1302
|
+
moreMenu.className = 'menu';
|
|
1303
|
+
moreMenu.hidden = true;
|
|
1304
|
+
moreMenu.setAttribute('role', 'menu');
|
|
1305
|
+
const openAppButton = document.createElement('button');
|
|
1306
|
+
openAppButton.type = 'button';
|
|
1307
|
+
openAppButton.setAttribute('role', 'menuitem');
|
|
1308
|
+
openAppButton.addEventListener('click', (event) => {
|
|
1309
|
+
event.preventDefault();
|
|
1310
|
+
event.stopPropagation();
|
|
1311
|
+
this.setBottomBarMenuOpen(false);
|
|
1312
|
+
this.openEinblickApp();
|
|
1313
|
+
});
|
|
1314
|
+
const logoutButton = document.createElement('button');
|
|
1315
|
+
logoutButton.type = 'button';
|
|
1316
|
+
logoutButton.setAttribute('role', 'menuitem');
|
|
1317
|
+
logoutButton.addEventListener('click', (event) => {
|
|
1318
|
+
event.preventDefault();
|
|
1319
|
+
event.stopPropagation();
|
|
1320
|
+
this.setBottomBarMenuOpen(false);
|
|
1321
|
+
void this.logoutFromEinblick();
|
|
1322
|
+
});
|
|
1323
|
+
moreMenu.append(openAppButton, logoutButton);
|
|
1324
|
+
actions.append(cmsButton, moreButton);
|
|
1325
|
+
bar.append(brand, actions, moreMenu);
|
|
1326
|
+
shadowRoot.append(style, bar);
|
|
1327
|
+
document.body.append(host);
|
|
1328
|
+
this.bottomBarHost = host;
|
|
1329
|
+
this.bottomBarSiteName = siteName;
|
|
1330
|
+
this.bottomBarCmsButton = cmsButton;
|
|
1331
|
+
this.bottomBarMoreButton = moreButton;
|
|
1332
|
+
this.bottomBarMoreMenu = moreMenu;
|
|
1333
|
+
this.bottomBarOpenAppButton = openAppButton;
|
|
1334
|
+
this.bottomBarLogoutButton = logoutButton;
|
|
1335
|
+
this.updateBottomBar();
|
|
1336
|
+
}
|
|
993
1337
|
updateBrandBadge() {
|
|
994
1338
|
if (!this.brandBadge) {
|
|
995
1339
|
return;
|
|
@@ -1020,6 +1364,71 @@ class EinblickEditRuntime {
|
|
|
1020
1364
|
? this.messages.brand.authenticatedHint
|
|
1021
1365
|
: this.messages.brand.unauthenticatedHint;
|
|
1022
1366
|
}
|
|
1367
|
+
updateBottomBar() {
|
|
1368
|
+
if (!this.bottomBarHost) {
|
|
1369
|
+
this.applyBottomLayout(false);
|
|
1370
|
+
return;
|
|
1371
|
+
}
|
|
1372
|
+
const isVisible = this.chrome === 'bar' && this.state.isAuthenticated;
|
|
1373
|
+
this.bottomBarHost.hidden = !isVisible;
|
|
1374
|
+
this.bottomBarHost.style.display = isVisible ? 'block' : 'none';
|
|
1375
|
+
this.applyBottomLayout(isVisible);
|
|
1376
|
+
if (!isVisible) {
|
|
1377
|
+
this.setBottomBarMenuOpen(false);
|
|
1378
|
+
this.closeNavigator();
|
|
1379
|
+
return;
|
|
1380
|
+
}
|
|
1381
|
+
if (this.bottomBarSiteName) {
|
|
1382
|
+
this.bottomBarSiteName.textContent =
|
|
1383
|
+
this.state.siteName?.trim() || this.messages.brand.connectedSite;
|
|
1384
|
+
this.bottomBarSiteName.title = this.bottomBarSiteName.textContent;
|
|
1385
|
+
}
|
|
1386
|
+
if (this.bottomBarCmsButton) {
|
|
1387
|
+
this.bottomBarCmsButton.textContent = this.messages.actions.cmsCollections;
|
|
1388
|
+
this.bottomBarCmsButton.setAttribute('aria-expanded', this.navigatorPanel ? 'true' : 'false');
|
|
1389
|
+
}
|
|
1390
|
+
if (this.bottomBarMoreButton) {
|
|
1391
|
+
this.bottomBarMoreButton.setAttribute('aria-label', this.messages.actions.moreActions);
|
|
1392
|
+
this.bottomBarMoreButton.setAttribute('aria-expanded', this.isBottomBarMenuOpen() ? 'true' : 'false');
|
|
1393
|
+
}
|
|
1394
|
+
if (this.bottomBarOpenAppButton) {
|
|
1395
|
+
this.bottomBarOpenAppButton.textContent =
|
|
1396
|
+
this.messages.actions.goToEinblick;
|
|
1397
|
+
}
|
|
1398
|
+
if (this.bottomBarLogoutButton) {
|
|
1399
|
+
this.bottomBarLogoutButton.textContent = this.messages.actions.logout;
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
applyBottomLayout(active) {
|
|
1403
|
+
if (typeof document === 'undefined') {
|
|
1404
|
+
return;
|
|
1405
|
+
}
|
|
1406
|
+
const root = document.documentElement;
|
|
1407
|
+
if (!active) {
|
|
1408
|
+
root.style.removeProperty('--einblick-editor-bottom-offset');
|
|
1409
|
+
root.removeAttribute('data-einblick-editor-bar-active');
|
|
1410
|
+
if (this.hasReservedBodyPadding) {
|
|
1411
|
+
if (this.originalBodyPaddingBottom) {
|
|
1412
|
+
document.body.style.paddingBottom = this.originalBodyPaddingBottom;
|
|
1413
|
+
}
|
|
1414
|
+
else {
|
|
1415
|
+
document.body.style.removeProperty('padding-bottom');
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
this.hasReservedBodyPadding = false;
|
|
1419
|
+
this.originalBodyPaddingBottom = null;
|
|
1420
|
+
return;
|
|
1421
|
+
}
|
|
1422
|
+
root.style.setProperty('--einblick-editor-bottom-offset', `${CONTROL_BAR_HEIGHT}px`);
|
|
1423
|
+
root.setAttribute('data-einblick-editor-bar-active', 'true');
|
|
1424
|
+
if (!this.reserveBottomSpace || this.hasReservedBodyPadding) {
|
|
1425
|
+
return;
|
|
1426
|
+
}
|
|
1427
|
+
this.originalBodyPaddingBottom = document.body.style.paddingBottom || null;
|
|
1428
|
+
const currentPadding = window.getComputedStyle(document.body).paddingBottom;
|
|
1429
|
+
document.body.style.paddingBottom = `calc(${currentPadding} + ${CONTROL_BAR_HEIGHT}px)`;
|
|
1430
|
+
this.hasReservedBodyPadding = true;
|
|
1431
|
+
}
|
|
1023
1432
|
isBrandPopoverOpen() {
|
|
1024
1433
|
return !!this.brandPopover && !this.brandPopover.hidden;
|
|
1025
1434
|
}
|
|
@@ -1039,6 +1448,68 @@ class EinblickEditRuntime {
|
|
|
1039
1448
|
const url = new URL('/cms', this.appOrigin).toString();
|
|
1040
1449
|
window.open(url, '_blank', 'noopener,noreferrer');
|
|
1041
1450
|
}
|
|
1451
|
+
setNavigatorOpen(open) {
|
|
1452
|
+
if (open) {
|
|
1453
|
+
this.openNavigator();
|
|
1454
|
+
return;
|
|
1455
|
+
}
|
|
1456
|
+
this.closeNavigator();
|
|
1457
|
+
}
|
|
1458
|
+
openNavigator() {
|
|
1459
|
+
if (!this.state.isAuthenticated) {
|
|
1460
|
+
this.callbacks.onError?.(this.messages.errors.signInToEditContent);
|
|
1461
|
+
return;
|
|
1462
|
+
}
|
|
1463
|
+
if (this.navigatorPanel) {
|
|
1464
|
+
return;
|
|
1465
|
+
}
|
|
1466
|
+
this.setBottomBarMenuOpen(false);
|
|
1467
|
+
let navigatorUrl;
|
|
1468
|
+
const nonce = createRandomId();
|
|
1469
|
+
try {
|
|
1470
|
+
navigatorUrl = this.buildNavigatorUrl(nonce);
|
|
1471
|
+
}
|
|
1472
|
+
catch (error) {
|
|
1473
|
+
this.callbacks.onError?.(error instanceof Error
|
|
1474
|
+
? error.message
|
|
1475
|
+
: this.messages.errors.openEditorFailed);
|
|
1476
|
+
return;
|
|
1477
|
+
}
|
|
1478
|
+
const panel = document.createElement('div');
|
|
1479
|
+
panel.setAttribute('data-einblick-navigator-panel', 'true');
|
|
1480
|
+
panel.style.position = 'fixed';
|
|
1481
|
+
panel.style.left = '0';
|
|
1482
|
+
panel.style.right = '0';
|
|
1483
|
+
panel.style.bottom = `${CONTROL_BAR_HEIGHT}px`;
|
|
1484
|
+
panel.style.height = `min(40rem, calc(100vh - ${CONTROL_BAR_HEIGHT}px))`;
|
|
1485
|
+
panel.style.zIndex = '2147483643';
|
|
1486
|
+
panel.style.borderTop = '1px solid rgba(148, 163, 184, 0.36)';
|
|
1487
|
+
panel.style.overflow = 'hidden';
|
|
1488
|
+
panel.style.background = 'rgb(255, 255, 255)';
|
|
1489
|
+
panel.style.boxShadow = '0 -12px 28px rgba(15, 23, 42, 0.12)';
|
|
1490
|
+
const iframe = document.createElement('iframe');
|
|
1491
|
+
iframe.src = navigatorUrl;
|
|
1492
|
+
iframe.title = this.messages.actions.cmsCollections;
|
|
1493
|
+
iframe.style.display = 'block';
|
|
1494
|
+
iframe.style.width = '100%';
|
|
1495
|
+
iframe.style.height = '100%';
|
|
1496
|
+
iframe.style.border = '0';
|
|
1497
|
+
iframe.style.background = 'rgb(255, 255, 255)';
|
|
1498
|
+
panel.append(iframe);
|
|
1499
|
+
document.body.append(panel);
|
|
1500
|
+
this.navigatorPanel = panel;
|
|
1501
|
+
this.navigatorNonce = nonce;
|
|
1502
|
+
this.updateBottomBar();
|
|
1503
|
+
}
|
|
1504
|
+
closeNavigator() {
|
|
1505
|
+
const hadNavigator = !!this.navigatorPanel || !!this.navigatorNonce;
|
|
1506
|
+
this.navigatorPanel?.remove();
|
|
1507
|
+
this.navigatorPanel = null;
|
|
1508
|
+
this.navigatorNonce = null;
|
|
1509
|
+
if (hadNavigator) {
|
|
1510
|
+
this.updateBottomBar();
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1042
1513
|
async logoutFromEinblick() {
|
|
1043
1514
|
if (typeof window === 'undefined') {
|
|
1044
1515
|
return;
|
|
@@ -1207,6 +1678,34 @@ class EinblickEditRuntime {
|
|
|
1207
1678
|
}
|
|
1208
1679
|
return url.toString();
|
|
1209
1680
|
}
|
|
1681
|
+
buildNavigatorUrl(nonce) {
|
|
1682
|
+
const sessionToken = this.getActiveSessionToken();
|
|
1683
|
+
if (!sessionToken) {
|
|
1684
|
+
throw new Error(this.messages.errors.editSessionExpired);
|
|
1685
|
+
}
|
|
1686
|
+
const url = new URL('/sdk/navigator', this.appOrigin);
|
|
1687
|
+
url.searchParams.set('origin', window.location.origin);
|
|
1688
|
+
url.searchParams.set('nonce', nonce);
|
|
1689
|
+
url.searchParams.set('sessionToken', sessionToken);
|
|
1690
|
+
return url.toString();
|
|
1691
|
+
}
|
|
1692
|
+
buildCollectionEditorUrl(args) {
|
|
1693
|
+
const sessionToken = this.getActiveSessionToken();
|
|
1694
|
+
if (!sessionToken) {
|
|
1695
|
+
throw new Error(this.messages.errors.editSessionExpired);
|
|
1696
|
+
}
|
|
1697
|
+
const url = new URL('/sdk/editor', this.appOrigin);
|
|
1698
|
+
url.searchParams.set('origin', window.location.origin);
|
|
1699
|
+
url.searchParams.set('nonce', args.nonce);
|
|
1700
|
+
url.searchParams.set('sessionToken', sessionToken);
|
|
1701
|
+
url.searchParams.set('returnTo', window.location.href);
|
|
1702
|
+
url.searchParams.set('collectionId', args.collectionId);
|
|
1703
|
+
url.searchParams.set('intent', args.intent);
|
|
1704
|
+
if (args.recordId) {
|
|
1705
|
+
url.searchParams.set('recordId', args.recordId);
|
|
1706
|
+
}
|
|
1707
|
+
return url.toString();
|
|
1708
|
+
}
|
|
1210
1709
|
updateHoverButtonVisibility(element) {
|
|
1211
1710
|
if (!this.hoverCreateButton) {
|
|
1212
1711
|
return;
|
|
@@ -1529,7 +2028,9 @@ class EinblickEditRuntime {
|
|
|
1529
2028
|
this.callbacks.onError?.(this.messages.errors.signInToEditContent);
|
|
1530
2029
|
return;
|
|
1531
2030
|
}
|
|
2031
|
+
this.setBottomBarMenuOpen(false);
|
|
1532
2032
|
this.closeInlineEditor();
|
|
2033
|
+
this.closeNavigator();
|
|
1533
2034
|
this.closeDrawer();
|
|
1534
2035
|
this.setActiveElement(null);
|
|
1535
2036
|
const nonce = createRandomId();
|
|
@@ -1564,6 +2065,71 @@ class EinblickEditRuntime {
|
|
|
1564
2065
|
document.body.append(backdrop);
|
|
1565
2066
|
this.editorBackdrop = backdrop;
|
|
1566
2067
|
}
|
|
2068
|
+
openCollectionDrawer(args) {
|
|
2069
|
+
if (!this.state.isAuthenticated) {
|
|
2070
|
+
this.callbacks.onError?.(this.messages.errors.signInToEditContent);
|
|
2071
|
+
return;
|
|
2072
|
+
}
|
|
2073
|
+
this.setBottomBarMenuOpen(false);
|
|
2074
|
+
this.closeInlineEditor();
|
|
2075
|
+
this.closeNavigator();
|
|
2076
|
+
this.closeDrawer();
|
|
2077
|
+
this.setActiveElement(null);
|
|
2078
|
+
const nonce = createRandomId();
|
|
2079
|
+
let editorUrl;
|
|
2080
|
+
try {
|
|
2081
|
+
editorUrl = this.buildCollectionEditorUrl({
|
|
2082
|
+
collectionId: args.collectionId,
|
|
2083
|
+
nonce,
|
|
2084
|
+
intent: args.intent,
|
|
2085
|
+
recordId: args.recordId,
|
|
2086
|
+
});
|
|
2087
|
+
}
|
|
2088
|
+
catch (error) {
|
|
2089
|
+
this.callbacks.onError?.(error instanceof Error
|
|
2090
|
+
? error.message
|
|
2091
|
+
: this.messages.errors.openEditorFailed);
|
|
2092
|
+
return;
|
|
2093
|
+
}
|
|
2094
|
+
this.editorNonce = nonce;
|
|
2095
|
+
this.editorTarget = null;
|
|
2096
|
+
this.editorBinding = args.resourceSlug
|
|
2097
|
+
? {
|
|
2098
|
+
resourceSlug: args.resourceSlug,
|
|
2099
|
+
recordId: args.recordId ?? '',
|
|
2100
|
+
resourceMode: 'collection',
|
|
2101
|
+
displayMode: 'drawer',
|
|
2102
|
+
}
|
|
2103
|
+
: null;
|
|
2104
|
+
const backdrop = document.createElement('div');
|
|
2105
|
+
backdrop.setAttribute('data-einblick-editor-backdrop', 'true');
|
|
2106
|
+
const shell = document.createElement('div');
|
|
2107
|
+
shell.setAttribute('data-einblick-editor-shell', 'true');
|
|
2108
|
+
const iframe = document.createElement('iframe');
|
|
2109
|
+
iframe.setAttribute('data-einblick-editor-frame', 'true');
|
|
2110
|
+
iframe.src = editorUrl;
|
|
2111
|
+
iframe.title = this.messages.editor.frameTitle;
|
|
2112
|
+
shell.append(iframe);
|
|
2113
|
+
backdrop.append(shell);
|
|
2114
|
+
backdrop.addEventListener('click', (event) => {
|
|
2115
|
+
if (event.target === backdrop) {
|
|
2116
|
+
this.closeDrawer();
|
|
2117
|
+
}
|
|
2118
|
+
});
|
|
2119
|
+
document.body.append(backdrop);
|
|
2120
|
+
this.editorBackdrop = backdrop;
|
|
2121
|
+
}
|
|
2122
|
+
isBottomBarMenuOpen() {
|
|
2123
|
+
return !!this.bottomBarMoreMenu && !this.bottomBarMoreMenu.hidden;
|
|
2124
|
+
}
|
|
2125
|
+
setBottomBarMenuOpen(open) {
|
|
2126
|
+
if (!this.bottomBarMoreMenu || !this.bottomBarMoreButton) {
|
|
2127
|
+
return;
|
|
2128
|
+
}
|
|
2129
|
+
const nextOpen = open && this.state.isAuthenticated;
|
|
2130
|
+
this.bottomBarMoreMenu.hidden = !nextOpen;
|
|
2131
|
+
this.bottomBarMoreButton.setAttribute('aria-expanded', nextOpen ? 'true' : 'false');
|
|
2132
|
+
}
|
|
1567
2133
|
closeDrawer() {
|
|
1568
2134
|
this.editorBackdrop?.remove();
|
|
1569
2135
|
this.editorBackdrop = null;
|