/** * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or http://ckeditor.com/license */ 'use strict'; /** * A lightweight representation of an HTML DOM structure. * * @class * @constructor Creates a fragment class instance. */ CKEDITOR.htmlParser.fragment = function() { /** * The nodes contained in the root of this fragment. * * var fragment = CKEDITOR.htmlParser.fragment.fromHtml( 'Sample Text' ); * alert( fragment.children.length ); // 2 */ this.children = []; /** * Get the fragment parent. Should always be null. * * @property {Object} [=null] */ this.parent = null; /** @private */ this._ = { isBlockLike: true, hasInlineStarted: false }; }; ( function() { // Block-level elements whose internal structure should be respected during // parser fixing. var nonBreakingBlocks = CKEDITOR.tools.extend( { table: 1, ul: 1, ol: 1, dl: 1 }, CKEDITOR.dtd.table, CKEDITOR.dtd.ul, CKEDITOR.dtd.ol, CKEDITOR.dtd.dl ); var listBlocks = { ol: 1, ul: 1 }; // Dtd of the fragment element, basically it accept anything except for intermediate structure, e.g. orphan
  • . var rootDtd = CKEDITOR.tools.extend( {}, { html: 1 }, CKEDITOR.dtd.html, CKEDITOR.dtd.body, CKEDITOR.dtd.head, { style: 1, script: 1 } ); // Which element to create when encountered not allowed content. var structureFixes = { ul: 'li', ol: 'li', dl: 'dd', table: 'tbody', tbody: 'tr', thead: 'tr', tfoot: 'tr', tr: 'td' }; function isRemoveEmpty( node ) { // Keep marked element event if it is empty. if ( node.attributes[ 'data-cke-survive' ] ) return false; // Empty link is to be removed when empty but not anchor. (#7894) return node.name == 'a' && node.attributes.href || CKEDITOR.dtd.$removeEmpty[ node.name ]; } /** * Creates a {@link CKEDITOR.htmlParser.fragment} from an HTML string. * * var fragment = CKEDITOR.htmlParser.fragment.fromHtml( 'Sample Text' ); * alert( fragment.children[ 0 ].name ); // 'b' * alert( fragment.children[ 1 ].value ); // ' Text' * * @static * @param {String} fragmentHtml The HTML to be parsed, filling the fragment. * @param {CKEDITOR.htmlParser.element/String} [parent] Optional contextual * element which makes the content been parsed as the content of this element and fix * to match it. * If not provided, then {@link CKEDITOR.htmlParser.fragment} will be used * as the parent and it will be returned. * @param {String/Boolean} [fixingBlock] When `parent` is a block limit element, * and the param is a string value other than `false`, it is to * avoid having block-less content as the direct children of parent by wrapping * the content with a block element of the specified tag, e.g. * when `fixingBlock` specified as `p`, the content `foo` * will be fixed into `

    foo

    `. * @returns {CKEDITOR.htmlParser.fragment/CKEDITOR.htmlParser.element} The created fragment or passed `parent`. */ CKEDITOR.htmlParser.fragment.fromHtml = function( fragmentHtml, parent, fixingBlock ) { var parser = new CKEDITOR.htmlParser(); var root = parent instanceof CKEDITOR.htmlParser.element ? parent : typeof parent == 'string' ? new CKEDITOR.htmlParser.element( parent ) : new CKEDITOR.htmlParser.fragment(); var pendingInline = [], pendingBRs = [], currentNode = root, // Indicate we're inside a