How can the omnibox suggestions be styled in Firefox?

I built an extension for Chrome, which I want to use in Firefox. In chrome one can style suggestions using XML-syntax.

Screenshot from Chrome: Example of how the styling looks in chrome

I couldn’t find anything for Firefox and was wondering whether it was possible, and if so, how? If it’s not possible, are there plans to implement this?

I found these three documentation pages and the omnibox extension example.

beforeEach on Mocha does not reset object

I have the following in state.js:

var state = {};

function getState() {
  return state;
}

function setItem(key, value) {
  state[key] = value;
}

function resetState() {
  state = {};
}

exports.getState = getState;
exports.setItem = setItem;
exports.resetState = resetState;

In my Mocha test file, I have the following:

const { getState, setItem, resetState } = require("./state");
var assert = require("assert");

describe("...", function () {
    beforeEach(function() {
      resetState();
    })

    it("Case 1", function (done) {
      setItem("a", "b");
      assert.equal(JSON.stringify(getState()), JSON.stringify({"a": "b"}));
      done();
    });

    it("Case 2", function (done) {
      setItem("x", "y");
      assert.equal(JSON.stringify(getState()), JSON.stringify({"x": "y"}));
      done();
    });
});

Unfortunately, Case 2 fails because it looks like the resetState() function does not work here even though I’m calling it in beforeEach. What am I doing wrong?

Webpack served application not handling bundle.js file correctly

I have an application that uses module federation and webpack. Everything is working fine when I deploy the application locally to a nginx docker image. However, when the pipeline runs and I access it from the browser from its dev URL, I can see that the bundle.js and remoteEntry.js files have the content of index.html. So my page is rendered blank. Here is a screenshot, side by side, of both local and deployed applications sources:

enter image description here

This is my first time using webpack, so I don’t know what exactly is missing. Below is my webpack.config:

const HtmlWebPackPlugin = require("html-webpack-plugin");
const { ModuleFederationPlugin } = require("webpack").container;

const path = require("path");
const deps = require("./package.json").dependencies;

const htmlPlugin = new HtmlWebPackPlugin({
  template: "./public/index.html",
  filename: "./index.html",
});

