Javascript page transition issue

I’m using Javascript to create some page transition effect without reloading pages in a website.

The interface of the website is divided in 2 parts. The first part is the menu that is present in all pages of the site. The second part is the main content that refreshs by loading the content of the page.

The issue is, when I have a link inside the main content, the link doesn’t trigger the page transition. I think the JS links selector doesn’t update once the content has been transitioned. It only works with the main menu, not with the links inside the main content.

I don’t find the way to make the JS recognizing the links inside the updated main content once it has been transitioned.

const main = document.querySelector('.js-content');
const links = [...document.querySelectorAll('a')];

let isAnimating = false;

links.forEach(link => {
    link.addEventListener('click', async e => {
        e.preventDefault();
        if(isAnimating) return
        const url = e.target.href;
        console.log(url)
        startTransition(url);
        const pathname = new URL(url).pathname;
        history.pushState(null, '', pathname);
    })
})

window.addEventListener('popstate', e => {
    const url = window.location.pathname;
    startTransition(url)
})

const startTransition = async (url) => {
    isAnimating = true;
    const html = await fetch(url);
    const htmlString = await html.text();
    const parser = new DOMParser();
    const parsedhtml = parser.parseFromString(htmlString, 'text/html').querySelector('.js-content')

    transitionDiv.classList.add('is-animate-in');
    transitionDiv.addEventListener('transitionend', () => {
        main.innerHTML = parsedhtml.innerHTML;
        transitionDiv.classList.remove('is-animate-in');
        transitionDiv.classList.add('is-animate-out');
        setTimeout(() => {
            transitionDiv.style.transition = '0s';
            transitionDiv.classList.remove('is-animate-out');

            setTimeout(() => {
                transitionDiv.style.transition = '1s';
            }, 100)
            isAnimating = false;
        }, 1000)
    }, {once: true})
}

Overlaying a over another on hovering

I have two boxes in my web app that should live next to each other. However when hovering over the left box, I want it to increase width so that it covers parts of the right box. I want to keep the positioning of the right box, so the left box should extend over it. How can i accomplish this? See code example for how its not working, the right box is moving when i hover the left box.

.container {
  display: flex;
  gap: 20px;
  padding: 20px;
  position: relative;
}

.component {
  width: 200px;
  height: 200px;
  transition: all 0.3s ease;
}

.component-a {
  background-color: #3498db;
  position: relative;
  z-index: 1;
}

.component-b {
  background-color: #e74c3c;
  position: relative;
}

.component-a:hover {
  width: 420px;
  /* Original width (200px) + gap (20px) + B's width (200px) */
  transform: translateY(-20px);
  z-index: 2;
}
<div class="container">
  <div class="component component-a">Component A</div>
  <div class="component component-b">Component B</div>
</div>

Firebase v2 forced upgrade increased server costs

A few weeks ago I was forced to upgrade my firebase to v2 and my node.js from version 16 to 22, after I made this update my firebase costs ballooned overnight by 4x, I have had to shut down my server until I can figure out what could have caused this because this isn’t sustainable at this new frustrating cost, the only change I had to make to my code was the way the request handler is written, below I will give the before and after versions of how this code currently looks if anyone can explain to me how this is causing my server to cost 4x as much as it did the day before and how I can fix this would helpful.

Before:

const runtimeRetryOpts = {
  failurePolicy: true,
};

exports.webhook = functions
    .runWith(runtimeRetryOpts)
    .https.onRequest(async (request, response) =>{
// code here is the same
});

After:

exports.webhookV2 = onRequest(
// Configuration options
{
  retryConfig: {
    maxRetryAttempts: 1,
    minBackoffSeconds: 5,
  },
},
async (request, response) => {
// code here is the same
});

ng-repeat disable other repeated HTML Attribute

