import Node from './Node';
/** Return a new {@link Doctype} {@link Node}.
* @extends Node
*/
class Doctype extends Node {
/**
* @param {DoctypeSettings|string} settings - Custom settings applied to the {@link Doctype}, or the name of the {@link Doctype}.
* @example
* new Doctype({ name: 'html' }) // <!doctype html>
*/
constructor (settings) {
super();
if (typeof settings === 'string') {
settings = { name: settings };
}
/** Type identifier of the Doctype
* @type {'doctype'} */
this.type = 'doctype';
/** Label of the Doctype
* @type {string} */
this.doctype = String(Object(settings).doctype || 'doctype');
/** Name of the Doctype
* @type {string} */
this.name = String(Object(settings).name || 'html');
/** Public identifier portion of the Doctype
* @type {string|null} */
this.publicId = Object(settings).publicId || null;
/** System identifier portion of the Doctype
* @type {string|null} */
this.systemId = Object(settings).systemId || null;
/** Source mapping of the Doctype
* @type {DoctypeSource} */
this.source = Object.assign({
before: Object(Object(settings).source).before || ' ',
after: Object(Object(settings).source).after || '',
beforePublicId: Object(Object(settings).source).beforePublicId || null,
beforeSystemId: Object(Object(settings).source).beforeSystemId || null
}, Object(settings).source);
}
/**
* Return a clone of the current {@link Doctype}.
* @param {DoctypeSettings} settings - Custom settings applied to the cloned {@link Doctype}.
* @returns {Doctype}
* @example
* doctype.clone()
* @example <caption>Clone the current text with new source.</caption>
* doctype.clone({ source: { input: 'modified source' } })
*/
clone (settings) {
return new this.constructor(Object.assign({}, this, settings, {
source: Object.assign({}, this.source, Object(settings).source)
}));
}
/**
* Return the current {@link Doctype} as a String.
*/
toString () {
const publicId = this.publicId ? `${this.source.beforePublicId || ' '}${this.publicId}` : '';
const systemId = this.systemId ? `${this.source.beforeSystemId || ' '}${this.systemId}` : '';
return `<!${this.doctype}${this.source.before}${this.name}${this.source.after}${publicId}${systemId}>`;
}
/**
* Return the current {@link Doctype} as an Object.
*/
toJSON () {
return {
name: this.name,
publicId: this.publicId,
systemId: this.systemId
};
}
}
export default Doctype;
/**
* @typedef {Object} DoctypeSettings - Custom settings applied to the Doctype, or the content of the Doctype.
* @property {string} doctype - Label of the Doctype.
* @property {string} [name] - Name of the Doctype.
* @property {string} [publicId] - Public identifier portion of the Doctype.
* @property {string} [systemId] - System identifier portion of the Doctype.
* @property {DoctypeSource} [source] - Source mapping of the Doctype.
*
* @typedef {Object} DoctypeSource - Source mapping of the Doctype.
* @property {{ html: string }} input - Raw HTML source of the Doctype.
* @property {number} before - Starting content within the Doctype.
* @property {number} after - Starting content within the Doctype.
* @property {number} beforePublicId - Ending offset within the Doctype.
* @property {number} afterPublicId - Ending offset within the Doctype.
*/