@plaidev/karte-action-sdk 1.1.179-28041859.8b5339d0 → 1.1.180-28041937.24d05b80

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.es.js CHANGED
@@ -275,13 +275,6 @@ const NOOP = (_args) => { }; // eslint-disable-line @typescript-eslint/no-unused
275
275
  const isPreview = () => {
276
276
  return false;
277
277
  };
278
- // prettier-ignore
279
- /** @internal */
280
- const actionId = typeof __FIX_ACTION_CHANGE_STATE_EVENT__ === 'string'
281
- ? __FIX_ACTION_CHANGE_STATE_EVENT__
282
- : typeof __FLYER_GEN_ACTION_ID_ON_BUILD__ === 'string'
283
- ? __FLYER_GEN_ACTION_ID_ON_BUILD__
284
- : randStr();
285
278
  /** @internal */
286
279
  const setPreviousFocus = () => {
287
280
  const previously_focused = typeof document !== 'undefined' && document.activeElement;
@@ -1008,6 +1001,50 @@ function cloneToJson(data) {
1008
1001
  }
1009
1002
  }
1010
1003
 
1004
+ // prettier-ignore
1005
+ /** @internal */
1006
+ const actionId = typeof __FIX_ACTION_CHANGE_STATE_EVENT__ === 'string'
1007
+ ? __FIX_ACTION_CHANGE_STATE_EVENT__
1008
+ : typeof __FLYER_GEN_ACTION_ID_ON_BUILD__ === 'string'
1009
+ ? __FLYER_GEN_ACTION_ID_ON_BUILD__
1010
+ : randStr();
1011
+ /** @internal */
1012
+ const ACTION_DESTROY_EVENT = `KARTE-ACTION-DESTROY-${actionId}`;
1013
+ /** @internal */
1014
+ const ACTION_SHOW_EVENT = `KARTE-ACTION-SHOW-${actionId}`;
1015
+ /** @internal */
1016
+ const ACTION_CLOSE_EVENT = `KARTE-ACTION-CLOSE-${actionId}`;
1017
+ /** @internal */
1018
+ const ACTION_CHANGE_STATE_EVENT = `KARTE-ACTION-CHANGE-STATE-${actionId}`;
1019
+ /** @internal */
1020
+ const send_event = (event_name, values) => {
1021
+ const setting = getSetting();
1022
+ setting?.send?.(event_name, values);
1023
+ };
1024
+ /** @internal */
1025
+ const initialize = (setting) => {
1026
+ const newSetting = setSetting(setting);
1027
+ if (newSetting.initialState) {
1028
+ setState$1(newSetting.initialState);
1029
+ }
1030
+ setOpened(true);
1031
+ setClosed(false); // deprecated
1032
+ return () => finalize();
1033
+ };
1034
+ /** @internal */
1035
+ const finalize = () => {
1036
+ resetSetting();
1037
+ };
1038
+ /**
1039
+ * Dispatch the event to destroy KARTE action
1040
+ *
1041
+ * @internal
1042
+ */
1043
+ function dispatchDestroyEvent() {
1044
+ const event = new CustomEvent(ACTION_DESTROY_EVENT);
1045
+ window.dispatchEvent(event);
1046
+ }
1047
+
1011
1048
  /**
1012
1049
  * モーダル(ポップアップ)のロジックを管理する
1013
1050
  */
@@ -1155,20 +1192,6 @@ function checkAndDo(checkFn, fn, ...conditionFns) {
1155
1192
  return haveCondition ? cleanupAll : null;
1156
1193
  }
1157
1194
 
1158
- /** @internal */
1159
- const ACTION_DESTROY_EVENT = `KARTE-ACTION-DESTROY-${actionId}`;
1160
- /** @internal */
1161
- const ACTION_SHOW_EVENT = `KARTE-ACTION-SHOW-${actionId}`;
1162
- /** @internal */
1163
- const ACTION_CLOSE_EVENT = `KARTE-ACTION-CLOSE-${actionId}`;
1164
- /** @internal */
1165
- const ACTION_CHANGE_STATE_EVENT = `KARTE-ACTION-CHANGE-STATE-${actionId}`;
1166
- /** @internal */
1167
- const send_event = (event_name, values) => {
1168
- const setting = getSetting();
1169
- setting?.send?.(event_name, values);
1170
- };
1171
-
1172
1195
  /**
1173
1196
  * アクションテーブルに関連するコードの管理
1174
1197
  */
@@ -1224,6 +1247,7 @@ function collection$1(config) {
1224
1247
  },
1225
1248
  };
1226
1249
  }