I am using "ng-repeat" to display 3 elements => Radio buttons- Yes/No, “Save” & “Cancel” buttons.
Objective of this question is to Enable only 1 HTML Attribute at a time in "ng-repeat" functionality.
“Save” button is repeated in each row, hence it should be enabled as soon as user clicks on either Yes or No in a particular row, Row-0 or Row-1 or Row-2.
The list of users (refer to images) contains Columns as Full-Name, Row-Index and Choice-Buttons, which are Radio-Buttons.

    When a user clicks on "Yes" for Row-0, then "Save" button on Row-0 should be enabled,
    and "Save" button on Row-1 should remain as disabled.
    
    As a user clicks on Yes/No radio button, a function-call is made at Controller Side, which checks whether the Row-Index of the current row is same as Row-Index mentioned in the Save-button's id, i.e. ```id="{{$index}}-saveBtn"```.
    
    If this match is found, then ```"var controller.isDisable"``` gets marked as false.
    
    However, when user click on Yes/No of the Row-0, then both the Save buttons on Row-0 & Row-1 gets enabled.
    
    Please suggest any correction in this approach or
    any other better way to achieve this use-case.
    
    As you can notice from the attached image, "Save" button's id is dynamic.
    So, Row-0 Save Button has ```id = "0-saveBtn"``` and
    Row-1 Save Button has ```id = "1-saveBtn"```.
    
    Please refer to the images for more clarification.
    [Image-1][1]
    [Image-2][2]
    [Image-3][3]
    [Save-Button][4]
    
    
      [1]: https://i.sstatic.net/Z4olzZam.png
      [2]: https://i.sstatic.net/ZrcT9vmS.png
      [3]: https://i.sstatic.net/pBZzyysf.png
      [4]: https://i.sstatic.net/xFAKySzi.png

Svelte 5 memory leak in simple example

I’m encountering many memory leaks when using both Svelte 4 and 5 on reasonably complex projects, and having trouble identifying what I’m doing wrong.

Here is an extremely simplified Svelte 5 example (adapted from svelte-7GUIs) that seems to present a memory leak.

<script lang="ts">
    class Circle {
        cx: number;
        cy: number;

        constructor(clientX: number, clientY: number) {
            this.cx = +clientX.toFixed();
            this.cy = +clientY.toFixed();
        }
    }
    
    let circles = $state<Circle[]>([]);
    
    function addCircles() {
        for (let i = 0; i < 2; i++) {
            circles.push(new Circle(Math.random() * 600, Math.random() * 400));
        }
    }

    function deleteCircle() {
        circles.shift();
    }
</script>

