From fc67f0d0d2665829903b9f641de74e31ae986de4 Mon Sep 17 00:00:00 2001 From: Jelle De Loecker Date: Thu, 9 May 2024 16:48:28 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=A5=20Make=20template=20slots=20behave?= =?UTF-8?q?=20more=20like=20vanilla=20custom=20element=20slots?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + lib/core/hawkejs.js | 25 +++++++++++-------- lib/element/custom_element.js | 14 +++++------ test/05-custom_elements.js | 6 ++--- test/10-expressions.js | 2 +- test/11-custom_elements.js | 4 +-- .../templates/partials/template_slot_test.hwk | 2 +- 7 files changed, 30 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2d43485..9c3e9351 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ * Add support for ternary conditionals * Add `CustomElement.defineStateVariable(name, config)` static method * Add `CustomElement#setState(name, value)` and `CustomElement#getState(name)` methods +* Make *template slots* behave more like vanilla custom element slots ## 2.3.19 (2024-04-13) diff --git a/lib/core/hawkejs.js b/lib/core/hawkejs.js index 7e065fde..0a73681b 100644 --- a/lib/core/hawkejs.js +++ b/lib/core/hawkejs.js @@ -2247,17 +2247,17 @@ defStat(function appendChildren(target, new_children) { * * @author Jelle De Loecker * @since 2.0.0 - * @version 2.0.0 + * @version 2.4.0 * * @param {HTMLElement} element - * @param {String} name + * @param {String} names * @param {String} value * * @return {Array} */ -defStat(function getElementsByAttribute(element, name, value) { +defStat(function getElementsByAttribute(element, names, value) { var check_value = arguments.length > 2; - return _getElementsByAttribute([], check_value, element, name, value); + return _getElementsByAttribute([], check_value, element, names, value); }); /** @@ -2265,7 +2265,7 @@ defStat(function getElementsByAttribute(element, name, value) { * * @author Jelle De Loecker * @since 2.0.0 - * @version 2.0.0 + * @version 2.4.0 * * @param {Array} result * @param {HTMLElement} element @@ -2274,7 +2274,7 @@ defStat(function getElementsByAttribute(element, name, value) { * * @return {Array} */ -function _getElementsByAttribute(result, check_value, element, name, value) { +function _getElementsByAttribute(result, check_value, element, names, value) { if (typeof element == 'string' || element.nodeType != 1) { return; @@ -2290,6 +2290,8 @@ function _getElementsByAttribute(result, check_value, element, name, value) { children = element.children; } + names = Array.cast(names); + for (i = 0; i < children.length; i++) { child = children[i]; @@ -2297,13 +2299,16 @@ function _getElementsByAttribute(result, check_value, element, name, value) { continue; } - if (child.hasAttribute(name)) { - if (!check_value || child.getAttribute(name) == value) { - result.push(child); + for (let name of names) { + if (child.hasAttribute(name)) { + if (!check_value || child.getAttribute(name) == value) { + result.push(child); + break; + } } } - _getElementsByAttribute(result, check_value, child, name, value); + _getElementsByAttribute(result, check_value, child, names, value); } return result; diff --git a/lib/element/custom_element.js b/lib/element/custom_element.js index dab91b21..7f2d0f1e 100644 --- a/lib/element/custom_element.js +++ b/lib/element/custom_element.js @@ -2623,7 +2623,7 @@ Element.setMethod(function afterRender(callback) { * * @author Jelle De Loecker * @since 2.1.3 - * @version 2.3.17 + * @version 2.4.0 * * @param {boolean} clear_content * @param {boolean} re_render @@ -2671,11 +2671,11 @@ function _extractSlotData(clear_content, re_render) { // If this element is being re-rendered, the slots have already been used. // We need to extract them from the children if (re_render) { - let slot_elements = this.querySelectorAll('[data-he-slot]'); + let slot_elements = this.querySelectorAll('[data-he-slot],[slot]'); for (i = 0; i < slot_elements.length; i++) { child = slot_elements[i]; - slot_name = child.getAttribute('data-he-slot'); + slot_name = child.getAttribute('data-he-slot') || child.getAttribute('slot'); if (!slots) { slots = {}; @@ -2721,7 +2721,7 @@ function _extractSlotData(clear_content, re_render) { * * @author Jelle De Loecker * @since 2.1.3 - * @version 2.1.3 + * @version 2.4.0 * * @param {Object} slot_data */ @@ -2731,17 +2731,17 @@ function _insertSlotData(slot_data) { return; } - let slots = Hawkejs.getElementsByAttribute(this, 'data-he-slot'), + let slots = this.querySelectorAll('slot'), slot, name, i; for (i = 0; i < slots.length; i++) { slot = slots[i]; - name = slot.dataset.heSlot; + name = slot.getAttribute('name'); if (slot_data.slots[name]) { - Hawkejs.replaceChildren(slot, slot_data.slots[name].childNodes); + Hawkejs.replaceChildren(slot, [slot_data.slots[name]]); } } }; diff --git a/test/05-custom_elements.js b/test/05-custom_elements.js index cbe21d17..6a14d188 100644 --- a/test/05-custom_elements.js +++ b/test/05-custom_elements.js @@ -628,7 +628,7 @@ describe('CustomElement', function() { let compiled = hawkejs.compile('template_test_2', code); let result = await renderWithPledge(compiled); - assertEqualHtml(result.html, '
This will set the content of the main slot
'); + assertEqualHtml(result.html, '
This will set the content of the main slot
'); }); it('should not confuse slots with similar elements', async function() { @@ -643,7 +643,7 @@ describe('CustomElement', function() { let compiled = hawkejs.compile('template_test_3', code); let result = await renderWithPledge(compiled); - assertEqualHtml(result.html, '
Slot test 1
\n
Slot test 2
'); + assertEqualHtml(result.html, '
Slot test 1
Slot test 2
'); }); it('should render the contents after the attributes have been set', async function() { @@ -658,7 +658,7 @@ describe('CustomElement', function() { assertEqualHtml(result.html, 'pretty-title'); }); - it('should render the contents after the attribtues have been set (within extensions)', async function() { + it('should render the contents after the attributes have been set (within extensions)', async function() { await setLocation('/render_after_attributes'); diff --git a/test/10-expressions.js b/test/10-expressions.js index c4896eb8..da8dd3cb 100644 --- a/test/10-expressions.js +++ b/test/10-expressions.js @@ -244,7 +244,7 @@ describe('Expressions', function() { let tests = [ [ `{% include "partials/template_slot_test" %}`, - `
Default main slot
` + `Default main slot` ], [ `{% include "partials/print_title_var" title="Test" %}`, diff --git a/test/11-custom_elements.js b/test/11-custom_elements.js index c0439ae6..a938c809 100644 --- a/test/11-custom_elements.js +++ b/test/11-custom_elements.js @@ -511,7 +511,7 @@ describe('CustomElement', function() { let result = await renderWithPledge(compiled); - assertEqualHtml(result.html, '
This will set the content of the main slot
'); + assertEqualHtml(result.html, '
This will set the content of the main slot
'); }); it('should not confuse slots with similar elements', async function() { @@ -527,7 +527,7 @@ describe('CustomElement', function() { let result = await renderWithPledge(compiled); - assertEqualHtml(result.html, '
Slot test 1
\n
Slot test 2
'); + assertEqualHtml(result.html, '
Slot test 1
Slot test 2
'); }); it('should render the contents after the attributes have been set', async function() { diff --git a/test/templates/partials/template_slot_test.hwk b/test/templates/partials/template_slot_test.hwk index fe5e7ecc..03ee5323 100644 --- a/test/templates/partials/template_slot_test.hwk +++ b/test/templates/partials/template_slot_test.hwk @@ -1 +1 @@ -
Default main slot
\ No newline at end of file +Default main slot \ No newline at end of file