I have installed tailwindcss but it doesn`t work

Well, I instaled tailwindcss to my VSCode project via npm. I had some errors I and couldnt figure that out, so I created some files with my bare hands and after that, other files were created by themselfs (especialy one big 2000+ lines css file). So, now in theory it should work and give me some oportunities but it doesnt. I think that might be something related with import and files connections, so I watched some videos on youtube, took a look on some familiar questions here on overflow, but I can`t find the answer

I tried to install tailwindcss via npm, also wrote: "scripts": { "start": "npx tailwindcss -i ./input.css -o ./css/style.css --watch" },
to the package.json(and I have such error)
Error: Can’t resolve ‘tailwind/base’ in ‘C:UsersAsusOneDriveРабочий столwww’

Error from Express API: Unexpected token “Unexpected token ‘I’, “Infinite l”… is not valid JSON””

I am building a react next app with vercel hosting. In my application i created a Express API but now i need to deploy it. I decided to deploy it on vercel but i keep getting this error for my /vectorize api call!

{
    "error": "Error from Express API",
    "details": {
        "error": "Error from Express API",
        "details": {
            "error": "Error from Express API",
            "details": {
                "error": "Error from Express API",
                "details": {
                    "error": "Unexpected token 'I', "Infinite l"... is not valid JSON"
                }
            }
        }
    }
}

In my local host it works but i am only getting that error when i fetch with a public domain URL.

How to I keep two signals in sync (Service and Component)

I have this component, which is accepting a parameter as input.required ( say ID ).

I use this component in multiple places, with different IDs, I want to make sure the current input signal value get’s updated on the service so that my resource always fetches the proper data.

I know I can achieve this by just directly assigning the service signal, but as mentioned earlier, I have multiple inputs, the component must have an id provided (input.required), but my resource lies at the service level (Shared by this component and it’s children).

Above are the requirements of my scenario, below if my minimal reproducible code:

Service:

@Injectable({
  providedIn: 'root',
})
export class SomeService {
  http = inject(HttpClient);
  serviceIdSignal: WritableSignal<number> = signal(0); // <- I want to sync this at the component level.

  rxResource = rxResource({
    request: () => this.serviceIdSignal(),
    loader: ({ request: id }) => {
      return this.http.get(`https://jsonplaceholder.typicode.com/todos/${id}`);
    },
  });

  resource = resource({
    request: () => this.serviceIdSignal(),
    loader: ({ request: id, abortSignal }) => {
      return fetch(`https://jsonplaceholder.typicode.com/todos/${id}`, {
        signal: abortSignal,
      }).then((r) => r.json());
    },
  });
}

Child Component:

@Component({
  selector: 'app-child',
  template: `
    <div></div>
  `,
})
export class Child {
  someService = inject(SomeService);
  componentIdSignal: InputSignal<number> = input.required({
    alias: 'id',
  });
}

Root Component:

@Component({
  selector: 'app-root',
  imports: [Child, JsonPipe],
  template: `
    <app-child [id]="id()"/>
    <hr/>
    {{id()}}
    <hr/>
    @if(someService.rxResource.status() === rs.Resolved) {
      {{someService.rxResource.value() | json}}
    } @else {
      Loading...
    }
    <hr/>
    @if(someService.rxResource.status() === rs.Resolved) {
      {{someService.resource.value() | json}}
    } @else {
      Loading...
    }
  `,
})
export class App {
  rs = ResourceStatus;
  someService = inject(SomeService);
  id = signal(1);
}

Stackblitz Demo

Shortening an HTML file by referring to external HTML?

I’m pretty new to web development. I’m working on a senior project for school. It’s supposed to take me all semester to do. It’s like an independent project, and we’re allowed to use any and all sources available to us.

Anyway! My project is going to be a website that allows the user to build a custom banjo and give them an accurate price for it (I build banjos as a hobby).

So far I have a main HTML page where all the options will be displayed and a 3D Model is displayed as well. The goal is for the options to dynamically update the model and the price.

In order to keep my main HTML file as clean and short as possible, I would like to have several different forms for each part of the banjo in external HTML files. I would like form1.html to be shown in a details pane in the main HTML, and depending upon the options selected in form1.html, that will determine if form2A.html or form2B.html is shown in the next details pane. There’s more than just that, but that’s what I’m stuck on right now.

