diff --git a/src/code_manager/model/HtmlGenerator.ts b/src/code_manager/model/HtmlGenerator.ts
index 8a7ad32c5..5b966c5ee 100644
--- a/src/code_manager/model/HtmlGenerator.ts
+++ b/src/code_manager/model/HtmlGenerator.ts
@@ -1,19 +1,14 @@
import { Model } from '../../common';
import Component from '../../dom_components/model/Component';
+import { ToHTMLOptions } from '../../dom_components/model/types';
import EditorModel from '../../editor/model/Editor';
-export type HTMLGeneratorBuildOptions = {
+export interface HTMLGeneratorBuildOptions extends ToHTMLOptions {
/**
* Remove unnecessary IDs (eg. those created automatically).
*/
cleanId?: boolean;
-
- /**
- * You can pass an object of custom attributes to replace with the current ones
- * or you can even pass a function to generate attributes dynamically.
- */
- attributes?: Record | ((component: Component, attr: Record) => Record);
-};
+}
export default class HTMLGenerator extends Model {
build(model: Component, opts: HTMLGeneratorBuildOptions & { em?: EditorModel } = {}) {
diff --git a/src/dom_components/model/ComponentWrapper.ts b/src/dom_components/model/ComponentWrapper.ts
index e0d20f894..71a0552a1 100644
--- a/src/dom_components/model/ComponentWrapper.ts
+++ b/src/dom_components/model/ComponentWrapper.ts
@@ -1,5 +1,6 @@
import Component from './Component';
import ComponentHead, { type as typeHead } from './ComponentHead';
+import { ToHTMLOptions } from './types';
export default class ComponentWrapper extends Component {
get defaults() {
@@ -12,6 +13,8 @@ export default class ComponentWrapper extends Component {
draggable: false,
components: [],
traits: [],
+ // In case we might need the doctype as component https://stackoverflow.com/a/10162353
+ doctype: '',
head: null,
stylable: [
'background',
@@ -40,6 +43,14 @@ export default class ComponentWrapper extends Component {
return this.get('head');
}
+ toHTML(opts: ToHTMLOptions = {}) {
+ const { asDocument } = opts;
+ const { doctype = '' } = this.attributes;
+ const body = super.toHTML(opts);
+ const head = (asDocument && this.head?.toHTML(opts)) || '';
+ return asDocument ? `${doctype}${head}${body}` : body;
+ }
+
__postAdd() {
const um = this.em?.UndoManager;
!this.__hasUm && um?.add(this);
diff --git a/src/dom_components/model/types.ts b/src/dom_components/model/types.ts
index e782f76e5..f8139e0e2 100644
--- a/src/dom_components/model/types.ts
+++ b/src/dom_components/model/types.ts
@@ -264,7 +264,7 @@ type ComponentAddType = Component | ComponentDefinition | ComponentDefinitionDef
export type ComponentAdd = ComponentAddType | ComponentAddType[];
-export type ToHTMLOptions = {
+export interface ToHTMLOptions {
/**
* Custom tagName.
*/
@@ -280,12 +280,17 @@ export type ToHTMLOptions = {
*/
altQuoteAttr?: boolean;
+ /**
+ * Return the HTML string as document (option valid on the root component, eg. will include the ).
+ */
+ asDocument?: boolean;
+
/**
* You can pass an object of custom attributes to replace with the current ones
* or you can even pass a function to generate attributes dynamically.
*/
attributes?: Record | ((component: Component, attr: Record) => Record);
-};
+}
export interface ComponentOptions {
em?: EditorModel;