How to extract text content preserving its formatting using DOM

I am developing a Chrome extension that can extract job descriptions from LinkedIn job posts. However, when I use .textContent or .innerText in DOM manipulation to extract the job description, the output does not match the formatting or appearance of manually copying and pasting the job description into a document. How can I resolve this issue?

How to extract text content with its styles using DOM

I am developing a Chrome extension that can extract job descriptions from LinkedIn job posts. However, when I use .textContent or .innerText in DOM manipulation to extract the job description, the output does not match the formatting or appearance of manually copying and pasting the job description into a document. How can I resolve this issue?

Fabric “Rect” object is placed outside the “div” element of its “canvas” element

I’m working with Fabric js and I’m having a problem with a “rect” object. With the following structure of my page:

<div id="div0">
        <div id="divDespl"></div>
        <div id="divCont">
            <div id="divIz"></div><div id="div1" ><canvas id="micanvas"></canvas></div>
        </div>
</div>

The “rect” object is placed outside of the “div1” div (which is the div containing the “micanvas” canvas that the “rect” object is supposed to be added to).

The result looks like this:

enter image description here

The rectangle is below.

When I use a simple structure like this:

<div id="div1" ><canvas id="micanvas"></canvas></div>

The rectangle does appear placed in the div “div1”. It looks like this.

enter image description here

The function that does the work with javascript is the following:

function Canvas2(nombrearchivo) {
       
        let di = document.getElementById("div1");
       
        di.style.backgroundImage = "url('/google/archivosdescargados/" + nombrearchivo + "')";     
        $("#div1").css("background-size", "contain");
        $("#div1").css("background-repeat", "no-repeat");  
       
        const canvas = new fabric.Canvas(micanvas);      

        // create a rect object
        const deleteIcon =
            "data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3C!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3E%3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='500.275px' height='500.275px' viewBox='200 215 230 470' xml:space='preserve'%3E%3Ccircle style='fill:%23F44336;' cx='299.76' cy='439.067' r='218.516'/%3E%3Cg%3E%3Crect x='267.162' y='307.978' transform='matrix(0.7071 -0.7071 0.7071 0.7071 -222.6202 340.6915)' style='fill:white;' width='65.545' height='262.18'/%3E%3Crect x='266.988' y='308.153' transform='matrix(0.7071 0.7071 -0.7071 0.7071 398.3889 -83.3116)' style='fill:white;' width='65.544' height='262.179'/%3E%3C/g%3E%3C/svg%3E";

        var deleteImg = document.createElement('img');
        deleteImg.src = deleteIcon;

        fabric.Object.prototype.transparentCorners = false;
        fabric.Object.prototype.cornerColor = 'blue';
        fabric.Object.prototype.cornerStyle = 'circle';

        const rect = new fabric.Rect({
            left: 100,
            top: 50,
            width: 200,
            height: 100,
            objectCaching: false,
            stroke: 'lightgreen',
            strokeWidth: 4            
        });
        rect.controls.deleteControl = new fabric.Control({
            x: 0.5,
            y: -0.5,
            offsetY: 16,
            cursorStyle: 'pointer',
            mouseUpHandler: deleteObject,
            render: renderIcon,
            cornerSize: 24,
        });
        canvas.add(rect);
        canvas.setActiveObject(rect);


        function deleteObject(_eventData, transform) {
            const canvas = transform.target.canvas;
            canvas.remove(transform.target);
            canvas.requestRenderAll();

        }

        function renderIcon(ctx, left, top, _styleOverride, fabricObject) {
            const size = this.cornerSize;
            ctx.save();
            ctx.translate(left, top);
            ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle));
            ctx.drawImage(deleteImg, -size / 2, -size / 2, size, size);
            ctx.restore();

        }

}

The CSS style code is as follows:

  <style type="text/css">
         html, body {
             height: 100%; margin: 0; width: 100%;
         }
         
         /* html {padding-top: 1%;} */
          #div0 {  
             height: 100%;
             width: 100%;
             background-color: red;
         }
           #divDespl {            
             height: 3%;
             width: 100%;
             background-color: yellow;
         }
            #divCont {            
             display: inline-block;
             height: 97%;
             width: 100%;
             background-color: orange;
         }
            #divIz {            
             height: 97%;
             width: 3%;
             background-color: navajowhite;
             float: left;             
         }
         #div1 {            
             display: block;
             justify-content: center;
             align-items: center;
             height: 97%;
             width: 94%;
             background-color: blue;
             z-index: 1
         }
          #divDe {            
             height: 97%;
             width: 3%;
             background-color: black;
             float: right;
             display: inline;
             
         }

         </style>

