GithubHelp home page GithubHelp logo

Comments (5)

justin-schroeder avatar justin-schroeder commented on May 4, 2024 1

Thanks for the well articulated thoughts and comprehensive code example. Overall its a good direction, a few thoughts on what this implementation should look like (in my opinion):

  1. We need a size efficient way to determine if we need to set the IDL or not. A tagname map of inputs would be too large for a 2kb library. I think we can do this by checking against 3 interfaces: HTMLInputElement, HTMLSelectElement, HTMLTextareaElement. All of those have a value IDL that can be set. I dont think we should set the actual value attribute of any of these. This would fall in line with how Vue does it, but would be in contrast to React.
  2. false removing an attribute is a personal preference of mine that I think leads to much more concise and readable code, despite being a slight deviation from . Vue 2 used to do attributes this way and it switching to false being a valid value, its been a minor pain (in my opinion) and the number of use cases where false is a desired attribute is rare, and in those cases providing the string false is acceptable. So I don’t currently plan to change this part of the implementation — opinionated as it may be.

And with that said — this is now published/fixed in alpha.5 🎉

from arrow-js.

atellmer avatar atellmer commented on May 4, 2024
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>arrow-js</title>
</head>
<body>
  <div id="app"></div>
  <script type='module'>
    import { reactive, html } from 'https://unpkg.com/@arrow-js/[email protected]/dist/index.min.mjs';

    const data = reactive({
      text: 'hello',
    });

    html`
      <div>${() => data.text}</div>
      <input value="${() => data.text}" @input="${e => (data.text = e.target.value)}">
      <input value="${() => data.text}" @input="${e => (data.text = e.target.value)}">
    `(document.getElementById('app'))
  </script>
</body>
</html>

from arrow-js.

justin-schroeder avatar justin-schroeder commented on May 4, 2024

yeah interesting. Attribute binding in arrow uses setAttribute — inputs are weird in that they have their own state with a value content attribute and a value IDL property. AFAIK the IDL property is the one that is actually displayed — I wonder if we should have a few special cases where we detect if the attribute being set has an matching own property (hasOwn) and set it accordingly.

from arrow-js.

atellmer avatar atellmer commented on May 4, 2024

I think in case of input and maybe textarea you need to patch that element directly by setting their internal property.
At the same time, ignore the setting through the setAttribute property, because in this case there is a small security problem (we can see the password in the attribute through the element inspector for inputs with the password type)

from arrow-js.

atellmer avatar atellmer commented on May 4, 2024

I would suggest such a solution, which, in addition to setting value directly to the element, also includes the correct processing of boolean attributes when they have a false value, but they are still put down, which affects, for example, html5 validation through the required attribute.

type AttributeValue = string | number | boolean;

function patchProperties(element: Element, attrName: string, attrValue: AttributeValue): boolean {
  const tagName = element.tagName.toLowerCase();
  const fn = specialCasesMap[tagName];
  let stop = fn ? fn(element, attrName, attrValue) : false;

  // check IDL props
  if (Object.getPrototypeOf(element).hasOwnProperty(attrName)) {
    element[attrName] = attrValue;
  }

  // blocking the setting of all boolean attributes, except for data-attributes or other custom attributes
  if (!stop && typeof attrValue === 'boolean' && !attrName.includes('-')) {
    stop = true;
  }

  // we give out the blocking flag for setting this attribute through setAttribute
  return stop;
}

const specialCasesMap: Record<string, typeof patchProperties> = {
  input: (element: HTMLInputElement, attrName: string, attrValue: AttributeValue) => {
    if (attrName === 'value' && typeof attrValue === 'boolean') {
      // checkbox case
      element.checked = attrValue;
    } else if (attrName === 'autoFocus') {
      // autofocus case
      element.autofocus = Boolean(attrValue);
    }

    return false;
  },
  textarea: (element: HTMLTextAreaElement, attrName: string, attrValue: AttributeValue) => {
    if (attrName === 'value') {
      // redirect value to innerHTML
      element.innerHTML = String(attrValue);

      return true;
    }

    return false;
  },
};

from arrow-js.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.