<div class="space-y">
    <div class="actions flex-center">
        <button onclick={addCircles}>Add 2 Circles</button>
        <button onclick={deleteCircle}>Delete Circle</button>
    </div>

    <svg viewBox="0 0 600 400">
        {#each circles as circle}
            <circle {...circle} r={40} fill="#444"></circle>
        {/each}
    </svg>
</div>

Running the above, I press “Add 2 Circles” once and “Delete Circle” twice. The canvas is clear, but inspecting the heap using Chrome dev tools and I can see that an instance of the Circle class remains.

Repeating the process, these lost instances of Circle continue to accumulate.

Repeat the cycle of adding/deleting 5 times, and 5 Circle instance remain on the heap

In this particular example, if I switch circles.shift() to instead use pop or slice, then the memory leak seems to disappear.

For more complex examples, I’ve also seen similar issues when using SvelteMap instead of a $state([]).

Can anyone explain why this is happening?

Is there a Google reCAPTCHA v3 package compatible with Angular 18?

I’m migrating a project from Angular 11 to Angular 18 and need to integrate Google reCAPTCHA v3.

Previously, I used:

"angular-recaptcha3": "^2.0.0"

Now, I’m trying to use:

"ng-recaptcha": "^13.2.1"

But ng-recaptcha officially supports only up to Angular 17, and I’m currently on Angular 18.2.13.

When I run npm install, I get peer dependency errors because ng-recaptcha expects Angular 17.

As a workaround, I’m using the following in package.json:

"overrides": {
  "ng-recaptcha": {
    "@angular/core": "18.2.13",
    "@angular/common": "18.2.13"
  }
}

While this allows the install to succeed, I’m unsure if this is stable or future-proof.

Is there a reCAPTCHA v3 package that officially supports Angular 18?

Or is there a better workaround to make ng-recaptcha work reliably with Angular 18?

Date format different hosts [closed]

I use php(8.1) and fullcalendar. Everything works as expected. The events are displayed correctly. I can add and edit events too. When I use the exact same setup at another host, it does not display the events. The console error is 404 – not finding the start and end date. It works at one host but not another. There are no errors, no logs. I suspect it is to do with datae format between the different hosts, but I cannot seem to pinpoint it. Here is my code:

<!DOCTYPE html>
<html>

<head>
<link rel="stylesheet" href="fullcalendar/fullcalendar.min.css" />
<script src="fullcalendar/lib/jquery.min.js"></script>
<script src="fullcalendar/lib/moment.min.js"></script>
<script src="fullcalendar/fullcalendar.min.js"></script>

<script>

$(document).ready(function () {
 
      
    var calendar = $('#calendar').fullCalendar({
        
        editable: true,
        events: "fetch-event.php",
        displayEventTime: false,
        eventRender: function (event, element, view) {
            if (event.allDay === 'true') {
                event.allDay = true;
            } else {
                event.allDay = false;
            }
        },
        selectable: true,
        selectHelper: true,
        select: function (start, end, allDay) {
            var title = prompt('Event Title:');

            if (title) {
                var start = $.fullCalendar.formatDate(start, 'YYYY-MM-DD HH:mm');
                var end = $.fullCalendar.formatDate(end, 'YYYY-MM-DD HH:mm');

                $.ajax({
                    url: 'add-event.php',
                    data: 'title=' + title + '&start=' + start + '&end=' + end,
                    type: "POST",
                    success: function (data) {
                        displayMessage("Added Successfully");
                    }
                });
                calendar.fullCalendar('renderEvent',
                        {
                            title: title,
                            start: start,
                            end: end,
                            allDay: allDay
                        },
                true
                        );
            }
            calendar.fullCalendar('unselect');
        },
        
        editable: true,
        eventDrop: function (event, delta) {
                    var start = $.fullCalendar.formatDate(event.start, "YYYY-MM-DD HH:mm");
                    var end = $.fullCalendar.formatDate(event.end, "YYYY-MM-DD HH:mm");
                    $.ajax({
                        url: 'edit-event.php',
                        data: 'title=' + event.title + '&start=' + start + '&end=' + end + '&id=' + event.id,
                        type: "POST",
                        success: function (response) {
                            displayMessage("Updated Successfully");
                        }
                    });
                },
        eventClick: function (event) {
            var deleteMsg = confirm("Do you really want to delete?");
            if (deleteMsg) {
                $.ajax({
                    type: "POST",
                    url: "delete-event.php",
                    data: "&id=" + event.id,
                    success: function (response) {
                        if(parseInt(response) > 0) {
                            $('#calendar').fullCalendar('removeEvents', event.id);
                            displayMessage("Deleted Successfully");
                        }
                    }
                });
            }
        }

    });
});

function displayMessage(message) {
        $(".response").html("<div class='success'>"+message+"</div>");
    setInterval(function() { $(".success").fadeOut(); }, 4000);
}
</script>

<style>
body {
    margin-top: 50px;
    text-align: left;
    font-size: 12px;
    font-family: "Lucida Grande", Helvetica, Arial, Verdana, sans-serif;
}

#calendar {
    width: 900px;
    margin: 0 auto;
}

.response {
    height: 60px;
}

.success {
    background: #cdf3cd;
    padding: 10px 60px;
    border: #c3e6c3 1px solid;
    display: inline-block;
}
</style>
</head>
<body>
    <h2>Basic Calendar Demo - no GUI.</h2>
        <ul>
            <li>Click date to add event.</li>
            <li>Click-and-drag for multiple days</li>
        </ul>
    <div class="response"></div>
    <div id='calendar'></div>
</body>


</html>

It works correctly at one host, but not at another.

How to implement my web app’s back button?

Let’s say we have a web app with the following structure:

- news feed page
- articles list page
-- article details page

