Hide text if it overflow

Is there any efficient way to show/hide text in an element based on its width?
For example, there is an element with a dynamic width that can change and the text displayed in it. I want the text to be displayed only when the width of the element is wide enough to show it completely, and to hide when it overflowing the element (no line breaks, only one line)

I tried to write a react component that would display such text, but it works for me only for a static width, when changing, the text does not disappear/appear. Also, I don’t like the way it’s done here:

const AdaptiveText: React.FC<Props> = ({ text }) => {
    const textRef = useRef<HTMLDivElement>(null);
    const [isOverflowing, setIsOverflowing] = useState(false);

    useEffect(() => {
        const checkOverflow = () => {
            if (textRef.current) {

                setIsOverflowing(textRef.current.scrollWidth > textRef.current.clientWidth);
            }
        };
        checkOverflow();
        window.addEventListener("resize", checkOverflow);
        return () => {
            window.removeEventListener("resize", checkOverflow);
        };
    }, [text]);

    return (
        <div
            style={{
                width: "100%",
                whiteSpace: "nowrap",
                overflow: "hidden",
                textOverflow: "ellipsis",
                display: isOverflowing ? "none" : "block",
                position: "relative",
            }}
            ref={textRef}
            title={isOverflowing ? text : ""}
        >
            {text}
        </div>
    );
};

Cannot Focus Input Field When NextUI Drawer Sidebar is Open

I have a React application where I’m using the @nextui-org/react library to implement a sidebar using the Drawer component. Within my main content area, I have an input field. The issue is that when the sidebar is open, clicking on the input field doesn’t focus it. Instead of the input gaining focus, one of the items within the open sidebar’s navigation list becomes focused.

This prevents users from interacting with the input while the sidebar is visible. Removing the DrawerContent component from the Sidebar implementation resolves the issue, suggesting the problem lies within that component or its interaction with the Drawer. The presence of <span data-focus-scope-start="true" hidden="" aria-hidden="true"></span> within the Drawer when open makes me suspect it’s related to focus management.

I initially suspected the portalContainer prop was causing an issue with event handling, so I removed it, but the problem persisted. I also checked the z-index of the relevant elements using the browser’s developer tools to rule out any stacking order issues.

Through testing, I isolated the problem to the DrawerContent component. When the sidebar is open and I click the input, I expect the input field to receive focus, allowing the user to type. However, the actual result is that the input does not get focused, and instead, an item in the sidebar’s navigation receives the focus. I also noticed the <span data-focus-scope-start="true" ...> element and suspect it is involved in incorrectly managing focus.

LayoutPanel.js:

import React from "react";
import { Outlet, useLocation, useNavigate } from "react-router";
import Sidebar from "../components/Sidebar";
import {
  Button,
  Card,
  CardBody,
  CardHeader,
  Divider,
  useDisclosure,
} from "@nextui-org/react";
import { Icon } from "@iconify/react";
import { images } from "../utils/images";

const LayoutPanel = () => {
  const { isOpen, onOpen, onOpenChange } = useDisclosure();

  const navigate = useNavigate();
  const location = useLocation();

  return (
    <div>
      {/* <HeaderNavigation /> */}
      <div className="flex w-full">
        <Sidebar isOpen={isOpen} onOpenChange={onOpenChange} />
        <Card className="flex-1 m-3 min-h-[calc(100vh-24px)]">
          <CardHeader className="h-[76px]">
            <div className="flex items-center gap-2">
              {!isOpen && (
                <Button isIconOnly variant="light" onPress={onOpenChange}>
                  <Icon icon="solar:siderbar-outline" width={24} />
                </Button>
              )}
              <img
                src={images.logo}
                alt="logo"
                className="object-contain h-6 dark:invert"
              />
            </div>
          </CardHeader>
          <Divider />
          <CardBody className="container mx-auto max-w-7xl text-start">
            <Outlet />
          </CardBody>
        </Card>
      </div>
      {/* <Footer /> */}
    </div>
  );
};

export default LayoutPanel;

Sidebar.js:

import React from "react";
import {
  Drawer,
  DrawerContent,
  DrawerHeader,
  DrawerBody,
  Listbox,
  ListboxItem,
  Accordion,
  Button,
  AccordionItem,
  cn,
  Divider,
} from "@nextui-org/react";
import sidebarNavigation from "../utils/sidebarNavigation";
import { Icon } from "@iconify/react";

