UNPKG

yoastseo

Version:

Yoast client-side content analysis

273 lines (249 loc) 8.06 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _lodash = require("lodash"); const defaultProperties = { original: "", marked: "", fieldsToMark: [] }; /** * Represents a place where highlighting should be applied. */ class Mark { /** * Represents a place where highlighting should be applied. * We allow both replacement-based highlighting (through providing `original`, `marked`, and potentially `fieldsToMark`) and * position-based highlighting (through providing a `position`). * * @param {Object} [properties] The properties of this Mark. * * @param {string} [properties.original] The original text that should be marked. * @param {string} [properties.marked] The new text including marks. * @param {array} [properties.fieldsToMark] The array that specifies which text section(s) to mark, e.g. "heading". * * @param {SourceCodeRange} [properties.position] The position object: a range in the source code. */ constructor(properties) { properties = properties || {}; (0, _lodash.defaults)(properties, defaultProperties); this._properties = properties; this.isValid(); } /** * Returns the original text. * * @returns {string} The original text. */ getOriginal() { return this._properties.original; } /** * Returns the marked text. * * @returns {string} The replaced text. */ getMarked() { return this._properties.marked; } /** * Returns the fields to mark. * * @returns {array} The fields to mark. */ getFieldsToMark() { return this._properties.fieldsToMark; } /** * Returns the position information. * * @returns {Object} The position information. */ getPosition() { return this._properties.position; } /** * Returns the start position. * * @returns {number} The start position. */ getPositionStart() { return this._properties.position && this._properties.position.startOffset; } /** * Returns the end position. * * @returns {number} The end position. */ getPositionEnd() { return this._properties.position && this._properties.position.endOffset; } /** * Sets the start position. * * @param {number} positionStart The new start position. * * @returns {void} */ setPositionStart(positionStart) { this._properties.position.startOffset = positionStart; } /** * Sets the end position. * * @param {number} positionEnd The new end position. * * @returns {void} */ setPositionEnd(positionEnd) { this._properties.position.endOffset = positionEnd; } /** * Returns the start position of a block. * * @param {number} startOffsetBlock The block start offset. * * @returns {number} The start position of a block. */ setBlockPositionStart(startOffsetBlock) { this._properties.position.startOffsetBlock = startOffsetBlock; } /** * Returns the end position of a block. * * @param {number} endOffsetBlock The block end offset. * * @returns {number} The end position of a block. */ setBlockPositionEnd(endOffsetBlock) { this._properties.position.endOffsetBlock = endOffsetBlock; } /** * Gets the block client id. * * @returns {string} The block client id. */ getBlockClientId() { return this._properties.position && this._properties.position.clientId; } /** * Gets the block attribute id. * * @returns {string} The block attribute id. */ getBlockAttributeId() { return this._properties.position && this._properties.position.attributeId; } /** * Checks if the mark object is intended for the first section of a Yoast sub-block. * This method will be used only for Yoast blocks where each block consists of sub-blocks * with two sections. * * @returns {boolean} Whether the mark object is intended for the first section of a Yoast sub-block. */ isMarkForFirstBlockSection() { return this._properties.position && this._properties.position.isFirstSection; } /** * Returns the start position inside block. * * @returns {number} The start position inside the block if the mark has position information, undefined otherwise. */ getBlockPositionStart() { return this._properties.position && this._properties.position.startOffsetBlock; } /** * Returns the end position inside block if the mark has position information, undefined otherwise. * * @returns {number} The end position inside block. */ getBlockPositionEnd() { return this._properties.position && this._properties.position.endOffsetBlock; } /** * Applies this mark to the given text with replacement-based highlighting. * * @param {string} text The original text without the mark applied. * @returns {string} A new text with the mark applied to it. */ applyWithReplace(text) { // (=^ ◡ ^=) Cute method to replace everything in a string without using regex. return text.split(this._properties.original).join(this._properties.marked); } /** * Applies this mark to the given text with position-based highlighting. * * @param {string} text The original text without the mark applied. * @returns {string} A new text with the mark applied to it. */ applyWithPosition(text) { const markStart = "<yoastmark class='yoast-text-mark'>"; const markEnd = "</yoastmark>"; const newPositionEnd = this.getPositionEnd() + markStart.length; text = text.substring(0, this.getPositionStart()) + markStart + text.substring(this.getPositionStart()); text = text.substring(0, newPositionEnd) + markEnd + text.substring(newPositionEnd); return text; } /** * Serializes the Mark instance to an object. * * @returns {Object} The serialized Mark. */ serialize() { return { _parseClass: "Mark", ...this._properties }; } /* eslint-disable complexity */ /** * Checks if the mark object is valid for position-based highlighting. * @returns {void} */ isValid() { if (!(0, _lodash.isUndefined)(this.getPositionStart()) && this.getPositionStart() < 0) { throw new RangeError("positionStart should be larger or equal than 0."); } if (!(0, _lodash.isUndefined)(this.getPositionEnd()) && this.getPositionEnd() <= 0) { throw new RangeError("positionEnd should be larger than 0."); } if (!(0, _lodash.isUndefined)(this.getPositionStart()) && !(0, _lodash.isUndefined)(this.getPositionEnd()) && this.getPositionStart() >= this.getPositionEnd()) { throw new RangeError("The positionStart should be smaller than the positionEnd."); } if ((0, _lodash.isUndefined)(this.getPositionStart()) && !(0, _lodash.isUndefined)(this.getPositionEnd()) || (0, _lodash.isUndefined)(this.getPositionEnd()) && !(0, _lodash.isUndefined)(this.getPositionStart())) { throw new Error("A mark object should either have start and end defined or start and end undefined."); } } /* eslint-enable complexity */ /** * Checks if a mark has position information available. * @returns {boolean} Returns true if the Mark object has position information, false otherwise. */ hasPosition() { return !(0, _lodash.isUndefined)(this.getPositionStart()); } /** * Checks if a mark has block position information available. * A block has position information if the block start offset is available. * * @returns {boolean} Returns true if the Mark object has block position information, false otherwise. */ hasBlockPosition() { return !(0, _lodash.isUndefined)(this.getBlockPositionStart()); } /** * Parses the object to a Mark. * * @param {Object} serialized The serialized object. * * @returns {Mark} The parsed Mark. */ static parse(serialized) { delete serialized._parseClass; return new Mark(serialized); } } var _default = exports.default = Mark; //# sourceMappingURL=Mark.js.map