Skip to content

Commit

Permalink
Improve morph support for <template> elements
Browse files Browse the repository at this point in the history
Closes [bigskysoftware#15][]

When morphing `<template>` elements, treat the [DocumentFragment][]
instances returned from the [HTMLTemplateElement.content][] properties
as `morphChildren` methods' `newParent` and `oldParent` variables.

That way, descendant nodes can be iterated across the
connected-disconnected boundary.

[bigskysoftware#15]: bigskysoftware#15
[DocumentFragment]:
[HTMLTemplateElement.content]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLTemplateElement/content
  • Loading branch information
seanpdoyle committed Apr 12, 2024
1 parent f75fba1 commit f5b02eb
Show file tree
Hide file tree
Showing 11 changed files with 38 additions and 6 deletions.
8 changes: 6 additions & 2 deletions dist/idiomorph-ext.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ var Idiomorph = (function () {
* @returns {boolean}
*/
function ignoreValueOfActiveElement(possibleActiveElement, ctx) {
return ctx.ignoreActiveValue && possibleActiveElement === document.activeElement;
return ctx.ignoreActiveValue && possibleActiveElement === document.activeElement && possibleActiveElement !== document.body;
}

/**
Expand Down Expand Up @@ -177,6 +177,10 @@ var Idiomorph = (function () {
* @param ctx the merge context
*/
function morphChildren(newParent, oldParent, ctx) {
if (newParent instanceof HTMLTemplateElement && oldParent instanceof HTMLTemplateElement) {
newParent = newParent.content;
oldParent = oldParent.content;
}

let nextNewChild = newParent.firstChild;
let insertionPoint = oldParent.firstChild;
Expand Down Expand Up @@ -860,7 +864,7 @@ var Idiomorph = (function () {
htmx.defineExtension('morph', {
isInlineSwap: function(swapStyle) {
let config = createMorphConfig(swapStyle);
return config.swapStyle === "outerHTML" || config.swapStyle == null;
return config?.morphStyle === "outerHTML" || config?.morphStyle == null;
},
handleSwap: function (swapStyle, target, fragment) {
let config = createMorphConfig(swapStyle);
Expand Down
2 changes: 1 addition & 1 deletion dist/idiomorph-ext.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/idiomorph-htmx.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
htmx.defineExtension('morph', {
isInlineSwap: function(swapStyle) {
let config = createMorphConfig(swapStyle);
return config.swapStyle === "outerHTML" || config.swapStyle == null;
return config?.morphStyle === "outerHTML" || config?.morphStyle == null;
},
handleSwap: function (swapStyle, target, fragment) {
let config = createMorphConfig(swapStyle);
Expand Down
4 changes: 4 additions & 0 deletions dist/idiomorph.amd.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ var Idiomorph = (function () {
* @param ctx the merge context
*/
function morphChildren(newParent, oldParent, ctx) {
if (newParent instanceof HTMLTemplateElement && oldParent instanceof HTMLTemplateElement) {
newParent = newParent.content;
oldParent = oldParent.content;
}

let nextNewChild = newParent.firstChild;
let insertionPoint = oldParent.firstChild;
Expand Down
4 changes: 4 additions & 0 deletions dist/idiomorph.cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ var Idiomorph = (function () {
* @param ctx the merge context
*/
function morphChildren(newParent, oldParent, ctx) {
if (newParent instanceof HTMLTemplateElement && oldParent instanceof HTMLTemplateElement) {
newParent = newParent.content;
oldParent = oldParent.content;
}

let nextNewChild = newParent.firstChild;
let insertionPoint = oldParent.firstChild;
Expand Down
4 changes: 4 additions & 0 deletions dist/idiomorph.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ var Idiomorph = (function () {
* @param ctx the merge context
*/
function morphChildren(newParent, oldParent, ctx) {
if (newParent instanceof HTMLTemplateElement && oldParent instanceof HTMLTemplateElement) {
newParent = newParent.content;
oldParent = oldParent.content;
}

let nextNewChild = newParent.firstChild;
let insertionPoint = oldParent.firstChild;
Expand Down
6 changes: 5 additions & 1 deletion dist/idiomorph.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ var Idiomorph = (function () {
* @returns {boolean}
*/
function ignoreValueOfActiveElement(possibleActiveElement, ctx) {
return ctx.ignoreActiveValue && possibleActiveElement === document.activeElement;
return ctx.ignoreActiveValue && possibleActiveElement === document.activeElement && possibleActiveElement !== document.body;
}

/**
Expand Down Expand Up @@ -177,6 +177,10 @@ var Idiomorph = (function () {
* @param ctx the merge context
*/
function morphChildren(newParent, oldParent, ctx) {
if (newParent instanceof HTMLTemplateElement && oldParent instanceof HTMLTemplateElement) {
newParent = newParent.content;
oldParent = oldParent.content;
}

let nextNewChild = newParent.firstChild;
let insertionPoint = oldParent.firstChild;
Expand Down
2 changes: 1 addition & 1 deletion dist/idiomorph.min.js

Large diffs are not rendered by default.

Binary file modified dist/idiomorph.min.js.gz
Binary file not shown.
4 changes: 4 additions & 0 deletions src/idiomorph.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ var Idiomorph = (function () {
* @param ctx the merge context
*/
function morphChildren(newParent, oldParent, ctx) {
if (newParent instanceof HTMLTemplateElement && oldParent instanceof HTMLTemplateElement) {
newParent = newParent.content;
oldParent = oldParent.content;
}

let nextNewChild = newParent.firstChild;
let insertionPoint = oldParent.firstChild;
Expand Down
8 changes: 8 additions & 0 deletions test/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,14 @@ describe("Core morphing tests", function(){
initial.outerHTML.should.equal("<div></div>");
});

it('can morph a template tag properly', function()
{
let initial = make("<template data-old>Foo</template>");
let final = make("<template data-new>Bar</template>");
Idiomorph.morph(initial, final);
initial.outerHTML.should.equal(final.outerHTML);
});

it('ignores active element when ignoreActive set to true', function()
{
let initialSource = "<div><div id='d1'>Foo</div><input id='i1'></div>";
Expand Down

0 comments on commit f5b02eb

Please sign in to comment.