const Sidebar = ({ isOpen, onOpenChange }) => {
  return (
    <div
      id="sidebar"
      className={cn(
        "transition-all absolute md:relative duration-300 ease-in-out overflow-hidden",
        isOpen ? "w-[336px]" : "w-0"
      )}
    >
      <Drawer
        isDismissable={false}
        hideCloseButton
        isKeyboardDismissDisabled={false}
        portalContainer={document.getElementById("sidebar") || undefined}
        backdrop={window.innerWidth < 768 && isOpen ? "blur" : "transparent"}
        classNames={{
          wrapper: "!items-stretch w-auto relative",
          base: "data-[placement=right]:sm:my-3 data-[placement=left]:sm:my-3 rounded-e-large rounded-s-none",
          body: "pe-0",
          header: "p-[calc(1rem+2px)] ",
        }}
        shouldBlockScroll
        isOpen={isOpen}
        onOpenChange={onOpenChange}
      >
        <DrawerContent>
          <DrawerHeader className="flex justify-between gap-3 ">
            <h3>منو</h3>
            <Button isIconOnly variant="light" onPress={onOpenChange}>
              <Icon icon="solar:siderbar-outline" width={24} />
            </Button>
          </DrawerHeader>
          <Divider />
          <DrawerBody>
            <Listbox
              variant="flat"
              className="overflow-y-auto pe-3 ps-0"
            >
              {sidebarNavigation.map((menuItem) =>
                menuItem.subItems ? (
                  <ListboxItem key={menuItem.title}>
                    <Accordion showDivider={false} className="space-y-3">
                      <AccordionItem
                        key={menuItem.title}
                        aria-label={menuItem.title}
                        startContent={
                          <div
                            className={`flex items-center rounded-small justify-center ${menuItem.color} w-9 h-9`}
                          >
                            <img
                              src={menuItem.icon}
                              className="object-contain invert"
                              width={24}
                              alt={menuItem.title}
                            />
                          </div>
                        }
                        subtitle={menuItem.subtitle}
                        classNames={{
                          trigger: "p-0",
                          content: "py-0 ps-3",
                        }}
                        title={menuItem.title}
                      >
                        <Listbox
                          variant="flat"
                          aria-label={`زیرمنو ${menuItem.title}`}
                          classNames={{
                            list: cn("border-s border-default-200 ps-4"),
                          }}
                        >
                          {menuItem.subItems.map((subItem) => (
                            <ListboxItem
                              key={subItem.title}
                              textValue={subItem.title}
                              href={subItem.path}
                              startContent={
                                <div
                                  className={`flex items-center rounded-small justify-center ${menuItem.color} w-7 h-7`}
                                >
                                  <img
                                    src={subItem.icon}
                                    width={20}
                                    className="object-contain"
                                    alt={subItem.title}
                                  />
                                </div>
                              }
                            >
                              <span>{subItem.title}</span>
                            </ListboxItem>
                          ))}
                        </Listbox>
                      </AccordionItem>
                    </Accordion>
                  </ListboxItem>
                ) : (
                  <ListboxItem
                    title={menuItem.title}
                    description={menuItem.subtitle}
                    classNames={{
                      base: "gap-3",
                    }}
                    startContent={
                      <div className="ms-2">
                        <div
                          className={`flex items-center rounded-small justify-center ${menuItem.color} w-9 h-9`}
                        >
                          <img
                            src={menuItem.icon}
                            width={20}
                            className="invert"
                            alt={menuItem.title}
                          />
                        </div>
                      </div>
                    }
                  >
                    {menuItem.title}
                  </ListboxItem>
                )
              )}
            </Listbox>
          </DrawerBody>
        </DrawerContent>
      </Drawer>
    </div>
  );
};

export default Sidebar;

FormFastGroup.js:

import { Controller, useForm } from "react-hook-form";
import { Button, Form, Input } from "@nextui-org/react";

const FormFastGroup = () => {
  const { handleSubmit, control } = useForm();

  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <Form
      className="w-full max-w-xs flex flex-col gap-4"
      onSubmit={handleSubmit(onSubmit)}
    >
      <Controller
        control={control}
        name="name"
        render={({
          field: { name, value, onChange, onBlur, ref },
          fieldState: { invalid, error },
        }) => (
          <Input
            ref={ref}
            isRequired
            errorMessage={error?.message}
            // Let React Hook Form handle validation instead of the browser.
            validationBehavior="aria"
            isInvalid={invalid}
            label="Name"
            name={name}
            value={value}
            onBlur={onBlur}
            onChange={onChange}
          />
        )}
        rules={{ required: "Name is required." }}
      />
      <Button type="submit">Submit</Button>
    </Form>
  );
};

export default FormFastGroup;

FastGroup.js:

import React from "react";
import FormFastGroup from "../components/FormFastGroup";

const FastGroup = () => {
  return (
    <div className="flex flex-col gap-4">
      <h3 className="font-bold text-xl">ارسال سریع و گروهی</h3>
      <div>
        <FormFastGroup />
      </div>
    </div>
  );
};

export default FastGroup;

Highcharts – Stacked Column chart bars overlapping when range of min and max is large

using the column chart with stacking on,

If I have a big disparity between min and max value in the series the low values are getting overlapped, is there a workaround to this?

See the Jan category in this fiddle for reproduction – both bars have a value but only one of them is visible in the chart, hovering over legend shows that they are overlapping. This only occurs when the max value in the series is multiple times larger than the min value, setting minimum size for the bar did not help either, they still overlap.

    Highcharts.chart('container', {
    chart: {
        type: 'column'
    },
    xAxis: {
        categories: [
            'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
            'Oct', 'Nov', 'Dec'
        ]
    },

    plotOptions: {
        series: {
            stacking: 'normal'
        },
        column: {
            minPointLength: 3
        }
    },

    series: [{
        data: [
            27, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1,
            95.6, 5400.4
        ]
    }, {
        data: [
            25, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4, 29.9, 71.5,
            106.4, 129.2
        ]
    }],

    tooltip: {
        pointFormat: '{series.name}: <b>{point.y}</b> ' +
            '({point.percentage:.1f}%)<br/>'
    }
});

