diff --git a/packages/metal-dom/src/domNamed.js b/packages/metal-dom/src/domNamed.js index 4e10534b..9d3c64c6 100644 --- a/packages/metal-dom/src/domNamed.js +++ b/packages/metal-dom/src/domNamed.js @@ -521,6 +521,34 @@ export function parent(element, selector) { return closest(element.parentNode, selector); } +/** + * Inserts a node before first child of the parent. If child is a HTML string + * it will be converted to document fragment before prepending it to the parent. + * @param {!Element} parent The node to prepend to. + * @param {!(Element|NodeList|string)} child The thing who must be prepended + * @return {!Element} The prepended child + */ +export function prepend(parent, child) { + if (isString(child)) { + child = buildFragment(child); + } + + if (!isNodeListLike(child) && !isDefAndNotNull(parent.firstChild)) { + return append(parent, child); + } + + if (isNodeListLike(child)) { + const childArr = Array.prototype.slice.call(child); + for (let i = childArr.length - 1; i >= 0; i--) { + parent.insertBefore(childArr[i], parent.firstChild); + } + } else { + parent.insertBefore(child, parent.firstChild); + } + + return child; +} + /** * Registers a custom event. * @param {string} eventName The name of the custom event. diff --git a/packages/metal-dom/test/dom.js b/packages/metal-dom/test/dom.js index 3d98ae8d..fc48f160 100644 --- a/packages/metal-dom/test/dom.js +++ b/packages/metal-dom/test/dom.js @@ -215,6 +215,83 @@ describe('dom', function() { assert.strictEqual('myChild2', parent.childNodes[1].className); }); + it('should prepend an element into a div without first child', function() { + let parent = document.createElement('div'); + let elem = dom.buildFragment('
Hello World
'); + + dom.prepend(parent, elem); + + assert.strictEqual('Hello World
', parent.innerHTML); + }); + + it('should prepend an element into a div', function() { + let parent = document.createElement('div'); + let p = document.createElement('p'); + let span = document.createElement('span'); + + dom.append(parent, p); + dom.prepend(parent, span); + + assert.strictEqual(parent.innerHTML, ''); + }); + + it('should prepend a text into a div', function() { + let parent = document.createElement('div'); + + dom.append(parent, 'Some text'); + dom.prepend(parent, 'Headline: '); + + assert.strictEqual(parent.innerHTML, 'Headline: Some text'); + }); + + it('should prepend a node list to parent element', function() { + let parent = document.createElement('div'); + + let childFrag = dom.buildFragment( + '