Javascript event check if events were triggered by the same user action

I want to check if two different events were triggered by the same user action.
For example, I have a “keydown” event listener and a “beforeinput” event listener with an editable div.
Is there a way I can check if both events were triggered by the same key press?
I know I could do it in a hacky way checking the time between the events, but is there a reliable/deterministic way to know if the events were triggered by the same input from the user?

If not a specific property, is there maybe a more reliable way to increment an id number after each event loop or push a callback to the end of the stack after the event loop to know the events on the stack would have all needed to be added at the same time by the same user input before the user would have been able to press another key or do another action?

How to download .lnk file in html

I’ve a shared directory reachable by html page in this way

<div onclick="windows.open('file://mypath/mysharefolder','_blank');">Shared folder</div>

This works with internet explorer, but not with Chrome browser (error: Not allowed to load local resource).
So I’ve thought of replacing the link with a tag to allow the download of a lnk file (created manually) containing the path of the shared directory like this

<a href="mylinktofolder.lnk" download>Shared folder</a>

this tag works to download other kind of file (img,pdf,…), but not with lnk file; download in Chrome fails because doesn’t find file mylinktofolder.download.

Is it possible to download such a file?

Thanks in advance

Block validation: Expected attribute `class` of value `wp-block-cgb-block-test-gutenberg-block

I’m trying to create a custom WordPress gutenberg block that allows me to edit the second a a paragraph.

I can create the block using this code and I can see content on the frontend of the site however the block crashes if I view the block to edit it.

The console gives the following error:

Block validation: Expected attribute class of value wp-block-cgb-block-test-gutenberg-block, saw text-blueGray-700 .

Block validation: Block validation failed for cgb/block-test-gutenberg-block ({name: ‘cgb/block-test-gutenberg-block’, icon: {…}, keywords: Array(3), attributes: {…}, providesContext: {…}, …}).

Content generated by save function…..

My code is:

attributes: {
    content: {
        type: 'array',
        source: 'html',
        selector: 'p',
    }
},


edit: ( { attributes, setAttributes, className, isSelected } ) => {
    

    function onChangeContentName ( content ) {
        setAttributes({content: content})
    }

    let content = attributes.content // To bind attribute link_text

    // Creates a <p class='wp-block-cgb-block-test-gutenberg-block'></p>.
    return (

        
            <h1
                class="mx-auto mb-8 text-2xl font-semibold leading-none tracking-tighter text-black lg:text-3xl title-font">
                Test Site</h1>
            <p class="mx-auto text-base font-medium leading-relaxed text-blueGray-700 ">
  recreate this whole icon box component as UI of your gutenberg block; displaying site's title as a header and sites tagline at the bottom below the 2nd paragraph. 
  the 2nd paragraph should be editable.</p>
        </div>
    </div>
    <div class="w-full lg:w-1/3">
        <div class="h-full p-4 space-y-4 lg:rounded-r-xl rounded-b-xl lg:p-8 bg-blueGray-50">
            
                <RichText
                    tagName="p"
                    className={className} // Automatic class: gutenberg-blocks-sample-block-editable
                    onChange={onChangeContentName} // onChange event callback
                    value={content} // Binding
                    placeholder="Lorem impsum write your content..."
                />
            
            <h2 class="text-xs font-semibold tracking-widest text-black uppercase title-font"> Just another WordPress site
            </h2>
        </div>
        <div>
        </div>
    </div>
</div>
save: ( { attributes } ) => {
    
    return (

        <section class="text-blueGray-700 ">
<div class="container items-center px-5 py-8 mx-auto">
    <div class="flex flex-wrap justify-center mb-12 divide-y-2 lg:divide-y-0 lg:divide-x-2">
        <div class="w-full lg:w-1/3">
            <div class="p-4 rounded-t-xl lg:rounded-l-xl lg:p-8 bg-blueGray-50">
                <div
                    class="inline-flex items-center justify-center flex-shrink-0 w-12 h-12 mx-auto mb-5 text-black bg-blueGray-100 rounded-full">
                    <svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 icon icon-tabler icon-tabler-aperture"
                        width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
                        fill="none" stroke-linecap="round" stroke-linejoin="round">
                        <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
                        <circle cx="12" cy="12" r="9"></circle>
                        <line x1="3.6" y1="15" x2="14.15" y2="15"></line>
                        <line x1="3.6" y1="15" x2="14.15" y2="15" transform="rotate(72 12 12)"></line>
                        <line x1="3.6" y1="15" x2="14.15" y2="15" transform="rotate(144 12 12)"></line>
                        <line x1="3.6" y1="15" x2="14.15" y2="15" transform="rotate(216 12 12)"></line>
                        <line x1="3.6" y1="15" x2="14.15" y2="15" transform="rotate(288 12 12)"></line>
                    </svg>
                </div>
                <h3 class="mb-4 text-xs font-semibold tracking-widest text-black uppercase title-font">test Option 2
                </h3>

                <h1
                    class="mx-auto mb-8 text-2xl font-semibold leading-none tracking-tighter text-black lg:text-3xl title-font">
                    Test Site</h1>
                <p class="mx-auto text-base font-medium leading-relaxed text-blueGray-700 ">
      recreate this whole icon box component as UI of your gutenberg block; displaying site's title as a header and sites tagline at the bottom below the 2nd paragraph. 
      the 2nd paragraph should be editable.</p>
            </div>
        </div>
        <div class="w-full lg:w-1/3">
            <div class="h-full p-4 space-y-4 lg:rounded-r-xl rounded-b-xl lg:p-8 bg-blueGray-50">
                
                    <RichText.Content tagName="p" value={ attributes.content } />
                
                <h2 class="text-xs font-semibold tracking-widest text-black uppercase title-font"> Just another WordPress site
                </h2>
            </div>
            <div>
            </div>
        </div>
    </div>
</div>
    );
}

Call or access nested const inside variable in Javascript

i’m newbie in javascript but i need help, can i access or call from outside a variable inside const block ? here are the code :

  let selectedElement = _element.layer;
  const layerAttributes = {
    trait_type: _element.layer.trait,
    value: selectedElement.traitValue,
    ...(_element.layer.display_type !== undefined && {
      display_type: _element.layer.display_type,
    }),
  };
  console.log(layerAttributes);
  if (
    attributesList.some(
      (attr) => attr.trait_type === layerAttributes.trait_type
    )   
  )
    return;
  attributesList.push(layerAttributes);

};

I need to access layerAttributes from outside variable or const block, just in example access from console.log , inside block the console.log(layerAttributes); is working, but when i access from outside variable block is not working, any suggestion ?

Thanks in advance.

Code for Dummies: How to Make My Button Go?

Building out a page using DNN for my job, I don’t like their shortcode button options, trying to code one myself. Main importance, I don’t know how to code from scratch. I can jack other code together for a functional element, usually.

Code below (alternatively, Codepen) is as far as I’ve gotten. I want a blue button, white text, and a white hover action, got that far. My issue is in getting the button to GO. I substituted a link to Facebook instead of our site. Really, I just want an easy fill in the blank code we can drop into any block on the site to quickly change colors, link, and shown text. I feel like I’m close, but not quite there. Any suggestions on making my button go??

        body {
          padding-left: 100px;
        }
    
        input#go {
          background-color: #4c9ed9;
          color: #ffffff;
          padding: 20px 40px;
          border: 1px solid #111;
        }
    
        input#go:hover {
          background-color: #ffffff;
          color: #4c9ed9;
          border: 1px solid #111;
        }
    <html>
    
    <head>
      <title>MK Button 2</title>
    </head>
    
    <body>
      <form>
      <input type="button" id="go" onclick="window.location.href='https://www.facebook.org';" value="Register">
      </form>
        </body>
    
    </html>

Reload page onSubmit in React.js

I want my React.js page to reload after hitting the submit button. This is because I put new entries into my database and once submitting was successful, I want to request new data from the database and display them.

import React, {useEffect, useState} from 'react';
import axios from "axios";

const Questionnaire = () => {
    const [questions, setQuestions] = useState({questions: []});
    const [updated, setUpdated] = useState(false); // approach 1
    // let updated = false // approach 2

    const onSubmit = async (answeredQuestions) => {
        let data = Object.values(answeredQuestions)
        
        axios.put('http://localhost:8000/questionnaire/', data)
            .then(response => {
                // setUpdated(false); // approach 1
                // updated = !updated; // approach 2
            }
        );
    };

    useEffect( () => {
        axios.get('http://localhost:8000/questionnaire/', {})
            .then((response) => {
                setQuestions({"questions": response.data});
                setUpdated(true); // approach 1
            });
    }, [updated]);

    return (
        <> 
            <Questions questions={questions} onSubmit={onSubmit} />
        </>
    );
}

export default Questionnaire;

I want the useEffect() to be executed immediately after getting the response from axios.put() so that the new questions can be requested and displayed to the user.
I tried out two approaches, but either axios.get() was executed twice or the re-render didn’t work properly.

I appreciate your support!

Can’t use Material UI in external library with webpack/rollup/react

I’m working on a component library that wraps some of the MaterialUI components and implements others to be used in a larger project. While setting up the library I had to setup webpack in order to be able to import and bundle images and css files in my library.

This library is located nested in the folder of the main project, where I add it as a dependency with npm i ./shared/path_to_library. this seems to work fine, since the typescript is working correctly and the npm start gives me no error. Then when I open it in a browser I get the following error page:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

But this error only occurs if I try to use any component from @mui/material inside my library. Exporting handmade components and using them in the main project works fine, but using any material component wrapped by my own component and then using it in the project brings me to this error. I also tried to move from webpack to rollup but I ended up getting the same problem.

Here are my config files for webpack and rollup:

rollup.config.js

import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "@rollup/plugin-typescript";
import dts from "rollup-plugin-dts";

const pkg = require("./package.json");

const config = [
  {
    input: "src/index.ts",
    output: [
      { file: pkg.main, format: "cjs", sourcemap: true },
      { file: pkg.module, format: "esm", sourcemap: true },
    ],
    plugins: [
      resolve(),
      commonjs(),
      typescript({ tsconfig: "./tsconfig.json" }),
    ],
  },
  {
    input: "lib/esm/types/index.d.ts",
    output: [{ file: "lib/index.d.ts", format: "esm" }],
    plugins: [dts()],
  },
];

export default config;

webpack.config.js

const path = require("path");

module.exports = {
  entry: "./src/index.ts",
  mode: "development",
  output: {
    path: path.resolve(__dirname, "lib"),
    filename: "[name].js",
    libraryTarget: "umd",
    library: "my-core-library",
    umdNamedDefine: true,
  },
  devtool: "source-map",
  module: {
    rules: [
      {
        test: /.css?$/,
        use: ["style-loader", "css-loader"],
        exclude: /node_modules/,
      },
      {
        test: /.tsx?$/,
        use: ["babel-loader", "ts-loader"],
        exclude: /node_modules/,
      },
      {
        test: /.(png|jpe?g|gif|svg)$/,
        use: ["file-loader"],
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: [".ts", ".tsx", ".js", ".jsx"],
  },
  externals: [
    {
      react: "react",
      "react-dom": "react-dom",
      "@mui/material": "@mui/material",
      "@emotion/react": "@emotion/react",
      "@emotion/styled": "@emotion/styled",
      "@mui/lab": "@mui/lab",
    },
  ],
};

I’m running out of ideas 🙁

ESLint with Airbnb style guide does not work for all rules

Recently I started checking all various JavaScript style guides and I liked Airbnb the best.

However, when I configured ESLint with Airbnb style guide, I noticed that some rules defined in their docs are not checked at all. For example:

  1. Group all your consts and then group all your lets.
  2. Use shortcuts for booleans, but explicit comparisons for strings and numbers.
  3. Use // for single line comments. Place single line comments on a newline above the subject of the comment. Put an empty line before the comment unless it’s on the first line of a block.

So, if you take this code as an example:

const array = [1, 2, 3, 4, 5];
let foo = 'foo';
const bar = 'bar';

if (array.length) {
  console.log('Foo:', foo);
  // Changing foo
  foo = 'baz';
}

The linter should throw 3 errors:

  1. I didn’t group all consts and then all lets, I defined them sequentially.
  2. I didn’t use explicit comparation in if statement – array.length > 0
  3. I didn’t add new line before my comment

However, linter does not throw any error. Does that mean that eslint-config-airbnb-base does not include all rules that Airbnb style guide suggests?

How do you reset Vimeo embed playback on hover?

I’m trying to figure out how to replay the Vimeo video each time you hover over the box. But the problem is that it just plays all the way when you hover the first time.

It looks like it may be possible to do this with Froogaloop, but I’m not sure how to implement it in the current javascript code.

Is there a way to restart the video each time on hover?

Here’s what I have so far. Any help would be awesome!

HTML

<section class="full video-downloads gray-bg">
    <div class="video-downloads-wrapper" video-rollover="1">
        <div class="video-item">
            <div class="download-wrap video-rollover black-bg" data-video="642263700">
            <p style="color:#ffffff;display:grid;justify-content:center;align-items:center;width:100%;">rollover this</p>
            </div>
        </div>
    </div>
</section>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://player.vimeo.com/api/player.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/froogaloop.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.8.0/gsap.min.js"></script>

CSS

.video-item .download-wrap a{
          display: flex;
        }
        .video-item img{
          max-width: 100%;
          height: 305px;
          object-fit: contain;
          width: 100%;
          border: 1px solid #424242;
        }
        .video-item .video-rollover i span{
          font-family: myriad-pro, sans-serif;
          font-size: 12px;
          text-transform: uppercase;
          margin-top: 10px;
        }
        .video-item .video-rollover{
          position: relative;
          margin-bottom: 10px;
          display: flex;
          cursor: pointer;
          width:350px;
          height:350px;
          background: black;
        }
        .video-reveal {
          position: fixed;
          width: 350px;
          height: 200px;
          top: 0;
          left: 0;
          pointer-events: none;
          opacity: 0;
          background: #000000;
          border: 1px solid #424242;
        }
        .video-reveal-clip iframe{
          width: 100%;
          height: 100%;
          object-fit: contain;
        }
        .video-reveal-inner,
        .video-reveal-clip {
          width: 100%;
          height: 100%;
          position: relative;
        }
        .video-downloads-wrapper{
          color: #ffffff;
          display: grid;
          grid-template-columns: repeat(auto-fit, minmax(241px,1fr));
          gap: 20px;
        }

JS

{ // Video Rollover Function
    const mapNumber = (X,A,B,C,D) => (X-A)*(D-C)/(B-A)+C;
    // from http://www.quirksmode.org/js/events_properties.html#position
    const getMousePos = (e) => {
        let posx = 0;
        let posy = 0;
        if (!e) e = window.event;
        if (e.pageX || e.pageY) {
            posx = e.pageX;
            posy = e.pageY;
        }
        else if (e.clientX || e.clientY)    {
            posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
            posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
        }
        return { x : posx, y : posy }
    }
    // Generate a random float.
    const getRandomFloat = (min, max) => (Math.random() * (max - min) + min).toFixed(2);

    // Plug in video id into iframe
    class videoHover {
        constructor(el) {
            this.DOM = {el: el};
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'video-reveal';
            this.DOM.reveal.innerHTML = `
                <div class="video-reveal-inner">
                    <div class="video-reveal-clip">
                    <iframe id="${this.DOM.el.dataset.video}" class="video-iframe" src="https://player.vimeo.com/video/${this.DOM.el.dataset.video}?h=53a1e27e93&amp;badge=0&amp;autopause=0&amp;autoplay=1&amp;loop=1&amp;muted=1" width="1080" height="1350" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" title="video-test"></iframe>
                    </div>
                </div>`;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealInner = this.DOM.reveal.querySelector('.video-reveal-inner');
            this.DOM.revealInner.style.overflow = 'hidden';
            this.DOM.revealVideo = this.DOM.revealInner.querySelector('.video-reveal-clip');
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showVideo();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideVideo();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showVideo() {
            TweenMax.killTweensOf(this.DOM.revealInner);
            TweenMax.killTweensOf(this.DOM.revealVideo);

            this.tl = new TimelineMax({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    TweenMax.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .add('begin')
            .add(new TweenMax(this.DOM.revealInner, 0.2, {
                ease: Sine.easeOut,
                startAt: {x: '-100%'},
                x: '0%'
            }), 'begin')
            .add(new TweenMax(this.DOM.revealVideo, 0.2, {
                ease: Sine.easeOut,
                startAt: {x: '100%'},
                x: '0%'
            }), 'begin');
        }
        hideVideo() {
            TweenMax.killTweensOf(this.DOM.revealInner);
            TweenMax.killTweensOf(this.DOM.revealVideo);

            this.tl = new TimelineMax({
                onStart: () => {
                    TweenMax.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    TweenMax.set(this.DOM.el, {zIndex: ''});
                    TweenMax.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add('begin')
            .add(new TweenMax(this.DOM.revealInner, 0.2, {
                ease: Sine.easeOut,
                x: '100%'
            }), 'begin')
            
            .add(new TweenMax(this.DOM.revealVideo, 0.2, {
                ease: Sine.easeOut,
                x: '-100%'
            }), 'begin');
        }
    }

    // Attach video to cursor on hover
    [...document.querySelectorAll('[video-rollover="1"] .video-rollover, a[video-rollover="1"]')].forEach(link => new videoHover(link));

}

LINK TO CODEPEN
https://codepen.io/tampham/pen/ExwaJWX

Why isn’t pushed() array being shown in console? [duplicate]

I am adding a String and an array to an already created array myArray using push(). However, when I print the updated myArray in the console after pushing(), I only see the String added to myArray, not the added array, in myArray‘s content. (The content is seen when I press the little carrot next to the myArray array in the console.) The added array isn’t being taken account in the length of the updated myArray either. Why is this?

Note: The added array isn’t shown to be in the updated myArray, but when I pop() the last element from the updated myArray, the array that was added (the one of interest) is returned. So it seems to be stored in myArray but not technically?? What is going on?

My code:

var myArray = [1, 2, 3];
myArray.push('Jacob', ['Brandy', 2]);
console.log(myArray);

var removedValue = myArray.pop();
console.log(removedValue);

Current Output:

Array(5) [ 1, 2, 3, "Jacob", (2) […] ]
    0: 1
    1: 2
    2: 3
    3: "Jacob"
    length: 4
    <prototype>: Array []

Expect:

Array(5) [ 1, 2, 3, "Jacob", (2) […] ]
    0: 1
    1: 2
    2: 3
    3: "Jacob"
    4: ["Brandy", 2]
    length: 5
    <prototype>: Array []

Remove element if Safari/iOS

I am creating a website where I have created a fullscreen button, which can be kind of useful on mobile – at least for my website. This is done through some Javascript. However, if I’m not mistaken, this fullscreen mode does not work in Safari (or maybe just iOS in general). So basically, I would like to remove the button in those cases, since it doesn’t work for them.

Can this be accomplished with CSS, or do I need some Javascript as well ?

NextJS i18n – Locale getting undefined

I’m trying to migrate my website to NextJS, and I’m having trouble to do some internationalization.

I’m following the tutorial from Documentation itself, but my locale in the inspector is coming up as undefined.

What i’m doing wrong?
I’m using the latest version of nextJS.

Im trying to get some info from console.log.

console.log("Locale: " + locale);
console.log(router);

and it prints:
enter image description here

next.config.js

module.exports = {
    i18n: {
        locales: ['en-US', 'pt-BR'],
        defaultLocale: 'pt-BR',
    },
}

/pages/index.js

import Head from 'next/head'
import { useRouter } from 'next/router'

import pt from '../locale/index/pt'
import en from '../locale/index/en'

export default function Home() {

    const router = useRouter();
    const { locale } = router;
    const t = locale === 'pt' ? pt : en;

    return (
        <div className="container">
            <Head>
                <title>{t.title}</title>
            </Head>
        </div>
    )
}

/locale/pt.js

export default {
    title: "Teste Portugues."
}

/locale/en.js

export default {
    title: "Test English"
}

Some random info:
NextJS Version: 12.0.4
Chrome Version: 96.0.4664.55
Node Version: 17.0.1

Ethers decode/get information about collection and token from Etherscan transaction

I am using Ethers and I am listening to Open Sea contract to get latest sales. The problem that I know how to get transaction hash, how to get price etc. but I do not know how can I get collection details and ID of the token that was sold. Is it even possible to get it? Where is it stored. I see something like this:

  args: [
    '0x0000000000000000000000000000000000000000000000000000000000000000',
    '0x57caab574ab5d945029c09beac5bfd9f39f669513c7d4dea0941a96c1017a80e',
    '0x1D6F2F0356B3DefAdf14b1a0F8A3Dcda89367D68',
    '0x78f0269f5b1Ca914c8c58993f41181f89e212B27',
    BigNumber { _hex: '0x1bc16d674ec80000', _isBigNumber: true },      
    '0x5c5321ae45550685308a405827575e3d6b4a84aa000000000000000000000000',
    buyHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
    sellHash: '0x57caab574ab5d945029c09beac5bfd9f39f669513c7d4dea0941a96c1017a80e',
    maker: '0x1D6F2F0356B3DefAdf14b1a0F8A3Dcda89367D68',
    taker: '0x78f0269f5b1Ca914c8c58993f41181f89e212B27',
    price: BigNumber { _hex: '0x1bc16d674ec80000', _isBigNumber: true },
    metadata: '0x5c5321ae45550685308a405827575e3d6b4a84aa000000000000000000000000'
  ]

I know I can get price from it. But where is information about collection or collection address or something? Is it stored in metadata? If yes how can I decode it?

I know that I can go to transaction like here – https://etherscan.io/tx/0xe29462cd6cd6cfcf2f05a3139de1aead4fc9e84d8966ad9a5227b996eb90c33d but I want to get it from contract listener in ethers.