diff --git a/packages/core/src/dom_components/model/ComponentWrapper.ts b/packages/core/src/dom_components/model/ComponentWrapper.ts index defc6cc8c..d32080d74 100644 --- a/packages/core/src/dom_components/model/ComponentWrapper.ts +++ b/packages/core/src/dom_components/model/ComponentWrapper.ts @@ -36,10 +36,11 @@ export default class ComponentWrapper extends Component { const CmpHead = cmp?.getType(typeHead)?.model; const CmpDef = cmp?.getType('default').model; if (CmpHead) { + const { head, docEl } = props; this.set( { - head: new CmpHead({ ...props.head }, opt), - docEl: new CmpDef({ tagName: 'html', ...props.docEl }, opt), + head: head && head instanceof Component ? head : new CmpHead({ ...head }, opt), + docEl: docEl && docEl instanceof Component ? docEl : new CmpDef({ tagName: 'html', ...docEl }, opt), }, { silent: true }, ); @@ -58,6 +59,14 @@ export default class ComponentWrapper extends Component { return this.attributes.doctype || ''; } + clone(opt?: { symbol?: boolean | undefined; symbolInv?: boolean | undefined }): this { + const result = super.clone(opt); + result.set('head', this.get('head').clone(opt)); + result.set('docEl', this.get('docEl').clone(opt)); + + return result; + } + toHTML(opts: ToHTMLOptions = {}) { const { doctype } = this; const asDoc = !isUndefined(opts.asDocument) ? opts.asDocument : !!doctype; diff --git a/packages/core/test/specs/dom_components/model/ComponentWrapper.ts b/packages/core/test/specs/dom_components/model/ComponentWrapper.ts new file mode 100644 index 000000000..9706bd389 --- /dev/null +++ b/packages/core/test/specs/dom_components/model/ComponentWrapper.ts @@ -0,0 +1,36 @@ +import Component from '../../../../src/dom_components/model/Component'; +import ComponentHead from '../../../../src/dom_components/model/ComponentHead'; +import Editor from '../../../../src/editor'; + +describe('ComponentWrapper', () => { + let em: Editor; + + beforeEach(() => { + em = new Editor({ avoidDefaults: true }); + em.Pages.onLoad(); + }); + + describe('.clone', () => { + test('clones the component and returns a new instance for head and document element', () => { + const originalComponent = em.Pages.getSelected()?.getMainComponent(); + const clonedComponent = originalComponent?.clone(); + em.Pages.add( + { + id: 'PAGE_ID', + clonedComponent, + }, + { + select: true, + }, + ); + const newPageComponent = em.Pages.get('PAGE_ID')?.getMainComponent(); + + expect(clonedComponent?.head).toBeInstanceOf(ComponentHead); + expect(clonedComponent?.head.cid).not.toEqual(originalComponent?.head.cid); + + expect(clonedComponent?.docEl).toBeInstanceOf(Component); + expect(clonedComponent?.docEl.cid).not.toEqual(originalComponent?.docEl.cid); + expect(newPageComponent?.head.cid).not.toEqual(originalComponent?.head.cid); + }); + }); +});