-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #11 from preset-io/replace_children_polyfill
replaceChildren: Polyfill with tests
- Loading branch information
Showing
6 changed files
with
82 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = { | ||
testEnvironment: 'jsdom', | ||
}; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { applyReplaceChildrenPolyfill } from './polyfills'; | ||
|
||
describe('replaceChildren polyfill', () => { | ||
it('should add replaceChildren method to the prototype', () => { | ||
const originalReplaceChildren = Element.prototype.replaceChildren; | ||
// Remove the replaceChildren implementation from the Element prototype | ||
delete (Element.prototype as any).replaceChildren; | ||
|
||
// Check that the replaceChildren method does not exist | ||
expect(HTMLElement.prototype.replaceChildren).toBeUndefined(); | ||
|
||
// Apply the polyfill | ||
applyReplaceChildrenPolyfill(); | ||
|
||
// Check that the replaceChildren method has been added to the HTMLElement prototype | ||
expect(HTMLElement.prototype.replaceChildren).toBeDefined(); | ||
expect(HTMLElement.prototype.replaceChildren).not.toEqual(originalReplaceChildren); | ||
|
||
// Restore the original replaceChildren implementation | ||
Object.defineProperty(Element.prototype, 'replaceChildren', { | ||
configurable: true, | ||
enumerable: true, | ||
value: originalReplaceChildren, | ||
writable: true, | ||
}); | ||
}); | ||
|
||
it('should replace children correctly', () => { | ||
// Create a parent element with two child elements | ||
const parent = document.createElement('div'); | ||
const child1 = document.createElement('p'); | ||
const child2 = document.createElement('span'); | ||
parent.appendChild(child1); | ||
parent.appendChild(child2); | ||
|
||
// Replace the children with a new child element | ||
parent.replaceChildren(document.createElement('a')); | ||
|
||
// Check that the parent element only has one child | ||
expect(parent.children.length).toBe(1); | ||
// Check that the child element has been replaced with a new one | ||
expect(parent.children[0].tagName).toBe('A'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
export function applyReplaceChildrenPolyfill() { | ||
(function (prototype) { | ||
// If the prototype already has a replaceChildren method, skip it | ||
if (prototype.hasOwnProperty('replaceChildren')) { | ||
return; | ||
} | ||
// Otherwise, define a new replaceChildren method on the prototype | ||
Object.defineProperty(prototype, 'replaceChildren', { | ||
configurable: true, | ||
enumerable: true, | ||
// The replaceChildren method takes any number of arguments | ||
value: function (...nodes: (Element | Text)[]) { | ||
// Remove all existing child nodes | ||
while (this.firstChild) { | ||
this.removeChild(this.firstChild); | ||
} | ||
// Add the new child nodes | ||
nodes.forEach((node) => { | ||
// If the node is a string, create a new text node | ||
// Otherwise, assume it's a DOM element and use it directly | ||
this.appendChild( | ||
typeof node === 'string' ? document.createTextNode(node) : node | ||
); | ||
}); | ||
}, | ||
}); | ||
})(Element.prototype); | ||
} |