I wonder what could be the reason why when placing a more complex structure the rectangle comes out. At first it seems that it must be due to the CSS attributes of the elements, but I can’t find which one or which ones.

The image is as a background image in the div “div1” with “background-size” as “contain”. I don’t think that can affect it.

WebCrypto:DataError when attempting to unwrapKey

I want to use one public key to wrap another public key. Almost everything works right up until the unwrapKey step. It throws an opaque DataError with no further information about what is wrong. What could the issue be here?

const {privateKey: unwrappingKey, publicKey: wrappingKey} =
  await window.crypto.subtle.generateKey(
    {name: 'RSA-OAEP', modulusLength: 2000, publicExponent: new Uint8Array([1, 0, 1]), hash: 'SHA-256'},
    true, ['decrypt', 'wrapKey', 'unwrapKey']);

const {privateKey, publicKey} = await window.crypto.subtle.generateKey(
  {name: 'RSA-OAEP', modulusLength: 512, publicExponent: new Uint8Array([1, 0, 1]), hash: 'SHA-256'},
  true, ['encrypt', 'decrypt']);

const wrappedKey = await window.crypto.subtle.wrapKey(
  'jwk', publicKey, wrappingKey,
  {name: 'RSA-OAEP', modulusLength: 512, publicExponent: new Uint8Array([1, 0, 1]), hash: 'SHA-256'});

// vvvv This line throws `DataError`
const unwrappedKey = await window.crypto.subtle.unwrapKey(
  'spki', wrappedKey, unwrappingKey, {name: 'RSA-OAEP'},
  {name: 'RSA-OAEP', hash: 'SHA-256'},
  true, ['encrypt']);
console.log(unwrappedKey);

setup hedera local network

Here’s your question with the code properly formatted:


I’m trying to run a Hedera local node locally, and I’m following the docker set up instructions followed by these instructions to set up a localhost network, but then hoping to change the connection settings to be able to connect to Hedera Testnet, instead of my own private network. But I got this error:

Error: MaxAttemptsOrTimeoutError: max attempts of 10 was reached for request with last error being: GrpcServiceError: gRPC service failed with: Status: TIMEOUT, Code: 17
    at AccountCreateTransaction.execute (C:UserssouhaOneDriveDesktopSouhailHederahello-hedera-js-sdknode_modules@hashgraphsdklibExecutable.cjs:677:11)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:540:9)
    at process.processTimers (node:internal/timers:514:7)
    at async main (C:UserssouhaOneDriveDesktopSouhailHederahello-hedera-js-sdkindex.js:25:22) {
  nodeAccountId: '0.0.3'
}

Here is the code I am running:

const {
  Client,
  PrivateKey,
  AccountId,
  AccountCreateTransaction,
  Hbar,
} = require("@hashgraph/sdk");

async function main() {
  // Operator credentials
  const operatorAccountId = "0.0.5163020"; // Default operator account
  const operatorPrivateKey = PrivateKey.fromString(
    "302e020100300506032b657004220420200c4b94c8449cb9b024fd9048c863245e5397d408771c7d86b58cb1ac602856" // Replace with private key from logs
  );

  // Node configuration
  const node = { "127.0.0.1:50211": new AccountId(3) }; // Node account ID is often `0.0.3`
  const client = Client.forNetwork(node).setMirrorNetwork("127.0.0.1:5600");

  // Set the operator
  client.setOperator(operatorAccountId, operatorPrivateKey);

  // Create a new account
  const newKey = PrivateKey.generateED25519();
  const newAccount = await new AccountCreateTransaction()
    .setKey(newKey.publicKey)
    .setInitialBalance(Hbar.fromTinybars(1000))
    .execute(client);

  const receipt = await newAccount.getReceipt(client);
  console.log("New Account ID:", receipt.accountId);
}

main().catch((err) => {
  console.error("Error:", err);
});

How to do Client-Side Data Validation Before Using Server Actions with useActionStatus

I have been researching this question for quite a while but always find methods that validate data on the server side, pass those validations back to the form, and then display the messages on the form. However, I don’t like this approach. I want to validate the data on the client side before sending it to server actions.

Note: I don’t want validation in server actions because I’m using a NestJS backend API, so server-side validation can be handled by the APIs.

I have solved it with the react query but I am still looking forward if I can do it using the useActionStatus or built-in APIs

