Hiding the global javascript context with my own

I’m reading the MDN web docs on globalThis.

It says:

Note: The globalThis property is configurable and writable so that
code authors can hide it when executing untrusted code and prevent
exposing the global object.

I want to do exactly this, creating a sandbox of sorts so that a function can be written which accesses variables in the sandbox without needing to prefix it with anything and also preventing any variables not in the sandbox object from being accessible – like an improved alternative to the deprecated “with” construct which will fail to find anything not in the global context I define.

I wrote a proof of concept running in an ES6 module:

let myContext = { a:1, b:2 }
let f = ()=> {
    let savedGlobal = globalThis
    globalThis = myContext
    let ret = a+b
    savedGlobal.globalThis = savedGlobal
    return ret
}
f()

As an explanation, I am first saving the current value of globalThis to a local variable, as I expect that otherwise the original value won’t be accessible from my new global context. Then I hide the existing global context by overwriting it with my own, which the documentation seems to suggest is possible. Then I try to assign a local variable to the result of a+b which should be 1+2 = 3, then I restore the global context from the local saved value and return the value I calculated.

If I log the variables, I see that globalThis is the Window object before I assign to it, and it’s myContext after, but I still get a reference error “a is not defined” despite the fact that I would expect that it would find it in the now global context “myContext”. It also successfully ran the console.log despite the fact that I would expect it to no longer be visible after reassigning globalThis.

Behaviour of setInterval with respect to Event loop

Trying to figure out why the output of the following code is the way it is

console.log("Start");

setInterval(function() {
    console.log("setInterval");
}, 5000);

let date = new Date();
while(new Date() - date <= 10000) {}

console.log("End");

Actual Output

  • Start
  • …. 10 seconds ….
  • End
  • setInterval
  • …. 5 seconds ….
  • setInterval

Since the while block blocks the main thread for 10 seconds, the callback function of setInterval should have been pushed twice in the task queue since it has a timer of 5 seconds. So the output should have been

Expected Output

  • Start
  • …. 10 seconds ….
  • End
  • setInterval
  • setInterval
  • …. 5 seconds ….
  • setInterval

In TradingView widget chart, how can I know when the chart is ready and data is loaded?

I’m adding a TradingView chart to my website, using Javascript.
I want to know when the chart is loaded and the data was loaded successfully, and print the success status in a dedicated textbox.

My code doesn’t work, I added a onChartReady callback, but it never get there, even when the chart is loaded successfully.

Here is the relevant code I created:

    widget = new TradingView.widget({
        "width": "100%",
        "height": 500,
        "symbol": symbol,
        "interval": "D",
        "timezone": "Etc/UTC",
        "theme": "light",
        "style": "1",
        "locale": "en",
        "datafeed": "Datafeed",
        "toolbar_bg": "#f1f3f6",
        "enable_publishing": false,
        "allow_symbol_change": true,
        "container_id": "tradingview_widget",
    });
    
    widget.onChartReady(function () {
        chartLoaded = true;
        document.getElementById('result').textContent = "Chart loaded successfully!";
    });

I also tried to put the onChartReady inside the new TradingView.widget block, but it still doesn’t work.

Any ideas what should I change in order to make it work?

Thank you

Webkitspeechrecognition not working on chrome [closed]

I used webkitspeechrecognition for speech to text converter project but webkitspeechrecognition is working only in bing and not working in chrome. not working it is working but is active for only a certain time interval and after that the mic is turning off. Please help!!

tried adding set time interval, also tried exporting this line

const recognition = new SpeechRecognition();

The image created by SigaturePad does not save the writing, it only saves the background [closed]

I’m using the signature-pad lib with livewire and alpine.

I put the canvas element in a modal and the element is rendered without problems. For example, I put the background in blue and the handwriting in yellow.

The problem happens when I save the image. When it is sent to the component and saved in the application, the image only has a blue background and the yellow writing is not passed when generating the saved image, it just leaves a blue image.

view

