yoastseo
Version:
Yoast client-side content analysis
181 lines (172 loc) • 8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _i18n = require("@wordpress/i18n");
var _lodash = require("lodash");
var _getSubheadings = require("../../../languageProcessing/helpers/html/getSubheadings");
var _assessment = _interopRequireDefault(require("../assessment"));
var _shortlinker = require("../../../helpers/shortlinker");
var _inRange = require("../../helpers/assessments/inRange.js");
var _AssessmentResult = _interopRequireDefault(require("../../../values/AssessmentResult"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Represents the assessment that checks if the keyword is present in one of the subheadings.
*/
class SubHeadingsKeywordAssessment extends _assessment.default {
/**
* Sets the identifier and the config.
*
* @param {object} config The configuration to use.
*
* @returns {void}
*/
constructor(config = {}) {
super();
const defaultConfig = {
parameters: {
lowerBoundary: 0.3,
upperBoundary: 0.75
},
scores: {
noMatches: 3,
tooFewMatches: 3,
goodNumberOfMatches: 9,
tooManyMatches: 3
},
urlTitle: (0, _shortlinker.createAnchorOpeningTag)("https://yoa.st/33m"),
urlCallToAction: (0, _shortlinker.createAnchorOpeningTag)("https://yoa.st/33n")
};
this.identifier = "subheadingsKeyword";
this._config = (0, _lodash.merge)(defaultConfig, config);
}
/**
* Runs the matchKeywordInSubheadings 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) {
this._subHeadings = researcher.getResearch("matchKeywordInSubheadings");
const assessmentResult = new _AssessmentResult.default();
this._minNumberOfSubheadings = Math.ceil(this._subHeadings.count * this._config.parameters.lowerBoundary);
this._maxNumberOfSubheadings = Math.floor(this._subHeadings.count * this._config.parameters.upperBoundary);
const calculatedResult = this.calculateResult();
assessmentResult.setScore(calculatedResult.score);
assessmentResult.setText(calculatedResult.resultText);
return assessmentResult;
}
/**
* Checks whether the paper has a subheadings.
*
* @param {Paper} paper The paper to use for the check.
*
* @returns {boolean} True when there is at least one subheading.
*/
hasSubheadings(paper) {
const subheadings = (0, _getSubheadings.getSubheadingsTopLevel)(paper.getText());
return subheadings.length > 0;
}
/**
* Checks whether the paper has a text and a keyword.
*
* @param {Paper} paper The paper to use for the assessment.
*
* @returns {boolean} True when there is text and a keyword.
*/
isApplicable(paper) {
return paper.hasText() && paper.hasKeyword() && this.hasSubheadings(paper);
}
/**
* Checks whether there are too few subheadings with the keyphrase.
*
* This is the case if the number of subheadings with the keyphrase is more than 0 but less than the specified
* recommended minimum.
*
* @returns {boolean} Returns true if the keyphrase is included in too few subheadings.
*/
hasTooFewMatches() {
return this._subHeadings.matches > 0 && this._subHeadings.matches < this._minNumberOfSubheadings;
}
/**
* Checks whether there are too many subheadings with the keyphrase.
*
* The upper limit is only applicable if there is more than one subheading. If there is only one subheading with
* the keyphrase this would otherwise always lead to a 100% match rate.
*
* @returns {boolean} Returns true if there is more than one subheading and if the keyphrase is included in less
* subheadings than the recommended maximum.
*/
hasTooManyMatches() {
return this._subHeadings.count > 1 && this._subHeadings.matches > this._maxNumberOfSubheadings;
}
/**
* Checks whether there is only one higher-level subheading and this subheading includes the keyphrase.
*
* @returns {boolean} Returns true if there is exactly one higher-level subheading and this
* subheading has a keyphrase match.
*/
isOneOfOne() {
return this._subHeadings.count === 1 && this._subHeadings.matches === 1;
}
/**
* Checks whether there is a good number of subheadings with the keyphrase.
*
* This is the case if there is only one subheading and that subheading includes the keyphrase or if the number of
* subheadings with the keyphrase is within the specified recommended range.
*
* @returns {boolean} Returns true if the keyphrase is included in a sufficient number of subheadings.
*/
hasGoodNumberOfMatches() {
return (0, _inRange.inRangeStartEndInclusive)(this._subHeadings.matches, this._minNumberOfSubheadings, this._maxNumberOfSubheadings);
}
/**
* Determines the score and the Result text for the subheadings.
*
* @returns {Object} The object with the calculated score and the result text.
*/
calculateResult() {
if (this.hasTooFewMatches()) {
return {
score: this._config.scores.tooFewMatches,
resultText: (0, _i18n.sprintf)(/* translators: %1$s and %2$s expand to a link on yoast.com, %3$s expands to the anchor end tag. */
(0, _i18n.__)("%1$sKeyphrase in subheading%3$s: %2$sUse more keyphrases or synonyms in your H2 and H3 subheadings%3$s!", "wordpress-seo"), this._config.urlTitle, this._config.urlCallToAction, "</a>")
};
}
if (this.hasTooManyMatches()) {
return {
score: this._config.scores.tooManyMatches,
resultText: (0, _i18n.sprintf)(/* translators: %1$s and %2$s expand to a link on yoast.com, %3$s expands to the anchor end tag. */
(0, _i18n.__)("%1$sKeyphrase in subheading%3$s: More than 75%% of your H2 and H3 subheadings reflect the topic of your copy. That's too much. %2$sDon't over-optimize%3$s!", "wordpress-seo"), this._config.urlTitle, this._config.urlCallToAction, "</a>")
};
}
if (this.isOneOfOne()) {
return {
score: this._config.scores.goodNumberOfMatches,
resultText: (0, _i18n.sprintf)(
/* translators: %1$s expands to a link on yoast.com, %2$s expands to the anchor end tag,
%3$d expands to the number of subheadings containing the keyphrase. */
(0, _i18n.__)("%1$sKeyphrase in subheading%2$s: Your H2 or H3 subheading reflects the topic of your copy. Good job!", "wordpress-seo"), this._config.urlTitle, "</a>", this._subHeadings.matches)
};
}
if (this.hasGoodNumberOfMatches()) {
return {
score: this._config.scores.goodNumberOfMatches,
resultText: (0, _i18n.sprintf)(
/* translators: %1$s expands to a link on yoast.com, %2$s expands to the anchor end tag,
%3$d expands to the number of subheadings containing the keyphrase. */
(0, _i18n._n)("%1$sKeyphrase in subheading%2$s: %3$s of your H2 and H3 subheadings reflects the topic of your copy. Good job!", "%1$sKeyphrase in subheading%2$s: %3$s of your H2 and H3 subheadings reflect the topic of your copy. Good job!", this._subHeadings.matches, "wordpress-seo"), this._config.urlTitle, "</a>", this._subHeadings.matches)
};
}
return {
score: this._config.scores.noMatches,
resultText: (0, _i18n.sprintf)(/* translators: %1$s and %2$s expand to a link on yoast.com, %3$s expands to the anchor end tag. */
(0, _i18n.__)("%1$sKeyphrase in subheading%3$s: %2$sUse more keyphrases or synonyms in your H2 and H3 subheadings%3$s!", "wordpress-seo"), this._config.urlTitle, this._config.urlCallToAction, "</a>")
};
}
}
exports.default = SubHeadingsKeywordAssessment;
//# sourceMappingURL=SubHeadingsKeywordAssessment.js.map