Fiddle: https://jsfiddle.net/onbx4pre/1/

Trying to get all user ids from firestore database, so I can access the ratings and combine them,

import React, { useEffect, useState } from "react";
import { db } from "./firebase/Firebase";
import { collection, getDocs } from "firebase/firestore";
import { useAuth } from "./AuthContext";

const Ratings = () => {
  const { currentUser } = useAuth(); // Get the currently logged-in user
  const [userRatings, setUserRatings] = useState([]);
  const [userUIDs, setUserUIDs] = useState([]); // State for all user UIDs
  const [loadingRatings, setLoadingRatings] = useState(true); // Loading state for user ratings
  const [loadingUIDs, setLoadingUIDs] = useState(true); // Loading state for user UIDs

  useEffect(() => {
    const fetchUserRatings = async () => {
      if (!currentUser) {
        console.error("No user is logged in.");
        setLoadingRatings(false);
        return;
      }

      try {
        console.log("Fetching ratings for the logged-in user...");
        const userRatingsCollection = collection(
          db,
          "users",
          currentUser.uid,
          "ratings"
        );
        const ratingsSnapshot = await getDocs(userRatingsCollection);

        const ratings = ratingsSnapshot.docs.map((doc) => ({
          id: doc.id,
          ...doc.data(),
        }));

        console.log("Fetched User Ratings:", ratings);
        setUserRatings(ratings);
      } catch (error) {
        console.error("Error fetching user ratings:", error);
      } finally {
        setLoadingRatings(false);
      }
    };

    const fetchAllUserUIDs = async () => {
      try {
        console.log("Fetching all user UIDs...");
        const usersCollection = collection(db, "users"); // Accessing the users collection
        const usersSnapshot = await getDocs(usersCollection); // Fetching all documents

        const uids = usersSnapshot.docs.map((doc) => doc.id); // Extracting the document IDs (user IDs)
        console.log("Fetched User UIDs:", uids);
        setUserUIDs(uids);
      } catch (error) {
        console.error("Error fetching user UIDs:", error);
      } finally {
        setLoadingUIDs(false);
      }
    };

    fetchUserRatings();
    fetchAllUserUIDs();
  }, [currentUser]);

  return (
    <div className="container mx-auto p-4">
      <h2 className="text-2xl font-bold mb-4">Your Ratings</h2>
      {loadingRatings ? (
        <p>Loading your ratings...</p>
      ) : userRatings.length > 0 ? (
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
          {userRatings.map((rating) => (
            <div
              key={rating.id}
              className="border rounded-lg p-4 shadow hover:shadow-lg transition"
            >
              <h3 className="text-lg font-semibold">{rating.itemTitle}</h3>
              <p className="text-gray-700">Rating: {rating.rating}</p>
            </div>
          ))}
        </div>
      ) : (
        <p>No ratings found for your account.</p>
      )}

      <h2 className="text-2xl font-bold mt-8">All User UIDs</h2>
      {loadingUIDs ? (
        <p>Loading user UIDs...</p>
      ) : userUIDs.length > 0 ? (
        <ul className="list-disc pl-6">
          {userUIDs.map((uid) => (
            <li key={uid} className="text-gray-700">
              {uid}
            </li>
          ))}
        </ul>
      ) : (
        <p>No users found.</p>
      )}
    </div>
  );
};

export default Ratings;

This shows the ratings for the items for the logged in user, but when I try to get user ids from all the registered users from firebase database, I get No users found. This is how the pathing is /users/mu2CXMasv4eBb4qxLYhs8mnKPty2/ratings/1

How the database looks like pt 1
How the database looks like pt 2

So how can I get all the user ids or combine all the ratings?

I tried aggregating and averaging ratings across multiple users in Firestore, querying /users/{userId}/ratings subcollections for community ratings.

Why am I getting Invalid Date when trying to display days?

This is a React component using React Date Picker:

import { useState, useRef, useLayoutEffect } from 'react';
import { DayPicker } from 'react-day-picker';
import { PseudoInput } from '@/components/PseudoInput';
import { Col } from '@/components/Col';
import { cn } from '@/utils';

export type DatePickerProps = {
  label?: string;
  value?: Date;
  onChange: (value: Date) => void;
  placeholder?: string;
  error?: string;
  className?: string;
  required?: boolean;
  disabled?: boolean;
  small?: boolean;
};

