yoastseo
Version:
Yoast client-side content analysis
175 lines (169 loc) • 7.87 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _lodash = require("lodash");
var _assessment = _interopRequireDefault(require("../assessment"));
var _AssessmentResult = _interopRequireDefault(require("../../../values/AssessmentResult"));
var _helpers = require("../../../helpers");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* @typedef {import("../../../languageProcessing/AbstractResearcher").default } Researcher
* @typedef {import("../../../values/").Paper } Paper
*/
/**
* Represents an assessment that returns a score based on the largest percentage of text in which no keyphrase occurs.
*/
class KeyphraseDistributionAssessment extends _assessment.default {
/**
* Sets the identifier and the config.
*
* @param {Object} [config] The configuration to use.
* @param {Object} [config.scores] The scores to use.
* @param {Object} [config.parameters] The parameters to use.
* @param {number} [config.parameters.maxGoodDistractionPercentage]
* The maximum distraction percentage allowed to receive a GOOD result.
* The percentage represents the largest portion of text without the keyphrase.
* @param {number} [config.parameters.maxAcceptableDistractionPercentage]
* The maximum distraction percentage allowed to receive an OKAY result.
* @param {Object} [config.scores] The scores to use.
* @param {number} [config.scores.good] The score to return if keyword occurrences are evenly distributed.
* @param {number} [config.scores.okay] The score to return if keyword occurrences are somewhat unevenly distributed.
* @param {number} [config.scores.bad] The score to return if there is way too much text between keyword occurrences.
* @param {number} [config.scores.noKeyphraseOrText] The score to return if there is no text and/or no keyphrase set.
* @param {string} [config.urlTitle] The URL to the article about this assessment.
* @param {string} [config.urlCallToAction] The URL to the help article for this assessment.
* @param {object} [config.callbacks] The callbacks to use for the assessment.
* @param {function} [config.callbacks.getResultTexts] The function that returns the result texts.
*
*/
constructor(config = {}) {
super();
const defaultConfig = {
parameters: {
maxGoodDistractionPercentage: 30,
maxAcceptableDistractionPercentage: 50
},
scores: {
good: 9,
okay: 6,
bad: 1,
noKeyphraseOrText: 1
},
urlTitle: "https://yoa.st/33q",
urlCallToAction: "https://yoa.st/33u",
callbacks: {}
};
this.identifier = "keyphraseDistribution";
this._config = (0, _lodash.merge)(defaultConfig, config);
}
/**
* Runs the keyphraseDistribution research and based on this returns an assessment result.
*
* @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) {
// Whether the paper has the data needed to return meaningful feedback (keyphrase and text).
this._canAssess = false;
this._keyphraseDistribution = researcher.getResearch("keyphraseDistribution");
if (paper.hasKeyword() && paper.hasText()) {
this._canAssess = true;
}
const assessmentResult = new _AssessmentResult.default();
const calculatedResult = this.calculateResult();
assessmentResult.setScore(calculatedResult.score);
assessmentResult.setText(calculatedResult.resultText);
assessmentResult.setHasMarks(calculatedResult.hasMarks);
// Shows the AI Optimize button even when there's no keyphrase or text.
// The button will handle its own disabled state and tooltip.
if (calculatedResult.score < 9) {
assessmentResult.setHasAIFixes(true);
}
return assessmentResult;
}
/**
* Calculates the result based on the keyphrase distraction percentage from the keyphraseDistribution research.
*
* @returns {{score: number, hasMarks: boolean, resultText: string}} The calculated result.
*/
calculateResult() {
const {
good: goodResultText,
okay: okayResultText,
bad: badResultText,
noKeyphraseOrText: noKeyphraseOrTextResultText
} = this.getFeedbackStrings();
const distractionPercentage = this._keyphraseDistribution.keyphraseDistractionPercentage;
const hasMarks = this._keyphraseDistribution.sentencesToHighlight?.length > 0;
if (!this._canAssess || distractionPercentage === 100) {
return {
score: this._config.scores.noKeyphraseOrText,
hasMarks: hasMarks,
resultText: noKeyphraseOrTextResultText
};
}
if (distractionPercentage > this._config.parameters.maxAcceptableDistractionPercentage) {
return {
score: this._config.scores.bad,
hasMarks: hasMarks,
resultText: badResultText
};
}
if (distractionPercentage > this._config.parameters.maxGoodDistractionPercentage && distractionPercentage <= this._config.parameters.maxAcceptableDistractionPercentage) {
return {
score: this._config.scores.okay,
hasMarks: hasMarks,
resultText: okayResultText
};
}
return {
score: this._config.scores.good,
hasMarks: hasMarks,
resultText: goodResultText
};
}
/**
* Gets the feedback strings for the keyphrase distribution assessment.
* If you want to override the feedback strings, you can do so by providing a custom callback in the config: `this._config.callbacks.getResultTexts`.
* The callback function should return an object with the following properties:
* - good: string
* - okay: string
* - bad: string
* - noKeyphraseOrText: string
*
* @returns {{good: string, okay: string, bad: string, noKeyphraseOrText: string}} The feedback strings.
*/
getFeedbackStrings() {
// `urlTitleAnchorOpeningTag` represents the anchor opening tag with the URL to the article about this assessment.
const urlTitleAnchorOpeningTag = (0, _helpers.createAnchorOpeningTag)(this._config.urlTitle);
// `urlActionAnchorOpeningTag` represents the anchor opening tag with the URL for the call to action.
const urlActionAnchorOpeningTag = (0, _helpers.createAnchorOpeningTag)(this._config.urlCallToAction);
if (!this._config.callbacks.getResultTexts) {
const defaultResultTexts = {
good: "%1$sKeyphrase distribution%3$s: Good job!",
okay: "%1$sKeyphrase distribution%3$s: Uneven. Some parts of your text do not contain the keyphrase or its synonyms. %2$sDistribute them more evenly%3$s.",
bad: "%1$sKeyphrase distribution%3$s: Very uneven. Large parts of your text do not contain the keyphrase or its synonyms. %2$sDistribute them more evenly%3$s.",
noKeyphraseOrText: "%1$sKeyphrase distribution%3$s: %2$sPlease add both a keyphrase and some text containing the keyphrase or its synonyms%3$s."
};
return (0, _lodash.mapValues)(defaultResultTexts, resultText => this.formatResultText(resultText, urlTitleAnchorOpeningTag, urlActionAnchorOpeningTag));
}
return this._config.callbacks.getResultTexts({
urlTitleAnchorOpeningTag,
urlActionAnchorOpeningTag
});
}
/**
* Creates a marker for all content words in keyphrase and synonyms.
*
* @returns {string[]} All markers for the current text.
*/
getMarks() {
return this._keyphraseDistribution.sentencesToHighlight;
}
}
var _default = exports.default = KeyphraseDistributionAssessment;
//# sourceMappingURL=KeyphraseDistributionAssessment.js.map