module.exports = {
  mode: "development",
  entry: "./src/index.tsx",
  resolve: {
    extensions: [".ts", ".tsx", ".js"],
    modules: [path.resolve(__dirname, "src"), "node_modules"],
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
    publicPath: "mfe-prompt/", //This line only exists on the pipe. Locally, I have the exact same file without this single line
  },
  devServer: {
    static: path.join(__dirname, "dist"),
    port: 3000,
    headers: {
      "Access-Control-Allow-Origin": "*",
    },
  },
  module: {
    rules: [
      {
        test: /.(ts|tsx|js)$/,
        exclude: /node_modules/,
        loader: "ts-loader",
      },
      {
        test: /.s[ac]ss$/i,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
    ],
  },
  plugins: [
    htmlPlugin,
    new ModuleFederationPlugin({
      name: "prompt_mfe",
      filename: "remoteEntry.js",
      exposes: {
        "./Prompt": "./src/containers/Prompt/Prompt.tsx",
      },
      shared: {
        ...deps,
        react: { singleton: true, eager: true, requiredVersion: deps.react },
        "react-dom": {
          singleton: true,
          eager: true,
          requiredVersion: deps["react-dom"],
        },
        "react-router-dom": {
          singleton: true,
          eager: true,
          requiredVersion: deps["react-router-dom"],
        },
        "@dds/react": {
          singleton: true,
          eager: true,
          requiredVersion: deps["@dds/react"],
        },
        "prop-types": {
          singleton: true,
          eager: true,
          requiredVersion: deps["prop-types"],
        },
      },
    }),
  ],
};

Don’t know if its useful, but this is my nginx conf:

worker_processes 4;

events {
    worker_connections 1024;
}

http {
    server {
        listen 80;
        root /usr/share/nginx/html;
        include /etc/nginx/mime.types;
        
        location / {
            root /usr/share/nginx/html;
            index index.html;
            try_files $uri $uri/ /index.html;
        }
    }
}

ParcelJS: Error: Does not have node 17172 when running dev server

seem to having an issue with ParcelJS. It was working and the build compiling with no issues. Went to restart the development server and now have an issue and it wont work. It throws the following error:

Error: Does not have node 17172
    at RequestGraph._assertHasNodeId (/Users/ollienorris/Documents/gsap-test/node_modules/@parcel/graph/lib/Graph.js:449:13)
    at RequestGraph.getNodeIdsConnectedTo (/Users/ollienorris/Documents/gsap-test/node_modules/@parcel/graph/lib/Graph.js:77:10)
    at RequestGraph.respondToFSEvents (/Users/ollienorris/Documents/gsap-test/node_modules/@parcel/core/lib/RequestTracker.js:459:26)
    at loadRequestGraph (/Users/ollienorris/Documents/gsap-test/node_modules/@parcel/core/lib/RequestTracker.js:873:18)
    at async RequestTracker.init (/Users/ollienorris/Documents/gsap-test/node_modules/@parcel/core/lib/RequestTracker.js:822:17)
    at async Parcel._init (/Users/ollienorris/Documents/gsap-test/node_modules/@parcel/core/lib/Parcel.js:188:28)
    at async Parcel.watch (/Users/ollienorris/Documents/gsap-test/node_modules/@parcel/core/lib/Parcel.js:260:7)
    at async run (/Users/ollienorris/Documents/gsap-test/node_modules/parcel/lib/cli.js:283:9)

I have had a Google of the issue, but there doesn’t seem to be anything there to help me fix the issue.

Any help would be appreciated!

Am getting “Cannot set property .. which has only a getter” error (javascript canvas width)

More completely, I got:
“Cannot set property clientWidth of #<Element> which has only a getter”
(Obviously I could have had a HTML <canvas> element, but this is a minimized example of my problem.)

But I found a solution: Instead of creating elements and appending, write a string of the HTML I want and use innerHTML = string. Is there a disadvantage in doing this?
Change ‘true’ to ‘false’ in the code to demo the solution:

<html>
  <head>
    <meta charset="utf-8">
    <style>
canvas { outline:1px dotted black; } 
    </style>
  </head>
  <body>
    <script>
  "use strict";
  if (true) { // this code has the error
    let elt = document.createElement('canvas');
    elt.setAttribute('id','canvas');
    elt.clientWidth = 500;
    elt.clientHeight = 500;
    document.body.appendChild(elt);
  } else {    // this has the workaround/solution
    let s = '<canvas id="canvas" width="500" height="500"></canvas>';
    document.body.innerHTML = s;
  }
  let ctx = canvas.getContext("2d");
  ctx.arc(250,250,200, 0, 6.2832);
  ctx.stroke();
    </script>
  </body>
</html>

How to send this data to Database using Express and MongoDB and React Native ? Issue with Sending Data to Backend Endpoint in React Native

I’m encountering an issue with sending data from my React Native frontend to a backend endpoint. I’ve provided the relevant code snippets below.I’m encountering an issue with sending data from my React Native frontend to a backend endpoint (/onboarding/v3). Below, I’ve provided relevant code snippets and additional details about my setup.

enter image description here

User Model:

I’m using a MongoDB database with Mongoose to define my user schema. The schema includes fields for name, email, password, and various other user details. Of particular relevance to this issue is the areasOfInterest field, which is an array of objects containing title and items properties.

I have a React Native component AreasOfInterest where users select their areas of interest and rate their expertise. Upon pressing a “Next” button, I want to send this data to the backend.

I would appreciate any guidance on how to properly format the data and resolve the issue with sending it to the backend endpoint. I’ve included relevant code snippets below for reference.

Backend Endpoint:

I have a backend endpoint /onboarding/v3

Please fix my code
My User Model is below. after it

const mongoose = require("mongoose");

// Define schema for items within an area of interest
const InterestItemSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
  },
  stars: {
    type: Number,
    min: 1,
    max: 5,
    default: 1, // Default to 1 star
  },
});

// Define schema for areas of interest
const InterestSchema = new mongoose.Schema({
  title: {
    type: String,
    required: true,
  },
  items: {
    type: [InterestItemSchema],
    default: [],
  },
});

const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    required: true,
    unique: true,
  },
  password: {
    type: String,
    required: true,
  },
  image: {
    type: String,
    required: true,
  },
  friendRequests: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
    },
  ],
  friends: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
    },
  ],
  sentFriendRequests: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
    },
  ],
  First_Name: {
    type: String,
    default: "",
  },
  Last_Name: {
    type: String,
    default: "",
  },
  Pronoun: {
    type: String,
    default: "",
  },
  Gender: {
    type: String,
    default: "",
  },
  Race: {
    type: String,
    default: "",
  },
  Country: {
    type: String,
    default: "",
  },
  State: {
    type: String,
    default: "",
  },
  City: {
    type: String,
    default: "",
  },
  Role: {
    type: String,
    default: "",
  },
  Student: {
    type: Boolean,
    default: false,
  },
  Mentor: {
    type: Boolean,
    default: false,
  },
  Affiliation: {
    type: String,
    default: "",
  },
  Headline: {
    type: String,
    default: "",
  },
  Education: {
    type: String,
    default: "",
  },
  Major: {
    type: String,
    default: "",
  },
  Degree: {
    type: String,
    default: "",
  },
  GradeYear: {
    type: String,
    default: "",
  },
  areasOfInterest: {
    type: [InterestSchema],
    default: [],
  },
  Career_Goals: {
    type: [String],
    default: [],
  },
  withOrgOnly: {
    type: Boolean,
    default: false,
  },
  createdAt: {
    type: Date,
    default: Date.now,
  },
  updatedAt: {
    type: Date,
    default: Date.now,
  },
});

const User = mongoose.model("User", userSchema);

module.exports = User;

// Backend Endpoint (Working (not sure about onboarding/v3) )

