Is there a way to open a second connection to IndexedDB or kill a prior request so the next loads?

I’m trying to get a bunch of MP3 blob files off of a website that stored them to the browser cache in IndexedDB > localforage. In the developer console, I tried a simple:

const request = window.indexedDB.open("localforage", 1);
console.log(request)

But the readyState is stuck in “pending”. Obviously the site has something going on in the background. Is there a way to kill whatever request is currently at the head of the queue or open a second “read only” connection?

From initial research, this seemed to be the only way to get the blob files to download in bulk. I can do them one by one by hitting play on the offline player and stripping it from the HTML, but it takes forever since I have to play each one before the blob loads and I can download it. The blob file is a straight MP3 – once it’s downloaded, I just add the .mp3 extension and it works. If there is a better way to get these files than trying to force my way into IndexedDB, I’m open to suggestions.

Boolean based authentication in java script

This is my first website so any advice will be appreciated.

Main questions

How can I stop functions from executing in java script?
Is this a bad authentication method? IE would I be better of building something else?

I am making a website that my friends and I can upload all the pictures we took on a trip we went on. I do not want random people to be able to upload to the website. So I am requiring a key before the upload and submit buttons are shown. I am using wix and adding my own java-script.

I have a back end server that will check the value of a key and return a boolean. That triggers the front end to change. I know this isn’t secure so I would like deny submissions if the returned boolean is false to the upload button.

I have tried an if statement that should break out of function by calling return. That did not work. I have also tried using a try catch block where an error is thrown if the boolean is false

What else can I try block the submit?

The code is below

$w('#button1').onClick((event) => {
   if (!allowedUpload) {
       console.log(curKey,"not authorized");
       return;
    }
   console.log(curKey," may upload");
  
});



/* try catch attempt

try {
   if (allowedUpload === false) {
     throw new Error("notAuthorized");
       console.log(curKey,"not authorized");

    }
   console.log(curKey," may upload");
} catch (error) {
       console.log("may not upload");
} 

*/

Display Hidden Table Cell on click of another Table Cell in HTML, CSS, and JavaScript

So here’s my problem…

I’m trying to create a fun little “avoid the mines” game using HTML, CSS, and JavaScript.

The objective is to get to the end of the level by clicking on a grid of tiles while avoiding clicking on a mine tile (this will give you a game over).
To do this, you have to click on each tile sequential order, which will reveal the next adjacent tile. For example: clicking on tile A2 will reveal tile A3, clicking on tile A3 will reveal tile A4, and so on.

Figure 1 showing all the currently visible tiles in the grid (which is just a table with some CSS styling applied).

Figure 2 showing a tile that has been clicked on (A2), along with the adjacent tile (A3) that should be revealed by clicking on A2.

However, I can’t figure out how to make the “reveal tile by clicking on an adjacent tile” function work.

If anyone could help me figure out how to make the hidden tiles be revealed sequentially by clicking on another already-visible adjacent tile, I would be very grateful.

(Ideally, I’d like to avoid having to use JavaScript as much as possible. But if it has to be done, then please share your JavaScript-based solutions.)

Also, Here’s the HTML and CSS code I have for the table…

body {
    background-color: black;
}

table {
    border-collapse: collapse;
    position: absolute;
}

td {
    width: 64px;
    height: 64px;
    text-align: center;
    justify-content: center;
}

.TileStart {
    border: 1px solid lightgray;
    background-color: white;
}

.Tile {
    border: 1px solid lightgray;
    background-color: black;
    cursor: pointer;
}

.TileFinish {
    border: 1px solid lightgray;
    background-color: black;
    cursor: pointer;
}

#A4, #A5 {
    visibility: hidden;
}
<!DOCTYPE html>
<html>
<head>
  <title>Minefield Game Hidden Tiles Test</title>
  <link rel="stylesheet" href="hidden-tiles-test-styles.css">
  <meta charset="utf-8">
  <meta name="description" content="Testing hidden cells in tables.">
 </head>
 <body>
  <table>
    <tr>
        <td class="TileStart" id="A1"></td>
        <td class="Tile" id="A2" onclick="style='background-color: darkgray;'"></td>
        <td class="Tile" id="A3" onclick="style='background-color: darkgray;'"></td>
        <td class="Tile" id="A4" onclick="style='background-color: darkgray;'"></td>
        <td class="TileFinish" id="A5" onclick="style='background-color: white;'"></td>
    </tr>
  </table>
 </body>
 </html>

