@einblick/sdk 0.5.5 → 0.6.0

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.
@@ -1,5 +1,28 @@
1
1
  import { EINBLICK_AUTH_SOURCE, EINBLICK_BRIDGE_SOURCE, EINBLICK_EDITOR_SOURCE, EINBLICK_PARENT_SOURCE, formatValueForText, isMediaEditableBinding, isEditSessionExpired, readBindingFromElement, resolveAppOrigin, serializeBindingValue, shouldUseInlineEditor, } from './shared.js';
2
2
  import { getEinblickSdkMessages, resolveEinblickSdkLocale, } from './i18n.js';
3
+ function normalizeResourceHints(hints) {
4
+ const normalized = [];
5
+ const seen = new Set();
6
+ for (const hint of hints ?? []) {
7
+ const resourceSlug = hint.resourceSlug?.trim();
8
+ if (!resourceSlug)
9
+ continue;
10
+ const sourceType = hint.sourceType ?? 'cms';
11
+ const key = `${sourceType}:${resourceSlug}`;
12
+ if (seen.has(key))
13
+ continue;
14
+ seen.add(key);
15
+ normalized.push({
16
+ sourceType,
17
+ resourceSlug,
18
+ label: hint.label?.trim() || undefined,
19
+ mode: hint.mode,
20
+ recordIds: hint.recordIds?.filter((id) => id.trim().length > 0),
21
+ showInBottomBar: hint.showInBottomBar,
22
+ });
23
+ }
24
+ return normalized;
25
+ }
3
26
  const RUNTIME_STYLE_ID = 'einblick-edit-runtime-styles';
4
27
  const EINBLICK_ACCENT_RGB = '250, 105, 62';
5
28
  const EINBLICK_ACCENT_COLOR = `rgb(${EINBLICK_ACCENT_RGB})`;
