UNPKG

@ckeditor/ckeditor5-html-support

Version:

HTML Support feature for CKEditor 5.

986 lines (985 loc) • 25.1 kB
/** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ /** * @module html-support/schemadefinitions */ /** * Skipped elements due to HTML deprecation: * * noframes (not sure if we should provide support for this element. CKE4 is not supporting frameset and frame, * but it will unpack <frameset><noframes>foobar</noframes></frameset> to <noframes>foobar</noframes>, so there * may be some content loss. Although using noframes as a standalone element seems invalid) * * keygen (this one is also empty) * * applet (support is limited mostly to old IE) * * basefont (this one is also empty) * * isindex (basically no support for modern browsers at all) * * Skipped elements due to lack empty element support: * * hr * * area * * br * * command * * map * * wbr * * colgroup -> col * * Skipped elements due to complexity: * * datalist with option elements used as a data source for input[list] element * * Skipped elements as they are handled as an object content: * * track * * source * * option * * param * * optgroup * * Skipped full page HTML elements: * * body * * html * * title * * head * * meta * * link * * etc... * * Skipped hidden elements: * noscript * * When adding elements to this list, update the feature guide listing, too. * * @internal */ export const defaultConfig = { block: [ // Existing features. { model: 'codeBlock', view: 'pre' }, { model: 'paragraph', view: 'p' }, { model: 'blockQuote', view: 'blockquote' }, { model: 'listItem', view: 'li' }, { model: 'pageBreak', view: 'div' }, { model: 'rawHtml', view: 'div' }, { model: 'table', view: 'table' }, { model: 'tableRow', view: 'tr' }, { model: 'tableCell', view: 'td' }, { model: 'tableCell', view: 'th' }, { model: 'tableColumnGroup', view: 'colgroup' }, { model: 'tableColumn', view: 'col' }, { model: 'caption', view: 'caption' }, { model: 'caption', view: 'figcaption' }, { model: 'imageBlock', view: 'img' }, { model: 'imageInline', view: 'img' }, { model: 'horizontalLine', view: 'hr' }, // Compatibility features. { model: 'htmlP', view: 'p', modelSchema: { inheritAllFrom: '$block' } }, { model: 'htmlBlockquote', view: 'blockquote', modelSchema: { inheritAllFrom: '$container' } }, { model: 'htmlTable', view: 'table', modelSchema: { allowWhere: '$block', isBlock: true } }, { model: 'htmlTbody', view: 'tbody', modelSchema: { allowIn: 'htmlTable', isBlock: false } }, { model: 'htmlThead', view: 'thead', modelSchema: { allowIn: 'htmlTable', isBlock: false } }, { model: 'htmlTfoot', view: 'tfoot', modelSchema: { allowIn: 'htmlTable', isBlock: false } }, { model: 'htmlCaption', view: 'caption', modelSchema: { allowIn: 'htmlTable', allowChildren: '$text', isBlock: false } }, { model: 'htmlColgroup', view: 'colgroup', modelSchema: { allowIn: 'htmlTable', allowChildren: 'col', isBlock: false } }, { model: 'htmlCol', view: 'col', modelSchema: { allowIn: 'htmlColgroup', isBlock: false } }, { model: 'htmlTr', view: 'tr', modelSchema: { allowIn: ['htmlTable', 'htmlThead', 'htmlTbody'], isLimit: true } }, // TODO can also include text. { model: 'htmlTd', view: 'td', modelSchema: { allowIn: 'htmlTr', allowContentOf: '$container', isLimit: true, isBlock: false } }, // TODO can also include text. { model: 'htmlTh', view: 'th', modelSchema: { allowIn: 'htmlTr', allowContentOf: '$container', isLimit: true, isBlock: false } }, // TODO can also include text. { model: 'htmlFigure', view: 'figure', modelSchema: { inheritAllFrom: '$container', isBlock: false } }, // TODO can also include other block elements. { model: 'htmlFigcaption', view: 'figcaption', modelSchema: { allowIn: 'htmlFigure', allowChildren: '$text', isBlock: false } }, // TODO can also include text. { model: 'htmlAddress', view: 'address', modelSchema: { inheritAllFrom: '$container', isBlock: false } }, // TODO can also include text. { model: 'htmlAside', view: 'aside', modelSchema: { inheritAllFrom: '$container', isBlock: false } }, // TODO can also include text. { model: 'htmlMain', view: 'main', modelSchema: { inheritAllFrom: '$container', isBlock: false } }, // TODO can also include text. { model: 'htmlDetails', view: 'details', modelSchema: { inheritAllFrom: '$container', isBlock: false } }, { model: 'htmlSummary', view: 'summary', modelSchema: { allowChildren: [ 'htmlH1', 'htmlH2', 'htmlH3', 'htmlH4', 'htmlH5', 'htmlH6', '$text' ], allowIn: 'htmlDetails', isBlock: false } }, { model: 'htmlDiv', view: 'div', paragraphLikeModel: 'htmlDivParagraph', modelSchema: { inheritAllFrom: '$container' } }, // TODO can also include text. { model: 'htmlFieldset', view: 'fieldset', modelSchema: { inheritAllFrom: '$container', isBlock: false } }, // TODO can also include h1-h6. { model: 'htmlLegend', view: 'legend', modelSchema: { allowIn: 'htmlFieldset', allowChildren: '$text' } }, // TODO can also include text. { model: 'htmlHeader', view: 'header', modelSchema: { inheritAllFrom: '$container', isBlock: false } }, // TODO can also include text. { model: 'htmlFooter', view: 'footer', modelSchema: { inheritAllFrom: '$container', isBlock: false } }, // TODO can also include text. { model: 'htmlForm', view: 'form', modelSchema: { inheritAllFrom: '$container', isBlock: true } }, { model: 'htmlHgroup', view: 'hgroup', modelSchema: { allowIn: ['$root', '$container'], allowChildren: [ 'paragraph', 'htmlP', 'htmlH1', 'htmlH2', 'htmlH3', 'htmlH4', 'htmlH5', 'htmlH6' ], isBlock: false } }, { model: 'htmlH1', view: 'h1', modelSchema: { inheritAllFrom: '$block' } }, { model: 'htmlH2', view: 'h2', modelSchema: { inheritAllFrom: '$block' } }, { model: 'htmlH3', view: 'h3', modelSchema: { inheritAllFrom: '$block' } }, { model: 'htmlH4', view: 'h4', modelSchema: { inheritAllFrom: '$block' } }, { model: 'htmlH5', view: 'h5', modelSchema: { inheritAllFrom: '$block' } }, { model: 'htmlH6', view: 'h6', modelSchema: { inheritAllFrom: '$block' } }, { model: '$htmlList', modelSchema: { allowWhere: '$container', allowChildren: ['$htmlList', 'htmlLi'], isBlock: false } }, { model: 'htmlDir', view: 'dir', modelSchema: { inheritAllFrom: '$htmlList' } }, { model: 'htmlMenu', view: 'menu', modelSchema: { inheritAllFrom: '$htmlList' } }, { model: 'htmlUl', view: 'ul', modelSchema: { inheritAllFrom: '$htmlList' } }, { model: 'htmlOl', view: 'ol', modelSchema: { inheritAllFrom: '$htmlList' } }, // TODO can also include other block elements. { model: 'htmlLi', view: 'li', modelSchema: { allowIn: '$htmlList', allowChildren: '$text', isBlock: false } }, { model: 'htmlPre', view: 'pre', modelSchema: { inheritAllFrom: '$block' } }, { model: 'htmlArticle', view: 'article', modelSchema: { inheritAllFrom: '$container', isBlock: false } }, { model: 'htmlSection', view: 'section', modelSchema: { inheritAllFrom: '$container', isBlock: false } }, // TODO can also include text. { model: 'htmlNav', view: 'nav', modelSchema: { inheritAllFrom: '$container', isBlock: false } }, { model: 'htmlDivDl', view: 'div', modelSchema: { allowChildren: ['htmlDt', 'htmlDd'], allowIn: 'htmlDl' } }, { model: 'htmlDl', view: 'dl', modelSchema: { allowWhere: '$container', allowChildren: ['htmlDt', 'htmlDd', 'htmlDivDl'], isBlock: false } }, { model: 'htmlDt', view: 'dt', modelSchema: { allowChildren: '$block', isBlock: false } }, { model: 'htmlDd', view: 'dd', modelSchema: { allowChildren: '$block', isBlock: false } }, { model: 'htmlCenter', view: 'center', modelSchema: { inheritAllFrom: '$container', isBlock: false } }, { model: 'htmlHr', view: 'hr', isEmpty: true, modelSchema: { inheritAllFrom: '$blockObject' } } ], inline: [ // Existing features (attribute set on an existing model element). { model: 'htmlLiAttributes', view: 'li', appliesToBlock: true, coupledAttribute: 'listItemId' }, { model: 'htmlOlAttributes', view: 'ol', appliesToBlock: true, coupledAttribute: 'listItemId' }, { model: 'htmlUlAttributes', view: 'ul', appliesToBlock: true, coupledAttribute: 'listItemId' }, { model: 'htmlFigureAttributes', view: 'figure', appliesToBlock: 'table' }, { model: 'htmlTheadAttributes', view: 'thead', appliesToBlock: 'table' }, { model: 'htmlTbodyAttributes', view: 'tbody', appliesToBlock: 'table' }, { model: 'htmlFigureAttributes', view: 'figure', appliesToBlock: 'imageBlock' }, // Compatibility features. { model: 'htmlAcronym', view: 'acronym', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlTt', view: 'tt', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlFont', view: 'font', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlTime', view: 'time', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlVar', view: 'var', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlBig', view: 'big', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlSmall', view: 'small', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlSamp', view: 'samp', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlQ', view: 'q', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlOutput', view: 'output', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlKbd', view: 'kbd', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlBdi', view: 'bdi', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlBdo', view: 'bdo', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlAbbr', view: 'abbr', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlA', view: 'a', priority: 5, coupledAttribute: 'linkHref', attributeProperties: { isFormatting: true } }, { model: 'htmlStrong', view: 'strong', coupledAttribute: 'bold', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlB', view: 'b', coupledAttribute: 'bold', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlI', view: 'i', coupledAttribute: 'italic', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlEm', view: 'em', coupledAttribute: 'italic', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlS', view: 's', coupledAttribute: 'strikethrough', attributeProperties: { copyOnEnter: true, isFormatting: true } }, // TODO According to HTML-spec can behave as div-like element, although CKE4 only handles it as an inline element. { model: 'htmlDel', view: 'del', coupledAttribute: 'strikethrough', attributeProperties: { copyOnEnter: true, isFormatting: true } }, // TODO According to HTML-spec can behave as div-like element, although CKE4 only handles it as an inline element. { model: 'htmlIns', view: 'ins', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlU', view: 'u', coupledAttribute: 'underline', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlSub', view: 'sub', coupledAttribute: 'subscript', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlSup', view: 'sup', coupledAttribute: 'superscript', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlCode', view: 'code', coupledAttribute: 'code', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlMark', view: 'mark', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlSpan', view: 'span', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlCite', view: 'cite', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlLabel', view: 'label', attributeProperties: { copyOnEnter: true, isFormatting: true } }, { model: 'htmlDfn', view: 'dfn', attributeProperties: { copyOnEnter: true, isFormatting: true } }, // Objects. { model: 'htmlObject', view: 'object', isObject: true, modelSchema: { inheritAllFrom: '$inlineObject' } }, { model: 'htmlIframe', view: 'iframe', isObject: true, modelSchema: { inheritAllFrom: '$inlineObject' } }, { model: 'htmlInput', view: 'input', isObject: true, modelSchema: { inheritAllFrom: '$inlineObject' } }, { model: 'htmlButton', view: 'button', isObject: true, modelSchema: { inheritAllFrom: '$inlineObject' } }, { model: 'htmlTextarea', view: 'textarea', isObject: true, modelSchema: { inheritAllFrom: '$inlineObject' } }, { model: 'htmlSelect', view: 'select', isObject: true, modelSchema: { inheritAllFrom: '$inlineObject' } }, { model: 'htmlVideo', view: 'video', isObject: true, modelSchema: { inheritAllFrom: '$inlineObject' } }, { model: 'htmlEmbed', view: 'embed', isObject: true, modelSchema: { inheritAllFrom: '$inlineObject' } }, { model: 'htmlOembed', view: 'oembed', isObject: true, modelSchema: { inheritAllFrom: '$inlineObject' } }, { model: 'htmlAudio', view: 'audio', isObject: true, modelSchema: { inheritAllFrom: '$inlineObject' } }, { model: 'htmlImg', view: 'img', isObject: true, modelSchema: { inheritAllFrom: '$inlineObject' } }, { model: 'htmlCanvas', view: 'canvas', isObject: true, modelSchema: { inheritAllFrom: '$inlineObject' } }, // TODO it could be probably represented as non-object element, although it has graphical representation, // so probably makes more sense to keep it as an object. { model: 'htmlMeter', view: 'meter', isObject: true, modelSchema: { inheritAllFrom: '$inlineObject' } }, // TODO it could be probably represented as non-object element, although it has graphical representation, // so probably makes more sense to keep it as an object. { model: 'htmlProgress', view: 'progress', isObject: true, modelSchema: { inheritAllFrom: '$inlineObject' } }, { model: 'htmlScript', view: 'script', modelSchema: { allowWhere: ['$text', '$block'], isInline: true } }, { model: 'htmlStyle', view: 'style', modelSchema: { allowWhere: ['$text', '$block'], isInline: true } }, { model: 'htmlCustomElement', view: '$customElement', modelSchema: { allowWhere: ['$text', '$block'], allowAttributesOf: '$inlineObject', isInline: true } } ] };