@fieldnotes/core 0.23.0 → 0.24.0

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/dist/index.cjs CHANGED
@@ -1033,16 +1033,17 @@ var KeyboardActions = class {
1033
1033
  this.pasteCount = 0;
1034
1034
  }
1035
1035
  paste() {
1036
+ if (this.deps.isToolActive()) return;
1036
1037
  this.flushPendingNudge();
1037
- if (this.clipboard.length === 0 || this.deps.isToolActive()) return;
1038
+ if (this.clipboard.length === 0) return;
1038
1039
  const sel = this.selectTool();
1039
1040
  if (!sel) return;
1040
1041
  this.pasteCount++;
1041
1042
  this.insertClones(this.clipboard, this.pasteCount * 20, sel);
1042
1043
  }
1043
1044
  duplicate() {
1044
- this.flushPendingNudge();
1045
1045
  if (this.deps.isToolActive()) return;
1046
+ this.flushPendingNudge();
1046
1047
  const sel = this.selectTool();
1047
1048
  if (!sel) return;
1048
1049
  const source = [];
@@ -1226,6 +1227,11 @@ function parseBinding(binding) {
1226
1227
  throw new Error(`Invalid shortcut binding "${binding}": unknown modifier "${part}"`);
1227
1228
  }
1228
1229
  }
1230
+ if (parsed.mod && (parsed.ctrl || parsed.meta)) {
1231
+ throw new Error(
1232
+ `Invalid shortcut binding "${binding}": "mod" already means Ctrl or Cmd; don't combine it with ctrl/meta`
1233
+ );
1234
+ }
1229
1235
  return parsed;
1230
1236
  }
1231
1237
  function bindingMatches(p, e, allowShift) {
@@ -1369,6 +1375,10 @@ var InputHandler = class {
1369
1375
  this.inputFilter.reset();
1370
1376
  this.deferredDown = null;
1371
1377
  this.lastPointerEvent = null;
1378
+ if (this.scope === "focus") {
1379
+ this.element.removeAttribute("tabindex");
1380
+ this.element.style.outline = "";
1381
+ }
1372
1382
  }
1373
1383
  bind() {
1374
1384
  const opts = { signal: this.abortController.signal };
@@ -1699,6 +1709,22 @@ var DoubleTapDetector = class {
1699
1709
  }
1700
1710
  };
1701
1711
 
1712
+ // src/core/geometry.ts
1713
+ function distSqToSegment(p, a, b) {
1714
+ const abx = b.x - a.x;
1715
+ const aby = b.y - a.y;
1716
+ const apx = p.x - a.x;
1717
+ const apy = p.y - a.y;
1718
+ const lenSq = abx * abx + aby * aby;
1719
+ if (lenSq === 0) {
1720
+ return apx * apx + apy * apy;
1721
+ }
1722
+ const t = Math.max(0, Math.min(1, (apx * abx + apy * aby) / lenSq));
1723
+ const dx = p.x - (a.x + t * abx);
1724
+ const dy = p.y - (a.y + t * aby);
1725
+ return dx * dx + dy * dy;
1726
+ }
1727
+
1702
1728
  // src/elements/arrow-geometry.ts
1703
1729
  function getArrowControlPoint(from, to, bend) {
1704
1730
  const midX = (from.x + to.x) / 2;
@@ -1787,16 +1813,7 @@ function bezierPoint(from, cp, to, t) {
1787
1813
  };
1788
1814
  }
1789
1815
  function isNearLine(point, a, b, threshold) {
1790
- const dx = b.x - a.x;
1791
- const dy = b.y - a.y;
1792
- const lenSq = dx * dx + dy * dy;
1793
- if (lenSq === 0) {
1794
- return Math.hypot(point.x - a.x, point.y - a.y) <= threshold;
1795
- }
1796
- const t = Math.max(0, Math.min(1, ((point.x - a.x) * dx + (point.y - a.y) * dy) / lenSq));
1797
- const projX = a.x + t * dx;
1798
- const projY = a.y + t * dy;
1799
- return Math.hypot(point.x - projX, point.y - projY) <= threshold;
1816
+ return distSqToSegment(point, a, b) <= threshold * threshold;
1800
1817
  }
1801
1818
 
1802
1819
  // src/elements/element-bounds.ts
@@ -3227,9 +3244,9 @@ var ElementRenderer = class {
3227
3244
  });
