Skip to content

Commit

Permalink
💥 Make template slots behave more like vanilla custom element slots
Browse files Browse the repository at this point in the history
  • Loading branch information
skerit committed May 9, 2024
1 parent bfe71b6 commit fc67f0d
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 24 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
25 changes: 15 additions & 10 deletions lib/core/hawkejs.js
Original file line number Diff line number Diff line change
Expand Up @@ -2247,25 +2247,25 @@ defStat(function appendChildren(target, new_children) {
*
* @author Jelle De Loecker <jelle@develry.be>
* @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);
});

/**
* Get elements by attribute name/value
*
* @author Jelle De Loecker <jelle@develry.be>
* @since 2.0.0
* @version 2.0.0
* @version 2.4.0
*
* @param {Array} result
* @param {HTMLElement} element
Expand All @@ -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;
Expand All @@ -2290,20 +2290,25 @@ 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];

if (!child || !child.hasAttribute) {
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;
Expand Down
14 changes: 7 additions & 7 deletions lib/element/custom_element.js
Original file line number Diff line number Diff line change
Expand Up @@ -2623,7 +2623,7 @@ Element.setMethod(function afterRender(callback) {
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 2.1.3
* @version 2.3.17
* @version 2.4.0
*
* @param {boolean} clear_content
* @param {boolean} re_render
Expand Down Expand Up @@ -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 = {};
Expand Down Expand Up @@ -2721,7 +2721,7 @@ function _extractSlotData(clear_content, re_render) {
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 2.1.3
* @version 2.1.3
* @version 2.4.0
*
* @param {Object} slot_data
*/
Expand All @@ -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]]);
}
}
};
Expand Down
6 changes: 3 additions & 3 deletions test/05-custom_elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ describe('CustomElement', function() {
let compiled = hawkejs.compile('template_test_2', code);

let result = await renderWithPledge(compiled);
assertEqualHtml(result.html, '<template-slot-test he-rendered="1"><div data-he-slot="main">This will set the content of the <b>main</b> slot</div></template-slot-test>');
assertEqualHtml(result.html, '<template-slot-test he-rendered="1"><slot name="main"><div slot="main">This will set the content of the <b>main</b> slot</div></slot></template-slot-test>');
});

it('should not confuse slots with similar elements', async function() {
Expand All @@ -643,7 +643,7 @@ describe('CustomElement', function() {
let compiled = hawkejs.compile('template_test_3', code);

let result = await renderWithPledge(compiled);
assertEqualHtml(result.html, '<template-slot-test he-rendered="1"><div data-he-slot="main">Slot test 1</div></template-slot-test>\n<template-slot-test he-rendered="1"><div data-he-slot="main">Slot test 2</div></template-slot-test>');
assertEqualHtml(result.html, '<template-slot-test he-rendered="1"><slot name="main"><div slot="main">Slot test 1</div></slot></template-slot-test> <template-slot-test he-rendered="1"><slot name="main"><div slot="main">Slot test 2</div></slot></template-slot-test>');
});

it('should render the contents after the attributes have been set', async function() {
Expand All @@ -658,7 +658,7 @@ describe('CustomElement', function() {
assertEqualHtml(result.html, '<render-after-attributes title="pretty-title" he-rendered="1"><span class="title">pretty-title</span></render-after-attributes>');
});

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');

Expand Down
2 changes: 1 addition & 1 deletion test/10-expressions.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ describe('Expressions', function() {
let tests = [
[
`{% include "partials/template_slot_test" %}`,
`<div data-he-slot="main">Default main slot</div>`
`<slot name="main">Default main slot</slot>`
],
[
`{% include "partials/print_title_var" title="Test" %}`,
Expand Down
4 changes: 2 additions & 2 deletions test/11-custom_elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ describe('CustomElement', function() {

let result = await renderWithPledge(compiled);

assertEqualHtml(result.html, '<template-slot-test he-rendered="1"><div data-he-slot="main">This will set the content of the <b>main</b> slot</div></template-slot-test>');
assertEqualHtml(result.html, '<template-slot-test he-rendered="1"><slot name="main"><div slot="main">This will set the content of the <b>main</b> slot</div></slot></template-slot-test>');
});

it('should not confuse slots with similar elements', async function() {
Expand All @@ -527,7 +527,7 @@ describe('CustomElement', function() {

let result = await renderWithPledge(compiled);

assertEqualHtml(result.html, '<template-slot-test he-rendered="1"><div data-he-slot="main">Slot test 1</div></template-slot-test>\n<template-slot-test he-rendered="1"><div data-he-slot="main">Slot test 2</div></template-slot-test>');
assertEqualHtml(result.html, '<template-slot-test he-rendered="1"><slot name="main"><div slot="main">Slot test 1</div></slot></template-slot-test> <template-slot-test he-rendered="1"><slot name="main"><div slot="main">Slot test 2</div></slot></template-slot-test>');
});

it('should render the contents after the attributes have been set', async function() {
Expand Down
2 changes: 1 addition & 1 deletion test/templates/partials/template_slot_test.hwk
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<div data-he-slot="main">Default main slot</div>
<slot name="main">Default main slot</slot>

0 comments on commit fc67f0d

Please sign in to comment.