From 4065e8715b8b546999b8f9fe8cd61a0ccd0a52e4 Mon Sep 17 00:00:00 2001 From: Erik Arvidsson Date: Mon, 25 Nov 2013 11:56:28 -0500 Subject: [PATCH] Implement inserAdjacentHTML --- src/wrappers/HTMLElement.js | 40 +++++++++ test/js/MutationObserver/childList.js | 112 ++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) diff --git a/src/wrappers/HTMLElement.js b/src/wrappers/HTMLElement.js index 7fc1f91..394dfd7 100644 --- a/src/wrappers/HTMLElement.js +++ b/src/wrappers/HTMLElement.js @@ -137,14 +137,54 @@ return getOuterHTML(this); }, set outerHTML(value) { + // TODO(arv): Mutation observer var p = this.parentNode; if (p) { p.invalidateShadowRenderer(); this.impl.outerHTML = value; } + }, + + insertAdjacentHTML: function(position, text) { + var contextElement, refNode; + switch (String(position).toLowerCase()) { + case 'beforebegin': + contextElement = this.parentNode; + refNode = this; + break; + case 'afterend': + contextElement = this.parentNode; + refNode = this.nextSibling; + break; + case 'afterbegin': + contextElement = this; + refNode = this.firstChild; + break; + case 'beforeend': + contextElement = this; + refNode = null; + break; + default: + return; + } + + var df = frag(contextElement, text); + contextElement.insertBefore(df, refNode); } }); + function frag(contextElement, html) { + // TODO(arv): This does not work with SVG and other non HTML elements. + var p = unwrap(contextElement.cloneNode(false)); + p.innerHTML = html; + var df = unwrap(document.createDocumentFragment()); + var c; + while (c = p.firstChild) { + df.appendChild(c); + } + return wrap(df); + } + function getter(name) { return function() { scope.renderAllPending(); diff --git a/test/js/MutationObserver/childList.js b/test/js/MutationObserver/childList.js index 448bd36..a4117e4 100644 --- a/test/js/MutationObserver/childList.js +++ b/test/js/MutationObserver/childList.js @@ -646,6 +646,118 @@ suite('MutationObserver', function() { }); }); + test('insertAdjacentHTML beforebegin', function() { + var a = document.createElement('a'); + a.innerHTML = ''; + var b = a.firstChild; + var c = a.lastChild; + + var observer = new MutationObserver(function() {}); + observer.observe(a, { + childList: true + }); + + c.insertAdjacentHTML('beforebegin', ''); + + assert.equal(a.innerHTML, ''); + var d = b.nextSibling; + var e = d.nextSibling; + + var records = observer.takeRecords(); + assert.equal(records.length, 1); + expectMutationRecord(records[0], { + type: 'childList', + target: a, + addedNodes: [d, e], + previousSibling: b, + nextSibling: c + }); + }); + + test('insertAdjacentHTML afterbegin', function() { + var a = document.createElement('a'); + a.innerHTML = ''; + var b = a.firstChild; + var c = a.lastChild; + + var observer = new MutationObserver(function() {}); + observer.observe(a, { + childList: true + }); + + a.insertAdjacentHTML('afterbegin', ''); + + assert.equal(a.innerHTML, ''); + var d = a.firstChild; + var e = d.nextSibling; + + var records = observer.takeRecords(); + assert.equal(records.length, 1); + expectMutationRecord(records[0], { + type: 'childList', + target: a, + addedNodes: [d, e], + previousSibling: null, + nextSibling: b + }); + }); + + test('insertAdjacentHTML beforeend', function() { + var a = document.createElement('a'); + a.innerHTML = ''; + var b = a.firstChild; + var c = a.lastChild; + + var observer = new MutationObserver(function() {}); + observer.observe(a, { + childList: true + }); + + a.insertAdjacentHTML('beforeend', ''); + + assert.equal(a.innerHTML, ''); + var d = c.nextSibling; + var e = d.nextSibling; + + var records = observer.takeRecords(); + assert.equal(records.length, 1); + expectMutationRecord(records[0], { + type: 'childList', + target: a, + addedNodes: [d, e], + previousSibling: c, + nextSibling: null + }); + }); + + test('insertAdjacentHTML afterend', function() { + var a = document.createElement('a'); + a.innerHTML = ''; + var b = a.firstChild; + var c = a.lastChild; + + var observer = new MutationObserver(function() {}); + observer.observe(a, { + childList: true + }); + + b.insertAdjacentHTML('afterend', ''); + + assert.equal(a.innerHTML, ''); + var d = b.nextSibling; + var e = d.nextSibling; + + var records = observer.takeRecords(); + assert.equal(records.length, 1); + expectMutationRecord(records[0], { + type: 'childList', + target: a, + addedNodes: [d, e], + previousSibling: b, + nextSibling: c + }); + }); + }); });