export const DatePicker = ({
  label,
  value,
  onChange,
  placeholder = 'Select a date',
  error,
  className,
  required,
  disabled,
  small = false,
}: DatePickerProps) => {
  const [isOpen, setIsOpen] = useState(false);
  const [dropdownPosition, setDropdownPosition] = useState<'top' | 'bottom'>(
    'bottom',
  );

  const dropdownRef = useRef<HTMLDivElement | null>(null);
  const triggerRef = useRef<HTMLDivElement | null>(null);

  // Adjust dropdown position based on available space
  const adjustDropdownPosition = () => {
    if (triggerRef.current && dropdownRef.current) {
      const triggerRect = triggerRef.current.getBoundingClientRect();
      const dropdownHeight = dropdownRef.current.scrollHeight;
      const viewportHeight = window.innerHeight;

      const shouldFlip = triggerRect.bottom + dropdownHeight > viewportHeight;
      setDropdownPosition(shouldFlip ? 'top' : 'bottom');
    }
  };

  useLayoutEffect(() => {
    if (isOpen) {
      adjustDropdownPosition();
      const handleResize = () => adjustDropdownPosition();
      window.addEventListener('resize', handleResize);
      return () => {
        window.removeEventListener('resize', handleResize);
      };
    }
  }, [isOpen]);

  // Close dropdown if user clicks outside
  useLayoutEffect(() => {
    const handleOutsideClick = (event: MouseEvent) => {
      if (
        dropdownRef.current &&
        !dropdownRef.current.contains(event.target as Node) &&
        triggerRef.current &&
        !triggerRef.current.contains(event.target as Node)
      ) {
        setIsOpen(false);
      }
    };
    document.addEventListener('mousedown', handleOutsideClick);
    return () => {
      document.removeEventListener('mousedown', handleOutsideClick);
    };
  }, []);

  return (
    <Col className={cn('relative', className)}>
      {/* Render label */}
      {label && (
        <label className="text-sm font-semibold">
          {label} {required && <span className="text-danger"> *</span>}
        </label>
      )}

      {/* PseudoInput for toggling calendar */}
      <div
        ref={triggerRef}
        className="relative w-full"
        onClick={() => !disabled && setIsOpen((prev) => !prev)}
        tabIndex={0}
      >
        <PseudoInput
          tabIndex={0}
          error={error}
          disabled={disabled}
          className={cn(
            'cursor-pointer justify-between shadow',
            {
              'focus-visible:ring-0 focus-visible:ring-offset-0': isOpen,
              'hover:shadow-dark': !disabled,
              'h-6 px-2 py-1 text-xs': small,
            },
            className,
          )}
        >
          <div className="flex items-center gap-2">
            <span>{value ? value.toLocaleDateString() : placeholder}</span>
          </div>
        </PseudoInput>

        {/* Dropdown with DayPicker */}
        {isOpen && (
          <div
            ref={dropdownRef}
            className={cn(
              'absolute z-10 mt-1 rounded border border-border bg-white shadow',
              dropdownPosition === 'top' ? 'bottom-full mb-1' : 'top-full mt-1',
              'w-full',
            )}
          >
            <DayPicker
              mode="single"
              selected={value}
              onSelect={(date) => {
                if (date) {
                  onChange(date);
                  setIsOpen(false);
                }
              }}
              className="rounded-md border shadow"
              components={{
                DayButton: ({ day, modifiers, ...props }) => (
                  <button
                    {...props}
                    className={cn(
                      'rounded p-1',
                      modifiers.selected
                        ? 'bg-blue-500 text-white'
                        : 'hover:bg-gray-200',
                    )}
                  >
                    {day instanceof Date ? day.getDate() : 'Invalid Date'}
                  </button>
                ),
              }}
            />
          </div>
        )}
      </div>

      {/* Error message */}
      {error && <span className="text-sm text-danger">{error}</span>}
    </Col>
  );
};

Everything works well. I can even choose the correct date. The only issue is that all the days display as Invalid Date:

enter image description here

Why is this and how to fix it?

Vue3 Pinia State Management

