@einblick/sdk 0.4.0 → 0.4.5

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.
@@ -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,16 @@ 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
+ }
108
119
  function createRandomId() {
109
120
  if (typeof crypto !== 'undefined' &&
110
121
  typeof crypto.randomUUID === 'function') {
@@ -419,6 +430,8 @@ class EinblickEditRuntime {
419
430
  siteKey;
420
431
  appOrigin;
421
432
  callbacks;
433
+ chrome;
434
+ reserveBottomSpace;
422
435
  locale;
423
436
  messages;
424
437
  bridgeNonce = createRandomId();
@@ -442,6 +455,14 @@ class EinblickEditRuntime {
442
455
  brandPopoverHint = null;
443
456
  brandPopoverOpenAppButton = null;
444
457
  brandPopoverLogoutButton = null;
458
+ bottomBarHost = null;
459
+ bottomBarSiteName = null;
460
+ bottomBarStatus = null;
461
+ bottomBarCmsButton = null;
462
+ bottomBarOpenAppButton = null;
463
+ bottomBarLogoutButton = null;
464
+ originalBodyPaddingBottom = null;
465
+ hasReservedBodyPadding = false;
445
466
  mutationObserver = null;
446
467
  destroyed = false;
447
468
  started = false;
@@ -452,11 +473,16 @@ class EinblickEditRuntime {
452
473
  editorNonce = null;
453
474
  editorTarget = null;
454
475
  editorBinding = null;
476
+ navigatorPanel = null;
477
+ navigatorNonce = null;
455
478
  pendingInlineSaves = new Map();
456
479
  pendingLogin = null;
457
480
  constructor(options) {
458
481
  this.siteKey = options.siteKey;
459
482
  this.appOrigin = resolveAppOrigin(options.appOrigin, options.appUrl);
483
+ this.chrome = options.chrome ?? 'bar';
484
+ this.reserveBottomSpace =
485
+ options.reserveBottomSpace ?? this.chrome === 'bar';
460
486
  this.locale = resolveEinblickSdkLocale(options.locale);
461
487
  this.messages = getEinblickSdkMessages(this.locale);
462
488
  this.session =
@@ -488,7 +514,12 @@ class EinblickEditRuntime {
488
514
  this.started = true;
489
515
  injectRuntimeStyles();
490
516
  this.ensureHoverButton();
491
- this.ensureBrandBadge();
517
+ if (this.chrome === 'badge') {
518
+ this.ensureBrandBadge();
519
+ }
520
+ else if (this.chrome === 'bar') {
521
+ this.ensureBottomBar();
522
+ }
492
523
  window.addEventListener('message', this.handleMessage);
493
524
  window.addEventListener('pointerdown', this.handleGlobalPointerDown, true);
494
525
  window.addEventListener('pointermove', this.handlePointerMove, true);
@@ -547,7 +578,16 @@ class EinblickEditRuntime {
547
578
  this.brandPopoverHint = null;
548
579
  this.brandPopoverOpenAppButton = null;
549
580
  this.brandPopoverLogoutButton = null;
581
+ this.bottomBarHost?.remove();
582
+ this.bottomBarHost = null;
583
+ this.bottomBarSiteName = null;
584
+ this.bottomBarStatus = null;
585
+ this.bottomBarCmsButton = null;
586
+ this.bottomBarOpenAppButton = null;
587
+ this.bottomBarLogoutButton = null;
588
+ this.applyBottomLayout(false);
550
589
  this.closeInlineEditor();
590
+ this.closeNavigator();
551
591
  this.closeDrawer();
552
592
  if (this.pendingLogin) {
553
593
  if (this.pendingLogin.closePollId !== null) {
@@ -593,6 +633,7 @@ class EinblickEditRuntime {
593
633
  this.messages.actions.logout;
594
634
  }
595
635
  this.updateBrandPopover();
636
+ this.updateBottomBar();
596
637
  }
597
638
  async login(options) {
598
639
  if (typeof window === 'undefined') {
@@ -641,6 +682,7 @@ class EinblickEditRuntime {
641
682
  }
642
683
  openEditor(binding, element) {
643
684
  this.setBrandPopoverOpen(false);
685
+ this.closeNavigator();
644
686
  const target = element ?? this.findElementForBinding(binding);
645
687
  if (shouldUseInlineEditor(binding)) {
646
688
  this.openInlineEditor(target, binding);
@@ -651,7 +693,8 @@ class EinblickEditRuntime {
651
693
  handlePointerMove = (event) => {
652
694
  if (!this.state.isAuthenticated ||
653
695
  this.currentInlineTarget ||
654
- this.editorBackdrop) {
696
+ this.editorBackdrop ||
697
+ this.navigatorPanel) {
655
698
  this.setActiveElement(null);
656
699
  return;
657
700
  }
@@ -678,6 +721,11 @@ class EinblickEditRuntime {
678
721
  this.setBrandPopoverOpen(false);
679
722
  return;
680
723
  }
724
+ if (this.navigatorPanel) {
725
+ event.preventDefault();
726
+ this.closeNavigator();
727
+ return;
728
+ }
681
729
  if (this.currentInlineTarget) {
682
730
  event.preventDefault();
683
731
  this.closeInlineEditor();
@@ -845,6 +893,21 @@ class EinblickEditRuntime {
845
893
  pending.resolve(false);
846
894
  }
847
895
  handleEditorMessage(message) {
896
+ if (this.navigatorNonce && message.nonce === this.navigatorNonce) {
897
+ if (message.type === 'navigator-closed') {
898
+ this.closeNavigator();
899
+ return;
900
+ }
901
+ if (message.type === 'navigator-open-editor') {
902
+ this.openCollectionDrawer({
903
+ collectionId: message.collectionId,
904
+ intent: message.intent,
905
+ recordId: message.recordId,
906
+ resourceSlug: message.resourceSlug,
907
+ });
908
+ return;
909
+ }
910
+ }
848
911
  if (!this.editorNonce || message.nonce !== this.editorNonce) {
849
912
  return;
850
913
  }
@@ -864,6 +927,17 @@ class EinblickEditRuntime {
864
927
  source: 'drawer',
865
928
  });
866
929
  }
930
+ else if (this.editorBinding) {
931
+ const nextBinding = {
932
+ ...this.editorBinding,
933
+ recordId: message.recordId ?? this.editorBinding.recordId,
934
+ };
935
+ void this.callbacks.onSave?.({
936
+ binding: nextBinding,
937
+ value: message.fields,
938
+ source: 'drawer',
939
+ });
940
+ }
867
941
  this.closeDrawer();
868
942
  }
869
943
  }
@@ -886,8 +960,10 @@ class EinblickEditRuntime {
886
960
  this.callbacks.onStateChange(nextState);
887
961
  this.updateBrandBadge();
888
962
  this.updateBrandPopover();
963
+ this.updateBottomBar();
889
964
  if (!nextState.isAuthenticated) {
890
965
  this.setActiveElement(null);
966
+ this.closeNavigator();
891
967
  }
892
968
  }
893
969
  ensureHoverButton() {
@@ -990,6 +1066,186 @@ class EinblickEditRuntime {
990
1066
  this.updateBrandBadge();
991
1067
  this.updateBrandPopover();
992
1068
  }
1069
+ ensureBottomBar() {
1070
+ if (this.bottomBarHost || typeof document === 'undefined') {
1071
+ return;
1072
+ }
1073
+ const host = document.createElement('div');
1074
+ host.setAttribute('data-einblick-control-bar-host', 'true');
1075
+ host.hidden = true;
1076
+ host.style.position = 'fixed';
1077
+ host.style.left = '0';
1078
+ host.style.right = '0';
1079
+ host.style.bottom = '0';
1080
+ host.style.zIndex = '2147483644';
1081
+ host.style.height = `${CONTROL_BAR_HEIGHT}px`;
1082
+ const shadowRoot = host.attachShadow({ mode: 'open' });
1083
+ const style = document.createElement('style');
1084
+ style.textContent = `
1085
+ :host {
1086
+ all: initial;
1087
+ display: block;
1088
+ height: ${CONTROL_BAR_HEIGHT}px;
1089
+ color: rgb(255, 255, 255);
1090
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
1091
+ }
1092
+
1093
+ *, *::before, *::after {
1094
+ box-sizing: border-box;
1095
+ }
1096
+
1097
+ .bar {
1098
+ display: flex;
1099
+ align-items: center;
1100
+ justify-content: space-between;
1101
+ gap: 1rem;
1102
+ width: 100%;
1103
+ height: ${CONTROL_BAR_HEIGHT}px;
1104
+ padding: 0 0.75rem;
1105
+ background: ${EINBLICK_ACCENT_COLOR};
1106
+ border-top: 1px solid rgba(255, 255, 255, 0.24);
1107
+ box-shadow: 0 -8px 24px rgba(15, 23, 42, 0.18);
1108
+ }
1109
+
1110
+ .brand,
1111
+ .actions {
1112
+ display: inline-flex;
1113
+ align-items: center;
1114
+ gap: 0.6rem;
1115
+ min-width: 0;
1116
+ }
1117
+
1118
+ .mark {
1119
+ display: inline-flex;
1120
+ align-items: center;
1121
+ justify-content: center;
1122
+ flex: none;
1123
+ width: 1.35rem;
1124
+ height: 1.35rem;
1125
+ color: rgb(255, 255, 255);
1126
+ }
1127
+
1128
+ .site {
1129
+ min-width: 0;
1130
+ max-width: min(26rem, 40vw);
1131
+ overflow: hidden;
1132
+ text-overflow: ellipsis;
1133
+ white-space: nowrap;
1134
+ font: 700 0.84rem/1.1 system-ui, sans-serif;
1135
+ }
1136
+
1137
+ .status {
1138
+ flex: none;
1139
+ border-radius: 999px;
1140
+ background: rgba(255, 255, 255, 0.18);
1141
+ padding: 0.25rem 0.5rem;
1142
+ font: 650 0.72rem/1 system-ui, sans-serif;
1143
+ }
1144
+
1145
+ button {
1146
+ appearance: none;
1147
+ display: inline-flex;
1148
+ align-items: center;
1149
+ justify-content: center;
1150
+ gap: 0.35rem;
1151
+ min-width: 0;
1152
+ height: 2rem;
1153
+ margin: 0;
1154
+ border: 1px solid rgba(255, 255, 255, 0.36);
1155
+ border-radius: 0.35rem;
1156
+ background: rgba(255, 255, 255, 0.13);
1157
+ color: rgb(255, 255, 255);
1158
+ padding: 0 0.7rem;
1159
+ font: 700 0.78rem/1 system-ui, sans-serif;
1160
+ letter-spacing: 0;
1161
+ cursor: pointer;
1162
+ }
1163
+
1164
+ button:hover,
1165
+ button[aria-expanded="true"] {
1166
+ background: rgba(255, 255, 255, 0.23);
1167
+ }
1168
+
1169
+ button:focus-visible {
1170
+ outline: 2px solid rgba(255, 255, 255, 0.72);
1171
+ outline-offset: 2px;
1172
+ }
1173
+
1174
+ .secondary {
1175
+ border-color: transparent;
1176
+ background: transparent;
1177
+ }
1178
+
1179
+ @media (max-width: 640px) {
1180
+ .bar {
1181
+ gap: 0.4rem;
1182
+ padding: 0 0.5rem;
1183
+ }
1184
+
1185
+ .site {
1186
+ max-width: 34vw;
1187
+ }
1188
+
1189
+ .status {
1190
+ display: none;
1191
+ }
1192
+
1193
+ button {
1194
+ padding: 0 0.55rem;
1195
+ }
1196
+ }
1197
+ `;
1198
+ const bar = document.createElement('div');
1199
+ bar.className = 'bar';
1200
+ bar.setAttribute('role', 'toolbar');
1201
+ bar.setAttribute('aria-label', this.messages.brand.controlBarLabel);
1202
+ const brand = document.createElement('div');
1203
+ brand.className = 'brand';
1204
+ const mark = document.createElement('span');
1205
+ mark.className = 'mark';
1206
+ mark.innerHTML = getBrandMarkSvg(22);
1207
+ const siteName = document.createElement('span');
1208
+ siteName.className = 'site';
1209
+ const status = document.createElement('span');
1210
+ status.className = 'status';
1211
+ brand.append(mark, siteName, status);
1212
+ const actions = document.createElement('div');
1213
+ actions.className = 'actions';
1214
+ const cmsButton = document.createElement('button');
1215
+ cmsButton.type = 'button';
1216
+ cmsButton.addEventListener('click', (event) => {
1217
+ event.preventDefault();
1218
+ event.stopPropagation();
1219
+ this.setNavigatorOpen(!this.navigatorPanel);
1220
+ });
1221
+ const openAppButton = document.createElement('button');
1222
+ openAppButton.type = 'button';
1223
+ openAppButton.className = 'secondary';
1224
+ openAppButton.addEventListener('click', (event) => {
1225
+ event.preventDefault();
1226
+ event.stopPropagation();
1227
+ this.openEinblickApp();
1228
+ });
1229
+ const logoutButton = document.createElement('button');
1230
+ logoutButton.type = 'button';
1231
+ logoutButton.className = 'secondary';
1232
+ logoutButton.addEventListener('click', (event) => {
1233
+ event.preventDefault();
1234
+ event.stopPropagation();
1235
+ void this.logoutFromEinblick();
1236
+ });
1237
+ actions.append(cmsButton, openAppButton, logoutButton);
1238
+ bar.append(brand, actions);
1239
+ shadowRoot.append(style, bar);
1240
+ document.body.append(host);
1241
+ this.bottomBarHost = host;
1242
+ this.bottomBarSiteName = siteName;
1243
+ this.bottomBarStatus = status;
1244
+ this.bottomBarCmsButton = cmsButton;
1245
+ this.bottomBarOpenAppButton = openAppButton;
1246
+ this.bottomBarLogoutButton = logoutButton;
1247
+ this.updateBottomBar();
1248
+ }
993
1249
  updateBrandBadge() {
994
1250
  if (!this.brandBadge) {
995
1251
  return;
@@ -1020,6 +1276,69 @@ class EinblickEditRuntime {
1020
1276
  ? this.messages.brand.authenticatedHint
1021
1277
  : this.messages.brand.unauthenticatedHint;
1022
1278
  }
1279
+ updateBottomBar() {
1280
+ if (!this.bottomBarHost) {
1281
+ this.applyBottomLayout(false);
1282
+ return;
1283
+ }
1284
+ const isVisible = this.chrome === 'bar' && this.state.isAuthenticated;
1285
+ this.bottomBarHost.hidden = !isVisible;
1286
+ this.bottomBarHost.style.display = isVisible ? 'block' : 'none';
1287
+ this.applyBottomLayout(isVisible);
1288
+ if (!isVisible) {
1289
+ this.closeNavigator();
1290
+ return;
1291
+ }
1292
+ if (this.bottomBarSiteName) {
1293
+ this.bottomBarSiteName.textContent =
1294
+ this.state.siteName?.trim() || this.messages.brand.connectedSite;
1295
+ this.bottomBarSiteName.title = this.bottomBarSiteName.textContent;
1296
+ }
1297
+ if (this.bottomBarStatus) {
1298
+ this.bottomBarStatus.textContent = this.messages.brand.editModeActive;
1299
+ }
1300
+ if (this.bottomBarCmsButton) {
1301
+ this.bottomBarCmsButton.textContent = this.messages.actions.cmsCollections;
1302
+ this.bottomBarCmsButton.setAttribute('aria-expanded', this.navigatorPanel ? 'true' : 'false');
1303
+ }
1304
+ if (this.bottomBarOpenAppButton) {
1305
+ this.bottomBarOpenAppButton.textContent =
1306
+ this.messages.actions.goToEinblick;
1307
+ }
1308
+ if (this.bottomBarLogoutButton) {
1309
+ this.bottomBarLogoutButton.textContent = this.messages.actions.logout;
1310
+ }
1311
+ }
1312
+ applyBottomLayout(active) {
1313
+ if (typeof document === 'undefined') {
1314
+ return;
1315
+ }
1316
+ const root = document.documentElement;
1317
+ if (!active) {
1318
+ root.style.removeProperty('--einblick-editor-bottom-offset');
1319
+ root.removeAttribute('data-einblick-editor-bar-active');
1320
+ if (this.hasReservedBodyPadding) {
1321
+ if (this.originalBodyPaddingBottom) {
1322
+ document.body.style.paddingBottom = this.originalBodyPaddingBottom;
1323
+ }
1324
+ else {
1325
+ document.body.style.removeProperty('padding-bottom');
1326
+ }
1327
+ }
1328
+ this.hasReservedBodyPadding = false;
1329
+ this.originalBodyPaddingBottom = null;
1330
+ return;
1331
+ }
1332
+ root.style.setProperty('--einblick-editor-bottom-offset', `${CONTROL_BAR_HEIGHT}px`);
1333
+ root.setAttribute('data-einblick-editor-bar-active', 'true');
1334
+ if (!this.reserveBottomSpace || this.hasReservedBodyPadding) {
1335
+ return;
1336
+ }
1337
+ this.originalBodyPaddingBottom = document.body.style.paddingBottom || null;
1338
+ const currentPadding = window.getComputedStyle(document.body).paddingBottom;
1339
+ document.body.style.paddingBottom = `calc(${currentPadding} + ${CONTROL_BAR_HEIGHT}px)`;
1340
+ this.hasReservedBodyPadding = true;
1341
+ }
1023
1342
  isBrandPopoverOpen() {
1024
1343
  return !!this.brandPopover && !this.brandPopover.hidden;
1025
1344
  }
@@ -1039,6 +1358,68 @@ class EinblickEditRuntime {
1039
1358
  const url = new URL('/cms', this.appOrigin).toString();
1040
1359
  window.open(url, '_blank', 'noopener,noreferrer');
1041
1360
  }
1361
+ setNavigatorOpen(open) {
1362
+ if (open) {
1363
+ this.openNavigator();
1364
+ return;
1365
+ }
1366
+ this.closeNavigator();
1367
+ }
1368
+ openNavigator() {
1369
+ if (!this.state.isAuthenticated) {
1370
+ this.callbacks.onError?.(this.messages.errors.signInToEditContent);
1371
+ return;
1372
+ }
1373
+ if (this.navigatorPanel) {
1374
+ return;
1375
+ }
1376
+ let navigatorUrl;
1377
+ const nonce = createRandomId();
1378
+ try {
1379
+ navigatorUrl = this.buildNavigatorUrl(nonce);
1380
+ }
1381
+ catch (error) {
1382
+ this.callbacks.onError?.(error instanceof Error
1383
+ ? error.message
1384
+ : this.messages.errors.openEditorFailed);
1385
+ return;
1386
+ }
1387
+ const panel = document.createElement('div');
1388
+ panel.setAttribute('data-einblick-navigator-panel', 'true');
1389
+ panel.style.position = 'fixed';
1390
+ panel.style.right = '0.75rem';
1391
+ panel.style.bottom = `${CONTROL_BAR_HEIGHT + 12}px`;
1392
+ panel.style.width = 'min(58rem, calc(100vw - 1.5rem))';
1393
+ panel.style.height = `min(40rem, calc(100vh - ${CONTROL_BAR_HEIGHT + 24}px))`;
1394
+ panel.style.zIndex = '2147483645';
1395
+ panel.style.border = '1px solid rgba(148, 163, 184, 0.36)';
1396
+ panel.style.borderRadius = '0.65rem';
1397
+ panel.style.overflow = 'hidden';
1398
+ panel.style.background = 'rgb(255, 255, 255)';
1399
+ panel.style.boxShadow = '0 24px 64px rgba(15, 23, 42, 0.26)';
1400
+ const iframe = document.createElement('iframe');
1401
+ iframe.src = navigatorUrl;
1402
+ iframe.title = this.messages.actions.cmsCollections;
1403
+ iframe.style.display = 'block';
1404
+ iframe.style.width = '100%';
1405
+ iframe.style.height = '100%';
1406
+ iframe.style.border = '0';
1407
+ iframe.style.background = 'rgb(255, 255, 255)';
1408
+ panel.append(iframe);
1409
+ document.body.append(panel);
1410
+ this.navigatorPanel = panel;
1411
+ this.navigatorNonce = nonce;
1412
+ this.updateBottomBar();
1413
+ }
1414
+ closeNavigator() {
1415
+ const hadNavigator = !!this.navigatorPanel || !!this.navigatorNonce;
1416
+ this.navigatorPanel?.remove();
1417
+ this.navigatorPanel = null;
1418
+ this.navigatorNonce = null;
1419
+ if (hadNavigator) {
1420
+ this.updateBottomBar();
1421
+ }
1422
+ }
1042
1423
  async logoutFromEinblick() {
1043
1424
  if (typeof window === 'undefined') {
1044
1425
  return;
@@ -1207,6 +1588,34 @@ class EinblickEditRuntime {
1207
1588
  }
1208
1589
  return url.toString();
1209
1590
  }
1591
+ buildNavigatorUrl(nonce) {
1592
+ const sessionToken = this.getActiveSessionToken();
1593
+ if (!sessionToken) {
1594
+ throw new Error(this.messages.errors.editSessionExpired);
1595
+ }
1596
+ const url = new URL('/sdk/navigator', this.appOrigin);
1597
+ url.searchParams.set('origin', window.location.origin);
1598
+ url.searchParams.set('nonce', nonce);
1599
+ url.searchParams.set('sessionToken', sessionToken);
1600
+ return url.toString();
1601
+ }
1602
+ buildCollectionEditorUrl(args) {
1603
+ const sessionToken = this.getActiveSessionToken();
1604
+ if (!sessionToken) {
1605
+ throw new Error(this.messages.errors.editSessionExpired);
1606
+ }
1607
+ const url = new URL('/sdk/editor', this.appOrigin);
1608
+ url.searchParams.set('origin', window.location.origin);
1609
+ url.searchParams.set('nonce', args.nonce);
1610
+ url.searchParams.set('sessionToken', sessionToken);
1611
+ url.searchParams.set('returnTo', window.location.href);
1612
+ url.searchParams.set('collectionId', args.collectionId);
1613
+ url.searchParams.set('intent', args.intent);
1614
+ if (args.recordId) {
1615
+ url.searchParams.set('recordId', args.recordId);
1616
+ }
1617
+ return url.toString();
1618
+ }
1210
1619
  updateHoverButtonVisibility(element) {
1211
1620
  if (!this.hoverCreateButton) {
1212
1621
  return;
@@ -1530,6 +1939,7 @@ class EinblickEditRuntime {
1530
1939
  return;
1531
1940
  }
1532
1941
  this.closeInlineEditor();
1942
+ this.closeNavigator();
1533
1943
  this.closeDrawer();
1534
1944
  this.setActiveElement(null);
1535
1945
  const nonce = createRandomId();
@@ -1564,6 +1974,59 @@ class EinblickEditRuntime {
1564
1974
  document.body.append(backdrop);
1565
1975
  this.editorBackdrop = backdrop;
1566
1976
  }
1977
+ openCollectionDrawer(args) {
1978
+ if (!this.state.isAuthenticated) {
1979
+ this.callbacks.onError?.(this.messages.errors.signInToEditContent);
1980
+ return;
1981
+ }
1982
+ this.closeInlineEditor();
1983
+ this.closeNavigator();
1984
+ this.closeDrawer();
1985
+ this.setActiveElement(null);
1986
+ const nonce = createRandomId();
1987
+ let editorUrl;
1988
+ try {
1989
+ editorUrl = this.buildCollectionEditorUrl({
1990
+ collectionId: args.collectionId,
1991
+ nonce,
1992
+ intent: args.intent,
1993
+ recordId: args.recordId,
1994
+ });
1995
+ }
1996
+ catch (error) {
1997
+ this.callbacks.onError?.(error instanceof Error
1998
+ ? error.message
1999
+ : this.messages.errors.openEditorFailed);
2000
+ return;
2001
+ }
2002
+ this.editorNonce = nonce;
2003
+ this.editorTarget = null;
2004
+ this.editorBinding = args.resourceSlug
2005
+ ? {
2006
+ resourceSlug: args.resourceSlug,
2007
+ recordId: args.recordId ?? '',
2008
+ resourceMode: 'collection',
2009
+ displayMode: 'drawer',
2010
+ }
2011
+ : null;
2012
+ const backdrop = document.createElement('div');
2013
+ backdrop.setAttribute('data-einblick-editor-backdrop', 'true');
2014
+ const shell = document.createElement('div');
2015
+ shell.setAttribute('data-einblick-editor-shell', 'true');
2016
+ const iframe = document.createElement('iframe');
2017
+ iframe.setAttribute('data-einblick-editor-frame', 'true');
2018
+ iframe.src = editorUrl;
2019
+ iframe.title = this.messages.editor.frameTitle;
2020
+ shell.append(iframe);
2021
+ backdrop.append(shell);
2022
+ backdrop.addEventListener('click', (event) => {
2023
+ if (event.target === backdrop) {
2024
+ this.closeDrawer();
2025
+ }
2026
+ });
2027
+ document.body.append(backdrop);
2028
+ this.editorBackdrop = backdrop;
2029
+ }
1567
2030
  closeDrawer() {
1568
2031
  this.editorBackdrop?.remove();
1569
2032
  this.editorBackdrop = null;