On the article details page, in the top-left corner, there is a back button. The problem?

  1. If the user navigates news feed > article details, then the back button should lead back to the news feed page.

  2. But if the user navigates articles list > article details, then the back button should lead back to the articles list page.

  3. Lastly, if the user arrives at the article details page from an external link, the back button should lead to the articles list page.

So basically, I want it to be like a navigation stack, like a mobile app, but with an optional default. And ideally, I don’t want to have to hardcode all of the above cases for each page. Plus, the browser’s back button should trigger my custom back behaviour.

I’m using Next.js with app router.

How can I reset createResource() .error to null?

I want to implement a refetch function manually when user clicked the button.

Currently whenever I got an error from API, I’m showing a toast when the error appear, now I want to add “Retry” button next to a toast message and disappear after 3 second, the problem is toast component always show because of <Show when={data.error}/>

import { render } from "solid-js/web";
import { Show, createResource } from "solid-js";

const fetcher = async () => {
  await new Promise((resolve) => setTimeout(resolve, 3000));
  throw new Error("Something went wrong");
};

function App() {
  const [data] = createResource(fetcher);

  return (
    <div>
      <p>HELLO WORLD</p>
      <Show when={data.error}>
        <p>{data.error.message}| try again</p>
      </Show>
    </div>
  );
}

render(() => <App />, document.getElementById("app")!);

Playground

How do I reset the .error value to null manually? I don’t want to show Toast forever until refetch resolve.

Why my audio is nuted while capturing in chrome extension?

PROBLEM : I am trying to capture the audio for my chrome extension but it is muting the audio for the user.

WHAT I WANT : I want the audio should be available for both the user(speaker output) and for my extension for processing.

I have tried most of the methods none working for me you may also try I might be missing something. I would really appreciate your help.

NOTE: You can reproduce the same below is the complete code.

//manifest.json

{
    "name": "Audio Capture Test",
    "description": "Records tab audio with transcription.",
    "version": "1",
    "manifest_version": 3,
    "minimum_chrome_version": "116",
    "background": {
        "service_worker": "service-worker.js",
        "type": "module"
    },
    "action": {
        "default_popup": "popup.html",
        "default_title": "Capture Audio"
    },
    "permissions": [
        "tabCapture",
        "activeTab",
        "scripting"
    ],
    "host_permissions": [
        "http://*/*",
        "https://*/*"
    ]
}

//popup.js

document.getElementById("startCapture").addEventListener("click", async () => {
    const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

    if (tab) {
        alert("start recording called")
        chrome.runtime.sendMessage({ type: "start-recording", tabId: tab.id });
    }
});


chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
    if (message.type === 'message') {
        alert(message.mes)
    }
})

//service-worker.js

chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
    if (message.type === "start-recording") {
        try {
            console.log("Requesting tab media stream...");
            const streamId = await chrome.tabCapture.getMediaStreamId({
                consumerTabId: message.tabId
            });

            console.log("Stream ID received:", streamId);

            // Inject content script
            await chrome.scripting.executeScript({
                target: { tabId: message.tabId },
                files: ["content.js"]
            });

            // Send stream ID to content script
            await chrome.tabs.sendMessage(message.tabId, {
                type: "process-stream",
                streamId: streamId
            });

        } catch (error) {
            console.error("Error starting tab capture:", error);
        }
    }
});

//content.js

chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
    if (message.type === 'process-stream') {
        try {
            const audioContext = new AudioContext({
                sampleRate: 48000,
                latencyHint: 'interactive'
            });

            // Get tab audio stream
            let tabStream = await navigator.mediaDevices.getUserMedia({
                audio: {
                    mandatory: {
                        chromeMediaSource: 'tab',
                        chromeMediaSourceId: message.streamId
                    }
                },
                video: false
            });

            chrome.runtime.sendMessage({ type: "message", mes: "starting hte capture" });

            // Load the AudioWorklet Processor
            await audioContext.audioWorklet.addModule("processor.js");

            const audioProcessor = new AudioWorkletNode(audioContext, "audio-processor");
            const source = audioContext.createMediaStreamSource(tabStream);

            source.connect(audioProcessor).connect(audioContext.destination);

        } catch (error) {
            console.error("Error capturing audio:", error.message || error);
        }
    }
    return true;
});