Eventually I’d like it to work so that when the user presses submit, it will pull the data from all the different forms. I just don’t know how to do any of it.

I’m confident I could figure it out fairly easily if I put them all in the one HTML file, but considering the number of options there may be, I feel that may make for a very long and messy HTML file.

JavaScript code doesn’t change style in HTML page

I’m new to webDev and to JavaScript. I’ll preface by saying that I tried to look for (a lot of) similar question but it was just people getting the grammar wrong.

I was annoyed at a particular page not making stuff selectable, so I tried making an extension that changes the ” user-select : “none” ” to ” user-select : “contain” ” (chrome).

my extension runs this

    const elements = document.querySelectorAll("*[style]");


elements.forEach((element) => {
  const userSelect = element.style.userSelect;
  const flex = element.style.flex;

  //select by style because Objects have no id there and classes change everytime you reload for some reasons.

  if (userSelect === "none" && flex === "1 1 0%") {
    console.log(element.className + "was changed, the complete style was" + 
    element.style);
    element.style.userSelect = "contain";
    element.style.setProperty('user-select', 'contain');
    console.log("new style is " + element.style.cssText);
    //tried both out of desperation, log is unchanged
  }
});

the console log keeps returning the correct element but when i press F12 the “user-select” attribute is unchanged, the script runs way after the page is loaded.

I even tried running this out of desperation

element.style.cssText = element.style.cssText.replace("user-select: none", "user-select: contain");
        console.log("after the replace it is " + element.style.cssText);

and the “user-select” attribute just disappears from the style.

If I change it manually to “user-select : contain” from the F12 window I can correctly select everything I want.

I’m new to this but completely lost. Also sorry for writing so much

How do I sign an HTTP request for https://api.x.com’s OAuth 1.0a flow?

When making my post request as seen below, I receive a status 401 error from the /oauth/request_token endpoint. I’m at the first step in a 3 step process for authenticating with https://api.x.com to enable a “Log in with X” button.

import crypto from 'crypto';
import axios from 'axios';
import { NextResponse } from 'next/server';

const X_CLIENT_ID = process.env.X_CLIENT_ID as string;
const X_CLIENT_SECRET = process.env.X_CLIENT_SECRET as string;
const X_CALLBACK_URL = process.env.X_CALLBACK_URL as string;

if (!X_CLIENT_ID || !X_CLIENT_SECRET || !X_CALLBACK_URL) {
  throw 'Missing env vars';
}

const BASE_URL = 'https://api.x.com/oauth/request_token';

export async function GET() {
  try {
    const params = createSignedRequestParams();
    const authorizationHeader = `Oauth oauth_callback="${params.oauth_callback}",oauth_consumer_key="${params.oauth_consumer_key}",oauth_nonce="${params.oauth_nonce}",oauth_signature="${params.oauth_signature}",oauth_signature_method="${params.oauth_signature_method}",oauth_timestamp="${params.oauth_timestamp}",oauth_version="${params.oauth_version}"`
    const response = await axios.post(BASE_URL, null, {
      headers: {
        'User-Agent': 'Cutcosts',
        'Host': 'api.x.com',
        'Accept': '*/*',
        'Authorization': authorizationHeader
      }
    });
    console.log(response);
    return NextResponse.json({ success: true })
  } catch (error: any) {
    console.log(JSON.stringify(error, null, 2));
    return NextResponse.json({ message: 'Internal server error' }, { status: 500 });
  }
}

function enc(str: string) {
  return encodeURIComponent(str);
}

