@fc3/mmcadi 0.1.56 → 0.1.58

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.
@@ -1 +1 @@
1
- 1767665040
1
+ 1767847432
@@ -1 +1 @@
1
- 1767665144
1
+ 1767848006
package/dist/client.js CHANGED
@@ -2280,20 +2280,29 @@
2280
2280
  var InteractionHelper = class {
2281
2281
  constructor() {
2282
2282
  this.drag_start_coordinate = null;
2283
+ this.drag_current_coordinate = null;
2283
2284
  this.drag_delay_timer = null;
2285
+ this.scroll_timer = null;
2286
+ this.scroll_direction = null;
2287
+ this.last_scroll_time = null;
2288
+ this.current_scroll_y = null;
2284
2289
  }
2285
2290
  attach() {
2286
- document.addEventListener("pointerdown", (event) => {
2287
- this.handlePointerDown(event);
2291
+ if (!this.isTouchDevice()) {
2292
+ return;
2293
+ }
2294
+ this.applyNonInteractiveClasses();
2295
+ document.addEventListener("touchstart", (event) => {
2296
+ this.handleTouchStart(event);
2288
2297
  }, { capture: true });
2289
- document.addEventListener("pointermove", (event) => {
2290
- this.handlePointerMove(event);
2298
+ document.addEventListener("touchmove", (event) => {
2299
+ this.handleTouchMove(event);
2291
2300
  }, { capture: true, passive: false });
2292
- document.addEventListener("pointerup", (event) => {
2293
- this.handlePointerUp(event);
2301
+ document.addEventListener("touchend", (event) => {
2302
+ this.handleTouchEnd(event);
2294
2303
  }, { capture: true });
2295
- document.addEventListener("pointercancel", (event) => {
2296
- this.handlePointerCancel(event);
2304
+ document.addEventListener("click", (event) => {
2305
+ this.handleGenericClick(event);
2297
2306
  }, { capture: true });
2298
2307
  document.addEventListener("dragstart", (event) => {
2299
2308
  this.handleNativeDragStart(event);
@@ -2303,14 +2312,29 @@
2303
2312
  const elements = Array.from(document.querySelectorAll(".dragging"));
2304
2313
  return elements.length > 0;
2305
2314
  }
2306
- handlePointerDown(event) {
2315
+ applyNonInteractiveClasses() {
2316
+ const raw_elements = document.querySelectorAll("section.block");
2317
+ const elements = Array.from(raw_elements);
2318
+ elements.forEach((element) => {
2319
+ element.classList.add("no-interaction");
2320
+ });
2321
+ }
2322
+ isTouchDevice() {
2323
+ if (Math.random() > 0) {
2324
+ return true;
2325
+ }
2326
+ const pointer_matches = window.matchMedia("(pointer: coarse)").matches;
2327
+ const hover_none_matches = window.matchMedia("(hover: none)").matches;
2328
+ return pointer_matches && hover_none_matches;
2329
+ }
2330
+ handleTouchStart(event) {
2307
2331
  const { target } = event;
2308
2332
  if (target === null) {
2309
2333
  return;
2310
2334
  }
2311
2335
  const target_element = target;
2312
2336
  let current_element = target_element;
2313
- while (current_element) {
2337
+ while (current_element instanceof HTMLElement) {
2314
2338
  const attribute = current_element.getAttribute("data-role");
2315
2339
  if (attribute === "block_activation") {
2316
2340
  break;
@@ -2319,24 +2343,23 @@
2319
2343
  return;
2320
2344
  }
2321
2345
  current_element = current_element.parentNode;
2322
- if (!(current_element instanceof HTMLElement)) {
2323
- break;
2324
- }
2325
2346
  }
2326
2347
  const block = target_element.closest("section.block");
2327
2348
  if (block === null) {
2328
2349
  return;
2329
2350
  }
2330
- if (target_element.closest("button, input, textarea, select, label, form")) {
2351
+ if (target_element.closest("input, textarea, select, label, form")) {
2331
2352
  return;
2332
2353
  }
2333
2354
  const coordinate = this.getEventCoordinate(event);
2334
2355
  if (coordinate === null) {
2335
2356
  return;
2336
2357
  }
2337
- this.drag_start_coordinate = coordinate;
2358
+ this.setDragStartCoordinate(coordinate);
2359
+ this.setDragCurrentCoordinate(coordinate);
2338
2360
  block.classList.add("drag-candidate");
2339
2361
  this.scheduleDelayedDrag();
2362
+ event.preventDefault();
2340
2363
  }
2341
2364
  scheduleDelayedDrag() {
2342
2365
  this.cancelDelayedDrag();
@@ -2348,7 +2371,8 @@
2348
2371
  clearTimeout(this.drag_delay_timer);
2349
2372
  }
2350
2373
  }
2351
- removeClassFromAllElements(class_name) {
2374
+ demoteAllDragCandidates() {
2375
+ const class_name = "drag-candidate";
2352
2376
  const raw_elements = document.querySelectorAll(`.${class_name}`);
2353
2377
  const elements = Array.from(raw_elements);
2354
2378
  elements.forEach((element) => {
@@ -2356,7 +2380,22 @@
2356
2380
  });
2357
2381
  return elements;
2358
2382
  }
2383
+ createDragMask() {
2384
+ const mask = document.createElement("div");
2385
+ mask.classList.add("drag-mask");
2386
+ document.body.appendChild(mask);
2387
+ document.body.style.overflow = "hidden";
2388
+ }
2389
+ hideDragMask() {
2390
+ const raw_elements = document.querySelectorAll(".drag-mask");
2391
+ const elements = Array.from(raw_elements);
2392
+ elements.forEach((element) => {
2393
+ document.body.removeChild(element);
2394
+ });
2395
+ document.body.style.overflow = "auto";
2396
+ }
2359
2397
  beginDelayedDrag() {
2398
+ this.createDragMask();
2360
2399
  const raw_candidates = document.querySelectorAll(".drag-candidate");
2361
2400
  const candidates = Array.from(raw_candidates);
2362
2401
  candidates.forEach((candidate) => {
@@ -2380,6 +2419,7 @@
2380
2419
  });
2381
2420
  candidate.setAttribute("data-drag-start-x", rect.left.toString());
2382
2421
  candidate.setAttribute("data-drag-start-y", rect.top.toString());
2422
+ candidate.setAttribute("data-dragging", "true");
2383
2423
  candidate.classList.add("dragging");
2384
2424
  parentNode.insertBefore(ghost, candidate);
2385
2425
  });
@@ -2394,39 +2434,28 @@
2394
2434
  event.preventDefault();
2395
2435
  }
2396
2436
  }
2397
- handlePointerMove(event) {
2437
+ handleTouchMove(event) {
2398
2438
  const current_coordinate = this.getEventCoordinate(event);
2399
2439
  const start_coordinate = this.getDragStartCoordinate();
2400
2440
  if (start_coordinate === null || current_coordinate === null) {
2401
2441
  return;
2402
2442
  }
2403
- const { target } = event;
2404
- if (target !== null) {
2405
- const target_element = target;
2406
- const block = target_element.closest("section.block");
2407
- if (block) {
2408
- if (!block.classList.contains("dragging")) {
2409
- block.classList.add("drag-candidate");
2410
- }
2411
- }
2412
- }
2413
- const { x: start_x, y: start_y } = start_coordinate;
2414
- const { x: current_x, y: current_y } = current_coordinate;
2415
- const distance = Math.hypot(current_x - start_x, current_y - start_y);
2416
- if (distance > 25) {
2417
- this.removeClassFromAllElements("drag-candidate");
2418
- }
2443
+ this.demoteAllDragCandidates();
2419
2444
  this.scheduleDelayedDrag();
2445
+ this.setDragCurrentCoordinate(current_coordinate);
2446
+ this.updateDragTargets();
2447
+ if (this.isDragging()) {
2448
+ event.preventDefault();
2449
+ }
2450
+ }
2451
+ updateDragTargets() {
2420
2452
  const raw_targets = document.querySelectorAll(".dragging");
2421
2453
  const drag_target_blocks = Array.from(raw_targets);
2422
2454
  drag_target_blocks.forEach((target_block) => {
2423
- this.translateDragTargetBlock(target_block, current_coordinate);
2455
+ this.updateDragTarget(target_block);
2424
2456
  });
2425
- if (drag_target_blocks.length > 0) {
2426
- event.preventDefault();
2427
- }
2428
2457
  }
2429
- translateDragTargetBlock(block, current_coordinate) {
2458
+ updateDragTarget(block) {
2430
2459
  const x_attribute = block.getAttribute("data-drag-start-x");
2431
2460
  const y_attribute = block.getAttribute("data-drag-start-y");
2432
2461
  if (x_attribute === null || y_attribute === null) {
@@ -2446,17 +2475,36 @@
2446
2475
  `);
2447
2476
  }
2448
2477
  const start_coordinate = this.getDragStartCoordinate();
2478
+ const current_coordinate = this.getDragCurrentCoordinate();
2449
2479
  if (start_coordinate === null) {
2450
2480
  throw new import_errors8.InvariantViolation(`
2451
2481
  Tried to translate drag target, but drag start coordinate was null
2452
2482
  `);
2453
2483
  }
2484
+ if (current_coordinate === null) {
2485
+ throw new import_errors8.InvariantViolation(`
2486
+ Tried to translate drag target, but drag current coordinate was null
2487
+ `);
2488
+ }
2454
2489
  const { x: start_x, y: start_y } = start_coordinate;
2455
2490
  const { x: current_x, y: current_y } = current_coordinate;
2456
2491
  const x_delta = current_x - start_x;
2457
2492
  const y_delta = current_y - start_y;
2493
+ const container = document.querySelector("main");
2494
+ if (container === null) {
2495
+ throw new import_errors8.InvariantViolation(`
2496
+ Unable to find <main> container element in the DOM
2497
+ `);
2498
+ }
2499
+ const container_rect = container.getBoundingClientRect();
2458
2500
  const new_x = parsed_x + x_delta;
2459
- const new_y = parsed_y + y_delta;
2501
+ const new_y = Math.max(
2502
+ container_rect.top,
2503
+ Math.min(
2504
+ parsed_y + y_delta,
2505
+ container_rect.bottom
2506
+ )
2507
+ );
2460
2508
  block.style.left = `${new_x}px`;
2461
2509
  block.style.top = `${new_y}px`;
2462
2510
  const block_rect = block.getBoundingClientRect();
@@ -2487,6 +2535,91 @@
2487
2535
  }
2488
2536
  }
2489
2537
  }
2538
+ if (block_rect.top < 0) {
2539
+ this.startScrollingUp();
2540
+ } else if (block_rect.bottom > window.innerHeight) {
2541
+ this.startScrollingDown();
2542
+ } else {
2543
+ this.stopScrolling();
2544
+ }
2545
+ }
2546
+ stopScrolling() {
2547
+ this.setScrollDirection(null);
2548
+ }
2549
+ startScrollingUp() {
2550
+ this.setScrollDirection("up" /* UP */);
2551
+ }
2552
+ startScrollingDown() {
2553
+ this.setScrollDirection("down" /* DOWN */);
2554
+ }
2555
+ setScrollDirection(scroll_direction) {
2556
+ if (this.scroll_direction === scroll_direction) {
2557
+ return;
2558
+ }
2559
+ this.scroll_direction = scroll_direction;
2560
+ if (scroll_direction === null) {
2561
+ this.last_scroll_time = null;
2562
+ this.current_scroll_y = null;
2563
+ } else {
2564
+ this.last_scroll_time = Date.now();
2565
+ this.current_scroll_y = window.scrollY;
2566
+ this.scheduleScroll();
2567
+ }
2568
+ }
2569
+ getScrollDirection() {
2570
+ return this.scroll_direction;
2571
+ }
2572
+ setLastScrollTime(time) {
2573
+ this.last_scroll_time = time;
2574
+ }
2575
+ getLastScrollTime() {
2576
+ if (this.last_scroll_time === null) {
2577
+ throw new import_errors8.InvariantViolation(`
2578
+ Tried to read last scroll time, but it was not set
2579
+ `);
2580
+ }
2581
+ return this.last_scroll_time;
2582
+ }
2583
+ scheduleScroll() {
2584
+ if (this.scroll_timer) {
2585
+ window.cancelAnimationFrame(this.scroll_timer);
2586
+ this.scroll_timer = null;
2587
+ }
2588
+ this.scroll_timer = window.requestAnimationFrame(() => {
2589
+ this.scroll();
2590
+ });
2591
+ }
2592
+ scroll() {
2593
+ if (!this.isDragging()) {
2594
+ return;
2595
+ }
2596
+ const scroll_direction = this.getScrollDirection();
2597
+ if (scroll_direction === null) {
2598
+ return;
2599
+ }
2600
+ const last_scroll_time = this.getLastScrollTime();
2601
+ const now = Date.now();
2602
+ const elapsed_time = now - last_scroll_time;
2603
+ const scroll_speed_per_second = window.innerHeight / 2;
2604
+ const time_ratio = elapsed_time / import_time.TimeInterval.ONE_SECOND;
2605
+ const scroll_amount = scroll_speed_per_second * time_ratio;
2606
+ const scroll_y = this.getCurrentScrollY();
2607
+ const sign = scroll_direction === "up" /* UP */ ? -1 : 1;
2608
+ const new_scroll_y = Math.max(
2609
+ 0,
2610
+ Math.min(
2611
+ document.documentElement.scrollHeight,
2612
+ scroll_y + scroll_amount * sign
2613
+ )
2614
+ );
2615
+ this.setCurrentScrollY(new_scroll_y);
2616
+ this.setLastScrollTime(now);
2617
+ const window_moved = new_scroll_y !== scroll_y;
2618
+ if (window_moved) {
2619
+ window.scrollTo(0, new_scroll_y);
2620
+ this.updateDragTargets();
2621
+ }
2622
+ this.scheduleScroll();
2490
2623
  }
2491
2624
  getGhostForBlock(block) {
2492
2625
  const index_path = get_index_path_for_element_default(block);
@@ -2530,12 +2663,16 @@
2530
2663
  if (index === -1) {
2531
2664
  throw new import_errors8.InvariantViolation("Unable to locate ghost within siblings");
2532
2665
  }
2666
+ index++;
2533
2667
  while (index < siblings.length) {
2534
- index++;
2535
- const sibling = siblings[index];
2668
+ const sibling = siblings[index++];
2536
2669
  if (sibling === block) {
2537
2670
  continue;
2538
2671
  }
2672
+ if (sibling === void 0) {
2673
+ console.log(sibling);
2674
+ console.log(siblings);
2675
+ }
2539
2676
  const { classList } = sibling;
2540
2677
  if (!classList.contains("block")) {
2541
2678
  continue;
@@ -2547,26 +2684,36 @@
2547
2684
  }
2548
2685
  return null;
2549
2686
  }
2550
- handlePointerUp(event) {
2687
+ handleTouchEnd(event) {
2551
2688
  this.stopDragging();
2552
2689
  }
2553
- handlePointerCancel(event) {
2554
- this.stopDragging();
2690
+ handleGenericClick(event) {
2691
+ const { target } = event;
2692
+ if (target === null) {
2693
+ return;
2694
+ }
2695
+ const target_element = target;
2696
+ const block = target_element.closest("section.block");
2697
+ if (block === null) {
2698
+ return;
2699
+ }
2700
+ const attribute = block.getAttribute("data-dragging");
2701
+ if (attribute === "true") {
2702
+ block.removeAttribute("data-dragging");
2703
+ event.preventDefault();
2704
+ event.stopPropagation();
2705
+ }
2555
2706
  }
2556
2707
  stopDragging() {
2557
- this.showFullscreenBlockingOverlay();
2558
2708
  this.stopDraggingAsync().then(() => {
2559
- this.hideFullscreenBlockingOverlay();
2709
+ this.hideDragMask();
2560
2710
  });
2561
2711
  }
2562
- showFullscreenBlockingOverlay() {
2563
- }
2564
- hideFullscreenBlockingOverlay() {
2565
- }
2566
2712
  async stopDraggingAsync() {
2567
2713
  this.cancelDelayedDrag();
2568
- this.removeClassFromAllElements("drag-candidate");
2569
- const dragging_elements = this.removeClassFromAllElements("dragging");
2714
+ this.demoteAllDragCandidates();
2715
+ const raw_elements = document.querySelectorAll(".dragging");
2716
+ const dragging_elements = Array.from(raw_elements);
2570
2717
  let index = 0;
2571
2718
  while (index < dragging_elements.length) {
2572
2719
  const element = dragging_elements[index++];
@@ -2574,8 +2721,8 @@
2574
2721
  const source_index_path = get_index_path_for_element_default(element);
2575
2722
  const target_index_path = this.getIndexPathForGhost(ghost);
2576
2723
  await this.submitReposition(source_index_path, target_index_path);
2577
- ghost.replaceWith(element);
2578
2724
  Object.assign(element.style, {
2725
+ opacity: "0",
2579
2726
  left: "",
2580
2727
  top: "",
2581
2728
  right: "",
@@ -2583,39 +2730,55 @@
2583
2730
  width: "",
2584
2731
  height: ""
2585
2732
  });
2733
+ element.classList.remove("dragging");
2734
+ ghost.replaceWith(element);
2735
+ element.style.opacity = "1";
2586
2736
  }
2737
+ this.recomputeIndexPaths();
2587
2738
  }
2588
- getIndexPathSafe(element) {
2589
- const is_block = element.classList.contains("block");
2590
- if (!is_block) {
2591
- return null;
2592
- }
2593
- const is_ghost = element.classList.contains("ghost");
2594
- if (is_ghost) {
2595
- return null;
2596
- }
2597
- return get_index_path_for_element_default(element);
2739
+ recomputeIndexPaths() {
2740
+ const raw_blocks = document.querySelectorAll("section.block");
2741
+ const blocks = Array.from(raw_blocks);
2742
+ let index = 0;
2743
+ blocks.forEach((block) => {
2744
+ const block_parent = block.parentNode;
2745
+ if (block_parent === null) {
2746
+ throw new import_errors8.InvariantViolation(`
2747
+ Tried to read block parent element, but it was not set
2748
+ `);
2749
+ }
2750
+ const multicolumn_ancestor = block_parent.closest("section.block.multi_column");
2751
+ if (multicolumn_ancestor === null) {
2752
+ const index_path = index.toString();
2753
+ block.setAttribute("data-index-path", index_path);
2754
+ index++;
2755
+ }
2756
+ });
2598
2757
  }
2599
2758
  getIndexPathForGhost(ghost) {
2600
- let current_child = ghost;
2601
- while (current_child) {
2602
- const index_path = this.getIndexPathSafe(current_child);
2603
- if (index_path !== null) {
2604
- return index_path;
2605
- }
2606
- current_child = current_child.nextElementSibling;
2759
+ const parent_element = ghost.parentNode;
2760
+ if (parent_element === null) {
2761
+ throw new import_errors8.InvariantViolation(`
2762
+ Tried to read parent element for ghost, but it was not set
2763
+ `);
2607
2764
  }
2608
- current_child = ghost;
2609
- while (current_child) {
2610
- const index_path = this.getIndexPathSafe(current_child);
2611
- if (index_path !== null) {
2612
- const index_major_version = parseInt(index_path);
2613
- const next_version = index_major_version + 1;
2614
- return next_version.toString();
2765
+ const siblings = Array.from(parent_element.children);
2766
+ let index = 0;
2767
+ let effective_index = 0;
2768
+ while (index < siblings.length) {
2769
+ const sibling = siblings[index++];
2770
+ if (!sibling.classList.contains("block")) {
2771
+ continue;
2615
2772
  }
2616
- current_child = current_child.previousElementSibling;
2773
+ if (sibling.classList.contains("dragging")) {
2774
+ continue;
2775
+ }
2776
+ if (sibling === ghost) {
2777
+ break;
2778
+ }
2779
+ effective_index++;
2617
2780
  }
2618
- return "0";
2781
+ return effective_index.toString();
2619
2782
  }
2620
2783
  async submitReposition(source_index_path, target_index_path) {
2621
2784
  const form = new FormData();
@@ -2637,14 +2800,42 @@
2637
2800
  }
2638
2801
  }
2639
2802
  getEventCoordinate(event) {
2803
+ const { touches } = event;
2804
+ if (touches === void 0) {
2805
+ return null;
2806
+ }
2807
+ const touch = touches[0];
2808
+ if (touch === void 0) {
2809
+ return null;
2810
+ }
2640
2811
  return {
2641
- x: event.clientX,
2642
- y: event.clientY
2812
+ x: touch.clientX,
2813
+ y: touch.clientY
2643
2814
  };
2644
2815
  }
2645
2816
  getDragStartCoordinate() {
2646
2817
  return this.drag_start_coordinate;
2647
2818
  }
2819
+ setDragStartCoordinate(coordinate) {
2820
+ this.drag_start_coordinate = coordinate;
2821
+ }
2822
+ getDragCurrentCoordinate() {
2823
+ return this.drag_current_coordinate;
2824
+ }
2825
+ setDragCurrentCoordinate(coordinate) {
2826
+ this.drag_current_coordinate = coordinate;
2827
+ }
2828
+ getCurrentScrollY() {
2829
+ if (this.current_scroll_y === null) {
2830
+ throw new import_errors8.InvariantViolation(`
2831
+ Tried to read current scroll y, but it was not set
2832
+ `);
2833
+ }
2834
+ return this.current_scroll_y;
2835
+ }
2836
+ setCurrentScrollY(scroll_y) {
2837
+ this.current_scroll_y = scroll_y;
2838
+ }
2648
2839
  };
2649
2840
  var interaction_default = InteractionHelper;
2650
2841
 
@@ -1,30 +1,52 @@
1
1
  declare class InteractionHelper {
2
2
  private drag_start_coordinate;
3
+ private drag_current_coordinate;
3
4
  private drag_delay_timer;
5
+ private scroll_timer;
6
+ private scroll_direction;
7
+ private last_scroll_time;
8
+ private current_scroll_y;
4
9
  constructor();
5
10
  attach(): void;
6
11
  isDragging(): boolean;
7
- private handlePointerDown;
12
+ private applyNonInteractiveClasses;
13
+ private isTouchDevice;
14
+ private handleTouchStart;
8
15
  private scheduleDelayedDrag;
9
16
  private cancelDelayedDrag;
10
- private removeClassFromAllElements;
17
+ private demoteAllDragCandidates;
18
+ private createDragMask;
19
+ private hideDragMask;
11
20
  private beginDelayedDrag;
12
21
  private handleNativeDragStart;
13
- private handlePointerMove;
14
- private translateDragTargetBlock;
22
+ private handleTouchMove;
23
+ private updateDragTargets;
24
+ private updateDragTarget;
25
+ private stopScrolling;
26
+ private startScrollingUp;
27
+ private startScrollingDown;
28
+ private setScrollDirection;
29
+ private getScrollDirection;
30
+ private setLastScrollTime;
31
+ private getLastScrollTime;
32
+ private scheduleScroll;
33
+ private scroll;
15
34
  private getGhostForBlock;
16
35
  private getPreviousBlock;
17
36
  private getNextBlock;
18
- private handlePointerUp;
19
- private handlePointerCancel;
37
+ private handleTouchEnd;
38
+ private handleGenericClick;
20
39
  private stopDragging;
21
- private showFullscreenBlockingOverlay;
22
- private hideFullscreenBlockingOverlay;
23
40
  private stopDraggingAsync;
24
- private getIndexPathSafe;
41
+ private recomputeIndexPaths;
25
42
  private getIndexPathForGhost;
26
43
  private submitReposition;
27
44
  private getEventCoordinate;
28
45
  private getDragStartCoordinate;
46
+ private setDragStartCoordinate;
47
+ private getDragCurrentCoordinate;
48
+ private setDragCurrentCoordinate;
49
+ private getCurrentScrollY;
50
+ private setCurrentScrollY;
29
51
  }
30
52
  export default InteractionHelper;