How to get contentWindow of iframe without mounting to DOM

I’m working on a React app where I need to manage multiple iframes dynamically. Each iframe is created only once and stored in a cache (Map/Ref) for reuse. At any given time, only the selected iframe should be mounted in the DOM. Other iframes remain cached (not attached to the DOM).

My question is:
Is there a way to send messages/events (using postMessage or similar) to an iframe that is stored in cache but not currently mounted in the DOM? Currently i’m getting contentWindow value as null

Example workflow:

  1. Create iframe for itemId = 1, store it in cache.
  2. Switch to itemId = 2 → mount its iframe, keep itemId = 1 iframe in cache (not in DOM).
  3. From itemId = 2, I want to send a message/event to the iframe of itemId = 1.

Is this possible? Anyway?

DHTMLX Gantt – Internal server error when exporting

I’ve inherited a project that uses DHTMLX Gantt charts, and I was trying to understand why the export was not working as expected.

To achieve this, I recreated a small application to test the basics, however, here I am already running into an issue.

When trying to export a fairly simple project, with 3 sub-tasks, calling the export method gives me a beautiful black screen, stating “Internal server error. Error: Gantt to Excel. TypeError: Cannot read properties of undefined (reading ‘forEach’)

Here is the snippet:
https://snippet.dhtmlx.com/28horkya

Any help in understanding this is greatly appreciated.

Configuring ConsoleNinja to run in VSCode

I have installed ConsoleNinja extention in VSCode.

In powershell terminal, i run index.js file using node index.js I get the output of my index.js file but don’t see console.log message values I am supposed to see.

In the status bar I can see ConsoleNinja icon with the following message:

enter image description here

also I get the following in ConsoleNinja log file:

20:49:53.483 WARN host No clients connected

20:49:54.076 info buildHook-11924 allowed tools: vite, angular, jest, webpack, next.js, nest.js, cypress, http-server, serve, live-server, nuxt, remix, qwik, hydrogen, serverless, astro, live-server-extension, live-preview-extension, node

20:49:54.076 info buildHook-11924 running tools: live-preview-extension

20:49:54.083 info buildHook-11924 installing fs interceptor

20:49:54.082 info host client connected: buildHook { address: ‘127.0.0.1’, family: ‘IPv4’, port: 59380 }

20:49:54.131 info buildHook-11924 file processed (stat): 2 log points, error handler: false, network logging handler: false

20:49:54.140 info buildHook-11924 file processed (stat): 1 log points, error handler: false, network logging handler: false

20:49:54.158 info buildHook-11924 file processed (stat): 0 log points, error handler: false, network logging handler: false

20:49:54.198 info buildHook-11924 file processed (stat): 0 log points, error handler: false, network logging handler: false

20:49:54.231 info buildHook-11924 file processed (stat): 0 log points, error handler: false, network logging handler: false

20:49:54.246 info buildHook-11924 file processed (stat): 0 log points, error handler: false, network logging handler: false

20:49:54.250 info buildHook-11924 allowed tools: vite, angular, jest, webpack, next.js, nest.js, cypress, http-server, serve, live-server, nuxt, remix, qwik, hydrogen, serverless, astro, live-server-extension, live-preview-extension, node

20:49:54.250 info buildHook-11924 running tools: live-preview-extension

Also from the terminal running this command gives an error:

npx console-ninja run index.js

npx : File C:Program Filesnodejsnpx.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see
At line:1 char:1

  • npx console-ninja run index.js

ConsoleNinja Settings in VSCode:

enter image description here

CSS/JS Animation not playing in some browsers

I’m using this javascript code to play two different kinds of animations (a “fade” and a “wipe”) when an element is visible. Everything works as intended in Firefox, but when I test it in Chrome/Edge, the “wipe” doesn’t work.

const options = {
  root: null, // null means you want to observe changes relative to the viewport
  threshold: 0.1, // Trigger when 10% of the element is visible
  rootMargin: '0px'
};

const callback = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // Element is in view, add the animation
      entry.target.classList.add('animate');
    }
  });
};

const observer = new IntersectionObserver(callback, options);