When using Pinia in your ViewModel, are you allowed to combine the viewmodel’s methods along with the pinia actions when using Pinia’s mapActions and mapState wrappers? or do all methods and computed methods have to remain in the pinia store and then be referenced in the viewModel?

    computed: {
        ...mapState(useFilterStore, ['selectedItem', 'selectedOrderBy', 'selectedPageSize', 'toggle', 'toggleAdvFilter', 'view']),
        ...mapState(useCalendarStore, ['getCalendarByUser']),
        setting() { return Base.currentUser.CalendarSetting },
    },
    methods: {
        ...mapActions(useCartStore, ['addToCart']),
        
        async SendRequest(form) { await new UserService().SendCalendarRequest(form); },
    

I’ve tried commenting out each mapState/mapAction and vice versa with the viewModel methods

This code changes the style of a targeted element in the console debug but does not change it in the DOM

`let html
function display(array){
    tasksList.innerHTML = ''
    html = ''
    array.forEach(elm=>{

        html += `<li>

        <span id="${elm.id}" class="${elm.class}">${elm.title}</span>

        <p >${elm.desc}</p>
                <div>
                <button id="${elm.id}" class="done-task">Done</button>
                <button id="${elm.id}" class="delete-task">Delete</button>
                <button id="${elm.id}" class="edit-task">Edit</button>
                </div>
            </li>`

            tasksList.innerHTML = html
    })
}

tasksList.addEventListener('click', (e)=>{

    if(e.target.tagName == 'SPAN'){
        console.log(e.target.nextElementSibling.tagName)

            e.target.nextElementSibling.classList.toggle('desc')
            e.target.style.color = 'red'

    console.log('Changed color to red for', e.target.nextElementSibling);
    }
})

this is the only css related to that part:

  #tasks-list li span{
           cursor: pointer;
        }
        /* #tasks-list li p{
            display: none;
        } */

        .desc{
            display: none;
        }`

in the console it states that the nextElementSibling is actually adding the class and the style but in the same time in the DOM it doesn’t.

I have tried adding the class manually to the

and it did hide the element.
I tried console logging the targetElement and to console log its sibling and indeed they both return to be the span and the p.

Is this StockfishWorker implementation for evaluating chess moves functional and efficient?

I’m working on a chess analysis tool that uses a StockfishWorker class to evaluate moves and provide engine suggestions. The code is designed to interface with a web worker running Stockfish, handle communication, and process multi-PV lines.

Here’s the complete code for the class:

import type { EngineLine, Evaluation, Lan } from '../types/Game';
import type GameReviewManager from './_GameReviewManager';
import { getCloudEvaluation } from '../api/lichessApiAccess';

class StockfishWorker {
  private workerUrl: URL;
  private stockfishWorker: Worker;
  private verbose: boolean;
  private multipv: number;
  private targetDepth: number;
  readonly game_review_manager: GameReviewManager;

  private waitFor(response: string, errormsg = 'error') {
    return new Promise((resolve, reject) => {
      const listener = <K extends keyof WorkerEventMap>(
        e: WorkerEventMap[K],
      ) => {
        if (this.verbose) console.debug(e);
        if (e instanceof MessageEvent && e.data.includes(response)) {
          this.stockfishWorker.removeEventListener('message', listener);
          resolve(true);
        }
      };
      this.stockfishWorker.addEventListener('message', listener);
      // Add a timeout for error handling (optional)
      setTimeout(() => {
        this.stockfishWorker.removeEventListener('message', listener);
        reject(`delay time exceeded: ${errormsg}`);
      }, 5000);
    });
  }

  _init(restart = false) {
    return new Promise(async (resolve) => {
      this.stockfishWorker.onmessageerror = (e) => console.debug(e);
      if (!restart) {
        this.stockfishWorker.postMessage('uci');
        await this.waitFor('uciok', 'uci setup error');
      } else console.debug('Restarting engine...');
      this.stockfishWorker.postMessage(`ucinewgame`);
      this.stockfishWorker.postMessage('isready');
      this.stockfishWorker.postMessage(
        `setoption name MultiPV value ${this.multipv}`,
      );
      this.waitFor('readyok', 'this.stockfishWorker not ready after timeout')
        .then(() => {
          resolve(true);
        })
        .catch((err) => {
          throw new Error(err);
        });
    });
  }

  evaluateMove(fen: string = 'startpos'): Promise<EngineLine[]> {
    console.log('evaluate move');
    !fen || fen == 'startpos'
      ? this.stockfishWorker.postMessage(`position startpos`)
      : this.stockfishWorker.postMessage(`position fen ${fen}`);
    this.stockfishWorker.postMessage(`go depth ${this.targetDepth}`);

    let messages = [];
    let lines: EngineLine[] = [];
    return new Promise((resolve, reject) => {
      const listener = <K extends keyof WorkerEventMap>(
        e: WorkerEventMap[K],
      ) => {
        if (e instanceof MessageEvent) {
          messages.unshift(e.data);
          if (e.data.includes('depth 0')) {
            if (this.verbose) console.warn(`${e}`);
          }
          if (e.data.startsWith('bestmove') || e.data.includes('depth 0')) {
            this.stockfishWorker.removeEventListener('message', listener);
            let searchMessages = messages.filter((msg) =>
              msg.startsWith('info depth'),
            );
            for (let searchMessage of searchMessages) {
              // Extract depth, MultiPV line ID and evaluation from search message
              let idString = searchMessage.match(/(?:multipv )(d+)/)?.[1];
              let depthString = searchMessage.match(/(?:depth )(d+)/)?.[1];

              let bestMove: Lan =
                searchMessage.match(/(?: pv )(.+?)(?= |$)/)?.[1];

              let evaluation: Evaluation = {
                type: searchMessage.includes(' cp ') ? 'cp' : 'mate',
                value: parseInt(
                  searchMessage.match(/(?:(?:cp )|(?:mate ))([d-]+)/)?.[1] ||
                    '0',
                ),
              };
              // Invert evaluation if black to play since scores are from black perspective
              // and we want them always from the perspective of white
              if (fen && fen.includes(' b ')) {
                evaluation.value *= -1;
              }
              // If any piece of data from message is missing, discard message
              if (!idString || !depthString || !bestMove) {
                lines.push(
                  {
                    id: parseInt(idString),
                    depth: parseInt(depthString),
                    evaluation: { type: 'mate', value: 0 },
                    bestMove: 'a1a1',
                  },
                  {
                    id: parseInt(idString),
                    depth: parseInt(depthString),
                    evaluation: { type: 'mate', value: 0 },
                    bestMove: 'a1a1',
                  },
                );
                resolve(lines);
                return;
              }

              let id = parseInt(idString);
              let depth = parseInt(depthString);

              // Discard if target depth not reached or lineID already present
              if (
                depth != this.targetDepth ||
                lines.some((line) => line.id == id)
              )
                continue;

              lines.push({
                id,
                depth,
                evaluation,
                bestMove,
              });
            }
            clearTimeout(timeoutId); // Clear the timeout if message is received
            console.debug(lines);
            console.debug('cleared time out id');
            resolve(lines);
          }
        }
      };
      this.stockfishWorker.addEventListener('message', listener);
      const timeoutId = setTimeout(() => {
        this.stockfishWorker.removeEventListener('message', listener);
        reject(new Error('takes alot of time'));
      }, 20000); // Adjust timeout as needed
    });
  }

  private restartWorker(
    ui_update_callback: () => void,
    move: {
      current_fen: string;
      move_num: number;
      sanmove: string;
    },
  ) {
    console.log('restarting worker....');
    this.stockfishWorker.terminate();
    this.stockfishWorker = new Worker(this.workerUrl, { type: 'classic' });
    this._init().then(() => {
      this.evaluateStuckMove(ui_update_callback, move).then((res) => {
        if (res.success) {
          console.warn('continue with work');
          this.evaluatePosition(ui_update_callback);
        } else {
          console.error('restarting worker again');
          this.restartWorker(ui_update_callback, move);
        }
      });
    });
  }

  private async evaluateStuckMove(
    ui_update_callback: () => void,
    move: {
      current_fen: string;
      move_num: number;
      sanmove: string;
    },
  ) {
    try {
      console.debug('evaluating halt move', move);
      const engineLines = await this.evaluateMove(move.current_fen);
      ui_update_callback();
      this.game_review_manager.add_enginelines(engineLines, move.move_num);
      return { success: true };
    } catch (error) {
      return { success: false };
    }
  }

  async evaluatePosition(ui_update_callback: () => void) {
    console.log('evaluating position');
    while (!this.game_review_manager.done_evaluating()) {
      const currentMove = this.game_review_manager.get_next_move();
      const { current_fen, move_num } = currentMove;
      console.debug({ currentMove });
      try {
        const engineLines = await this.evaluateMove(current_fen);
        const cloud_eval = await getCloudEvaluation(current_fen);
        console.warn({ cloud_eval });
        console.debug({ engineLines });
        ui_update_callback();
        this.game_review_manager.add_enginelines(engineLines, move_num);
      } catch (error) {
        console.error('error');
        console.error('restarting');
        this.restartWorker(ui_update_callback, currentMove);
      }
    }
    console.log('terminate_worker');
    this.stockfishWorker.terminate();
    return { success: true };
  }

  /**
   * @param startingpos : fen format
   * @param multipv : number of lines to return
   * @param verbose : testing
   */
  constructor(
    game_review_manager: GameReviewManager,
    multipv = 2,
    targetDepth = 15,
    verbose = false,
  ) {
    var wasmSupported =
      typeof WebAssembly === 'object' &&
      WebAssembly.validate(
        Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00),
      );

    this.workerUrl = wasmSupported
      ? new URL('./stockfish/stockfish.js', import.meta.url)
      : new URL('./stockfish/stockfish.wasm.js', import.meta.url);
    this.stockfishWorker = new Worker(this.workerUrl, { type: 'classic' });
    this.multipv = multipv;
    //this.evaluateMove = this.evaluateMove.bind(this);
    this.targetDepth = targetDepth;
    this.verbose = verbose;
    //this.waitFor = this.waitFor.bind(this);
    this.game_review_manager = game_review_manager;
  }
}
export default StockfishWorker;

