/**
 * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */
/**
 * @module engine/view/text
 */
import Node from './node';
/**
 * Tree view text node.
 *
 * The constructor of this class should not be used directly. To create a new text node instance
 * use the {@link module:engine/view/downcastwriter~DowncastWriter#createText `DowncastWriter#createText()`}
 * method when working on data downcasted from the model or the
 * {@link module:engine/view/upcastwriter~UpcastWriter#createText `UpcastWriter#createText()`}
 * method when working on non-semantic views.
 *
 * @extends module:engine/view/node~Node
 */
export default class Text extends Node {
    /**
     * Creates a tree view text node.
     *
     * @protected
     * @param {module:engine/view/document~Document} document The document instance to which this text node belongs.
     * @param {String} data The text's data.
     */
    constructor(document, data) {
        super(document);
        /**
         * The text content.
         *
         * Setting the data fires the {@link module:engine/view/node~Node#event:change:text change event}.
         *
         * @protected
         * @member {String} module:engine/view/text~Text#_textData
         */
        this._textData = data;
    }
    /**
     * The text content.
     *
     * @readonly
     * @type {String}
     */
    get data() {
        return this._textData;
    }
    /**
     * The `_data` property is controlled by a getter and a setter.
     *
     * The getter is required when using the addition assignment operator on protected property:
     *
     *		const foo = downcastWriter.createText( 'foo' );
     *		const bar = downcastWriter.createText( 'bar' );
     *
     *		foo._data += bar.data;   // executes: `foo._data = foo._data + bar.data`
     *		console.log( foo.data ); // prints: 'foobar'
     *
     * If the protected getter didn't exist, `foo._data` will return `undefined` and result of the merge will be invalid.
     *
     * The setter sets data and fires the {@link module:engine/view/node~Node#event:change:text change event}.
     *
     * @protected
     * @type {String}
     */
    get _data() {
        return this.data;
    }
    set _data(data) {
        this._fireChange('text', this);
        this._textData = data;
    }
    /**
     * Checks if this text node is similar to other text node.
     * Both nodes should have the same data to be considered as similar.
     *
     * @param {module:engine/view/node~Node} otherNode Node to check if it is same as this node.
     * @returns {Boolean}
     */
    isSimilar(otherNode) {
        if (!(otherNode instanceof Text)) {
            return false;
        }
        return this === otherNode || this.data === otherNode.data;
    }
    /**
     * Clones this node.
     *
     * @protected
     * @returns {module:engine/view/text~Text} Text node that is a clone of this node.
     */
    _clone() {
        return new Text(this.document, this.data);
    }
}
/**
 * Checks whether this object is of the given type.
 *
 *		text.is( '$text' ); // -> true
 *		text.is( 'node' ); // -> true
 *		text.is( 'view:$text' ); // -> true
 *		text.is( 'view:node' ); // -> true
 *
 *		text.is( 'model:$text' ); // -> false
 *		text.is( 'element' ); // -> false
 *		text.is( 'range' ); // -> false
 *
 * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.
 *
 * **Note:** Until version 20.0.0 this method wasn't accepting `'$text'` type. The legacy `'text'` type is still
 * accepted for backward compatibility.
 *
 * @param {String} type Type to check.
 * @returns {Boolean}
 */
Text.prototype.is = function (type) {
    return type === '$text' || type === 'view:$text' ||
        // This are legacy values kept for backward compatibility.
        type === 'text' || type === 'view:text' ||
        // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.
        type === 'node' || type === 'view:node';
};