function createSignedRequestParams() {
  // RFC 5849 Section 3.4.1
  // Encoding method is only necessary for custom methods
  const method = 'POST';

  // Params
  const params: Record<string, string> = {
    'oauth_callback': X_CALLBACK_URL,
    'oauth_consumer_key': X_CLIENT_ID, // "API Key" in X Developer Portal, per https://docs.x.com/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens#overview-of-the-process
    'oauth_nonce': Math.random().toString(36).substring(2) + Math.random().toString(36).substring(2),
    'oauth_signature_method': 'HMAC-SHA1',
    'oauth_timestamp': String(Math.floor(Date.now() / 1000)),
    'oauth_version': '1.0'
  };

  // Encode params
  const encodedParams: Record<string, string> = {};

  Object.keys(params).forEach((key) => {
    encodedParams[key] = enc(params[key]);
  });

  // Normalize encoded params
  const normalizedParams = Object.keys(encodedParams).sort().map(key => `${key}=${encodedParams[key]}`).join('&');

  // The example in RFC 5849 Section 3.4.1.1 shows one ampersand after POST, and one after base URL
  //   the rest of the ampersands and equal signs in params are encoded

  // Encode normalize params
  const encodedNormalizedParams = normalizedParams; // enc(normalizedParams);

  // Encode base url
  const encodedBaseUrl = enc(BASE_URL);

  // Construct base string
  // https://docs.x.com/resources/fundamentals/authentication/oauth-1-0a/creating-a-signature#creating-the-signature-base-string
  const baseString = method + '&' + encodedBaseUrl + '&' + enc(encodedNormalizedParams);
  console.log('Example:', 'POST&https%3A%2F%2Fapi.x.com%2F1.1%2Fstatuses%2Fupdate.json&include_entities%3Dtrue%26oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog%26oauth_nonce%3DkYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1318622958%26oauth_token%3D370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb%26oauth_version%3D1.0%26status%3DHello%2520Ladies%2520%252B%2520Gentlemen%252C%2520a%2520signed%2520OAuth%2520request%2521');
  console.log('Actual:', baseString);

  // Construct encoded signature
  // X_CLIENT_SECRET is "API Secret" in X Developer Portal, per https://docs.x.com/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens#overview-of-the-process
  const signingKey = enc(X_CLIENT_SECRET) + '&';
  const signature = crypto.createHmac('sha1', signingKey)
    .update(baseString)
    .digest('base64');
  const encodedSignature = enc(signature);

  // Update params to include encoded signature
  encodedParams.oauth_signature = encodedSignature;
  return encodedParams;
}

Troubleshooting attempts:

Tried encoding the entire string after “Oauth ” in the authorization header. (status 400)

Tried not encoding the signature after it is in base64 (status 400)

Tried putting the oauth_callback parameter in POST body rather than authorization header (status 401)

Tried not encoding the normalized params during signature creation (status 401)

Verified that callback URI in X developer portal matches callback URI in POST request

Verified that oauth_consumer_key value matches Client ID value from X developer portal

Verified that value used in POST request signing process matches Client Secret from X developer portal