const elements = document.querySelectorAll('.animate-fade, .animate-wipe');
elements.forEach(element => {
  observer.observe(element);
});
.animate-fade,
.animate-wipe {
  transition-timing-function: ease-out;
  transition-duration: 1.7s;
}

.animate-fade {
  opacity: 0;
}

.animate-wipe {
  clip-path: rect(0px 0% 100% 0px);
}

.animate {
  opacity: 1;
  clip-path: rect(0px 100% 100% 0px);
}
<div class="animate-fade">
  <p>This text has a fade effect and seems to work across browsers :).</p>
</div>
<div class="animate-wipe">
  <p>This text has a wipe effect and seems to only work on some browsers :(.</p>
</div>

How do I fix this?

How to preserve screen reader reading position when switching sections?

I’m building a React web application for blind users (screen reader users). The goal is to let users read a document while also being able to ask an AI chatbot questions at any time.

Intended flow:

  1. The user reads through the document with their screen reader.
  2. When they have a question, they switch to the chat section to ask it
    and listen to the answer.
  3. They return to the document and should ideally continue from the
    same spot they left off.

I’m unsure how to best preserve this reading position when switching between the two sections.

I’ve considered:

Option 1: Using clear headings, landmarks, or adding IDs for each paragraph so users can navigate back manually.

Question: Does this place too much cognitive demand on the user? What should I watch out for if I do it this way?

Option 2: On top of Option 1, also providing a “Return to where you left off” button or bookmark system.

Question: From my research, screen readers use a virtual cursor in “browse mode” so web developers cannot capture their screenreader cursor position directly, is such a feature actually doable? If so, how should I get their reading position?

Are there any other solutions?

In general, I would like to know:

Is this web design generally in line with accessibility guidelines?

What are the best practices in web development to help screen reader users resume reading from the same spot after switching to another interactive area?

why CSS mix-blend-mode: difference not working with Spline 3D background element

I’m trying to implement a mix-blend-mode: difference effect on header text that should blend with a 3D Spline background, but it’s not working. The navigation bar has the same blend mode and works perfectly, but the header text doesn’t show any color inversion.

this is my current setup:

  • Using Spline 3D background (<spline-viewer> element)

  • Navigation bar has mix-blend-mode: difference and works correctly

  • Header text has mix-blend-mode: difference but shows no effect

  • Both are positioned outside the main content to avoid stacking context issues

here the html code block:

<!-- 3D BACKGROUND -->
<spline-viewer id="spline-background" url="..."></spline-viewer>

<!-- NAVIGATION (working blend mode) -->
<div id="navigationbar">
    <span class="nav-name">Anubhab</span>
    <div class="nav-links">...</div>
</div>

<!-- HEADER TEXT (blend mode not working) -->
<div id="header">
    <h1>I am a Developer specializing in...</h1>
</div>

<!-- MAIN CONTENT -->
<main id="main-content">...</main>


here the css code block:


#spline-background { 
    position: fixed; 
    top: 0; 
    left: 0; 
    width: 100%; 
    height: 100%; 
    z-index: -2;
    pointer-events: none; 
}


#navigationbar { 
    position: fixed; 
    top: 0; 
    left: 0; 
    width: 100%; 
    z-index: 100; 
    mix-blend-mode: difference; /* This works */
}

#header {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 0;
}

#header h1 { 
    color: rgba(255, 255, 255, 0.75); 
    mix-blend-mode: difference; /* This doesn't work */
    z-index: -1;
}

full code here :
html, css, js

  1. Moved header outside main content to avoid opacity transitions

  2. Adjusted z-index values to ensure proper layering

  3. Removed isolation: isolate properties

  4. Added hardware acceleration (will-change: transform, transform: translateZ(0))

  5. Tried different blend modes (exclusion, multiply)

Header text should invert colors (white to black) when overlapping with dark parts of the 3D background, similar to how the navigation bar works.

Afterall:

Header text remains white without any blend effect, even when overlapping the 3D background elements.

Browser: Chrome (latest), Windows 11