3228
3245
  }
3229
3246
  };
3230
- img.onerror = () => {
3247
+ img.onerror = (event) => {
3231
3248
  this.imageCache.set(src, "failed");
3232
- this.onImageError?.(src);
3249
+ this.onImageError?.(src, event);
3233
3250
  this.onImageLoad?.();
3234
3251
  };
3235
3252
  return null;
@@ -3654,7 +3671,10 @@ var NoteEditor = class {
3654
3671
  this.editingNode.removeAttribute("data-fn-placeholder");
3655
3672
  this.editingNode.removeAttribute("data-fn-empty");
3656
3673
  const text = sanitizeNoteHtml(this.editingNode.innerHTML);
3657
- store.update(this.editingId, { text });
3674
+ const current = store.getById(this.editingId);
3675
+ if (current && (current.type === "note" || current.type === "text") && current.text !== text) {
3676
+ store.update(this.editingId, { text });
3677
+ }
3658
3678
  this.editingNode.contentEditable = "false";
3659
3679
  Object.assign(this.editingNode.style, {
3660
3680
  userSelect: "none",
@@ -5251,13 +5271,13 @@ var Viewport = class {
5251
5271
  this.renderLoop.markAllLayersDirty();
5252
5272
  this.requestRender();
5253
5273
  });
5254
- this.renderer.setOnImageError((src) => {
5274
+ this.renderer.setOnImageError((src, cause) => {
5255
5275
  const elementIds = [];
5256
5276
  for (const el of this.store.getAll()) {
5257
5277
  if (el.type === "image" && el.src === src) elementIds.push(el.id);
5258
5278
  }
5259
5279
  if (options.onImageError) {
5260
- options.onImageError({ src, elementIds });
5280
+ options.onImageError({ src, elementIds, cause });
5261
5281
  } else {
5262
5282
  console.warn(`[fieldnotes] image failed to load: ${src}`);
5263
5283
  }
@@ -5476,6 +5496,10 @@ var Viewport = class {
5476
5496
  this.loadState(parseState(json));
5477
5497
  }
5478
5498
  setTool(name) {
5499
+ if (!this.toolManager.getTool(name)) {
5500
+ console.warn(`[fieldnotes] setTool: no tool registered as "${name}"`);
5501
+ return;
5502
+ }
5479
5503
  this.toolManager.setTool(name, this.toolContext);
5480
5504
  }
5481
5505
  get shortcuts() {
@@ -5972,20 +5996,6 @@ var PencilTool = class {
5972
5996
  };
5973
5997
 
5974
5998
  // src/elements/stroke-hit.ts
5975
- function distSqToSegment(p, a, b) {
5976
- const abx = b.x - a.x;
5977
- const aby = b.y - a.y;
5978
- const apx = p.x - a.x;
5979
- const apy = p.y - a.y;
5980
- const lenSq = abx * abx + aby * aby;
5981
- if (lenSq === 0) {
5982
- return apx * apx + apy * apy;
5983
- }
5984
- const t = Math.max(0, Math.min(1, (apx * abx + apy * aby) / lenSq));
5985
- const dx = p.x - (a.x + t * abx);
5986
- const dy = p.y - (a.y + t * aby);
5987
- return dx * dx + dy * dy;
5988
- }
5989
5999
  function hitTestStroke(stroke, point, radius) {
5990
6000
  const bounds = getElementBounds(stroke);
5991
6001
  if (!bounds) return false;
@@ -7582,7 +7592,7 @@ var TemplateTool = class {
7582
7592
  };
7583
7593
 
7584
7594
  // src/index.ts
7585
- var VERSION = "0.23.0";
7595
+ var VERSION = "0.24.0";
7586
7596
  // Annotate the CommonJS export names for ESM import in node:
7587
7597
  0 && (module.exports = {
7588
7598
  AddElementCommand,