<commit_before>import '../src/html.js';
const $ = require('jquery');

fillInPropertyTable('custom-a');
$(window).on('hashchange', setSelectedLink);
setSelectedLink();

function fillInPropertyTable(elementName) {
  const section = $('section#' + elementName);
  const el = section.find('.example.custom ' + elementName)[0];
  const tbody = section.find('table.properties tbody');

  const properties = Object.keys(Object.getPrototypeOf(el));
  const rowsHtml = properties.reduce(
    (soFar, prop) => soFar + `<tr><td>${prop}</td><td>${getPropertyValue(el, prop)}</td></tr>`,
    ''
  );
  tbody.html(rowsHtml);

  $(tbody).on('input', ev => updateOtherProperties(event.target, tbody, el));
}

function getPropertyValue(el, prop) {
  let val;
  try {
    val = el[prop];
  } catch (e) {
    console.error(`Error getting property ${prop} from <${el.tagName}>`, e);
    return '[Exception]';
  }

  if (typeof val === 'string') {
    return `<input type="text" data-property-name="${prop}" value="${val}">`;
  }
  return val;
}

function updateOtherProperties(changedPropertyInput, tbody, customEl) {
  const changedPropertyName = changedPropertyInput.dataset.propertyName;
  customEl[changedPropertyName] = changedPropertyInput.value;

  for (const input of Array.from(tbody.find('input[type="text"]'))) {
    if (input !== changedPropertyInput) {
      input.value = customEl[input.dataset.propertyName];
    }
  }
}

function setSelectedLink() {
  const nav = $('body > nav');
  nav.find('a.selected').removeClass('selected');
  nav.find(`a[href="${window.location.hash}"]`).addClass('selected');
}<commit_msg>Make the property editor better in various ways<commit_after>import '../src/html.js';
const $ = require('jquery');

fillInPropertyTable('custom-a');
$(window).on('hashchange', setSelectedLink);
setSelectedLink();

function fillInPropertyTable(elementName) {
  const section = $('section#' + elementName);
  const el = section.find('.example.custom ' + elementName)[0];
  const tbody = section.find('table.properties tbody');

  const properties = Object.keys(Object.getPrototypeOf(el));
  const rowsHtml = properties.reduce(
    (soFar, prop) => soFar + `<tr><td>${prop}</td><td>${getPropertyValue(el, prop)}</td></tr>`,
    ''
  );
  tbody.html(rowsHtml);

  $(tbody).on('input', 'input[type="text"]', ev => updateOtherProperties(event.target, el));
  $(tbody).on('blur', 'input[type="text"]', ev => updateSingleProperty(event.target, el));
}

function getPropertyValue(el, prop) {
  let val;
  try {
    val = el[prop];
  } catch (e) {
    console.error(`Error getting property ${prop} from <${el.tagName}>`, e);
    return '[Exception]';
  }

  if (typeof val === 'string') {
    if (typeof Object.getOwnPropertyDescriptor(Object.getPrototypeOf(el), prop).set === 'function') {
      return `<input type="text" value="${val}">`;
    } else {
      return val;
    }
  }
  return val;
}

function updateOtherProperties(changedPropertyInput, customEl) {
  const changedRow = changedPropertyInput.parentElement.parentElement;
  const changedPropertyName = changedRow.children[0].textContent;

  customEl[changedPropertyName] = changedPropertyInput.value;

  for (const row of Array.from($(changedRow).siblings())) {
    const propName = row.children[0].textContent;
    const valueCell = row.children[1];
    valueCell.innerHTML = getPropertyValue(customEl, propName);
  }
}

function updateSingleProperty(changedPropertyInput, customEl) {
  const changedRow = changedPropertyInput.parentElement.parentElement;
  const changedPropertyName = changedRow.children[0].textContent;

  changedRow.children[1].innerHTML = getPropertyValue(customEl, changedPropertyName);
}

function setSelectedLink() {
  const nav = $('body > nav');
  nav.find('a.selected').removeClass('selected');
  nav.find(`a[href="${window.location.hash}"]`).addClass('selected');
}
{'fraction_non_alphanumeric': 0.1734059097978227, 'fraction_numerical': 0.0018144116122343183, 'mean_word_length': 5.164536741214057, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1400456', 'n_tokens_mistral': 1195, 'n_tokens_neox': 1178, 'n_words': 229}