Skip to content

Commit

Permalink
Support Idiomorph.defaults settings object so users can change the …
Browse files Browse the repository at this point in the history
…global defaults
  • Loading branch information
1cg committed Dec 17, 2023
1 parent b754f3e commit f983345
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 21 deletions.
73 changes: 52 additions & 21 deletions src/idiomorph.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,31 @@
//=============================================================================
let EMPTY_SET = new Set();

// default configuration values, updatable by users now
let defaults = {
morphStyle: "outerHTML",
callbacks : {
beforeNodeAdded: noOp,
afterNodeAdded: noOp,
beforeNodeMorphed: noOp,
afterNodeMorphed: noOp,
beforeNodeRemoved: noOp,
afterNodeRemoved: noOp,

},
head: {
style: 'merge',
shouldPreserve: function (elt) {
return elt.getAttribute("im-preserve") === "true";
},
shouldReAppend: function (elt) {
return elt.getAttribute("im-re-append") === "true";
},
shouldRemove: noOp,
afterHeadMorphed: noOp,
}
};

//=============================================================================
// Core Morphing Algorithm - morph, morphNormalizedContent, morphOldNodeTo, morphChildren
//=============================================================================
Expand Down Expand Up @@ -440,7 +465,30 @@
function noOp() {
}

/*
Deep merges the config object and the Idiomoroph.defaults object to
produce a final configuration object
*/
function mergeDefaults(config) {
let finalConfig = {};
// copy top level stuff into final config
Object.assign(finalConfig, defaults);
Object.assign(finalConfig, config);

// copy callbacks into final config (do this to deep merge the callbacks)
finalConfig.callbacks = {};
Object.assign(finalConfig.callbacks, defaults.callbacks);
Object.assign(finalConfig.callbacks, config.callbacks);

// copy head config into final config (do this to deep merge the head)
finalConfig.head = {};
Object.assign(finalConfig.head, defaults.head);
Object.assign(finalConfig.head, config.head);
return finalConfig;
}

function createMorphContext(oldNode, newContent, config) {
config = mergeDefaults(config);
return {
target: oldNode,
newContent: newContent,
Expand All @@ -450,26 +498,8 @@
ignoreActiveValue: config.ignoreActiveValue,
idMap: createIdMap(oldNode, newContent),
deadIds: new Set(),
callbacks: Object.assign({
beforeNodeAdded: noOp,
afterNodeAdded: noOp,
beforeNodeMorphed: noOp,
afterNodeMorphed: noOp,
beforeNodeRemoved: noOp,
afterNodeRemoved: noOp,

}, config.callbacks),
head: Object.assign({
style: 'merge',
shouldPreserve: function (elt) {
return elt.getAttribute("im-preserve") === "true";
},
shouldReAppend: function (elt) {
return elt.getAttribute("im-re-append") === "true";
},
shouldRemove: noOp,
afterHeadMorphed: noOp,
}, config.head),
callbacks: config.callbacks,
head: config.head
}
}

Expand Down Expand Up @@ -787,7 +817,8 @@
// This is what ends up becoming the Idiomorph global object
//=============================================================================
return {
morph
morph,
defaults
}
}));

44 changes: 44 additions & 0 deletions test/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -335,4 +335,48 @@ describe("Core morphing tests", function(){
initial.checked.should.equal(false);
document.body.removeChild(parent);
});

it('can override defaults w/ global set', function()
{
try {
// set default to inner HTML
Idiomorph.defaults.morphStyle = 'innerHTML';
let initial = make("<button>Foo</button>");
let finalSrc = "<button>Bar</button>";

// should more inner HTML despite no config
Idiomorph.morph(initial, finalSrc);

if (initial.outerHTML !== "<button>Bar</button>") {
console.log("HTML after morph: " + initial.outerHTML);
console.log("Expected: " + finalSrc);
}
initial.outerHTML.should.equal("<button><button>Bar</button></button>");
} finally {
Idiomorph.defaults.morphStyle = 'outerHTML';
}
});

it('can override globally set default w/ local value', function()
{
try {
// set default to inner HTML
Idiomorph.defaults.morphStyle = 'innerHTML';
let initial = make("<button>Foo</button>");
let finalSrc = "<button>Bar</button>";

// should morph outer HTML despite default setting
Idiomorph.morph(initial, finalSrc, {morphStyle:'outerHTML'});

if (initial.outerHTML !== "<button>Bar</button>") {
console.log("HTML after morph: " + initial.outerHTML);
console.log("Expected: " + finalSrc);
}
initial.outerHTML.should.equal("<button>Bar</button>");
} finally {
Idiomorph.defaults.morphStyle = 'outerHTML';
}
});


})

0 comments on commit f983345

Please sign in to comment.