@mantou/gem 1.7.8 → 1.7.9

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 (63) hide show
  1. package/dist/gem.es.js +234 -102
  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/link.d.ts.map +1 -1
  7. package/elements/base/link.js +8 -4
  8. package/elements/base/link.js.map +1 -1
  9. package/elements/base/modal-factory.d.ts +28 -6
  10. package/elements/base/modal-factory.d.ts.map +1 -1
  11. package/elements/base/reflect.d.ts +8 -0
  12. package/elements/base/reflect.d.ts.map +1 -1
  13. package/elements/base/reflect.js +36 -9
  14. package/elements/base/reflect.js.map +1 -1
  15. package/elements/base/route.d.ts +25 -10
  16. package/elements/base/route.d.ts.map +1 -1
  17. package/elements/base/route.js +90 -56
  18. package/elements/base/route.js.map +1 -1
  19. package/elements/base/title.d.ts.map +1 -1
  20. package/elements/base/title.js +8 -2
  21. package/elements/base/title.js.map +1 -1
  22. package/helper/i18n.d.ts +8 -1
  23. package/helper/i18n.d.ts.map +1 -1
  24. package/helper/i18n.js +6 -2
  25. package/helper/i18n.js.map +1 -1
  26. package/helper/logger.d.ts +9 -0
  27. package/helper/logger.d.ts.map +1 -0
  28. package/helper/logger.js +16 -0
  29. package/helper/logger.js.map +1 -0
  30. package/helper/ssr-shim.d.ts.map +1 -1
  31. package/helper/ssr-shim.js +12 -4
  32. package/helper/ssr-shim.js.map +1 -1
  33. package/lib/element.d.ts +5 -5
  34. package/lib/element.d.ts.map +1 -1
  35. package/lib/element.js +40 -14
  36. package/lib/element.js.map +1 -1
  37. package/lib/history.d.ts +3 -2
  38. package/lib/history.d.ts.map +1 -1
  39. package/lib/history.js +22 -9
  40. package/lib/history.js.map +1 -1
  41. package/lib/utils.d.ts +2 -1
  42. package/lib/utils.d.ts.map +1 -1
  43. package/lib/utils.js +10 -8
  44. package/lib/utils.js.map +1 -1
  45. package/lib/version.d.ts +1 -1
  46. package/lib/version.js +1 -1
  47. package/package.json +1 -1
  48. package/src/elements/base/dialog.ts +4 -1
  49. package/src/elements/base/link.ts +8 -4
  50. package/src/elements/base/reflect.ts +43 -9
  51. package/src/elements/base/route.ts +102 -51
  52. package/src/elements/base/title.ts +9 -2
  53. package/src/helper/i18n.ts +11 -3
  54. package/src/helper/logger.ts +21 -0
  55. package/src/helper/ssr-shim.ts +14 -4
  56. package/src/lib/element.ts +46 -17
  57. package/src/lib/history.ts +30 -12
  58. package/src/lib/utils.ts +16 -9
  59. package/src/lib/version.ts +1 -1
  60. package/src/test/elements/link.test.ts +15 -0
  61. package/src/test/elements/reflect.test.ts +27 -0
  62. package/src/test/elements/title.test.ts +25 -0
  63. 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.9";
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,7 +2155,7 @@ 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;
2124
2159
  class ParamsRegExp extends RegExp {
2125
2160
  constructor(pattern) {
2126
2161
  const namePosition = {};
@@ -2172,87 +2207,118 @@ function createHistoryParams(route, options) {
2172
2207
  ...options
2173
2208
  };
2174
2209
  }
2175
- let GemRouteElement = class extends GemElement {
2210
+ const scrollPositionMap = /* @__PURE__ */ new Map();
2211
+ const _GemRouteElement = class extends GemElement {
2176
2212
  constructor({ isLight, routes } = {}) {
2177
2213
  super({ isLight });
2214
+ __privateAdd2(this, _scrollContainer);
2215
+ this.trigger = history;
2178
2216
  this.currentParams = {};
2179
2217
  __privateAdd2(this, _lastLoader, void 0);
2180
2218
  this.state = {
2181
2219
  content: void 0
2182
2220
  };
2183
2221
  __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
- });
2222
+ if (!this.locationStore)
2223
+ return;
2224
+ const { path, query, hash, data } = history.getParams();
2225
+ updateStore(this.locationStore, {
2226
+ path,
2227
+ params: this.currentParams,
2228
+ query,
2229
+ hash,
2230
+ data
2231
+ });
2232
+ });
2233
+ __privateAdd2(this, _updateScrollContainerPosition, () => {
2234
+ if (!__privateGet2(this, _scrollContainer, scrollContainer_get))
2235
+ return;
2236
+ const scrollTop = scrollPositionMap.get(history.currentKey);
2237
+ if (scrollTop) {
2238
+ __privateGet2(this, _scrollContainer, scrollContainer_get).scroll(0, scrollTop);
2239
+ } else if (this.scrollIgnoreHash || !history.getParams().hash) {
2240
+ __privateGet2(this, _scrollContainer, scrollContainer_get).scroll(0, 0);
2192
2241
  }
2193
2242
  });
