@jsenv/dom 0.8.5 → 0.8.7

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 (2) hide show
  1. package/dist/jsenv_dom.js +92 -33
  2. package/package.json +1 -1
package/dist/jsenv_dom.js CHANGED
@@ -92,16 +92,17 @@ const getElementSignature = (element) => {
92
92
  }
93
93
  return `[${functionLabel}]`;
94
94
  }
95
- if (element.nodeType === Node.TEXT_NODE) {
96
- return `#text(${getElementSignature(element.nodeValue)})`;
97
- }
98
95
  if (element.props) {
99
96
  const type = element.type;
97
+ const elementName = typeof type === "function" ? type.name : type;
100
98
  const id = element.props.id;
101
99
  if (id) {
102
- return `<${type} id="${id}" />`;
100
+ return `<${elementName} id="${id}" />`;
103
101
  }
104
- return `<${type} />`;
102
+ return `<${elementName} />`;
103
+ }
104
+ if (element.nodeType === Node.TEXT_NODE) {
105
+ return `#text(${getElementSignature(element.nodeValue)})`;
105
106
  }
106
107
 
107
108
  const tagName = element.tagName.toLowerCase();
@@ -399,6 +400,14 @@ const parseCSSColor = (color, element) => {
399
400
  if (typeof color !== "string") {
400
401
  return color;
401
402
  }
403
+ if (color === "inherit") {
404
+ if (!element) {
405
+ return color;
406
+ }
407
+ const computedStyle = getComputedStyle(element);
408
+ const resolvedColor = parseCSSColor(computedStyle.color, element);
409
+ return resolvedColor;
410
+ }
402
411
  let resolvedColor = color;
403
412
 
404
413
  // Handle light-dark() function
@@ -413,6 +422,40 @@ const parseCSSColor = (color, element) => {
413
422
  return parseCSSColor(resolvedColor, element);
414
423
  }
415
424
 
425
+ if (color.startsWith("color-mix(")) {
426
+ return color;
427
+ }
428
+
429
+ // Pass through CSS functions that we don't want to resolve
430
+ if (
431
+ color.includes("calc(") ||
432
+ color.includes("min(") ||
433
+ color.includes("max(") ||
434
+ color.includes("clamp(") ||
435
+ color.includes("env(") ||
436
+ color.includes("attr(")
437
+ ) {
438
+ return color;
439
+ }
440
+
441
+ // Pass through CSS color functions we don't handle
442
+ if (
443
+ color.startsWith("color(") ||
444
+ color.startsWith("lch(") ||
445
+ color.startsWith("oklch(") ||
446
+ color.startsWith("lab(") ||
447
+ color.startsWith("oklab(") ||
448
+ color.startsWith("hwb(") ||
449
+ color.includes("color-contrast(")
450
+ ) {
451
+ return color;
452
+ }
453
+
454
+ // Pass through relative color syntax (CSS Color Module Level 5)
455
+ if (color.includes(" from ")) {
456
+ return color;
457
+ }
458
+
416
459
  // If it's a CSS custom property, resolve it using getComputedStyle
417
460
  if (resolvedColor.includes("var(")) {
418
461
  if (!element) {
@@ -3662,26 +3705,29 @@ const createPreviousNodeIterator = (fromNode, rootNode, skipRoot = null) => {
3662
3705
  };
3663
3706
  };
3664
3707
 
3665
- const activeElementSignal = signal(document.activeElement);
3666
-
3667
- document.addEventListener(
3668
- "focus",
3669
- () => {
3670
- activeElementSignal.value = document.activeElement;
3671
- },
3672
- { capture: true },
3708
+ const activeElementSignal = signal(
3709
+ typeof document === "object" ? document.activeElement : undefined,
3673
3710
  );
3674
- // When clicking on document there is no "focus" event dispatched on the document
3675
- // We can detect that with "blur" event when relatedTarget is null
3676
- document.addEventListener(
3677
- "blur",
3678
- (e) => {
3679
- if (!e.relatedTarget) {
3711
+ if (typeof document === "object") {
3712
+ document.addEventListener(
3713
+ "focus",
3714
+ () => {
3680
3715
  activeElementSignal.value = document.activeElement;
3681
- }
3682
- },
3683
- { capture: true },
3684
- );
3716
+ },
3717
+ { capture: true },
3718
+ );
3719
+ // When clicking on document there is no "focus" event dispatched on the document
3720
+ // We can detect that with "blur" event when relatedTarget is null
3721
+ document.addEventListener(
3722
+ "blur",
3723
+ (e) => {
3724
+ if (!e.relatedTarget) {
3725
+ activeElementSignal.value = document.activeElement;
3726
+ }
3727
+ },
3728
+ { capture: true },
3729
+ );
3730
+ }
3685
3731
 
3686
3732
  const useActiveElement = () => {
3687
3733
  return activeElementSignal.value;
@@ -5050,7 +5096,8 @@ const bodyIsScrollable = (body) => {
5050
5096
  // https://developer.mozilla.org/en-US/docs/Glossary/Scroll_container
5051
5097
 
5052
5098
 
5053
- const { documentElement: documentElement$2 } = document;
5099
+ const { documentElement: documentElement$2 } =
5100
+ typeof document === "object" ? document : { documentElement: null };
5054
5101
 
5055
5102
  const getScrollContainer = (arg, { includeHidden } = {}) => {
5056
5103
  if (typeof arg !== "object" || arg.nodeType !== 1) {
@@ -5291,7 +5338,8 @@ const getBorderSizes = (element) => {
5291
5338
  */
5292
5339
 
5293
5340
 
5294
- const { documentElement: documentElement$1 } = document;
5341
+ const { documentElement: documentElement$1 } =
5342
+ typeof document === "object" ? document : { documentElement: null };
5295
5343
 
5296
5344
  /**
5297
5345
  * Get element rectangle relative to its scroll container
@@ -6154,7 +6202,9 @@ const isOverlayOf = (element, potentialTarget) => {
6154
6202
  return false;
6155
6203
  };
6156
6204
 
6157
- const { documentElement } = document;
6205
+ const { documentElement } =
6206
+ typeof document === "object" ? document : { documentElement: null };
6207
+
6158
6208
  const createGetScrollOffsets = (
6159
6209
  scrollContainer,
6160
6210
  referenceScrollContainer,
@@ -9372,6 +9422,7 @@ const pickPositionRelativeTo = (
9372
9422
  {
9373
9423
  alignToViewportEdgeWhenTargetNearEdge = 0,
9374
9424
  minLeft = 0,
9425
+ positionPreference,
9375
9426
  forcePosition,
9376
9427
  } = {},
9377
9428
  ) => {
@@ -9452,8 +9503,12 @@ const pickPositionRelativeTo = (
9452
9503
  position = forcePosition;
9453
9504
  break determine_position;
9454
9505
  }
9455
- const preferredPosition = element.getAttribute("data-position");
9506
+ const elementPreferredPosition = element.getAttribute("data-position");
9456
9507
  const minContentVisibilityRatio = 0.6; // 60% minimum visibility to keep position
9508
+
9509
+ // Check positionPreference parameter first, then element attribute
9510
+ const preferredPosition = positionPreference || elementPreferredPosition;
9511
+
9457
9512
  if (preferredPosition) {
9458
9513
  // Element has a preferred position - try to keep it unless we really struggle
9459
9514
  const visibleRatio =
@@ -9651,7 +9706,9 @@ const startTimeline = () => {
9651
9706
  backgroundUpdateLoop.start();
9652
9707
  animationUpdateLoop.start();
9653
9708
  };
9654
- startTimeline();
9709
+ if (typeof document === "object") {
9710
+ startTimeline();
9711
+ }
9655
9712
 
9656
9713
  // Default lifecycle methods that do nothing
9657
9714
  const LIFECYCLE_DEFAULT = {
@@ -9671,11 +9728,13 @@ const onTransitionPausedByBreakpoint = (transition) => {
9671
9728
  const cleanupTransitionPausedByBreakpoint = (transition) => {
9672
9729
  transitionPausedByBreakpointWeakSet.delete(transition);
9673
9730
  };
9674
- window.resumeTransitions = () => {
9675
- for (const transition of transitionPausedByBreakpointWeakSet) {
9676
- transition.play();
9677
- }
9678
- };
9731
+ if (typeof window !== "undefined") {
9732
+ window.resumeTransitions = () => {
9733
+ for (const transition of transitionPausedByBreakpointWeakSet) {
9734
+ transition.play();
9735
+ }
9736
+ };
9737
+ }
9679
9738
 
9680
9739
  const combineTwoLifecycle = (lifecycleA, lifecycleB) => {
9681
9740
  if (!lifecycleA && !lifecycleB) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/dom",
3
- "version": "0.8.5",
3
+ "version": "0.8.7",
4
4
  "description": "DOM utilities for writing frontend code",
5
5
  "repository": {
6
6
  "type": "git",