JointJS is not rendering HTML elements with scroll on Safari

In my Vue app, I’m using JointJS to create a process diagram.

Everything works fine on Chrome – both locally and in the testing environment.
On Safari, it also works fine locally, but after being deployed to the testing environment – styles break.

There are 2 elements in the process (we can call them “Input” and “Output”), which contain a list of items inside. In case there are too many items, I want to be able to scroll – therefore, I’ve added overflow-y: auto; to the div styles. Instead, those items are rendered in the top-left corner of the canvas for some reason.

enter image description here

I’ve read that there are some issues with overflow-y: auto; on Safari, so I’ve changed it to overflow-y: scroll; – but it doesn’t help. Seems like for some reason scroll doesn’t work – just on Safari & testing environment… any idea how to solve it?

Everything works well when I’m removing overflow-y: scroll; line:
enter image description here

… or, keeping it, but removing some element from the list, so it prevents overflowing:
enter image description here

Unfortunately, scrolling is essential here.

Here’s a function responsible for generating those 2 elements:

const generateMassDataHtml = (title, massData = null, totalMass = null) => `
    <div style="height: ${unitOpHeight}px; padding: 10px 16px; width: 100%; overflow-y: ${isSafari ? 'scroll' : 'auto'};">
      <p style="text-align: center; ${textLabelStyle} font-weight: 600; margin-bottom: 4px;">${title}</p>
      <hr style="border: none; border-top: 1px solid #e0e0e0; margin: 0 0 10px 0;">
      ${
        this.hasResults && massData && totalMass
          ? Object.entries(massData).map(([name, mass]) => `
              <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; margin-bottom: 8px;">
                <p style="text-align: center; ${textLabelStyle} font-weight: 500; margin-bottom: 0;">${name}</p>
                ${
                  this.isFree && mass.component
                    ? `<span style="${getHiddenValueBlockStyle()}"></span>`
                    : `<p style="text-align: center; ${textValueStyle} margin-bottom: 0;">${mass.value.toLocaleString('en-US', { maximumFractionDigits: 0 })} kg</p>`
                }
              </div>
            `).join('') + `
              <p style="text-align: center; ${textLabelStyle} font-weight: 500; margin-bottom: 0;">Total Mass:</p>
              <p style="text-align: center; ${textValueStyle}; margin-bottom: 0;">${totalMass.toLocaleString('en-US', { maximumFractionDigits: 0 })} kg</p>
            `
          : this.hasConfiguration
            ? `<p style="text-align: center; ${textLabelStyle} margin-top: 20px;">No results can be calculated, please reconfigure the process parameters</p>`
            : `<p style="text-align: center; ${textLabelStyle} margin-top: 20px;">No process parameters configured</p>`
      }
    </div>
  `

const input = new joint.shapes.standard.Rectangle()
  input.resize(unitOpWidth, unitOpHeight)
  const inputX = xStart + (stepWidth * (elementsCount % unitsPerRow))
  const inputY = yStart + (Math.floor(elementsCount / unitsPerRow) * (unitOpHeight + yGap))
  input.position(inputX, inputY)
  elementsCount++
  input.markup = [
    { tagName: 'rect', selector: 'body' },
    {
      tagName: 'foreignObject',
      selector: 'fo',
      attributes: { width: unitOpWidth, height: unitOpHeight },
      children: [
        {
          namespaceURI: 'http://www.w3.org/1999/xhtml',
          tagName: 'div',
          selector: 'htmlContent',
          attributes: { style: unitOpCardStyle }
        }
      ]
    }
  ]
  const inputHtml = generateMassDataHtml('DSP Input', this.hasResults ? this.massData.input : null, this.hasResults ? this.results.input.mass : null)
  input.attr({
    body: { fill: '#fff', rx: 16, ry: 16, stroke: '#e0e0e0' },
    fo: { width: unitOpWidth, height: unitOpHeight },
    htmlContent: { html: inputHtml }
  })
  input.addTo(this.graph)

chartjs dynamically increase line sizing

I’m using chartjs for line charts, and I have this code I’m using to dynamically increase the thickness of the lines:

    $(document).on('change', ".line_width", function(e)
    {
        e.preventDefault();

        picked_width = $(this).val();

    $.each( charttest.config.data.datasets, function( index, value )
    {
        charttest.config.data.datasets[index].borderWidth = parseInt(picked_width);
    });

charttest.update();

});

It works but it also annoyingly increases the size of each legend at the top.