2194
2243
  __privateAdd2(this, _setContent, (route, params, content) => {
2244
+ this.beforeroutechange(route);
2195
2245
  __privateSet2(this, _lastLoader, void 0);
2196
2246
  this.currentRoute = route;
2197
2247
  this.currentParams = params;
2198
- const changeContent = () => {
2248
+ const changeContent = async () => {
2199
2249
  this.setState({ content });
2200
- this.routechange(this.currentRoute);
2201
2250
  __privateGet2(this, _updateLocationStore).call(this);
2251
+ await Promise.resolve();
2252
+ __privateGet2(this, _updateScrollContainerPosition).call(this);
2253
+ this.routechange(this.currentRoute);
2202
2254
  };
2203
2255
  if (this.transition && "startViewTransition" in document) {
2204
- document.startViewTransition(() => {
2205
- changeContent();
2206
- return Promise.resolve();
2207
- });
2256
+ document.startViewTransition(() => changeContent());
2208
2257
  } else {
2209
2258
  changeContent();
2210
2259
  }
2211
2260
  });
2261
+ this.update = () => {
2262
+ const { route, params = {} } = _GemRouteElement.findRoute(this.routes, this.trigger.getParams().path);
2263
+ const { redirect, content, getContent } = route || {};
2264
+ if (redirect) {
2265
+ this.trigger.replace({ path: redirect });
2266
+ return;
2267
+ }
2268
+ if (this.trigger === history) {
2269
+ updateStore(titleStore, { title: route == null ? void 0 : route.title });
2270
+ }
2271
+ const contentOrLoader = content || (getContent == null ? void 0 : getContent(params));
2272
+ this.loading(route);
2273
+ if (contentOrLoader instanceof Promise) {
2274
+ __privateSet2(this, _lastLoader, contentOrLoader);
2275
+ const isSomeLoader = () => __privateGet2(this, _lastLoader) === contentOrLoader;
2276
+ contentOrLoader.then((content2) => {
2277
+ if (isSomeLoader())
2278
+ __privateGet2(this, _setContent).call(this, route, params, content2);
2279
+ }).catch((err) => {
2280
+ if (isSomeLoader())
2281
+ this.error(err);
2282
+ });
2283
+ return;
2284
+ }
2285
+ __privateGet2(this, _setContent).call(this, route, params, contentOrLoader);
2286
+ };
2212
2287
  this.routes = routes;
2213
2288
  }