//processor.js

class AudioProcessor extends AudioWorkletProcessor {
    process(inputs, outputs, parameters) {
      const input = inputs[0];
      const output = outputs[0];

      if (input.length > 0) {
        for (let channel = 0; channel < input.length; channel++) {
          output[channel].set(input[channel]); // Forward audio to keep it audible
        }
      }

      return true; // Keep the processor running
    }
}

registerProcessor('audio-processor', AudioProcessor);

// popup.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Audio Capture</title>
    <link rel="stylesheet" href="popup.css">
</head>
<body>
    <button id="startCapture">Start Capture</button>
    <script src="popup.js"></script>
</body>
</html>

Checkboxes to select/check groups of checkboxes with Javascript

i have a form with a table in and each row has a checkbox. The n-rows show potentialy 3 types of entries (fruit/meat/vegetable). What i like to provide is 4 more Check Boxes on top of the Table so the user can

  1. check/select all rows,
  2. The fruit rows
  3. The meat rows
  4. The vegetable rows
    It should be possible to check/select fruit and meat (for example).
    I find code for Check/uncheck all rows but i am lost with check/select “groups” of rows.
    Any ideas?
    Many thanks in advice!
<FORM name="sel" action="nextpage.html" method=post>
  <table border="0" cellpadding="0" cellspacing="0" width="210px">
    <thead>
      <tr>
        <th with=50px></th>
        <th with=80px>NAME</th>
        <th with=80px>TYPE</th>
      </tr>
    </thead>
    <tbody>
      <TR>
        <TD with=50px><input type="checkbox" name="target[]" id="target" value="Banana;fruit" /> <label for="target"></label></td>
        <TD with=80px>Banana</TD>
        <TD with=80px>fruit</TD>
      <TR>
      <TR>
        <TD with=50px><input type="checkbox" name="target[]" id="target" value="Steak;meat" /> <label for="target"></label></td>
        <TD with=80px>Steak</TD>
        <TD with=80px>meat</TD>
      <TR>
      <TR>
        <TD with=50px><input type="checkbox" name="target[]" id="target" value="Apple;fruit" /> <label for="target"></label></td>
        <TD with=80px>Apple</TD>
        <TD with=80px>fruit</TD>
      <TR>
      <TR>
        <TD with=50px><input type="checkbox" name="target[]" id="target" value="Chicken breast;meat" /> <label for="target"></label></td>
        <TD with=80px>Chicken breast</TD>
        <TD with=80px>meat</TD>
      <TR>
      <TR>
        <TD with=50px><input type="checkbox" name="target[]" id="target" value="Potato;vegetable" /> <label for="target"></label></td>
        <TD with=80px>Potato</TD>
        <TD with=80px>vegetable</TD>
      <TR>
      <TR>
        <TD with=50px><input type="checkbox" name="target[]" id="target" value="Onion;vegetable" /> <label for="target"></label></td>
        <TD with=80px>Onion</TD>
        <TD with=80px>vegetable</TD>
      <TR>
      <TR>
        <TD with=50px><input type="checkbox" name="target[]" id="target" value="pineapple;fruit" /> <label for="target"></label></td>
        <TD with=80px>Pineapple</TD>
        <TD with=80px>fruit</TD>
      <TR>
    </tbody>
  </table>
  </div>
  <BR />
  <BUTTON TYPE="SUBMIT" VALUE='Weiter!' />Weiter</BUTTON>
</FORM>

select element inside a table after creating it with ajax call

I have an unput field and some functions. This input field makes an ajax call, returns a table and inserts it onto the page. This table has editable fields and a save button.

Functions I have don’t seem to work with this returned table. I think it is because functions existed before the table and are not aware of it?

How can I make the pre-existing functions aware of the new table and its elements? Or what is the correct way to work with the new table?

JsSIP “peerconnection” Event Not Firing for Outbound Calls – Why and How to Fix?