Why is mix-blend-mode: difference working for the navigation bar but not for the header text, despite having similar positioning and CSS properties? Is there something specific about Spline 3D elements that prevents blend modes from working properly?

Inkscape SVG misaligned when put into React+Vite project and won’t rotate around hinge

I am making a microfuge tube that has two groups: the cap and the body. I used Inkscape to make the microfuge tube, and then I ran the XML file through Chat GPT to get a simplified version of the SVG file. However, when I import it into my program, the cap is not aligned with the body, and the cap doesn’t rotate around the hinge.Image of the microfuge tube in Inkscape. Image of the microfuge tube in React+Vite.

Attached below is the way I use it. Basically, I want the microfuge tube to switch between two states, one with the cap on and one with the cap off. But, I just can’t get the cap to align with the body, and it’s beyond me how to rotate it around the specific hinge.

export default function MicrofugeTube({ capOff = false }) {
  return (
    <svg
      viewBox="0 0 800 600"
      width={300}
      height={225}
      xmlns="http://www.w3.org/2000/svg"
    >
      {/* Animated Cap */}
      <motion.g
  transform="translate(110, -10000)" // adjust until hinge sits on neck
  style={{ transformOrigin: "85px 152px", transformBox: "fill-box" }}
  animate={{ rotate: capOff ? -120 : 0 }}
  transition={{ duration: 0.8, ease: "easeInOut" }}
>
  <path
    d="M84.8,151.7c0,3.06667,0,6.13333,0,9.2
      c22.17767-0.0983,44.38367,0.0623,66.54365-0.1976
      c3.18545-0.7008,6.3709-1.4016,9.55635-2.1024
      c0.71378-3.61798-1.47148-4.71625-4.73651-4.87603
      c-4.4144-1.35434-8.98911-1.38782-13.56349-1.42397
      c-0.0333-6.13333-0.0667-12.26667-0.1-18.4
      c-13.2-0.0667-26.4-0.13333-39.6-0.2
      c0,6,0,12,0,18c-6.033333,0-12.066667,0-18.1,0z"
    fill="#5b88b4"
    fillOpacity={0.5}
  />
</motion.g>
      {/* Tube Body */}
      <path
        d="M196.2,134.1v0.2z
          M196.2,134.1c-9.27074,0.38254-18.61158,0.25031-27.83401,1.07853
          c-2.3981,0.82584-6.14016,0.64247-7.73115,2.07439
          c-0.89721,3.74244,2.19367,4.14387,5.10309,4.69733
          c2.54792,0.59357,5.05574,1.31273,7.46207,2.34975
          c0.21053,26.36438,0.11861,52.74924,0.51779,79.10085
          c2.89407,22.13305,5.78814,44.2661,8.68221,66.39915
          c2.3272,2.15245,3.58971,6.21119,7.29718,5.89232
          c5.2662,0.78805,10.66732,0.53642,15.90282-0.39232
          c2.15558-2.83047,5.44348-5.16439,5.07117-9.10341
          c2.73994-21.5376,5.78218-43.05474,8.33348-64.6051
          c0.13178-25.76383,0.26357-51.52766,0.39535-77.29149
          c3.6118-0.24173,3.81689-2.82813,3.4-5.84261
          c1.24809-4.02448-1.97453-3.72759-4.99398-3.62709
          C210.60403,134.58642,203.40218,134.33825,196.2,134.1z"
        fill="#5b88b4"
        fillOpacity={0.5}
      />
    </svg>
  );
}

I’ve tried to change the translate(110,-10000), but there is no noticeable effect even when I go to extremes. I’ve also tried to change the viewBox, but that doesn’t do anything except make it smaller or larger.

How can I have intellisense in VS Code for opencv.js

I want to have intellisense for opencv.js inside VS Code when I call it from a JavaScript file, but when I use import "path/opencv.js" or import cv from "path/opencv.js", I can’t have intellisense for cv.

In the OpenCV documentation, there are following description and a example:

Once opencv.js is ready, you can access OpenCV objects and functions through cv object. The promise-typed cv object should be unwrap with await operator. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await .

