Repository: DevExpress/devextreme-vue
Pull request #352 (2020-02-19 07:34:00)

Fix content wrapping
Fix [T862697](https://supportcenter.devexpress.com/ticket/details/t862697/scrollview-placed-into-the-popup-container-is-rendered-incorrectly)


Patch:
diff --git a/src/core/component.ts b/src/core/component.ts
index f3bfaaf..a46ee94 100644
--- a/src/core/component.ts
+++ b/src/core/component.ts
@@ -5,7 +5,7 @@ import * as events from "devextreme/events";
 
 import { pullAllChildren } from "./children-processing";
 import Configuration, { bindOptionWatchers, setEmitOptionChangedFunc } from "./configuration";
-import { IConfigurable, initBinding } from "./configuration-component";
+import { IConfigurable, IConfigurationComponent, initBinding } from "./configuration-component";
 import { DX_REMOVE_EVENT, DX_TEMPLATE_WRAPPER_CLASS } from "./constants";
 import { IExtension, IExtensionComponentNode } from "./extension-component";
 import { camelize, forEachChildNode, toComparable } from "./helpers";
@@ -244,7 +244,8 @@ function splitNodes(nodes: VNode[]) {
     const configNodes: VNode[] = [];
 
     for (const node of nodes) {
-        if (node.componentOptions && (node.componentOptions as any as IExtensionComponentNode).$_hasOwner) {
+
+        if (node.componentOptions && (node.componentOptions.Ctor as any as IConfigurationComponent).$_isNested) {
             configNodes.push(node);
         } else {
             domNodes.push(node);
diff --git a/src/core/configuration-component.ts b/src/core/configuration-component.ts
index d95fabf..8a02ead 100644
--- a/src/core/configuration-component.ts
+++ b/src/core/configuration-component.ts
@@ -11,6 +11,7 @@ interface IConfigurationOwner {
 
 interface IConfigurationComponent extends IConfigurationOwner {
     $_optionName: string;
+    $_isNested: boolean;
     $_isCollectionItem: boolean;
     $_predefinedProps: Record<string, any>;
 }
diff --git a/tools/src/component-generator.ts b/tools/src/component-generator.ts
index d7e8bba..66457b0 100644
--- a/tools/src/component-generator.ts
+++ b/tools/src/component-generator.ts
@@ -226,6 +226,7 @@ L0 + `});\n` +
         L1 + `}\n` +
         `});\n` +
         `(<#= nested.name #> as any).$_optionName = "<#= nested.optionName #>";\n` +
+        `(<#= nested.name #> as any).$_isNested = true;\n` +
 
         `<#? nested.isCollectionItem #>` +
             `(<#= nested.name #> as any).$_isCollectionItem = true;\n` +


Test patch:
diff --git a/src/core/component.test.ts b/src/core/component.test.ts
index 961880f..e1e3743 100644
--- a/src/core/component.test.ts
+++ b/src/core/component.test.ts
@@ -1217,6 +1217,7 @@ describe("template", () => {
                 template: String
             }
         });
+        (NestedItem as any as IConfigurationComponent).$_isNested = true;
         (NestedItem as any as IConfigurationComponent).$_optionName = "items";
         (NestedItem as any as IConfigurationComponent).$_isCollectionItem = true;
 
@@ -1235,6 +1236,33 @@ describe("template", () => {
         expect(vm.$el.innerHTML).toBe("<div class=\"dx-template-wrapper\"> <div>Template</div></div><!---->");
     });
 
+    it("should wrap components", () => {
+        const NestedItem = Vue.extend({
+            extends: DxConfiguration,
+            props: {
+                prop1: Number,
+                template: String
+            }
+        });
+        (NestedItem as any as IConfigurationComponent).$_isNested = true;
+        (NestedItem as any as IConfigurationComponent).$_optionName = "items";
+        (NestedItem as any as IConfigurationComponent).$_isCollectionItem = true;
+
+        const vm = new Vue({
+            template: `<test-component-with-content>
+                            <nested-item>
+                            </nested-item>
+                            <test-component-with-content></test-component-with-content>
+                        </test-component-with-content>`,
+            components: {
+                TestComponentWithContent,
+                NestedItem
+            },
+        }).$mount();
+
+        expect(vm.$el.innerHTML).toBe("<div class=\"dx-template-wrapper\"> <div></div></div><!---->");
+    });
+
     it("renders", () => {
         new Vue({
             template: `<test-component>
diff --git a/tools/src/component-generator.test.ts b/tools/src/component-generator.test.ts
index 139c1ab..842a63f 100644
--- a/tools/src/component-generator.test.ts
+++ b/tools/src/component-generator.test.ts
@@ -188,6 +188,7 @@ const NESTED_COMPONENT: any = Vue.extend({
   }
 });
 (NESTED_COMPONENT as any).$_optionName = "NESTED_OPTION_NAME";
+(NESTED_COMPONENT as any).$_isNested = true;
 
 export default COMPONENT;
 export {
@@ -257,6 +258,7 @@ const NESTED_COMPONENT: any = Vue.extend({
   }
 });
 (NESTED_COMPONENT as any).$_optionName = "NESTED_OPTION_NAME";
+(NESTED_COMPONENT as any).$_isNested = true;
 (NESTED_COMPONENT as any).$_isCollectionItem = true;
 
 export default COMPONENT;
@@ -331,6 +333,7 @@ const NESTED_COMPONENT: any = Vue.extend({
   }
 });
 (NESTED_COMPONENT as any).$_optionName = "NESTED_OPTION_NAME";
+(NESTED_COMPONENT as any).$_isNested = true;
 (NESTED_COMPONENT as any).$_expectedChildren = {
   EXPECTED_3: { isCollectionItem: true, optionName: "ghi" },
   EXPECTED_4: { isCollectionItem: false, optionName: "jkl" }
@@ -514,6 +517,7 @@ const NESTED_COMPONENT: any = Vue.extend({
   }
 });
 (NESTED_COMPONENT as any).$_optionName = "NESTED_OPTION_NAME";
+(NESTED_COMPONENT as any).$_isNested = true;
 (NESTED_COMPONENT as any).$_predefinedProps = {
   PROP_1: "PREDEFINED_VALUE"
 };
@@ -589,6 +593,7 @@ const NESTED_COMPONENT: any = Vue.extend({
   }
 });
 (NESTED_COMPONENT as any).$_optionName = "NESTED_OPTION_NAME";
+(NESTED_COMPONENT as any).$_isNested = true;
 (NESTED_COMPONENT as any).$_predefinedProps = {
   PROP_1: "PREDEFINED_VALUE_1",
   PROP_2: "PREDEFINED_VALUE_2"