← All changes
|
assets/js/atomic-widgets-frontend-handler.js
+25
-61
4.0.9
→
4.0.0-beta1
View file →
| @@ -17,12 +17,11 @@ | ||
| 17 | 17 | var _alpinejs = __webpack_require__(/*! @elementor/alpinejs */ "@elementor/alpinejs"); |
| 18 | 18 | const LINK_ACTIONS_EDITOR_WHITELIST = ['off_canvas', 'lightbox']; |
| 19 | 19 | const WHITELIST_FILTER = 'frontend/handlers/atomic-widgets/link-actions-whitelist'; |
| 20 | 20 | const ACTION_LINK_SELECTOR = '[data-action-link]'; |
| 21 | -const REGISTRATION_SELECTOR = `${ACTION_LINK_SELECTOR}, :has(${ACTION_LINK_SELECTOR})`; | |
| 21 | +const REGISTRATION_SELECTOR = `${ACTION_LINK_SELECTOR}, :has(> ${ACTION_LINK_SELECTOR})`; | |
| 22 | 22 | const ATOMIC_FORM_SELECTOR = '[data-element_type="e-form"]'; |
| 23 | 23 | const ATOMIC_FORM_FIELD_SELECTOR = 'input[data-interaction-id], textarea[data-interaction-id]'; |
| 24 | -const ELEMENTOR_DOCUMENT_SELECTOR = '[data-elementor-id]'; | |
| 25 | 24 | (0, _frontendHandlers.registerBySelector)({ |
| 26 | 25 | id: 'atomic-link-action-handler', |
| 27 | 26 | selector: REGISTRATION_SELECTOR, |
| 28 | 27 | callback: ({ |
| @@ -35,21 +34,18 @@ | ||
| 35 | 34 | callback: ({ |
| 36 | 35 | element |
| 37 | 36 | }) => handleAtomicFormSubmit(element) |
| 38 | 37 | }); |
| 39 | -function handleLinkActions(registrationElement) { | |
| 40 | - if (!registrationElement) { | |
| 41 | - return; | |
| 42 | - } | |
| 43 | - const actionLinkElement = registrationElement.matches(ACTION_LINK_SELECTOR) ? registrationElement : registrationElement.querySelector(ACTION_LINK_SELECTOR); | |
| 44 | - if (!actionLinkElement) { | |
| 45 | - return; | |
| 46 | - } | |
| 47 | - const url = actionLinkElement.dataset.actionLink || actionLinkElement.getAttribute('href') || ''; | |
| 38 | +function handleLinkActions(element) { | |
| 39 | + const actionLinkElement = element.matches(ACTION_LINK_SELECTOR) ? element : element.querySelector(ACTION_LINK_SELECTOR); | |
| 40 | + const url = actionLinkElement?.dataset.actionLink; | |
| 48 | 41 | if (!url) { |
| 49 | 42 | return; |
| 50 | 43 | } |
| 51 | - const onClick = event => { | |
| 44 | + const handler = event => { | |
| 45 | + if (actionLinkElement && actionLinkElement !== element && !actionLinkElement.contains(event.target)) { | |
| 46 | + return; | |
| 47 | + } | |
| 52 | 48 | if (!shouldFireLinkActionHandler(url)) { |
| 53 | 49 | return; |
| 54 | 50 | } |
| 55 | 51 | if (!window.elementorFrontend?.utils?.urlActions) { |
| @@ -57,21 +53,17 @@ | ||
| 57 | 53 | } |
| 58 | 54 | event.preventDefault(); |
| 59 | 55 | elementorFrontend.utils.urlActions.runAction(url, event); |
| 60 | 56 | }; |
| 61 | - actionLinkElement.addEventListener('click', onClick); | |
| 62 | - return () => { | |
| 63 | - actionLinkElement.removeEventListener('click', onClick); | |
| 64 | - }; | |
| 57 | + element.addEventListener('click', handler); | |
| 58 | + return () => element.removeEventListener('click', handler); | |
| 65 | 59 | } |
| 66 | -function registerAtomicFormAlpineData(form) { | |
| 60 | +function handleAtomicFormSubmit(element) { | |
| 61 | + const form = element; | |
| 67 | 62 | if (!form || !_alpinejs.Alpine?.data) { |
| 68 | 63 | return; |
| 69 | 64 | } |
| 70 | - const alpineId = getAlpineId(form); | |
| 71 | - if (!alpineId) { | |
| 72 | - return; | |
| 73 | - } | |
| 65 | + const alpineId = getFormAlpineId(form); | |
| 74 | 66 | _alpinejs.Alpine.data(alpineId, () => ({ |
| 75 | 67 | async submit(event) { |
| 76 | 68 | if (isEditorContext()) { |
| 77 | 69 | return; |
| @@ -88,37 +80,27 @@ | ||
| 88 | 80 | const payload = buildAtomicFormPayload(form); |
| 89 | 81 | if (payload) { |
| 90 | 82 | try { |
| 91 | 83 | const response = await submitAtomicForm(payload); |
| 92 | - const state = response?.success ? 'success' : 'error'; | |
| 93 | - setFormState(form, state); | |
| 94 | - if (response?.success) { | |
| 95 | - form.reset(); | |
| 96 | - form.addEventListener('input', () => { | |
| 97 | - setFormState(form, 'default'); | |
| 98 | - }, { | |
| 99 | - once: true | |
| 100 | - }); | |
| 101 | - } | |
| 84 | + setFormState(element, response?.success ? 'success' : 'error'); | |
| 102 | 85 | } catch (error) { |
| 103 | - setFormState(form, 'error'); | |
| 86 | + setFormState(element, 'error'); | |
| 104 | 87 | } finally { |
| 105 | 88 | clearAtomicFormSubmittingState(form, submitButtons); |
| 106 | 89 | } |
| 107 | 90 | } else { |
| 108 | - setFormState(form, 'error'); | |
| 91 | + setFormState(element, 'error'); | |
| 109 | 92 | clearAtomicFormSubmittingState(form, submitButtons); |
| 110 | 93 | } |
| 111 | 94 | } |
| 112 | 95 | })); |
| 96 | + return () => { | |
| 97 | + _alpinejs.Alpine.destroyTree(form); | |
| 98 | + }; | |
| 113 | 99 | } |
| 114 | -function handleAtomicFormSubmit(form) { | |
| 115 | - registerAtomicFormAlpineData(form); | |
| 116 | - return refreshDom(form); | |
| 100 | +function getFormAlpineId(form) { | |
| 101 | + return form.getAttribute('x-data'); | |
| 117 | 102 | } |
| 118 | -function getAlpineId(element) { | |
| 119 | - return element.getAttribute('x-data'); | |
| 120 | -} | |
| 121 | 103 | function clearAtomicFormSubmittingState(form, submitButtons) { |
| 122 | 104 | delete form.dataset.atomicFormSubmitting; |
| 123 | 105 | submitButtons.forEach(button => { |
| 124 | 106 | button.disabled = false; |
| @@ -124,9 +106,9 @@ | ||
| 124 | 106 | button.disabled = false; |
| 125 | 107 | }); |
| 126 | 108 | } |
| 127 | 109 | function buildAtomicFormPayload(form) { |
| 128 | - const postId = getPostId(form); | |
| 110 | + const postId = getPostId(); | |
| 129 | 111 | const formId = form.dataset.id; |
| 130 | 112 | const formName = form.dataset.formName || ''; |
| 131 | 113 | const formFields = getAtomicFormFields(form); |
| 132 | 114 | if (!postId || !formFields.length) { |
| @@ -148,9 +130,9 @@ | ||
| 148 | 130 | return; |
| 149 | 131 | } |
| 150 | 132 | const label = getAtomicFormFieldLabel(input, form); |
| 151 | 133 | const type = getAtomicFormFieldType(input); |
| 152 | - const value = getAtomicFormFieldValue(input, type); | |
| 134 | + const value = input.value; | |
| 153 | 135 | fields.push({ |
| 154 | 136 | id, |
| 155 | 137 | type, |
| 156 | 138 | label, |
| @@ -178,14 +160,8 @@ | ||
| 178 | 160 | } |
| 179 | 161 | const placeholder = field.getAttribute('placeholder'); |
| 180 | 162 | return placeholder || ''; |
| 181 | 163 | } |
| 182 | -function getAtomicFormFieldValue(input, type) { | |
| 183 | - if ('checkbox' !== type) { | |
| 184 | - return input.value; | |
| 185 | - } | |
| 186 | - return input.checked ? input.value || 'on' : ''; | |
| 187 | -} | |
| 188 | 164 | function getAtomicFormFieldType(field) { |
| 189 | 165 | if (field.matches('textarea')) { |
| 190 | 166 | return 'textarea'; |
| 191 | 167 | } |
| @@ -233,12 +209,10 @@ | ||
| 233 | 209 | } |
| 234 | 210 | element.classList.remove('form-state-default', 'form-state-success', 'form-state-error'); |
| 235 | 211 | element.classList.add(`form-state-${state}`); |
| 236 | 212 | } |
| 237 | -function getPostId(form) { | |
| 238 | - const innerDocumentId = form?.closest?.(ELEMENTOR_DOCUMENT_SELECTOR)?.dataset?.elementorId; | |
| 239 | - const ownerDocument = elementorFrontend?.config?.post?.id; | |
| 240 | - return innerDocumentId || ownerDocument || null; | |
| 213 | +function getPostId() { | |
| 214 | + return elementorFrontend?.config?.post?.id || null; | |
| 241 | 215 | } |
| 242 | 216 | function shouldFireLinkActionHandler(url) { |
| 243 | 217 | if (!isEditorContext()) { |
| 244 | 218 | return true; |
| @@ -254,18 +228,8 @@ | ||
| 254 | 228 | return !!whitelist.find(allowedAction => action.includes(allowedAction)); |
| 255 | 229 | } |
| 256 | 230 | function isEditorContext() { |
| 257 | 231 | return !!window.elementor || !!window.parent?.elementor; |
| 258 | -} | |
| 259 | -function refreshDom(element) { | |
| 260 | - if (!_alpinejs.Alpine?.nextTick || !_alpinejs.Alpine?.destroyTree || !_alpinejs.Alpine?.initTree) { | |
| 261 | - return; | |
| 262 | - } | |
| 263 | - _alpinejs.Alpine.nextTick(() => { | |
| 264 | - _alpinejs.Alpine.destroyTree(element); | |
| 265 | - _alpinejs.Alpine.initTree(element); | |
| 266 | - }); | |
| 267 | - return () => _alpinejs.Alpine.destroyTree(element); | |
| 268 | 232 | } |
| 269 | 233 | |
| 270 | 234 | /***/ }), |
| 271 | 235 | |