diff --git a/src/dom_components/model/Component.ts b/src/dom_components/model/Component.ts index ab2f1028f..1804261c9 100644 --- a/src/dom_components/model/Component.ts +++ b/src/dom_components/model/Component.ts @@ -20,6 +20,7 @@ import Selectors from '../../selector_manager/model/Selectors'; import Traits from '../../trait_manager/model/Traits'; import EditorModel from '../../editor/model/Editor'; import { + AddComponentsOption, ComponentAdd, ComponentDefinition, ComponentDefinitionDefined, @@ -1149,7 +1150,7 @@ export default class Component extends StyleableModel { */ components( components?: T, - opts: any = {} + opts: AddComponentsOption = {} ): undefined extends T ? Components : Component[] { const coll = this.get('components')!; diff --git a/src/dom_components/model/Components.ts b/src/dom_components/model/Components.ts index 41a950046..9da8866d1 100644 --- a/src/dom_components/model/Components.ts +++ b/src/dom_components/model/Components.ts @@ -5,7 +5,7 @@ import { DomComponentsConfig } from '../config/config'; import EditorModel from '../../editor/model/Editor'; import ComponentManager from '..'; import CssRule from '../../css_composer/model/CssRule'; -import { ComponentAdd, ComponentProperties } from './types'; +import { ComponentAdd, ComponentDefinitionDefined, ComponentProperties } from './types'; import ComponentText from './ComponentText'; import ComponentWrapper from './ComponentWrapper'; @@ -238,10 +238,12 @@ Component> { if (asDocument) { const root = parent as ComponentWrapper; - components = (parsed.html as any).components; + const { components: bodyCmps, ...restBody } = (parsed.html as ComponentDefinitionDefined) || {}; const { components: headCmps, ...restHead } = parsed.head || {}; + components = bodyCmps!; + root.set(restBody as any, opt); root.head.set(restHead as any, opt); - root.head.components(headCmps); + root.head.components(headCmps, opt); root.docEl.set(parsed.root as any, opt); root.set({ doctype: parsed.doctype }); } diff --git a/src/dom_components/model/types.ts b/src/dom_components/model/types.ts index 87d22d950..17b9a54d6 100644 --- a/src/dom_components/model/types.ts +++ b/src/dom_components/model/types.ts @@ -1,5 +1,5 @@ import Frame from '../../canvas/model/Frame'; -import { Nullable, OptionAsDocument } from '../../common'; +import { AddOptions, Nullable, OptionAsDocument } from '../../common'; import EditorModel from '../../editor/model/Editor'; import Selectors from '../../selector_manager/model/Selectors'; import { TraitProperties } from '../../trait_manager/types'; @@ -15,6 +15,8 @@ export type DragMode = 'translate' | 'absolute' | ''; export type DraggableDroppableFn = (source: Component, target: Component, index?: number) => boolean | void; +export interface AddComponentsOption extends AddOptions, OptionAsDocument {} + export interface ComponentStackItem { id: string; model: typeof Component; diff --git a/test/specs/dom_components/index.ts b/test/specs/dom_components/index.ts index 975b36d91..468aedee7 100644 --- a/test/specs/dom_components/index.ts +++ b/test/specs/dom_components/index.ts @@ -3,6 +3,7 @@ import EditorModel from '../../../src/editor/model/Editor'; import Editor from '../../../src/editor'; import utils from './../../test_utils.js'; import { Component } from '../../../src'; +import ComponentWrapper from '../../../src/dom_components/model/ComponentWrapper'; describe('DOM Components', () => { describe('Main', () => { @@ -312,4 +313,86 @@ describe('DOM Components', () => { }); }); }); + + describe('Rendered components', () => { + let editor: Editor; + let em: EditorModel; + let fxt: HTMLElement; + let root: ComponentWrapper; + + beforeEach(done => { + fxt = document.createElement('div'); + document.body.appendChild(fxt); + editor = new Editor({ + el: fxt, + avoidInlineStyle: true, + storageManager: false, + }); + em = editor.getModel(); + fxt.appendChild(em.Canvas.render()); + em.loadOnStart(); + editor.on('change:ready', () => { + root = editor.Components.getWrapper()!; + done(); + }); + }); + + afterEach(() => { + editor.destroy(); + }); + + describe('render components with asDocument', () => { + const docHtml = ` + + + + + Test + + + + +

H1

+ + + `; + + test('initial setup', () => { + expect(root.head.components().length).toBe(0); + expect(root.get('doctype')).toBe(''); + }); + + test('import HTML document without option', () => { + root.components(docHtml); + expect(root.head.components().length).toBe(0); + expect(root.get('doctype')).toBe(''); + }); + + test('import HTML document with asDocument', () => { + root.components(docHtml, { asDocument: true }); + const { head, docEl } = root; + expect(head.components().length).toBe(4); + expect(head.get('headp')).toBe(true); + expect(docEl.get('htmlp')).toBe(true); + expect(root.get('bodyp')).toBe(true); + expect(root.get('doctype')).toBe(''); + + const outputHtml = ` + + + + + Test + + + + +

H1

+ + + `.replace(/>\s+|\s+ m.trim()); + expect(root.toHTML()).toBe(outputHtml); + }); + }); + }); });