diff --git a/packages/@glimmer/integration-tests/lib/suites/in-element.ts b/packages/@glimmer/integration-tests/lib/suites/in-element.ts
index d38119ff1..960377f7d 100644
--- a/packages/@glimmer/integration-tests/lib/suites/in-element.ts
+++ b/packages/@glimmer/integration-tests/lib/suites/in-element.ts
@@ -29,6 +29,29 @@ export class InElementSuite extends RenderTest {
this.assertStableNodes();
}
+ @test
+ 'clears existing content'() {
+ let externalElement = this.delegate.createElement('div');
+ let initialContent = '
Hello there!
';
+ replaceHTML(externalElement, initialContent);
+
+ this.render('{{#in-element externalElement}}[{{foo}}]{{/in-element}}', {
+ externalElement,
+ foo: 'Yippie!',
+ });
+
+ equalsElement(externalElement, 'div', {}, '[Yippie!]');
+ this.assertStableRerender();
+
+ this.rerender({ foo: 'Double Yups!' });
+ equalsElement(externalElement, 'div', {}, '[Double Yups!]');
+ this.assertStableNodes();
+
+ this.rerender({ foo: 'Yippie!' });
+ equalsElement(externalElement, 'div', {}, '[Yippie!]');
+ this.assertStableNodes();
+ }
+
@test
'Changing to falsey'() {
let first = this.delegate.createElement('div');
@@ -79,10 +102,13 @@ export class InElementSuite extends RenderTest {
let initialContent = 'Hello there!
';
replaceHTML(externalElement, initialContent);
- this.render(stripTight`{{#in-element externalElement}}[{{foo}}]{{/in-element}}`, {
- externalElement,
- foo: 'Yippie!',
- });
+ this.render(
+ stripTight`{{#in-element externalElement insertBefore=null}}[{{foo}}]{{/in-element}}`,
+ {
+ externalElement,
+ foo: 'Yippie!',
+ }
+ );
equalsElement(externalElement, 'div', {}, `${initialContent}[Yippie!]`);
this.assertHTML('');
@@ -105,38 +131,17 @@ export class InElementSuite extends RenderTest {
}
@test
- 'With nextSibling'() {
+ '`insertBefore` can only be null'() {
let externalElement = this.delegate.createElement('div');
- replaceHTML(externalElement, 'Hellothere!');
-
- this.render(
- stripTight`{{#in-element externalElement nextSibling=nextSibling}}[{{foo}}]{{/in-element}}`,
- { externalElement, nextSibling: externalElement.lastChild, foo: 'Yippie!' }
- );
-
- equalsElement(externalElement, 'div', {}, 'Hello[Yippie!]there!');
- this.assertHTML('');
- this.assertStableRerender();
-
- this.rerender({ foo: 'Double Yips!' });
- equalsElement(externalElement, 'div', {}, 'Hello[Double Yips!]there!');
- this.assertHTML('');
- this.assertStableNodes();
+ let before = this.delegate.createElement('div');
- this.rerender({ nextSibling: null });
- equalsElement(externalElement, 'div', {}, 'Hellothere![Double Yips!]');
- this.assertHTML('');
- this.assertStableRerender();
-
- this.rerender({ externalElement: null });
- equalsElement(externalElement, 'div', {}, 'Hellothere!');
- this.assertHTML('');
- this.assertStableRerender();
-
- this.rerender({ externalElement, nextSibling: externalElement.lastChild, foo: 'Yippie!' });
- equalsElement(externalElement, 'div', {}, 'Hello[Yippie!]there!');
- this.assertHTML('');
- this.assertStableRerender();
+ this.assert.throws(() => {
+ this.render('{{#in-element externalElement insertBefore=before}}[{{foo}}]{{/in-element}}', {
+ externalElement,
+ before,
+ foo: 'Yippie!',
+ });
+ }, /insertBefore only takes `null` as an argument/);
}
@test
diff --git a/packages/@glimmer/interfaces/lib/dom/attributes.d.ts b/packages/@glimmer/interfaces/lib/dom/attributes.d.ts
index 69f70986e..ed526446e 100644
--- a/packages/@glimmer/interfaces/lib/dom/attributes.d.ts
+++ b/packages/@glimmer/interfaces/lib/dom/attributes.d.ts
@@ -40,7 +40,7 @@ export interface DOMStack {
pushRemoteElement(
element: SimpleElement,
guid: string,
- nextSibling: Option
+ insertBefore: Option
): Option;
popRemoteElement(): void;
popElement(): void;
diff --git a/packages/@glimmer/node/lib/serialize-builder.ts b/packages/@glimmer/node/lib/serialize-builder.ts
index 9e83bc848..b845d1530 100644
--- a/packages/@glimmer/node/lib/serialize-builder.ts
+++ b/packages/@glimmer/node/lib/serialize-builder.ts
@@ -96,13 +96,13 @@ class SerializeBuilder extends NewElementBuilder implements ElementBuilder {
pushRemoteElement(
element: SimpleElement,
cursorId: string,
- nextSibling: Option = null
+ insertBefore: Option = null
): Option {
let { dom } = this;
let script = dom.createElement('script');
script.setAttribute('glmr', cursorId);
- dom.insertBefore(element, script, nextSibling);
- return super.pushRemoteElement(element, cursorId, nextSibling);
+ dom.insertBefore(element, script, insertBefore);
+ return super.pushRemoteElement(element, cursorId, insertBefore);
}
}
diff --git a/packages/@glimmer/opcode-compiler/lib/syntax/builtins.ts b/packages/@glimmer/opcode-compiler/lib/syntax/builtins.ts
index c90ef1dd4..cf6b1e51b 100644
--- a/packages/@glimmer/opcode-compiler/lib/syntax/builtins.ts
+++ b/packages/@glimmer/opcode-compiler/lib/syntax/builtins.ts
@@ -173,7 +173,7 @@ export function populateBuiltins(
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
- if (key === 'nextSibling' || key === 'guid') {
+ if (key === 'guid' || key === 'insertBefore') {
actions.push(op('Expr', values[i]));
} else {
throw new Error(`SYNTAX ERROR: #in-element does not take a \`${keys[0]}\` option`);
diff --git a/packages/@glimmer/runtime/lib/compiled/opcodes/dom.ts b/packages/@glimmer/runtime/lib/compiled/opcodes/dom.ts
index 944cdd40b..006a37ee8 100644
--- a/packages/@glimmer/runtime/lib/compiled/opcodes/dom.ts
+++ b/packages/@glimmer/runtime/lib/compiled/opcodes/dom.ts
@@ -7,9 +7,8 @@ import {
isConst,
isConstTag,
} from '@glimmer/reference';
-import { Option } from '@glimmer/util';
-import { check, CheckString, CheckElement, CheckNode, CheckOption } from '@glimmer/debug';
-import { Op } from '@glimmer/interfaces';
+import { check, CheckString, CheckElement } from '@glimmer/debug';
+import { Op, Option } from '@glimmer/interfaces';
import { $t0 } from '@glimmer/vm';
import {
ModifierDefinition,
@@ -22,7 +21,7 @@ import { Assert } from './vm';
import { DynamicAttribute } from '../../vm/attributes/dynamic';
import { CheckReference, CheckArguments, CheckOperations } from './-debug-strip';
import { CONSTANTS } from '../../symbols';
-import { SimpleElement, SimpleNode } from '@simple-dom/interface';
+import { SimpleElement } from '@simple-dom/interface';
APPEND_OPCODES.add(Op.Text, (vm, { op1: text }) => {
vm.elements().appendText(vm[CONSTANTS].getString(text));
@@ -43,11 +42,10 @@ APPEND_OPCODES.add(Op.OpenDynamicElement, vm => {
APPEND_OPCODES.add(Op.PushRemoteElement, vm => {
let elementRef = check(vm.stack.pop(), CheckReference);
- let nextSiblingRef = check(vm.stack.pop(), CheckReference);
+ let insertBeforeRef = check(vm.stack.pop(), CheckReference);
let guidRef = check(vm.stack.pop(), CheckReference);
let element: SimpleElement;
- let nextSibling: Option;
let guid = guidRef.value() as string;
if (isConst(elementRef)) {
@@ -58,15 +56,9 @@ APPEND_OPCODES.add(Op.PushRemoteElement, vm => {
vm.updateWith(new Assert(cache));
}
- if (isConst(nextSiblingRef)) {
- nextSibling = check(nextSiblingRef.value(), CheckOption(CheckNode));
- } else {
- let cache = new ReferenceCache(nextSiblingRef as Reference