diff --git a/package-lock.json b/package-lock.json index 8364a5932..8098a1cdf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "marko", - "version": "4.13.4", + "version": "4.13.4-4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 070f3740a..af5593b72 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "marko", - "version": "4.13.4", + "version": "4.13.4-4", "license": "MIT", "description": "UI Components + streaming, async, high performance, HTML templating for Node.js and the browser.", "scripts": { diff --git a/src/morphdom/fragment.js b/src/morphdom/fragment.js index 11047bce6..8eb6be7ac 100644 --- a/src/morphdom/fragment.js +++ b/src/morphdom/fragment.js @@ -40,13 +40,13 @@ var fragmentPrototype = { insertInto: function(newParentNode, referenceNode) { this.nodes.forEach(function(node) { insertBefore(node, referenceNode, newParentNode); - }); + }, this); return this; }, remove: function() { this.nodes.forEach(function(node) { this.detachedContainer.appendChild(node); - }); + }, this); } }; diff --git a/src/runtime/dom-insert.js b/src/runtime/dom-insert.js index bebcb9197..6e5e44588 100644 --- a/src/runtime/dom-insert.js +++ b/src/runtime/dom-insert.js @@ -2,6 +2,11 @@ var extend = require("raptor-util/extend"); var componentsUtil = require("../components/util"); var destroyComponentForNode = componentsUtil.___destroyComponentForNode; var destroyNodeRecursive = componentsUtil.___destroyNodeRecursive; +var helpers = require("../morphdom/helpers"); + +var insertBefore = helpers.___insertBefore; +var insertAfter = helpers.___insertAfter; +var removeChild = helpers.___removeChild; function resolveEl(el) { if (typeof el == "string") { @@ -24,20 +29,21 @@ module.exports = function(target, getEl, afterInsert) { appendTo: function(referenceEl) { referenceEl = resolveEl(referenceEl); var el = getEl(this, referenceEl); - referenceEl.appendChild(el); + insertBefore(el, null, referenceEl); return afterInsert(this, referenceEl); }, prependTo: function(referenceEl) { referenceEl = resolveEl(referenceEl); var el = getEl(this, referenceEl); - referenceEl.insertBefore(el, referenceEl.firstChild || null); + insertBefore(el, referenceEl.firstChild || null, referenceEl); return afterInsert(this, referenceEl); }, replace: function(referenceEl) { referenceEl = resolveEl(referenceEl); var el = getEl(this, referenceEl); beforeRemove(referenceEl); - referenceEl.parentNode.replaceChild(el, referenceEl); + insertBefore(el, referenceEl, referenceEl.parentNode); + removeChild(referenceEl); return afterInsert(this, referenceEl); }, replaceChildrenOf: function(referenceEl) { @@ -52,25 +58,19 @@ module.exports = function(target, getEl, afterInsert) { } referenceEl.innerHTML = ""; - referenceEl.appendChild(el); + insertBefore(el, null, referenceEl); return afterInsert(this, referenceEl); }, insertBefore: function(referenceEl) { referenceEl = resolveEl(referenceEl); var el = getEl(this, referenceEl); - referenceEl.parentNode.insertBefore(el, referenceEl); + insertBefore(el, referenceEl, referenceEl.parentNode); return afterInsert(this, referenceEl); }, insertAfter: function(referenceEl) { referenceEl = resolveEl(referenceEl); var el = getEl(this, referenceEl); - var nextSibling = referenceEl.nextSibling; - var parentNode = referenceEl.parentNode; - if (nextSibling) { - parentNode.insertBefore(el, nextSibling); - } else { - parentNode.appendChild(el); - } + insertAfter(el, referenceEl, referenceEl.parentNode); return afterInsert(this, referenceEl); } }); diff --git a/test/components-browser/fixtures/append-prepend/components/app-hello/index.marko b/test/components-browser/fixtures/append-prepend/components/app-hello/index.marko new file mode 100644 index 000000000..2b1322cea --- /dev/null +++ b/test/components-browser/fixtures/append-prepend/components/app-hello/index.marko @@ -0,0 +1,3 @@ +
+ Hello ${input.value} +
diff --git a/test/components-browser/fixtures/append-prepend/index.marko b/test/components-browser/fixtures/append-prepend/index.marko new file mode 100644 index 000000000..58133f769 --- /dev/null +++ b/test/components-browser/fixtures/append-prepend/index.marko @@ -0,0 +1,5 @@ +class {} + +
+ ref +
\ No newline at end of file diff --git a/test/components-browser/fixtures/append-prepend/test.js b/test/components-browser/fixtures/append-prepend/test.js new file mode 100644 index 000000000..2077adbd6 --- /dev/null +++ b/test/components-browser/fixtures/append-prepend/test.js @@ -0,0 +1,15 @@ +var expect = require("chai").expect; + +module.exports = function(helpers) { + var component = helpers.mount(require.resolve("./index.marko")); + var hello = require("./components/app-hello"); + + var renderTarget = component.getEl("renderTarget"); + expect(renderTarget.innerHTML).to.equal("ref"); + + hello.renderSync({ value: "before" }).prependTo(renderTarget); + hello.renderSync({ value: "after" }).appendTo(renderTarget); + expect(renderTarget.innerHTML).to.equal( + "
Hello before
ref
Hello after
" + ); +}; diff --git a/test/components-browser/fixtures/component-api-move-root/index.marko b/test/components-browser/fixtures/component-api-move-root/index.marko new file mode 100644 index 000000000..d73fad23f --- /dev/null +++ b/test/components-browser/fixtures/component-api-move-root/index.marko @@ -0,0 +1,10 @@ +class { + onCreate() { + this.state = { count:0 }; + } + increment() { + this.state.count++; + } +} + +-- Hello World ${state.count} \ No newline at end of file diff --git a/test/components-browser/fixtures/component-api-move-root/test.js b/test/components-browser/fixtures/component-api-move-root/test.js new file mode 100644 index 000000000..705ac1e3c --- /dev/null +++ b/test/components-browser/fixtures/component-api-move-root/test.js @@ -0,0 +1,14 @@ +var expect = require("chai").expect; + +module.exports = function(helpers) { + var component = helpers.mount(require.resolve("./index"), {}); + var newTarget = document.createElement("div"); + document.body.appendChild(newTarget); + component.increment(); + component.update(); + component.appendTo(newTarget); + expect(newTarget.innerHTML).to.equal("Hello World 1"); + component.increment(); + component.update(); + expect(newTarget.innerHTML).to.equal("Hello World 2"); +}; diff --git a/test/components-browser/fixtures/insert-before-after/components/app-hello/index.marko b/test/components-browser/fixtures/insert-before-after/components/app-hello/index.marko new file mode 100644 index 000000000..2b1322cea --- /dev/null +++ b/test/components-browser/fixtures/insert-before-after/components/app-hello/index.marko @@ -0,0 +1,3 @@ +
+ Hello ${input.value} +
diff --git a/test/components-browser/fixtures/insert-before-after/index.marko b/test/components-browser/fixtures/insert-before-after/index.marko new file mode 100644 index 000000000..58133f769 --- /dev/null +++ b/test/components-browser/fixtures/insert-before-after/index.marko @@ -0,0 +1,5 @@ +class {} + +
+ ref +
\ No newline at end of file diff --git a/test/components-browser/fixtures/insert-before-after/test.js b/test/components-browser/fixtures/insert-before-after/test.js new file mode 100644 index 000000000..331cdc5de --- /dev/null +++ b/test/components-browser/fixtures/insert-before-after/test.js @@ -0,0 +1,16 @@ +var expect = require("chai").expect; + +module.exports = function(helpers) { + var component = helpers.mount(require.resolve("./index.marko")); + var hello = require("./components/app-hello"); + + var renderTarget = component.getEl("renderTarget"); + var referenceElement = component.getEl("referenceElement"); + expect(renderTarget.innerHTML).to.equal("ref"); + + hello.renderSync({ value: "before" }).insertBefore(referenceElement); + hello.renderSync({ value: "after" }).insertAfter(referenceElement); + expect(renderTarget.innerHTML).to.equal( + "
Hello before
ref
Hello after
" + ); +};