const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const bcrypt = require("bcrypt");
const os = require("os");
const app = express();
const morgan = require("morgan");
const port = 8080;
const cors = require("cors");
const router = express.Router();

app.use(morgan("dev"));
app.use(cors());

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(passport.initialize());
const jwt = require("jsonwebtoken");

const User = require("./models/user");

// POST endpoint for onboarding/v3
app.post("/onboarding/v3", async (req, res) => {
  try {
    const { userId, areasOfInterest } = req.body;

    const user = await User.findById(userId);
    console.log(user.name);
    console.log(areasOfInterest);
    if (!user) {
      return res.status(404).json({ message: "User not found" });
    }

    user.areasOfInterest = areasOfInterest;

    await user.save();

    res.status(200).json({ message: "Areas of interest updated successfully" });
  } catch (err) {
    console.log("Error updating areas of interest", err);
    res.status(500).json({ message: "Error updating areas of interest" });
  }
});

// Frontend Main Page.

import React, { useState, useContext } from "react";
import {
  View,
  Text,
  SafeAreaView,
  TextInput,
  TouchableOpacity,
  FlatList,
} from "react-native";
import Icon from "react-native-vector-icons/FontAwesome5";
import { CheckBox } from "react-native-elements";
import { AntDesign } from "@expo/vector-icons";
import axios from "axios";
import { UserType } from "../../UserContext";

const NavigationLine = ({ active }) => (
  <View
    style={{
      flex: 1,
      height: 5,
      backgroundColor: active ? "#57D5DB" : "#DBD4D4",
      marginHorizontal: 5,
    }}
  />
);

const InterestList = ({ data }) => {
  const [expanded, setExpanded] = useState(false);
  const [ratings, setRatings] = useState(Array(data.items.length).fill(0));
  const [selectedItems, setSelectedItems] = useState(
    Array(data.items.length).fill(false)
  );

  const handleRatingChange = (index, rating) => {
    const newRatings = [...ratings];
    newRatings[index] = rating;
    setRatings(newRatings);
  };

  const toggleCheckbox = (index) => {
    const newSelectedItems = [...selectedItems];
    newSelectedItems[index] = !selectedItems[index];
    setSelectedItems(newSelectedItems);
    // Reset rating to 0 when unchecking the checkbox
    if (!newSelectedItems[index]) {
      handleRatingChange(index, 0);
    }
  };
  return (
    <View>
      <TouchableOpacity
        onPress={() => setExpanded(!expanded)}
        style={{
          flexDirection: "row",
          alignItems: "center",
          backgroundColor: "#F1F1F3",
          width: "90%",
          height: 50,
          borderRadius: 20,
          marginTop: 15,
          paddingHorizontal: 20,
          borderColor: "#D9D9D9",
          borderWidth: 1,
          marginHorizontal: 15,
        }}
      >
        <Icon
          name={expanded ? "caret-down" : "caret-right"}
          size={15}
          color="#9C9C9C"
        />
        <Text style={{ flex: 1, marginLeft: 10 }}>{data.title}</Text>
      </TouchableOpacity>
      {expanded && (
        <FlatList
          data={data.items}
          keyExtractor={(item, index) => index.toString()}
          renderItem={({ item, index }) => (
            <View
              style={{
                flexDirection: "row",
                alignItems: "center",
                backgroundColor: "#F1F1F3",
                width: "90%",
                height: 50,
                borderRadius: 20,
                marginTop: 5,
                marginHorizontal: 15,
                borderWidth: 0.1,
              }}
            >
              <TouchableOpacity
                onPress={() => toggleCheckbox(index)}
                style={{ marginLeft: 20, marginRight: 10 }}
              >
                <Icon
                  name={selectedItems[index] ? "check-square" : "square"}
                  size={20}
                  color="#000"
                />
              </TouchableOpacity>
              <View style={{ flex: 1 }}>
                <Text style={{ fontSize: 13 }}>{item}</Text>
              </View>
              {selectedItems[index] && ( // Show stars only if checkbox is selected
                <View style={{ flexDirection: "row", marginRight: 20 }}>
                  {[1, 2, 3, 4, 5].map((star) => (
                    <TouchableOpacity
                      key={star}
                      onPress={() => handleRatingChange(index, star)}
                      style={{ marginRight: 4 }}
                    >
                      <AntDesign
                        name="star"
                        size={20}
                        color={ratings[index] >= star ? "#FFD700" : "#D3D3D3"}
                      />
                    </TouchableOpacity>
                  ))}
                </View>
              )}
            </View>
          )}
        />
      )}
    </View>
  );
};