Tried using “API Key” and “API Secret” for oauth_consumer_key and signing secret instead of Client ID and Client secret (Learned from docs[dot]x[dot]com/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens#overview-of-the-process that this is actually correct for OAuth 1.0a flow, however I still receive a status 401)

What else can I troubleshoot?

Do I have the signing steps correct? (createHMAC, update, digest)

SVG color change with javascript

I am working on an industrial flow HMI and I believe javascript is the only way I can easily achieve my goals w/o purchasing special SW. I need some help with color changes.

Here’s my example code; how do I make the “LightSwitch” and the “Lights” change color to RED? I am trying to change the class but not having any luck. Help is greatly appreciated!

<!DOCTYPE html>
<html>
    <head>
<script type="text/javascript">
    // 0=OPEN 1=CLOSE
    let Switchstate = 0

</script>
</head>
<body>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by Microsoft Visio, SVG Export Switch.svg Unit01 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
        xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="0.853639in" height="1.96174in"
        viewBox="0 0 61.462 141.245" xml:space="preserve" color-interpolation-filters="sRGB" class="st4">

    <style type="text/css">
    <![CDATA[
        .NOVOLTS {stroke:#0000ff;stroke-linecap:butt;stroke-width:2}
        .st2 {stroke:#0000ff;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}
        .st3 {stroke:#ff0000;stroke-linecap:butt;stroke-width:2}
        .V110 {stroke:#ff0000;stroke-linecap:butt;stroke-width:2}
        .st3 {stroke:#ff0000;stroke-linecap:butt;stroke-width:2}
        .st4 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
    ]]>
    </style>

    <g v:mID="76" v:index="1" v:groupContext="foregroundPage">
        <title>Wire</title>
        <v:pageProperties v:drawingScale="1" v:pageScale="1" v:drawingUnits="19" v:shadowOffsetX="9" v:shadowOffsetY="-9"/>
        <g id="Lights" v:mID="536" v:groupContext="shape" transform="translate(0,0) rotate(0)">
            <title>Lights</title>
            <v:userDefs>
                <v:ud v:nameU="visAltText" v:val="VT4(Lights)"/>
            </v:userDefs>
            <path d="M100 100 L100 200" class="NOVOLTS"/>
        </g>
        <g id="LightSwitch" v:mID="539" v:groupContext="shape" transform="translate(0.0, 0.0) rotate(0.0)">
            <title>LightSwitch</title>
            <path d="M100 100 L60 50" class="NOVOLTS"/>
        </g>
        <g id="SUPPLY" transform="translate(0.0, 0.0)" v:mID="540" v:groupContext="group">
            <g id="shape533-8" v:mID="533" v:groupContext="shape" transform="translate(0.0, 0.0)">
                <title>A</title>
                <path d="M95 50 L105 50" class="V110"/>
            </g>
            <g id="shape535-11" v:mID="535" v:groupContext="shape" transform="translate(0.0, 0.0) rotate(0.0)">
                <title>B</title>
                <path d="M100 10 L100 50" class="V110"/>
            </g>
        </g>
    </g>
</svg>
</body>


<script type="text/javascript">
function ToggleState() {
    var theSwitch = document.getElementById("LightSwitch")
if (Switchstate==0) {
    Switchstate = 1;
    console.log("Turn ON...");
    theSwitch.setAttribute("transform", "translate(0,0) rotate(0,100, 100)");
    theSwitch.className.baseVal = "V110";
} else {
    theSwitch.setAttribute("transform", "translate(0,0) rotate(39,100, 100)");
    Switchstate = 0;
    console.log("Turn OFF...");
    theSwitch.className.baseVal = "NOVOLTS";
}
}
    ///////////////////////////////////////////////////////////////////////
var pic_src=setInterval(ToggleState,2000);
</script>`enter code here`



</html>

How to properly minify a node package in vite when working on an extension

I am working on a wallet extension. I am bundling this package within my extension which has made the extension extremely slow like extremely slow. The problem is certain features such as transaction builder won’t work if I don’t bundle it.

"@bitgo/utxo-lib": "git+https://github.com/VerusCoin/BitGoJS.git#utxo-lib-verus",

I do have a dist folder of the above package and want to bundle it in a single JS file. However it has some imports and exports are in Common JS I suppose.

The following is my current vite config.

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import webExtension from '@samrum/vite-plugin-web-extension';
import { nodePolyfills } from 'vite-plugin-node-polyfills';
import path from 'path';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const srcDir = path.resolve(__dirname, 'src');

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    nodePolyfills({
      globals: {
        Buffer: true,
        global: true,
        process: true
      },
      protocolImports: true
    }),
    webExtension({
      manifest: {
        manifest_version: 3,
        name: 'Layer VOne (Testnet)',
        version: '0.0.4',
        description: 'Help me make the extension that brings native Layer 1 and Web 3 together on The Verus Blockchain',
        permissions: [
          'storage',
          'activeTab'
        ],
        host_permissions: [
          "http://localhost:5173/*",
          "http://localhost:3000/*"
        ],
        action: {
          default_popup: 'popup.html'
        },
        background: {
          service_worker: 'src/background.js',
          type: 'module'
        },
        content_scripts: [
          {
            matches: [
              "http://localhost:5173/*",
              "http://localhost:3000/*"
            ],
            js: ["src/contentScript.js"],
            run_at: "document_start"
          }
        ],
        web_accessible_resources: [{
          resources: ["provider.js"],
          matches: [
            "http://localhost:5173/*",
            "http://localhost:3000/*"
          ]
        }],
        content_security_policy: {
          extension_pages: "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'"
        },
      }
    })
  ],
  resolve: {
    alias: {
      '@': srcDir,
      'stream': 'stream-browserify',
      'crypto': 'crypto-browserify',
      'buffer': 'buffer',
      'bitcoin-ops/evals.json': path.resolve(__dirname, 'src/utils/bitcoin-ops-evals.json')
    }
  },
  build: {
    outDir: 'dist',
    emptyOutDir: true,
    sourcemap: process.env.NODE_ENV === 'development',
    minify: true,
    rollupOptions: {
      input: {
        popup: path.resolve(__dirname, 'popup.html'),
        provider: path.resolve(__dirname, 'src/provider.js')
      },
      output: {
        preserveModules: true,
        preserveModulesRoot: 'src',
        entryFileNames: (chunkInfo) => {
          if (chunkInfo.name === 'provider') {
            return '[name].js';
          }
          return 'assets/[name]-[hash].js';
        }
      },
      preserveEntrySignatures: 'strict',
    }
  }
});

What should I do I need suggestions. The following is my project.

https://github.com/iamahmedshahh/veruswebextension/tree/pub-fixes

React: Add an image in a top nav dropdown

I am new at React. I create a top-nav and data is fetched from MenuData.jsx.
There are 2 dropdowns from About and Resources.

I plan to show a list of dropdown on the left side and to add an image on the right side in a dropdown. What I try are: in MenuData.jsx, I add an image img: './assets/images/about-img.jpg' under About and img: './assets/images/resources.jpg' under Resources, then I create a component named DropPic and insert it to <div className="col-md-9">...</div>

But I face an issue: Not only an image related to a dropdown, but other images are show up in a dropdown!

How can I get only about-img.jpg shows in About dropdown and resources.jpg shows in Resources dropdown?

Please give me a hand and thanks in advance!

Here is my files in stackblitz: https://stackblitz.com/edit/react-gup8vgmg?file=src%2FMenuitems.jsx,src%2Fstyle.css,public%2Findex.html,src%2FDropdownPic.jsx,src%2FDropdown.jsx,src%2FMenuData.js

regex capturing incorrect

Simply put, I’m trying to replace certain tags with BBcode. What I have at the moment seems to grab the first <b> skips the following closing tag </b> and instead matches with the next one, leaving a closing tag inbetween them and keeping another one open.

I’m not sure how to fix the expression to capture the two groups of tags separately.

const test = `
 <zxlarge><b>Title and stuff
  - Yo</b></zxlarge>

<zimg>images/path/4137974393811117.png</zimg>



<zlarge><b>Preface.</b></zlarge>

<i>What if making excellent menu systems was as easy as a single command, and you also had access to the code?</i>
`;

let result = test.replace(/<b>([sS]*)</b>/gi, '[b]$1[/b]');

console.log(result);

Set logout link for react-oidc-context

I use this code to logout user:

const signOut: JwtAuthContextType['signOut'] = useCallback(() => {
        removeTokenStorageValue();
        removeGlobalHeaders(['Authorization']);
        setAuthState({
            authStatus: 'unauthenticated',
            isAuthenticated: false,
            user: null
        });
        auth.signoutRedirect();
    }, [removeTokenStorageValue]);

When I call it I’m redirected to http://host:8080/logout?id_token_hint=eyJraWQiOi.......

I need to set a custom logout url: http://host:8080/connect/logout?id_token_hint=eyJraWQiOi......

Do you know how I can configure this?

Can I prevent the Next router from pushing back in history without any effects?

I have a simple code preventing a page with a form from closing when the form filling is started but isn’t finished. Unfortunately, when a user tries to move to the previous page with the browser’s button (usually an arrow in the top-left corner of the browser’s window) the URL is changed regardless of user’s choise to left the page or to stay on the page.

const onRouteChangeStart = useCallback(() => {
    if (
        (checkConditions &&
        !window.confirm("Do you want to exit without saving changes?")
    ) {
        // Prevent navigation
        router.events.emit("routeChangeError");
        throw "Route change aborted.";
    }
}, [usedMetric, editedMetric, fullMetricState, router.events]);

useEffect(() => {
    router.events.on("routeChangeStart", onRouteChangeStart);
    return () => {
        router.events.off("routeChangeStart", onRouteChangeStart);
    };
}, [onRouteChangeStart, router.events]);

I tried to use router.push inside the onRouteChangeStart event handler to return the current page’s URL after the URL is changed. It worked but turned history into a mess because two changes of URL (to the previous page’s URL and then to the current page’s URL) were saved in the history.

Also I tried to change window.location inside onRouteChangeStart but as expected it was even worse thatn router.push because it triggered the handler infinitely.

Can i prevent going to the previous page (or the next page – it has the same problem) without any effects on history and URL?

function will not toggle

<div id="btn" onclick="toggletopmenu()"></div>
        
<script>
function toggletopmenu() 
  {
  var x = document.getElementById('header')
   ;
  if (x.style.backgroundImage !== "url('images/heading.png')")
    {
    x.style.backgroundImage = "url('images/headermenu.png')";    
    } 
  else 
    {
    x.style.backgroundImage = "url('images/heading.png')";
    }
  }
</script>

For some reson this switches the background once only, then the button does nothing. It acts like even though the url is correct for comparison, it cannot confirm that.

I cannot reset the select;

I’m facing a problem using Choices.js. I’m making an application with Razor Pages and I can’t clear the select selection

I just want to clear the select selection, returning it to its initial state

$('#destino').change(function() {
  var origem = "2" //$('#origem').val();
  var destino = $(this).val();
  if (origem && destino && origem === destino) {
  console.log(origem,destino)
  /* 
    Toast.fire({
      icon: "warning",
      title: "Os pontos de origem e destino devem ser diferentes."
    });
    */
    $('#destino').val("");
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/choices.js/1.1.6/choices.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/choices.js/1.1.6/styles/css/base.css" />


<div class="">
  <label class="form-label">Destino</label>
  <select class="form-select destino" id="destino" name="destino" data-choices="data-choices" size="1" data-options='{"removeItemButton":true,"searchResultLimit":100,"placeholder":true}' required>
    <option value="">Selecione uma opção</option>
    <option value="1">Parceiro 1</option>
    <option value="2">Parceiro 2</option>
    <option value="3">Parceiro 3</option>
    <option value="4">Parceiro 4</option>
    <option value="5">Parceiro 5</option>
  </select>
</div>

How to set cursor position on last child node of a contenteditable paragraph tag and the last child node is #text node

I want to set cursor position on the last child node of a paragraph contenteditable tag and the last child node is a #text node, hence the cursor position should be at the end of the text.

Given the paragraph node as below

<p contenteditable="true">
  Node 1
  <div>Node 2</div>
  Node 3
  <div>Node 4</div>
  Node 5
</p>

I want to be able to set the cursor position at the end of Node 5, in order to do so I did the following below.

//function to sum the length of the the #text node text content

function sumAllTextNodeLengthInTreeAsOffset(tree: HTMLElement, childNodeIndex?: number | undefined) {
  let sum = 0;
  for(let i=0; i<(tree as HTMLElement).childNodes.length; i++) {
    if(((tree as HTMLElement).childNodes[i] as HTMLElement).nodeType === 3) {
      sum+=(((tree as HTMLElement).childNodes[i] as HTMLElement).textContent as string).length;
      if(childNodeIndex !== undefined) {
        if(i === childNodeIndex) {
          break;
        }
      }
    }
  }
  return sum;
}

Then I am using the function below to set cursor position

function setCursorPositionInContenteditableElement(el: HTMLElement, pos: number) {
  const
    selectedText = window.getSelection(),
    selectedRange = document.createRange()
  ;
  if(el.childNodes[0]) {
    selectedRange.setStart(el.childNodes[0], pos);
  }
  else {
    el.innerText = ' ';
    selectedRange.setStart(el.childNodes[0], pos);
    const time = setTimeout(() => {
      el.innerText = '';
      clearTimeout(time);
    }, 0);
  }
  selectedRange.collapse(true);
  selectedText?.removeAllRanges();
  selectedText?.addRange(selectedRange);
  el.focus();
}

If The last child node is #text node then set cursor position to the end of the last child below always fails, instead of setting cursor position to last child it sets the cursor position on the first child.

if((tree as HTMLElement).hasChildNodes()) {
  if(
    (
      (tree as HTMLElement).childNodes[
        (tree as HTMLElement).childNodes.length - 1
      ] as HTMLElement
    ).nodeType === 3
  ) {
    setCursorPositionInContenteditableElement(
      (tree as HTMLElement),
      (tree as HTMLElement).children.length >= 1?
        ((tree as HTMLElement).childNodes.length - 1)
        :
        sumAllTextNodeLengthInTreeAsOffset(tree as HTMLElement)
    );
    (tree as HTMLElement).focus();
    (tree as HTMLElement).click();
  }
}

As shown in the images below enter image description here

I am trying to do the following

setCursorPositionInContenteditableElement(p, <index of the last child (which is a text node)>)

and the index of the last child from the image below is 10. instead of setting the cursor position at the end of <click here to continue new line> at node 10, the cursor is set at offset 10 of the first child of paragraph tag.

I have tried to sum all text node text content length up to the last child text content length to calculate the offset of the last child which is a text node, but setting the calculated offset causes error.

Please can someone help me on how to solve this problem.