2214
2289
  mounted() {
2290
+ this.effect(
2291
+ () => {
2292
+ if (!__privateGet2(this, _scrollContainer, scrollContainer_get))
2293
+ return;
2294
+ return addListener(
2295
+ history,
2296
+ "beforechange",
2297
+ () => scrollPositionMap.set(history.currentKey, __privateGet2(this, _scrollContainer, scrollContainer_get).scrollTop)
2298
+ );
2299
+ },
2300
+ () => [this.scrollContainer]
2301
+ );
2302
+ this.effect(
2303
+ () => connect(this.trigger.store, () => this.setState({})),
2304
+ () => [this.trigger]
2305
+ );
2215
2306
  this.effect(
2216
2307
  ([key2, path], old) => {
2217
2308
  if (old && key2 === old[0] && path === old[1]) {
2218
2309
  __privateGet2(this, _updateLocationStore).call(this);
2219
2310
  return;
2220
2311
  }
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);
2312
+ this.update();
2245
2313
  },
2246
2314
  () => {
2247
- const { path } = history.getParams();
2248
- return [this.key, path, location.search];
2315
+ const { path, query, hash } = this.trigger.getParams();
2316
+ return [this.key, path, query, hash];
2249
2317
  }
2250
2318
  );
2251
2319
  }
2252
2320
  shouldUpdate() {
2253
- if (this.inert)
2254
- return false;
2255
- return true;
2321
+ return this.inert ? false : true;
2256
2322
  }