Features:
Initialization: The _init method sets up the Stockfish engine and waits for it to be ready.
Move Evaluation: evaluateMove sends FEN positions to the engine and collects depth-based evaluations.
Timeout Handling: There are multiple timeout mechanisms to ensure the process doesn’t hang.
Worker Restarts: restartWorker attempts to recover the worker if it becomes unresponsive.
Cloud Integration: It also integrates with a cloud evaluation API for additional analysis.
problems:
the engine keeps halting and restarting, and the engine sometimes returns an empty result as the eval even if I know it exists one
when I increase the multiple the failing rises a lot to the point of it not working

My Concerns:
Timeouts and Asynchronous Handling: Are the timeout and retry mechanisms implemented correctly to ensure robust communication with the worker?
Message Filtering: Is the filtering and processing of engine output (info depth, bestmove, etc.) reliable for real-time chess analysis?
Redundancy: Certain parts, like pushing fallback lines with placeholder values (a1a1 moves), seem redundant. Should this be optimized?
Worker Performance: Does terminating and restarting the worker frequently affect performance, and is there a better way to handle “stuck” evaluations?

Input type file retrieval/access question

Can someone tell me why the first code snippet works and the second does not? I am able to get filelist in the first snippet but its empty in the second one?

Works:

<label class="bi bi-paperclip" title="click to attach files">
    <input type="file" id="uploadFile" style="display: none;" multiple>
</label>