<x-jet-dialog-modal wire:model="showJetstreamModalCreate" maxWidth="lg"
        class="modal-dialog-centered modal-dialog-scrollable">
        <x-slot name="title">Nova Anamnese</x-slot>
        <x-slot name="content">
            <div class="modal-body">
                
                <div class="mt-2">
                    Solicitar assinatura:
                            <div x-data="signaturePad()">
                                <canvas x-ref="signature_canvas" style="border: 1px solid #cecaca;"></canvas>
                            </div>
    
                </div>
            </div>
        </x-slot>
        <x-slot name="footer">
            <x-jet-secondary-button wire:click="$toggle('showJetstreamModalCreate')">
                Fechar
            </x-jet-secondary-button>
            <x-jet-button wire:click.prevent="create" wire:loading.remove>
                Salvar Anamnese
            </x-jet-button>
            <x-jet-button wire:loading wire:target="create">
                Processando...
            </x-jet-button>
        </x-slot>
    </x-jet-dialog-modal>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/signature_pad.umd.min.js"></script>
    <script>
    
        document.addEventListener('alpine:init', () => {
            Alpine.data('signaturePad', () => ({
                signaturePadInstance: null,
                init() {
                    this.signaturePadInstance = new SignaturePad(this.$refs.signature_canvas, {
                        minWidth: 5,
                        maxWidth: 10,
                        backgroundColor: 'rgb(5,5,255)',
                        penColor: "rgb(255, 255, 25)"
                    });
                    @this.set('signature', this.signaturePadInstance.toDataURL('image/png'));
                }
            }))
        })
    </script>

component

<?php
    
    namespace AppHttpLivewirePatientAnamnesis;
    
    use IlluminateSupportStr;
    use LivewireComponent;
    use IlluminateSupportFacadesStorage;
    
    class Create extends Component
    {
        public $signature;
    
    
        public function render()
        {
            return view('livewire.patient.anamnesis.create');
        }
       
    
        public function create(){
            Storage::disk('public')->put('signature.png', base64_decode(Str::of($this->signature)->after(',')));
    
        }
    
    }

I removed a lot of code from both files, sending only what is necessary for the functionality I am showing.

As you can see, I have the canvas element, and I capture the signature with alpine to send to the Livewire component, but only the background is displayed in the generated image without displaying the writing.

How to use merge-stream with ES6 imports?

I’m using Gulp 5, and I converted my Gulpfile to use modules instead of CommonJS. It mostly works but I’m having trouble with the merge-stream package. Here’s the minimal version of my original code:

const mergeStream = require('merge-stream');

function js() {
    let stream1 = src('example.js');
    let stream2 = src([/* multiple files */])
        .pipe(concat('global.js'));

    return mergeStream(stream1, stream2)
        .pipe(terser())
        .pipe(rev())
        .pipe(dest(jsPath))
        .pipe(rev.manifest('rev-manifest.json'))
        .pipe(dest(jsPath));
}

exports.js = js;

I converted it to use modules like so:

import mergeStream from 'merge-stream';

// same js() function as above

export {js};

It should output example-abc123.js and global-def456.js files, and a rev-manifest.json file listing both of those. The build runs without errors, but only the first file is processed (example.js). So it doesn’t appear to be merging the streams.

I’ve also tried doing this which I saw in another question, but it’s no different:

import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const mergeStream = require('merge-stream');

How Can I Disable Lightningchart Scrolling Heatmap Automatic Color Transition

I am using a scrolling heatmap with several scrolling grid series to visualize data. However, there is a gap between the series where no data exists. I do not want anything to be drawn in these gaps, but the scrolling heatmap automatically fills them with colors. When new data arrives, these automatic colors are corrected based on the data, but if I stop feeding data to a specific series, the automatically drawn colors remain visible on the heatmap.

How can I disable this automatic drawing? (I believe these automatic drawings are intended to provide a smoother heatmap view, but I don’t want a smooth heatmap). Is there a configuration to turn this off?

I am using @lightningchart/lcjs version ^6.0.0. I have forked example from GitHub and created a new branch to recreate the issue. My code is accessable here: https://github.com/gurcankavakci/lcjs-example-0803-scrollingHeatmap/tree/issue-1-demo

I have also attached a screenshot illustrating the issue. In the screenshot, The series for 5 seconds with a 1-second space between them can be seen. The blue rectangles represent the actual data, while the green ones are not. These spaces should appear black.

How can I ensure these gaps are black (i.e., no drawing, just the background color)?

enter image description here

React Native (Reanimated) – Texts alternation in a loop, with fade effect

I’m trying to implement an animation in React Native using the react-native-reanimated library, where two texts alternate visibility with a fade-in and fade-out effect. The desired behavior is that only one text is visible at a time, with the following sequence:

  1. Initial State:
text1 opacity = 1 (visible)
text2 opacity = 0 (invisible)
  1. After 3500 ms:
text1 fades out over 500 ms.
Immediately after text1 fades out, text2 fades in over 500 ms.
  1. After 3500 ms:
text2 fades out over 500 ms.
Immediately after text2 fades out, text1 fades in over 500 ms.
  1. Repeat the sequence indefinitely.

I tried something like this:

import { useCallback, useEffect } from "react";
import {
  useAnimatedStyle,
  useSharedValue,
  withDelay,
  withRepeat,
  withSequence,
  withTiming,
  Easing,
} from "react-native-reanimated";

/**
 * Handles the animations of the fading texts.
 *
 * @returns {import("@atoms/texts/types/texts.d").FadeTextsAnimationInterface}
 *   An interface for accessing the members of the hook.
 */
export default function useFadeTextsAnimation() {
  const text1Opacity = useSharedValue(1);
  const text2Opacity = useSharedValue(0);

  const text1AnimatedStyle = useAnimatedStyle(() => ({
    opacity: text1Opacity.value,
  }), []);

  const text2AnimatedStyle = useAnimatedStyle(() => ({
    opacity: text2Opacity.value,
  }), []);

  /**
   * Triggers the animation for both texts, creating a loop where the texts
   * fade in and out sequentially.
   *
   * @returns {void}
   */
  const animate = useCallback(() => {
    const timingConfig = { duration: 500, easing: Easing.linear };

    text1Opacity.value = withRepeat(withSequence(
      withDelay(6000, withTiming(0, timingConfig)),
      withDelay(7000, withTiming(1, timingConfig))
    ), -1);

    text2Opacity.value = withRepeat(withSequence(
      withDelay(6500, withTiming(1, timingConfig)),
      withDelay(6000, withTiming(0, timingConfig)),
      withDelay(500, withTiming(0, { duration: 0 }))
    ), -1);
  }, [text1Opacity, text2Opacity]);

  useEffect(() => {
    animate();
  }, [animate]);

  return { text1AnimatedStyle, text2AnimatedStyle };
};

This is working fine, but, sometimes, both texts overlap.

How to avoid YAML lib to add new blank line after a variable with null value

I have a node script to modify content of docker compose file (yaml file). I used yaml lib to parse from file:

const fs = require('fs')
const yaml = require('yaml')

const compose = yaml.parseDocument(fs.readFileSync(file, 'utf-8'), {merge: true})

... do something to modify content...

fs.writeFileSync(file, yaml.stringify(compose, {
  nullStr: '',
  simpleKeys: true,
  lineWidth: 0
}))

after I write the updated content back to the file, there is no problem except it added new blank line after each null value (attached file)

enter image description here

I don’t know the reason why it do it (maybe the variable with null value is the reason). it’s default behaviour? How I can avoid it?

Capturing console and not affecting the log line

I am working on a class that will be used for console logging, but with every call a new object will be added to the console history array. I created a class ConsoleLogger


    export class ConsoleLogger {
      private static instance: ConsoleLogger | null = null;

      private logs: LogEntry[] = [];
      private maxLogs = 50;

      public static getInstance(): ConsoleLogger {
        if (this.instance === null) {
          this.instance = new ConsoleLogger();
        }
        return this.instance;
      }

      private addLog(type: LogType, message: string): void {
        if (this.logs.length >= this.maxLogs) {
          this.logs.shift();
        }
        this.logs.push({ type, message, timestamp: new Date() });
      }


      public log = (function () {
        return Function.prototype.bind.call(console.log, console);
      })();

 public error = (function () {
    return Function.prototype.bind.call(console.error, console);
  })();
}

I can use it in .vue and .ts files, with e.g.
ConsoleLogger.getInstance().log('console msg'); and the line information is refering correctly, to my .ts file/.vue file. I am not sure how can I connect addLog line to each of these methods, as I cannot refer to this.addLog in this exact log function, and if I try to change the log method that I will make this.addLog available, then I am losing the proper line information as it starts refering to the line in my consoleLogger.ts.

How can I not lose the line information and also use my addLog method properly?

Why does TypeScript go out of its way to be a feature packed transpiler? [closed]

TypeScript is meant to add static typing to JavaScript.
This means

  • Static types. Explictily add types in your code.

  • Turns JS from weakly typed (type coercion etc.) to strongly typed.

  • Compile time error handling (errors related to types).

  • Enhanced dev tooling e.g. code completion, error highlighting.

