@reckona/mreact-compat 0.0.162 → 0.0.164

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reckona/mreact-compat",
3
- "version": "0.0.162",
3
+ "version": "0.0.164",
4
4
  "description": "React-compatible runtime implementation for mreact.",
5
5
  "keywords": [
6
6
  "compatibility",
@@ -69,7 +69,7 @@
69
69
  "access": "public"
70
70
  },
71
71
  "dependencies": {
72
- "@reckona/mreact-reactive-core": "0.0.162",
73
- "@reckona/mreact-shared": "0.0.162"
72
+ "@reckona/mreact-reactive-core": "0.0.164",
73
+ "@reckona/mreact-shared": "0.0.164"
74
74
  }
75
75
  }
package/src/dom-props.ts CHANGED
@@ -283,6 +283,10 @@ export function applyPostChildFormProps(
283
283
  props: Record<string, unknown>,
284
284
  previousProps?: Record<string, unknown>,
285
285
  ): void {
286
+ if (!isPostChildFormElement(element)) {
287
+ return;
288
+ }
289
+
286
290
  if (element instanceof HTMLInputElement) {
287
291
  if (hasOwnProp(props, "checked")) {
288
292
  const checked = props.checked !== null && props.checked !== undefined && props.checked !== false;
@@ -322,6 +326,16 @@ export function applyPostChildFormProps(
322
326
  }
323
327
  }
324
328
 
329
+ function isPostChildFormElement(
330
+ element: Element,
331
+ ): element is HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement {
332
+ return (
333
+ element instanceof HTMLInputElement ||
334
+ element instanceof HTMLTextAreaElement ||
335
+ element instanceof HTMLSelectElement
336
+ );
337
+ }
338
+
325
339
  function postChildFormValue(
326
340
  props: Record<string, unknown>,
327
341
  previousProps: Record<string, unknown> | undefined,
@@ -9,12 +9,21 @@ export interface SyntheticEvent {
9
9
  type: string;
10
10
  target: EventTarget | null;
11
11
  currentTarget: EventTarget | null;
12
+ pointerId?: number;
13
+ pointerType?: string;
14
+ isPrimary?: boolean;
12
15
  clientX?: number;
13
16
  clientY?: number;
14
17
  pageX?: number;
15
18
  pageY?: number;
16
19
  screenX?: number;
17
20
  screenY?: number;
21
+ button?: number;
22
+ buttons?: number;
23
+ ctrlKey?: boolean;
24
+ shiftKey?: boolean;
25
+ altKey?: boolean;
26
+ metaKey?: boolean;
18
27
  relatedTarget?: EventTarget | null;
19
28
  touches?: TouchList;
20
29
  changedTouches?: TouchList;
package/src/events.ts CHANGED
@@ -99,10 +99,7 @@ export function toEventNames(propName: string): string[] {
99
99
  return eventNames;
100
100
  }
101
101
 
102
- export function forEachEventName(
103
- propName: string,
104
- callback: (eventName: string) => void,
105
- ): void {
102
+ export function forEachEventName(propName: string, callback: (eventName: string) => void): void {
106
103
  const directEventName = directNativeEventName(propName);
107
104
 
108
105
  if (directEventName !== undefined) {
@@ -123,10 +120,7 @@ export function forEachEventName(
123
120
  }
124
121
  }
125
122
 
126
- export function ensureDelegatedEventListenersForProp(
127
- root: Element,
128
- propName: string,
129
- ): void {
123
+ export function ensureDelegatedEventListenersForProp(root: Element, propName: string): void {
130
124
  const directEventName = directNativeEventName(propName);
131
125
 
132
126
  if (directEventName !== undefined) {
@@ -206,16 +200,11 @@ export function toEventPropNames(eventName: string): string[] {
206
200
  return [propName];
207
201
  }
208
202
 
209
- export function setLogicalEventParent(
210
- container: Element,
211
- parent: ParentNode,
212
- ): void {
203
+ export function setLogicalEventParent(container: Element, parent: ParentNode): void {
213
204
  logicalEventParents.set(container, parent);
214
205
  }
215
206
 
216
- export function getEventPriority(
217
- eventName: string,
218
- ): "discrete" | "continuous" | "default" {
207
+ export function getEventPriority(eventName: string): "discrete" | "continuous" | "default" {
219
208
  if (discreteEventNames.has(eventName)) {
220
209
  return "discrete";
221
210
  }
@@ -263,10 +252,7 @@ const continuousEventNames = new Set([
263
252
  "wheel",
264
253
  ]);
265
254
 
266
- export function ensureDelegatedEventListener(
267
- root: Element,
268
- eventName: string,
269
- ): void {
255
+ export function ensureDelegatedEventListener(root: Element, eventName: string): void {
270
256
  const listeners = delegatedRootListeners.get(root) ?? new Set<string>();
271
257
 
272
258
  if (listeners.has(eventName)) {
@@ -296,11 +282,7 @@ function markDispatchedDelegatedEvent(event: Event, eventName: string): void {
296
282
  dispatchedDelegatedEvents.set(event, events);
297
283
  }
298
284
 
299
- function dispatchDelegatedEvent(
300
- root: Element,
301
- eventName: string,
302
- event: Event,
303
- ): void {
285
+ function dispatchDelegatedEvent(root: Element, eventName: string, event: Event): void {
304
286
  const path = getEventPath(root, event);
305
287
  const propNames = toEventPropNames(eventName);
306
288
  const state = {
@@ -393,11 +375,7 @@ function dispatchEventPropNames(
393
375
  state: { defaultPrevented: boolean; propagationStopped: boolean },
394
376
  ): void {
395
377
  for (const propName of propNames) {
396
- if (
397
- propName === "onChange" &&
398
- event.type === "change" &&
399
- isTextInputChangeTarget(target)
400
- ) {
378
+ if (propName === "onChange" && event.type === "change" && isTextInputChangeTarget(target)) {
401
379
  continue;
402
380
  }
403
381
 
@@ -458,9 +436,7 @@ function dispatchMouseTransitionEvent(
458
436
 
459
437
  function isInternalMouseTransition(event: Event, target: Element): boolean {
460
438
  const relatedTarget =
461
- event instanceof MouseEvent && event.relatedTarget instanceof Node
462
- ? event.relatedTarget
463
- : null;
439
+ event instanceof MouseEvent && event.relatedTarget instanceof Node ? event.relatedTarget : null;
464
440
 
465
441
  return relatedTarget !== null && target.contains(relatedTarget);
466
442
  }
@@ -505,6 +481,10 @@ function createSyntheticEvent(
505
481
  syntheticType = nativeEvent.type,
506
482
  ): SyntheticEvent {
507
483
  const mouseEvent = nativeEvent instanceof MouseEvent ? nativeEvent : undefined;
484
+ const pointerEvent =
485
+ "pointerId" in nativeEvent || "pointerType" in nativeEvent
486
+ ? (nativeEvent as PointerEvent)
487
+ : undefined;
508
488
  const touchEvent = nativeEvent instanceof TouchEvent ? nativeEvent : undefined;
509
489
  const keyboardEvent = nativeEvent instanceof KeyboardEvent ? nativeEvent : undefined;
510
490
 
@@ -530,8 +510,21 @@ function createSyntheticEvent(
530
510
  pageY: mouseEvent.pageY,
531
511
  screenX: mouseEvent.screenX,
532
512
  screenY: mouseEvent.screenY,
513
+ button: mouseEvent.button,
514
+ buttons: mouseEvent.buttons,
515
+ ctrlKey: mouseEvent.ctrlKey,
516
+ shiftKey: mouseEvent.shiftKey,
517
+ altKey: mouseEvent.altKey,
518
+ metaKey: mouseEvent.metaKey,
533
519
  relatedTarget: mouseEvent.relatedTarget,
534
520
  }),
521
+ ...(pointerEvent === undefined
522
+ ? {}
523
+ : {
524
+ pointerId: pointerEvent.pointerId,
525
+ pointerType: pointerEvent.pointerType,
526
+ isPrimary: pointerEvent.isPrimary,
527
+ }),
535
528
  ...(touchEvent === undefined
536
529
  ? {}
537
530
  : {
@@ -106,13 +106,17 @@ function reconcileSameKeyOrderChildren(
106
106
  }
107
107
 
108
108
  let cursor: Fiber | undefined = currentFirstChild;
109
+ let matchedCount = 0;
109
110
 
110
111
  for (const child of children) {
112
+ if (cursor === undefined) {
113
+ break;
114
+ }
115
+
111
116
  const key = getNodeKey(child);
112
117
 
113
118
  if (
114
119
  key === undefined ||
115
- cursor === undefined ||
116
120
  cursor.key !== key ||
117
121
  !isReactCompatElement(child) ||
118
122
  !canReuseElementFiber(cursor, child)
@@ -121,9 +125,10 @@ function reconcileSameKeyOrderChildren(
121
125
  }
122
126
 
123
127
  cursor = cursor.sibling;
128
+ matchedCount += 1;
124
129
  }
125
130
 
126
- if (cursor !== undefined) {
131
+ if (matchedCount === 0 || cursor !== undefined) {
127
132
  return undefined;
128
133
  }
129
134
 
@@ -131,9 +136,11 @@ function reconcileSameKeyOrderChildren(
131
136
  let first: Fiber | undefined;
132
137
  let previous: Fiber | undefined;
133
138
 
134
- for (const child of children) {
139
+ for (let index = 0; index < children.length; index += 1) {
140
+ const child = children[index] as ReactCompatNode;
135
141
  const key = getNodeKey(child) as string;
136
- const fiber = reconcileSingleChild(parent, cursor, child, key) as Fiber;
142
+ const matchedCurrent: Fiber | undefined = index < matchedCount ? cursor : undefined;
143
+ const fiber = reconcileSingleChild(parent, matchedCurrent, child, key) as Fiber;
137
144
 
138
145
  fiber.lanes |= parent.lanes;
139
146
  fiber.return = parent;
@@ -146,7 +153,7 @@ function reconcileSameKeyOrderChildren(
146
153
  }
147
154
 
148
155
  previous = fiber;
149
- cursor = cursor?.sibling;
156
+ cursor = matchedCurrent?.sibling;
150
157
  }
151
158
 
152
159
  parent.child = first;
@@ -435,10 +435,7 @@ function reconcileKeyedRowHostChildren(
435
435
  let subtreeFlags = NoFlags;
436
436
  let subtreeChildListChanged = false;
437
437
  let hasRefSubtree = false;
438
- const currentSiblingCount = countFiberSiblings(currentFirstChild);
439
- const canReuseUnchangedRows =
440
- currentSiblingCount === children.length ||
441
- isKeyedAppendOnly(currentFirstChild, children, currentSiblingCount);
438
+ const canReuseUnchangedRows = hasSameKeyOrderPrefix(currentFirstChild, children);
442
439
  const row = createKeyedRowHostElementScratch();
443
440
 
444
441
  for (let index = 0; index < children.length; index += 1) {
@@ -514,33 +511,21 @@ function reconcileKeyedRowHostChildren(
514
511
  return { fiber: first, consumed: 0 };
515
512
  }
516
513
 
517
- function countFiberSiblings(first: Fiber): number {
518
- let count = 0;
519
- let cursor: Fiber | undefined = first;
520
-
521
- while (cursor !== undefined) {
522
- count += 1;
523
- cursor = cursor.sibling;
524
- }
525
-
526
- return count;
527
- }
528
-
529
- function isKeyedAppendOnly(
514
+ function hasSameKeyOrderPrefix(
530
515
  currentFirstChild: Fiber,
531
516
  children: readonly ReactCompatNode[],
532
- currentSiblingCount: number,
533
517
  ): boolean {
534
- if (children.length <= currentSiblingCount) {
535
- return false;
536
- }
537
-
538
518
  let current: Fiber | undefined = currentFirstChild;
539
519
 
540
- for (let index = 0; index < currentSiblingCount; index += 1) {
541
- if (current === undefined || current.key !== getNodeKey(children[index])) {
520
+ for (let index = 0; index < children.length; index += 1) {
521
+ if (current === undefined) {
522
+ return true;
523
+ }
524
+
525
+ if (current.key !== getNodeKey(children[index])) {
542
526
  return false;
543
527
  }
528
+
544
529
  current = current.sibling;
545
530
  }
546
531