Phase 2 of Google Apps Script Web App Fails to Load via ?page= Query — No Logs Triggered

Introduction:
I’m building a multi-phase contractor dashboard in Google Apps Script using a custom HTML frontend and doGet(e) routing. The form UI loads in three sequential phases (?page=1, ?page=2, ?page=3), and each phase is served by the same doGet(e) function using an if/else switch on e.parameter.page.

The issue:
?page=1 loads perfectly. However, when navigating to ?page=2, the app freezes with a blank page, and no error appears in the Execution Log. No doGet(e) execution is triggered, which leads me to suspect:

Either a client-side blocking bug in the Phase 1 HTML,

Or that a server-side error is failing silently in Apps Script.

Despite console debugging and test logging, no entry shows in the Executions log for the second page load.

What we’ve tried:
Verified that the navigation links are valid.

Used Logger.log() and console.log() to trace phase entry points.

Checked HTML and JS for missing form elements or syntax errors.

Deployed a test version with minimal HTML to isolate where the error might occur.

Question:

How can I debug Apps Script doGet routing when nothing appears in the Execution Log?

Also, are there known conditions (like malformed HTML or JS errors) that can prevent doGet() from firing at all?

Invertase Stripe Payment Extension Issue: Metered Pricing

I am trying to get the invertase extension to work with metered pricing but I keep getting the error: {message: ‘Quantity should not be specified where usage_type is metered. Remove quantity from line_items[0]‘} even though I have no quantity part of the adddoc package.

I am not setting the quantity anywhere in my code but I can’t get it to work. I have tried setting quantity to null, unset etc but it just gives invalid integer then.

Not sure what else to provide but happy to give any information needed.

'use client';

import { auth, db } from '@/firebaseConfig';
import type { FirebaseApp } from 'firebase/app';
// make sure db is exported here
import { addDoc, collection, onSnapshot } from 'firebase/firestore';
import { getFunctions, httpsCallable } from 'firebase/functions';

import { logger } from '@/lib/default-logger';

const PRICE_ID = process.env.NEXT_PUBLIC_STRIPE_METERED_PRICE!;
const CLOUD_RUN_ROOT = process.env.NEXT_PUBLIC_CLOUD_RUN_ROOT!;

/**
 * Creates a Checkout Session document in
 *   stripe_customers/{uid}/checkout_sessions
 * and waits for the extension to fill in `url`.
 */
export async function getCheckoutUrl(): Promise<string> {
  const user = auth.currentUser;
  if (!user) throw new Error('Must be signed-in first');

  // 1️⃣  Create the Checkout-Session request doc
  const sessionRef = await addDoc(collection(db, 'stripe_customers', user.uid, 'checkout_sessions'), {
    price: PRICE_ID, // single-price subscription
    mode: 'subscription',
    success_url: window.location.href,
    cancel_url: window.location.href,
    metadata: { storeId: user.uid },
  });

  // 2️⃣  Listen for the extension to populate `url` or `error`
  return new Promise<string>((resolve, reject) => {
    const unsubscribe = onSnapshot(
      sessionRef,
      (snap) => {
        const data = snap.data();
        if (!data) return;

        if (data.error) {
          unsubscribe();
          logger.error('Stripe ext error', data.error);
          reject(new Error(data.error.message ?? 'Stripe extension failed'));
        }

        if (data.url) {
          unsubscribe();
          resolve(data.url as string);
        }
      },
      (err) => {
        unsubscribe();
        reject(err);
      }
    );

    setTimeout(() => {
      unsubscribe();
      reject(new Error('Timed out waiting for Stripe Checkout URL'));
    }, 60_000);
  });
}

How do I redesign the JSONeditor to display JSON data so that the design of the fields and values ​is more user-friendly [closed]

How do I redesign the JSONeditor to display JSON data so that the design of the fields and values ​​is more user-friendly? The current design is completely unsuitable for this purpose. I would like the design to be dynamic, so that the fields and values ​​are generated from the JSON data.

    <div id="json-editor-container" style="height: 500px; border: 1px solid #ccc;"></div>

