@mantou/gem 2.2.2 → 2.2.4

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.
package/lib/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const version = "0.0.0";
1
+ export declare const version = "2.2.4";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/lib/version.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,OAAO,UAAU,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/lib/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAC"}
package/lib/version.js CHANGED
@@ -1,3 +1,2 @@
1
- // Do not modify manually
2
- export const version = '0.0.0';
1
+ export const version = '2.2.4';
3
2
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/lib/version.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/lib/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mantou/gem",
3
- "version": "2.2.2",
3
+ "version": "2.2.4",
4
4
  "description": "💎 使用自定义元素的轻量级 WebApp 开发框架",
5
5
  "keywords": [
6
6
  "frontend",
@@ -41,7 +41,7 @@
41
41
  "test": "cross-env wtr"
42
42
  },
43
43
  "devDependencies": {
44
- "@gemjs/config": "^2.1.2",
44
+ "@gemjs/config": "^2.1.3",
45
45
  "@types/chai": "^5.0.0",
46
46
  "@types/mocha": "^10.0.7",
47
47
  "@types/trusted-types": "^2.0.7",
@@ -11,6 +11,7 @@ export type PanEventDetail = {
11
11
  timeStamp: number;
12
12
  isPrimary: boolean;
13
13
  pointerId: number;
14
+ pressed: boolean;
14
15
  };
15
16
  export interface SwipeEventDetail {
16
17
  direction: 'top' | 'right' | 'bottom' | 'left';
@@ -143,7 +144,7 @@ export class GemGestureElement extends GemElement {
143
144
 
144
145
  #onMove = (evt: PointerEvent) => {
145
146
  const { pointerId, clientX, clientY, isPrimary, pointerType, timeStamp } = evt;
146
- if (!this.#pressed && this.hasPointerCapture(pointerId)) {
147
+ if (this.hasPointerCapture(pointerId)) {
147
148
  const moves = this.#getMoves(pointerId);
148
149
  const startEvent = this.#getStartEvent(pointerId);
149
150
  const lastMove = moves[moves.length - 1] || startEvent;
@@ -161,6 +162,7 @@ export class GemGestureElement extends GemElement {
161
162
  timeStamp,
162
163
  isPrimary,
163
164
  pointerId,
165
+ pressed: this.#pressed,
164
166
  };
165
167
  moves.push(move);
166
168
  this.pan(move);
@@ -8,9 +8,9 @@ type Options = {
8
8
  origin?: string;
9
9
  base?: string;
10
10
  // only for get/del/put/post
11
- appendHeaders?: (input?: any) => HeadersInit;
12
- transformInput?: (input?: any) => any;
13
- transformOutput?: (output: any, req: Request) => any;
11
+ appendHeaders?: (input?: any) => HeadersInit | Promise<HeadersInit>;
12
+ transformInput?: (input?: any) => any | Promise<any>;
13
+ transformOutput?: (output: any, req: Request) => any | Promise<any>;
14
14
  } & RequestInit;
15
15
 
16
16
  function initRequest(options: Options = {}) {
@@ -83,7 +83,7 @@ function initRequest(options: Options = {}) {
83
83
  data = await res.text();
84
84
  }
85
85
  if (isClientError) throw new (Error as any)(res.statusText, { cause: data });
86
- return transformOutput(data, req);
86
+ return await transformOutput(data, req);
87
87
  } catch {
88
88
  throw new Error('Parse error');
89
89
  }
@@ -91,33 +91,33 @@ function initRequest(options: Options = {}) {
91
91
 
92
92
  return {
93
93
  request,
94
- get<T>(path: string, params?: ReqParams) {
95
- const i = transformInput(params);
94
+ async get<T>(path: string, params?: ReqParams) {
95
+ const i = await transformInput(params);
96
96
  return request<T>(serializationUrl(path, i), {
97
97
  method: 'GET',
98
- headers: appendHeaders(i),
98
+ headers: await appendHeaders(i),
99
99
  });
100
100
  },
101
- del<T>(path: string, params?: ReqParams) {
102
- const i = transformInput(params);
101
+ async del<T>(path: string, params?: ReqParams) {
102
+ const i = await transformInput(params);
103
103
  return request<T>(serializationUrl(path, i), {
104
104
  method: 'DELETE',
105
- headers: appendHeaders(i),
105
+ headers: await appendHeaders(i),
106
106
  });
107
107
  },
108
- put<T>(path: string, body?: ReqBody) {
109
- const i = transformInput(body);
108
+ async put<T>(path: string, body?: ReqBody) {
109
+ const i = await transformInput(body);
110
110
  return request<T>(serializationUrl(path), {
111
111
  method: 'PUT',
112
- headers: appendHeaders(i),
112
+ headers: await appendHeaders(i),
113
113
  body: serializationBody(i),
114
114
  });
115
115
  },
116
- post<T>(path: string, body?: ReqBody) {
117
- const i = transformInput(body);
116
+ async post<T>(path: string, body?: ReqBody) {
117
+ const i = await transformInput(body);
118
118
  return request<T>(serializationUrl(path), {
119
119
  method: 'POST',
120
- headers: appendHeaders(i),
120
+ headers: await appendHeaders(i),
121
121
  body: serializationBody(i),
122
122
  });
123
123
  },
@@ -126,4 +126,4 @@ function initRequest(options: Options = {}) {
126
126
 
127
127
  const { request, del, get, post, put } = initRequest();
128
128
 
129
- export { initRequest, request, del, get, post, put };
129
+ export { del, get, initRequest, post, put, request };
@@ -482,15 +482,10 @@ export function connectStore(store: Store<any>) {
482
482
  };
483
483
  }
484
484
 
485
- export function shadow({
486
- mode = 'open',
487
- serializable = true,
488
- delegatesFocus,
489
- slotAssignment,
490
- }: Partial<ShadowRootInit> = {}) {
485
+ export function shadow({ mode = 'open', serializable = true, ...rest }: Partial<ShadowRootInit> = {}) {
491
486
  return (_: any, context: ClassDecoratorContext) => {
492
487
  const metadata = context.metadata as Metadata;
493
- assign(metadata, { mode, serializable, delegatesFocus, slotAssignment });
488
+ assign(metadata, { mode, serializable, ...rest });
494
489
  };
495
490
  }
496
491
 
@@ -374,6 +374,7 @@ const getTemplateHtml = (strings: TemplateStringsArray, type: ResultType): [Trus
374
374
 
375
375
  /** @internal */
376
376
  export type { Template };
377
+
377
378
  class Template {
378
379
  /** @internal */
379
380
  el!: HTMLTemplateElement;
@@ -547,15 +548,13 @@ function resolveDirective(
547
548
  return value;
548
549
  }
549
550
 
550
- export type { TemplateInstance };
551
551
  /**
552
552
  * An updateable instance of a Template. Holds references to the Parts used to
553
553
  * update the template instance.
554
554
  */
555
- class TemplateInstance implements Disconnectable {
555
+ export class TemplateInstance implements Disconnectable {
556
556
  _$template: Template;
557
557
  _$parts: Array<Part | undefined> = [];
558
- /** @internal */
559
558
  _$conditions: ConditionChain[] = [];
560
559
 
561
560
  /** @internal */
@@ -656,12 +655,13 @@ class TemplateInstance implements Disconnectable {
656
655
  }
657
656
  }
658
657
 
659
- class ConditionChain {
658
+ export class ConditionChain {
660
659
  readonly mark: Comment;
661
660
  readonly list: { ele: Element; idx?: number }[];
662
661
 
663
662
  constructor(ele: Element, idx: number) {
664
663
  const mark = createMarker();
664
+ (mark as any)._$chain = this;
665
665
  ele.before(mark);
666
666
  this.mark = mark;
667
667
  this.list = [{ ele, idx }];
@@ -1012,6 +1012,7 @@ export interface RootPart extends ChildPart {
1012
1012
  }
1013
1013
 
1014
1014
  export type { AttributePart };
1015
+
1015
1016
  class AttributePart implements Disconnectable {
1016
1017
  readonly type: typeof ATTRIBUTE_PART | typeof PROPERTY_PART | typeof BOOLEAN_ATTRIBUTE_PART | typeof EVENT_PART =
1017
1018
  ATTRIBUTE_PART;
@@ -1135,6 +1136,7 @@ class AttributePart implements Disconnectable {
1135
1136
  }
1136
1137
 
1137
1138
  export type { PropertyPart };
1139
+
1138
1140
  class PropertyPart extends AttributePart {
1139
1141
  override readonly type = PROPERTY_PART;
1140
1142
 
@@ -1145,6 +1147,7 @@ class PropertyPart extends AttributePart {
1145
1147
  }
1146
1148
 
1147
1149
  export type { BooleanAttributePart };
1150
+
1148
1151
  class BooleanAttributePart extends AttributePart {
1149
1152
  override readonly type = BOOLEAN_ATTRIBUTE_PART;
1150
1153
 
@@ -1157,6 +1160,7 @@ class BooleanAttributePart extends AttributePart {
1157
1160
  type EventListenerWithOptions = EventListenerOrEventListenerObject & Partial<AddEventListenerOptions>;
1158
1161
 
1159
1162
  export type { EventPart };
1163
+
1160
1164
  class EventPart extends AttributePart {
1161
1165
  override readonly type = EVENT_PART;
1162
1166
 
@@ -1192,8 +1196,7 @@ class EventPart extends AttributePart {
1192
1196
  }
1193
1197
  }
1194
1198
 
1195
- export type { ElementPart };
1196
- class ElementPart implements Disconnectable {
1199
+ export class ElementPart implements Disconnectable {
1197
1200
  readonly type = ELEMENT_PART;
1198
1201
 
1199
1202
  /** @internal */
@@ -1247,6 +1250,7 @@ class ElementPart implements Disconnectable {
1247
1250
  export const createRef = <T = Element>() => new Ref<T>();
1248
1251
 
1249
1252
  export type { Ref };
1253
+
1250
1254
  class Ref<T = Element> {
1251
1255
  value?: T;
1252
1256
  }
@@ -25,6 +25,14 @@ export function setEngine(h: typeof Lit.html, r: typeof Lit.render) {
25
25
  render = r;
26
26
  }
27
27
 
28
+ let hydrationEngine = (_value: unknown, _container: HTMLElement | DocumentFragment): Lit.RootPart | undefined => {
29
+ return;
30
+ };
31
+
32
+ export function setHydrationEngine(engine: typeof hydrationEngine) {
33
+ hydrationEngine = engine;
34
+ }
35
+
28
36
  const { assign, defineProperty } = Object;
29
37
 
30
38
  // https://github.com/tc39/proposal-decorator-metadata
@@ -41,6 +49,7 @@ export type SheetTokenType = typeof SheetToken;
41
49
  export const UpdateToken = Symbol.for('gem@update');
42
50
 
43
51
  const BoundaryCSSState = 'gem-style-boundary';
52
+ const ElementCSSState = 'gem-element';
44
53
 
45
54
  /**@internal */
46
55
  export const _RenderErrorEvent = 'gem@render-error';
@@ -188,7 +197,7 @@ const appleCSSStyleSheet = (ele: HTMLElement, sheets: CSSStyleSheet[]) => {
188
197
  rootStyleSheetInfo.set(root, map);
189
198
  rootUpdateFnMap.set(map, () => {
190
199
  // 先找到外部样式表
191
- const newSheets = root.adoptedStyleSheets.filter((e) => !map.has(e));
200
+ const newSheets = (root.adoptedStyleSheets || []).filter((e) => !map.has(e));
192
201
  map.forEach((count, sheet) => count && newSheets.push(sheet));
193
202
  // 外层元素的样式要放到最后,以提升优先级,但是只考虑第一次出现样式表的位置
194
203
  root.adoptedStyleSheets = newSheets.reverse();
@@ -247,6 +256,10 @@ export let _createTemplate: (ele: GemElement, item: RenderItem) => void;
247
256
  export type Metadata = Partial<ShadowRootInit> & {
248
257
  /** 内容可被外部样式化 */
249
258
  penetrable?: boolean;
259
+ /**
260
+ * 这个属性用来解决同步渲染长列表,且渲染过程有大量计算阻塞主线程
261
+ * 否则应该考虑 `content-visibility: auto` 和虚拟列表
262
+ */
250
263
  noBlocking?: boolean;
251
264
  aria?: Partial<
252
265
  ARIAMixin & {
@@ -271,7 +284,7 @@ export type Metadata = Partial<ShadowRootInit> & {
271
284
  // global render task pool
272
285
  const noBlockingTaskList = new LinkedList<() => void>();
273
286
  const tick = (timeStamp = performance.now()) => {
274
- if (performance.now() > timeStamp + 16) return requestAnimationFrame(tick);
287
+ if (performance.now() > timeStamp + 50) return requestAnimationFrame(tick);
275
288
  const task = noBlockingTaskList.get();
276
289
  if (task) {
277
290
  task();
@@ -347,10 +360,11 @@ export abstract class GemElement extends HTMLElement {
347
360
 
348
361
  currentConstructGemElement = this;
349
362
 
350
- const { mode, serializable, delegatesFocus, slotAssignment, aria } = this.#metadata;
363
+ const { aria, mode, delegatesFocus, ...rest } = this.#metadata;
351
364
  const { focusable, ...internalsAria } = aria || {};
352
365
 
353
- this.#renderRoot = !mode ? this : this.attachShadow({ mode, serializable, delegatesFocus, slotAssignment });
366
+ // 这里认为 rest 不会有自定义字段和 ShadowRootInit 参数冲突
367
+ this.#renderRoot = !mode ? this : this.shadowRoot || this.attachShadow({ mode, delegatesFocus, ...rest });
354
368
  this.#internals = this.attachInternals() as GemElement['internals'];
355
369
  this.#internals.stateList = [];
356
370
  this.#internals.sheets = [];
@@ -415,10 +429,8 @@ export abstract class GemElement extends HTMLElement {
415
429
  const isLight = this.#renderRoot === this;
416
430
  const temp = item ? item.render() : isLight ? undefined : html`<slot></slot>`;
417
431
  if (temp === undefined) return;
418
- render(
419
- temp !== null ? temp : html`<style>${isLight ? '@scope' : ':host'}{&{display:none!important;}}</style>`,
420
- this.#renderRoot,
421
- );
432
+ const r = temp !== null ? temp : html`<style>${isLight ? '@scope' : ':host'}{&{display:none!important;}}</style>`;
433
+ hydrationEngine(r, this.#renderRoot) || render(r, this.#renderRoot);
422
434
  } catch (err) {
423
435
  this.dispatchEvent(new CustomEvent(_RenderErrorEvent, { bubbles: true, composed: true, detail: err }));
424
436
  throw err;
@@ -507,6 +519,8 @@ export abstract class GemElement extends HTMLElement {
507
519
 
508
520
  const { observedStores, mode, penetrable } = this.#metadata;
509
521
 
522
+ // https://github.com/w3c/csswg-drafts/issues/10407#issuecomment-4418616596
523
+ this.#internals.states.add(ElementCSSState);
510
524
  // 有渲染函数的 light dom 应该添加边界,防止内容被外部样式化
511
525
  // 如果渲染内容需要应用外部样式,需要手动 `delete` 边界
512
526
  if (!mode && this.#renderList.length && !penetrable) this.#internals.states.add(BoundaryCSSState);
@@ -1,2 +1 @@
1
- // Do not modify manually
2
- export const version = '0.0.0';
1
+ export const version = '2.2.4';