useAddNewCard

import { useRouter } from 'next/navigation';

import { useMutation } from '@tanstack/react-query';
import { toast } from 'react-hot-toast';

import paymentService from '@/services/payment.service';

const useAddNewCard = () => {
  const router = useRouter();

  const { mutate: addNewCard, isPending: isAdding } = useMutation({
    mutationFn: paymentService().addNewCard,
    onSuccess: (data) => {
      router.push(data.url);
    },
    onError: (err) => toast.error(err.message),
  });

  return { isAdding, addNewCard };
};

export default useAddNewCard;

Helper method

export const handleClientAction = <Args extends any[], Success>(
  // eslint-disable-next-line no-unused-vars
  asyncFn: (...args: Args) => Promise<{ success?: Success; error?: string }>
) => {
  return async (...args: Args): Promise<Success> => {
    const filteredArguments = args.filter((item) => {
      const isObj = item instanceof Object;
      if (isObj && 'queryKey' in item) {
        return false;
      }
      if (isObj && 'meta' in item) return false;
      return true;
    }) as Args;
    const { success, error } = await asyncFn(...filteredArguments);
    if (success !== undefined) return success;
    throw new Error(error || 'An unknown error occurred');
  };
};

```

### Service

```
const addNewCard = handleClientAction(addNewCardAction);
```

### Server actions
```
export const handleAsyncAction = <Args extends any[], Result>(
  asyncFn: (...args: Args) => Promise<Result>
) => {
  return async (
    ...args: Args
  ): Promise<{ error?: string; success?: Result }> => {
    try {
      const success = await asyncFn(...args);
      return { success };
    } catch (error: any) {
      return { error: error.message || 'An unknown error occurred' };
    }
  };
};

export const addNewCardAction = handleAsyncAction(
  async (requestData: AddNewCardRequestType) => {
    const res: Response = await fetch(
      `${process.env.BACKEND_BASE}/payments/authorization`,
      {
        method: REQUEST_METHODS.POST,
        headers: {
          ...getJsonTypeHeader(),
          ...getNodeRequiredRequestHeaders(),
          ...getAuthorizationHeader(),
        },
        body: JSON.stringify(requestData),
      }
    );

    if (!res.ok) {
      const errorResponse = await getApiError(res);
      throw new Error(errorResponse.error);
    }
    const data: AddNewCardResponseType = await res.json();
    return data;
  }
);