const AreasOfInterest = ({ navigation }) => {
  // Use userId to send backend
  const { userId, setUserId } = useContext(UserType);
  const interestData = [
    {
      title: "Accounting",
      items: [
        "Financial Accounting",
        "Cost Accounting",
        "Managerial Accounting",
        "Auditing",
        "Tax Accounting",
        "Forensic Accounting",
      ],
    },
    {
      title: "Finance",
      items: [
        "Investment Management",
        "Financial Risk Management",
        "Corporate Finance",
        "Public Finance",
        "Personal Finance",
      ],
    },
    {
      title: "Human Resources",
      items: [
        "Learning & Development",
        "Performance Management",
        "HR Information Systems",
        "Compensation & Benefits",
        "Recruiting & Staffing",
        "Organizational Structure",
        "Employee & Labor Relations",
        "Diversity Equity & Inclusion",
      ],
    },
    {
      title: "Information Technology",
      items: [
        "Systems Security",
        "Data Management",
        "IT Management",
        "Network Administration",
        "Software Development",
        "Web Development",
      ],
    },
    {
      title: "Legal",
      items: [
        "Litigation",
        "Risk Management",
        "Contract Law",
        "Import/Export Law",
        "Compliance Policies & Procedures",
        "Property Law",
        "Intellectual Property Law",
        "Employment Law",
        "Ethics",
        "Law Enforcement",
        "Criminal Justice",
      ],
    },
    {
      title: "Manufacturing",
      items: [
        "Plant Management",
        "Fabrication & Machining",
        "Reliability & Asset Management",
        "Procurement",
        "Distribution",
        "Production Installation",
      ],
    },
    {
      title: "Operations",
      items: [
        "Improve Processes",
        "LEAN & Six Sigma",
        "Production Planning & Control",
        "Quality Management",
        "Supply Chain Management",
        "Design Process",
      ],
    },
    {
      title: "Marketing & Communication",
      items: [
        "Sales Support",
        "Marketing Communications",
        "Advertising Strategy",
        "Pricing Strategy",
        "Market Research",
        "Social Media Strategy",
        "Brand Management",
        "Copy & Content Creation",
        "Imaging/Graphics",
      ],
    },
    {
      title: "Sales",
      items: [
        "Capture Management",
        "Building a Book of Business",
        "Channel Strategy",
        "Sales Forecasting",
        "Enterprise Sales",
        "Inside Sales",
        "Objection Handling",
        "Business Development",
      ],
    },
    {
      title: "Management",
      items: [
        "Delegation",
        "Emotional Intelligence",
        "Improve Processes",
        "Product Management",
        "Project Management",
        "Decision Making",
        "Negotiation Skills",
        "Develop Others",
        "Change Management",
        "Priority Management",
        "Effective Communication",
        "Conflict Management",
      ],
    },
    {
      title: "Leadership",
      items: [
        "Team Building",
        "Shaping Culture",
        "Setting Vision & Strategy",
        "Strategic Thinking",
        "Product Development",
        "Service Development",
        "Value Creation",
      ],
    },
    {
      title: "Healthcare",
      items: [
        "Dentistry",
        "Health Sciences",
        "Physician",
        "Veterinarian",
        "Pharmacist",
        "Healthcare Management",
        "Patient Care",
      ],
    },
    {
      title: "Education",
      items: [
        "Teaching",
        "Education Administration",
        "School Counseling",
        "Curriculum Development",
      ],
    },
    {
      title: "Consulting",
      items: [
        "Management Consulting",
        "Corporate Consulting",
        "Independent Consulting",
      ],
    },
    {
      title: "Government & Public Administration",
      items: [
        "Revenue & Taxation",
        "Law Enforcement",
        "Public Management & Administration",
        "Environmental & Resource Planning",
        "National Security",
        "Governance",
      ],
    },
    {
      title: "Customer Service",
      items: [
        "Customer Retention",
        "Customer Management",
        "Customer Support",
        "SaaS Customer Experience",
      ],
    },
    {
      title: "Engineering",
      items: [
        "Civil Engineering",
        "Chemical Engineering",
        "Mechanical Engineering",
        "Electrical Engineering",
        "Industrial Engineering",
        "Aerospace Engineering",
        "Biomedical Engineering",
        "Environmental Engineering",
        "Computer Engineering",
        "Materials/Textiles Engineering",
        "Nuclear Engineering",
        "Architecture",
      ],
    },
    {
      title: "Sciences",
      items: [
        "Agricultural Science",
        "Social Science",
        "Biology",
        "Chemistry",
        "Political Science",
        "Physics",
        "Psychology",
        "Mining & Petroleum",
      ],
    },
    {
      title: "Social Services",
      items: [
        "Therapists",
        "Probation Officer",
        "Rehabilitation Counselor",
        "Career Counselor",
        "Social Worker",
        "Substance Abuse Counselor",
        "Mental Health Counselor",
        "Clergy",
      ],
    },
    {
      title: "Creative / Design",
      items: [
        "Creative Arts",
        "Graphic Design",
        "Interior Design",
        "Product Design",
        "User Experience",
      ],
    },
  ];

  const [initialInterestData, setInitialInterestData] = useState([]);
  // Search Logic
  // TODO: Later Search Logic
  // Handle Next
  const handleNext = async () => {
    try {
      // Construct the data object to send
      const dataToSend = initialInterestData.map((interest) => ({
        title: interest.title,
        selectedItems: interest.items
          .filter((item, index) => selectedItems[index])
          .map((item, index) => ({
            name: item,
            rating: ratings[index],
          })),
      }));
      console.log(dataToSend);
      // Make the HTTP request to the backend API
      const response = await axios.post(
        "http://172.20.10.3:8080/onboarding/v3",
        dataToSend
      );

      // Handle response as needed (e.g., show success message, navigate to next screen)
      console.log("Response from backend:", response.data);
      navigation.navigate("Career"); // Navigate to the next screen
    } catch (error) {
      // Handle error (e.g., show error message)
      console.error("Error sending data to backend:", error);
    }
  };

  return (
    // Margin Top is missing in this. i want same level of margin as my previous pages.
    <SafeAreaView style={{ flex: 1, alignItems: "center", marginTop: 40 }}>
      <TouchableOpacity
        onPress={() => {
          navigation.goBack();
        }}
        style={{
          position: "absolute",
          top: 3,
          left: 20,
          justifyContent: "center",
          alignItems: "center",
          flexDirection: "row",
        }}
      >
        <Icon name="chevron-left" size={24} color="#000" />
      </TouchableOpacity>
      <Text style={{ fontWeight: "bold", fontSize: 20, marginBottom: 5 }}>
        Areas of Interest
      </Text>
      <View style={{ width: 400, height: 1.5, backgroundColor: "#DBD4D4" }} />

      <FlatList
        data={interestData}
        keyExtractor={(item, index) => index.toString()}
        renderItem={({ item }) => <InterestList data={item} />}
        ListHeaderComponent={() => (
          <>
            <Text
              style={{ fontSize: 17, marginTop: 10, paddingHorizontal: 15 }}
            >
              Select areas of interest and rate your expertise in each to
              receive personalized mentoring recommendations. Rate your
              expertise with the star system (1 - 5) to establish your
              proficiency.
            </Text>
            <Text
              style={{
                fontSize: 11,
                color: "#9C9C9C",
                textAlign: "left",
                marginTop: 10,
                paddingHorizontal: 15,
              }}
            >
              Your ratings are confidential and not displayed on your profile.
              We recommend selecting at least 3 options.
            </Text>

            <View
              style={{
                flexDirection: "row",
                alignItems: "center",
                backgroundColor: "#F1F1F3",
                width: "90%",
                height: 50,
                borderRadius: 20,
                marginTop: 15,
                paddingHorizontal: 20,
                borderColor: "#D9D9D9",
                borderWidth: 1,
                marginHorizontal: 15,
              }}
            >
              <Icon name="search" size={15} color="#9C9C9C" />
              <TextInput
                placeholder="Search Here"
                style={{ flex: 1, marginLeft: 10 }}
              />
            </View>
          </>
        )}
      />
      <View style={{ flexDirection: "row", height: 10, marginVertical: 10 }}>
        <NavigationLine active={true} />
        <NavigationLine active={true} />
        <NavigationLine active={true} />
        <NavigationLine active={false} />
        <NavigationLine active={false} />
      </View>
      <TouchableOpacity
        onPress={handleNext}
        style={{
          backgroundColor: "#09A1F6",
          padding: 10,
          borderRadius: 30,
          width: "90%",
          height: 50,
          justifyContent: "center",
          alignItems: "center",
          marginBottom: 10,
        }}
      >
        <Text style={{ color: "#fff", fontSize: 24, fontWeight: "bold" }}>
          Next
        </Text>
      </TouchableOpacity>
    </SafeAreaView>
  );
};