function onEditingStart(e) {
    currentEditingData = e.data;

    setTimeout(() => {
        const container = document.getElementById("json-editor-container");
        if (container) {
            container.innerHTML = "";

            //const options = {
            //    mode: 'form',
            //    // modes: ['tree', 'form', 'code'],
            //    // disableEditJson: true,     //  JSON
            //    // disableProperties: true ,   //
            //    onChangeJSON: function (json) {
            //        if (e.component && e.data && jsonEditorInstance) {
            //            console.log(jsonEditorInstance);
            //            const updatedJson = jsonEditorInstance.get();
            //            console.log(updatedJson);
            //            // e.component.cellValue(e.key, "Parameters", JSON.stringify(updatedJson));
            //            currentEditingData.Details = JSON.stringify(updatedJson);
            //        }
            //    }
            //};
            const options = {
                modes: ['tree', 'form', 'view'],
                search: true,
                onError: (err) => console.error(err),

                // القالب الديناميكي الرئيسي
                templates: [
                    {
                        text: 'Dynamic Image Preview',
                        field: '*', // تطبق على جميع الحقول
                        template: (value, path) => {
                            // الفحص الديناميكي إذا كانت القيمة تمثل صورة
                            console.log(value);
                            console.log(path);
                            if (isImageField(value)) {
                                return renderImagePreview(value);
                            }
                            // فحص خاص للحقول التي تحتوي على مصفوفة من الصور
                            if (Array.isArray(value) && value.every(isImageField)) {
                                return value.map(img => renderImagePreview(img)).join('');
                            }

                            // إرجاع القيمة الأصلية إذا لم تكن صورة
                            return value;
                        }
                    }
                ]
            };
            jsonEditorInstance = new JSONEditor(container, options);

            try {
                const processedData = e.data.Details ? JSON.parse(e.data.Details) : {};
                console.log(processedData);
                const initialJson = processDynamicFields(processedData, baseUrl+'/');
                //const initialJson = processedData ? JSON.parse(processedData) : {};
              //  const editor = new JSONEditor(container, options, processedData);
                console.log(initialJson);
                jsonEditorInstance.set(initialJson);
            } catch (err) {
                jsonEditorInstance.set({});
            }
        }
    }, 100);
}

Recording audio using expo-audio not releasing instance

I have a chat/messaging app with audio recording feature where users can send voice messages.

I am currently using the old, deprecated expo-av library and trying to migrate the newer version expo-audio.

In the old version (expo-av), after the user finishes recording audio and I complete uploading (processing) it, I would call a method:

await recording.stopAndUnloadAsync();

Which releases the instance, so user can record a new audio

In the newer version (expo-audio), I can’t find a similar method to call. In the documentation, it says just do:

audioRecorder.stop();

But it seems that this method doesn’t clear the current memory/release the instance.

If a user records audio once, then tries again to record new audio, they get the previous recorded audio (same audio and same local uri)

My code:

import { RecordingPresets, useAudioRecorder } from 'expo-audio';
import { useState } from "react";


export default function useRecorder() {
    const audioRecorder = useAudioRecorder(RecordingPresets.HIGH_QUALITY);
    const [isRecording, setIsRecording] = useState(false);

    const startRecording = async () => {
        await audioRecorder.prepareToRecordAsync();
        audioRecorder.record();
        setIsRecording(true);
    };

    const stopRecording = async () => {
        await audioRecorder.stop();
        console.log(audioRecorder.uri)
        setIsRecording(false);
    };

    return { startRecording, stopRecording };
}

I am using the recorder as a hook with two methods (I have omitted the permission part for simplicity).
The first method starts the recording and the second method stops the recording.

In the stopRecording method, I console.log the uri for the file. Every time I am getting the very same uri and if I play it, I get the same audio I recorded the first time.

React Router renders wrong component for the grandchildren. @react-router/dev

Routes.ts

import { 
  type RouteConfig,
  index,
  route,
  layout
} from "@react-router/dev/routes";

export default [
  layout("layouts/main_layout.tsx", [
    route("dashboard", "routes/dashboard/index.tsx", [
      route("employee", "routes/dashboard/employee/index.tsx", [
        route("add", "routes/dashboard/employee/add/index.tsx")
      ]),
    ]),
    route("*", "routes/not-found.tsx")
  ]),
  layout("layouts/auth_layout.tsx", [
    route("/login", "routes/login.tsx"),
  ])
] satisfies RouteConfig;

./routes/dashboard/employee/add/index.tsx

import EmployeeAddPage from "~/pages/dashboard/employees/Add";

