yoastseo
Version:
Yoast client-side content analysis
211 lines (198 loc) • 9.39 kB
JavaScript
"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