export default AreasOfInterest;

Trying to use swiper js with npm but I can not( Pure JS

I want to use swiper js for my project and I want to install it using npm. Many times there were errors with the installation, but after fixing the errors there were no errors, but the slider did not work. Before this I installed it using a cdn file and everything worked, but I want to use npm. Help please, I’ve been sitting all day trying to do this.

Here’s my code:

import Swiper from "swiper";
import "../node_modules/swiper/swiper.css";
import "../node_modules/swiper/modules/navigation.css";
import { Navigation } from "swiper/modules";
const controlMain = async function () {
  await model.setDefault();
  document.querySelector(".main-spinner").classList.add("active");

  const topAuthorsMarkup = `
  <section class="top-authors">
  <h2 class="heading-secondary">Top authors</h2>
  <!-- Список слайдов -->
  <div class="swiper top-authors__list">
    <div class="swiper-wrapper">
      ${model.state.default.topAuthorsNames
        .map((authorName, i) => {
          return `
        <div class="swiper-slide top-authors__item">
          <figure class="top-authors__author">
            <img class="top-authors__img"
                 src="${model.state.default.topAuthorsImgs[i]}"
                 alt="${authorName} image" />
            <figcaption class="top-authors__description">
              <h3 class="top-authors__name">${authorName}</h3>
              <p class="top-authors__text">
                ${model.state.default.topAuthorsDescription[i]}
              </p>
            </figcaption>
            <a class="top-authors__link" href="#"></a>
          </figure>
        </div>
      `;
        })
        .join("")}
    </div>
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>
  </div>
</section>
`

Here’s video

I want to make an exstntion that will paste text from a random list. but i cant get it to work

i cant seem to get the text to acctally paste into any text box or doc
i have tiend a lot of diffrent things but nothing seems to be working.
if there is something im missing im not sure.
is there a way to do so?
could i get some help?

manifest.json

{
    "manifest_version": 3,
    "name": "Random Word Inserter",
    "version": "1.0",
    "description": "Inserts a randomly chosen word into text boxes when the tab key is pressed.",
    "permissions": ["activeTab"],
    "background": {
      "service_worker": "background.js"
    },
    "action": {
      "default_popup": "popup.html",
      "default_icon": {
        "16": "icon.png",
        "48": "icon.png",
        "128": "icon.png"
      }
    },
    "content_scripts": [
      {
        "matches": ["<all_urls>"],
        "js": ["content.js"]
      }
    ]
  }
  

Contents.js

const words = ["apple", "banana", "orange", "grape", "pineapple"];

document.addEventListener("keydown", function (event) {
  if (event.key === "Tab") {
    const inputFields = document.querySelectorAll("input[type='text']");
    inputFields.forEach(function (input) {
      const randomIndex = Math.floor(Math.random() * words.length);
      const randomWord = words[randomIndex];
      input.value += randomWord;
    });
  }
});

popup.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Random Word Inserter Settings</title>
</head>
<body>
  <h1>Random Word Inserter Settings</h1>
  <p>No settings available yet.</p>
</body>
</html>

Issue with Animated Counter Functionality on Mobile Devices

I’m encountering an issue with an animated counter on my website. The counter is intended to simulate a statistic and works perfectly on desktop browsers. However, when accessed on mobile devices in a production environment, there seems to be a problem with parsing or conversion that resets any number above 999, consequently resetting the initial number.

Here’s the relevant HTML code snippet:

<span id="counter">4898988</span><br />

Here’s the relevant JavaScript code snippet:

document.addEventListener('DOMContentLoaded', (event) => {
  const counterElement = document.getElementById('counter');
  console.log('counterElement:', counterElement); // log the counterElement
  counterElement.textContent = `${parseInt(counterElement.textContent, 10).toLocaleString()} USD`; // format the initial number
  console.log('counterElement.textContent after formatting:', counterElement.textContent); // log the textContent after formatting
  animateCount(counterElement);
  
  // Animate the counter
  function animateCount(targetElement) {
    console.log('targetElement in animateCount:', targetElement); // log the targetElement in animateCount
    let count = parseInt(targetElement.textContent.replace(/,/g, ''), 10);
    console.log('count after parsing:', count); // log the count after parsing
    const finalCount = count + Math.floor(Math.random() * 31); // generate a random number between 0 and 30
    const interval = setInterval(() => {
      if (count < finalCount) {
        count++;
        targetElement.textContent = `${count.toLocaleString()} USD`;
      } else {
        clearInterval(interval);
        setTimeout(() => animateCount(targetElement), Math.random() * 9000 + 5000); // wait for a random period between 5 and 14 seconds before starting the next cycle
      }
    }, 100);
  }
});

Console log:

[Log] counterElement:
<span id="counter">4 898 988 USD</span>
[Log] after formatting: – "4 898 988 USD"
[Log] animateCount: 
<span id="counter">4 898 988 USD</span>
[Log] count after parsing: – 4 

As you can see, the ‘let count =’ line seems to not parse correctly a number above 999.

How to include external css in Svelte Custom Element?

I’m new to Svelte and I’m trying to create a custom element that relies on font-awesome fonts. However, when I build the component and try to use it — none of my styling (including the font-awesome css) gets applied.

I really don’t want the user of my element to have to include font-awesome on their own — I want it to just be included as part of my custom element.

Just curious what I need to do to get this to work?

Here’s what I have:

App.js

<svelte:options customElement="my-custom-element"></svelte:options> 

<script>
   export let overrideCss = null;  //Give user of element chance to override css
   ...
</script>

<!-- Css below is applied when running dev server, but doesn't get applied after build -->
<link rel="stylesheet" href="/src/app.css">
<link href="./../node_modules/@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet"> 
{#if overrideCss}
    <link rel="stylesheet" href={overrideCss}/>
{/if}

<div id="my-app-container">
  ...
  <i class="fas fa-thumbs-{approved ? 'up' : 'down'}"></i>
</div>

Vanilla JavaScript to show scroll progress bar that fills only while scrolling the element?

I’m trying to create a scroll progress bar that fills from 0-100% when scrolling the element only, but i can’t get it to work. I’ve got it working to show the whole page scrolling progress when scrolling the element, but I need it to only show 0-100% on the element, and only while that element is being scrolled. I also need to create it using vanilla javascript.

Here’s what i have that isn’t working:

HTML

<body>
    <header>
        <section>
        </section>
    </header>
    <nav>
        <div class="nav"></div>
        <div class="scroll">
                <div class="scroll-bar" id="scroll-progress"></div>
        </div>
    </nav>
    <main>
        <section>
            <p>some content</p>
        </section>
        <section>
            <p>some content</p>
        </section>
    </main>
    <section>
        <p>some content</p>
    </section>
    <section>
        <p>some content</p>
    </section>
    
</body>

CSS

.nav {
    background-color: black;
    height:50px;
}
section {
    height: 400px;
}

.scroll {
    width: 100%;
    height: 4px;
    background-color: lightgray;
}

#scroll-progress {
    width: 0%;
    height: 4px;
    background-color: green;
}

JS

const main = document.querySelector('main');
const progress = () => {
    const scroll = main.scrollTop;
    const height = main.scrollHeight - main.clientHeight;
    const scrollProgress = (scroll / height) * 100;
    document.getElementById('scroll-progress').style.width = scrollProgress + "%";
}

window.addEventListener('scroll', progress);

This, however, works as expected, but shows the progress through the whole page, while scrolling the element, I’m just not sure how to get from this to what i need.

const main = document.querySelector('main');
const progress = () => {
    let scroll = document.documentElement.scrollTop;
    let height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
    let scrollProgress = (scroll / height) * 100;
    document.getElementById("scroll-progress").style.width = scrollProgress + "%";
}

window.addEventListener('scroll', progress);

Any help greatly appreciated

How do I fix the following issues with my port of a manifest v2 browser extension to manifest v3?

I am in the process of transitioning a manifest v2 Chrome extension to manifest v3 and while converting my background script background.js to a service worker, and I am getting error messages in Google Chrome. I am somewhat familiar with Manifest v3, however the concept of service workers is still very confusing to me. Here is the error message. Note: Keep in mind, despite the single error message, I believe there may be some logical errors rather than syntax errors in my source code that may present undesired or unexpected behavior in the browser extension.

Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.

To put this error into context, I have included the code of my service worker called service-worker.js, content-script.js, and manifest.json. I think I did most of the “heavy lifting” porting my MV2 extension to MV3, but there seems to be some minor issues.

service-worker.js

"use strict";

function sendAudioMessage(actionType, audioFile) {
  chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
    tabs.forEach(tab => {
      chrome.tabs.sendMessage(tab.id, { action: actionType });
    });
  });
}