export function meta() {
  return [
    { title: "Dashboard - Employee - Add - Index" },
    { name: "dashboard", content: "Index" },
  ];
}

export default function Index() {
  return <EmployeeAddPage />;
}
export default function EmployeeAddPage() {
  return (
    <div>
      <input name={"trajce"} value={"trajce"} />
      asdasd

      <p>asdasd</p>
    </div>
  )
}

./routes/dashboard/employee/index.tsx

import EmployeeListPage from "~/pages/dashboard/employees/List";

export function meta() {
  return [
    { title: "Dashboard - Employee" },
    { name: "dashboard", content: "Index" },
  ];
}

export default function Index() {
  return <EmployeeListPage />;
}

browser image

For some reason the <EmployeeListPage /> component is showing on "/dashboard/employee/add", instead of <EmployeeAddPage />. Is there some limitation to the routing depth, like only the parent and children working, but children’s children and so on, not? Is this a bug or I need to configure this or maybe the code is broken?

I see “Dashboard – Employee – Add – Index” on the tab

Stuck on SQL Lab 6.2.3 (Cisco Data Analytics Essentials) – Query Not Working

Currently stuck on 6.2.3 SQL Lab: SQL Around the World in the Data Analytics Essentials course (CISCO Networking Academy).

I’ve tried both:

SELECT * 
FROM shapes 
WHERE color = 'red'

and

SELECT * 
FROM shapes 
WHERE color LIKE 'red'

…but I keep getting the same error and now I can’t claim my badge
Anyone know what I might be missing?

enter image description here

Vite API proxy redirects to configured target

I have configured an API proxy in vite.config.ts:

    server: {
        proxy: {
            '/api': {
                target: 'http://nginx_backend:80',
                changeOrigin: true,
                rewrite: (path) => path.replace(/^/api/, ''),
            }
        }
    },

(https://git.var-lab.com/opencal/web-frontend/-/blob/main/vite.config.ts?ref_type=heads#L26)

the endpoint is set here as baseUrl:

const apiClient = axios.create({
    baseURL: '/api',
    headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    },
});