$(document).on('change', '#uploadFile', function () {
    const fileInput1 = $(this)[0];
    const files1 = fileInput1.files;
    console.log("**this[0]**");
    console.log(files1);
});

Does not work, always empty:

<label class="bi bi-paperclip" title="click to attach files">
    <input type="file" id="uploadFile" style="display: none;" multiple>
</label>

$(document).on('change', '#uploadFile', function () {
    const fileInput = document.getElementById('uploadFile');
    const files = fileInput.files;
    console.log("**document.getElementById**");
    console.log(files);
});

console

Is V8 Ignition “Interpreter” capable of producing byte code only because it was built on top of TurboFan Compiler?

The V8 Engine contains both Ignition “Interpreter” (which is an interesting name for something that not only interprets) and TurboFan Compiler. TurboFan compiler helps to optimize “hot” parts of code by compiling it into machine code.

However, when it comes to Ignition Interpreter. It can produce byte code and then execute it. To create the byte code, however, it needs to “compile/transform” the AST (Abstract Syntax Tree). Is Ignition’s ability to do it (create the byte code) possible only because it was built on TurboFan which itself can “compile” code?

Hover button with javascript

I’m trying to make a hover-able button with javascript. It works but the onmouseout function hide the div to soon. Not sure what I’m doing wrong here.
I know you can use CSS to this but i would like to use javascript

function show() {
  let div = document.getElementById("cloth");
  div.setAttribute("style", "display:block; border:1px solid black;");
}

function hide() {
  let div = document.getElementById("cloth");
  div.setAttribute("style", "display:none;");
}
.dropA {
  display: block;
}

.cloths {
  display: none;
}
<div>
  <button id="menu" class="dropA"  onmouseover="show()">
    Menu
  </button>
  <div id="cloth"   class="cloths" onmouseout="hide()">
    <p>Dresses</p>
    <p>Shirts</p>
    <p>Pants</p>
  </div>
</div>

weird answers to uninitialized variables/properties in javascript [duplicate]

Case 1:

The below snippet throws a reference error because let variables are hoisted but not initialized.

console.log(x); 
let x = 5;

Case 2:

const arr = [1, 2];
arr.length = 10;
console.log(arr[5])

prints undefined instead of throwing a reference error despite being uninitialized. Why?

As we increase the length of the arr object, empty slots get created. Note that these empty slots do not mean they are initialized as undefined. they are uninitialized as well.

My question is why doesn’t it throw an error in the second case?

Is JavaScript code executed now by CPU instead of Interpreter?

Before the Sparkplug compiler, JS code was first converted into byte code and executed, all done by the Ignition Interpreter. The Sparkplug compiler nowadays will take the byte code generated by Ignition Interpreter and turn it into machine code. Great. What executes code, though?

Does the Ignition Interpreter still execute it or maybe the CPU executes it now (machine code generated by Sparkplug)?

EDIT: There is also another JIT compiler called Maglev. So it adds even more confusion now

Mix-Blend-Mode Overlay – prevent images in lower stacking context to be effected

This might be a pretty specific question.
I have this running text marquee animation. On hover the animation pauses and shows a gradient as “text color”. The mouse is being tracked to pin the black gradient center to the mouse movement.

Goal:
The gradient on the text should span across the whole width. Images inside of the text should not be effected. The center of the gradient should always be the black color. The gradient should ideally be on the level of .marquee (wrapper) to not be effected by the animation. (.marqueeConetent is being animated)

Challenge:
Different stacking contexts are created therefore it is hard to place the images above a gradient overlay. Because of the text animation the content gets duplicated and replaced at some point -> leads to anomalies with the gradient not hitting every text block.

What I tried:

mix-blend-mode overlay approach – hard to overcome different stacking contexts therefore the images are always effected.

background-clip text approach – either the gradient center changes or the effect is applied to each text block individually.

Is there any way to achieve what I am looking for? Is there any way to prevent images in a lower stacking context to be effected by an overlay with mix-blend-mode in a higher stacking context?

const marquees = document.querySelectorAll(".marquee");

// If recuded motion isn't activated we add the animation
if (!window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
  addMarqueeAnimation();
}

function addMarqueeAnimation() {
  marquees.forEach((marquee) => {
    // add data-animated="true" to every `.marquee` on the page
    marquee.setAttribute("data-animated", true);

    // Make an array from the elements within .marquee
    const scrollerContent = Array.from(marquee.children);

    // For each item in the array, clone it
    // add aria-hidden to it
    // add it into the .marquee
    scrollerContent.forEach((item) => {
      const duplicatedItem = item.cloneNode(true);
      duplicatedItem.setAttribute("aria-hidden", true);
      marquee.appendChild(duplicatedItem);
    });
  });
}

//track mouse for gradient hover
const button = document.querySelectorAll(".marquee");

for (let i = 0; i < button.length; i++) {
  button[i].addEventListener("mousemove", (e) => {
    const { x, y } = button[i].getBoundingClientRect();
    button[i].style.setProperty("--x", e.clientX - x + "px");
    button[i].style.setProperty("--y", e.clientY - y + "px");
  });
}
body {
  margin: 0;
  font-family: system-ui;
  font-size: 2.5rem;
  background: white;
  color: black;
}
section {
  position: relative;
}


