From 8bba67137933dd41565f1fef6ea303366aeb75fd Mon Sep 17 00:00:00 2001 From: Johannes Raggam Date: Sun, 5 Nov 2023 15:31:21 +0100 Subject: [PATCH 1/3] maint(core utils): Modernize code for findRelatives. --- src/core/utils.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/core/utils.js b/src/core/utils.js index a2cc666ce..4493b3503 100644 --- a/src/core/utils.js +++ b/src/core/utils.js @@ -494,18 +494,22 @@ function parseLength(length, reference_length = null) { // Return a jQuery object with elements related to an input element. function findRelatives(el) { - var $el = $(el), - $relatives = $(el), - $label = $(); + const $el = $(el); + let $relatives = $(el); + let $label = $(); $relatives = $relatives.add($el.closest("label")); $relatives = $relatives.add($el.closest("fieldset")); - if (el.id) $label = $("label[for='" + el.id + "']"); + if (el.id) { + $label = $(`label[for="${el.id}"]`); + } if (!$label.length) { - var $form = $el.closest("form"); - if (!$form.length) $form = $(document.body); - $label = $form.find("label[for='" + el.name + "']"); + let $form = $el.closest("form"); + if (!$form.length) { + $form = $(document.body); + } + $label = $form.find(`label[for="${el.name}"]`); } $relatives = $relatives.add($label); return $relatives; From 2a53aeb973715cbcd834d13417bed3d67bbbaa42 Mon Sep 17 00:00:00 2001 From: Johannes Raggam Date: Sun, 5 Nov 2023 15:28:50 +0100 Subject: [PATCH 2/3] maint(lib dependshandler): Modernize code. --- src/lib/dependshandler.js | 56 +++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/src/lib/dependshandler.js b/src/lib/dependshandler.js index 770ad487d..05e912217 100644 --- a/src/lib/dependshandler.js +++ b/src/lib/dependshandler.js @@ -11,48 +11,60 @@ function DependsHandler($el, expression) { DependsHandler.prototype = { _findInputs: function (name) { - var $input = this.$context.find(":input[name='" + name + "']"); - if (!$input.length) $input = $("#" + name); + let $input = this.$context.find(":input[name='" + name + "']"); // TODO input outside form + if (!$input.length) { + $input = $("#" + name); + } return $input; }, _getValue: function (name) { - var $input = this._findInputs(name); - if (!$input.length) return null; - - if ($input.attr("type") === "radio" || $input.attr("type") === "checkbox") + const $input = this._findInputs(name); + if (!$input.length) { + return null; + } + if ($input.attr("type") === "radio" || $input.attr("type") === "checkbox") { return $input.filter(":checked").val() || null; - else return $input.val(); + } + return $input.val(); }, getAllInputs: function () { - var todo = [this.ast], - $inputs = $(), - node; + const todo = [this.ast]; + let $inputs = $(); + let node; while (todo.length) { node = todo.shift(); - if (node.input) $inputs = $inputs.add(this._findInputs(node.input)); - if (node.children && node.children.length) + if (node.input) { + $inputs = $inputs.add(this._findInputs(node.input)); + } + if (node.children && node.children.length) { todo.push.apply(todo, node.children); + } } return $inputs; }, _evaluate: function (node) { - var value = node.input ? this._getValue(node.input) : null, - i; + const value = node.input ? this._getValue(node.input) : null; switch (node.type) { case "NOT": return !this._evaluate(node.children[0]); case "AND": - for (i = 0; i < node.children.length; i++) - if (!this._evaluate(node.children[i])) return false; + for (const child of node.children) { + if (!this._evaluate(child)) { + return false; + } + } return true; case "OR": - for (i = 0; i < node.children.length; i++) - if (this._evaluate(node.children[i])) return true; + for (const child of node.children) { + if (this._evaluate(child)) { + return true; + } + } return false; case "comparison": switch (node.operator) { @@ -69,10 +81,14 @@ DependsHandler.prototype = { case ">=": return value >= node.value; case "~=": - if (value === null) return false; + if (value === null) { + return false; + } return value.indexOf(node.value) != -1; case "=~": - if (value === null || !node.value) return false; + if (value === null || !node.value) { + return false; + } return node.value.indexOf(value) != -1; } break; From 3b0a4177b11998414172b592d2743ce327404720 Mon Sep 17 00:00:00 2001 From: Johannes Raggam Date: Mon, 6 Nov 2023 01:51:08 +0100 Subject: [PATCH 3/3] feat: Improve support for input elements outside form. --- src/core/utils.js | 6 ++---- src/lib/dependshandler.js | 6 +++--- src/pat/auto-suggest/auto-suggest.js | 2 +- src/pat/close-panel/close-panel.js | 2 +- src/pat/image-crop/image-crop.js | 2 +- src/pat/sortable/sortable.js | 2 +- 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/core/utils.js b/src/core/utils.js index 4493b3503..8fa1baf53 100644 --- a/src/core/utils.js +++ b/src/core/utils.js @@ -494,6 +494,7 @@ function parseLength(length, reference_length = null) { // Return a jQuery object with elements related to an input element. function findRelatives(el) { + el = jqToNode(el); const $el = $(el); let $relatives = $(el); let $label = $(); @@ -505,10 +506,7 @@ function findRelatives(el) { $label = $(`label[for="${el.id}"]`); } if (!$label.length) { - let $form = $el.closest("form"); - if (!$form.length) { - $form = $(document.body); - } + const $form = $(el.form || el.closest("form") || document.body); $label = $form.find(`label[for="${el.name}"]`); } $relatives = $relatives.add($label); diff --git a/src/lib/dependshandler.js b/src/lib/dependshandler.js index 05e912217..0b9796c97 100644 --- a/src/lib/dependshandler.js +++ b/src/lib/dependshandler.js @@ -1,11 +1,11 @@ import $ from "jquery"; import parser from "./depends_parse"; +import utils from "../core/utils"; function DependsHandler($el, expression) { - var $context = $el.closest("form"); - if (!$context.length) $context = $(document); + const el = utils.jqToNode($el); this.$el = $el; - this.$context = $context; + this.$context = $(el.form || el.closest("form") || document); this.ast = parser.parse(expression); // TODO: handle parse exceptions here } diff --git a/src/pat/auto-suggest/auto-suggest.js b/src/pat/auto-suggest/auto-suggest.js index 6548957bd..1f7524aa1 100644 --- a/src/pat/auto-suggest/auto-suggest.js +++ b/src/pat/auto-suggest/auto-suggest.js @@ -132,7 +132,7 @@ export default Base.extend({ // Clear values on reset. events.add_event_listener( - this.el.closest("form"), + this.el.form || this.el.closest("form"), // TODO: `closest` necessary? "reset", "pat-auto-suggest--reset", () => this.$el.select2("val", "") diff --git a/src/pat/close-panel/close-panel.js b/src/pat/close-panel/close-panel.js index 2f8436ea4..5486f54b3 100644 --- a/src/pat/close-panel/close-panel.js +++ b/src/pat/close-panel/close-panel.js @@ -27,7 +27,7 @@ export default Base.extend({ if ( e.target.matches(":not([formnovalidate])") && e.target.matches("[type=submit], button:not([type=button])") && - this.el.closest("form")?.checkValidity() === false + this.el.form?.checkValidity() === false ) { // Prevent closing an invalid form when submitting. return; diff --git a/src/pat/image-crop/image-crop.js b/src/pat/image-crop/image-crop.js index a9f4be408..789eff90a 100644 --- a/src/pat/image-crop/image-crop.js +++ b/src/pat/image-crop/image-crop.js @@ -52,7 +52,7 @@ var _ = { // Set the form ID if (opts.formId.length === 0) { // no form ID supplied. Look for the closest parent form element - data.form = $this.closest("form"); + data.form = $(this.form || this.closest("form")); if (data.form.length === 0) { log.error("No form specified or found"); return; diff --git a/src/pat/sortable/sortable.js b/src/pat/sortable/sortable.js index 2dc4c9c44..c87ed17ff 100644 --- a/src/pat/sortable/sortable.js +++ b/src/pat/sortable/sortable.js @@ -20,7 +20,7 @@ export default Base.extend({ if (window.__patternslib_import_styles) { import("./_sortable.scss"); } - this.$form = this.$el.closest("form"); + this.$form = $(this.el.form || this.el.closest("form")); this.options = parser.parse(this.$el, false); this.recordPositions().initScrolling(); this.$el.on("pat-update", this.onPatternUpdate.bind(this));