UNPKG

yoastseo

Version:

Yoast client-side content analysis

175 lines (169 loc) 7.87 kB
"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