Is there a way to stop this? I assume I’m increasing the wrong variable with borderWidth.

Web Component causing Layout Shift

I’m creating a plain vanilla website, and many pages of my website has a component in common (a sidebar), so I created a Web Component to easily include in all pages.

The class of the component:

//sidebar/index.js

class Sidebar extends HTMLElement {
    connectedCallback() {
        if(!this.querySelector("div")) {
            this.innerHTML = 
               '<div id="sidebar" class="d-flex flex-column h-100 p-3 bg-body-tertiary">' +
               '    <a href="/admin/home" class="h4 text-decoration-none text-nowrap">Central Api</a>' +
               '    <hr>' +
               '    <ul class="nav nav-pills flex-column">' +
               '        <li class="nav-item">' +
               '            <a id="home" class="nav-link" href="/admin/home">Home</a>' +
               '        </li>' +
               '        <li class="nav-item">' +
               '            <a id="users" class="nav-link" href="/admin/users">Usuários</a>' +
               '        </li>' +
               '    </ul>' +
               '</div>';
            if(window.location.href.includes("/home")) {
                this.querySelector("#home").classList.add("active");
            } else if(window.location.href.includes("/user")) {
                this.querySelector("#users").classList.add("active");
            }
        }
    }
}

export const defineSideBar = () => {
    customElements.define("x-sidebar", Sidebar);
}

How the main script are imported:

<!-- index.html -->
<script type="module" src="main.js"></script>

And how the main script load the new component

//main.js

import { defineSideBar } from "../../../components/sidebar/index.js";

const app = () => {
    defineSideBar();

    //... more code here but not related
};

document.addEventListener('DOMContentLoaded', app);

The problem is that the component is causing Layout Shift.

Cumulative Layout Shift metric provided by browser Developer Tools

What I already tried:

  1. call the defineSideBar() directly inside main.js script instead inside app() expecting the web component to be defined early.

  2. prefetch/preload the script main.js script and sidebar/index.js expecting reducing the time to render the component.

  3. encapsulating the component with a fixed size div, this really reduced the Layout Shift to zero. But doesn’t look right to me, because the without being a web component, the sidebar don’t cause layout shift, so being a web component should do not cause either.

As I understand, the browser first load the component as an empty tag, draw de rest of page, and then when DOMContentLoaded event occurs the x-sidebar is rendered, causing layout shift. So, maybe there a way to draw the entire page in one time?

Finally, there something that I can do to avoid layout shift using web-components without encapsulating it with a fixed size div?

dont summarize JS function [closed]

// acsesProperty buttons display

let typeBtns = document.querySelectorAll("#typeBtn");
let acsesPropertys = document.querySelectorAll("#acsesProperty");

typeBtns[0].addEventListener("click", () => {
  acsesPropertys[0].classList.remove("d-none");
  acsesPropertys[1].classList.add("d-none");
  acsesPropertys[2].classList.add("d-none");
});

typeBtns[1].addEventListener("click", () => {
  acsesPropertys[1].classList.remove("d-none");
  acsesPropertys[0].classList.add("d-none");
  acsesPropertys[2].classList.add("d-none");
});

typeBtns[2].addEventListener("click", () => {
  acsesPropertys[2].classList.remove("d-none");
  acsesPropertys[1].classList.add("d-none");
  acsesPropertys[0].classList.add("d-none");
});

I’m write this code but it’s soo long this function control the typeBtns clicked show or hide acsesPropertys

Javascript document.write causes ASP 500 – Internal server error [closed]

This works just fine on an HTML page, but breaks ASP, any idea why?

<script>
this.load_Version=function(){
   if (globREG == "EUROPE"){
   document.write("<script src='EUROPE.js'></script>");
   }else{
   document.write("<script src='NORTHAM.js'></script>");
   }
}

load_Version();
</script> 

Even simply commenting out or even deleting the call load_Version(); results in a 500…

When I remove the code, console.log(globREG); confirms that the variable exists.

This produces the same 500 error:

<script>
function load_Version(){
   if (globREG == "EUROPE"){
   document.write("<script src='EUROPE.js'></script>");
   }else{
   document.write("<script src='NORTHAM.js'></script>");
   }
}

load_Version();
<script>

What could be the issue? Thanks.

Unable to get Stripe setup intents to work