1250
+ /** @internal */
1227
1251
  function request(url, data, cb) {
1228
1252
  console.debug('[debug] request', isPreview(), url, JSON.stringify(data));
1229
1253
  fetch(url, {
@@ -1251,6 +1275,7 @@ const loadActionTableRows = async (config, api_key, endpoint) => {
1251
1275
  const loadActionTableQuery = async (config, api_key, endpoint) => {
1252
1276
  return new Promise((resolve, reject) => collection$1({ endpoint, api_key, table: config.query.table_name }).getByQuery(config.query.query_name, config.query.params, null, (err, data) => (err ? reject(err) : resolve(data))));
1253
1277
  };
1278
+ /** @internal */
1254
1279
  const loadActionTable = async (config, api_key, endpoint) => {
1255
1280
  console.debug('[debug] loadActionTable', isPreview(), api_key, endpoint, JSON.stringify(config));
1256
1281
  const results = await Promise.all(config
@@ -1276,13 +1301,23 @@ const loadActionTable = async (config, api_key, endpoint) => {
1276
1301
  return acc;
1277
1302
  }, {});
1278
1303
  };
1304
+ /** @internal */
1305
+ async function setupActionTable(localVariablesQuery, apiKey) {
1306
+ const result = await loadActionTable(localVariablesQuery, apiKey);
1307
+ let success = false;
1308
+ if (Object.keys(result).length === localVariablesQuery.length) {
1309
+ setVariables(result);
1310
+ success = true;
1311
+ }
1312
+ return {
1313
+ success,
1314
+ };
1315
+ }
1279
1316
 
1280
1317
  /**
1281
- * Edgeが起動するアクションに関連するコードを管理する
1282
- *
1283
- * アクションのCreate, Destroyの状態はここで管理する。
1318
+ * モーダル(ポップアップ)に関連するコードの管理
1284
1319
  *
1285
- * FIXME: モーダルなどの機能ごとのコードを分離したい
1320
+ * アクションのShow, Close, ChangeStateの状態はここで管理する。
1286
1321
  */
1287
1322
  /** @internal */
1288
1323
  const handleState = (event) => {
@@ -1291,100 +1326,234 @@ const handleState = (event) => {
1291
1326
  setState$1(event.detail.to, { disableInPreview: event.detail.disableInPreview });
1292
1327
  }
1293
1328
  };
1294
- /** @internal */
1295
- const initialize = (setting) => {
1296
- const newSetting = setSetting(setting);
1297
- if (newSetting.initialState) {
1298
- setState$1(newSetting.initialState);
1329
+ /**
1330
+ * アクションが表示 (show) された後にフックする関数
1331
+ *
1332
+ * @param fn - 呼び出されるフック関数
1333
+ *
1334
+ * @public
1335
+ */
1336
+ function onShow(fn) {
1337
+ let { onShowHandlers } = getInternalHandlers();
1338
+ if (!onShowHandlers) {
1339
+ onShowHandlers = [];
1299
1340
  }
1300
- setOpened(true);
1301
- setClosed(false); // deprecated
1302
- return () => finalize();
1303
- };
1304
- /** @internal */
1305
- const finalize = () => {
1306
- resetSetting();
1307
- };
1341
+ onShowHandlers.push(fn);
1342
+ setInternalHandlers({ onShowHandlers });
1343
+ }
1308
1344
  /**
1309
- * アクションを作成する
1345
+ * アクションがクローズ (close) される前にフックする関数
1310
1346
  *
1311
- * @param App - Svelte コンポーネントのエントリポイント
1312
- * @param options - {@link ActionOptions | オプション}
1347
+ * @param fn - 呼び出されるフック関数
1313
1348
  *
1314
- * @returns アクションを破棄する関数
1349
+ * @public
1350
+ */
1351
+ function onClose(fn) {
1352
+ let { onCloseHandlers } = getInternalHandlers();
1353
+ if (!onCloseHandlers) {
1354
+ onCloseHandlers = [];
1355
+ }
1356
+ onCloseHandlers.push(fn);
1357
+ setInternalHandlers({ onCloseHandlers });
1358
+ }
1359
+ /**
1360
+ * アクションのステートが変更された (changeState) 後にフックする関数
1361
+ *
1362
+ * @param fn - 呼び出されるフック関数
1315
1363
  *
1316
1364
  * @public
1317
1365
  */
1318
- function create(App, options = {
1319
- send: () => { },
1320
- publish: () => { },
1321
- props: {},
1322
- variables: {},
1323
- localVariablesQuery: undefined,
1324
- }) {
1325
- let app = null;
1326
- const data = {
1327
- ...options.props,
1328
- ...options.variables,
1329
- ...getVariables(),
1330
- };
1331
- const actionProps = {
1332
- send: options.send,
1333
- publish: options.publish,
1334
- data,
1335
- };
1336
- const handleDestroy = () => {
1337
- const { onDestroyHandlers } = getInternalHandlers();
1338
- onDestroyHandlers?.forEach(h => {
1339
- const actionHookLog = { name: 'onDestroy' };
1340
- console.info(`${ACTION_HOOK_LABEL}:${JSON.stringify(actionHookLog)}`);
1341
- h(actionProps);
1342
- });
1343
- // 旧Widget APIの内部で利用するため、実行ログは出力しない
1344
- const { onDestroyHandlers: onDestroyWidgetHandlers } = getWidgetHandlers();
1345
- if (onDestroyWidgetHandlers) {
1346
- onDestroyWidgetHandlers.forEach(h => h(actionProps));
1347
- }
1348
- };
1349
- const close = (trigger = 'none') => {
1350
- if (!app) {
1351
- return NOOP;
1352
- }
1353
- options.send('message_close', { trigger, state: getState$1() });
1354
- setOpened(false);
1355
- setClosed(true); // deprecated
1356
- const { onCloseHandlers } = getInternalHandlers();
1357
- if (onCloseHandlers) {
1358
- onCloseHandlers.forEach(h => {
1359
- const actionHookLog = { name: 'onClose', values: { trigger } };
1360
- console.info(`${ACTION_HOOK_LABEL}:${JSON.stringify(actionHookLog)}`);
1361
- h({ send: options.send, publish: options.publish, data }, trigger);
1362
- });
1363
- }
1364
- finalize();
1365
- dispatchDestroyEvent();
1366
- app.$destroy();
1367
- app = null;
1368
- return NOOP;
1369
- };
1370
- const handleClose = (event) => {
1371
- const trigger = event?.detail?.trigger ? event.detail.trigger : 'none';
1372
- close(trigger);
1373
- };
1374
- const show = async (trigger = 'none') => {
1375
- if (app) {
1366
+ function onChangeState(fn) {
1367
+ let { onChangeStateHandlers } = getInternalHandlers();
1368
+ if (!onChangeStateHandlers) {
1369
+ onChangeStateHandlers = [];
1370
+ }
1371
+ onChangeStateHandlers.push(fn);
1372
+ setInternalHandlers({ onChangeStateHandlers });
1373
+ }
1374
+ /**
1375
+ * アクションを表示する
1376
+ *
1377
+ * @public
1378
+ */
1379
+ function showAction() {
1380
+ const event = new CustomEvent(ACTION_SHOW_EVENT, { detail: { trigger: 'custom' } });
1381
+ window.dispatchEvent(event);
1382
+ }
1383
+ /**
1384
+ * アクションを閉じる
1385
+ *
1386
+ * @param trigger - 閉じた時のトリガー。デフォルト `'none'`
1387
+ *
1388
+ * @public
1389
+ */
1390
+ function closeAction(trigger = 'none') {
1391
+ const event = new CustomEvent(ACTION_CLOSE_EVENT, { detail: { trigger } });
1392
+ window.dispatchEvent(event);
1393
+ }
1394
+ /**
1395
+ * アクションに CSS を適用する
1396
+ *
1397
+ * @param css - 適用する CSS
1398
+ *
1399
+ * @returns 適用された style 要素を返す Promise
1400
+ *
1401
+ * @public
1402
+ */
1403
+ async function applyCss(css) {
1404
+ return new Promise((resolve, reject) => {
1405
+ const style = document.createElement('style');
1406
+ style.textContent = css;
1407
+ const shadowRoot = getActionRoot();
1408
+ if (!shadowRoot)
1376
1409
  return;
1410
+ shadowRoot.append(style);
1411
+ style.addEventListener('load', () => resolve(style));
1412
+ style.addEventListener('error', () => reject(style));
1413
+ });
1414
+ }
1415
+ async function fixFontFaceIssue(href, cssRules) {
1416
+ const css = new CSSStyleSheet();
1417
+ // @ts-ignore
1418
+ await css.replace(cssRules);
1419
+ const rules = [];
1420
+ const fixedRules = [];
1421
+ Array.from(css.cssRules).forEach(cssRule => {
1422
+ if (cssRule.type !== 5) {
1423
+ rules.push(cssRule.cssText);
1377
1424
  }
1378
- if (trigger === 'custom' && (options.props.show_on_scroll || options.props.show_on_time)) {
1425
+ // type 5 is @font-face
1426
+ const split = href.split('/');
1427
+ const stylePath = split.slice(0, split.length - 1).join('/');
1428
+ const cssText = cssRule.cssText;
1429
+ const newCssText = cssText.replace(
1430
+ // relative paths
1431
+ /url\s*\(\s*['"]?(?!((\/)|((?:https?:)?\/\/)|(?:data:?:)))([^'")]+)['"]?\s*\)/g, `url("${stylePath}/$4")`);
1432
+ if (cssText === newCssText)
1379
1433
  return;
1380
- }
1381
- if (actionTablePromise) {
1382
- const result = await actionTablePromise;
1383
- if (!result.success)
1384
- return;
1385
- }
1386
- options.send('message_open', { state: getState$1() });
1387
- setOpened(true);
1434
+ fixedRules.push(newCssText);
1435
+ });
1436
+ return [rules.join('\n'), fixedRules.join('\n')];
1437
+ }
1438
+ /**
1439
+ * アクションにグローバルなスタイルを読み込む
1440
+ *
1441
+ * @param href - style ファイルのリンク URL
1442
+ *
1443
+ * @public
1444
+ */
1445
+ async function loadStyle(href) {
1446
+ const sr = getActionRoot();
1447
+ if (!sr)
1448
+ return;
1449
+ let cssRules = '';
1450
+ try {
1451
+ const res = await fetch(href);
1452
+ cssRules = await res.text();
1453
+ }
1454
+ catch (e) {
1455
+ // pass
1456
+ }
1457
+ if (!cssRules)
1458
+ return;
1459
+ // Chromeのバグで、Shadow Rootの@font-faceを絶対パスで指定する必要がある
1460
+ // @see https://stackoverflow.com/a/63717709
1461
+ const [rules, fontFaceRules] = await fixFontFaceIssue(href, cssRules);
1462
+ const css = new CSSStyleSheet();
1463
+ // @ts-ignore
1464
+ await css.replace(rules);
1465
+ const fontFaceCss = new CSSStyleSheet();
1466
+ // @ts-ignore
1467
+ await fontFaceCss.replace(fontFaceRules);
1468
+ // @ts-ignore
1469
+ sr.adoptedStyleSheets = [...sr.adoptedStyleSheets, css, fontFaceCss];
1470
+ // Chromeのバグで、ページとShadow Rootの両方に、@font-faceを設定する必要がある
1471
+ // @see https://stackoverflow.com/a/63717709
1472
+ // @ts-ignore
1473
+ document.adoptedStyleSheets = [...document.adoptedStyleSheets, css, fontFaceCss];
1474
+ }
1475
+ // @internal
1476
+ function getCssVariables(data) {
1477
+ return Object.entries(data)
1478
+ .filter(([key, value]) => {
1479
+ return ['string', 'number'].includes(typeof value) && key.startsWith('--');
1480
+ })
1481
+ .map(([key, value]) => `${key}:${value}`)
1482
+ .join(';');
1483
+ }
1484
+ /**
1485
+ * アクションのルートの DOM 要素を取得する
1486
+ *
1487
+ * @returns アクションがルートの DOM 要素 を持つ場合は DOM 要素を返します。ない場合は `null` を返します
1488
+ *
1489
+ * @public
1490
+ */
1491
+ function getActionRoot() {
1492
+ const root = document.querySelector(`.${KARTE_ACTION_ROOT}[data-${KARTE_ACTION_RID}='${actionId}']`);
1493
+ if (!root?.shadowRoot) {
1494
+ return null;
1495
+ }
1496
+ return root.shadowRoot;
1497
+ }
1498
+ /** @internal */
1499
+ function createModal(App, options = {
1500
+ send: () => { },
1501
+ publish: () => { },
1502
+ props: {},
1503
+ variables: {},
1504
+ localVariablesQuery: undefined,
1505
+ karteTemplate: {},
1506
+ }) {
1507
+ let app = null;
1508
+ const data = {
1509
+ ...options.props,
1510
+ ...options.variables,
1511
+ ...getVariables(),
1512
+ };
1513
+ const actionProps = {
1514
+ send: options.send,
1515
+ publish: options.publish,
1516
+ data,
1517
+ };
1518
+ const close = (trigger = 'none') => {
1519
+ if (!app) {
1520
+ return NOOP;
1521
+ }
1522
+ options.send('message_close', { trigger, state: getState$1() });
1523
+ setOpened(false);
1524
+ setClosed(true); // deprecated
1525
+ const { onCloseHandlers } = getInternalHandlers();
1526
+ if (onCloseHandlers) {
1527
+ onCloseHandlers.forEach(h => {
1528
+ const actionHookLog = { name: 'onClose', values: { trigger } };
1529
+ console.info(`${ACTION_HOOK_LABEL}:${JSON.stringify(actionHookLog)}`);
1530
+ h({ send: options.send, publish: options.publish, data }, trigger);
1531
+ });
1532
+ }
1533
+ finalize();
1534
+ dispatchDestroyEvent();
1535
+ app.$destroy();
1536
+ app = null;
1537
+ return NOOP;
1538
+ };
1539
+ const handleClose = (event) => {
1540
+ const trigger = event?.detail?.trigger ? event.detail.trigger : 'none';
1541
+ close(trigger);
1542
+ };
1543
+ const show = async (trigger = 'none') => {
1544
+ if (app) {
1545
+ return;
1546
+ }
1547
+ if (trigger === 'custom' && (options.props.show_on_scroll || options.props.show_on_time)) {
1548
+ return;
1549
+ }
1550
+ if (actionTablePromise) {
1551
+ const result = await actionTablePromise;
1552
+ if (!result.success)
1553
+ return;
1554
+ }
1555
+ options.send('message_open', { state: getState$1() });
1556
+ setOpened(true);
1388
1557
  setClosed(false); // deprecated
1389
1558
  // 非同期処理中にappが初期化されている可能性がある
1390
1559
  if (app) {
@@ -1463,33 +1632,15 @@ function create(App, options = {
1463
1632
  };
1464
1633
  // ここからメインの処理
1465
1634
  initialize({ send: options.send, initialState: data.initial_state });
1466
- setSystem({
1467
- // @ts-ignore
1468
- apiKey: data.api_key || null,
1469
- shortenId: data.shorten_id || null,
1470
- campaignId: data.campaign_id || null,
1471
- });
1472
1635
  // ActionTable APIへの非同期リクエスト
1473
1636
  let actionTablePromise = null;
1474
1637
  if (options.localVariablesQuery && data.api_key) {
1475
- actionTablePromise = (async () => {
1476
- const result = await loadActionTable(options.localVariablesQuery, data.api_key);
1477
- let success = false;
1478
- if (Object.keys(result).length === options.localVariablesQuery.length) {
1479
- setVariables(result);
1480
- success = true;
1481
- }
1482
- return {
1483
- success,
1484
- };
1485
- })();
1638
+ actionTablePromise = setupActionTable(options.localVariablesQuery, data.api_key);
1486
1639
  }
1487
1640
  // NOTE: onCreateより前にListenする必要がある
1488
1641
  window.addEventListener(ACTION_SHOW_EVENT, handleShow);
1489
1642
  window.addEventListener(ACTION_CLOSE_EVENT, handleClose);
1490
1643
  window.addEventListener(ACTION_CHANGE_STATE_EVENT, handleState);
1491
- window.addEventListener(ACTION_DESTROY_EVENT, handleDestroy);
1492
- window.addEventListener('beforeunload', dispatchDestroyEvent, false);
1493
1644
  let showTriggerCleanups = [];
1494
1645
  let closeTriggerCleanups = [];
1495
1646
  {
@@ -1504,7 +1655,6 @@ function create(App, options = {
1504
1655
  console.debug(`${ACTION_HOOK_LABEL}: onCreate`);
1505
1656
  });
1506
1657
  }
1507
- // カスタムスクリプトの処理
1508
1658
  if (options.onCreate) {
1509
1659
  options.onCreate(actionProps);
1510
1660
  }
@@ -1516,8 +1666,6 @@ function create(App, options = {
1516
1666
  window.removeEventListener(ACTION_SHOW_EVENT, handleShow);
1517
1667
  window.removeEventListener(ACTION_CLOSE_EVENT, handleClose);
1518
1668
  window.removeEventListener(ACTION_CHANGE_STATE_EVENT, handleState);
1519
- window.removeEventListener(ACTION_DESTROY_EVENT, handleDestroy);
1520
- window.removeEventListener('beforeunload', dispatchDestroyEvent, false);
1521
1669
  };
1522
1670
  return appCleanup;
1523
1671
  }
@@ -1545,53 +1693,13 @@ function ensureActionRoot(useShadow = true) {
1545
1693
  }
1546
1694
  }
1547
1695
  /**
1548
- * Dispatch the event to destroy KARTE action
1549
- *
1550
- * @internal
1551
- */
1552
- function dispatchDestroyEvent() {
1553
- const event = new CustomEvent(ACTION_DESTROY_EVENT);
1554
- window.dispatchEvent(event);
1555
- }
1556
- /**
1557
- * アクションの破棄する
1558
- *
1559
- * @public
1560
- */
1561
- function destroyAction() {
1562
- setDestroyed(true);
1563
- dispatchDestroyEvent();
1564
- }
1565
- /**
1566
- * アクションが作成 (create) される前にフックする関数
1567
- *
1568
- * @param fn - 呼び出されるフック関数
1569
- *
1570
- * @public
1571
- */
1572
- function onCreate(fn) {
1573
- let { onCreateHandlers } = getInternalHandlers();
1574
- if (!onCreateHandlers) {
1575
- onCreateHandlers = [];
1576
- }
1577
- onCreateHandlers.push(fn);
1578
- setInternalHandlers({ onCreateHandlers });
1579
- }
1580
- /**
1581
- * アクションが破棄 (destroy) される前にフックする関数
1696
+ * 非推奨
1582
1697
  *
1583
- * @param fn - 呼び出されるフック関数
1698
+ * @deprecated 非推奨
1584
1699
  *
1585
- * @public
1700
+ * @internal
1586
1701
  */
1587
- function onDestroy(fn) {
1588
- let { onDestroyHandlers } = getInternalHandlers();
1589
- if (!onDestroyHandlers) {
1590
- onDestroyHandlers = [];
1591
- }
1592
- onDestroyHandlers.push(fn);
1593
- setInternalHandlers({ onDestroyHandlers });
1594
- }
1702
+ const show = showAction;
1595
1703
  /**
1596
1704
  * 非推奨
1597
1705
  *
@@ -1599,7 +1707,7 @@ function onDestroy(fn) {
1599
1707
  *
1600
1708
  * @internal
1601
1709
  */
1602
- const showModal = create;
1710
+ const close = closeAction;
1603
1711
  /**
1604
1712
  * 非推奨
1605
1713
  *
@@ -1656,17 +1764,6 @@ function createApp(App, options = {
1656
1764
  },
1657
1765
  };
1658
1766
  }
1659
- /**
1660
- * 非推奨
1661
- *
1662
- * @deprecated 非推奨
1663
- *
1664
- * @internal
1665
- */
1666
- function destroy() {
1667
- setDestroyed(true);
1668
- dispatchDestroyEvent();
1669
- }
1670
1767
  /**
1671
1768
  * 非推奨
1672
1769
  *
@@ -1703,6 +1800,42 @@ function createFog({ color = '#000', opacity = '50%', zIndex = 999, onclick, })
1703
1800
  /**
1704
1801
  * スクリプト接客が利用するコードの管理
1705
1802
  */
1803
+ /** @internal */
1804
+ async function runScript$1(options = {
1805
+ send: () => { },
1806
+ publish: () => { },
1807
+ props: {},
1808
+ variables: {},
1809
+ localVariablesQuery: undefined,
1810
+ karteTemplate: {},
1811
+ }) {
1812
+ if (!options.onCreate)
1813
+ return;
1814
+ const data = {
1815
+ ...options.props,
1816
+ ...options.variables,
1817
+ ...getVariables(),
1818
+ };
1819
+ const actionProps = {
1820
+ send: options.send,
1821
+ publish: options.publish,
1822
+ data,
1823
+ };
1824
+ initialize({ send: options.send, initialState: data.initial_state });
1825
+ const { success } = await setupActionTable(options.localVariablesQuery, data.api_key);
1826
+ if (!success)
1827
+ return;
1828
+ // 旧Widget API IFの処理
1829
+ const { onCreateHandlers } = getInternalHandlers();
1830
+ if (onCreateHandlers) {
1831
+ onCreateHandlers.forEach(h => {
1832
+ h({ send: options.send, publish: options.publish, data });
1833
+ console.debug(`${ACTION_HOOK_LABEL}: onCreate`);
1834
+ });
1835
+ }
1836
+ options.onCreate(actionProps);
1837
+ finalize();
1838
+ }
1706
1839
  /**
1707
1840
  * ES Modules に対応していない JavaScript をページに読み込む
1708
1841
  *
@@ -1763,178 +1896,110 @@ async function loadGlobalStyle(href) {
1763
1896
  }
1764
1897
 
1765
1898
  /**
1766
- * モーダル(ポップアップ)に関連するコードの管理
1899
+ * Edgeが起動するアクションに関連するコードを管理する
1767
1900
  *
1768
- * アクションのShow, Close, ChangeStateの状態はここで管理する。
1901
+ * アクションのCreate, Destroyの状態はここで管理する。
1769
1902
  */
1770
1903
  /**
1771
- * アクションが表示 (show) された後にフックする関数
1772
- *
1773
- * @param fn - 呼び出されるフック関数
1904
+ * アクションを作成する
1774
1905
  *
1775
- * @public
1776
- */
1777
- function onShow(fn) {
1778
- let { onShowHandlers } = getInternalHandlers();
1779
- if (!onShowHandlers) {
1780
- onShowHandlers = [];
1781
- }
1782
- onShowHandlers.push(fn);
1783
- setInternalHandlers({ onShowHandlers });
1784
- }
1785
- /**
1786
- * アクションがクローズ (close) される前にフックする関数
1906
+ * @param App - Svelte コンポーネントのエントリポイント
1907
+ * @param options - {@link ActionOptions | オプション}
1787
1908
  *
1788
- * @param fn - 呼び出されるフック関数
1909
+ * @returns アクションを破棄する関数
1789
1910
  *
1790
1911
  * @public
1791
1912
  */
1792
- function onClose(fn) {
1793
- let { onCloseHandlers } = getInternalHandlers();
1794
- if (!onCloseHandlers) {
1795
- onCloseHandlers = [];
1913
+ function create(App, options = {
1914
+ send: () => { },
1915
+ publish: () => { },
1916
+ props: {},
1917
+ variables: {},
1918
+ localVariablesQuery: undefined,
1919
+ karteTemplate: {},
1920
+ }) {
1921
+ const data = {
1922
+ ...options.props,
1923
+ ...options.variables,
1924
+ ...getVariables(),
1925
+ };
1926
+ const actionProps = {
1927
+ send: options.send,
1928
+ publish: options.publish,
1929
+ data,
1930
+ };
1931
+ const handleDestroy = () => {
1932
+ const { onDestroyHandlers } = getInternalHandlers();
1933
+ onDestroyHandlers?.forEach(h => {
1934
+ const actionHookLog = { name: 'onDestroy' };
1935
+ console.info(`${ACTION_HOOK_LABEL}:${JSON.stringify(actionHookLog)}`);
1936
+ h(actionProps);
1937
+ });
1938
+ // 旧Widget APIの内部で利用するため、実行ログは出力しない
1939
+ const { onDestroyHandlers: onDestroyWidgetHandlers } = getWidgetHandlers();
1940
+ if (onDestroyWidgetHandlers) {
1941
+ onDestroyWidgetHandlers.forEach(h => h(actionProps));
1942
+ }
1943
+ };
1944
+ // ここからメインの処理
1945
+ setSystem({
1946
+ // @ts-ignore
1947
+ apiKey: data.api_key || null,
1948
+ shortenId: data.shorten_id || null,
1949
+ campaignId: data.campaign_id || null,
1950
+ });
1951
+ window.addEventListener(ACTION_DESTROY_EVENT, handleDestroy);
1952
+ window.addEventListener('beforeunload', dispatchDestroyEvent, false);
1953
+ let modalCleanup = NOOP;
1954
+ if (options.karteTemplate?.template_type === 'script') {
1955
+ runScript$1(options);
1796
1956
  }
1797
- onCloseHandlers.push(fn);
1798
- setInternalHandlers({ onCloseHandlers });
1799
- }
1800
- /**
1801
- * アクションのステートが変更された (changeState) 後にフックする関数
1802
- *
1803
- * @param fn - 呼び出されるフック関数
1804
- *
1805
- * @public
1806
- */
1807
- function onChangeState(fn) {
1808
- let { onChangeStateHandlers } = getInternalHandlers();
1809
- if (!onChangeStateHandlers) {
1810
- onChangeStateHandlers = [];
1957
+ else {
1958
+ modalCleanup = createModal(App, options);
1811
1959
  }
1812
- onChangeStateHandlers.push(fn);
1813
- setInternalHandlers({ onChangeStateHandlers });
1814
- }
1815
- /**
1816
- * アクションを表示する
1817
- *
1818
- * @public
1819
- */
1820
- function showAction() {
1821
- const event = new CustomEvent(ACTION_SHOW_EVENT, { detail: { trigger: 'custom' } });
1822
- window.dispatchEvent(event);
1823
- }
1824
- /**
1825
- * アクションを閉じる
1826
- *
1827
- * @param trigger - 閉じた時のトリガー。デフォルト `'none'`
1828
- *
1829
- * @public
1830
- */
1831
- function closeAction(trigger = 'none') {
1832
- const event = new CustomEvent(ACTION_CLOSE_EVENT, { detail: { trigger } });
1833
- window.dispatchEvent(event);
1960
+ return () => {
1961
+ modalCleanup();
1962
+ window.removeEventListener(ACTION_DESTROY_EVENT, handleDestroy);
1963
+ };
1834
1964
  }
1835
1965
  /**
1836
- * アクションに CSS を適用する
1837
- *
1838
- * @param css - 適用する CSS
1839
- *
1840
- * @returns 適用された style 要素を返す Promise
1966
+ * アクションの破棄する
1841
1967
  *
1842
1968
  * @public
1843
1969
  */
1844
- async function applyCss(css) {
1845
- return new Promise((resolve, reject) => {
1846
- const style = document.createElement('style');
1847
- style.textContent = css;
1848
- const shadowRoot = getActionRoot();
1849
- if (!shadowRoot)
1850
- return;
1851
- shadowRoot.append(style);
1852
- style.addEventListener('load', () => resolve(style));
1853
- style.addEventListener('error', () => reject(style));
1854
- });
1855
- }
1856
- async function fixFontFaceIssue(href, cssRules) {
1857
- const css = new CSSStyleSheet();
1858
- // @ts-ignore
1859
- await css.replace(cssRules);
1860
- const rules = [];
1861
- const fixedRules = [];
1862
- Array.from(css.cssRules).forEach(cssRule => {
1863
- if (cssRule.type !== 5) {
1864
- rules.push(cssRule.cssText);
1865
- }
1866
- // type 5 is @font-face
1867
- const split = href.split('/');
1868
- const stylePath = split.slice(0, split.length - 1).join('/');
1869
- const cssText = cssRule.cssText;
1870
- const newCssText = cssText.replace(
1871
- // relative paths
1872
- /url\s*\(\s*['"]?(?!((\/)|((?:https?:)?\/\/)|(?:data:?:)))([^'")]+)['"]?\s*\)/g, `url("${stylePath}/$4")`);
1873
- if (cssText === newCssText)
1874
- return;
1875
- fixedRules.push(newCssText);
1876
- });
1877
- return [rules.join('\n'), fixedRules.join('\n')];
1970
+ function destroyAction() {
1971
+ setDestroyed(true);
1972
+ dispatchDestroyEvent();
1878
1973
  }
1879
1974
  /**
1880
- * アクションにグローバルなスタイルを読み込む
1975
+ * アクションが作成 (create) される前にフックする関数
1881
1976
  *
1882
- * @param href - style ファイルのリンク URL
1977
+ * @param fn - 呼び出されるフック関数
1883
1978
  *
1884
1979
  * @public
1885
1980
  */
1886
- async function loadStyle(href) {
1887
- const sr = getActionRoot();
1888
- if (!sr)
1889
- return;
1890
- let cssRules = '';
1891
- try {
1892
- const res = await fetch(href);
1893
- cssRules = await res.text();
1894
- }
1895
- catch (e) {
1896
- // pass
1981
+ function onCreate(fn) {
1982
+ let { onCreateHandlers } = getInternalHandlers();
1983
+ if (!onCreateHandlers) {
1984
+ onCreateHandlers = [];
1897
1985
  }
1898
- if (!cssRules)
1899
- return;
1900
- // Chromeのバグで、Shadow Rootの@font-faceを絶対パスで指定する必要がある
1901
- // @see https://stackoverflow.com/a/63717709
1902
- const [rules, fontFaceRules] = await fixFontFaceIssue(href, cssRules);
1903
- const css = new CSSStyleSheet();
1904
- // @ts-ignore
1905
- await css.replace(rules);
1906
- const fontFaceCss = new CSSStyleSheet();
1907
- // @ts-ignore
1908
- await fontFaceCss.replace(fontFaceRules);
1909
- // @ts-ignore
1910
- sr.adoptedStyleSheets = [...sr.adoptedStyleSheets, css, fontFaceCss];
1911
- // Chromeのバグで、ページとShadow Rootの両方に、@font-faceを設定する必要がある
1912
- // @see https://stackoverflow.com/a/63717709
1913
- // @ts-ignore
1914
- document.adoptedStyleSheets = [...document.adoptedStyleSheets, css, fontFaceCss];
1915
- }
1916
- // @internal
1917
- function getCssVariables(data) {
1918
- return Object.entries(data)
1919
- .filter(([key, value]) => {
1920
- return ['string', 'number'].includes(typeof value) && key.startsWith('--');
1921
- })
1922
- .map(([key, value]) => `${key}:${value}`)
1923
- .join(';');
1986
+ onCreateHandlers.push(fn);
1987
+ setInternalHandlers({ onCreateHandlers });
1924
1988
  }
1925
1989
  /**
1926
- * アクションのルートの DOM 要素を取得する
1990
+ * アクションが破棄 (destroy) される前にフックする関数
1927
1991
  *
1928
- * @returns アクションがルートの DOM 要素 を持つ場合は DOM 要素を返します。ない場合は `null` を返します
1992
+ * @param fn - 呼び出されるフック関数
1929
1993
  *
1930
1994
  * @public
1931
1995
  */
1932
- function getActionRoot() {
1933
- const root = document.querySelector(`.${KARTE_ACTION_ROOT}[data-${KARTE_ACTION_RID}='${actionId}']`);
1934
- if (!root?.shadowRoot) {
1935
- return null;
1996
+ function onDestroy(fn) {
1997
+ let { onDestroyHandlers } = getInternalHandlers();
1998
+ if (!onDestroyHandlers) {
1999
+ onDestroyHandlers = [];
1936
2000
  }
1937
- return root.shadowRoot;
2001
+ onDestroyHandlers.push(fn);
2002
+ setInternalHandlers({ onDestroyHandlers });
1938
2003
  }
1939
2004
  // -------- The following codes are deprecated --------
1940
2005
  /**
@@ -1944,7 +2009,7 @@ function getActionRoot() {
1944
2009
  *
1945
2010
  * @internal
1946
2011
  */
1947
- const show = showAction;
2012
+ const showModal = create;
1948
2013
  /**
1949
2014
  * 非推奨
1950
2015
  *
@@ -1952,7 +2017,10 @@ const show = showAction;
1952
2017
  *
1953
2018
  * @internal
1954
2019
  */
1955
- const close = closeAction;
2020
+ function destroy() {
2021
+ setDestroyed(true);
2022
+ dispatchDestroyEvent();
2023
+ }
1956
2024
 
1957
2025
  /**
1958
2026
  * エディタv1のWidget API 互換のインターフェース
@@ -2805,13 +2873,13 @@ function customAnimation(node, { transform, animationStyle, delay = 0, duration
2805
2873
  };
2806
2874
  }
2807
2875
 
2808
- /* src/components/BackgroundOverray.svelte generated by Svelte v3.53.1 */
2876
+ /* src/components/BackgroundOverlay.svelte generated by Svelte v3.53.1 */
2809
2877
 
2810
2878
  function add_css$s(target) {
2811
2879
  append_styles(target, "svelte-1d4fta", ".background.svelte-1d4fta{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0, 0, 0, 0.3);z-index:2147483646}");
2812
2880
  }
2813
2881
 
2814
- // (9:0) {#if backgroundOverray}
2882
+ // (9:0) {#if backgroundOverlay}
2815
2883
  function create_if_block$7(ctx) {
2816
2884
  let div;
2817
2885
  let mounted;
@@ -2841,7 +2909,7 @@ function create_if_block$7(ctx) {
2841
2909
 
2842
2910
  function create_fragment$v(ctx) {
2843
2911
  let if_block_anchor;
2844
- let if_block = /*backgroundOverray*/ ctx[0] && create_if_block$7(ctx);
2912
+ let if_block = /*backgroundOverlay*/ ctx[0] && create_if_block$7(ctx);
2845
2913
 
2846
2914
  return {
2847
2915
  c() {
@@ -2853,7 +2921,7 @@ function create_fragment$v(ctx) {
2853
2921
  insert(target, if_block_anchor, anchor);
2854
2922
  },
2855
2923
  p(ctx, [dirty]) {
2856
- if (/*backgroundOverray*/ ctx[0]) {
2924
+ if (/*backgroundOverlay*/ ctx[0]) {
2857
2925
  if (if_block) {
2858
2926
  if_block.p(ctx, dirty);
2859
2927
  } else {
@@ -2876,21 +2944,21 @@ function create_fragment$v(ctx) {
2876
2944
  }
2877
2945
 
2878
2946
  function instance$v($$self, $$props, $$invalidate) {
2879
- let { backgroundOverray = false } = $$props;
2947
+ let { backgroundOverlay = false } = $$props;
2880
2948
  const dispatch = createEventDispatcher();
2881
2949
  const click_handler = () => dispatch('click');
2882
2950
 
2883
2951
  $$self.$$set = $$props => {
2884
- if ('backgroundOverray' in $$props) $$invalidate(0, backgroundOverray = $$props.backgroundOverray);
2952
+ if ('backgroundOverlay' in $$props) $$invalidate(0, backgroundOverlay = $$props.backgroundOverlay);
2885
2953
  };
2886
2954
 
2887
- return [backgroundOverray, dispatch, click_handler];
2955
+ return [backgroundOverlay, dispatch, click_handler];
2888
2956
  }
2889
2957
 
2890
- class BackgroundOverray extends SvelteComponent {
2958
+ class BackgroundOverlay extends SvelteComponent {
2891
2959
  constructor(options) {
2892
2960
  super();
2893
- init(this, options, instance$v, create_fragment$v, safe_not_equal, { backgroundOverray: 0 }, add_css$s);
2961
+ init(this, options, instance$v, create_fragment$v, safe_not_equal, { backgroundOverlay: 0 }, add_css$s);
2894
2962
  }
2895
2963
  }
2896
2964
 
@@ -3603,20 +3671,20 @@ function create_default_slot$6(ctx) {
3603
3671
  }
3604
3672
 
3605
3673
  function create_fragment$t(ctx) {
3606
- let backgroundoverray;
3674
+ let backgroundoverlay;
3607
3675
  let t;
3608
3676
  let if_block_anchor;
3609
3677
  let current;
3610
3678
  let mounted;
3611
3679
  let dispose;
3612
3680
 
3613
- backgroundoverray = new BackgroundOverray({
3681
+ backgroundoverlay = new BackgroundOverlay({
3614
3682
  props: {
3615
- backgroundOverray: /*backgroundOverray*/ ctx[10]
3683
+ backgroundOverlay: /*backgroundOverlay*/ ctx[10]
3616
3684
  }
3617
3685
  });
3618
3686
 
3619
- backgroundoverray.$on("click", function () {
3687
+ backgroundoverlay.$on("click", function () {
3620
3688
  if (is_function(/*backgroundClick*/ ctx[18])) /*backgroundClick*/ ctx[18].apply(this, arguments);
3621
3689
  });
3622
3690
 
@@ -3624,13 +3692,13 @@ function create_fragment$t(ctx) {
3624
3692
 
3625
3693
  return {
3626
3694
  c() {
3627
- create_component(backgroundoverray.$$.fragment);
3695
+ create_component(backgroundoverlay.$$.fragment);
3628
3696
  t = space();
3629
3697
  if (if_block) if_block.c();
3630
3698
  if_block_anchor = empty();
3631
3699
  },
3632
3700
  m(target, anchor) {
3633
- mount_component(backgroundoverray, target, anchor);
3701
+ mount_component(backgroundoverlay, target, anchor);
3634
3702
  insert(target, t, anchor);
3635
3703
  if (if_block) if_block.m(target, anchor);
3636
3704
  insert(target, if_block_anchor, anchor);
@@ -3646,9 +3714,9 @@ function create_fragment$t(ctx) {
3646
3714
  },
3647
3715
  p(new_ctx, [dirty]) {
3648
3716
  ctx = new_ctx;
3649
- const backgroundoverray_changes = {};
3650
- if (dirty & /*backgroundOverray*/ 1024) backgroundoverray_changes.backgroundOverray = /*backgroundOverray*/ ctx[10];
3651
- backgroundoverray.$set(backgroundoverray_changes);
3717
+ const backgroundoverlay_changes = {};
3718
+ if (dirty & /*backgroundOverlay*/ 1024) backgroundoverlay_changes.backgroundOverlay = /*backgroundOverlay*/ ctx[10];
3719
+ backgroundoverlay.$set(backgroundoverlay_changes);
3652
3720
 
3653
3721
  if (/*visible*/ ctx[12]) {
3654
3722
  if (if_block) {
@@ -3675,17 +3743,17 @@ function create_fragment$t(ctx) {
3675
3743
  },
3676
3744
  i(local) {
3677
3745
  if (current) return;
3678
- transition_in(backgroundoverray.$$.fragment, local);
3746
+ transition_in(backgroundoverlay.$$.fragment, local);
3679
3747
  transition_in(if_block);
3680
3748
  current = true;
3681
3749
  },
3682
3750
  o(local) {
3683
- transition_out(backgroundoverray.$$.fragment, local);
3751
+ transition_out(backgroundoverlay.$$.fragment, local);
3684
3752
  transition_out(if_block);
3685
3753
  current = false;
3686
3754
  },
3687
3755
  d(detaching) {
3688
- destroy_component(backgroundoverray, detaching);
3756
+ destroy_component(backgroundoverlay, detaching);
3689
3757
  if (detaching) detach(t);
3690
3758
  if (if_block) if_block.d(detaching);
3691
3759
  if (detaching) detach(if_block_anchor);
@@ -3722,7 +3790,7 @@ function instance$t($$self, $$props, $$invalidate) {
3722
3790
  let { closeEventValue = null } = $$props;
3723
3791
  let { closeButtonColor = '#000000' } = $$props;
3724
3792
  let { _closeStyle = '' } = $$props;
3725
- let backgroundOverray = DefaultModalPlacement.backgroundOverlay;
3793
+ let backgroundOverlay = DefaultModalPlacement.backgroundOverlay;
3726
3794
  let backgroundClickFunction = DefaultModalPlacement.backgroundClick;
3727
3795
  let modal;
3728
3796
 
@@ -3773,7 +3841,7 @@ function instance$t($$self, $$props, $$invalidate) {
3773
3841
  if ($$self.$$.dirty & /*placement*/ 2097152) {
3774
3842
  {
3775
3843
  if (placement && placement.backgroundOverlay) {
3776
- $$invalidate(10, backgroundOverray = placement.backgroundOverlay);
3844
+ $$invalidate(10, backgroundOverlay = placement.backgroundOverlay);
3777
3845
  }
3778
3846
  }
3779
3847
  }
@@ -3845,7 +3913,7 @@ function instance$t($$self, $$props, $$invalidate) {
3845
3913
  closeEventValue,
3846
3914
  closeButtonColor,
3847
3915
  _closeStyle,
3848
- backgroundOverray,
3916
+ backgroundOverlay,
3849
3917
  modal,
3850
3918
  visible,
3851
3919
  handle_keydown,