.imgEmoji {
  height: 2.5rem;
  width: 2.5rem;
  margin-bottom: -6px;

  position: relative;
  z-index: 999;
  mix-blend-mode: unset;
}

.marquee {
  --gap: 1.5rem;
  display: flex;
  gap: var(--gap);
  overflow-x: clip;
  background: white;
}

.marqueeContent {
  display: flex;
  gap: calc(var(--gap));
  flex-shrink: 0;
  align-items: center;
  justify-content: space-around;
  min-width: 100%;
  padding-block: 0.75rem;
  background: inherit;
}


/* Animation */
  .marquee[data-animated="true"] .marqueeContent {
    animation: scroll var(--marquee-duration, 15.5s)
      var(--marquee-direction, forwards) linear infinite;
  }
  .marquee[data-animated="true"]:hover .marqueeContent {
    animation-play-state: paused;
  }

  @keyframes scroll {
    to {
      transform: translate(
        calc(-50% - calc(var(--gap) / 2))
      );
    }
  }

  /* Direction */
  .marquee[data-direction="left"] {
    --marquee-direction: forwards;
  }
  /* Speed */
  .marquee[data-speed="faster"] {
    --marquee-duration: 5s;
  }


/* IDEA 1 */
/* pseudo element on non animated wrapper
+ it stays the same and is not animated 
- images get effected since different stacking context
*/
.marquee:hover::after {
  content: "";
  height: 100%;
  width: 100%;
  top: 0;
  left: 0;
  background: radial-gradient(
      circle at var(--x, 0) var(--y, 0),
      black 0vw,
      red 21vw,
      green 34vw,
      yellow 51vw
  );
  mix-blend-mode: screen;
  position: absolute;
  z-index: 2;
}



/* IDEA 2 */
/* pseudo element on animated content
+ images are not effected
- since the pseudo element is also animated the gradient center changes
- when parts of both content groups are shown the gradient isn't the same on all elements

.marqueeContent:hover::after {
  content: "";
  height: 100%;
  width: 100%;
  top: 0;
  left: 0;
  background: radial-gradient(
      circle at var(--x, 0) var(--y, 0),
      black 0vw,
      red 21vw,
      green 34vw,
      yellow 51vw
  );
  mix-blend-mode: screen;
  position: absolute;
  z-index: 2;
}
*/


/* IDEA 3 */
/* background clip on all spans and a with text 
+ images are not effected
- gradient is different and limited to each text element

span:not(:has(img)), .marqueeContent a {
  background: radial-gradient(
      circle at var(--x, 0) var(--y, 0),
      black 0vw,
      red 21vw,
      green 34vw,
      yellow 51vw
    );
  background-clip: text;
  color: transparent;  
}
*/


/* IDEA 4 */
/* background clip on wraper 
+ images are not effected
- gradient is wierd the center is moving

.marquee:hover {
  background: radial-gradient(
      circle at var(--x, 0) var(--y, 0),
      black 0vw,
      red 21vw,
      green 34vw,
      yellow 51vw
    );
  background-clip: text;
  color: transparent;
}
*/
<section>

  <div class="marquee" data-speed="faster">

    <div class="marqueeContent">
      <a target="blank">Happy Holidays</a>
      <span>
        <img class="imgEmoji" src="https://shorturl.at/kzntl" />
        <img class="imgEmoji" src="https://shorturl.at/kzntl" />
      </span>
      <span aria-hidden="true">Happy Holidays</span>
      <span aria-hidden="true">
        <img class="imgEmoji" src="https://shorturl.at/kzntl" />
        <img class="imgEmoji" src="https://shorturl.at/kzntl" />
      </span>
      <span aria-hidden="true">Happy Holidays</span>
      <span aria-hidden="true">
        <img class="imgEmoji" src="https://shorturl.at/kzntl" />
        <img class="imgEmoji" src="https://shorturl.at/kzntl" />
      </span>
      <span aria-hidden="true">Happy Holidays</span>
      <span aria-hidden="true">
        <img class="imgEmoji" src="https://shorturl.at/kzntl" />
        <img class="imgEmoji" src="https://shorturl.at/kzntl" />
      </span>
    </div>
    
  </div>

</section>

How to make dialog show up in 3 seconds after event onMouseOver

I have an element and after over mouse on it, i show up additional information

document.getElementById(item.id).getElementsByTagName("div")[0].classList.add(classes.hoverDescription)
 .treeNodeDescription{
    font-family: "liberation-sans", sans-serif;
    font-weight: 400;
    font-style: normal;
    font-size: 13px;
    padding: 5px;
    background-color: #333333;
    color: #F8F7F7;
    padding: 10px;
    border-radius: 10px;
    display: none;
    position: absolute;
    top: 130%;
    left: 21%;   
    z-index: 10;
    max-width: 300px;
    text-wrap: wrap;
  }
 .hoverDescription{
    display: block;
  }

But i want to show up this information if user over his mouse along 3 seconds, and if he leave his mouse, don’t show up this DIV.
How to do it using js or css?