diff -r be944660c56a -r 3d72ae0968f4 wp/wp-includes/js/dist/vendor/wp-polyfill-formdata.js --- a/wp/wp-includes/js/dist/vendor/wp-polyfill-formdata.js Wed Sep 21 18:19:35 2022 +0200 +++ b/wp/wp-includes/js/dist/vendor/wp-polyfill-formdata.js Tue Sep 27 16:37:53 2022 +0200 @@ -1,3 +1,5 @@ +/* formdata-polyfill. MIT License. Jimmy Wärting */ + /* global FormData self Blob File */ /* eslint-disable no-inner-declarations */ @@ -40,16 +42,13 @@ new File([], '') // eslint-disable-line } catch (a) { global.File = function File (b, d, c) { - const blob = new Blob(b, c) + const blob = new Blob(b, c || {}) const t = c && void 0 !== c.lastModified ? new Date(c.lastModified) : new Date() Object.defineProperties(blob, { name: { value: d }, - lastModifiedDate: { - value: t - }, lastModified: { value: +t }, @@ -70,50 +69,52 @@ } } - function normalizeValue ([name, value, filename]) { - if (value instanceof Blob) { - // Should always returns a new File instance - // console.assert(fd.get(x) !== fd.get(x)) - value = new File([value], filename, { - type: value.type, - lastModified: value.lastModified - }) - } - - return [name, value] - } - function ensureArgs (args, expected) { if (args.length < expected) { throw new TypeError(`${expected} argument required, but only ${args.length} present.`) } } + /** + * @param {string} name + * @param {string | undefined} filename + * @returns {[string, File|string]} + */ function normalizeArgs (name, value, filename) { - return value instanceof Blob - // normalize name and filename if adding an attachment - ? [String(name), value, filename !== undefined - ? filename + '' // Cast filename to string if 3th arg isn't undefined - : typeof value.name === 'string' // if name prop exist - ? value.name // Use File.name - : 'blob'] // otherwise fallback to Blob + if (value instanceof Blob) { + filename = filename !== undefined + ? String(filename + '') + : typeof value.name === 'string' + ? value.name + : 'blob' - // If no attachment, just cast the args to strings - : [String(name), String(value)] + if (value.name !== filename || Object.prototype.toString.call(value) === '[object Blob]') { + value = new File([value], filename) + } + return [String(name), value] + } + return [String(name), String(value)] } - // normalize linefeeds for textareas + // normalize line feeds for textarea // https://html.spec.whatwg.org/multipage/form-elements.html#textarea-line-break-normalisation-transformation function normalizeLinefeeds (value) { - return value.replace(/\r\n/g, '\n').replace(/\n/g, '\r\n') + return value.replace(/\r?\n|\r/g, '\r\n') } + /** + * @template T + * @param {ArrayLike} arr + * @param {{ (elm: T): void; }} cb + */ function each (arr, cb) { for (let i = 0; i < arr.length; i++) { cb(arr[i]) } } + const escape = str => str.replace(/\n/g, '%0A').replace(/\r/g, '%0D').replace(/"/g, '%22') + /** * @implements {Iterable} */ @@ -121,14 +122,14 @@ /** * FormData class * - * @param {HTMLElement=} form + * @param {HTMLFormElement=} form */ constructor (form) { + /** @type {[string, string|File][]} */ this._data = [] const self = this - - form && each(form.elements, elm => { + form && each(form.elements, (/** @type {HTMLInputElement} */ elm) => { if ( !elm.name || elm.disabled || @@ -196,7 +197,7 @@ */ * entries () { for (var i = 0; i < this._data.length; i++) { - yield normalizeValue(this._data[i]) + yield this._data[i] } } @@ -205,7 +206,6 @@ * * @param {Function} callback Executed for each item with parameters (value, name, thisArg) * @param {Object=} thisArg `this` context for callback function - * @return {undefined} */ forEach (callback, thisArg) { ensureArgs(arguments, 1) @@ -216,7 +216,7 @@ /** * Return first field value given name - * or null if non existen + * or null if non existent * * @param {string} name Field name * @return {string|File|null} value Fields value @@ -227,7 +227,7 @@ name = String(name) for (let i = 0; i < entries.length; i++) { if (entries[i][0] === name) { - return normalizeValue(entries[i])[1] + return entries[i][1] } } return null @@ -244,7 +244,7 @@ const result = [] name = String(name) each(this._data, data => { - data[0] === name && result.push(normalizeValue(data)[1]) + data[0] === name && result.push(data[1]) }) return result @@ -284,17 +284,17 @@ * @param {string} name Filed name * @param {string} value Field value * @param {string=} filename Filename (optional) - * @return {undefined} */ set (name, value, filename) { ensureArgs(arguments, 2) name = String(name) + /** @type {[string, string|File][]} */ const result = [] const args = normalizeArgs(name, value, filename) let replace = true // - replace the first occurrence with same name - // - discards the remaning with same name + // - discards the remaining with same name // - while keeping the same order items where added each(this._data, data => { data[0] === name @@ -340,38 +340,23 @@ * @return {Blob} [description] */ ['_blob'] () { - const boundary = '----formdata-polyfill-' + Math.random() - const chunks = [] - - for (const [name, value] of this) { - chunks.push(`--${boundary}\r\n`) - - if (value instanceof Blob) { - chunks.push( - `Content-Disposition: form-data; name="${name}"; filename="${value.name}"\r\n` + - `Content-Type: ${value.type || 'application/octet-stream'}\r\n\r\n`, - value, - '\r\n' - ) - } else { - chunks.push( - `Content-Disposition: form-data; name="${name}"\r\n\r\n${value}\r\n` - ) - } - } - - chunks.push(`--${boundary}--`) - - return new Blob(chunks, { - type: 'multipart/form-data; boundary=' + boundary - }) + const boundary = '----formdata-polyfill-' + Math.random(), + chunks = [], + p = `--${boundary}\r\nContent-Disposition: form-data; name="` + this.forEach((value, name) => typeof value == 'string' + ? chunks.push(p + escape(normalizeLinefeeds(name)) + `"\r\n\r\n${normalizeLinefeeds(value)}\r\n`) + : chunks.push(p + escape(normalizeLinefeeds(name)) + `"; filename="${escape(value.name)}"\r\nContent-Type: ${value.type||"application/octet-stream"}\r\n\r\n`, value, `\r\n`)) + chunks.push(`--${boundary}--`) + return new Blob(chunks, { + type: "multipart/form-data; boundary=" + boundary + }) } /** * The class itself is iterable * alias for formdata.entries() * - * @return {Iterator} + * @return {Iterator} */ [Symbol.iterator] () { return this.entries()