assets/unpoly/unpoly.js in unpoly-rails-3.7.1 vs assets/unpoly/unpoly.js in unpoly-rails-3.7.2

- old
+ new

@@ -3,11 +3,11 @@ /* 0 */, /* 1 */ /***/ (() => { window.up = { - version: '3.7.1' + version: '3.7.2' }; /***/ }), /* 2 */ @@ -1987,13 +1987,10 @@ } execute() { this._rendered = this._executePromise(); return this; } - getPreflightFragments() { - return this._getChange().getPreflightProps().fragments; - } async _executePromise() { try { this._guardRender(); let result = await this._getChange().execute(); this._handleResult(result); @@ -3666,13 +3663,11 @@ this._watchFieldsWithin(this._root); this._root.addEventListener('up:fragment:inserted', ({ target }) => { if (target !== this._root) this._watchFieldsWithin(target); }); - for (let abortableElement of this._abortableElements()) { - this._unbindFns.push(up.fragment.onAborted(abortableElement, () => this._abort())); - } + this._unbindFns.push(up.fragment.onAborted(this._scope, () => this._abort())); this._unbindFns.push(up.on(this._scope, 'reset', () => this._onFormReset())); } stop() { this._abort(); for (let unbindFn of this._unbindFns) @@ -3680,18 +3675,10 @@ } _fieldOptions(field) { let rootOptions = u.copy(this._options); return up.form.watchOptions(field, rootOptions, { defaults: { event: 'input' } }); } - _abortableElements() { - if (this._abortable === false) { - return []; - } - else { - return u.wrapList(this._abortable ?? this._scope); - } - } _watchFieldsWithin(container) { for (let field of up.form.fields(container)) { this._watchField(field); } } @@ -3794,14 +3781,18 @@ this._rendering = false; this._resetNextRenderPromise(); this._honorAbort(); } _honorAbort() { - up.fragment.onAborted(this._form, { around: true }, ({ target }) => this._unscheduleSolutionsWithin(target)); + up.fragment.onAborted(this._form, (event) => this._onAborted(event)); } - _unscheduleSolutionsWithin(container) { - this._dirtySolutions = u.reject(this._dirtySolutions, ({ element }) => container.contains(element)); + _onAborted(event) { + if (this._dirtySolutions.length) { + this._dirtySolutions = []; + this._nextRenderPromise.reject(new up.Aborted(event.reason)); + this._resetNextRenderPromise(); + } } _resetNextRenderPromise() { this._nextRenderPromise = u.newDeferred(); } watchContainer(fieldOrForm) { @@ -3878,24 +3869,26 @@ return up.form.watchOptions(element, overrideOptions, { defaults: { event: 'change' } }); } _scheduleNextRender() { let solutionDelays = this._dirtySolutions.map((solution) => solution.renderOptions.delay); let shortestDelay = Math.min(...solutionDelays) || 0; - this._unscheduleNextRender(); - this._nextRenderTimer = u.timer(shortestDelay, () => this._renderDirtySolutions()); - } - _unscheduleNextRender() { clearTimeout(this._nextRenderTimer); + this._nextRenderTimer = u.timer(shortestDelay, () => { + this._nextRenderTimer = null; + this._renderDirtySolutions(); + }); } _renderDirtySolutions() { up.error.muteUncriticalRejection(this._doRenderDirtySolutions()); } async _doRenderDirtySolutions() { - this._dirtySolutions = u.filter(this._dirtySolutions, ({ element, origin }) => up.fragment.isAlive(element) && up.fragment.isAlive(origin)); - if (!this._dirtySolutions.length || this._rendering) { + if (!this._dirtySolutions.length) return; - } + if (this._rendering) + return; + if (this._nextRenderTimer) + return; let dirtySolutions = this._dirtySolutions; this._dirtySolutions = []; let dirtyOrigins = u.map(dirtySolutions, 'origin'); let dirtyFields = u.flatMap(dirtyOrigins, up.form.fields); let dirtyNames = u.uniq(u.map(dirtyFields, 'name')); @@ -3905,10 +3898,11 @@ options.target = u.map(dirtySolutions, 'target').join(', '); options.feedback = u.some(dirtyRenderOptionsList, 'feedback'); options.origin = this._form; options.focus ??= 'keep'; options.failOptions = false; + options.defaultMaybe = true; options.params = up.Params.merge(options.params, ...u.map(dirtyRenderOptionsList, 'params')); options.headers = u.merge(...u.map(dirtyRenderOptionsList, 'headers')); this._addValidateHeader(options.headers, dirtyNames); options.guardEvent = up.event.build('up:form:validate', { fields: dirtyFields, @@ -8542,17 +8536,18 @@ function splitTarget(target) { return u.parseTokens(target, { separator: 'comma' }); } function parseTargetSteps(target, options = {}) { let defaultPlacement = options.defaultPlacement || 'swap'; + let defaultMaybe = options.defaultMaybe ?? false; let steps = []; let simpleSelectors = splitTarget(target); for (let selector of simpleSelectors) { if (selector === ':none') continue; let placement = defaultPlacement; - let maybe = false; + let maybe = defaultMaybe; selector = selector.replace(/\b::?(before|after)\b/, (_match, customPlacement) => { placement = customPlacement; return ''; }); selector = selector.replace(/\b:maybe\b/, () => { @@ -8592,12 +8587,12 @@ } function shouldRevalidate(request, response, options = {}) { return request.fromCache && u.evalAutoOption(options.revalidate, config.autoRevalidate, response); } function targetForSteps(steps) { - let requiredSteps = u.reject(steps, 'maybe'); - let selectors = u.map(requiredSteps, 'selector'); + let bestSteps = steps.filter((step) => !step.maybe || step.oldElement?.isConnected); + let selectors = u.map(bestSteps, 'selector'); return selectors.join(', ') || ':none'; } function isContainedByRivalStep(steps, candidateStep) { return u.some(steps, function (rivalStep) { return (rivalStep !== candidateStep) && @@ -8629,17 +8624,15 @@ reason ||= 'Aborting requests within ' + layers.join(', '); } let testFnWithAbortable = (request) => request.abortable && testFn(request); up.network.abort(testFnWithAbortable, { ...options, reason }); for (let element of elements) { - up.emit(element, 'up:fragment:aborted', { newLayer, log: false }); + up.emit(element, 'up:fragment:aborted', { reason, newLayer, log: false }); } } - function onAborted(fragment, ...args) { - let callback = u.extractCallback(args); - let options = u.extractOptions(args); - let guard = (event) => event.target.contains(fragment) || (options.around && fragment.contains(event.target)); + function onAborted(fragment, callback) { + let guard = (event) => event.target.contains(fragment); let unsubscribe = up.on('up:fragment:aborted', { guard }, callback); up.destructor(fragment, unsubscribe); return unsubscribe; } up.on('up:framework:boot', function () { @@ -10044,15 +10037,12 @@ } function submitButtonSelector() { return config.selector('submitButtonSelectors'); } const submit = up.mockable((form, options) => { - return buildSubmitJob(form, options).execute(); + return up.render(submitOptions(form, options)); }); - function buildSubmitJob(form, options) { - return new up.RenderJob(submitOptions(form, options)); - } function submitOptions(form, options, parserOptions) { form = getForm(form); options = u.options(options); let parser = new up.OptionsParser(form, options, parserOptions); parser.include(destinationOptions); @@ -10065,13 +10055,10 @@ }); options.origin ||= up.viewport.focusedElementWithin(form) || options.submitButton || form; parser.include(up.link.followOptions); return options; } - function getPreflightFragments(form) { - return buildSubmitJob(form).getPreflightFragments(); - } function watchOptions(field, options, parserOptions = {}) { options = u.options(options); let parser = new up.OptionsParser(field, options, { ...parserOptions, closest: true, attrPrefix: 'up-watch-' }); parser.boolean('feedback'); parser.booleanOrString('disable'); @@ -10191,13 +10178,11 @@ if (rawCallback) { return up.NonceableCallback.fromString(rawCallback).toFunction('value', 'name').bind(element); } } function autosubmit(target, options = {}) { - const form = getForm(target); - options.abortable ??= [form, ...getPreflightFragments(form)]; - const onChange = (_value, _name, renderOptions) => submit(target, renderOptions); - return watch(target, options, onChange); + const onChange = (_diff, renderOptions) => submit(target, renderOptions); + return watch(target, { options, batch: true }, onChange); } function getGroupSelectors() { return up.migrate.migratedFormGroupSelectors?.() || config.groupSelectors; } function findGroup(field) { \ No newline at end of file