chrome.webNavigation.onCreatedNavigationTarget.addListener(onNav);
chrome.webNavigation.onBeforeNavigate.addListener(onNav);
chrome.webNavigation.onReferenceFragmentUpdated.addListener(onNav);
chrome.webNavigation.onHistoryStateUpdated.addListener(onNav);

function onNav({frameId}) {
  if(frameId > 0) return;
  sendAudioMessage('playNavigationSound');
}

chrome.downloads.onChanged.addListener(delta => {
  if(delta.state && delta.state.current === "complete") {
    sendAudioMessage('playDownloadCompleteSound');
  }
  if(delta.error && delta.error.current) {
    sendAudioMessage('playDownloadErrorSound');
  }
});

chrome.tabs.onUpdated.addListener((tabId, {mutedInfo}) => {
  if(mutedInfo && mutedInfo.reason === "user") {
    sendAudioMessage('playMuteWarningSound'); 
  }
});

function changeVolume(volumeLevel) {
  chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
    tabs.forEach(tab => {
      chrome.tabs.sendMessage(tab.id, { action: 'changeVolume', volume: volumeLevel });
    });
  });
}

// *** Message Handler ***
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  switch (message.action) {
    case 'playNavigationSound':
      sendAudioMessage('playNavigationSound');
      break;
    case 'playDownloadCompleteSound':
      sendAudioMessage('playDownloadCompleteSound');
      break;
    case 'playDownloadErrorSound':
      sendAudioMessage('playDownloadErrorSound');
      break;
    case 'playMuteWarningSound':
      sendAudioMessage('playMuteWarningSound');
      break;
    case 'changeVolume':
      changeVolume(0.75); 
      break;
    default:
      console.log('Unknown message action:', message.action);
  }
});