(https://git.var-lab.com/opencal/web-frontend/-/blob/main/src/services/api.ts?ref_type=heads#L3)

When I use a method like this

export async function getDayAvailabilities(email: string, dayAsString: string, eventTypeId: number): Promise<Availability> {
    try {
        const response = await apiClient.get(`/availability/day/?email=${email}&date=${dayAsString}&event_type_id=${eventTypeId}`);
        return response.data;
    } catch (error) {
        console.error(error);
        throw error;
    }
}

(used here: https://git.var-lab.com/opencal/web-frontend/-/blob/main/src/components/booking/BookingAvailabilities.vue?ref_type=heads#L99)

to request the API behind the proxy, the request is redirected from http://localhost/api/availability/day/[email protected]&date=2025-07-23&event_type_id=1 to http://nginx_backend/availability/[email protected]&date=2025-07-23&event_type_id=1

Reproduction

https://git.var-lab.com/opencal/web-frontend

Steps to reproduce

It can be reproduced by following the setup steps in the readme here https://git.var-lab.com/opencal/local-dev

When the fixtures are loaded, open http://localhost/[email protected] in your browser, select a event type and then a day. In the debug toolbar you will see what appens.

System Info

It runs in docker, see https://git.var-lab.com/opencal/web-frontend/-/blob/main/Dockerfile

Logs

How to plot Google Calendar–like API response (recurring events, exceptions) on a custom frontend calendar?

I’m currently building a backend-first calendar scheduling system (like Google Calendar), and I’m working with the following type of event data returned from my API:

It includes recurring events (RRULE), all-day events (start.date), time-specific events (start.dateTime), and exception instances (e.g. cancelled occurrences of a recurring event).

I am going to replicate the response same as a google calendar api reponse.

Here’s a sample of Google API response:

json
Copy
Edit
it

{
        "kind": "calendar#event",
        "etag": ""3503602610079486"",
        "id": "6butbk1c770g1pnp4fnn2sokbd",
        "status": "confirmed",
        "htmlLink": "https://www.google.com/calendar/event?eid=NmJ1dGJrMWM3NzBnMXBucDRmbm4yc29rYmRfMjAyNTA3MDYgZ2FnYW9xcGhzQG0",
        "created": "2025-07-06T11:24:59.000Z",
        "updated": "2025-07-06T11:28:25.039Z",
        "summary": "Event Daily All Day Event",
        "creator": {
            "email": "[email protected]",
            "self": true
        },
        "organizer": {
            "email": "[email protected]",
            "self": true
        },
        "start": {
            "date": "2025-07-06"
        },
        "end": {
            "date": "2025-07-07"
        },
        "recurrence": [
            "RRULE:FREQ=DAILY"
        ],
        "transparency": "transparent",
        "iCalUID": "[email protected]",
        "sequence": 0,
        "reminders": {
            "useDefault": false
        },
        "eventType": "default"
    },
    {
        "kind": "calendar#event",
        "etag": ""3503602610079486"",
        "id": "6butbk1c770g1pnp4fnn2sokbd_20250708",
        "status": "cancelled",
        "htmlLink": "https://www.google.com/calendar/event?eid=NmJ1dGJrMWM3NzBnMXBucDRmbm4yc29rYmRfMjAyNTA3MDggZ2FnYW9xcGhzQG0",
        "created": "2025-07-06T11:24:59.000Z",
        "updated": "2025-07-06T11:28:25.039Z",
        "summary": "Event Daily All Day Event",
        "creator": {
            "email": "[email protected]",
            "self": true
        },
        "organizer": {
            "email": "[email protected]",
            "self": true
        },
        "start": {
            "date": "2025-07-08"
        },
        "end": {
            "date": "2025-07-09"
        },
        "recurringEventId": "6butbk1c770g1pnp4fnn2sokbd",
        "originalStartTime": {
            "date": "2025-07-08"
        },
        "transparency": "transparent",
        "iCalUID": "[email protected]",
        "sequence": 1,
        "reminders": {
            "useDefault": false
        },
        "eventType": "default"
    },
    {
        "kind": "calendar#event",
        "etag": ""3503602744428542"",
        "id": "10rll18oedfpa2nbh6hrf6ragb",
        "status": "confirmed",
        "htmlLink": "https://www.google.com/calendar/event?eid=MTBybGwxOG9lZGZwYTJuYmg2aHJmNnJhZ2IgZ2FnYW9xcGhzQG0",
        "created": "2025-07-06T11:29:32.000Z",
        "updated": "2025-07-06T11:29:32.214Z",
        "summary": "Test ",
        "creator": {
            "email": "[email protected]",
            "self": true
        },
        "organizer": {
            "email": "[email protected]",
            "self": true
        },
        "start": {
            "dateTime": "2025-07-08T07:30:00Z",
            "timeZone": "UTC"
        },
        "end": {
            "dateTime": "2025-07-08T08:30:00Z",
            "timeZone": "UTC"
        },
        "iCalUID": "[email protected]",
        "sequence": 0,
        "reminders": {
            "useDefault": true
        },
        "eventType": "default"
    },
    {
        "kind": "calendar#event",
        "etag": ""3503603073450078"",
        "id": "6ldsh849d28crn0fl5kl9ne35o",
        "status": "confirmed",
        "htmlLink": "https://www.google.com/calendar/event?eid=Nmxkc2g4NDlkMjhjcm4wZmw1a2w5bmUzNW9fMjAyNTA3MDZUMjAzMDAwWiBnYWdhb3FwaHNAbQ",
        "created": "2025-07-06T11:32:16.000Z",
        "updated": "2025-07-06T11:32:16.725Z",
        "creator": {
            "email": "[email protected]",
            "self": true
        },
        "organizer": {
            "email": "[email protected]",
            "self": true
        },
        "start": {
            "dateTime": "2025-07-06T20:30:00Z",
            "timeZone": "UTC"
        },
        "end": {
            "dateTime": "2025-07-06T20:45:00Z",
            "timeZone": "UTC"
        },
        "recurrence": [
            "RRULE:FREQ=WEEKLY;WKST=SU;BYDAY=SU"
        ],
        "iCalUID": "[email protected]",
        "sequence": 0,
        "reminders": {
            "useDefault": true
        },
        "eventType": "default"
    }

Smoothing scroll animations in js

So my question is extremely simple, i see it on lots of websites
https://www.jordangilroy.com/#work
this one for example is my reference, when you scroll it feels alot smoother and the animations kinda like “catch up” to your scroll. only thing i can find is scroll-behaviour:smooth; which is obviously not what i need.

im very new to js so idk most of the functions ive tried to replicate a scrolling feature.

im not entirely sure how im supposed to show my example so ill just use a screenshot
my attempt
as you can see its kind of like splitting the images between the two parallax backgrounds, but the scrolling and animations feel too rigid.

The code below is mainly just for the image cutting kinda feature so yea. not sure how i can do the smooth animation

//#region history image changer (scroll Event)
const historyContent = document.getElementsByClassName("historyLayout");
const parallaxContent = document.querySelectorAll('section .parallax');
window.addEventListener('scroll', () => {
  let scrollY = window.scrollY;

  const prehistoricContainer = historyContent[0];
  const containerMiddle = (prehistoricContainer.getBoundingClientRect().top - prehistoricContainer.getBoundingClientRect().bottom) / 2;
  const containerHalf = prehistoricContainer.getBoundingClientRect().top - containerMiddle;
  if (containerHalf <= window.innerHeight / 2) {
    for (const content of historyContent) {
      content.style.position = "fixed";
      content.style.top = "0";
      content.style.left = "0";
      content.style.right = "0";
      content.style.bottom = "0";
      if ((scrollY - containerHalf - 1000) <= window.innerHeight / 2) {
        content.style.position = "absolute";
      }
    }
  }

  cuttingImages();
}
);

let cutcounter = 0;
function cuttingImages() {
  let section1 = historyContent[cutcounter];

  let parallax2 = parallaxContent[cutcounter + 1];
  let section2 = historyContent[cutcounter + 1];

  let image1Top = section1.getBoundingClientRect().top;
  let section2Top = parallax2.getBoundingClientRect().top;
  let progress = (image1Top - section2Top) / -966;
  progress = Math.max(0, Math.min(1, progress));
  section1.style.clipPath = 'inset(0 0 ' + (100 - progress * 100) + '% 0)';
  section2.style.clipPath = 'inset(' + (progress * 100) + '% 0 0 0)';
  if (progress === 0 && cutcounter === 0) {
    cutcounter++;
  }
  if (progress === 1 && cutcounter > 0) {
    cutcounter--;
  }
}

//#endregion

i tried scroll-behaviour: smooth; obviously not what i need
i heard about requestanimationframe and wasnt rlly sure how to implement it, i tried it, nothing looks different, there wasnt much difference if at all so not sure either.

Cant filter an array based on another arrays content

I’m willing to do the following:
I have an array with this apparence:

finalFiltrada = [
    {
      "año_cuatri": "1° 1°",
      "codigo": "1.1.1",
      "nombre": "Técnicas de Programación",
      "estado": "Promocionada",
      "año_cursada": "2024 2°C",
      "nota": 8,
      "tiene_apuntes": true,
      "link_apuntes": "111_tecnicas_de_programacion"
    },

]

Depending on the filter you click:showing the filters of the page

I receive an array with the above structure, where the field ‘estado’, can be one of these: ‘Promocionada’, ‘Pendiente’, ‘Cursando’

So I receive the subjects array of objects, but my problem is:
I also receive an array with the checkboxs clicked, looks like this:
dataFiltradaSeleccionada = ['Promocionada', 'Pendiente', 'Cursando']

What I’m currently doing is:

        if (dataFiltradaSeleccionada.length > 0) {
            finalFiltrada = finalFiltrada.filter((e, i) => {

                // if (e.estado === dataFiltradaSeleccionada) {
// this doesnt work because dataFiltradaSeleccionada is maximum 3 positions
                //     console.log("e.estado", e.estado);
                //     console.log("dataFiltradaSeleccionada[i]", dataFiltradaSeleccionada[i]);
                // }

                return e.estado.includes(dataFiltradaSeleccionada)
            })

        }

But this doesn’t work when I clicked more than one checkbox

Web Components: Slots are not working as (I) expected in light DOM

How can I change the following light DOM custom element to show the content of the default slot between (!!!) the two horizontal rulers?
Please be aware, that I cannot use shadow DOM in my use case.

<!DOCTYPE html>
<html lang="en">

<head>
</head>

<body>
  <script>
    class MyComponent extends HTMLElement {
      connectedCallback() {
        this.innerHTML = `
          <hr>
          <slot></slot>
          <hr>
        `;
      }
    }

    customElements.define('my-component', MyComponent);
  </script>

  <my-component>
    This text shall be placed between the two rulers, not below them.
  </my-component>
</body>

</html>