Using Stripe’s “Elements” from @stripe/react-stripe-js I am doing the following flow for subscribing a user to a subscription via payment intents:

  1. Customer submits payment form and a request is made to the backend to create the setup intent:

    const setupIntent = await stripe.setupIntents.create({
      usage: 'off_session',
      customer: req.user.stripeCustomerId,
      payment_method_types: ['card']
    });
    
    return {
      statusCode: 200,
      body: JSON.stringify({
        clientSecret: setupIntent.client_secret,
        setupIntentId: setupIntent.id
      })
    };
    
  2. A payment method is created via the frontend Stripe Elements API:

      const cardElement = elements.getElement(CardNumberElement)!;
    
      const { paymentMethod, error: pmError } =
        await stripe.createPaymentMethod({
          type: "card",
          card: cardElement,
          billing_details: {
            address: {
              postal_code: postalCode,
            },
            name: fullName,
          },
        });
    
  3. I then update the setup intent with this newly created payment method id on the backend:

    const { paymentMethodId, setupIntentId } = req.body;
    
    const setupIntent = await stripe.setupIntents.update(setupIntentId, {
      payment_method: paymentMethodId
    });
    
    return {
      statusCode: 200,
      body: JSON.stringify({
        clientSecret: setupIntent.client_secret,
        setupIntentId: setupIntent.id
      })
    };
    
  4. I then confirm the card setup on the frontend, this takes me through the 3DS flow where I successfully confirm through the 3DS portal/ window:

      const { setupIntent, error: confirmError } =
        await stripe.confirmCardSetup(updatedSetupIntentData.clientSecret);
    
  5. I then attempt create a subscription:

    const subscription = await stripe.subscriptions.create({
      customer: req.user.stripeCustomerId,
      items: [
        { price: PRICE_ID } 
      ],
      expand: ['latest_invoice.payment_intent'] // helps with frontend handling
    });
    

This is where the issue comes, I get the following error in Stripe dashboard:

The cardholder began 3D Secure authentication but has not completed
it.

I don’t understand why it’s trying to run the 3DS authentication again. I thought that was already done in step 4?

How do modern browsers optimize reflows when handling complex CSS Grid layouts with dynamic JavaScript content?

I’m experimenting with a responsive dashboard layout using CSS Grid and dynamic components injected via JavaScript (e.g. charts, lists, panels). I noticed that sometimes the reflow is sluggish or inconsistent on scroll-heavy views.

How exactly do modern browsers (like Chrome or Firefox) schedule reflows when DOM nodes with display: grid change dimensions frequently?

Is there a threshold or batching technique browsers use before triggering layout recalculations?

Would will-change or contain: layout actually help in these cases?

Should I debounce resize or DOM injection operations for better performance?

Would love insights from anyone who’s worked on dashboard UIs or knows how browsers render large grid layouts efficiently.

Some issue with using MariaDB in Node.js

async function StoreData(id, name, age, city) {
    let Conn;
    try {
        Conn = await Pool.getConnection();
        let Query = await Conn.query(`insert into users
                                      values (?, ?), [id, name, age, city]);
        ]`);
        console.log(Query);
    } catch (error) {
        console.log(error);
    } finally {
        if (Conn) {
            Conn.end();
        }
    }
}

// POST method
App.post("/api/data", (req, res) => {
    let RequestData = req.body;
    console.log("Received data:", RequestData);

    res.status(200).json({message: "Data received successfully."});

    StoreData(RequestData.id, RequestData.name, RequestData.age, RequestData.city)
        .then((response) => {
            return response.json();
        })
        .then((data) => {
            console.log(data);
        })
        .catch((error) => {
            console.log(error);
        });
});

I wanna store some test data in MariaDB using JavaScript, Node.js and Express.js.
A button is on an HTML page and when it’s clicked, it’s gonna store these data fetched from a simple JavaScript file.
An ID, a Name, an Age and a City.
I think the syntax is kinda fine but ESLint is showing me error on the arguments of the function “StoreData()”.
It says: “id, name, age and city are defined but not used”.
But I put them in the template string of a query for storing the data in MariaDB.
Can somebody please help me figure this out?
Whether I’m writing the code wrongly or something is missing.

Thingsboard html widget

I used html widget to display an image with boxes inside it. I want to create an action to navigate to another state when I press the boxes. I created the action settings, but it did not work. I used navigate to new dashboard state action and custom action and both did not work.

Custon action code:

var $injector = widgetContext.$scope.$injector;
$injector.get(widgetContext.servicesMap.get('entityService')).getEntity(entityId.entityType, entityId.id)
    .subscribe(function(data) {
        console.log(JSON.stringify(data))
        console.log(entityName);
        if (data.name.includes("Warehouse 1")) {


            openDashboardStates('device_details', data);
        }


    });

function openDashboardStates(statedId, m) {
    var stateParams = widgetContext.stateController.getStateParams();
    var EID = m.id.id;
    var ENAME = m.name;


    var parID = {
        id: EID,
        entityType: "ENTITY_VIEW"
    };
    var preparam = {
        entityId: parID,
        entityName: ENAME,
        entityLabel: ENAME

    };
    var newparam = {
        selectedFreezer: preparam,
        targetEntityParamName: "selectedFreezer"
    };



    widgetContext.stateController.openState(statedId, newparam, false);
}

How to force mobile view using iframe?

I’ve been trying to embed a place view from Google Maps into my app, not just a static embed, but the full mobile-style place panel UI (the one with photo, tabs, reviews, buttons, etc. like you see on the Google Maps mobile site).

Tried this:

And set my browser or iframe to mobile dimensions (like iPhone 12 Pro) to trigger the mobile layout. Weird thing is — sometimes it actually works in dev tools, especially if I spoof the user agent.

BUT:

On real browsers it often refuses to load

X-Frame-Options: SAMEORIGIN blocks it completely in most cases

Seems like Google is actively preventing this?

I know the Embed API exists, but it’s too limited (no tabs, reviews, or ticket prices). I’m building a more immersive experience and really want that native-looking mobile UI for places.

So is there a better workaround for this problem?

Why does inject() return the value of a ref from a reactive object instead of a reactive reference?

I’m working with Vue 3’s Composition API, and I’m trying to provide a ref that is part of a reactive object. However, when I inject it in a child component, I get the raw value, not the reactive ref.

Here’s a simplified version of what I’m doing:

Parent component:

const position = ref("right");

const imageSetup = reactive({
  position
});

provide('position', imageSetup.position);

Child component:

const position = inject('position');

When I access position in the child, it’s just a plain string (“right”) instead of a ref. I lose reactivity.
If I provide(position) directly without wrapping it in a reactive object, the child receives a reactive ref and everything works fine. But I want to avoid declaring each state separately and instead use a single reactive object.
I’d like to be able to structure my shared state as a single reactive object and still be able to inject individual refs from it without losing reactivity.

Is there a way to keep the reactive structure and preserve the reactivity of injected refs?

onclick only fires once [closed]

I encountered a problem before this everything worked fine but when I corrected errors in the code and added select group my button stopped being processed, to be more precise it works once after which I need to reopen the window with the button (not reload but call the window using the same onclick event)

modalBody.innerHTML = `
<h3>Редактирование условия</h3>
<label class="modal-label">Заголовок:
  <input type="text" id="nodeTitleInput" value="${node.data.title || ''}" class="modal-input"/>
</label>
<div id="conditions-container" class="conditions-container"></div>
<div class="condition-form">
  <select id="conditionField" class="modal-select">
        ${availableFields.map(f => {
    return `
            <option id="conditionValue" value="${f.title}">${f.title}</option>
    <optgroup label="${f.label}" id="conditionValue">
        <option class="subtitle" id="conditionValue">${f.value}</option>
    </optgroup>
    <hr />`
}).join('')};


 modalBody.querySelector('#addConditionBtn').onclick = () => {
    const field = conditionFieldSelect.value;
    const type = conditionTypeSelect.value;
    const valInput = modalBody.querySelector('#conditionValue');
    const value = valInput ? valInput.value.trim() : null;

    if (!field || (type !== 'not_null' && !value)) return;

    if (!node.data.conditions) node.data.conditions = [];

    const condition = { field, type };
    if (type !== 'not_null') condition.value = value;
    if (['equals', 'not_equals', 'greater_than', 'less_than', 'greater_or_equal', 'less_or_equal'].includes(type)) {
        condition.operator = {
            equals: '==',
            not_equals: '!=',
            greater_than: '>',
            less_than: '<',
            greater_or_equal: '>=',
            less_or_equal: '<='
        }[type];
    }

    node.data.conditions.push(condition);
    renderConditions();
    updateNodeHtml(node, id);

    if (valInput) valInput.value = '';
};

visual
I tried different options, tried to solve the problem through addEventListener, but with it, data is not sent at all, can you please help, I am a newbie in js, so I can’t immediately identify the problem