content-script.js

// Helper function to play audio
function playAudio(audioFile) {
  const audio = new Audio(chrome.runtime.getURL(audioFile)); // Use chrome.runtime.getURL for packaged extension resources
  audio.play();
}

// Helper function for setting volume
function setAudioVolume(volumeLevel) {
  const audioElements = document.querySelectorAll('audio');
  audioElements.forEach(audio => {
      audio.volume = volumeLevel;
  });
}

// Receive messages from your service worker
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  switch (message.action) {
      case 'playNavigationSound':
          playAudio('nav.ogg');
          break;
      case 'playDownloadCompleteSound':
          playAudio('done.ogg');
          break;
      case 'playDownloadErrorSound':
          playAudio('error.ogg');
          break;
      case 'playMuteWarningSound':
          playAudio('unlock.ogg');
          break;
      case 'changeVolme':
          setAudioVolume(0.75);
          break;
      default:
          console.log('Unknown message action:', message.action);
  }
});
  

manifest.json

{
  "manifest_version": 3,
  "name": "PopupSound",
  "description": "Plays a click sound when you click on a link. Also plays a trumpet sound when you finish downloading a file.",
  "author": "Michael Gunter",
  "version": "3.0",
  "default_locale": "en",
  "offline_enabled": true,
  "icons": {
    "32": "icon_32.png",
    "96": "icon_96.png",
    "128": "icon_128.png"
  },
  "background": {
    "service_worker": "service-worker.js"
  },
  "permissions": [
    "webNavigation",
    "downloads",
    "tabs"
  ],

  "content_scripts": [
    {
      "matches": ["<all_urls>"], 
      "js": ["content-script.js"],
      "run_at": "document_start"
    }
  ],

  "content_security_policy": {}
}

