UNPKG

yoastseo-dep

Version:

Yoast clientside page analysis

229 lines (205 loc) 7.72 kB
import { __, _n, sprintf } from "@wordpress/i18n"; import { filter, map, merge } from "lodash-es"; import { stripBlockTagsAtStartEnd as stripHTMLTags } from "../../../languageProcessing/helpers/sanitize/stripHTMLTags"; import marker from "../../../markers/addMark"; import { createAnchorOpeningTag } from "../../../helpers/shortlinker"; import { inRangeEndInclusive as inRange } from "../../helpers/assessments/inRange"; import AssessmentResult from "../../../values/AssessmentResult"; import Mark from "../../../values/Mark"; import Assessment from "../assessment"; /** * Represents the assessment that will look if the text has too long paragraphs. */ export default class ParagraphTooLongAssessment extends Assessment { /** * Sets the identifier and the config. * * @param {object} config The configuration to use. * @param {boolean} isProduct Whether product configuration should be used. * * @returns {void} */ constructor( config = {}, isProduct = false ) { super(); const defaultConfig = { urlTitle: createAnchorOpeningTag( "https://yoa.st/35d" ), urlCallToAction: createAnchorOpeningTag( "https://yoa.st/35e" ), countTextIn: __( "words", "wordpress-seo" ), parameters: { recommendedLength: 150, maximumRecommendedLength: 200, }, }; this.identifier = "textParagraphTooLong"; this._config = merge( defaultConfig, config ); this._isProduct = isProduct; } /** * Returns an array containing only the paragraphs longer than the recommended length. * * @param {array} paragraphsLength The array containing the lengths of individual paragraphs. * @param {object} config The config to use. * * @returns {array} The number of too long paragraphs. */ getTooLongParagraphs( paragraphsLength, config ) { const recommendedLength = config.parameters.recommendedLength; return filter( paragraphsLength, function( paragraph ) { return paragraph.countLength > recommendedLength; } ); } /** * 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. */ getConfig( researcher ) { const currentConfig = this._config; const languageSpecificConfig = researcher.getConfig( "paragraphLength" ); /* * If a language has a specific paragraph length config, check further if the assessment is run in product pages. * If it's run in product pages, override the default config parameters with the language specific config for product pages, * otherwise override it with the language specific config for default pages analysis. */ if ( languageSpecificConfig ) { currentConfig.parameters = this._isProduct ? languageSpecificConfig.productPageParams : languageSpecificConfig.defaultPageParams; } return currentConfig; } /** * Returns the scores and text for the ParagraphTooLongAssessment. * * @param {array} paragraphsLength The array containing the lengths of individual paragraphs. * @param {array} tooLongParagraphs The number of too long paragraphs. * @param {object} config The config to use. * * @returns {{score: number, text: string }} The assessmentResult. */ calculateResult( paragraphsLength, tooLongParagraphs, config ) { let score; if ( paragraphsLength.length === 0 ) { return {}; } const longestParagraphLength = paragraphsLength[ 0 ].countLength; if ( longestParagraphLength <= config.parameters.recommendedLength ) { // Green indicator. score = 9; } if ( inRange( longestParagraphLength, config.parameters.recommendedLength, config.parameters.maximumRecommendedLength ) ) { // Orange indicator. score = 6; } if ( longestParagraphLength > config.parameters.maximumRecommendedLength ) { // Red indicator. score = 3; } if ( score >= 7 ) { return { score: score, hasMarks: false, text: sprintf( /* translators: %1$s expands to a link on yoast.com, %2$s expands to the anchor end tag */ __( "%1$sParagraph length%2$s: None of the paragraphs are too long. Great job!", "wordpress-seo" ), config.urlTitle, "</a>" ), }; } return { score: score, hasMarks: true, text: sprintf( /* translators: %1$s and %5$s expand to a link on yoast.com, %2$s expands to the anchor end tag, %3$d expands to the number of paragraphs over the recommended word / character limit, %4$d expands to the word / character limit, %6$s expands to the word 'words' or 'characters'. */ _n( // eslint-disable-next-line max-len "%1$sParagraph length%2$s: %3$d of the paragraphs contains more than the recommended maximum of %4$d %6$s. %5$sShorten your paragraphs%2$s!", // eslint-disable-next-line max-len "%1$sParagraph length%2$s: %3$d of the paragraphs contain more than the recommended maximum of %4$d %6$s. %5$sShorten your paragraphs%2$s!", tooLongParagraphs.length, "wordpress-seo" ), config.urlTitle, "</a>", tooLongParagraphs.length, config.parameters.recommendedLength, config.urlCallToAction, this._config.countTextIn ), }; } /** * Sort the paragraphs based on word count. * * @param {Array} paragraphs The array with paragraphs. * * @returns {Array} The array sorted on word counts. */ sortParagraphs( paragraphs ) { return paragraphs.sort( function( a, b ) { return b.countLength - a.countLength; } ); } /** * Creates a marker for the paragraphs. * * @param {object} paper The paper to use for the assessment. * @param {Researcher} researcher The researcher used for calling research. * * @returns {Array} An array with marked paragraphs. */ getMarks( paper, researcher ) { const paragraphsLength = researcher.getResearch( "getParagraphLength" ); const tooLongParagraphs = this.getTooLongParagraphs( paragraphsLength, this.getConfig( researcher ) ); return map( tooLongParagraphs, function( paragraph ) { const paragraphText = stripHTMLTags( paragraph.text ); const marked = marker( paragraphText ); return new Mark( { original: paragraphText, marked: marked, } ); } ); } /** * Runs the getParagraphLength module, based on this returns an assessment result with score and text. * * @param {Paper} paper The paper to use for the assessment. * @param {Researcher} researcher The researcher used for calling research. * * @returns {object} The assessment result. */ getResult( paper, researcher ) { let paragraphsLength = researcher.getResearch( "getParagraphLength" ); const countTextInCharacters = researcher.getConfig( "countCharacters" ); if ( countTextInCharacters ) { this._config.countTextIn = __( "characters", "wordpress-seo" ); } paragraphsLength = this.sortParagraphs( paragraphsLength ); const config = this.getConfig( researcher ); const tooLongParagraphs = this.getTooLongParagraphs( paragraphsLength, config ); const paragraphLengthResult = this.calculateResult( paragraphsLength, tooLongParagraphs, config ); const assessmentResult = new AssessmentResult(); assessmentResult.setScore( paragraphLengthResult.score ); assessmentResult.setText( paragraphLengthResult.text ); assessmentResult.setHasMarks( paragraphLengthResult.hasMarks ); return assessmentResult; } /** * Checks if the paragraphTooLong assessment is applicable to the paper. * * @param {Paper} paper The paper to check. * * @returns {boolean} Returns true if the assessment is applicable to the paper. */ isApplicable( paper ) { return this.hasEnoughContentForAssessment( paper ); } }