All of these features are in the scope/relation to Types. Even options in tsconfig.json such as:

  • “strict”

  • “noUncheckedIndexedAccess”

  • “checkJs”

are all in scope/relation to types. This makes sense to me.

But features such as

  • Transpiling one version of ECMAScript code to another “target”

  • Transpiling one module system code to another “module”

  • Supporting/easing interop between module systems, “enableEsModuleInterop”

are not in scope/relation to “types”.

While these are great features, wouldn’t it be better to separate these features out into their own tools? This enables TS to just be a tool to support types. tsconfig.json would also really be simple.
A separate build tool can be used for the other features.

IMO, this is a better separation of concerns. TypeScript will then just be what its name implies, a tool to add type support for JS.

I understand that things are easier when all features are supported by a single tool, reducing the need for more build phases and tools, but I’d take the separation of concerns over a overly packed tool.

How to modify grid layout algorithm so it puts 2, 4, 6, 8, etc. fewer elements at the end rows?

Building off @trincot’s answer to How to chunk array into nice grid of rows and columns, where columns always line up (all rows are even, or all are odd)? how can we modify the goal slightly to allow for trailing rows to still be odd (if the starting rows were odd), or still be even (if starting rows were even), but instead of only allowing “2 fewer” elements in each trailing row, like this:

x x x x x x x x
  x x x x x x
    x x x x
      x x

(Here, each row has 2 fewer than the last). Instead of the 2-fewer approach, what if we just made it so it could have 2, 4, 6, 8 (multiple of 2) fewer? So something like this would be acceptible:

x x x x x x x x
x x x x x x x x
    x x x x

Or even this:

x x x x x x x x
x x x x x x x x
      x x

How could you modify the linked algorithm (copied here), to make that possible?

function distribute(length, maxColumns) {

    function recur(dp, length, width) {
        if (length == 0) return [];
        if (length < width - 2 || width <= 0) return false;
        if (dp[width].has(length)) return false;
        dp[width].add(length);
        for (let i = 0; i < 2; i++) {
            let result = recur(dp, length - width, width);
            if (result) return [width, ...result];
            width -= 2;
        }
        return false;
    }
    
    
    if (length <= maxColumns) return [length];
    const dec = 2 - length % 2;
    maxColumns -= maxColumns % dec;
    const dp = Array.from({length: maxColumns + 1}, () => new Set());
    for (let width = maxColumns; width > 0; width -= dec) {
        const result = recur(dp, length - width, width);
        if (result) return [width, ...result];
    }
    return false;
}

const tests = [
    [1, 5],
    [6, 5],
    [7, 6],
    [8, 6],
    [9, 6],
    [10, 6],
    [11, 6],
    [12, 6],
    [13, 6],
    [14, 6],
    [17, 7],
    [17, 6],
    [211, 16]
];

for (const [length, maxColumns] of tests) {
    const result = distribute(length, maxColumns);
    console.log(length, maxColumns, JSON.stringify(result));
}

CSP report-to URL in an authenticated context

I am trying to use the report-to CSP directive to report policy violations. This works well if the specified endpoint is a public (non-authenticated) URL. However, I would like the reporting URL to require a JWT (all CSP protected pages are in an authenticated context). Is there a way to specify the Bearer header when the browser sends the report?

Is it possible to display videos not only from YouTube Vimeo, or vzaar in owl.carousel.js?

I need to display a video on the detailed product page, the link to which is specified when creating the product, the fact is that the videos are stored in the NAS. Directly passing the url I get an error, is there any way to display the video?

<div id="owl-images" class="owl-carousel owl-theme">

  {% if object.video %}
    <div class="item-video">
       <a class="owl-video" href="{{ object.video }}"></a>
    </div>
  {% endif %}

  {% for item in object.ObjectImagess if item %}
    <a class="imagelightbox" title="" href="/images/objects/{{ object.id }}/{{ item.path }}" data-exthumbimage="/images/objects/{{ object.id }}/{{ item.path }}" data-sub-html="<h4>{{ object.typeName }} {{ object.title }}</h4><small>от</small><b>{{ object.priceMin|number_format(0,'.',' ') }}</b>{{ base.currency }}">
      <div class="item text-center" style="background-image:url('/images/objects/{{ object.id }}/{{ item.path }}')"></div>
    </a>
  {% endfor %}
</div>

I tried to rewrite the regular expression specified in js owl but probably did it incorrectly