<commit_before>// Memoized maps of attribute to property names and vice versa.
const attributeToPropertyNames = {};
const propertyNamesToAttributes = {};


/**
 * Mixin which marshalls attributes to properties and vice versa.
 *
 * If your component exposes a setter for a property, it's generally a good
 * idea to let devs using your component be able to set that property in HTML
 * via an element attribute. You can code that yourself by writing an
 * `attributeChangedCallback`, or you can use this mixin to get a degree of
 * automatic support.
 *
 * This mixin implements an `attributeChangedCallback` that will attempt to
 * convert a change in an element attribute into a call to the corresponding
 * property setter. Attributes typically follow hyphenated names ("foo-bar"),
 * whereas properties typically use camelCase names ("fooBar"). This mixin
 * respects that convention, automatically mapping the hyphenated attribute
 * name to the corresponding camelCase property name.
 *
 * Example: You define a component using this mixin:
 *
 *     class MyElement extends AttributeMarshallingMixin(HTMLElement) {
 *       get fooBar() { return this._fooBar; }
 *       set fooBar(value) { this._fooBar = value; }
 *     }
 *     customElements.define('my-element', MyElement);
 *
 * If someone then instantiates your component in HTML:
 *
 *     <my-element foo-bar="Hello"></my-element>
 *
 * Then, after the element has been upgraded, the `fooBar` setter will
 * automatically be invoked with the initial value "Hello".
 *
 * Attributes can only have string values. If you'd like to convert string
 * attributes to other types (numbers, booleans), you must implement parsing
 * yourself.
 *
 * This mixin also exposes helpers for reflecting attributes and classes to
 * the element. These helpers can be invoked during a component's constructor;
 * any attributes or classes set during the constructor are applied when the
 * component's `connectedCallback` is invoked.
 *
 * @module AttributeMarshallingMixin
 */
export default function AttributeMarshallingMixin(Base) {

  // The class prototype added by the mixin.
  class AttributeMarshalling extends Base {

    /**
     * Handle a change to the attribute with the given name.
     */
    attributeChangedCallback(attributeName, oldValue, newValue) {
      if (super.attributeChangedCallback) { super.attributeChangedCallback(); }
      const propertyName = attributeToPropertyName(attributeName);
      // If the attribute name corresponds to a property name, set the property.
      if (propertyName in this) {
        this[propertyName] = newValue;
      }
    }

    static get observedAttributes() {
      /** @type {any} */
      const elementClass = this;
      return attributesForClass(elementClass);
    }

  }

  return AttributeMarshalling;
}


/**
 * Return the custom attributes for the given class.
 * 
 * @param {{new(...args: any[]): object}} classFn
 */
function attributesForClass(classFn) {

  // We treat the HTMLElement base class as if it has no attributes, since we
  // don't want to receive attributeChangedCallback for it. We'd like to do
  // a simple check if classFn === HTMLElement, but this fails in the polyfill
  // under IE, so we compare prototypes instead.
  if (classFn.prototype === HTMLElement.prototype) {
    return [];
  }

  // Get attributes for parent class.
  const baseClass = Object.getPrototypeOf(classFn.prototype).constructor;
  // See if parent class defines observedAttributes manually.
  let baseAttributes = baseClass.observedAttributes;
  if (!baseAttributes) {
    // Calculate parent class attributes ourselves.
    baseAttributes = attributesForClass(baseClass);
  }<commit_msg>Remove type annotation causing problems with jsDoc.<commit_after>// Memoized maps of attribute to property names and vice versa.
const attributeToPropertyNames = {};
const propertyNamesToAttributes = {};


/**
 * Mixin which marshalls attributes to properties and vice versa.
 *
 * If your component exposes a setter for a property, it's generally a good
 * idea to let devs using your component be able to set that property in HTML
 * via an element attribute. You can code that yourself by writing an
 * `attributeChangedCallback`, or you can use this mixin to get a degree of
 * automatic support.
 *
 * This mixin implements an `attributeChangedCallback` that will attempt to
 * convert a change in an element attribute into a call to the corresponding
 * property setter. Attributes typically follow hyphenated names ("foo-bar"),
 * whereas properties typically use camelCase names ("fooBar"). This mixin
 * respects that convention, automatically mapping the hyphenated attribute
 * name to the corresponding camelCase property name.
 *
 * Example: You define a component using this mixin:
 *
 *     class MyElement extends AttributeMarshallingMixin(HTMLElement) {
 *       get fooBar() { return this._fooBar; }
 *       set fooBar(value) { this._fooBar = value; }
 *     }
 *     customElements.define('my-element', MyElement);
 *
 * If someone then instantiates your component in HTML:
 *
 *     <my-element foo-bar="Hello"></my-element>
 *
 * Then, after the element has been upgraded, the `fooBar` setter will
 * automatically be invoked with the initial value "Hello".
 *
 * Attributes can only have string values. If you'd like to convert string
 * attributes to other types (numbers, booleans), you must implement parsing
 * yourself.
 *
 * This mixin also exposes helpers for reflecting attributes and classes to
 * the element. These helpers can be invoked during a component's constructor;
 * any attributes or classes set during the constructor are applied when the
 * component's `connectedCallback` is invoked.
 *
 * @module AttributeMarshallingMixin
 */
export default function AttributeMarshallingMixin(Base) {

  // The class prototype added by the mixin.
  class AttributeMarshalling extends Base {

    /**
     * Handle a change to the attribute with the given name.
     */
    attributeChangedCallback(attributeName, oldValue, newValue) {
      if (super.attributeChangedCallback) { super.attributeChangedCallback(); }
      const propertyName = attributeToPropertyName(attributeName);
      // If the attribute name corresponds to a property name, set the property.
      if (propertyName in this) {
        this[propertyName] = newValue;
      }
    }

    static get observedAttributes() {
      /** @type {any} */
      const elementClass = this;
      return attributesForClass(elementClass);
    }

  }

  return AttributeMarshalling;
}


/**
 * Return the custom attributes for the given class.
 */
function attributesForClass(classFn) {

  // We treat the HTMLElement base class as if it has no attributes, since we
  // don't want to receive attributeChangedCallback for it. We'd like to do
  // a simple check if classFn === HTMLElement, but this fails in the polyfill
  // under IE, so we compare prototypes instead.
  if (classFn.prototype === HTMLElement.prototype) {
    return [];
  }

  // Get attributes for parent class.
  const baseClass = Object.getPrototypeOf(classFn.prototype).constructor;
  // See if parent class defines observedAttributes manually.
  let baseAttributes = baseClass.observedAttributes;
  if (!baseAttributes) {
    // Calculate parent class attributes ourselves.
    baseAttributes = attributesForClass(baseClass);
  }
{'fraction_non_alphanumeric': 0.07726657645466847, 'fraction_numerical': 0.0, 'mean_word_length': 3.7469492614001285, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '3288959', 'n_tokens_mistral': 1883, 'n_tokens_neox': 1827, 'n_words': 801}