UNPKG

yoastseo

Version:

Yoast client-side content analysis

211 lines (198 loc) 9.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _i18n = require("@wordpress/i18n"); var _lodash = require("lodash"); var _assessment = _interopRequireDefault(require("../assessment")); var _formatNumber = _interopRequireDefault(require("../../../helpers/formatNumber")); var _inRange = require("../../helpers/assessments/inRange"); var _helpers = require("../../../helpers"); var _AssessmentResult = _interopRequireDefault(require("../../../values/AssessmentResult")); var _Mark = _interopRequireDefault(require("../../../values/Mark")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** * Represents the assessment that will calculate the length of sentences in the text. */ class SentenceLengthInTextAssessment extends _assessment.default { /** * Sets the identifier and the config. * * @param {object} config The scoring configuration that should be used. * @param {boolean} isCornerstone Whether cornerstone configuration should be used. * @param {boolean} isProduct Whether product configuration should be used. * @returns {void} */ constructor(config = {}, isCornerstone = false, isProduct = false) { super(); const defaultConfig = { recommendedLength: 20, slightlyTooMany: 25, farTooMany: 30, urlTitle: (0, _helpers.createAnchorOpeningTag)("https://yoa.st/34v"), urlCallToAction: (0, _helpers.createAnchorOpeningTag)("https://yoa.st/34w"), countCharacters: false }; // Add cornerstone and/or product-specific config if applicable. this._config = (0, _lodash.merge)(defaultConfig, config); this._isCornerstone = isCornerstone; this._isProduct = isProduct; this.identifier = "textSentenceLength"; } /** * Scores the percentage of sentences including more than the recommended number of words. * * @param {Paper} paper The paper to use for the assessment. * @param {Researcher} researcher The researcher used for calling research. * * @returns {AssessmentResult} The Assessment result. */ getResult(paper, researcher) { const sentences = researcher.getResearch("countSentencesFromText"); if (researcher.getConfig("sentenceLength")) { this._config = this.getLanguageSpecificConfig(researcher); } this._config.countCharacters = !!researcher.getConfig("countCharacters"); const percentage = this.calculatePercentage(sentences); const score = this.calculateScore(percentage); const assessmentResult = new _AssessmentResult.default(); if (score < 9) { assessmentResult.setHasAIFixes(true); } assessmentResult.setScore(score); assessmentResult.setText(this.translateScore(score, percentage)); assessmentResult.setHasMarks(percentage > 0); return assessmentResult; } /** * Mark the sentences. * * @param {Paper} paper The paper to use for the marking. * @param {Researcher} researcher The researcher to use. * * @returns {Array} Array with all the marked sentences. */ getMarks(paper, researcher) { const sentenceCount = researcher.getResearch("countSentencesFromText"); if (researcher.getConfig("sentenceLength")) { this._config = this.getLanguageSpecificConfig(researcher); } const tooLongSentences = this.getTooLongSentences(sentenceCount); return tooLongSentences.map(tooLongSentence => { const { sentence, firstToken, lastToken } = tooLongSentence; const startOffset = firstToken.sourceCodeRange.startOffset; const endOffset = lastToken.sourceCodeRange.endOffset; return new _Mark.default({ position: { startOffset, endOffset, startOffsetBlock: startOffset - (sentence.parentStartOffset || 0), endOffsetBlock: endOffset - (sentence.parentStartOffset || 0), clientId: sentence.parentClientId || "", attributeId: sentence.parentAttributeId || "", isFirstSection: sentence.isParentFirstSectionOfBlock || false } }); }); } /** * Check if there is language-specific config, and if so, overwrite the current config with it. * * @param {Researcher} researcher The researcher to use. * * @returns {Object} The config that should be used. */ getLanguageSpecificConfig(researcher) { const currentConfig = this._config; const languageSpecificConfig = researcher.getConfig("sentenceLength"); if (languageSpecificConfig.hasOwnProperty("recommendedLength")) { currentConfig.recommendedLength = languageSpecificConfig.recommendedLength; } // Check if a language has specific cornerstone configuration for non-product pages. if (this._isCornerstone === true && this._isProduct === false && languageSpecificConfig.hasOwnProperty("cornerstonePercentages")) { return (0, _lodash.merge)(currentConfig, languageSpecificConfig.cornerstonePercentages); } // Check if a language has specific configuration for non-product, non-cornerstone pages. if (this._isCornerstone === false && this._isProduct === false && languageSpecificConfig.hasOwnProperty("percentages")) { return (0, _lodash.merge)(currentConfig, languageSpecificConfig.percentages); } // More conditions should be added below once we add language-specific config for product pages. return currentConfig; } /** * Translates the score to a message the user can understand. * * @param {number} score The score. * @param {number} percentage The percentage. * * @returns {string} A string. */ translateScore(score, percentage) { if (score >= 7) { return (0, _i18n.sprintf)(/* translators: %1$s expands to a link on yoast.com, %2$s expands to the anchor end tag */ (0, _i18n.__)("%1$sSentence length%2$s: Great!", "wordpress-seo"), this._config.urlTitle, "</a>"); } const wordFeedback = (0, _i18n.sprintf)( /* translators: %1$s and %6$s expand to links on yoast.com, %2$s expands to the anchor end tag, %3$s expands to percentage of sentences, %4$d expands to the recommended maximum sentence length, %5$s expands to the recommended maximum percentage. */ (0, _i18n._n)("%1$sSentence length%2$s: %3$s of the sentences contain more than %4$d word, which is more than the recommended maximum of %5$s. %6$sTry to shorten the sentences%2$s.", "%1$sSentence length%2$s: %3$s of the sentences contain more than %4$d words, which is more than the recommended maximum of %5$s. %6$sTry to shorten the sentences%2$s.", this._config.recommendedLength, "wordpress-seo"), this._config.urlTitle, "</a>", percentage + "%", this._config.recommendedLength, this._config.slightlyTooMany + "%", this._config.urlCallToAction); const characterFeedback = (0, _i18n.sprintf)( /* translators: %1$s and %6$s expand to links on yoast.com, %2$s expands to the anchor end tag, %3$s expands to percentage of sentences, %4$d expands to the recommended maximum sentence length, %5$s expands to the recommended maximum percentage. */ (0, _i18n._n)("%1$sSentence length%2$s: %3$s of the sentences contain more than %4$d character, which is more than the recommended maximum of %5$s. %6$sTry to shorten the sentences%2$s.", "%1$sSentence length%2$s: %3$s of the sentences contain more than %4$d characters, which is more than the recommended maximum of %5$s. %6$sTry to shorten the sentences%2$s.", this._config.recommendedLength, "wordpress-seo"), this._config.urlTitle, "</a>", percentage + "%", this._config.recommendedLength, this._config.slightlyTooMany + "%", this._config.urlCallToAction); return this._config.countCharacters ? characterFeedback : wordFeedback; } /** * Calculates the percentage of sentences that are too long. * * @param {SentenceLength[]} sentences The sentences to calculate the percentage for. * @returns {number} The calculates percentage of too long sentences. */ calculatePercentage(sentences) { let percentage = 0; if (sentences.length !== 0) { const tooLongTotal = this.getTooLongSentences(sentences).length; percentage = (0, _formatNumber.default)(tooLongTotal / sentences.length * 100); } return percentage; } /** * Calculates the score for the given percentage. * * @param {number} percentage The percentage to calculate the score for. * @returns {number} The calculated score. */ calculateScore(percentage) { let score; // Green indicator. if (percentage <= this._config.slightlyTooMany) { score = 9; } // Orange indicator. if ((0, _inRange.inRangeEndInclusive)(percentage, this._config.slightlyTooMany, this._config.farTooMany)) { score = 6; } // Red indicator. if (percentage > this._config.farTooMany) { score = 3; } return score; } /** * Returns the sentences that are qualified as being too long. * @param {SentenceLength[]} sentences The sentences to filter. * @returns {SentenceLength[]} Array with all the sentences considered to be too long. */ getTooLongSentences(sentences) { return sentences.filter(sentence => sentence.sentenceLength > this._config.recommendedLength); } } var _default = exports.default = SentenceLengthInTextAssessment; //# sourceMappingURL=SentenceLengthInTextAssessment.js.map