I’m building a web-based SIP phone application using JsSIP (version 3.10.0) to handle VoIP calls over WebRTC. My setup works fine for inbound calls—audio streams both ways—but I’m facing an issue with outbound calls where I can’t hear the remote party, and the “peerconnection” event isn’t firing as expected.

What I’m Doing

Setup: I’m using JsSIP to connect to a SIP server via WebSocket (WSS). The client registers successfully and can initiate/receive calls.
Code Structure: I handle all new sessions (inbound and outbound) in a handleNewRTCSession function triggered by the “newRTCSession” event from JsSIP’s UA. For WebRTC, I rely on the “peerconnection” event to access the RTCPeerConnection and attach a “track” listener to capture the remote audio stream.
Outbound Call Flow: I call userAgent.call(target, callOptions) to start an outbound call. The call connects (remote party answers), and they can hear me, but I don’t hear them.

 const userAgent = new JsSIP.UA({
  uri: "sip:[email protected]",
  password: "****",
  sockets: [new JsSIP.WebSocketInterface("wss://sip-server.example.com:7443")],
});

const callOptions = {
  mediaConstraints: { audio: true, video: false },
  pcConfig: { iceServers: [{ urls: "stun:stun.l.google.com:19302" }] },
};

userAgent.on("newRTCSession", handleNewRTCSession);

function handleNewRTCSession(e) {
  const session = e.session;
  console.log("New session:", session.direction);

  session.on("peerconnection", (data) => {
    console.log("Peerconnection event:", data);
    const peerConnection = data.peerconnection;
    peerConnection.addEventListener("track", (event) => {
      console.log("Remote stream received:", event.streams[0]);
      document.getElementById("remoteAudio").srcObject = event.streams[0];
    });
  });

  session.on("accepted", () => {
    console.log("Call accepted");
  });

  session.on("failed", (e) => {
    console.log("Call failed:", e.cause);
  });

  if (session.direction === "outgoing") {
    console.log("Outbound call started");
  }
}

function makeCall(target) {
  userAgent.call(target, callOptions);
}

// Start UA
userAgent.start();

The Workaround which i’m trying right now is forcing peerconnection when the call is accepted in outbound case:

   if (session.connection && session.direction === óutgoing) {
          console.log("Manually handling peer connection:", session.connection);
          handlePeerConnection({ peerconnection: session.connection });
        }

function handlePeerConnection(data) {
  console.log(data);
  const peerConnection = data.peerconnection;
  peerConnection.addEventListener("track", (event) => {
    console.log(event);
    console.log("StreamViewType", event.streams);
    const remoteStream = event.streams[0];
    console.log("Remote stream received:", remoteStream);
    audioElement.srcObject = remoteStream;
    audioElement
      .play()
      .catch((e) => console.error("Audio playback failed:", e));
  });

  peerConnection.addEventListener("icecandidate", (event) => {
    if (event.candidate) {
      console.log("ICE candidate:", event.candidate);
    } else {
      console.log("ICE gathering complete");
    }
  });
}

Questions

  1. Why isn’t the “peerconnection” event firing for outbound calls in
    JsSIP 3.10.0, even though the call connects and session.connection
    exists?
  2. Is this a known bug, a configuration issue, or something specific to
    my SIP server’s SDP/ICE handling?
  3. Is manually using session.connection a safe long-term solution, or
    should I adjust my approach (e.g., update JsSIP, change
    callOptions)?

Additional Details

JsSIP Version: 3.10.0

Browser: Chrome (latest)

SIP Server: A hosted FusionPBX.

SDP: Local offers Opus/G722/PCMU, remote responds with G722, both sendrecv.

I’d appreciate any insights or suggestions to fix this cleanly without relying on the workaround. Thanks!

Jodit inline toolbar auto-open

Is there a way to keep Jodit’s inline toolbar open (if there’s selected text) after a choice is made from the toolbar? If not, is there a way to auto-open the inline toolbar if currently there’s selected text?

Currently the toolbar closes any time a choice is made – this means if I need to apply multiple settings to a selection I need to make the same selection that many times.