```

the browser says the sw is “activated and running” but it never answers to any request (not working)

I’m using the workbox-build generateSW to generate my service worker.

  • Everything works fine with building the sw.js.
  • When it is installed, it follows with the precache and fills the cache storage as aspected but these assets are never used when a request is made by the client.
  • The browsers says the sw is activated and running but it never responds to any request from the client (like it was not there).

I tried listening to the fetch event but got nothing. Also, the runtimeCaching never happened. Allow me to summarize this again in points;

what works;

  • the sw is generated with no warning;
  • the precache part works fines and coroborate with the cache storage in the browser.

what doesn’t work:

  • the runtimeCaching does not seem to be working, the cache is empty of the expected assets from this action
  • even for the precached assset (in my case fonts, .css & .js), it still fetches it from the server, the sw does not react to any request from the client. I tried listening for the fetch event, got nothing. I also should add that i did’nt get the logs from workbox, even after i set disableDevLogs explicitly to false. I also tried ran this in incognito mode of the browser.

what i’ve tried:

  • played around in the app, to give it time (browser heuristics or something like that)
  • played around the ‘scope’ and ‘start_url’ from the manifest.json.

image of the Application devtool tab, the lower section is the network tab filtered for sw response

import {generateSW} from 'workbox-build';

export async function buildSW() {

  const {count, size, warnings}  = await generateSW({
    globDirectory: 'public',
    globPatterns: ['**/*.{js,css,ttf}'],
    swDest: 'public/sw.js',
    maximumFileSizeToCacheInBytes: 2000000000,
    disableDevLogs: false,
    cacheId: "local",
    cleanupOutdatedCaches: true,
    clientsClaim: true,
    // mode: "development",
    runtimeCaching: [{
      urlPattern: '/.(?:png|jpg|jpeg|svg)$/',
      handler: 'CacheFirst',
      options: {
        cacheName: 'image-cache',
        expiration: {
          maxEntries: 10,
          maxAgeSeconds: 60 * 60 * 24 * 30, // about a month
        },
      },
    }],
  })
  
  console.log(`Generated a service worker, which will precache ${count} files, totaling ${size} bytes and n warning: n ${warnings}.`);  
}

buildSW();

this is my package.json, i have a makefile target that runs pnpm sw && pnpm build

{
  "name": "frontend",
  "version": "1.0.0",
  "main": "tailwind.config.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "lint": "tsc",
    "build": "esbuild src/index.ts --bundle --minify --sourcemap --outfile=public/assets/scripts/beltech.js",
    "sw": "esbuild src/build-sw.ts --bundle --sourcemap --platform=node --packages=external --outfile=public/workbox-config.js && NODE_ENV=development node public/workbox-config.js",
    "dev:tsc": "tsc --watch --preserveWatchOutput",
    "dev:esbuild": "pnpm run build --watch=forever",
    "dev": "run-p dev:*"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "devDependencies": {
    "esbuild": "^0.24.0",
    "workbox-cli": "^7.3.0"
  },
  "dependencies": {
    "npm-run-all": "^4.1.5",
    "workbox-build": "^7.3.0",
    "workbox-routing": "^7.3.0"
  }
}

this is part of the manifest.json

...
"theme_color": "#fff",
    "background_color": "#fff",
    "display": "standalone",
    "orientation": "portrait",
    "start_url": "http://localhost:8090/account/dashboard",
    "scope": "/",
    "id": "/",
    "prefer_related_applications": false
...

How can I get a URL to open the Google Maps app from a custom route accessed via python API?

I am creating a Flask webapp that involves the use of the google maps API. I currently have JS query the flask backend for navigation results, using the googlemaps python library reference to compute a route calculation between two points. I have set alternatives=True to get multiple routes, and am now wondering how to use these route objects to create a custom google maps URL that will open The google maps app with the selected route.
All the solutions I have seen use maps URLs here that look something like: https://www.google.com/maps/dir/?api=1&parameters for a directions request but this seems to send a new directions calculation request to google and navigates to the maps app with that new directions request, which is not what I want. I want it to open google maps in navigation mode for the route I have already requested from google and clicked on in my app. I know navigation links can be achieved through dir_action=navigate but I want the link to work with the route I have clicked on in my app.

This seems like it should be possible, when using google maps normally, I can request a route in real time, click on one of the route alternatives, and create a link for that specific route and send it somewhere else like this, obviously the links are time sensitive but this sort of thing seems to be possible already. I wonder if I am going about this problem the wrong way, and if I should be using different frameworks entirely, but these have worked well for me for this project so far so I would like to continue to use them if possible

I use the decode_polyline function from the googlemaps api to send the polyline lat and long for the route to the front end, and then have added a listener that displays route data in a modal when the polyline is clicked on.

Here is the relevant JS

async function requestRoutes(start, end, waypoints = []) {
    try {
        const response = await fetch('/compute-route', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ start, end, waypoints })
        });

        if (!response.ok) {
            throw new Error('Failed to fetch route data');
        }
        const routeData = await response.json();
        if (routeData.error) {
            console.error('Error from server:', routeData.error);
            alert('Error calculating route. Please check input.');
        } else {
            //console.log('Route data:', routeData);
            curRouteData.push(routeData);
        }
    } catch (error) {
        console.error('Error:', error);
        alert('An error occurred while fetching the route.');
    }
}

function displayRoutesOnMap(routeData) {
    //console.log(routeData)
    curRouteData[0].forEach((route, index) => {

        const polyline = new google.maps.Polyline({
            path: route.overview_polyline,  
            strokeColor: index === 0 ? '#00FF00' : index===1 ? '#0000FF' :'#FF0000',  
            strokeOpacity: 0.7,
            strokeWeight: 4,
            map: map  
        });
        polyline.addListener('click', () => {
            showRouteInfo(route);
        });
        
        

    });
}

function showRouteInfo(route) {
    const routeDetails = document.getElementById('routeDetails');
    //console.log(route)
    routeDetails.innerHTML = '';
    route.legs.forEach(leg => {
        routeDetails.innerHTML += `${leg.start_address} to ${leg.end_address} : ${leg.steps.length} steps.`
      // more route details added
    });
    const mapsLink = document.getElementById("googleMapsButton")
    mapsLink.href = null; // I want help here if possible

    const routeModal = new bootstrap.Modal(document.getElementById('routeModal'));
    routeModal.show();
}

And here is the python that corresponds to the compute-route route:

@app.route('/compute-route', methods=['POST'])
def compute_route():
    data = request.get_json()
    start = data.get('start')
    end = data.get('end')
    directions_result = gmaps.directions(start, end, mode='driving', alternatives=True)

    for item in directions_result:
        item['overview_polyline'] = convert.decode_polyline(item['overview_polyline']['points'])
    
    return directions_result

All of my code works as I expect it to, the route is properly calculated and shown on the map from the polyline, and each listener for the polylines allow me to see the info for the route clicked on, now I just don’t know how to create a maps link that doesn’t just completely resend the navigation request to Google.

I see an old solution that uses a DirectionsRenderer Object here, and I have tried that, but I cannot get the DirectionsRenderer object to display routes from the python API backend responses, I am only having luck manually displaying the polyline. I get error InvalidValueError: setDirections: in property routes: not an Array when I instantiate a DirectionsRenderer object and pass my routeData object to it (the exact two lines of code I am adding in the displayRoutesOnMap function that error are:

const dRenderer = new google.maps.DirectionsRenderer({
        draggable: true,
        map: map,
    });
dRenderer.setDirections(curRouteData[0])

React Query – query with values of staleTime and cacheTime refetch api

I have defined

 export const ReactQueryConfig: QueryClientConfig = {   
    defaultOptions: {
        queries: {
            retryOnMount: false,
            refetchOnMount: false, // Prevent refetch when navigating back
            refetchOnReconnect: false,
            refetchOnWindowFocus: false,
            retry: 0,
            staleTime: 5 * 60 * 1000, // 5 minutes
            cacheTime:  10 * 60 * 1000 //default 10 minutes
        }
    } };

and I defined my queryClient as

const [queryClient] = React.useState(() => new QueryClient(ReactQueryConfig))

but when I go to another page and back to this page in a minute even when my query is fresh in “ReactQueryDevtools” but refetch the api .(react-query V3)

enter image description here

Extracting Data From Website (Javascript/VB.net)

I am trying to extract the total number of online users for a discord server. If I use the web version, you can see its located like this:

<h3 class="membersGroup_cbd271 container_a5ad5c text_a5ad5c">
   <span class="hiddenVisually_a98a7c">Online, 2,572 members</span>
   <span aria-hidden="true">Online — 2572</span>
</h3>

So, I have a timer that checks:

        Private Sub OnTimerTick(sender As Object, e As EventArgs)
            Dim browserTab = browser.ElementAt(0)
    
            If browserTab IsNot Nothing AndAlso browserTab.CanExecuteJavascriptInMainFrame Then
                Dim jsCode As String = "
        (function() {
    
    
            // Extract the number of online users between 'Online,' and 'members'
                const memberText = document.querySelector('div[role=""list""][aria-label=""Members""]')?.textContent.trim();
                const match = memberText ? memberText.match(/Online,s*([d,]+)smembers/) : null;
                const onlineUsers = match ? match[1] : 'Unknown';
    
       return { onlineUsers: onlineUsers };
       })();
       "

I then reference is as such:

Dim onlineUsers As String = "Unknown Online Users"

Me.Invoke(New Action(Sub()
                         Try

                             onlineUsers = result.onlineUsers
                         Catch ex As Exception

                             onlineUsers = "Unknown Online Users"

                         End Try

                         lblOnlineUsers.Text = onlineUsers

However, when I run it – it just says “Unknown”. The JS seems to work when I run it in the console, on a browser. Any idea why – I assume my vb.net code is wrong?

Node.js Sorting and Manipulation

I am not able to get all conditions right. I need to sort the object keys alphabetically. However, the sorting should be case-insensitive, and the original data structure should be preserved (e.g., arrays should remain arrays, objects should remain objects).

Two objects are considered duplicates if they have the same keys and values in the same order. Although JavaScript objects don’t inherently maintain key order, key order should be considered for this challenge (using something like a Set). Only the first occurrence should be preserved when an array contains duplicate objects.

Finally, remove any object properties with all values set to an empty string, null, or undefined, and console log an array of the modified objects as a string.

Example Input:

[{“name”:”John”,”age”:30,”city”:”New York”,”country”:”USA”,”Hobbies”:[“reading”,”swimming”,”hiking”,”swimming”],”occupation”:”programmer”,”favorite_foods”:{“Breakfast”:”pancakes”,”Lunch”:””,”dinner”:”pasta”,”Snack”:””},”gear”:{“type”:””,”material”:””,”color”:null},”affiliations”:[“”,””,””],”friends”:[{“name”:”Jane”,”age”:28,”city”:”New York”,”country”:”USA”,”occupation”:null},{“name”:”Tom”,”age”:32,”city”:”London”,”country”:”UK”,”occupation”:”teacher”},{“name”:”Jane”,”age”:28,”city”:”New York”,”country”:”USA”,”occupation”:null}]}]

Expected Output:

[{“age”:30,”city”:”New York”,”country”:”USA”,”favorite_foods”:{“Breakfast”:”pancakes”,”dinner”:”pasta”},”friends”:[{“age”:28,”city”:”New York”,”country”:”USA”,”name”:”Jane”},{“age”:32,”city”:”London”,”country”:”UK”,”name”:”Tom”,”occupation”:”teacher”}],”gear”:{},”Hobbies”:[“reading”,”swimming”,”hiking”],”name”:”John”,”occupation”:”programmer”}]

How to preload javascript chunks created after build in Nextjs?

The JS chunks created by webpack after build have a low priority and as result get downloaded late resulting in slowing down the website. I want these scripts to be loaded with high-priority, and I believe this can be done if these scripts are added with the preload attribute in the tag. I just can’t seem to figure out how to do this.

Please see the screenshots.

screenshot from the network tab of console in chrome

the link tags created by next

Detecting overflowing menu items doesn’t always calculate correctly

I’m trying to calculate if a horizontal menu has space for all menu items, and if not, wrap overflowing items inside a dropdown.

Here is what I have. It works – almost – because sometimes is doesn’t calculate correctly. Try resizing the window – you’ll see something like this:

enter image description here

const nav = document.querySelector(".navbar");
const contentBar = nav.querySelector(".navbar-nav");
const navItems = document.querySelectorAll(".navbar-nav > li:not(.grouped)");
const allItems = contentBar.querySelectorAll('li');
const dropdown = nav.querySelector(".grouped-content");
const more = nav.querySelector(".grouped");

const update = () => {
    // Show all items for exact calculation
    allItems.forEach((item) => {
        item.classList.remove('d-none');
    });

    let avaliableWidth = nav.offsetWidth;
    let stopWidth = more.offsetWidth;
    let subitems = [];
    dropdown.innerHTML = "";

    navItems.forEach((item, i) => {
        // Calculate if menu items are wider than navbar
        if (avaliableWidth > stopWidth + item.offsetWidth) {
            stopWidth += item.offsetWidth;
        } else {
            // Not enough space
            let li = document.createElement("li");
            li.innerHTML = item.innerHTML;
            // Append overflowing menu items to dropdown
            dropdown.appendChild(li);
            // Hide items that won't fit in menu
            item.classList.add('d-none');
            // Count items in dropdown
            subitems.push(i);
        }
    })

    // Hide "More" item if it has no children
    if (!subitems.length) {
        more.classList.add('d-none');
    } 
}

update();
window.addEventListener("resize", update);
.nav-link {
    white-space: nowrap;
    max-width: 100px;
    text-overflow: ellipsis;
    overflow: hidden;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
 <div class="container">
     <nav class="navbar navbar-expand-sm">
         <ul class="navbar-nav">
             <li class="nav-item"><a href="#" class="nav-link">Item 1</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 22</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 333</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 4444</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 5555555</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 66</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 7777777777777</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 8</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 999999</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 10101010</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 1111</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 12121212</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 131313131313</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 1414</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 15</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 16161616</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 1717</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 18181818181818</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 191919</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 20</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 212121</a></li>
                <li class="nav-item"><a href="#" class="nav-link">Item 2222</a></li>
                <li class="nav-item dropdown grouped">
                    <a href="#" class="nav-link dropdown-toggle" aria-haspopup="true" aria-expanded="false" role="button" data-bs-toggle="dropdown" data-bs-display="static" data-bs-auto-close="outside">More</a>
                    <ul class="grouped-content"></ul>
                </li>
            </ul>
        </nav>
    </div>
 <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>

What am I missing?
Thanks in advance.

Rollup says my const names are global, renames them with $1 suffix

I see this Q&A here, but that’s for an obvious global named Promise. I can find Promise in the MDN docs easily enough. But Rollup is renaming 4 of my consts that I don’t find anywhere in any docs:

  • C
  • E
  • Is
  • CFunc

Are these really JavaScript globals? Where can I find docs for them? I don’t want to rename them or wrap them in a namespace, but if there is a real conflict I’ll have to deal with it.