Text.js

import Node from './Node';

/** Return a new {@link Text} {@link Node}.
* @extends Node
* @example
* new Text({ data: 'Hello World' })
*/
class Text extends Node {
	/**
	* @param {TextSettings|string} settings - Custom settings applied to the {@link Text}, or the content of the {@link Text}.
	*/
	constructor (settings) {
		super();

		if (typeof settings === 'string') {
			/** @typedef {TextSettings} */
			settings = { data: settings };
		}

		/** Type identifier of the Text
		* @type {'text'} */
		this.type = 'text';

		/** Node name of the Text
		* @type {'#text'} */
		this.name = '#text';

		/** Content of the Text
		* @type {string} */
		this.data = String(Object(settings).data || '');

		/** Source mapping of the Text
		* @type {TextSource} */
		this.source = Object(Object(settings).source);
	}

	/**
	* Return the stringified innerHTML from the source input.
	* @returns {string}
	*/
	get sourceInnerHTML () {
		return typeof Object(this.source.input).html !== 'string'
			? ''
		: this.source.input.html.slice(
			this.source.startOffset,
			this.source.endOffset
		);
	}

	/**
	* Return the stringified outerHTML from the source input.
	* @returns {string}
	*/
	get sourceOuterHTML () {
		return typeof Object(this.source.input).html !== 'string'
			? ''
		: this.source.input.html.slice(
			this.source.startOffset,
			this.source.endOffset
		);
	}

	/**
	* Return the current {@link Text} as a String.
	* @returns {string}
	* @example
	* text.textContent // returns ''
	*/
	get textContent () {
		return String(this.data);
	}

	/**
	* Define the current {@link Text} from a String.
	* @returns {void}
	* @example
	* text.textContent = 'Hello World'
	* text.textContent // 'Hello World'
	*/
	set textContent (textContent) {
		this.data = String(textContent);
	}

	/**
	* Return a clone of the current {@link Text}.
	* @param {Object} settings - Custom settings applied to the cloned {@link Text}.
	* @returns {Text}
	* @example
	* text.clone()
	* @example <caption>Clone the current text with new source.</caption>
	* text.clone({ source: { input: 'modified source' } })
	*/
	clone (settings) {
		return new Text(Object.assign({}, this, settings, {
			source: Object.assign({}, this.source, Object(settings).source)
		}));
	}

	/**
	* Return the current {@link Text} as a String.
	* @returns {string}
	* @example
	* text.toString() // returns ''
	*/
	toString () {
		return String(this.data);
	}

	/**
	* Return the current {@link Text} as a String.
	* @returns {string}
	* @example
	* text.toJSON() // returns ''
	*/
	toJSON () {
		return String(this.data);
	}
}

export default Text;

/**
* @typedef {Object} TextSettings - Custom settings applied to the Text, or the content of the Text.
* @property {string} data - Content of the Text.
* @property {TextSource} source - Source mapping of the Text.
*
* @typedef {Object} TextSource - Source mapping of the Text.
* @property {{ html: string }} input - Raw HTML source of the Text.
* @property {number} startOffset - starting offset of the raw HTML source of the Text.
* @property {number} endOffset - Ending offset of the raw HTML source of the Text.
*/