@@ -394,6 +417,7 @@ class EinblickEditRuntime {
394
417
  callbacks;
395
418
  chrome;
396
419
  reserveBottomSpace;
420
+ resourceHints;
397
421
  locale;
398
422
  messages;
399
423
  bridgeNonce = createRandomId();
@@ -422,7 +446,7 @@ class EinblickEditRuntime {
422
446
  brandPopoverLogoutButton = null;
423
447
  bottomBarHost = null;
424
448
  bottomBarSiteName = null;
425
- bottomBarCmsButton = null;
449
+ bottomBarResourceList = null;
426
450
  bottomBarMoreButton = null;
427
451
  bottomBarMoreMenu = null;
428
452
  bottomBarOpenAppButton = null;
@@ -444,6 +468,7 @@ class EinblickEditRuntime {
444
468
  navigatorFrame = null;
445
469
  navigatorNonce = null;
446
470
  navigatorOpen = false;
471
+ navigatorFilter = null;
447
472
  pendingInlineSaves = new Map();
448
473
  pendingInlineMediaSaves = new Map();
449
474
  pendingLogin = null;
@@ -454,6 +479,7 @@ class EinblickEditRuntime {
454
479
  this.chrome = options.chrome ?? 'bar';
455
480
  this.reserveBottomSpace =
456
481
  options.reserveBottomSpace ?? this.chrome === 'bar';
482
+ this.resourceHints = normalizeResourceHints(options.resourceHints);
457
483
  this.locale = resolveEinblickSdkLocale(options.locale);
458
484
  this.messages = getEinblickSdkMessages(this.locale);
459
485
  this.session =
@@ -476,6 +502,10 @@ class EinblickEditRuntime {
476
502
  this.messages = getEinblickSdkMessages(nextLocale);
477
503
  this.refreshLocalizedUi();
478
504
  }
505
+ setResourceHints(hints) {
506
+ this.resourceHints = normalizeResourceHints(hints);
507
+ this.updateBottomBarResources();
508
+ }
479
509
  start() {
480
510
  if (this.started ||
481
511
  typeof window === 'undefined' ||
@@ -508,6 +538,7 @@ class EinblickEditRuntime {
508
538
  if (this.currentInlineTarget && !this.currentInlineTarget.isConnected) {
509
539
  this.closeInlineEditor();
510
540
  }
541
+ this.updateBottomBarResources();
511
542
  });
512
543
  this.mutationObserver.observe(document.body, {
513
544
  childList: true,
@@ -560,7 +591,7 @@ class EinblickEditRuntime {
560
591
  this.bottomBarHost?.remove();
561
592
  this.bottomBarHost = null;
562
593
  this.bottomBarSiteName = null;
563
- this.bottomBarCmsButton = null;
594
+ this.bottomBarResourceList = null;
564
595
  this.bottomBarMoreButton = null;
565
596
  this.bottomBarMoreMenu = null;
566
597
  this.bottomBarOpenAppButton = null;
@@ -942,6 +973,7 @@ class EinblickEditRuntime {
942
973
  collectionId: message.collectionId,
943
974
  intent: message.intent,
944
975
  recordId: message.recordId,
976
+ sourceType: message.sourceType,
945
977
  resourceSlug: message.resourceSlug,
946
978
  });
947
979
  return;
@@ -950,6 +982,7 @@ class EinblickEditRuntime {
950
982
  if (message.resourceSlug) {
951
983
  void this.callbacks.onSave?.({
952
984
  binding: {
985
+ sourceType: message.sourceType ?? 'cms',
953
986
  resourceSlug: message.resourceSlug,
954
987
  recordId: message.recordId ?? '',
955
988
  resourceMode: 'collection',
@@ -957,6 +990,7 @@ class EinblickEditRuntime {
957
990
  },
958
991
  value: {
959
992
  action: message.action,
993
+ sourceType: message.sourceType ?? 'cms',
960
994
  recordId: message.recordId,
961
995
  collectionId: message.collectionId,
962
996
  },
@@ -988,6 +1022,7 @@ class EinblickEditRuntime {
988
1022
  else if (this.editorBinding) {
989
1023
  const nextBinding = {
990
1024
  ...this.editorBinding,
1025
+ sourceType: message.sourceType ?? this.editorBinding.sourceType ?? 'cms',
991
1026
  recordId: message.recordId ?? this.editorBinding.recordId,
992
1027
  };
993
1028
  void this.callbacks.onSave?.({
@@ -1003,6 +1038,7 @@ class EinblickEditRuntime {
1003
1038
  if (this.editorBinding) {
1004
1039
  const nextBinding = {
1005
1040
  ...this.editorBinding,
1041
+ sourceType: message.sourceType ?? this.editorBinding.sourceType ?? 'cms',
1006
1042
  resourceSlug: message.resourceSlug ?? this.editorBinding.resourceSlug,
1007
1043
  recordId: message.recordId,
1008
1044
  };
@@ -1190,8 +1226,6 @@ class EinblickEditRuntime {
1190
1226
  height: ${CONTROL_BAR_HEIGHT}px;
1191
1227
  padding: 0 0.75rem;
1192
1228
  background: ${EINBLICK_ACCENT_COLOR};
1193
- border-top: 1px solid rgba(255, 255, 255, 0.24);
1194
- box-shadow: 0 -8px 24px rgba(15, 23, 42, 0.18);
1195
1229
  }
1196
1230
 
1197
1231
  .brand,
@@ -1221,6 +1255,25 @@ class EinblickEditRuntime {
1221
1255
  font: 700 0.84rem/1.1 system-ui, sans-serif;
1222
1256
  }
1223
1257
 
1258
+ .resources {
1259
+ display: inline-flex;
1260
+ align-items: center;
1261
+ gap: 0.35rem;
1262
+ min-width: 0;
1263
+ max-width: min(48rem, 54vw);
1264
+ overflow-x: auto;
1265
+ scrollbar-width: none;
1266
+ }
1267
+
1268
+ .resources::-webkit-scrollbar {
1269
+ display: none;
1270
+ }
1271
+
1272
+ .resource-button {
1273
+ flex: 0 0 auto;
1274
+ max-width: 12rem;
1275
+ }
1276
+
1224
1277
  button {
1225
1278
  appearance: none;
1226
1279
  display: inline-flex;
@@ -1230,10 +1283,9 @@ class EinblickEditRuntime {
1230
1283
  min-width: 0;
1231
1284
  height: 2rem;
1232
1285
  margin: 0;
1233
- border: 1px solid rgba(255, 255, 255, 0.36);
1234
1286
  border-radius: 0.35rem;
1235
- background: rgba(255, 255, 255, 0.13);
1236
- color: rgb(255, 255, 255);
1287
+ background: #ffffff;
1288
+ color: #fa693e;
1237
1289
  padding: 0 0.7rem;
1238
1290
  font: 700 0.78rem/1 system-ui, sans-serif;
1239
1291
  letter-spacing: 0;
@@ -1252,11 +1304,11 @@ class EinblickEditRuntime {
1252
1304
 
1253
1305
  button:hover,
1254
1306
  button[aria-expanded="true"] {
1255
- background: rgba(255, 255, 255, 0.23);
1307
+ opacity: 0.8;
1256
1308
  }
1257
1309
 
1258
1310
  button:focus-visible {
1259
- outline: 2px solid rgba(255, 255, 255, 0.72);
1311
+ outline: 2px solid #ffffff;
1260
1312
  outline-offset: 2px;
1261
1313
  }
1262
1314
 
@@ -1342,14 +1394,8 @@ class EinblickEditRuntime {
1342
1394
  brand.append(mark, siteName);
1343
1395
  const actions = document.createElement('div');
1344
1396
  actions.className = 'actions';
1345
- const cmsButton = document.createElement('button');
1346
- cmsButton.type = 'button';
1347
- cmsButton.addEventListener('click', (event) => {
1348
- event.preventDefault();
1349
- event.stopPropagation();
1350
- this.setBottomBarMenuOpen(false);
1351
- this.setNavigatorOpen(!this.isNavigatorOpen());
1352
- });
1397
+ const resourceList = document.createElement('div');
1398
+ resourceList.className = 'resources';
1353
1399
  const moreButton = document.createElement('button');
1354
1400
  moreButton.type = 'button';
1355
1401
  moreButton.className = 'secondary icon-button';
@@ -1387,13 +1433,13 @@ class EinblickEditRuntime {
1387
1433
  void this.logoutFromEinblick();
1388
1434
  });
1389
1435
  moreMenu.append(openAppButton, logoutButton);
1390
- actions.append(cmsButton, moreButton);
1436
+ actions.append(resourceList, moreButton);
1391
1437
  bar.append(brand, actions, moreMenu);
1392
1438
  shadowRoot.append(style, bar);
1393
1439
  document.body.append(host);
1394
1440
  this.bottomBarHost = host;
1395
1441
  this.bottomBarSiteName = siteName;
1396
- this.bottomBarCmsButton = cmsButton;
1442
+ this.bottomBarResourceList = resourceList;
1397
1443
  this.bottomBarMoreButton = moreButton;
1398
1444
  this.bottomBarMoreMenu = moreMenu;
1399
1445
  this.bottomBarOpenAppButton = openAppButton;
@@ -1430,6 +1476,79 @@ class EinblickEditRuntime {
1430
1476
  ? this.messages.brand.authenticatedHint
1431
1477
  : this.messages.brand.unauthenticatedHint;
1432
1478
  }
1479
+ collectBottomBarResources() {
1480
+ const resources = new Map();
1481
+ for (const hint of this.resourceHints) {
1482
+ const key = `${hint.sourceType}:${hint.resourceSlug}`;
1483
+ if (hint.showInBottomBar === false) {
1484
+ resources.delete(key);
1485
+ continue;
1486
+ }
1487
+ resources.set(key, hint);
1488
+ }
1489
+ if (typeof document !== 'undefined') {
1490
+ const elements = document.querySelectorAll('[data-einblick-editable="true"][data-einblick-resource]');
1491
+ elements.forEach((element) => {
1492
+ const binding = readBindingFromElement(element);
1493
+ if (!binding?.resourceSlug)
1494
+ return;
1495
+ const sourceType = binding.sourceType ?? 'cms';
1496
+ const key = `${sourceType}:${binding.resourceSlug}`;
1497
+ if (resources.has(key)) {
1498
+ const current = resources.get(key);
1499
+ if (binding.recordId &&
1500
+ !current.recordIds?.includes(binding.recordId)) {
1501
+ current.recordIds = [...(current.recordIds ?? []), binding.recordId];
1502
+ }
1503
+ return;
1504
+ }
1505
+ resources.set(key, {
1506
+ sourceType,
1507
+ resourceSlug: binding.resourceSlug,
1508
+ label: binding.label,
1509
+ mode: binding.resourceMode,
1510
+ recordIds: binding.recordId ? [binding.recordId] : undefined,
1511
+ });
1512
+ });
1513
+ }
1514
+ return [...resources.values()];
1515
+ }
1516
+ updateBottomBarResources() {
1517
+ if (!this.bottomBarResourceList) {
1518
+ return;
1519
+ }
1520
+ this.bottomBarResourceList.replaceChildren();
1521
+ const resources = this.collectBottomBarResources();
1522
+ if (resources.length === 0) {
1523
+ const button = document.createElement('button');
1524
+ button.type = 'button';
1525
+ button.className = 'resource-button';
1526
+ button.textContent = this.messages.actions.cmsCollections;
1527
+ button.setAttribute('aria-expanded', this.isNavigatorOpen() ? 'true' : 'false');
1528
+ button.addEventListener('click', (event) => {
1529
+ event.preventDefault();
1530
+ event.stopPropagation();
1531
+ this.setBottomBarMenuOpen(false);
1532
+ this.setNavigatorOpen(!this.isNavigatorOpen());
1533
+ });
1534
+ this.bottomBarResourceList.append(button);
1535
+ return;
1536
+ }
1537
+ for (const resource of resources) {
1538
+ const button = document.createElement('button');
1539
+ button.type = 'button';
1540
+ button.className = 'resource-button';
1541
+ button.textContent = resource.label ?? resource.resourceSlug;
1542
+ button.title = button.textContent;
1543
+ button.addEventListener('click', (event) => {
1544
+ event.preventDefault();
1545
+ event.stopPropagation();
1546
+ this.setBottomBarMenuOpen(false);
1547
+ this.openNavigator(resource);
1548
+ });
1549
+ this.bottomBarResourceList.append(button);
1550
+ }
1551
+ }
1433
1552
  updateBottomBar() {
1434
1553
  if (!this.bottomBarHost) {
1435
1554
  this.applyBottomLayout(false);
@@ -1449,10 +1568,7 @@ class EinblickEditRuntime {
1449
1568
  this.state.siteName?.trim() || this.messages.brand.connectedSite;
1450
1569
  this.bottomBarSiteName.title = this.bottomBarSiteName.textContent;
1451
1570
  }
1452
- if (this.bottomBarCmsButton) {
1453
- this.bottomBarCmsButton.textContent = this.messages.actions.cmsCollections;
1454
- this.bottomBarCmsButton.setAttribute('aria-expanded', this.isNavigatorOpen() ? 'true' : 'false');
1455
- }
1571
+ this.updateBottomBarResources();
1456
1572
  if (this.bottomBarMoreButton) {
1457
1573
  this.bottomBarMoreButton.setAttribute('aria-label', this.messages.actions.moreActions);
1458
1574
  this.bottomBarMoreButton.setAttribute('aria-expanded', this.isBottomBarMenuOpen() ? 'true' : 'false');
@@ -1464,7 +1580,7 @@ class EinblickEditRuntime {
1464
1580
  if (this.bottomBarLogoutButton) {
1465
1581
  this.bottomBarLogoutButton.textContent = this.messages.actions.logout;
1466
1582
  }
1467
- this.ensureNavigatorPanel();
1583
+ this.ensureNavigatorPanel(false, this.navigatorFilter);
1468
1584
  if (this.navigatorFrame) {
1469
1585
  this.navigatorFrame.title = this.messages.actions.cmsCollections;
1470
1586
  }
@@ -1528,7 +1644,7 @@ class EinblickEditRuntime {
1528
1644
  isNavigatorOpen() {
1529
1645
  return this.navigatorOpen && !!this.navigatorPanel;
1530
1646
  }
1531
- ensureNavigatorPanel(reportErrors = false) {
1647
+ ensureNavigatorPanel(reportErrors = false, filter) {
1532
1648
  if (this.navigatorPanel) {
1533
1649
  return true;
1534
1650
  }
@@ -1538,7 +1654,7 @@ class EinblickEditRuntime {
1538
1654
  let navigatorUrl;
1539
1655
  const nonce = createRandomId();
1540
1656
  try {
1541
- navigatorUrl = this.buildNavigatorUrl(nonce);
1657
+ navigatorUrl = this.buildNavigatorUrl(nonce, filter);
1542
1658
  }
1543
1659
  catch (error) {
1544
1660
  if (reportErrors) {
@@ -1565,18 +1681,22 @@ class EinblickEditRuntime {
1565
1681
  this.navigatorPanel = panel;
1566
1682
  this.navigatorFrame = iframe;
1567
1683
  this.navigatorNonce = nonce;
1684
+ this.navigatorFilter = filter ?? null;
1568
1685
  return true;
1569
1686
  }
1570
- openNavigator() {
1687
+ openNavigator(filter) {
1571
1688
  if (!this.state.isAuthenticated) {
1572
1689
  this.callbacks.onError?.(this.messages.errors.signInToEditContent);
1573
1690
  return;
1574
1691
  }
1575
- if (this.isNavigatorOpen()) {
1692
+ if (this.isNavigatorOpen() && !filter) {
1576
1693
  return;
1577
1694
  }
1695
+ if (this.isNavigatorOpen() && filter) {
1696
+ this.removeNavigatorPanel(false);
1697
+ }
1578
1698
  this.setBottomBarMenuOpen(false);
1579
- if (!this.ensureNavigatorPanel(true) || !this.navigatorPanel) {
1699
+ if (!this.ensureNavigatorPanel(true, filter) || !this.navigatorPanel) {
1580
1700
  return;
1581
1701
  }
1582
1702
  this.navigatorOpen = true;
@@ -1603,6 +1723,7 @@ class EinblickEditRuntime {
1603
1723
  this.navigatorPanel = null;
1604
1724
  this.navigatorFrame = null;
1605
1725
  this.navigatorNonce = null;
1726
+ this.navigatorFilter = null;
1606
1727
  this.navigatorOpen = false;
1607
1728
  if (hadNavigator && updateBottomBar) {
1608
1729
  this.updateBottomBar();
@@ -1945,6 +2066,7 @@ class EinblickEditRuntime {
1945
2066
  url.searchParams.set('nonce', nonce);
1946
2067
  url.searchParams.set('sessionToken', sessionToken);
1947
2068
  url.searchParams.set('returnTo', window.location.href);
2069
+ url.searchParams.set('sourceType', binding.sourceType ?? 'cms');
1948
2070
  url.searchParams.set('resourceSlug', binding.resourceSlug);
1949
2071
  url.searchParams.set('recordId', binding.recordId);
1950
2072
  if (intent === 'create') {
@@ -1955,7 +2077,7 @@ class EinblickEditRuntime {
1955
2077
  }
1956
2078
  return url.toString();
1957
2079
  }
1958
- buildNavigatorUrl(nonce) {
2080
+ buildNavigatorUrl(nonce, filter) {
1959
2081
  const sessionToken = this.getActiveSessionToken();
1960
2082
  if (!sessionToken) {
1961
2083
  throw new Error(this.messages.errors.editSessionExpired);
@@ -1964,6 +2086,15 @@ class EinblickEditRuntime {
1964
2086
  url.searchParams.set('origin', window.location.origin);
1965
2087
  url.searchParams.set('nonce', nonce);
1966
2088
  url.searchParams.set('sessionToken', sessionToken);
2089
+ if (filter?.sourceType) {
2090
+ url.searchParams.set('sourceType', filter.sourceType);
2091
+ }
2092
+ if (filter?.resourceSlug) {
2093
+ url.searchParams.set('resourceSlug', filter.resourceSlug);
2094
+ }
2095
+ if (filter?.recordIds && filter.recordIds.length > 0) {
2096
+ url.searchParams.set('recordIds', filter.recordIds.join(','));
2097
+ }
1967
2098
  return url.toString();
1968
2099
  }
1969
2100
  buildCollectionEditorUrl(args) {
@@ -1976,7 +2107,11 @@ class EinblickEditRuntime {
1976
2107
  url.searchParams.set('nonce', args.nonce);
1977
2108
  url.searchParams.set('sessionToken', sessionToken);
1978
2109
  url.searchParams.set('returnTo', window.location.href);
2110
+ url.searchParams.set('sourceType', args.sourceType ?? 'cms');
1979
2111
  url.searchParams.set('collectionId', args.collectionId);
2112
+ if (args.resourceSlug) {
2113
+ url.searchParams.set('resourceSlug', args.resourceSlug);
2114
+ }
1980
2115
  url.searchParams.set('intent', args.intent);
1981
2116
  if (args.recordId) {
1982
2117
  url.searchParams.set('recordId', args.recordId);
@@ -2008,6 +2143,7 @@ class EinblickEditRuntime {
2008
2143
  }
2009
2144
  const selector = [
2010
2145
  '[data-einblick-editable="true"]',
2146
+ `[data-einblick-source-type="${CSS.escape(binding.sourceType ?? 'cms')}"]`,
2011
2147
  `[data-einblick-resource="${CSS.escape(binding.resourceSlug)}"]`,
2012
2148
  ].join('');
2013
2149
  const elements = document.querySelectorAll(selector);
@@ -2041,6 +2177,7 @@ class EinblickEditRuntime {
2041
2177
  const parentBinding = readBindingFromElement(parent);
2042
2178
  if (parentBinding &&
2043
2179
  !parentBinding.fieldKey &&
2180
+ (parentBinding.sourceType ?? 'cms') === (binding.sourceType ?? 'cms') &&
2044
2181
  parentBinding.resourceSlug === binding.resourceSlug &&
2045
2182
  parentBinding.recordId === binding.recordId) {
2046
2183
  return parent;
@@ -2061,6 +2198,7 @@ class EinblickEditRuntime {
2061
2198
  }
2062
2199
  const selector = [
2063
2200
  '[data-einblick-editable="true"]',
2201
+ `[data-einblick-source-type="${CSS.escape(binding.sourceType ?? 'cms')}"]`,
2064
2202
  `[data-einblick-resource="${CSS.escape(binding.resourceSlug)}"]`,
2065
2203
  `[data-einblick-record-id="${CSS.escape(binding.recordId)}"]`,
2066
2204
  '[data-einblick-field-key]',
@@ -2090,6 +2228,7 @@ class EinblickEditRuntime {
2090
2228
  findElementForBinding(binding) {
2091
2229
  const selector = [
2092
2230
  '[data-einblick-editable="true"]',
2231
+ `[data-einblick-source-type="${CSS.escape(binding.sourceType ?? 'cms')}"]`,
2093
2232
  `[data-einblick-resource="${CSS.escape(binding.resourceSlug)}"]`,
2094
2233
  `[data-einblick-record-id="${CSS.escape(binding.recordId)}"]`,
2095
2234
  binding.fieldKey
@@ -2421,6 +2560,7 @@ class EinblickEditRuntime {
2421
2560
  nonce: this.bridgeNonce,
2422
2561
  requestId,
2423
2562
  payload: {
2563
+ sourceType: binding.sourceType ?? 'cms',
2424
2564
  resourceSlug: binding.resourceSlug,
2425
2565
  recordId: binding.recordId,
2426
2566
  fieldKey: binding.fieldKey,
@@ -2474,6 +2614,7 @@ class EinblickEditRuntime {
2474
2614
  nonce: this.bridgeNonce,
2475
2615
  requestId,
2476
2616
  payload: {
2617
+ sourceType: binding.sourceType ?? 'cms',
2477
2618
  resourceSlug: binding.resourceSlug,
2478
2619
  recordId: binding.recordId,
2479
2620
  fieldKey: binding.fieldKey,
@@ -2542,6 +2683,8 @@ class EinblickEditRuntime {
2542
2683
  nonce,
2543
2684
  intent: args.intent,
2544
2685
  recordId: args.recordId,
2686
+ sourceType: args.sourceType,
2687
+ resourceSlug: args.resourceSlug,
2545
2688
  });
2546
2689
  }
2547
2690
  catch (error) {
@@ -2554,6 +2697,7 @@ class EinblickEditRuntime {
2554
2697
  this.editorTarget = null;
2555
2698
  this.editorBinding = args.resourceSlug
2556
2699
  ? {
2700
+ sourceType: args.sourceType ?? 'cms',
2557
2701
  resourceSlug: args.resourceSlug,
2558
2702
  recordId: args.recordId ?? '',
2559
2703
  resourceMode: 'collection',
@@ -2625,6 +2769,7 @@ export function createEinblickEditRuntime(options) {
2625
2769
  login: (loginOptions) => runtime.login(loginOptions),
2626
2770
  openEditor: (binding, element) => runtime.openEditor(binding, element),
2627
2771
  setLocale: (locale) => runtime.setLocale(locale),
2772
+ setResourceHints: (hints) => runtime.setResourceHints(hints),
2628
2773
  };
2629
2774
  }
2630
2775
  //# sourceMappingURL=runtime.js.map