@mantou/gem 1.7.8 → 1.7.10

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.
Files changed (69) hide show
  1. package/dist/gem.es.js +246 -113
  2. package/dist/gem.umd.js +24 -24
  3. package/elements/base/dialog.d.ts.map +1 -1
  4. package/elements/base/dialog.js +1 -1
  5. package/elements/base/dialog.js.map +1 -1
  6. package/elements/base/gesture.d.ts.map +1 -1
  7. package/elements/base/gesture.js +7 -1
  8. package/elements/base/gesture.js.map +1 -1
  9. package/elements/base/link.d.ts.map +1 -1
  10. package/elements/base/link.js +8 -4
  11. package/elements/base/link.js.map +1 -1
  12. package/elements/base/modal-factory.d.ts +28 -6
  13. package/elements/base/modal-factory.d.ts.map +1 -1
  14. package/elements/base/reflect.d.ts +8 -0
  15. package/elements/base/reflect.d.ts.map +1 -1
  16. package/elements/base/reflect.js +36 -9
  17. package/elements/base/reflect.js.map +1 -1
  18. package/elements/base/route.d.ts +38 -10
  19. package/elements/base/route.d.ts.map +1 -1
  20. package/elements/base/route.js +119 -73
  21. package/elements/base/route.js.map +1 -1
  22. package/elements/base/title.d.ts.map +1 -1
  23. package/elements/base/title.js +8 -2
  24. package/elements/base/title.js.map +1 -1
  25. package/helper/i18n.d.ts +8 -1
  26. package/helper/i18n.d.ts.map +1 -1
  27. package/helper/i18n.js +7 -3
  28. package/helper/i18n.js.map +1 -1
  29. package/helper/logger.d.ts +9 -0
  30. package/helper/logger.d.ts.map +1 -0
  31. package/helper/logger.js +16 -0
  32. package/helper/logger.js.map +1 -0
  33. package/helper/ssr-shim.d.ts.map +1 -1
  34. package/helper/ssr-shim.js +12 -4
  35. package/helper/ssr-shim.js.map +1 -1
  36. package/lib/element.d.ts +5 -5
  37. package/lib/element.d.ts.map +1 -1
  38. package/lib/element.js +40 -14
  39. package/lib/element.js.map +1 -1
  40. package/lib/history.d.ts +3 -2
  41. package/lib/history.d.ts.map +1 -1
  42. package/lib/history.js +22 -9
  43. package/lib/history.js.map +1 -1
  44. package/lib/utils.d.ts +2 -1
  45. package/lib/utils.d.ts.map +1 -1
  46. package/lib/utils.js +10 -8
  47. package/lib/utils.js.map +1 -1
  48. package/lib/version.d.ts +1 -1
  49. package/lib/version.d.ts.map +1 -1
  50. package/lib/version.js +1 -1
  51. package/lib/version.js.map +1 -1
  52. package/package.json +2 -2
  53. package/src/elements/base/dialog.ts +4 -1
  54. package/src/elements/base/gesture.ts +6 -1
  55. package/src/elements/base/link.ts +8 -4
  56. package/src/elements/base/reflect.ts +43 -9
  57. package/src/elements/base/route.ts +130 -73
  58. package/src/elements/base/title.ts +9 -2
  59. package/src/helper/i18n.ts +12 -4
  60. package/src/helper/logger.ts +21 -0
  61. package/src/helper/ssr-shim.ts +14 -4
  62. package/src/lib/element.ts +46 -17
  63. package/src/lib/history.ts +30 -12
  64. package/src/lib/utils.ts +16 -9
  65. package/src/lib/version.ts +1 -1
  66. package/src/test/elements/link.test.ts +15 -0
  67. package/src/test/elements/reflect.test.ts +27 -0
  68. package/src/test/elements/title.test.ts +25 -0
  69. package/src/test/utils.test.ts +14 -0
package/dist/gem.es.js CHANGED
@@ -874,7 +874,11 @@ function addMicrotaskToStack(func) {
874
874
  }
875
875
  function absoluteLocation(currentPath = "", relativePath = "") {
876
876
  const { pathname, search, hash } = new URL(relativePath, location.origin + currentPath);
877
- return pathname + search + hash;
877
+ return pathname + search + decodeURIComponent(hash);
878
+ }
879
+ function addListener(target, type, listener, options) {
880
+ target.addEventListener(type, listener, options);
881
+ return () => target.removeEventListener(type, listener, options);
878
882
  }
