{"version":3,"sources":["jsdelivr-header.js","/npm/@polymer/iron-form@3.0.1/iron-form.js"],"names":[],"mappings":"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","file":"/npm/@polymer/iron-form@3.0.1/iron-form.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@polymer/iron-form@3.0.1/iron-form.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport '@polymer/iron-ajax/iron-ajax.js';\n\nimport {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';\nimport {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';\nimport {html} from '@polymer/polymer/lib/utils/html-tag.js';\n\n/**\n`<iron-form>` is a wrapper around the HTML `<form>` element, that can\nvalidate and submit both custom and native HTML elements. Note that this\nis a breaking change from iron-form 1.0, which was a type extension.\n\nIt has two modes: if `allow-redirect` is true, then after the form submission\nyou will be redirected to the server response. Otherwise, if it is false, it\nwill use an `iron-ajax` element to submit the form contents to the server.\n\n  Example:\n\n    <iron-form>\n      <form method=\"get\" action=\"/form/handler\">\n        <input type=\"text\" name=\"name\" value=\"Batman\">\n        <input type=\"checkbox\" name=\"donuts\" checked> I like donuts<br>\n        <paper-checkbox name=\"cheese\" value=\"yes\" checked></paper-checkbox>\n      </form>\n    </iron-form>\n\nBy default, a native `<button>` element will submit this form. However, if you\nwant to submit it from a custom element's click handler, you need to explicitly\ncall the `iron-form`'s `submit` method.\n\n  Example (using `<paper-button>` for the form `<iron-form id=\"myForm\">`):\n\n    <paper-button raised on-click=\"submitForm\">Submit</paper-button>\n\n    function submitForm() {\n      this.$.myForm.submit();\n    }\n\n  or (using `<button>` for a form in the same document):\n\n    <button raised onclick=\"submitForm()\">Submit</button>\n\n    function submitForm() {\n      document.getElementById('myForm').submit();\n    }\n\nIf you are not using the `allow-redirect` mode, then you also have the option of\ncustomizing the request sent to the server. To do so, you can listen to the\n`iron-form-presubmit` event, and modify the form's\n[`iron-ajax`](https://elements.polymer-project.org/elements/iron-ajax) object.\nHowever, If you want to not use `iron-ajax` at all, you can cancel the event and\ndo your own custom submission:\n\n  Example of modifying the request, but still using the build-in form\nsubmission:\n\n    form.addEventListener('iron-form-presubmit', function() {\n      this.request.method = 'put';\n      this.request.params['extraParam'] = 'someValue';\n    });\n\n  Example of bypassing the build-in form submission:\n\n    form.addEventListener('iron-form-presubmit', function(event) {\n      event.preventDefault();\n      var firebase = new Firebase(form.getAttribute('action'));\n      firebase.set(form.serializeForm());\n    });\n\nNote that if you're dynamically creating this element, it's mandatory that you\nfirst create the contained `<form>` element and all its children, and only then\nattach it to the `<iron-form>`:\n\n  var wrapper = document.createElement('iron-form');\n  var form = document.createElement('form');\n  var input = document.createElement('input');\n  form.appendChild(input);\n  document.body.appendChild(wrapper);\n  wrapper.appendChild(form);\n\n@element iron-form\n@hero hero.svg\n@demo demo/index.html\n*/\nPolymer({\n  _template: html`\n    <style>\n      :host {\n        display: block;\n      }\n    </style>\n\n    <!-- This form is used to collect the elements that should be submitted -->\n    <slot></slot>\n\n    <!-- This form is used for submission -->\n    <form id=\"helper\" action\\$=\"[[action]]\" method\\$=\"[[method]]\" enctype\\$=\"[[enctype]]\"></form>\n`,\n\n  is: 'iron-form',\n\n  properties: {\n    /*\n     * Set this to true if you don't want the form to be submitted through an\n     * ajax request, and you want the page to redirect to the action URL\n     * after the form has been submitted.\n     */\n    allowRedirect: {type: Boolean, value: false},\n    /**\n     * HTTP request headers to send. See PolymerElements/iron-ajax for\n     * more details. Only works when `allowRedirect` is false.\n     */\n    headers: {\n      type: Object,\n      value: function() {\n        return {};\n      }\n    },\n    /**\n     * Set the `withCredentials` flag on the request. See\n     * PolymerElements/iron-ajax for more details. Only works when\n     * `allowRedirect` is false.\n     */\n    withCredentials: {type: Boolean, value: false},\n  },\n\n  /**\n   * Fired if the form cannot be submitted because it's invalid.\n   *\n   * @event iron-form-invalid\n   */\n\n  /**\n   * Fired after the form is submitted.\n   *\n   * @event iron-form-submit\n   */\n\n  /**\n   * Fired before the form is submitted.\n   *\n   * @event iron-form-presubmit\n   */\n\n  /**\n   * Fired after the form is reset.\n   *\n   * @event iron-form-reset\n   */\n\n  /**\n   * Fired after the form is submitted and a response is received. An\n   * IronRequestElement is included as the event.detail object.\n   *\n   * @event iron-form-response\n   */\n\n  /**\n   * Fired after the form is submitted and an error is received. An\n   * error message is included in event.detail.error and an\n   * IronRequestElement is included in event.detail.request.\n   *\n   * @event iron-form-error\n   */\n\n  /**\n   * @return {void}\n   */\n  attached: function() {\n    // We might have been detached then re-attached.\n    // Avoid searching again for the <form> if we already found it.\n    if (this._form) {\n      return;\n    }\n    // Search for the `<form>`, if we don't find it, observe for\n    // mutations.\n    this._form = dom(this).querySelector('form');\n    if (this._form) {\n      this._init();\n      // Since some elements might not be upgraded yet at this time,\n      // we won't be able to look into their shadowRoots for submittables.\n      // We wait a tick and check again for any missing submittable default\n      // values.\n      this.async(this._saveInitialValues.bind(this), 1);\n    } else {\n      this._nodeObserver = dom(this).observeNodes(function(mutations) {\n        for (var i = 0; i < mutations.addedNodes.length; i++) {\n          if (mutations.addedNodes[i].tagName === 'FORM') {\n            this._form = mutations.addedNodes[i];\n            // At this point in time, all custom elements are expected\n            // to be upgraded, hence we'll be able to traverse their\n            // shadowRoots.\n            this._init();\n            dom(this).unobserveNodes(this._nodeObserver);\n            this._nodeObserver = null;\n          }\n        }\n      }.bind(this));\n    }\n  },\n\n  /**\n   * @return {void}\n   */\n  detached: function() {\n    if (this._nodeObserver) {\n      dom(this).unobserveNodes(this._nodeObserver);\n      this._nodeObserver = null;\n    }\n  },\n\n  _init: function() {\n    this._form.addEventListener('submit', this.submit.bind(this));\n    this._form.addEventListener('reset', this.reset.bind(this));\n\n    // Save the initial values.\n    this._defaults = this._defaults || new WeakMap();\n    this._saveInitialValues();\n  },\n\n  /**\n   * Saves the values of all form elements that will be used when resetting\n   * the form. Initially called asynchronously on attach. Any time you\n   * call this function, the previously saved values for a form element will\n   * be overwritten.\n   *\n   * This function is useful if you are dynamically adding elements to\n   * the form, or if your elements are asynchronously setting their values.\n   * @return {void}\n   */\n  saveResetValues: function() {\n    this._saveInitialValues(true);\n  },\n\n  /**\n   * @param {boolean=} overwriteValues\n   * @return {void}\n   */\n  _saveInitialValues: function(overwriteValues) {\n    var nodes = this._getValidatableElements();\n    for (var i = 0; i < nodes.length; i++) {\n      var node = nodes[i];\n      if (!this._defaults.has(node) || overwriteValues) {\n        // Submittables are expected to have `value` property,\n        // that's what gets serialized.\n        var defaults = {value: node.value};\n        if ('checked' in node) {\n          defaults.checked = node.checked;\n        }\n        // In 1.x iron-form would reset `invalid`, so\n        // keep it here for backwards compat.\n        if ('invalid' in node) {\n          defaults.invalid = node.invalid;\n        }\n        this._defaults.set(node, defaults);\n      }\n    }\n  },\n\n  /**\n   * Validates all the required elements (custom and native) in the form.\n   * @return {boolean} True if all the elements are valid.\n   */\n  validate: function() {\n    // If you've called this before distribution happened, bail out.\n    if (!this._form) {\n      return false;\n    }\n\n    if (this._form.getAttribute('novalidate') === '')\n      return true;\n\n    // Start by making the form check the native elements it knows about.\n    var valid = this._form.checkValidity();\n    var elements = this._getValidatableElements();\n\n    // Go through all the elements, and validate the custom ones.\n    for (var el, i = 0; el = elements[i], i < elements.length; i++) {\n      // This is weird to appease the compiler. We assume the custom element\n      // has a validate() method, otherwise we can't check it.\n      var validatable = /** @type {{validate: (function() : boolean)}} */ (el);\n      if (validatable.validate) {\n        valid = !!validatable.validate() && valid;\n      }\n    }\n    return valid;\n  },\n\n  /**\n   * Submits the form.\n   *\n   * @param {Event=} event\n   * @return {void}\n   */\n  submit: function(event) {\n    // We are not using this form for submission, so always cancel its event.\n    if (event) {\n      event.preventDefault();\n    }\n\n    // If you've called this before distribution happened, bail out.\n    if (!this._form) {\n      return;\n    }\n\n    if (!this.validate()) {\n      this.fire('iron-form-invalid');\n      return;\n    }\n\n    // Remove any existing children in the submission form (from a previous\n    // submit).\n    this.$.helper.textContent = '';\n\n    var json = this.serializeForm();\n\n    // If we want a redirect, submit the form natively.\n    if (this.allowRedirect) {\n      // If we're submitting the form natively, then create a hidden element for\n      // each of the values.\n      for (var element in json) {\n        this.$.helper.appendChild(\n            this._createHiddenElement(element, json[element]));\n      }\n\n      // Copy the original form attributes.\n      this.$.helper.action = this._form.getAttribute('action');\n      this.$.helper.method = this._form.getAttribute('method') || 'GET';\n      this.$.helper.contentType = this._form.getAttribute('enctype') ||\n          'application/x-www-form-urlencoded';\n\n      this.$.helper.submit();\n      this.fire('iron-form-submit');\n    } else {\n      this._makeAjaxRequest(json);\n    }\n  },\n\n  /**\n   * Resets the form to the default values.\n   *\n   * @param {Event=} event\n   * @return {void}\n   */\n  reset: function(event) {\n    // We are not using this form for submission, so always cancel its event.\n    if (event)\n      event.preventDefault();\n\n    // If you've called this before distribution happened, bail out.\n    if (!this._form) {\n      return;\n    }\n\n    // Ensure the native form fired the `reset` event.\n    // User might have bound `<button on-click=\"_resetIronForm\">`, or directly\n    // called `ironForm.reset()`. In these cases we want to first reset the\n    // native form.\n    if (!event || event.type !== 'reset' || event.target !== this._form) {\n      this._form.reset();\n      return;\n    }\n\n    // Load the initial values.\n    var nodes = this._getValidatableElements();\n    for (var i = 0; i < nodes.length; i++) {\n      var node = nodes[i];\n      if (this._defaults.has(node)) {\n        var defaults = this._defaults.get(node);\n        for (var propName in defaults) {\n          node[propName] = defaults[propName];\n        }\n      }\n    }\n\n    this.fire('iron-form-reset');\n  },\n\n  /**\n   * Serializes the form as will be used in submission. Note that `serialize`\n   * is a Polymer reserved keyword, so calling `someIronForm`.serialize()`\n   * will give you unexpected results.\n   * @return {!Object<string, *>} An object containing name-value pairs for elements that\n   *                  would be submitted.\n   */\n  serializeForm: function() {\n    // Only elements that have a `name` and are not disabled are submittable.\n    var elements = this._getSubmittableElements();\n    var json = {};\n    for (var i = 0; i < elements.length; i++) {\n      var values = this._serializeElementValues(elements[i]);\n      for (var v = 0; v < values.length; v++) {\n        this._addSerializedElement(json, elements[i].name, values[v]);\n      }\n    }\n    return json;\n  },\n\n  _handleFormResponse: function(event) {\n    this.fire('iron-form-response', event.detail);\n  },\n\n  _handleFormError: function(event) {\n    this.fire('iron-form-error', event.detail);\n  },\n\n  _makeAjaxRequest: function(json) {\n    // Initialize the iron-ajax element if we haven't already.\n    if (!this.request) {\n      this.request = document.createElement('iron-ajax');\n      this.request.addEventListener(\n          'response', this._handleFormResponse.bind(this));\n      this.request.addEventListener('error', this._handleFormError.bind(this));\n    }\n\n    // Native forms can also index elements magically by their name (can't make\n    // this up if I tried) so we need to get the correct attributes, not the\n    // elements with those names.\n    this.request.url = this._form.getAttribute('action');\n    this.request.method = this._form.getAttribute('method') || 'GET';\n    this.request.contentType = this._form.getAttribute('enctype') ||\n        'application/x-www-form-urlencoded';\n    this.request.withCredentials = this.withCredentials;\n    this.request.headers = this.headers;\n\n    if (this._form.method.toUpperCase() === 'POST') {\n      this.request.body = json;\n    } else {\n      this.request.params = json;\n    }\n\n    // Allow for a presubmit hook\n    var event = this.fire('iron-form-presubmit', {}, {cancelable: true});\n    if (!event.defaultPrevented) {\n      this.request.generateRequest();\n      this.fire('iron-form-submit', json);\n    }\n  },\n\n  _getValidatableElements: function() {\n    return this._findElements(\n        this._form, true /* ignoreName */, false /* skipSlots */);\n  },\n\n  _getSubmittableElements: function() {\n    return this._findElements(\n        this._form, false /* ignoreName */, false /* skipSlots */);\n  },\n\n  /**\n   * Traverse the parent element to find and add all submittable nodes to\n   * `submittable`.\n   * @param  {!Node} parent The parent node\n   * @param  {!boolean} ignoreName  Whether the name of the submittable nodes should be disregarded\n   * @param  {!boolean} skipSlots  Whether to skip traversing of slot elements\n   * @param  {!Array<!Node>=} submittable Reference to the array of submittables\n   * @return {!Array<!Node>}\n   * @private\n   */\n  _findElements: function(parent, ignoreName, skipSlots, submittable) {\n    submittable = submittable || [];\n    var nodes = dom(parent).querySelectorAll('*');\n    for (var i = 0; i < nodes.length; i++) {\n      // An element is submittable if it is not disabled, and if it has a\n      // name attribute.\n      if (!skipSlots &&\n          (nodes[i].localName === 'slot' || nodes[i].localName === 'content')) {\n        this._searchSubmittableInSlot(submittable, nodes[i], ignoreName);\n      } else {\n        this._searchSubmittable(submittable, nodes[i], ignoreName);\n      }\n    }\n    return submittable;\n  },\n\n  /**\n   * Traverse the distributed nodes of a slot or content element\n   * and add all submittable nodes to `submittable`.\n   * @param  {!Array<!Node>} submittable Reference to the array of submittables\n   * @param  {!Node} node The slot or content node\n   * @param  {!boolean} ignoreName  Whether the name of the submittable nodes should be disregarded\n   * @return {void}\n   * @private\n   */\n  _searchSubmittableInSlot: function(submittable, node, ignoreName) {\n    var assignedNodes = dom(node).getDistributedNodes();\n\n    for (var i = 0; i < assignedNodes.length; i++) {\n      if (assignedNodes[i].nodeType === Node.TEXT_NODE) {\n        continue;\n      }\n\n      // Note: assignedNodes does not contain <slot> or <content> because\n      // getDistributedNodes flattens the tree.\n      this._searchSubmittable(submittable, assignedNodes[i], ignoreName);\n      var nestedAssignedNodes = dom(assignedNodes[i]).querySelectorAll('*');\n      for (var j = 0; j < nestedAssignedNodes.length; j++) {\n        this._searchSubmittable(\n            submittable, nestedAssignedNodes[j], ignoreName);\n      }\n    }\n  },\n\n  /**\n   * Traverse the distributed nodes of a slot or content element\n   * and add all submittable nodes to `submittable`.\n   * @param  {!Array<!Node>} submittable Reference to the array of submittables\n   * @param  {!Node} node The node to be\n   * @param  {!boolean} ignoreName  Whether the name of the submittable nodes should be disregarded\n   * @return {void}\n   * @private\n   */\n  _searchSubmittable: function(submittable, node, ignoreName) {\n    if (this._isSubmittable(node, ignoreName)) {\n      submittable.push(node);\n    } else if (node.root) {\n      this._findElements(\n          node.root, ignoreName, true /* skipSlots */, submittable);\n    }\n  },\n\n  /**\n   * An element is submittable if it is not disabled, and if it has a\n   * 'name' attribute. If we ignore the name, check if is validatable.\n   * This allows `_findElements` to decide if to explore an element's shadowRoot\n   * or not: an element implementing `validate()` is considered validatable, and\n   * we don't search for validatables in its shadowRoot.\n   * @param {!Node} node\n   * @param {!boolean} ignoreName\n   * @return {boolean}\n   * @private\n   */\n  _isSubmittable: function(node, ignoreName) {\n    return (\n        !node.disabled &&\n        (ignoreName ? node.name || typeof node.validate === 'function' :\n                      node.name));\n  },\n\n  _serializeElementValues: function(element) {\n    // We will assume that every custom element that needs to be serialized\n    // has a `value` property, and it contains the correct value.\n    // The only weird one is an element that implements\n    // IronCheckedElementBehaviour, in which case like the native checkbox/radio\n    // button, it's only used when checked. For native elements, from\n    // https://www.w3.org/TR/html5/forms.html#the-form-element. Native\n    // submittable elements: button, input, keygen, object, select, textarea;\n    // 1. We will skip `keygen and `object` for this iteration, and deal with\n    // them if they're actually required.\n    // 2. <button> and <textarea> have a `value` property, so they behave like\n    //    the custom elements.\n    // 3. <select> can have multiple options selected, in which case its\n    //    `value` is incorrect, and we must use the values of each of its\n    //    `selectedOptions`\n    // 4. <input> can have a whole bunch of behaviours, so it's handled\n    // separately.\n    // 5. Buttons are hard. The button that was clicked to submit the form\n    //    is the one who's name/value gets sent to the server.\n    var tag = element.tagName.toLowerCase();\n    if (tag === 'button' ||\n        (tag === 'input' &&\n         (element.type === 'submit' || element.type === 'reset'))) {\n      return [];\n    }\n\n    if (tag === 'select') {\n      return this._serializeSelectValues(element);\n    } else if (tag === 'input') {\n      return this._serializeInputValues(element);\n    } else {\n      if (element['_hasIronCheckedElementBehavior'] && !element.checked)\n        return [];\n      return [element.value];\n    }\n  },\n\n  _serializeSelectValues: function(element) {\n    var values = [];\n\n    // A <select multiple> has an array of options, some of which can be\n    // selected.\n    for (var i = 0; i < element.options.length; i++) {\n      if (element.options[i].selected) {\n        values.push(element.options[i].value)\n      }\n    }\n    return values;\n  },\n\n  _serializeInputValues: function(element) {\n    // Most of the inputs use their 'value' attribute, with the exception\n    // of radio buttons, checkboxes and file.\n    var type = element.type.toLowerCase();\n\n    // Don't do anything for unchecked checkboxes/radio buttons.\n    // Don't do anything for file, since that requires a different request.\n    if (((type === 'checkbox' || type === 'radio') && !element.checked) ||\n        type === 'file') {\n      return [];\n    }\n    return [element.value];\n  },\n\n  _createHiddenElement: function(name, value) {\n    var input = document.createElement('input');\n    input.setAttribute('type', 'hidden');\n    input.setAttribute('name', name);\n    input.setAttribute('value', value);\n    return input;\n  },\n\n  _addSerializedElement: function(json, name, value) {\n    // If the name doesn't exist, add it. Otherwise, serialize it to\n    // an array,\n    if (json[name] === undefined) {\n      json[name] = value;\n    } else {\n      if (!Array.isArray(json[name])) {\n        json[name] = [json[name]];\n      }\n      json[name].push(value);\n    }\n  }\n});\n"]}