2257
2323
  render() {
2258
2324
  const { content } = this.state;
@@ -2269,12 +2335,18 @@ let GemRouteElement = class extends GemElement {
2269
2335
  `;
2270
2336
  }
2271
2337
  };
2338
+ let GemRouteElement = _GemRouteElement;
2272
2339
  _lastLoader = /* @__PURE__ */ new WeakMap();
2340
+ _scrollContainer = /* @__PURE__ */ new WeakSet();
2341
+ scrollContainer_get = function() {
2342
+ return typeof this.scrollContainer === "function" ? this.scrollContainer() : this.scrollContainer;
2343
+ };
2273
2344
  _updateLocationStore = /* @__PURE__ */ new WeakMap();
2345
+ _updateScrollContainerPosition = /* @__PURE__ */ new WeakMap();
2274
2346
  _setContent = /* @__PURE__ */ new WeakMap();
2275
2347
  GemRouteElement.createLocationStore = () => {
2276
- const { path, query, data } = history.getParams();
2277
- return createStore({ path, query, data, params: {} });
2348
+ const { path, query, hash, data } = history.getParams();
2349
+ return createStore({ path, query, hash, data, params: {} });
2278
2350
  };
2279
2351
  GemRouteElement.findRoute = (target = [], path) => {
2280
2352
  let defaultRoute = null;
@@ -2310,16 +2382,25 @@ __decorateClass$6([
2310
2382
  ], GemRouteElement.prototype, "key", 2);
2311
2383
  __decorateClass$6([
2312
2384
  emitter
2313
- ], GemRouteElement.prototype, "routechange", 2);
2385
+ ], GemRouteElement.prototype, "loading", 2);
2314
2386
  __decorateClass$6([
2315
2387
  emitter
2316
- ], GemRouteElement.prototype, "loading", 2);
2388
+ ], GemRouteElement.prototype, "beforeroutechange", 2);
2389
+ __decorateClass$6([
2390
+ emitter
2391
+ ], GemRouteElement.prototype, "routechange", 2);
2317
2392
  __decorateClass$6([
2318
2393
  emitter
2319
2394
  ], GemRouteElement.prototype, "error", 2);
2320
- GemRouteElement = __decorateClass$6([
2321
- connectStore(history.store)
2322
- ], GemRouteElement);
2395
+ __decorateClass$6([
2396
+ property
2397
+ ], GemRouteElement.prototype, "scrollContainer", 2);
2398
+ __decorateClass$6([
2399
+ property
2400
+ ], GemRouteElement.prototype, "scrollIgnoreHash", 2);
2401
+ __decorateClass$6([
2402
+ property
2403
+ ], GemRouteElement.prototype, "trigger", 2);
2323
2404
  class GemLightRouteElement extends GemRouteElement {
2324
2405
  constructor(options = {}) {
2325
2406
  super({ ...options, isLight: true });
@@ -2341,7 +2422,7 @@ function isExternal(path) {
2341
2422
  }
2342
2423
  let GemLinkElement = (_a = class extends GemElement {
2343
2424
  constructor() {
2344
- super();
2425
+ super({ focusable: true });
2345
2426
  __privateAdd(this, _routeOptions);
2346
2427
  __privateAdd(this, _hint);
2347
2428
  __privateAdd(this, _onClick, void 0);
@@ -2387,7 +2468,12 @@ let GemLinkElement = (_a = class extends GemElement {
2387
2468
  title: this.docTitle
2388
2469
  });
2389
2470
  } else {
2390
- history.pushIgnoreCloseHandle({ path: this.path, query: this.query, hash: this.hash, title: this.docTitle });
2471
+ history.pushIgnoreCloseHandle({
2472
+ path: this.path,
2473
+ query: this.query,
2474
+ hash: this.hash,
2475
+ title: this.docTitle
2476
+ });
2391
2477
  }
2392
2478
  });
2393
2479
  __privateSet(this, _preventDefault, (e) => {
@@ -2397,7 +2483,6 @@ let GemLinkElement = (_a = class extends GemElement {
2397
2483
  const locationString = this.getLocationString();
2398
2484
  return isExternal(locationString) ? locationString : new URL(history.basePath + locationString, location.origin).toString();
2399
2485
  });
2400
- this.tabIndex = 0;
2401
2486
  this.addEventListener("click", __privateGet(this, _onClick));
2402
2487
  }
2403
2488
  render() {
@@ -2525,15 +2610,18 @@ var __decorateClass$4 = (decorators, target, key2, kind) => {
2525
2610
  return result;
2526
2611
  };
2527
2612
  const defaultTitle = document.title;
2613
+ let documentTitle = "";
2614
+ const setTitle = () => document.title = documentTitle;
2528
2615
  function setDocumentTitle(str, prefix = "", suffix = "") {
2529
2616
  const title = titleStore.title || str;
2530
2617
  if (title && title !== defaultTitle) {
2531
2618
  GemTitleElement.title = title;
2532
- document.title = prefix + GemTitleElement.title + suffix;
2619
+ documentTitle = prefix + GemTitleElement.title + suffix;
2533
2620
  } else {
2534
2621
  GemTitleElement.title = defaultTitle;
2535
- document.title = GemTitleElement.title;
2622
+ documentTitle = GemTitleElement.title;
2536
2623
  }
2624
+ addMicrotask(setTitle);
2537
2625
  }
2538
2626
  connect(titleStore, setDocumentTitle);
2539
2627
  const PREFIX = `${defaultTitle} | `;
@@ -2549,6 +2637,7 @@ const _GemTitleElement = class extends GemElement {
2549
2637
  };
2550
2638
  new MutationObserver(() => this.update()).observe(this, {
2551
2639
  characterData: true,
2640
+ childList: true,
2552
2641
  subtree: true
2553
2642
  });
2554
2643
  }
@@ -2693,22 +2782,43 @@ var __decorateClass$1 = (decorators, target, key2, kind) => {
2693
2782
  __defProp$1(target, key2, result);
2694
2783
  return result;
2695
2784
  };
2785
+ const START = "gem-reflect-start";
2786
+ const END = "gem-reflect-end";
2787
+ const createReflectFragmentTag = (tag) => new Comment(tag);
2788
+ const getReflectFragment = (startNode) => {
2789
+ const result = [];
2790
+ let node = startNode;
2791
+ while (node) {
2792
+ result.push(node);
2793
+ if (node.nodeValue === END)
2794
+ break;
2795
+ node = node.nextSibling;
2796
+ }
2797
+ return result;
2798
+ };
2696
2799
  class GemReflectElement extends GemElement {
2697
2800
  constructor() {
2698
2801
  super({ isLight: true });
2699
2802
  this.target = document.head;
2700
- this.hidden = true;
2701
- this.dataset.gemReflect = "";
2702
2803
  this.effect(
2703
2804
  () => {
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
- });
2805
+ this.hidden = true;
2806
+ this.dataset.gemReflect = "";
2807
+ },
2808
+ () => []
2809
+ );
2810
+ const startNode = createReflectFragmentTag(START);
2811
+ const endNode = createReflectFragmentTag(END);
2812
+ let childNodes;
2813
+ this.effect(
2814
+ () => {
2815
+ if (!childNodes) {
2816
+ [startNode, ...this.childNodes, endNode].forEach((node) => this.target.append(node));
2817
+ } else {
2818
+ childNodes.forEach((node) => this.target.append(node));
2819
+ }
2711
2820
  return () => {
2821
+ childNodes = getReflectFragment(startNode);
2712
2822
  childNodes.forEach((node) => node.remove());
2713
2823
  };
2714
2824
  },
@@ -2839,7 +2949,10 @@ let GemDialogBaseElement = (_b = class extends GemElement {
2839
2949
  setTimeout(this.close, 100);
2840
2950
  return final;
2841
2951
  };
2842
- this.inert = true;
2952
+ this.effect(
2953
+ () => this.inert = true,
2954
+ () => []
2955
+ );
2843
2956
  this.internals.role = "dialog";
2844
2957
  this.internals.ariaModal = "true";
2845
2958
  }
@@ -2896,6 +3009,21 @@ function useTheme(themeObj) {
2896
3009
  const theme = createTheme(themeObj);
2897
3010
  return [theme, (newThemeObj) => updateTheme(theme, newThemeObj)];
2898
3011
  }
3012
+ class Logger {
3013
+ constructor(type) {
3014
+ this.info = (...args) => {
3015
+ console.log(`[${this._type}]:`, ...args);
3016
+ };
3017
+ this.warn = (...args) => {
3018
+ console.warn(`[${this._type}]:`, ...args);
3019
+ };
3020
+ this.error = (...args) => {
3021
+ console.error(`[${this._type}]:`, ...args);
3022
+ };
3023
+ this._type = type;
3024
+ }
3025
+ }
3026
+ const logger = new Logger("GEM");
2899
3027
  const splitReg = /\$\d(?:<[^>]*>)?/;
2900
3028
  const matchReg = /\$(\d)(<([^>]*)>)?/g;
2901
3029
  const matchStrIndex = 3;
@@ -2920,6 +3048,10 @@ const _I18n = class {
2920
3048
  __privateAdd(this, _isMain);
2921
3049
  __privateAdd(this, _lang);
2922
3050
  this.cachePrefix = "gem-i18n";
3051
+ this.replace = ({ path }) => {
3052
+ this.setLanguage(path);
3053
+ };
3054
+ this.getParams = () => ({ path: this.currentLanguage });
2923
3055
  if (!options.resources[options.fallbackLanguage]) {
2924
3056
  throw new GemError("i18n: fallbackLanguage invalid");
2925
3057
  }
@@ -2968,7 +3100,7 @@ const _I18n = class {
2968
3100
  let pack;
2969
3101
  const data = this.resources[lang];
2970
3102
  if (!data) {
2971
- console.warn(`${this.cachePrefix}: not found \`${lang}\``);
3103
+ logger.warn(`${this.cachePrefix}: not found \`${lang}\``);
2972
3104
  return this.resetLanguage();
2973
3105
  }
2974
3106
  if (typeof data === "string") {
@@ -3187,4 +3319,4 @@ const mediaQuery = {
3187
3319
  return match(this.WIDTHSCREEN);
3188
3320
  }
3189
3321
  };
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 };
3322
+ 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 };