imgElement.onload = await function() {
  cv = (cv instanceof Promise) ? await cv : cv;
  let mat = cv.imread(imgElement);`
}

but the intellisense doesn’t even show a promise-typed cv.

It is worth mentioning that my environment is browser.

`window.scrollTo` scrolls outside the container on iOS Safari

I’m running into an issue with window.scrollTo on iOS Safari.

On desktop browsers (Chrome/Firefox/Edge), this works as expected:

window.scrollTo(0, document.body.scrollHeight);

Even when resizing the window, the scroll goes correctly to the bottom of the page.

But on iOS Safari, the behavior is different:

  • It scrolls past the bottom of my main container (section#section).
  • The end of the <section> gets aligned at the top of the viewport.
  • I then need to manually scroll a little bit up/down before the browser “fixes” the scroll position (as if Safari realizes it scrolled outside the valid range).

Here’s the simplified HTML/CSS:

<html>
<head>
<style type="text/css">
body {
    height: 100vh;
}
section#section {
    height: auto;
}
</style>
</head>
<body>
<section id="section">
    [...]
</section>
</body>
</html>

Things I’ve already tried:

  • window.scrollTo(0, document.body.scrollHeight);

  • Scrolling the section itself:

    section.scrollTo({
        top: section.scrollHeight,
        behavior: 'smooth',
    });
    
  • Wrapping the scroll in a setTimeout (50ms delay).

Unfortunately, none of these fix the issue on iOS Safari.

Has anyone encountered this behavior before, or knows a reliable workaround to make sure the scroll goes correctly to the bottom on mobile Safari?

Thanks!

Kerberos: Getting username from service ticket using keytab file in JavaScript

I have a service ticket which I extracted from a Microsoft Active Directory joined computer. This service ticket then gets send to my server which has the keytab file generated for a custom SPN which was created for my service.

I want to extract the username from this service ticket using the generated keytab file. However, nothing seems to work. It is definitely possible, but the library support is just horrible and nearly all code examples I have stumbled across don’t work.

Is there some certified way of doing this? I don’t care if it is a CLI-Tool or a NpmJS package – I just need something.

Packages like kerb5 don’t seem to offer this feature and the kerberos library is somewhat broken for me.

If anyone has a certified way I would be very thankful for that code sample.

Sinon Snub Replace Function

Is it possible to replace or stub a function of the exports.

myStuff.js

function myOtherFunction() {
  return true;
}
function myFunction() {
  return myOtherFunction();
}

exports = {
  myOtherFunction: myOtherFunction,
  myFunction: myFunction
}

index.test.js:

const sinon = require('sinon');
const assert = require('assert');

describe('mystuff', function() {

  before{
    var myStuff = proxyquire('path/to/mystuff), {
      ...
    }
  }

  describe('my test', function() {
    beforeEach(function() {
      sinon.stub(myStuff, 'myOtherFunction');
    });
    it('should do something...', function() {
      myStuff.myOtherFunction.returns(false);
      assert.equal(myStuff.myOtherFunction(), false);
      assert.equal(myStuff.myFunction(), false);
    });
  });

});

When I I call the stubbed function ‘myOtherFunction’ directly it returns the stubbed value false, but when I call ‘myFunction’ which calls ‘myOtherFunction’ the original exported function is called.

I believe this is to do with references of the exported function, is there a way that I can over-ride the return function of ‘myOtherFunction’ when it is called by ‘myFunction’. I thought I might be able to manipulate it directly:

myStuff.myOtherFunction = function() { return false; }

Any ideas?

How does Node.js manage package files and directories? [closed]

I am using Node.js v24.1.0 to execute a JavaScript file in Terminal on macOS Sonoma 14.7.7.

node javascript/FizzBuzz.js

I noticed that Node.js created package files and directories, and I am curious about how they are managed.

Package files:

package-lock.json
package.json

Package directories:

node_modules/ansi-regex
node_modules/prompt-sync
node_modules/strip-ansi

Based on the timestamps, I observed that package-lock.json and package.json do not update every time that I execute my JavaScript file with node.

Will Node.js update the package files and directories if I use a new package in my JavaScript file and then execute it?

CSS 3D isometric cube – faces disappear at certain rotations

I’m trying to build a simple isometric cube with pure HTML and CSS (no WebGL).

At some rotation/frame, some faces of the cube are not shown. They are in the DOM, and they don’t have any of these properties (visibillity: hidden or dislplay: none).

I think this is related to perspective: none;. But I need it isometric.

Is there a way to prevent faces from disappearing?

The slider is just for debugging. Normally it is an on scroll animation.

(() => {
  const onReady = (fn) => {
    const wait = () => (window.anime && document.readyState !== 'loading') ? fn() : setTimeout(wait, 40);
    wait();
  };

  onReady(() => {
    const stage = document.querySelector('.stage');
    const cube = stage.querySelector('#cube');
    const topFace = stage.querySelector('#top');
    const leftFace = stage.querySelector('#left');
    const rightFace = stage.querySelector('#right');
    const backFace = stage.querySelector('#back');
    const range = stage.querySelector('#progress');
    const out = stage.querySelector('#progressOut');

    if (!cube || !topFace || !leftFace || !rightFace || !backFace || !range) return;

    const getS = () => parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--s')) || 280;
    const S = getS();
    const LIFT_PX = Math.round(S * 0.7);
    const FOLD_DEG = 90;

    topFace.style.setProperty('--lift-top', '0px');
    leftFace.style.setProperty('--fold-left', '0deg');
    rightFace.style.setProperty('--fold-right', '0deg');
    backFace.style.setProperty('--fold-back', '0deg');

    const makeVarTL = (el, name, from, to, unit, duration = 1000, easing = 'linear') => {
      const holder = {
        v: from
      };
      return anime.timeline({
          autoplay: false,
          duration,
          easing
        })
        .add({
          targets: holder,
          v: to,
          update: () => el.style.setProperty(name, holder.v + unit)
        });
    };

    const tlRotate = anime.timeline({
        autoplay: false,
        duration: 1600,
        easing: 'linear'
      })
      .add({
        targets: cube,
        rotateX: [0, 360],
        rotateY: [0, 360]
      });

    const tlTopLift = makeVarTL(topFace, '--lift-top', 0, LIFT_PX, 'px', 900);
    const tlLeft = makeVarTL(leftFace, '--fold-left', 0, -FOLD_DEG, 'deg', 700);
    const tlRight = makeVarTL(rightFace, '--fold-right', 0, FOLD_DEG, 'deg', 700);
    const tlBack = makeVarTL(backFace, '--fold-back', 0, FOLD_DEG, 'deg', 700);

    const seg = (g, a, b) => {
      if (g <= a) return 0;
      if (g >= b) return 1;
      return (g - a) / (b - a);
    };

    const seekAll = (g) => {
      const p1 = seg(g, 0.00, 0.25);
      const p2 = seg(g, 0.25, 0.50);
      const p3 = seg(g, 0.50, 0.75);
      const p4 = seg(g, 0.75, 1.00);

      tlRotate.seek(p1 * tlRotate.duration);
      tlTopLift.seek(p2 * tlTopLift.duration);
      tlLeft.seek(p3 * tlLeft.duration);
      tlRight.seek(p3 * tlRight.duration);
      tlBack.seek(p4 * tlBack.duration);
    };

    const onInput = () => {
      const g = (parseFloat(range.value) || 0) / 100;
      out.value = Math.round(g * 100) + '%';
      seekAll(g);
    };
    range.addEventListener('input', onInput);
    onInput();
  });
})();
:root {
  --s: min(20vmin, 340px);
  --isoX: -35.264deg;
  --isoY: 45deg;
  --lift-top: 0px;
  --fold-left: 0deg;
  --fold-right: 0deg;
  --fold-back: 0deg;
  --glass-rgb: 47 107 255;
  --glass-blur: 8px;
  --glass-sat: 160%;
  --glass-bright: 1.05;
}

.stage {
  width: 100%;
  height: 70vh;
  display: block;
  padding: 12px;
  box-sizing: border-box;
}

.controls {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
  font: 14px system-ui, sans-serif
}

.controls input[type="range"] {
  width: 320px
}

.cube-viewport {
  position: relative;
  width: 100%;
  height: calc(100% - 42px);
  overflow: visible;
  perspective: none;
}

.cube-camera {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transform-style: preserve-3d;
  transform: rotateX(var(--isoX)) rotateY(var(--isoY));
}

.cube-world {
  position: relative;
  width: var(--s);
  height: var(--s);
  transform-style: preserve-3d;
}

.cube {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  will-change: transform;
}

.face {
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--s);
  height: var(--s);
  transform-origin: center;
  transform-style: preserve-3d;
  backface-visibility: hidden;
  border-radius: 12px;
  overflow: hidden;
  background:
    linear-gradient(135deg, rgb(var(--glass-rgb) / 0.22), rgb(var(--glass-rgb) / 0.08)),
    radial-gradient(120% 120% at 0% 0%, rgb(255 255 255 / 0.28), transparent 60%);
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat)) brightness(var(--glass-bright));
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.28), inset 0 0 0 1px rgb(255 255 255 / 0.06);
}

.face::after {
  content: "";
  position: absolute;
  inset: 0;
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.06);
  pointer-events: none;
}

/* Face-Positionen */
#right {
  transform: translate(-50%, -50%) rotateY(-90deg) translateZ(calc(var(--s) * -0.5)) rotateX(var(--fold-right));
  transform-origin: 50% 100% 0;
}

#left {
  transform: translate(-50%, -50%) rotateY(-90deg) translateZ(calc(var(--s) * 0.5)) rotateX(var(--fold-left));
  transform-origin: 50% 100% 0;
}

#top {
  transform: translate(-50%, -50%) rotateX(90deg) translateZ(calc(var(--s) * 0.5 + var(--lift-top)));
}

#bottom {
  transform: translate(-50%, -50%) rotateX(90deg) translateZ(calc(var(--s) * -0.5));
}

#back {
  transform: translate(-50%, -50%) rotateX(0deg) translateZ(calc(var(--s) * -0.5)) rotateX(var(--fold-back));
  transform-origin: 50% 100% 0;
}
<main class="stage">
  <div class="controls">
    <label for="progress">Progress</label>
    <input id="progress" type="range" min="0" max="100" value="0" step="0.1" />
    <output id="progressOut">0%</output>
  </div>

  <div class="cube-viewport">
    <div class="cube-camera">
      <div class="cube-world">
        <div class="cube" id="cube">
          <div id="top" class="face">
            <div class="face-inner"></div>
          </div>
          <div id="bottom" class="face">
            <div class="face-inner"></div>
          </div>
          <div id="left" class="face">
            <div class="face-inner"></div>
          </div>
          <div id="right" class="face">
            <div class="face-inner"></div>
          </div>
          <div id="back" class="face">
            <div class="face-inner"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</main>

<!-- anime.js -->
<script src="https://unpkg.com/[email protected]/lib/anime.min.js"></script>

Mixing javascript with Angular

I am working on a Chrome Extension that requires a background service-worker in javascript and I want to use Angular and typescript for the rest of the extension. The service-worker has to be a separate javascript file that is named in the Chrome Extension configuration.

Can somebody point me to how to call my Angular typescript code from the service-worker.js?

Thanks

AgGrid: How to have multiple rowGroups without forcing them to the left and a sum column in between

I’m working with AgGrid, and I want to achieve the following column layout and behavior:

  • Have a rowGroup on one column (e.g., “Category”)
  • Then a regular column that shows the sum of Quantity (aggregated by the grouping)
  • Then another rowGroup on a different column (e.g., “SubCategory”)
  • Crucially, I want to keep the order of these columns as declared — so
    the first rowGroup stays where it is, the sum column stays in the
    middle, and the second rowGroup stays after it.
  • I do not want the two rowGroups to be forced to the left side of the grid, as AgGrid
    normally moves grouped columns to the left automatically and hides
    the original grouped columns. Is there a way to configure AgGrid so
    that multiple rowGroups can be displayed inline in the grid without
    moving them to the left, and still be able to show an aggregation
    column like sum of Quantity between them?

Thanks in advance!