Edit: While I no longer get the error message when the extension runs, I now get two error messages when audio is expected to be played from the browser extension.

Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.

Uncaught (in promise) NotAllowedError: play() can only be initiated by a user gesture.

I hope this helps.

How to Update Input Value without onChange in React?

I’ve been working on a React component where I have implemented handleStepUp and handleStepDown functions for incrementing and decrementing values. However, I’m facing a challenge with updating the input value within these functions since they don’t have access to an event like onChange. The onChange event is crucial for updating the input value in React, but I can’t directly use it within handleStepUp or handleStepDown.

import * as React from 'react';

import { Input } from '@/components/shadcnui/input';

export interface InputProps
  extends React.InputHTMLAttributes<HTMLInputElement> {
  onChange?: (event: ChangeEventExtendedProps) => void;
  defaultValue?: string;
  step?: number;
  onStepUp?: () => void; // Menambah properti onStepUp
  onStepDown?: () => void; // Menambah properti onStepDown
}

export interface CustomChangeEvent {
  target: { floatValue: number; formattedValue: string; value: string };
}
export interface ChangeEventExtendedProps
  extends React.ChangeEvent<HTMLInputElement> {
  target: HTMLInputElement & {
    floatValue: number | undefined;
    formattedValue: string | undefined;
  };
}

function formatNumber(number: number): string {
  const converted = number.toLocaleString(); // returns a number as a string, using local language format. 1000 => 1,000
  return converted;
}

export const NumberInputFormat = React.forwardRef<HTMLInputElement, InputProps>(
  (props, ref) => {
    const {
      onChange,
      defaultValue = 0,
      step = 1,
      onStepUp,
      onStepDown,
      min,
      max = 10,
    } = props;

    const [formattedValue, setFormattedValue] = React.useState<string>(
      defaultValue.toString()
    );

    // ketika kita mempassing sebuah fungsi ke dalam sebuah props,
    // ada baiknya kita buatkan dia useCallback sehingga fungsi
    // itu tidak dibuat kembali ketika proses re-render
    const handleChange = React.useCallback(
      (event: ChangeEventExtendedProps) => {
        const stringValue = event.target.value;

        const numericValue = stringValue
          ? parseFloat(stringValue.replace(/,/g, ''))
          : 0;

        const formattedStringValue = formatNumber(numericValue);
        setFormattedValue(formattedStringValue);
        onChange?.({
          ...event,
          target: {
            ...event.target,
            floatValue: numericValue,
            formattedValue: formattedStringValue,
            value: stringValue,
          },
        });
      },
      [onChange]
    );

    const handleStepUp = () => {
      const stringValue = formattedValue.replace(/,/g, '');
      const floatValue = parseFloat(stringValue) + step;
      const formattedStringValue = formatNumber(floatValue);
      setFormattedValue(formattedStringValue);

      onStepUp?.(); // Memanggil onStepUp jika diberikan
    };

    const handleStepDown = () => {
      const stringValue = formattedValue.replace(/,/g, '');
      const floatValue = parseFloat(stringValue) - step;
      const formattedStringValue = formatNumber(floatValue);
      setFormattedValue(formattedStringValue);

      onStepDown?.(); // Memanggil onStepUp jika diberikan
    };

    return (
      <>
        <button type="button" onClick={handleStepUp}>
          +
        </button>
        <button type="button" onClick={handleStepDown}>
          -
        </button>
        <Input
          {...props}
          value={formattedValue}
          onChange={handleChange}
          ref={ref}
          type="text"
        />
      </>
    );
  }
);

NumberInputFormat.displayName = 'NumberInputFormat';

What would be the best approach to update the input value without relying on the onChange event? Is there a way to achieve this while maintaining the React best practices? Any insights or alternative methods would be greatly appreciated. Thank you!

window.open can’t attach params to a url ends with .html

while I’m using

window.open(‘/a.html?title=666’)

there is no title = 666 in the new window’s url

but

window.open(‘/a?title=666’)

works fine.

it’s really confused me.

by the way, I’m using node’s ‘serve’ npm package to test in localhost.

during the research of documents, it is supposed to be the same.