879
883
  class LinkedList extends EventTarget {
880
884
  constructor() {
@@ -1049,12 +1053,10 @@ function createCSSSheet(rules, mediaQuery2 = "") {
1049
1053
  sheet[SheetToken] = styleSheet;
1050
1054
  return sheet;
1051
1055
  }
1052
- function randomStr(number = 5, origin = "0123456789abcdefghijklmnopqrstuvwxyz") {
1053
- const len = origin.length;
1054
- let str = "";
1055
- for (let i = 0; i < number; i++) {
1056
- str += origin[Math.floor(Math.random() * len)];
1057
- }
1056
+ function randomStr(len = 5) {
1057
+ const str = Math.random().toString(36).slice(2).slice(0, len);
1058
+ if (str.length < len)
1059
+ return str + randomStr(len - str.length);
1058
1060
  return str;
1059
1061
  }
1060
1062
  const nestingRuleRegExp = new RegExp("&.*{((.|\n)*)}", "g");
@@ -1175,7 +1177,7 @@ function disconnect(store2, func) {
1175
1177
  const listeners = StoreListenerMap.get(store2);
1176
1178
  listeners == null ? void 0 : listeners.delete(func);
1177
1179
  }
1178
- const version = "1.7.8";
1180
+ const version = "1.7.10";
1179
1181
  var VersionExports = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1180
1182
  __proto__: null,
1181
1183
  version
@@ -1390,7 +1392,7 @@ var __privateSet$1 = (obj, member, value, setter) => {
1390
1392
  setter ? setter.call(obj, value) : member.set(obj, value);
1391
1393
  return value;
1392
1394
  };
1393
- var _final, _renderRoot, _internals, _isAppendReason, _isMounted, _isAsync, _effectList, _memoList, _unmountCallback, _exec, _execEffect, _execMemo, _initEffect, _render, _shouldUpdate, _updateCallback, _update, _updated, _disconnectStore, _connectedCallback, _filterEffect;
1395
+ var _final, _renderRoot, _internals, _isAppendReason, _isMounted, _isAsync, _effectList, _memoList, _unmountCallback, _exec, _execEffect, _execMemo, _initEffect, _render, _shouldUpdate, _updateCallback, _update, _updated, _disconnectStore, _connectedCallback, _clearEffect;
1394
1396
  function emptyFunction() {
1395
1397
  }
1396
1398
  function execCallback(fun) {
@@ -1411,7 +1413,7 @@ const constructorSymbol = Symbol("constructor");
1411
1413
  const initSymbol = Symbol("init");
1412
1414
  const updateSymbol = Symbol("update");
1413
1415
  const _GemElement = class extends HTMLElement {
1414
- constructor({ isAsync, isLight, delegatesFocus, slotAssignment } = {}) {
1416
+ constructor(options = {}) {
1415
1417
  super();
1416
1418
  __privateAdd$1(this, _renderRoot, void 0);
1417
1419
  __privateAdd$1(this, _internals, void 0);
@@ -1481,8 +1483,8 @@ const _GemElement = class extends HTMLElement {
1481
1483
  });
1482
1484
  __privateAdd$1(this, _render, () => {
1483
1485
  __privateGet$1(this, _execMemo).call(this);
1484
- const isLight2 = __privateGet$1(this, _renderRoot) === this;
1485
- const temp = this.render ? this.render() : isLight2 ? void 0 : html`<slot></slot>`;
1486
+ const isLight = __privateGet$1(this, _renderRoot) === this;
1487
+ const temp = this.render ? this.render() : isLight ? void 0 : html`<slot></slot>`;
1486
1488
  if (temp === void 0)
1487
1489
  return;
1488
1490
  render(temp, __privateGet$1(this, _renderRoot));
@@ -1530,9 +1532,12 @@ const _GemElement = class extends HTMLElement {
1530
1532
  throw new GemError(`not allow current root type`);
1531
1533
  }
1532
1534
  });
1533
- __privateAdd$1(this, _filterEffect, (e) => {
1534
- e.initialized = false;
1535
- return e.inConstructor;
1535
+ __privateAdd$1(this, _clearEffect, (list) => {
1536
+ return list == null ? void 0 : list.filter((e) => {
1537
+ execCallback(e.preCallback);
1538
+ e.initialized = false;
1539
+ return e.inConstructor;
1540
+ });
1536
1541
  });
1537
1542
  addMicrotask(() => Reflect.set(this, initSymbol, false));
1538
1543
  Reflect.set(this, constructorSymbol, true);
@@ -1542,8 +1547,29 @@ const _GemElement = class extends HTMLElement {
1542
1547
  addMicrotask(__privateGet$1(this, _update));
1543
1548
  }
1544
1549
  });
1545
- __privateSet$1(this, _isAsync, isAsync);
1546
- __privateSet$1(this, _renderRoot, isLight ? this : this.attachShadow({ mode: "open", delegatesFocus, slotAssignment }));
1550
+ __privateSet$1(this, _isAsync, options.isAsync);
1551
+ __privateSet$1(this, _renderRoot, options.isLight ? this : this.attachShadow({
1552
+ mode: options.mode || "open",
1553
+ delegatesFocus: options.delegatesFocus,
1554
+ slotAssignment: options.slotAssignment
1555
+ }));
1556
+ let hasInitTabIndex;
1557
+ this.effect(
1558
+ ([disabled = false]) => {
1559
+ if (hasInitTabIndex === void 0)
1560
+ hasInitTabIndex = this.hasAttribute("tabindex");
1561
+ this.internals.ariaDisabled = String(disabled);
1562
+ if (options.focusable && !hasInitTabIndex) {
1563
+ this.tabIndex = -Number(disabled);
1564
+ }
1565
+ if ((options.focusable || options.delegatesFocus) && disabled) {
1566
+ return addListener(this, "click", (e) => e.isTrusted && e.stopImmediatePropagation(), {
1567
+ capture: true
1568
+ });
1569
+ }
1570
+ },
1571
+ () => [Reflect.get(this, "disabled")]
1572
+ );
1547
1573
  const { adoptedStyleSheets } = new.target;
1548
1574
  if (adoptedStyleSheets) {
1549
1575
  const sheets = adoptedStyleSheets.map((item) => item[SheetToken] || item);
@@ -1617,7 +1643,7 @@ const _GemElement = class extends HTMLElement {
1617
1643
  return __privateGet$1(_GemElement, _final);
1618
1644
  }
1619
1645
  disconnectedCallback() {
1620
- var _a2, _b2, _c, _d, _e;
1646
+ var _a2, _b2;
1621
1647
  if (this.isConnected) {
1622
1648
  __privateSet$1(this, _isAppendReason, true);
1623
1649
  return;
@@ -1626,9 +1652,8 @@ const _GemElement = class extends HTMLElement {
1626
1652
  (_a2 = __privateGet$1(this, _disconnectStore)) == null ? void 0 : _a2.forEach((disconnect2) => disconnect2());
1627
1653
  execCallback(__privateGet$1(this, _unmountCallback));
1628
1654
  (_b2 = this.unmounted) == null ? void 0 : _b2.call(this);
1629
- (_c = __privateGet$1(this, _effectList)) == null ? void 0 : _c.forEach(({ preCallback }) => execCallback(preCallback));
1630
- __privateSet$1(this, _effectList, (_d = __privateGet$1(this, _effectList)) == null ? void 0 : _d.filter(__privateGet$1(this, _filterEffect)));
1631
- __privateSet$1(this, _memoList, (_e = __privateGet$1(this, _memoList)) == null ? void 0 : _e.filter(__privateGet$1(this, _filterEffect)));
1655
+ __privateSet$1(this, _effectList, __privateGet$1(this, _clearEffect).call(this, __privateGet$1(this, _effectList)));
1656
+ __privateSet$1(this, _memoList, __privateGet$1(this, _clearEffect).call(this, __privateGet$1(this, _memoList)));
1632
1657
  return __privateGet$1(_GemElement, _final);
1633
1658
  }
1634
1659
  };
@@ -1653,7 +1678,7 @@ _update = /* @__PURE__ */ new WeakMap();
1653
1678
  _updated = /* @__PURE__ */ new WeakMap();
1654
1679
  _disconnectStore = /* @__PURE__ */ new WeakMap();
1655
1680
  _connectedCallback = /* @__PURE__ */ new WeakMap();
1656
- _filterEffect = /* @__PURE__ */ new WeakMap();
1681
+ _clearEffect = /* @__PURE__ */ new WeakMap();
1657
1682
  __privateAdd$1(GemElement, _final, Symbol());
1658
1683
  const gemElementProxyMap = new PropProxyMap();
1659
1684
  function defineAttribute(target, prop, attr) {
@@ -1739,9 +1764,7 @@ function defineRef(target, prop, ref) {
1739
1764
  return ref;
1740
1765
  },
1741
1766
  get element() {
1742
- const gemReflects = [...ele.querySelectorAll("[data-gem-reflect]")].map(
1743
- (e) => e.target
1744
- );
1767
+ const gemReflects = [...ele.querySelectorAll("[data-gem-reflect]")].map((e) => e.target);
1745
1768
  for (const e of [ele, ...gemReflects]) {
1746
1769
  const result = e.querySelector(`[ref=${ref}]`);
1747
1770
  if (result)
@@ -1907,14 +1930,20 @@ function getInternalPath(urlBarPath) {
1907
1930
  return "/";
1908
1931
  return urlBarPath.replace(new RegExp(`^${gemHistory.basePath}/`), "/");
1909
1932
  }
1933
+ function dispatchBeforeChangeEvent() {
1934
+ gemHistory.dispatchEvent(new CustomEvent("beforechange"));
1935
+ }
1910
1936
  function normalizeParams(params) {
1911
- const current = paramsMap.get(store.$key) || {};
1937
+ var _a2, _b2;
1938
+ const current = paramsMap.get(store.$key) || { path: getInternalPath(location.pathname), query: new QueryString() };
1912
1939
  const path = params.path ? absoluteLocation(current.path, params.path) : getInternalPath(location.pathname);
1913
- const query = new QueryString(params.query || (params.path ? "" : location.search));
1914
- const pathChanged = params.path && params.path !== current.path || params.query && String(params.query) !== String(current.query);
1915
- const title = params.title || (pathChanged ? "" : document.title);
1940
+ const newQueryObject = new QueryString((_a2 = params.query) != null ? _a2 : params.path ? "" : location.search);
1941
+ const queryChanged = String(newQueryObject) !== String(current.query);
1942
+ const query = queryChanged ? newQueryObject : current.query;
1943
+ const urlChanged = path !== current.path || queryChanged;
1944
+ const title = params.title || (urlChanged ? "" : document.title);
1916
1945
  const statusChanged = params.close || params.data || params.open || params.shouldClose;
1917
- const hash = params.hash || (!pathChanged && statusChanged ? decodeURIComponent(location.hash) : "");
1946
+ const hash = decodeURIComponent((_b2 = params.hash) != null ? _b2 : !urlChanged && statusChanged ? location.hash : "");
1918
1947
  return { ...params, title, path, query, hash };
1919
1948
  }
1920
1949
  function updateHistory(p, native) {
@@ -1930,6 +1959,7 @@ function updateHistory(p, native) {
1930
1959
  ...data
1931
1960
  };
1932
1961
  paramsMap.set(state2.$key, params);
1962
+ dispatchBeforeChangeEvent();
1933
1963
  cleanObject(store);
1934
1964
  updateHistoryStore(state2);
1935
1965
  const url = getUrlBarPath(path) + new QueryString(query) + hash;
@@ -1948,6 +1978,7 @@ function updateHistoryByNative(data, title, originUrl, native) {
1948
1978
  const { pathname, search, hash } = new URL(originUrl, location.origin + location.pathname);
1949
1979
  const params = normalizeParams({ path: pathname, query: new QueryString(search), hash, title, data });
1950
1980
  paramsMap.set(state2.$key, params);
1981
+ dispatchBeforeChangeEvent();
1951
1982
  cleanObject(store);
1952
1983
  updateHistoryStore(state2);
1953
1984
  const url = getUrlBarPath(pathname) + params.query + hash;
@@ -1959,10 +1990,13 @@ function updateHistoryByNative(data, title, originUrl, native) {
1959
1990
  const [gemBasePathStore, updateBasePathStore] = useStore({
1960
1991
  basePath: ""
1961
1992
  });
1962
- class GemHistory {
1993
+ class GemHistory extends EventTarget {
1963
1994
  get store() {
1964
1995
  return store;
1965
1996
  }
1997
+ get currentKey() {
1998
+ return store.$key;
1999
+ }
1966
2000
  get basePath() {
1967
2001
  return gemBasePathStore.basePath;
1968
2002
  }
@@ -2012,7 +2046,7 @@ if (!window._GEMHISTORY) {
2012
2046
  };
2013
2047
  window.addEventListener("hashchange", ({ isTrusted }) => {
2014
2048
  if (isTrusted) {
2015
- gemHistory.replace({ hash: decodeURIComponent(location.hash) });
2049
+ gemHistory.replace({ hash: location.hash });
2016
2050
  }
2017
2051
  });
2018
2052
  if (!nativeHistory.state) {
@@ -2059,7 +2093,7 @@ if (!window._GEMHISTORY) {
2059
2093
  paramsMap.set(newState.$key, {
2060
2094
  path: pathname,
2061
2095
  query: new QueryString(search),
2062
- hash,
2096
+ hash: decodeURIComponent(hash),
2063
2097
  title: newState.$title,
2064
2098
  data: newState
2065
2099
  });
@@ -2086,6 +2120,7 @@ if (!window._GEMHISTORY) {
2086
2120
  }
2087
2121
  }
2088
2122
  }
2123
+ dispatchBeforeChangeEvent();
2089
2124
  cleanObject(store);
2090
2125
  updateHistoryStore(newState);
2091
2126
  });
@@ -2120,19 +2155,18 @@ var __privateSet2 = (obj, member, value, setter) => {
2120
2155
  setter ? setter.call(obj, value) : member.set(obj, value);
2121
2156
  return value;
2122
2157
  };
2123
- var _lastLoader, _updateLocationStore, _setContent;
2158
+ var _lastLoader, _scrollContainer, scrollContainer_get, _updateLocationStore, _updateScrollContainerPosition, _setContent;
2159
+ const UNNAMED_PARAM_PREFIX = "_";
2124
2160
  class ParamsRegExp extends RegExp {
2125
2161
  constructor(pattern) {
2126
- const namePosition = {};
2127
2162
  let i = 0;
2128
2163
  super(
2129
- `^${pattern.replace(/:([^/$]+)/g, (_m, name) => {
2130
- namePosition[name] = i++;
2131
- return `([^/]+)`;
2132
- }).replace("*", ".*")}$`,
2133
- "i"
2164
+ `^${pattern.replace(/((:[^/$]+)|(\*))/g, (_m, name) => {
2165
+ if (name === "*")
2166
+ return `(?<${UNNAMED_PARAM_PREFIX}${i++}>.*)`;
2167
+ return `(?<${name.slice(1)}>[^/]+)`;
2168
+ })}$`
2134
2169
  );
2135
- this.namePosition = namePosition;
2136
2170
  }
2137
2171
  }
2138
2172
  function matchPath(pattern, path) {
@@ -2148,9 +2182,9 @@ function matchPath(pattern, path) {
2148
2182
  if (!matchResult)
2149
2183
  return null;
2150
2184
  const params = {};
2151
- if (matchResult) {
2152
- Object.keys(reg.namePosition).forEach((name) => {
2153
- params[name] = matchResult[reg.namePosition[name] + 1];
2185
+ if (matchResult.groups) {
2186
+ Object.entries(matchResult.groups).forEach(([key2, value]) => {
2187
+ params[key2.startsWith(UNNAMED_PARAM_PREFIX) ? key2.slice(1) : key2] = value;
2154
2188
  });
2155
2189
  }
2156
2190
  return params;
@@ -2172,87 +2206,120 @@ function createHistoryParams(route, options) {
2172
2206
  ...options
2173
2207
  };
2174
2208
  }
2175
- let GemRouteElement = class extends GemElement {
2209
+ const scrollPositionMap = /* @__PURE__ */ new Map();
2210
+ const _GemRouteElement = class extends GemElement {
2176
2211
  constructor({ isLight, routes } = {}) {
2177
2212
  super({ isLight });
2213
+ __privateAdd2(this, _scrollContainer);
2214
+ this.trigger = history;
2178
2215
  this.currentParams = {};
2179
2216
  __privateAdd2(this, _lastLoader, void 0);
2180
2217
  this.state = {
2181
2218
  content: void 0
2182
2219
  };
2183
2220
  __privateAdd2(this, _updateLocationStore, () => {
2184
- if (this.locationStore) {
2185
- const { path, query, data } = history.getParams();
2186
- updateStore(this.locationStore, {
2187
- path,
2188
- params: this.currentParams,
2189
- query,
2190
- data
2191
- });
2221
+ if (!this.locationStore)
2222
+ return;
2223
+ const { path, query, hash, data } = history.getParams();
2224
+ updateStore(this.locationStore, {
2225
+ path,
2226
+ params: this.currentParams,
2227
+ query,
2228
+ hash,
2229
+ data
2230
+ });
2231
+ });
2232
+ __privateAdd2(this, _updateScrollContainerPosition, () => {
2233
+ if (!__privateGet2(this, _scrollContainer, scrollContainer_get))
2234
+ return;
2235
+ const scrollTop = scrollPositionMap.get(history.currentKey);
2236
+ if (scrollTop) {
2237
+ __privateGet2(this, _scrollContainer, scrollContainer_get).scroll(0, scrollTop);
2238
+ } else if (this.scrollIgnoreHash || !history.getParams().hash) {
2239
+ __privateGet2(this, _scrollContainer, scrollContainer_get).scroll(0, 0);
2192
2240
  }
2193
2241
  });
2194
2242
  __privateAdd2(this, _setContent, (route, params, content) => {
2243
+ this.beforeroutechange(route);
2195
2244
  __privateSet2(this, _lastLoader, void 0);
2196
2245
  this.currentRoute = route;
2197
2246
  this.currentParams = params;
2198
- const changeContent = () => {
2247
+ const changeContent = async () => {
2199
2248
  this.setState({ content });
2200
- this.routechange(this.currentRoute);
2201
2249
  __privateGet2(this, _updateLocationStore).call(this);
2250
+ await Promise.resolve();
2251
+ __privateGet2(this, _updateScrollContainerPosition).call(this);
2252
+ this.routechange(this.currentRoute);
2202
2253
  };
2203
2254
  if (this.transition && "startViewTransition" in document) {
2204
- document.startViewTransition(() => {
2205
- changeContent();
2206
- return Promise.resolve();
2207
- });
2255
+ document.startViewTransition(() => changeContent());
2208
2256
  } else {
2209
2257
  changeContent();
2210
2258
  }
2211
2259
  });
2260
+ this.update = () => {
2261
+ const { route, params = {} } = _GemRouteElement.findRoute(this.routes, this.trigger.getParams().path);
2262
+ const { redirect, content, getContent } = route || {};
2263
+ if (redirect) {
2264
+ this.trigger.replace({
2265
+ path: createPath({ pattern: redirect }, { params })
2266
+ });
2267
+ return;
2268
+ }
2269
+ if (this.trigger === history) {
2270
+ updateStore(titleStore, { title: route == null ? void 0 : route.title });
2271
+ }
2272
+ const contentOrLoader = content || (getContent == null ? void 0 : getContent(params));
2273
+ this.loading(route);
2274
+ if (contentOrLoader instanceof Promise) {
2275
+ __privateSet2(this, _lastLoader, contentOrLoader);
2276
+ const isSomeLoader = () => __privateGet2(this, _lastLoader) === contentOrLoader;
2277
+ contentOrLoader.then((content2) => {
2278
+ if (isSomeLoader())
2279
+ __privateGet2(this, _setContent).call(this, route, params, content2);
2280
+ }).catch((err) => {
2281
+ if (isSomeLoader())
2282
+ this.error(err);
2283
+ });
2284
+ return;
2285
+ }
2286
+ __privateGet2(this, _setContent).call(this, route, params, contentOrLoader);
2287
+ };
2212
2288
  this.routes = routes;
2213
2289
  }
2214
2290
  mounted() {
2291
+ this.effect(
2292
+ () => {
2293
+ if (!__privateGet2(this, _scrollContainer, scrollContainer_get))
2294
+ return;
2295
+ return addListener(
2296
+ history,
2297
+ "beforechange",
2298
+ () => scrollPositionMap.set(history.currentKey, __privateGet2(this, _scrollContainer, scrollContainer_get).scrollTop)
2299
+ );
2300
+ },
2301
+ () => [this.scrollContainer]
2302
+ );
2303
+ this.effect(
2304
+ () => connect(this.trigger.store, () => this.setState({})),
2305
+ () => [this.trigger]
2306
+ );
2215
2307
  this.effect(
2216
2308
  ([key2, path], old) => {
2217
2309
  if (old && key2 === old[0] && path === old[1]) {
2218
2310
  __privateGet2(this, _updateLocationStore).call(this);
2219
2311
  return;
2220
2312
  }
2221
- const { route, params = {} } = GemRouteElement.findRoute(this.routes, path);
2222
- const { redirect, content, getContent } = route || {};
2223
- if (redirect) {
2224
- history.replace({ path: redirect });
2225
- return;
2226
- }
2227
- const title = route == null ? void 0 : route.title;
2228
- if (title)
2229
- updateStore(titleStore, { title });
2230
- const contentOrLoader = content || (getContent == null ? void 0 : getContent(params));
2231
- if (contentOrLoader instanceof Promise) {
2232
- this.loading(route);
2233
- __privateSet2(this, _lastLoader, contentOrLoader);
2234
- const isSomeLoader = () => __privateGet2(this, _lastLoader) === contentOrLoader;
2235
- contentOrLoader.then((content2) => {
2236
- if (isSomeLoader())
2237
- __privateGet2(this, _setContent).call(this, route, params, content2);
2238
- }).catch((err) => {
2239
- if (isSomeLoader())
2240
- this.error(err);
2241
- });
2242
- return;
2243
- }
2244
- __privateGet2(this, _setContent).call(this, route, params, contentOrLoader);
2313
+ this.update();
2245
2314
  },
2246
2315
  () => {
2247
- const { path } = history.getParams();
2248
- return [this.key, path, location.search];
2316
+ const { path, query, hash } = this.trigger.getParams();
2317
+ return [this.key, path, query, hash];
2249
2318
  }
2250
2319
  );
2251
2320
  }
2252
2321
  shouldUpdate() {
2253
- if (this.inert)
2254
- return false;
2255
- return true;
2322
+ return this.inert ? false : true;
2256
2323
  }
2257
2324
  render() {
2258
2325
  const { content } = this.state;
@@ -2269,12 +2336,18 @@ let GemRouteElement = class extends GemElement {
2269
2336
  `;
2270
2337
  }
2271
2338
  };
2339
+ let GemRouteElement = _GemRouteElement;
2272
2340
  _lastLoader = /* @__PURE__ */ new WeakMap();
2341
+ _scrollContainer = /* @__PURE__ */ new WeakSet();
2342
+ scrollContainer_get = function() {
2343
+ return typeof this.scrollContainer === "function" ? this.scrollContainer() : this.scrollContainer;
2344
+ };
2273
2345
  _updateLocationStore = /* @__PURE__ */ new WeakMap();
2346
+ _updateScrollContainerPosition = /* @__PURE__ */ new WeakMap();
2274
2347
  _setContent = /* @__PURE__ */ new WeakMap();
2275
2348
  GemRouteElement.createLocationStore = () => {
2276
- const { path, query, data } = history.getParams();
2277
- return createStore({ path, query, data, params: {} });
2349
+ const { path, query, hash, data } = history.getParams();
2350
+ return createStore({ path, query, hash, data, params: {} });
2278
2351
  };
2279
2352
  GemRouteElement.findRoute = (target = [], path) => {
2280
2353
  let defaultRoute = null;
@@ -2310,16 +2383,25 @@ __decorateClass$6([
2310
2383
  ], GemRouteElement.prototype, "key", 2);
2311
2384
  __decorateClass$6([
2312
2385
  emitter
2313
- ], GemRouteElement.prototype, "routechange", 2);
2386
+ ], GemRouteElement.prototype, "loading", 2);
2314
2387
  __decorateClass$6([
2315
2388
  emitter
2316
- ], GemRouteElement.prototype, "loading", 2);
2389
+ ], GemRouteElement.prototype, "beforeroutechange", 2);
2390
+ __decorateClass$6([
2391
+ emitter
2392
+ ], GemRouteElement.prototype, "routechange", 2);
2317
2393
  __decorateClass$6([
2318
2394
  emitter
2319
2395
  ], GemRouteElement.prototype, "error", 2);
2320
- GemRouteElement = __decorateClass$6([
2321
- connectStore(history.store)
2322
- ], GemRouteElement);
2396
+ __decorateClass$6([
2397
+ property
2398
+ ], GemRouteElement.prototype, "scrollContainer", 2);
2399
+ __decorateClass$6([
2400
+ property
2401
+ ], GemRouteElement.prototype, "scrollIgnoreHash", 2);
2402
+ __decorateClass$6([
2403
+ property
2404
+ ], GemRouteElement.prototype, "trigger", 2);
2323
2405
  class GemLightRouteElement extends GemRouteElement {
2324
2406
  constructor(options = {}) {
2325
2407
  super({ ...options, isLight: true });
@@ -2341,7 +2423,7 @@ function isExternal(path) {
2341
2423
  }
2342
2424
  let GemLinkElement = (_a = class extends GemElement {
2343
2425
  constructor() {
2344
- super();
2426
+ super({ focusable: true });
2345
2427
  __privateAdd(this, _routeOptions);
2346
2428
  __privateAdd(this, _hint);
2347
2429
  __privateAdd(this, _onClick, void 0);
@@ -2387,7 +2469,12 @@ let GemLinkElement = (_a = class extends GemElement {
2387
2469
  title: this.docTitle
2388
2470
  });
2389
2471
  } else {
2390
- history.pushIgnoreCloseHandle({ path: this.path, query: this.query, hash: this.hash, title: this.docTitle });
2472
+ history.pushIgnoreCloseHandle({
2473
+ path: this.path,
2474
+ query: this.query,
2475
+ hash: this.hash,
2476
+ title: this.docTitle
2477
+ });
2391
2478
  }
2392
2479
  });
2393
2480
  __privateSet(this, _preventDefault, (e) => {
@@ -2397,7 +2484,6 @@ let GemLinkElement = (_a = class extends GemElement {
2397
2484
  const locationString = this.getLocationString();
2398
2485
  return isExternal(locationString) ? locationString : new URL(history.basePath + locationString, location.origin).toString();
2399
2486
  });
2400
- this.tabIndex = 0;
2401
2487
  this.addEventListener("click", __privateGet(this, _onClick));
2402
2488
  }
2403
2489
  render() {
@@ -2525,15 +2611,18 @@ var __decorateClass$4 = (decorators, target, key2, kind) => {
2525
2611
  return result;
2526
2612
  };
2527
2613
  const defaultTitle = document.title;
2614
+ let documentTitle = "";
2615
+ const setTitle = () => document.title = documentTitle;
2528
2616
  function setDocumentTitle(str, prefix = "", suffix = "") {
2529
2617
  const title = titleStore.title || str;
2530
2618
  if (title && title !== defaultTitle) {
2531
2619
  GemTitleElement.title = title;
2532
- document.title = prefix + GemTitleElement.title + suffix;
2620
+ documentTitle = prefix + GemTitleElement.title + suffix;
2533
2621
  } else {
2534
2622
  GemTitleElement.title = defaultTitle;
2535
- document.title = GemTitleElement.title;
2623
+ documentTitle = GemTitleElement.title;
2536
2624
  }
2625
+ addMicrotask(setTitle);
2537
2626
  }
2538
2627
  connect(titleStore, setDocumentTitle);
2539
2628
  const PREFIX = `${defaultTitle} | `;
@@ -2549,6 +2638,7 @@ const _GemTitleElement = class extends GemElement {
2549
2638
  };
2550
2639
  new MutationObserver(() => this.update()).observe(this, {
2551
2640
  characterData: true,
2641
+ childList: true,
2552
2642
  subtree: true
2553
2643
  });
2554
2644
  }
@@ -2693,22 +2783,43 @@ var __decorateClass$1 = (decorators, target, key2, kind) => {
2693
2783
  __defProp$1(target, key2, result);
2694
2784
  return result;
2695
2785
  };
2786
+ const START = "gem-reflect-start";
2787
+ const END = "gem-reflect-end";
2788
+ const createReflectFragmentTag = (tag) => new Comment(tag);
2789
+ const getReflectFragment = (startNode) => {
2790
+ const result = [];
2791
+ let node = startNode;
2792
+ while (node) {
2793
+ result.push(node);
2794
+ if (node.nodeValue === END)
2795
+ break;
2796
+ node = node.nextSibling;
2797
+ }
2798
+ return result;
2799
+ };
2696
2800
  class GemReflectElement extends GemElement {
2697
2801
  constructor() {
2698
2802
  super({ isLight: true });
2699
2803
  this.target = document.head;
2700
- this.hidden = true;
2701
- this.dataset.gemReflect = "";
2702
2804
  this.effect(
2703
2805
  () => {
2704
- const childNodes = [...this.childNodes];
2705
- childNodes.forEach((node) => {
2706
- if (node instanceof HTMLElement) {
2707
- node.dataset.reflect = "";
2708
- }
2709
- this.target.append(node);
2710
- });
2806
+ this.hidden = true;
2807
+ this.dataset.gemReflect = "";
2808
+ },
2809
+ () => []
2810
+ );
2811
+ const startNode = createReflectFragmentTag(START);
2812
+ const endNode = createReflectFragmentTag(END);
2813
+ let childNodes;
2814
+ this.effect(
2815
+ () => {
2816
+ if (!childNodes) {
2817
+ [startNode, ...this.childNodes, endNode].forEach((node) => this.target.append(node));
2818
+ } else {
2819
+ childNodes.forEach((node) => this.target.append(node));
2820
+ }
2711
2821
  return () => {
2822
+ childNodes = getReflectFragment(startNode);
2712
2823
  childNodes.forEach((node) => node.remove());
2713
2824
  };
2714
2825
  },
@@ -2839,7 +2950,10 @@ let GemDialogBaseElement = (_b = class extends GemElement {
2839
2950
  setTimeout(this.close, 100);
2840
2951
  return final;
2841
2952
  };
2842
- this.inert = true;
2953
+ this.effect(
2954
+ () => this.inert = true,
2955
+ () => []
2956
+ );
2843
2957
  this.internals.role = "dialog";
2844
2958
  this.internals.ariaModal = "true";
2845
2959
  }
@@ -2896,6 +3010,21 @@ function useTheme(themeObj) {
2896
3010
  const theme = createTheme(themeObj);
2897
3011
  return [theme, (newThemeObj) => updateTheme(theme, newThemeObj)];
2898
3012
  }
3013
+ class Logger {
3014
+ constructor(type) {
3015
+ this.info = (...args) => {
3016
+ console.log(`[${this._type}]:`, ...args);
3017
+ };
3018
+ this.warn = (...args) => {
3019
+ console.warn(`[${this._type}]:`, ...args);
3020
+ };
3021
+ this.error = (...args) => {
3022
+ console.error(`[${this._type}]:`, ...args);
3023
+ };
3024
+ this._type = type;
3025
+ }
3026
+ }
3027
+ const logger = new Logger("GEM");
2899
3028
  const splitReg = /\$\d(?:<[^>]*>)?/;
2900
3029
  const matchReg = /\$(\d)(<([^>]*)>)?/g;
2901
3030
  const matchStrIndex = 3;
@@ -2920,6 +3049,10 @@ const _I18n = class {
2920
3049
  __privateAdd(this, _isMain);
2921
3050
  __privateAdd(this, _lang);
2922
3051
  this.cachePrefix = "gem-i18n";
3052
+ this.replace = ({ path }) => {
3053
+ this.setLanguage(path);
3054
+ };
3055
+ this.getParams = () => ({ path: this.currentLanguage });
2923
3056
  if (!options.resources[options.fallbackLanguage]) {
2924
3057
  throw new GemError("i18n: fallbackLanguage invalid");
2925
3058
  }
@@ -2968,7 +3101,7 @@ const _I18n = class {
2968
3101
  let pack;
2969
3102
  const data = this.resources[lang];
2970
3103
  if (!data) {
2971
- console.warn(`${this.cachePrefix}: not found \`${lang}\``);
3104
+ logger.warn(`${this.cachePrefix}: not found \`${lang}\``);
2972
3105
  return this.resetLanguage();
2973
3106
  }
2974
3107
  if (typeof data === "string") {
@@ -3001,7 +3134,7 @@ const _I18n = class {
3001
3134
  pack = data;
3002
3135
  }
3003
3136
  this.resources[lang] = pack;
3004
- updateStore(this.store, {});
3137
+ updateStore(this.store);
3005
3138
  if (lang !== this.currentLanguage) {
3006
3139
  __privateSet(this, _lang, lang, lang_set);
3007
3140
  }
@@ -3187,4 +3320,4 @@ const mediaQuery = {
3187
3320
  return match(this.WIDTHSCREEN);
3188
3321
  }
3189
3322
  };
3190
- export { GemActiveLinkElement, GemDialogBaseElement, GemElement, GemError, GemLightRouteElement, GemLinkElement, GemReflectElement, GemRouteElement, GemTitleElement, GemUnsafeElement, GemUseElement, I18n, LinkedList, PREFIX, PropProxyMap, QueryString, SUFFIX, SVGTemplateResult, SheetToken, StoreListenerMap, TemplateResult, absoluteLocation, addMicrotask, addMicrotaskToStack, adoptedStyle, attribute, basePathStore, boolattribute, camelToKebabCase, classMap, cleanObject, connect, connectStore, createCSSSheet, createHistoryParams, createModalClass, createPath, createStore, createTheme, css, customElement, defaultReqInit, defineAttribute, defineCSSState, defineProperty, defineRef, del, directive, disconnect, emitter, exportPartsMap, get, getThemeProps, getThemeStore, globalemitter, guard, history, html, ifDefined, isArrayChange, kebabToCamelCase, matchPath, mediaQuery, nativeDefineElement, numattribute, objectMapToString, part, partMap, post, property, put, randomStr, raw, refobject, removeItems, render, repeat, request, rootElement, slot, splice, state, styleMap, styled, svg, titleStore, updateStore, updateTheme, useStore, useTheme, version };
3323
+ export { GemActiveLinkElement, GemDialogBaseElement, GemElement, GemError, GemLightRouteElement, GemLinkElement, GemReflectElement, GemRouteElement, GemTitleElement, GemUnsafeElement, GemUseElement, I18n, LinkedList, PREFIX, PropProxyMap, QueryString, SUFFIX, SVGTemplateResult, SheetToken, StoreListenerMap, TemplateResult, absoluteLocation, addListener, addMicrotask, addMicrotaskToStack, adoptedStyle, attribute, basePathStore, boolattribute, camelToKebabCase, classMap, cleanObject, connect, connectStore, createCSSSheet, createHistoryParams, createModalClass, createPath, createStore, createTheme, css, customElement, defaultReqInit, defineAttribute, defineCSSState, defineProperty, defineRef, del, directive, disconnect, emitter, exportPartsMap, get, getThemeProps, getThemeStore, globalemitter, guard, history, html, ifDefined, isArrayChange, kebabToCamelCase, matchPath, mediaQuery, nativeDefineElement, numattribute, objectMapToString, part, partMap, post, property, put, randomStr, raw, refobject, removeItems, render, repeat, request, rootElement, slot, splice, state, styleMap, styled, svg, titleStore, updateStore, updateTheme, useStore, useTheme, version };