yoastseo-dep
Version:
Yoast clientside page analysis
191 lines (176 loc) • 6 kB
JavaScript
import { __, _n, sprintf } from "@wordpress/i18n";
import { merge } from "lodash-es";
import { inRangeStartEndInclusive } from "../../helpers/assessments/inRange";
import Assessment from "../assessment";
import { createAnchorOpeningTag } from "../../../helpers/shortlinker";
import AssessmentResult from "../../../values/AssessmentResult";
/**
* Represents the assessment that checks if the text has any images present, including videos in product pages.
*/
export default class TextImagesAssessment extends Assessment {
/**
* Sets the identifier and the config.
*
* @param {object} config The configuration to use.
* @param {boolean} countVideos Whether videos are also included in the assessment or not.
*
* @returns {void}
*/
constructor( config = {}, countVideos = false ) {
super();
const defaultConfig = {
scores: {
bad: 3,
good: 9,
},
recommendedCount: 1,
urlTitle: createAnchorOpeningTag( "https://yoa.st/4f4" ),
urlCallToAction: createAnchorOpeningTag( "https://yoa.st/4f5" ),
};
this.identifier = "images";
this._config = merge( defaultConfig, config );
this._countVideos = countVideos;
}
/**
* Execute the Assessment and return a result.
*
* @param {Paper} paper The Paper object to assess.
* @param {Researcher} researcher The Researcher object containing all available researches.
*
* @returns {AssessmentResult} The result of the assessment, containing both a score and a descriptive text.
*/
getResult( paper, researcher ) {
this.imageCount = researcher.getResearch( "imageCount" );
this.videoCount = researcher.getResearch( "videoCount" );
const calculatedScore = this.calculateResult();
const assessmentResult = new AssessmentResult();
assessmentResult.setScore( calculatedScore.score );
assessmentResult.setText( calculatedScore.resultText );
return assessmentResult;
}
/**
* Checks whether the paper has text.
*
* @param {Paper} paper The paper to use for the assessment.
*
* @returns {boolean} True when there is text.
*/
isApplicable( paper ) {
return paper.hasText();
}
/**
* Calculate the result based on the availability of images in the text, including videos in product pages.
*
* @returns {Object} The calculated result.
*/
calculateResult() {
// If "countVideos" is on, we include videos in the assessment
const mediaCount = this._countVideos ? this.imageCount + this.videoCount : this.imageCount;
// No images.
if ( mediaCount === 0 ) {
if ( this._countVideos ) {
return {
score: this._config.scores.bad,
resultText: sprintf(
/* translators: %1$s and %2$s expand to links on yoast.com, %3$s expands to the anchor end tag */
__(
"%1$sImages and videos%3$s: No images or videos appear on this page. %2$sAdd some%3$s!",
"wordpress-seo"
),
this._config.urlTitle,
this._config.urlCallToAction,
"</a>"
),
};
}
return {
score: this._config.scores.bad,
resultText: sprintf(
/* translators: %1$s and %2$s expand to links on yoast.com, %3$s expands to the anchor end tag */
__(
"%1$sImages%3$s: No images appear on this page. %2$sAdd some%3$s!",
"wordpress-seo"
),
this._config.urlTitle,
this._config.urlCallToAction,
"</a>"
),
};
}
if ( this._config.scores.okay ) {
if ( inRangeStartEndInclusive( mediaCount, 1, 3 ) && ! this._countVideos ) {
return {
score: this._config.scores.okay,
resultText: sprintf(
/* translators: %3$s and %4$s expand to links on yoast.com, %5$s expands to the anchor end tag,
* %1$d expands to the number of images found in the text,
* %2$d expands to the recommended number of images in the text, */
_n(
"%3$sImages%5$s: Only %1$d image appears on this page. We recommend at least %2$d. %4$sAdd more relevant images%5$s!",
"%3$sImages%5$s: Only %1$d images appear on this page. We recommend at least %2$d. %4$sAdd more relevant images%5$s!",
mediaCount,
"wordpress-seo"
),
mediaCount,
this._config.recommendedCount,
this._config.urlTitle,
this._config.urlCallToAction,
"</a>"
),
};
} else if ( inRangeStartEndInclusive( mediaCount, 1, 3 ) && this._countVideos ) {
return {
score: this._config.scores.okay,
resultText: sprintf(
/* translators: %3$s and %4$s expand to links on yoast.com, %5$s expands to the anchor end tag,
* %1$d expands to the number of images found in the text,
* %2$d expands to the recommended number of images in the text, */
_n(
// eslint-disable-next-line max-len
"%3$sImages and videos%5$s: Only %1$d image or video appears on this page. We recommend at least %2$d. %4$sAdd more relevant images or videos%5$s!",
// eslint-disable-next-line max-len
"%3$sImages and videos%5$s: Only %1$d images or videos appear on this page. We recommend at least %2$d. %4$sAdd more relevant images or videos%5$s!",
mediaCount,
"wordpress-seo"
),
mediaCount,
this._config.recommendedCount,
this._config.urlTitle,
this._config.urlCallToAction,
"</a>"
),
};
}
}
if ( this._countVideos ) {
// Text with at least one image or one video.
return {
score: this._config.scores.good,
resultText: sprintf(
/* translators: %1$s expands to a link on yoast.com,
* %2$s expands to the anchor end tag. */
__(
"%1$sImages and videos%2$s: Good job!",
"wordpress-seo"
),
this._config.urlTitle,
"</a>"
),
};
}
// Text with at least one image.
return {
score: this._config.scores.good,
resultText: sprintf(
/* translators: %1$s expands to a link on yoast.com,
* %2$s expands to the anchor end tag. */
__(
"%1$sImages%2$s: Good job!",
"wordpress-seo"
),
this._config.urlTitle,
"</a>"
),
};
}
}