Repository: trueadm/ripple
File: packages/ripple/src/runtime/internal/client/render.js (JavaScript)

Code before:
 */
function to_class(value, hash) {
  return (value == null ? '' : value) + (hash ? ' ' + hash : '');
}

/**
 * @param {HTMLElement} dom
 * @param {string} value
 * @param {string} [hash]
 * @returns {void}
 */
export function set_class(dom, value, hash) {
  // @ts-expect-error need to add __className to patched prototype
  var prev_class_name = dom.__className;
  var next_class_name = to_class(value, hash);

  if (prev_class_name !== next_class_name) {
    // Removing the attribute when the value is only an empty string causes
    // peformance issues vs simply making the className an empty string. So
    // we should only remove the class if the the value is nullish.
    if (value == null && !hash) {
      dom.removeAttribute('class');
    } else {
      // SVG and MathML elements don't support className property, must use setAttribute
      if (
        dom.namespaceURI === 'http://www.w3.org/2000/svg' ||
        dom.namespaceURI === 'http://www.w3.org/1998/Math/MathML'
      ) {
        dom.setAttribute('class', next_class_name);
      } else {
        dom.className = next_class_name;
      }
    }

    // @ts-expect-error need to add __className to patched prototype
    dom.__className = next_class_name;
  }
}

export function set_value(element, value) {
  // @ts-expect-error
  var attributes = (element.__attributes ??= {});

  if (
    attributes.value ===
      (attributes.value =
        // treat null and undefined the same for the initial value
        value ?? undefined) ||
    // @ts-expect-error
    // `progress` elements always need their value set when it's `0`
    (element.value === value && (value !== 0 || element.nodeName !== 'PROGRESS'))

Review comment (performance):
we likely just want `is_html` to be passed in from the compiler based off the namespace, rather than doing these expensive lookups here

Code after:
 * @returns {string | V}
 */
function to_class(value, hash) {
  return (value == null ? '' : value) + (hash ? ' ' + hash : '');
}

/**
 * @param {HTMLElement} dom
 * @param {string} value
 * @param {string} [hash]
 * @param {boolean} [is_html]
 * @returns {void}
 */
export function set_class(dom, value, hash, is_html = true) {
  // @ts-expect-error need to add __className to patched prototype
  var prev_class_name = dom.__className;
  var next_class_name = to_class(value, hash);

  if (prev_class_name !== next_class_name) {
    // Removing the attribute when the value is only an empty string causes
    // peformance issues vs simply making the className an empty string. So
    // we should only remove the class if the the value is nullish.
    if (value == null && !hash) {
      dom.removeAttribute('class');
    } else {
      if (is_html) {
        dom.className = next_class_name;
      } else {
        dom.setAttribute('class', next_class_name);
      }
    }

    // @ts-expect-error need to add __className to patched prototype
    dom.__className = next_class_name;
  }
}

export function set_value(element, value) {
  // @ts-expect-error
  var attributes = (element.__attributes ??= {});

  if (
    attributes.value ===
      (attributes.value =
        // treat null and undefined the same for the initial value
        value ?? undefined) ||
    // @ts-expect-error
    // `progress` elements always need their value set when it's `0`
    (element.value === value && (value !== 0 || element.nodeName !== 'PROGRESS'))
  ) {
    return;