| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- /**
- * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
- */
- /**
- * @module engine/dataprocessor/xmldataprocessor
- */
- /* globals DOMParser, document */
- import BasicHtmlWriter from './basichtmlwriter';
- import DomConverter from '../view/domconverter';
- /**
- * The XML data processor class.
- * This data processor implementation uses XML as input and output data.
- * This class is needed because unlike HTML, XML allows to use any tag with any value.
- * For example, `<link>Text</link>` is a valid XML but invalid HTML.
- *
- * @implements module:engine/dataprocessor/dataprocessor~DataProcessor
- */
- export default class XmlDataProcessor {
- /**
- * Creates a new instance of the XML data processor class.
- *
- * @param {module:engine/view/document~Document} document The view document instance.
- * @param {Object} options Configuration options.
- * @param {Array<String>} [options.namespaces=[]] A list of namespaces allowed to use in the XML input.
- */
- constructor( document, options = {} ) {
- /**
- * A list of namespaces allowed to use in the XML input.
- *
- * For example, registering namespaces [ 'attribute', 'container' ] allows to use `<attirbute:tagName></attribute:tagName>`
- * and `<container:tagName></container:tagName>` input. It is mainly for debugging.
- *
- * @public
- * @member {DOMParser}
- */
- this.namespaces = options.namespaces || [];
- /**
- * DOM parser instance used to parse an XML string to an XML document.
- *
- * @private
- * @member {DOMParser}
- */
- this._domParser = new DOMParser();
- /**
- * DOM converter used to convert DOM elements to view elements.
- *
- * @private
- * @member {module:engine/view/domconverter~DomConverter}
- */
- this._domConverter = new DomConverter( document, { blockFillerMode: 'nbsp' } );
- /**
- * A basic HTML writer instance used to convert DOM elements to an XML string.
- * There is no need to use a dedicated XML writer because the basic HTML writer works well in this case.
- *
- * @private
- * @member {module:engine/dataprocessor/basichtmlwriter~BasicHtmlWriter}
- */
- this._htmlWriter = new BasicHtmlWriter();
- }
- /**
- * Converts the provided {@link module:engine/view/documentfragment~DocumentFragment document fragment}
- * to data format — in this case an XML string.
- *
- * @param {module:engine/view/documentfragment~DocumentFragment} viewFragment
- * @returns {String} An XML string.
- */
- toData( viewFragment ) {
- // Convert view DocumentFragment to DOM DocumentFragment.
- const domFragment = this._domConverter.viewToDom( viewFragment, document );
- // Convert DOM DocumentFragment to XML output.
- // There is no need to use dedicated for XML serializing method because BasicHtmlWriter works well in this case.
- return this._htmlWriter.getHtml( domFragment );
- }
- /**
- * Converts the provided XML string to a view tree.
- *
- * @param {String} data An XML string.
- * @returns {module:engine/view/node~Node|module:engine/view/documentfragment~DocumentFragment|null} A converted view element.
- */
- toView( data ) {
- // Convert input XML data to DOM DocumentFragment.
- const domFragment = this._toDom( data );
- // Convert DOM DocumentFragment to view DocumentFragment.
- return this._domConverter.domToView( domFragment, { keepOriginalCase: true } );
- }
- /**
- * Converts an XML string to its DOM representation. Returns a document fragment containing nodes parsed from
- * the provided data.
- *
- * @private
- * @param {String} data
- * @returns {DocumentFragment}
- */
- _toDom( data ) {
- // Stringify namespaces.
- const namespaces = this.namespaces.map( nsp => `xmlns:${ nsp }="nsp"` ).join( ' ' );
- // Wrap data into root element with optional namespace definitions.
- data = `<xml ${ namespaces }>${ data }</xml>`;
- const parsedDocument = this._domParser.parseFromString( data, 'text/xml' );
- // Parse validation.
- const parserError = parsedDocument.querySelector( 'parsererror' );
- if ( parserError ) {
- throw new Error( 'Parse error - ' + parserError.textContent );
- }
- const fragment = parsedDocument.createDocumentFragment();
- const nodes = parsedDocument.documentElement.childNodes;
- while ( nodes.length > 0 ) {
- fragment.appendChild( nodes[ 0 ] );
- }
- return fragment;
- }
- }
|