diff --git a/admin/class-gutenberg-compatibility.php b/admin/class-gutenberg-compatibility.php index 568f73c8f1c..69f9022c3e9 100644 --- a/admin/class-gutenberg-compatibility.php +++ b/admin/class-gutenberg-compatibility.php @@ -15,14 +15,14 @@ class WPSEO_Gutenberg_Compatibility { * * @var string */ - const CURRENT_RELEASE = '16.8.0'; + const CURRENT_RELEASE = '16.8.1'; /** * The minimally supported version of Gutenberg by the plugin. * * @var string */ - const MINIMUM_SUPPORTED = '16.8.0'; + const MINIMUM_SUPPORTED = '16.8.1'; /** * Holds the current version. diff --git a/admin/tracking/class-tracking-settings-data.php b/admin/tracking/class-tracking-settings-data.php index 65375b85549..0af71efed1a 100644 --- a/admin/tracking/class-tracking-settings-data.php +++ b/admin/tracking/class-tracking-settings-data.php @@ -231,6 +231,9 @@ class WPSEO_Tracking_Settings_Data implements WPSEO_Collection { 'deny_search_crawling', 'deny_wp_json_crawling', 'deny_adsbot_crawling', + 'deny_ccbot_crawling', + 'deny_google_extended_crawling', + 'deny_gptbot_crawling', 'last_known_no_unindexed', ]; diff --git a/apps/content-analysis/src/analysis.worker.js b/apps/content-analysis/src/analysis.worker.js index 9e47240a739..89a5f51f8d7 100644 --- a/apps/content-analysis/src/analysis.worker.js +++ b/apps/content-analysis/src/analysis.worker.js @@ -24,6 +24,7 @@ import CollectionCornerstoneSEOAssessor from "yoastseo/src/scoring/collectionPag import CollectionRelatedKeywordAssessor from "yoastseo/src/scoring/collectionPages/relatedKeywordAssessor"; import CollectionCornerstoneRelatedKeywordAssessor from "yoastseo/src/scoring/collectionPages/cornerstone/relatedKeywordAssessor"; +import registerPremiumAssessments from "./utils/registerPremiumAssessments"; self.onmessage = ( event ) => { const language = event.data.language; @@ -36,6 +37,8 @@ self.onmessage = ( event ) => { const worker = new AnalysisWebWorker( self, new Researcher() ); + registerPremiumAssessments( worker, language ); + // Set custom assessors. // Store product pages. worker.setCustomSEOAssessorClass( productSEOAssessor, "productPage", { introductionKeyphraseUrlTitle: "https://yoa.st/shopify8", diff --git a/apps/content-analysis/src/utils/registerPremiumAssessments.js b/apps/content-analysis/src/utils/registerPremiumAssessments.js new file mode 100644 index 00000000000..a639f7ec014 --- /dev/null +++ b/apps/content-analysis/src/utils/registerPremiumAssessments.js @@ -0,0 +1,71 @@ +import { getLanguagesWithWordComplexity } from "yoastseo/src/helpers/getLanguagesWithWordComplexity"; + +// Configs for the supported languages. +import wordComplexityConfigEnglish from "yoastseo/src/languageProcessing/languages/en/config/wordComplexity"; +import wordComplexityConfigGerman from "yoastseo/src/languageProcessing/languages/de/config/wordComplexity"; +import wordComplexityConfigSpanish from "yoastseo/src/languageProcessing/languages/es/config/wordComplexity"; +import wordComplexityConfigFrench from "yoastseo/src/languageProcessing/languages/fr/config/wordComplexity"; + +// Helpers for the supported languages. +import wordComplexityHelperEnglish from "yoastseo/src/languageProcessing/languages/en/helpers/checkIfWordIsComplex"; +import wordComplexityHelperGerman from "yoastseo/src/languageProcessing/languages/de/helpers/checkIfWordIsComplex"; +import wordComplexityHelperSpanish from "yoastseo/src/languageProcessing/languages/es/helpers/checkIfWordIsComplex"; +import wordComplexityHelperFrench from "yoastseo/src/languageProcessing/languages/fr/helpers/checkIfWordIsComplex"; +// Research. +import wordComplexity from "yoastseo/src/languageProcessing/researches/wordComplexity"; +import keyPhraseDistribution from "yoastseo/src/languageProcessing/researches/keyphraseDistribution"; + +// Assessment. +import WordComplexityAssessment from "yoastseo/src/scoring/assessments/readability/WordComplexityAssessment"; +import KeyphraseDistributionAssessment from "yoastseo/src/scoring/assessments/seo/KeyphraseDistributionAssessment"; + +const helpers = { + de: wordComplexityHelperGerman, + en: wordComplexityHelperEnglish, + es: wordComplexityHelperSpanish, + fr: wordComplexityHelperFrench, +}; + +const configs = { + de: wordComplexityConfigGerman, + en: wordComplexityConfigEnglish, + es: wordComplexityConfigSpanish, + fr: wordComplexityConfigFrench, +}; + +const pluginName = "YoastSEOPremium"; + +export default function( worker, language ) { + if ( getLanguagesWithWordComplexity().includes( language ) ) { + // Get the word complexity config for the specific language. + const wordComplexityConfig = configs[ language ]; + // Get the word complexity helper for the specific language. + const wordComplexityHelper = helpers[ language ]; + // Initialize the assessment for regular content. + const wordComplexityAssessment = new WordComplexityAssessment(); + // Initialize the assessment for cornerstone content. + const wordComplexityAssessmentCornerstone = new WordComplexityAssessment( { + scores: { + acceptableAmount: 3, + }, + } ); + + // Register the word complexity config. + worker.registerResearcherConfig( "wordComplexity", wordComplexityConfig ); + + // Register the word complexity helper. + worker.registerHelper( "checkIfWordIsComplex", wordComplexityHelper ); + + // Register the word complexity research. + worker.registerResearch( "wordComplexity", wordComplexity ); + + // Register the word complexity assessment for regular content. + worker.registerAssessment( "wordComplexity", wordComplexityAssessment, pluginName, "readability" ); + + // Register the word complexity assessment for cornerstone content. + worker.registerAssessment( "wordComplexity", wordComplexityAssessmentCornerstone, pluginName, "cornerstoneReadability" ); + } + const keyphraseDistributionAssessment = new KeyphraseDistributionAssessment(); + worker.registerResearch( "keyphraseDistribution", keyPhraseDistribution ); + worker.registerAssessment( "keyphraseDistributionAssessment", keyphraseDistributionAssessment, pluginName, "seo" ); +} diff --git a/css/src/icons.css b/css/src/icons.css index b31d3288b08..6c1117aa666 100644 --- a/css/src/icons.css +++ b/css/src/icons.css @@ -1,6 +1,6 @@ :root { --yoast-svg-icon-info: url('data:image/svg+xml,'); - --yoast-svg-icon-check: url('data:image/svg+xml,'); + --yoast-svg-icon-check: url('data:image/svg+xml,'); --yoast-svg-icon-check-ok: url('data:image/svg+xml,'); --yoast-svg-icon-caret-right: url('data:image/svg+xml,'); --yoast-svg-icon-caret-left: url('data:image/svg+xml,'); diff --git a/css/src/modal.css b/css/src/modal.css index 21ff2ffc37e..e3484058d3e 100644 --- a/css/src/modal.css +++ b/css/src/modal.css @@ -59,6 +59,19 @@ right: 16px; } +.yoast-gutenberg-modal__box.components-modal__frame { + box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); + + @media (min-width: 600px) { + border-radius: 8px; + max-height: calc( 100% - 48px ); + } +} + +.yoast-gutenberg-modal__no-padding .components-modal__content { + padding: 0; +} + .yoast-modal__heading h1, .yoast-gutenberg-modal .components-modal__header-heading { font-size: 20px; @@ -68,6 +81,10 @@ margin: 0; } +.yoast-gutenberg-modal .components-modal__content .components-modal__header { + border-bottom: 1px solid #e2e8f0 !important; +} + .yoast-gutenberg-modal .components-modal__icon-container { display: inline-flex; } diff --git a/inc/options/class-wpseo-option-wpseo.php b/inc/options/class-wpseo-option-wpseo.php index 21c81483892..56f9708f6d0 100644 --- a/inc/options/class-wpseo-option-wpseo.php +++ b/inc/options/class-wpseo-option-wpseo.php @@ -127,6 +127,9 @@ class WPSEO_Option_Wpseo extends WPSEO_Option { 'deny_search_crawling' => false, 'deny_wp_json_crawling' => false, 'deny_adsbot_crawling' => false, + 'deny_ccbot_crawling' => false, + 'deny_google_extended_crawling' => false, + 'deny_gptbot_crawling' => false, 'redirect_search_pretty_urls' => false, 'least_readability_ignore_list' => [], 'least_seo_score_ignore_list' => [], @@ -511,6 +514,9 @@ protected function validate_option( $dirty, $clean, $old ) { * 'search_cleanup_patterns' * 'deny_wp_json_crawling' * 'deny_adsbot_crawling' + * 'deny_ccbot_crawling' + * 'deny_google_extended_crawling' + * 'deny_gptbot_crawling' * 'redirect_search_pretty_urls' * 'should_redirect_after_install_free' * 'show_new_content_type_notification' diff --git a/inc/options/class-wpseo-option.php b/inc/options/class-wpseo-option.php index d0fe27e870e..98d2ee8b356 100644 --- a/inc/options/class-wpseo-option.php +++ b/inc/options/class-wpseo-option.php @@ -6,7 +6,7 @@ */ /** - * This abstract class and it's concrete classes implement defaults and value validation for + * This abstract class and its concrete classes implement defaults and value validation for * all WPSEO options and subkeys within options. * * Some guidelines: @@ -22,9 +22,9 @@ * * [Updating/Adding options] * - For multisite site_options, please use the WPSEO_Options::update_site_option() method. - * - For normal options, use the normal add/update_option() functions. As long a the classes here + * - For normal options, use the normal add/update_option() functions. As long as the classes here * are instantiated, validation for all options and their subkeys will be automatic. - * - On (succesfull) update of a couple of options, certain related actions will be run automatically. + * - On (successful) update of a couple of options, certain related actions will be run automatically. * Some examples: * - on change of wpseo[yoast_tracking], the cron schedule will be adjusted accordingly * - on change of wpseo and wpseo_title, some caches will be cleared @@ -41,7 +41,7 @@ * translate_defaults() method. * - When you remove an array key from an option: if it's important that the option is really removed, * add the WPSEO_Option::clean_up( $option_name ) method to the upgrade run. - * This will re-save the option and automatically remove the array key no longer in existance. + * This will re-save the option and automatically remove the array key no longer in existence. * - When you rename a sub-option: add it to the clean_option() routine and run that in the upgrade run. * - When you change the default for an option sub-key, make sure you verify that the validation routine will * still work the way it should. @@ -74,8 +74,8 @@ abstract class WPSEO_Option { * Option group name for use in settings forms. * * Will be set automagically if not set in concrete class (i.e. - * if it confirm to the normal pattern 'yoast' . $option_name . 'options', - * only set in conrete class if it doesn't). + * if it conforms to the normal pattern 'yoast' . $option_name . 'options', + * only set in concrete class if it doesn't). * * @var string */ @@ -107,7 +107,7 @@ abstract class WPSEO_Option { protected $defaults; /** - * Array of variable option name patterns for the option - if any -. + * Array of variable option name patterns for the option - if any. * * Set this when the option contains array keys which vary based on post_type * or taxonomy. @@ -230,7 +230,7 @@ protected function __construct() { * ``` * --------------- * - * Concrete classes *may* contain a enrich_defaults method to add additional defaults once + * Concrete classes *may* contain an enrich_defaults method to add additional defaults once * all post_types and taxonomies have been registered. * * ``` @@ -497,7 +497,7 @@ public function get_option( $options = null ) { return $filtered; } - /* *********** METHODS influencing add_uption(), update_option() and saving from admin pages. *********** */ + /* *********** METHODS influencing add_option(), update_option() and saving from admin pages. *********** */ /** * Register (whitelist) the option for the configuration pages. @@ -523,7 +523,7 @@ public function register_setting() { } /** - * Validate the option + * Validate the option. * * @param mixed $option_value The unvalidated new value for the option. * @@ -645,7 +645,7 @@ public function maybe_add_option() { * * @param mixed $value The new value for the option. * - * @return bool Whether the update was succesfull. + * @return bool Whether the update was successful. */ public function update_site_option( $value ) { if ( $this->multisite_only === true && is_multisite() ) { @@ -667,7 +667,7 @@ public function update_site_option( $value ) { * @uses WPSEO_Option::import() * * @param string|null $current_version Optional. Version from which to upgrade, if not set, - * version specific upgrades will be disregarded. + * version-specific upgrades will be disregarded. * * @return void */ @@ -692,7 +692,7 @@ public function clean( $current_version = null ) { * * @param array $option_value Option value to be imported. * @param string|null $current_version Optional. Version from which to upgrade, if not set, - * version specific upgrades will be disregarded. + * version-specific upgrades will be disregarded. * @param array|null $all_old_option_values Optional. Only used when importing old options to * have access to the real old values, in contrast to * the saved ones. diff --git a/inc/sitemaps/class-taxonomy-sitemap-provider.php b/inc/sitemaps/class-taxonomy-sitemap-provider.php index c8980015e2f..02ebbb5ff9d 100644 --- a/inc/sitemaps/class-taxonomy-sitemap-provider.php +++ b/inc/sitemaps/class-taxonomy-sitemap-provider.php @@ -287,7 +287,7 @@ public function is_valid_taxonomy( $taxonomy_name ) { return false; } - if ( in_array( $taxonomy_name, [ 'link_category', 'nav_menu' ], true ) ) { + if ( in_array( $taxonomy_name, [ 'link_category', 'nav_menu', 'wp_pattern_category' ], true ) ) { return false; } diff --git a/package.json b/package.json index 995404ee9bb..dc7ac67627f 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "typescript": "^4.2.4" }, "yoast": { - "pluginVersion": "21.4" + "pluginVersion": "21.5" }, "version": "0.0.0" } diff --git a/packages/components/src/base/icons.css b/packages/components/src/base/icons.css index e56d6f19657..af4919cf834 100644 --- a/packages/components/src/base/icons.css +++ b/packages/components/src/base/icons.css @@ -4,7 +4,7 @@ --yoast-checkmark--white : url('data:image/svg+xml,'); --yoast-checkmark--green : url('data:image/svg+xml,'); --yoast-svg-icon-info: url('data:image/svg+xml,'); - --yoast-svg-icon-check: url('data:image/svg+xml,'); + --yoast-svg-icon-check: url('data:image/svg+xml,'); --yoast-svg-icon-check-ok: url('data:image/svg+xml,'); --yoast-svg-icon-caret-right: url('data:image/svg+xml,'); --yoast-svg-icon-caret-left: url('data:image/svg+xml,'); diff --git a/packages/js/package.json b/packages/js/package.json index 9c16ae0bd6b..ea70d872a91 100644 --- a/packages/js/package.json +++ b/packages/js/package.json @@ -5,7 +5,7 @@ "private": true, "scripts": { "test": "jest -u", - "lint": "eslint src tests --max-warnings=75" + "lint": "eslint src tests --max-warnings=74" }, "dependencies": { "@draft-js-plugins/mention": "^5.0.0", diff --git a/packages/js/src/analysis/collectAnalysisData.js b/packages/js/src/analysis/collectAnalysisData.js index d1254581381..d9d38b0860c 100644 --- a/packages/js/src/analysis/collectAnalysisData.js +++ b/packages/js/src/analysis/collectAnalysisData.js @@ -10,6 +10,7 @@ import getWritingDirection from "./getWritingDirection"; import { Paper } from "yoastseo"; +/* eslint-disable complexity */ /** * Retrieves the data needed for the analyses. diff --git a/packages/js/src/components/UpsellBox.js b/packages/js/src/components/UpsellBox.js index 2c4ebb2a7e6..6fc8bd6e47a 100644 --- a/packages/js/src/components/UpsellBox.js +++ b/packages/js/src/components/UpsellBox.js @@ -1,37 +1,66 @@ /* External dependencies */ -import { Component } from "@wordpress/element"; -import interpolateComponents from "interpolate-components"; +import { select } from "@wordpress/data"; +import { Component, Fragment, createInterpolateElement } from "@wordpress/element"; +import { makeOutboundLink } from "@yoast/helpers"; import PropTypes from "prop-types"; import styled from "styled-components"; -import { makeOutboundLink } from "@yoast/helpers"; +import { __ } from "@wordpress/i18n"; + +const Container = styled.div` + padding: 25px 32px 32px; + color: #303030; +`; const StyledList = styled.ul` - list-style: none; - margin: 0 0 24px; - padding: 0; + margin: 0; + padding: 0; - li { - margin: 10px 0 0 0; - } + li { + list-style-image: var(--yoast-svg-icon-check); + margin: 0.5rem 0 0 1.5rem; + line-height: 1.4em; - span[aria-hidden="true"]:before { - content: ""; - display: inline-block; - height: 13px; - width: 13px; - background-size: 13px 13px; - background-image: var( --yoast-svg-icon-check ); - background-repeat: no-repeat; - margin-right: 10px; - } + &::marker { + font-size: 1.5rem; + } + } +`; + +const ButtonLabel = styled.span` + display: block; + margin-top: 4px; +`; + +const Heading = styled.h2` + margin-top: 0; + margin-bottom: 0.25rem; + color: #303030; + font-size: 0.8125rem; + font-weight: 600; +`; + +const Description = styled.p` + display: block; + margin: 0.25rem 0 1rem 0 !important; + max-width: 420px; `; -const ButtonLabel = styled.small` - display: block; - margin-top: 4px; +const Divider = styled.hr` + margin-top: 1.5rem; + margin-bottom: 1rem; + border-top: 0; + border-bottom: 1px solid #E2E8F0; `; -const UpsellButton = makeOutboundLink(); +const ButtonContainer = styled.div` + text-align: center; +`; + +const Anchor = styled.a` + width: 100%; +`; + +const UpsellButton = makeOutboundLink( Anchor ); /** * Returns the UpsellBox component. @@ -48,6 +77,9 @@ class UpsellBox extends Component { */ constructor( props ) { super( props ); + this.state = { + defaultPrice: "99", + }; } /** @@ -62,60 +94,69 @@ class UpsellBox extends Component { benefits.length > 0 && { benefits.map( ( benefit, index ) => { - return
  • -
  • + { createInterpolateElement( + benefit.replace( "", "{{strong}}" ).replace( "", "{{/strong}}" ), + { strong: } + ) }
  • ; } ) }
    ); } - /** - * Creates the HTML for the info paragraphs. - * - * @param {array} paragraphs The paragraphs to be rendered. - * - * @returns {*} The HTML for the info paragraphs. - */ - createInfoParagraphs( paragraphs ) { - return ( - paragraphs.map( ( paragraph, index ) => { - return

    { paragraph }

    ; - } ) - ); - } - /** * Renders a UpsellBox component. * * @returns {wp.Element} The rendered UpsellBox component. */ render() { + const isBlackFriday = select( "yoast-seo/editor" ).isPromotionActive( "black-friday-2023-promotion" ); + const { defaultPrice } = this.state; + const newPrice = isBlackFriday ? "69.30" : null; + const price = newPrice ? newPrice : defaultPrice; return ( -
    - { this.createInfoParagraphs( this.props.infoParagraphs ) } - { this.createBenefitsList( this.props.benefits ) } - - { this.props.upsellButtonText } - { this.props.upsellButtonHasCaret && - - { this.props.upsellButtonLabel } - -
    + + { isBlackFriday && +
    +
    { __( "BLACK FRIDAY", "wordpress-seo" ) }
    +
    { __( "30% OFF", "wordpress-seo" ) }
    +
    } + + { this.props.title } + { this.props.description } + + + { this.props.upsellButtonText } + { this.props.upsellButtonHasCaret && +
    + { newPrice && <> + { defaultPrice } +   + } + { price } { __( "$ USD / € EUR / £ GBP per year (ex. VAT)", "wordpress-seo" ) } +
    + + { this.props.upsellButtonLabel } + +
    + + { this.props.benefitsTitle } + { this.createBenefitsList( this.props.benefits ) } +
    +
    ); } } UpsellBox.propTypes = { + title: PropTypes.node, benefits: PropTypes.array, - infoParagraphs: PropTypes.array, + benefitsTitle: PropTypes.node, + description: PropTypes.node, upsellButton: PropTypes.object, upsellButtonText: PropTypes.string.isRequired, upsellButtonLabel: PropTypes.string, @@ -123,8 +164,10 @@ UpsellBox.propTypes = { }; UpsellBox.defaultProps = { - infoParagraphs: [], + title: null, + description: null, benefits: [], + benefitsTitle: null, upsellButton: { href: "", className: "button button-primary", diff --git a/packages/js/src/components/contentAnalysis/SeoAnalysis.js b/packages/js/src/components/contentAnalysis/SeoAnalysis.js index 21961bd48eb..3fdd17080c2 100644 --- a/packages/js/src/components/contentAnalysis/SeoAnalysis.js +++ b/packages/js/src/components/contentAnalysis/SeoAnalysis.js @@ -11,8 +11,9 @@ import getL10nObject from "../../analysis/getL10nObject"; import Results from "../../containers/Results"; import AnalysisUpsell from "../AnalysisUpsell"; import MetaboxCollapsible from "../MetaboxCollapsible"; -import { ModalContainer } from "../modals/Container"; +import { ModalSmallContainer } from "../modals/Container"; import KeywordSynonyms from "../modals/KeywordSynonyms"; +import { defaultModalClassName } from "../modals/Modal"; import MultipleKeywords from "../modals/MultipleKeywords"; import Modal from "../modals/SeoAnalysisModal"; import ScoreIconPortal from "../portals/ScoreIconPortal"; @@ -41,6 +42,7 @@ class SeoAnalysis extends Component { */ renderSynonymsUpsell( location, locationContext ) { const modalProps = { + className: `${ defaultModalClassName } yoast-gutenberg-modal__box yoast-gutenberg-modal__no-padding`, classes: { openButton: "wpseo-keyword-synonyms button-link", }, @@ -59,10 +61,9 @@ class SeoAnalysis extends Component { return ( - -

    { __( "Write more natural and engaging content", "wordpress-seo" ) }

    + -
    +
    ); } @@ -77,6 +78,7 @@ class SeoAnalysis extends Component { */ renderMultipleKeywordsUpsell( location, locationContext ) { const modalProps = { + className: `${ defaultModalClassName } yoast-gutenberg-modal__box yoast-gutenberg-modal__no-padding`, classes: { openButton: "wpseo-multiple-keywords button-link", }, @@ -95,10 +97,9 @@ class SeoAnalysis extends Component { return ( - -

    { __( "Reach a wider audience", "wordpress-seo" ) }

    + -
    +
    ); } diff --git a/packages/js/src/components/modals/Container.js b/packages/js/src/components/modals/Container.js index a0eadb3a86a..c9425bbf2b9 100644 --- a/packages/js/src/components/modals/Container.js +++ b/packages/js/src/components/modals/Container.js @@ -12,6 +12,12 @@ export const ModalContainer = styled.div` } `; +export const ModalSmallContainer = styled.div` + @media screen and ( min-width: 600px ) { + max-width: 420px; + } +`; + export const ModalIcon = styled( Icon )` float: ${ getRtlStyle( "right", "left" ) }; margin: ${ getRtlStyle( "0 0 16px 16px", "0 16px 16px 0" ) }; diff --git a/packages/js/src/components/modals/InternalLinkingSuggestionsUpsell.js b/packages/js/src/components/modals/InternalLinkingSuggestionsUpsell.js index 5976049555f..01d583ee475 100644 --- a/packages/js/src/components/modals/InternalLinkingSuggestionsUpsell.js +++ b/packages/js/src/components/modals/InternalLinkingSuggestionsUpsell.js @@ -7,7 +7,7 @@ import { Badge, useSvgAria, useToggleState } from "@yoast/ui-library"; import { MetaboxButton } from "../MetaboxButton"; import SidebarButton from "../SidebarButton"; import UpsellBox from "../UpsellBox"; -import { ModalContainer } from "./Container"; +import { ModalSmallContainer } from "./Container"; import Modal, { defaultModalClassName } from "./Modal"; /** @@ -34,27 +34,18 @@ export const InternalLinkingSuggestionsUpsell = () => { onRequestClose={ closeModal } additionalClassName="" id="yoast-internal-linking-suggestions-upsell" - className={ defaultModalClassName } + className={ `${ defaultModalClassName } yoast-gutenberg-modal__box yoast-gutenberg-modal__no-padding` } shouldCloseOnClickOutside={ true } > - -

    { __( "Rank higher by connecting your content", "wordpress-seo" ) }

    + - { sprintf( - /* translators: %s expands to Yoast SEO Premium. */ - __( "%s automatically suggests to what content you can link with easy drag-and-drop functionality, which is good for your SEO!", "wordpress-seo" ), - "Yoast SEO Premium" - ) } - , - - { __( "What’s more in Yoast SEO Premium?", "wordpress-seo" ) } - , - ] } + title={ __( "Rank higher by connecting your content", "wordpress-seo" ) } + description={ sprintf( + /* translators: %s expands to Yoast SEO Premium. */ + __( "%s automatically suggests to what content you can link with easy drag-and-drop functionality, which is good for your SEO!", "wordpress-seo" ), + "Yoast SEO Premium" + ) } + benefitsTitle={ __( "What’s more in Yoast SEO Premium?", "wordpress-seo" ) } benefits={ [ __( "Create content faster: Use AI to create titles & meta descriptions", "wordpress-seo" ), __( "Get extra SEO checks with the Premium SEO analysis", "wordpress-seo" ), @@ -79,7 +70,7 @@ export const InternalLinkingSuggestionsUpsell = () => { } } upsellButtonLabel={ __( "1 year free support and updates included!", "wordpress-seo" ) } /> -
    + ) } { isSidebar && ( diff --git a/packages/js/src/components/modals/KeywordSynonyms.js b/packages/js/src/components/modals/KeywordSynonyms.js index fc3d1754f56..1a38cee6f4c 100644 --- a/packages/js/src/components/modals/KeywordSynonyms.js +++ b/packages/js/src/components/modals/KeywordSynonyms.js @@ -10,18 +10,6 @@ import UpsellBox from "../UpsellBox"; * @returns {wp.Element} The Keyword Synonyms upsell component. */ const KeywordSynonyms = ( props ) => { - const infoParagraphs = [ - - { sprintf( - /* translators: %s expands to "Yoast SEO Premium" */ - __( "Synonyms help users understand your copy better. It’s easier to read for both users and Google. In %s, you can add synonyms for your focus keyphrase, and we’ll help you optimize for them.", "wordpress-seo" ), - "Yoast SEO Premium" - ) } - , - - { __( "What’s more in Yoast SEO Premium?", "wordpress-seo" ) } - , - ]; const benefits = [ __( "Create content faster: Use AI to create titles & meta descriptions", "wordpress-seo" ), __( "Get extra SEO checks with the Premium SEO analysis", "wordpress-seo" ), @@ -33,7 +21,13 @@ const KeywordSynonyms = ( props ) => { return ( { onRequestClose={ closeModal } additionalClassName="" id="yoast-additional-keyphrases-modal" - className={ defaultModalClassName } + className={ `${ defaultModalClassName } yoast-gutenberg-modal__box yoast-gutenberg-modal__no-padding` } shouldCloseOnClickOutside={ true } > - -

    { __( "Reach a wider audience", "wordpress-seo" ) }

    + -
    + ) } { location === "sidebar" && ( diff --git a/packages/js/src/components/modals/MultipleKeywords.js b/packages/js/src/components/modals/MultipleKeywords.js index 4c5ca7dac43..d2502fc1600 100644 --- a/packages/js/src/components/modals/MultipleKeywords.js +++ b/packages/js/src/components/modals/MultipleKeywords.js @@ -10,14 +10,6 @@ import UpsellBox from "../UpsellBox"; * @returns {JSX.Element} The Multiple Keywords upsell component. */ const MultipleKeywords = ( props ) => { - const infoParagraphs = [ - - { __( "Get help optimizing for up to 5 related keyphrases. This helps you reach a wider audience and get more traffic.", "wordpress-seo" ) } - , - - { __( "What’s more in Yoast SEO Premium?", "wordpress-seo" ) } - , - ]; const benefits = [ __( "Create content faster: Use AI to create titles & meta descriptions", "wordpress-seo" ), __( "Get extra SEO checks with the Premium SEO analysis", "wordpress-seo" ), @@ -29,7 +21,9 @@ const MultipleKeywords = ( props ) => { return ( { return ( { isOpen && - -

    { __( "Improve your SEO by using the Premium SEO analysis", "wordpress-seo" ) }

    + -
    +
    } { location === "sidebar" && ( { - const infoParagraphs = [ - - { __( "Check your text on more SEO criteria and get an enhanced keyphrase analysis, making it easier to write optimized content.", "wordpress-seo" ) } - , - - { __( "What’s more in Yoast SEO Premium?", "wordpress-seo" ) } - , - ]; const benefits = [ __( "Create content faster: Use AI to create titles & meta descriptions", "wordpress-seo" ), __( "Get help ranking for multiple keyphrases", "wordpress-seo" ), @@ -35,7 +27,9 @@ const PremiumSEOAnalysisUpsell = ( props ) => { return ( { renderPreview() } @@ -79,6 +80,7 @@ export default function ImageSelect( { id={ url ? id + "__replace-image" : id + "__select-image" } className="yst-button yst-button yst-button--secondary yst-mr-2" onClick={ onSelectImageClick } + data-hiive-event-name={ url ? "clicked_replace_image" : "clicked_select_image" } > { url ? __( "Replace image", "wordpress-seo" ) : __( "Select image", "wordpress-seo" ) } @@ -88,6 +90,7 @@ export default function ImageSelect( { id={ id + "__remove-image" } className="yst-button--remove" onClick={ onRemoveImageClick } + data-hiive-event-name="clicked_remove_image" > { __( "Remove image", "wordpress-seo" ) } diff --git a/packages/js/src/first-time-configuration/tailwind-components/configuration-stepper-buttons.js b/packages/js/src/first-time-configuration/tailwind-components/configuration-stepper-buttons.js index 91b0d3e0dad..e61b427aeda 100644 --- a/packages/js/src/first-time-configuration/tailwind-components/configuration-stepper-buttons.js +++ b/packages/js/src/first-time-configuration/tailwind-components/configuration-stepper-buttons.js @@ -4,6 +4,7 @@ import PropTypes from "prop-types"; import { Step } from "./stepper"; import { stepperTimingClasses } from "../stepper-helper"; import classNames from "classnames"; +import { HIIVE_STEPS_NAMES } from "../constants"; /** * A ContinueButton that always goes to the next step. @@ -13,11 +14,13 @@ import classNames from "classnames"; * * @returns {WPElement} The ContinueButton, that always goes to the next step. */ -export function ContinueButton( { beforeGo, children, additionalClasses, ...restProps } ) { +export function ContinueButton( { stepId, beforeGo, children, additionalClasses, ...restProps } ) { return ( { children } @@ -25,6 +28,7 @@ export function ContinueButton( { beforeGo, children, additionalClasses, ...rest } ContinueButton.propTypes = { + stepId: PropTypes.string.isRequired, additionalClasses: PropTypes.string, beforeGo: PropTypes.func, children: PropTypes.node, @@ -44,13 +48,14 @@ ContinueButton.defaultProps = { * * @returns {WPElement} The EditButton, that always goes to the step it is placed in. */ -export function EditButton( { beforeGo, isVisible, children, additionalClasses, ...restProps } ) { +export function EditButton( { stepId, beforeGo, isVisible, children, additionalClasses, ...restProps } ) { const transitionClasses = `yst-transition-opacity ${stepperTimingClasses.slideDuration} yst-ease-out ${ isVisible ? "yst-opacity-100" : `${stepperTimingClasses.delayBeforeOpening} yst-opacity-0 yst-pointer-events-none yst-hidden` }`; return ( { children } @@ -65,6 +71,7 @@ export function EditButton( { beforeGo, isVisible, children, additionalClasses, } EditButton.propTypes = { + stepId: PropTypes.string.isRequired, additionalClasses: PropTypes.string, isVisible: PropTypes.bool, beforeGo: PropTypes.func, @@ -86,11 +93,13 @@ EditButton.defaultProps = { * * @returns {WPElement} The BackButton, that always goes to the previous step. */ -export function BackButton( { beforeGo, children, additionalClasses, ...restProps } ) { +export function BackButton( { stepId, beforeGo, children, additionalClasses, ...restProps } ) { return ( { children } @@ -98,6 +107,7 @@ export function BackButton( { beforeGo, children, additionalClasses, ...restProp } BackButton.propTypes = { + stepId: PropTypes.string.isRequired, additionalClasses: PropTypes.string, beforeGo: PropTypes.func, children: PropTypes.node, @@ -123,8 +133,19 @@ BackButton.defaultProps = { */ export function StepButtons( { stepId, beforeContinue, continueLabel, beforeBack, backLabel } ) { return
    - { continueLabel } - { backLabel } + + { continueLabel } + + + { backLabel } +
    ; } @@ -162,10 +183,16 @@ export function ConfigurationStepButtons( { stepId, stepperFinishedOnce, saveFun // If save is not succesful: we are still editing setEditState( ! saveSuccesful ); return saveSuccesful; - } ); + }, [ saveFunction ] ); if ( stepperFinishedOnce ) { - return + return { __( "Save changes", "wordpress-seo" ) } ; } diff --git a/packages/js/src/first-time-configuration/tailwind-components/steps/finish/finish-step.js b/packages/js/src/first-time-configuration/tailwind-components/steps/finish/finish-step.js index ba305a1b1f7..427cd5e3cc6 100644 --- a/packages/js/src/first-time-configuration/tailwind-components/steps/finish/finish-step.js +++ b/packages/js/src/first-time-configuration/tailwind-components/steps/finish/finish-step.js @@ -39,6 +39,7 @@ export default function FinishStep() { id="button-webinar-seo-dashboard" href={ webinarIntroFirstTimeConfigUrl } target="_blank" + data-hiive-event-name="clicked_to_onboarding_page" > { sprintf( /* translators: 1: Yoast SEO. */ @@ -51,6 +52,7 @@ export default function FinishStep() { { __( "Or go to your SEO dashboard", "wordpress-seo" ) } diff --git a/packages/js/src/first-time-configuration/tailwind-components/steps/indexation/indexation.js b/packages/js/src/first-time-configuration/tailwind-components/steps/indexation/indexation.js index bf5bcbb3792..f46b3065af8 100644 --- a/packages/js/src/first-time-configuration/tailwind-components/steps/indexation/indexation.js +++ b/packages/js/src/first-time-configuration/tailwind-components/steps/indexation/indexation.js @@ -284,6 +284,7 @@ class Indexation extends Component { className="yst-button yst-button--secondary" onClick={ this.startIndexing } id="indexation-data-optimization" + data-hiive-event-name="clicked_start_data_optimization" > { __( "Start SEO data optimization", "wordpress-seo" ) } ; diff --git a/packages/js/src/first-time-configuration/tailwind-components/steps/personal-preferences/newsletter-signup.js b/packages/js/src/first-time-configuration/tailwind-components/steps/personal-preferences/newsletter-signup.js index b81f2e1f7bf..9c9cec28e7d 100644 --- a/packages/js/src/first-time-configuration/tailwind-components/steps/personal-preferences/newsletter-signup.js +++ b/packages/js/src/first-time-configuration/tailwind-components/steps/personal-preferences/newsletter-signup.js @@ -123,6 +123,7 @@ export function NewsletterSignup( { gdprLink } ) { className="yst-button yst-button--primary yst-h-[45px] yst-items-center yst-mt-[27.5px] yst-shrink-0" onClick={ onSignUpClick } disabled={ signUpState === "loading" } + data-hiive-event-name="clicked_signup | personal preferences" > { __( "Sign up!", "wordpress-seo" ) } diff --git a/packages/js/src/first-time-configuration/tailwind-components/steps/social-profiles/social-field-array.js b/packages/js/src/first-time-configuration/tailwind-components/steps/social-profiles/social-field-array.js index 8cacdc3e913..a7b0a0b8bb7 100644 --- a/packages/js/src/first-time-configuration/tailwind-components/steps/social-profiles/social-field-array.js +++ b/packages/js/src/first-time-configuration/tailwind-components/steps/social-profiles/social-field-array.js @@ -66,6 +66,7 @@ const SocialFieldArray = ( { items, onAddProfile, onRemoveProfile, onChangeProfi id="add-profile" className="yst-button yst-button--secondary yst-items-center yst-mt-8" onClick={ onAddProfile } + data-hiive-event-name="clicked_add_profile" > { addButtonChildren } diff --git a/packages/js/src/first-time-configuration/tailwind-components/steps/social-profiles/social-profiles-step.js b/packages/js/src/first-time-configuration/tailwind-components/steps/social-profiles/social-profiles-step.js index ddea8a067e3..fab3090fb67 100644 --- a/packages/js/src/first-time-configuration/tailwind-components/steps/social-profiles/social-profiles-step.js +++ b/packages/js/src/first-time-configuration/tailwind-components/steps/social-profiles/social-profiles-step.js @@ -44,11 +44,12 @@ export default function SocialProfilesStep( { state, dispatch, setErrorFields } "" ), - { // eslint-disable-next-line jsx-a11y/anchor-has-content + { // eslint-disable-next-line jsx-a11y/anchor-has-content a: , } ); diff --git a/packages/js/src/installation-success.js b/packages/js/src/installation-success.js index e03dae47db8..5d01b6c1322 100644 --- a/packages/js/src/installation-success.js +++ b/packages/js/src/installation-success.js @@ -98,6 +98,7 @@ function InstallationSuccessPage() { id="installation-successful-configuration-link" href={ window.wpseoInstallationSuccess.firstTimeConfigurationUrl } className="yst-inline-flex yst-items-center yst-w-full yst-justify-center yst-no-underline yst-px-6 yst-py-3 yst-border yst-border-transparent yst-text-base yst-font-medium yst-rounded-md yst-shadow-none yst-text-primary-500 yst-bg-white hover:yst-bg-gray-50 focus:yst-outline-none focus:yst-ring-2 focus:yst-ring-offset-2 focus:yst-ring-white yst-ring-offset-2 yst-ring-offset-primary-500" + data-hiive-event-name="clicked_start_first_time_configuration" > { __( "Start first-time configuration!", "wordpress-seo" ) } - + { /* translators: %s expands to ' »'. */ sprintf( __( "Skip%s", "wordpress-seo" ), " »" ) diff --git a/packages/js/src/integrations-page/acf-integration.js b/packages/js/src/integrations-page/acf-integration.js index 662662cabea..73f57ba166c 100644 --- a/packages/js/src/integrations-page/acf-integration.js +++ b/packages/js/src/integrations-page/acf-integration.js @@ -121,7 +121,7 @@ export const AcfIntegration = ( { AcfIntegration.propTypes = { integration: PropTypes.shape( { name: PropTypes.string, - claim: PropTypes.string, + claim: PropTypes.node, slug: PropTypes.string, description: PropTypes.string, usps: PropTypes.array, diff --git a/packages/js/src/integrations-page/algolia-integration.js b/packages/js/src/integrations-page/algolia-integration.js index 9888806569f..5a182482643 100644 --- a/packages/js/src/integrations-page/algolia-integration.js +++ b/packages/js/src/integrations-page/algolia-integration.js @@ -87,9 +87,9 @@ export const AlgoliaIntegration = ( {
    -

    - { integration.claim && integration.claim } -

    + { integration.claim &&

    + { integration.claim } +

    }

    { integration.description } { integration.learnMoreLink && { Section.propTypes = { title: PropTypes.string, - description: PropTypes.string, + description: PropTypes.node, elements: PropTypes.array, }; diff --git a/packages/js/src/integrations-page/mastodon-integration.js b/packages/js/src/integrations-page/mastodon-integration.js index df1b91402e1..cb1958a2a84 100644 --- a/packages/js/src/integrations-page/mastodon-integration.js +++ b/packages/js/src/integrations-page/mastodon-integration.js @@ -43,7 +43,7 @@ export const MastodonIntegration = ( { integration, isActive } ) => { MastodonIntegration.propTypes = { integration: PropTypes.shape( { name: PropTypes.string, - claim: PropTypes.string, + claim: PropTypes.node, slug: PropTypes.string, description: PropTypes.string, usps: PropTypes.array, diff --git a/packages/js/src/integrations-page/plugin-integration.js b/packages/js/src/integrations-page/plugin-integration.js index adbe3d6e58d..c3cdcc5936b 100644 --- a/packages/js/src/integrations-page/plugin-integration.js +++ b/packages/js/src/integrations-page/plugin-integration.js @@ -43,7 +43,7 @@ export const PluginIntegration = ( { integration, isActive } ) => { PluginIntegration.propTypes = { integration: PropTypes.shape( { name: PropTypes.string, - claim: PropTypes.string, + claim: PropTypes.node, slug: PropTypes.string, description: PropTypes.string, usps: PropTypes.array, diff --git a/packages/js/src/integrations-page/schema-api-integrations.js b/packages/js/src/integrations-page/schema-api-integrations.js index 09d27679875..4445e712efd 100644 --- a/packages/js/src/integrations-page/schema-api-integrations.js +++ b/packages/js/src/integrations-page/schema-api-integrations.js @@ -157,6 +157,7 @@ const SchemaAPIIntegrations = [ /* eslint-disable dot-notation */ SchemaAPIIntegrations.push( {

    -

    - { integration.claim } -

    + { integration.claim &&

    + { integration.claim } +

    } { integration.description &&

    { integration.description }

    } { integration.usps &&
      { integration.usps.map( ( usp, idx ) => { @@ -106,7 +106,7 @@ export const SimpleIntegration = ( { integration, isActive, children } ) => { SimpleIntegration.propTypes = { integration: PropTypes.shape( { name: PropTypes.string, - claim: PropTypes.string, + claim: PropTypes.node, learnMoreLink: PropTypes.string, logoLink: PropTypes.string, slug: PropTypes.string, diff --git a/packages/js/src/integrations-page/toggleable-integration.js b/packages/js/src/integrations-page/toggleable-integration.js index a8d066bf8c6..b8503933e0d 100644 --- a/packages/js/src/integrations-page/toggleable-integration.js +++ b/packages/js/src/integrations-page/toggleable-integration.js @@ -12,12 +12,12 @@ import { Slot } from "@wordpress/components"; /** * An integration which can be toggled on and off. * - * @param {object} integration The integration. - * @param {bool} initialActivationState True if the integration has been activated by the user. - * @param {bool} isNetworkControlEnabled True if the integration is network-enabled. - * @param {bool} isMultisiteAvailable True if the integration is available on multisites. - * @param {string} toggleLabel The toggle label. - * @param {function} beforeToggle Check function to call before toggling the integration. + * @param {object} integration The integration. + * @param {bool} initialActivationState True if the integration has been activated by the user. + * @param {bool} isNetworkControlEnabled True if the integration is network-enabled. + * @param {bool} isMultisiteAvailable True if the integration is available on multisites. + * @param {string} toggleLabel The toggle label. + * @param {function} beforeToggle Check function to call before toggling the integration. * * @returns {WPElement} A card representing an integration which can be toggled active by the user. */ @@ -84,9 +84,9 @@ export const ToggleableIntegration = ( {
      -

      - { integration.claim && integration.claim } -

      + { integration.claim &&

      + { integration.claim } +

      }

      { integration.description } { integration.learnMoreLink &&

      } { getIsFreeIntegrationOrPremiumAvailable( integration ) && getIsMultisiteAvailable( integration ) && { as={ SelectField } name={ `wpseo_titles.post_types-${ postTypeName }-maintax` } id={ `input-wpseo_titles-post_types-${ postTypeName }-maintax` } - label={ <> - { postType.label } - { postTypeName } - } + label={ postType.label } + labelSuffix={ { postTypeName } } options={ postType.options } className="yst-max-w-sm" /> ) } @@ -131,12 +129,10 @@ const Breadcrumbs = () => { as={ SelectField } name={ `wpseo_titles.taxonomy-${ taxonomy.name }-ptparent` } id={ `input-wpseo_titles-taxonomy-${ taxonomy.name }-ptparent` } - label={ <> - { taxonomy.label } - { taxonomy.name } - } + label={ taxonomy.label } options={ taxonomy.options } className="yst-max-w-sm" + labelSuffix={ { taxonomy.name } } /> ) ) } diff --git a/packages/js/src/settings/routes/crawl-optimization.js b/packages/js/src/settings/routes/crawl-optimization.js index a45f4d40fe2..ca248d77fe4 100644 --- a/packages/js/src/settings/routes/crawl-optimization.js +++ b/packages/js/src/settings/routes/crawl-optimization.js @@ -1,21 +1,28 @@ /* eslint-disable complexity */ import { createInterpolateElement, useMemo } from "@wordpress/element"; import { __, sprintf } from "@wordpress/i18n"; -import { Alert, Code, TextField, ToggleField } from "@yoast/ui-library"; +import { Alert, Badge, Code, FeatureUpsell, TextField, ToggleField } from "@yoast/ui-library"; import { Field, useFormikContext } from "formik"; +import { OutboundLink } from "../../shared-admin/components"; import { FieldsetLayout, FormikTagField, FormikValueChangeField, FormLayout, RouteLayout } from "../components"; -import { withDisabledMessageSupport, withFormikError } from "../hocs"; +import { withDisabledMessageSupport, withFormikDummySelectField, withFormikError } from "../hocs"; import { useSelectSettings } from "../hooks"; const FormikFieldWithError = withFormikError( Field ); const FormikValueChangeFieldWithDisabledMessage = withDisabledMessageSupport( FormikValueChangeField ); +const FormikValueChangeFieldWithDisabledMessageAndDummy = withFormikDummySelectField( FormikValueChangeFieldWithDisabledMessage ); /** * @returns {JSX.Element} The crawl optimization route. */ const CrawlOptimization = () => { + const isPremium = useSelectSettings( "selectPreference", [], "isPremium", false ); + const isMultisite = useSelectSettings( "selectPreference", [], "isMultisite", false ); + const premiumUpsellConfig = useSelectSettings( "selectUpsellSettingsAsProps" ); const crawlSettingsLink = useSelectSettings( "selectLink", [], "https://yoa.st/crawl-settings" ); const permalinkCleanupLink = useSelectSettings( "selectLink", [], "https://yoa.st/permalink-cleanup" ); + const blockUnwantedBotsInfoLink = useSelectSettings( "selectLink", [], "https://yoa.st/block-unwanted-bots-info" ); + const premiumBlockUnwantedBotsLink = useSelectSettings( "selectLink", [], "https://yoa.st/block-unwanted-bots-upsell" ); const codeExample = useMemo( () => sprintf( /* translators: %1$s expands to an example within a code tag. */ @@ -154,6 +161,19 @@ const CrawlOptimization = () => { , } ), + // Block unwanted bots. + blockUnwantedBots: createInterpolateElement( + sprintf( + /* translators: %1$s expands to an opening tag. %2$s expands to a closing tag. */ + __( "Lots of web traffic comes from bots crawling the web. Some can benefit your site or business, while other bots don’t. Blocking unwanted bots can save energy, help with site performance, and protect copyrighted content. Learn more about %1$swhen to block unwanted bots%2$s.", "wordpress-seo" ), + "
      ", + "" + ), + { + a: , + } + ), + // Internal site search cleanup. redirectSearchPrettyUrls: createInterpolateElement( sprintf( @@ -544,7 +564,7 @@ const CrawlOptimization = () => {
      { name="wpseo.deny_adsbot_crawling" id="input-wpseo-deny_adsbot_crawling" label={ __( "Prevent Google AdsBot from crawling", "wordpress-seo" ) } - description={ __( "Add a 'disallow' rule to your robots.txt file to prevent crawling by Google's AdsBot. You should only enable this setting if you're not using Google Ads on your site.", "wordpress-seo" ) } + description={ __( "Add a ‘disallow’ rule to your robots.txt file to prevent crawling by Google AdsBot. You should only enable this setting if you're not using Google Ads on your site.", "wordpress-seo" ) } className="yst-max-w-2xl" /> + + Premium } + className="yst-max-w-2xl" + isDummy={ ! isPremium } + /> + Premium } + className="yst-max-w-2xl" + isDummy={ ! isPremium } + /> + Premium } + className="yst-max-w-2xl" + isDummy={ ! isPremium } + /> +
      { registerBlockType( "yoast/faq-block", { title: __( "Yoast FAQ", "wordpress-seo" ), - description: __( "List your Frequently Asked Questions in an SEO-friendly way. You can only use one FAQ block per post.", "wordpress-seo" ), + description: __( "List your Frequently Asked Questions in an SEO-friendly way.", "wordpress-seo" ), icon: "editor-ul", category: "yoast-structured-data-blocks", keywords: [ diff --git a/packages/yoastseo/spec/fullTextTests/testTexts/en/englishPaperForPerformanceTest.js b/packages/yoastseo/spec/fullTextTests/testTexts/en/englishPaperForPerformanceTest.js index a536d7ed065..48bb33fc8ef 100644 --- a/packages/yoastseo/spec/fullTextTests/testTexts/en/englishPaperForPerformanceTest.js +++ b/packages/yoastseo/spec/fullTextTests/testTexts/en/englishPaperForPerformanceTest.js @@ -160,7 +160,7 @@ const expectedResults = { wordComplexity: { isApplicable: true, score: 6, - resultText: "Word complexity: 25.31% of the words in your text are considered complex. " + + resultText: "Word complexity: 25.16% of the words in your text are considered complex. " + "Try to use shorter and more familiar words to improve readability.", }, textAlignment: { diff --git a/packages/yoastseo/spec/languageProcessing/languages/de/ResearcherSpec.js b/packages/yoastseo/spec/languageProcessing/languages/de/ResearcherSpec.js index 3e82f85084d..4ba479901bc 100644 --- a/packages/yoastseo/spec/languageProcessing/languages/de/ResearcherSpec.js +++ b/packages/yoastseo/spec/languageProcessing/languages/de/ResearcherSpec.js @@ -9,7 +9,7 @@ import stopWords from "../../../../src/languageProcessing/languages/de/config/st import syllables from "../../../../src/languageProcessing/languages/de/config/syllables.json"; import checkIfWordIsComplex from "../../../../src/languageProcessing/languages/de/helpers/checkIfWordIsComplex"; import wordComplexityConfig from "../../../../src/languageProcessing/languages/de/config/wordComplexity"; -const morphologyDataDE = getMorphologyData( "de" ); +const premiumData = getMorphologyData( "de" ); describe( "a test for the German Researcher", function() { const researcher = new Researcher( new Paper( "" ) ); @@ -55,7 +55,7 @@ describe( "a test for the German Researcher", function() { } ); it( "stems a word using the German stemmer", function() { - researcher.addResearchData( "morphology", morphologyDataDE ); + researcher.addResearchData( "morphology", premiumData ); expect( researcher.getHelper( "getStemmer" )( researcher )( "Katzen" ) ).toEqual( "Katz" ); } ); @@ -81,8 +81,8 @@ describe( "a test for the German Researcher", function() { it( "checks if a word is complex in German", function() { researcher.addHelper( "checkIfWordIsComplex", checkIfWordIsComplex ); - expect( researcher.getHelper( "checkIfWordIsComplex" )( wordComplexityConfig, "optimierungen" ) ).toEqual( true ); - expect( researcher.getHelper( "checkIfWordIsComplex" )( wordComplexityConfig, "boxen" ) ).toEqual( false ); + expect( researcher.getHelper( "checkIfWordIsComplex" )( wordComplexityConfig, "optimierungen", premiumData.de ) ).toEqual( true ); + expect( researcher.getHelper( "checkIfWordIsComplex" )( wordComplexityConfig, "boxen", premiumData.de ) ).toEqual( false ); } ); it( "checks if a word is a function word in German", function() { diff --git a/packages/yoastseo/spec/languageProcessing/languages/de/helpers/checkIfWordIsComplexSpec.js b/packages/yoastseo/spec/languageProcessing/languages/de/helpers/checkIfWordIsComplexSpec.js index 50434cc015c..90ec6b08ef4 100644 --- a/packages/yoastseo/spec/languageProcessing/languages/de/helpers/checkIfWordIsComplexSpec.js +++ b/packages/yoastseo/spec/languageProcessing/languages/de/helpers/checkIfWordIsComplexSpec.js @@ -1,35 +1,37 @@ import checkIfWordIsComplex from "../../../../../src/languageProcessing/languages/de/helpers/checkIfWordIsComplex"; import wordComplexityConfig from "../../../../../src/languageProcessing/languages/de/config/wordComplexity"; +import getMorphologyData from "../../../../specHelpers/getMorphologyData"; +const premiumData = getMorphologyData( "de" ).de; describe( "a test checking if the word is complex in German", function() { it( "returns singular word form as non-complex if it is found in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "präsident" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "präsident", premiumData ) ).toEqual( false ); } ); it( "returns plural word form as non-complex if its singular form is found in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "Verstärkungen" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "Verstärkungen", premiumData ) ).toEqual( false ); } ); it( "returns plural word form as non-complex if its singular form is found in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "Gouverneure" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "Gouverneure", premiumData ) ).toEqual( false ); } ); it( "returns word as non-complex if it is found in the function words list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "verschiedenes" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "verschiedenes", premiumData ) ).toEqual( false ); } ); it( "returns plural word as complex if it (and its singular form) are not in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "optimierungen" ) ).toEqual( true ); + expect( checkIfWordIsComplex( wordComplexityConfig, "optimierungen", premiumData ) ).toEqual( true ); } ); it( "returns word longer than 10 characters as complex if it's not in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "architektonisch" ) ).toEqual( true ); + expect( checkIfWordIsComplex( wordComplexityConfig, "architektonisch", premiumData ) ).toEqual( true ); } ); it( "returns plural word as non complex if the word is less than 10 characters", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "boxen" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "boxen", premiumData ) ).toEqual( false ); } ); it( "recognized contractions when the contraction uses ’ (right single quotation mark) instead of ' (apostrophe)", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "l’histoire" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "l’histoire", premiumData ) ).toEqual( false ); } ); } ); diff --git a/packages/yoastseo/spec/languageProcessing/languages/en/ResearcherSpec.js b/packages/yoastseo/spec/languageProcessing/languages/en/ResearcherSpec.js index f21deef2ed6..5174663cec4 100644 --- a/packages/yoastseo/spec/languageProcessing/languages/en/ResearcherSpec.js +++ b/packages/yoastseo/spec/languageProcessing/languages/en/ResearcherSpec.js @@ -9,7 +9,7 @@ import stopWords from "../../../../src/languageProcessing/languages/en/config/st import syllables from "../../../../src/languageProcessing/languages/en/config/syllables.json"; import checkIfWordIsComplex from "../../../../src/languageProcessing/languages/en/helpers/checkIfWordIsComplex"; import wordComplexityConfig from "../../../../src/languageProcessing/languages/en/config/wordComplexity"; -const morphologyDataEN = getMorphologyData( "en" ); +const premiumData = getMorphologyData( "en" ); describe( "a test for the English Researcher", function() { const researcher = new Researcher( new Paper( "This is another paper!" ) ); @@ -55,7 +55,7 @@ describe( "a test for the English Researcher", function() { } ); it( "stems a word using the English stemmer", function() { - researcher.addResearchData( "morphology", morphologyDataEN ); + researcher.addResearchData( "morphology", premiumData ); expect( researcher.getHelper( "getStemmer" )( researcher )( "cats" ) ).toEqual( "cat" ); } ); @@ -82,7 +82,7 @@ describe( "a test for the English Researcher", function() { it( "checks if a word is complex in English", function() { researcher.addHelper( "checkIfWordIsComplex", checkIfWordIsComplex ); - expect( researcher.getHelper( "checkIfWordIsComplex" )( wordComplexityConfig, "polygonal", morphologyDataEN.en ) ).toEqual( true ); - expect( researcher.getHelper( "checkIfWordIsComplex" )( wordComplexityConfig, "investigations", morphologyDataEN.en ) ).toEqual( false ); + expect( researcher.getHelper( "checkIfWordIsComplex" )( wordComplexityConfig, "polygonal", premiumData.en ) ).toEqual( true ); + expect( researcher.getHelper( "checkIfWordIsComplex" )( wordComplexityConfig, "investigations", premiumData.en ) ).toEqual( false ); } ); } ); diff --git a/packages/yoastseo/spec/languageProcessing/languages/en/helpers/checkIfWordIsComplexSpec.js b/packages/yoastseo/spec/languageProcessing/languages/en/helpers/checkIfWordIsComplexSpec.js index f9537b90690..257bbb5c468 100644 --- a/packages/yoastseo/spec/languageProcessing/languages/en/helpers/checkIfWordIsComplexSpec.js +++ b/packages/yoastseo/spec/languageProcessing/languages/en/helpers/checkIfWordIsComplexSpec.js @@ -2,54 +2,53 @@ import checkIfWordIsComplex from "../../../../../src/languageProcessing/language import wordComplexityConfig from "../../../../../src/languageProcessing/languages/en/config/wordComplexity"; import getMorphologyData from "../../../../specHelpers/getMorphologyData"; -const morphologyData = getMorphologyData( "en" ).en; +const premiumData = getMorphologyData( "en" ).en; describe( "a test checking if the word is complex in English", function() { it( "returns singular word as non-complex if it is found in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "example", morphologyData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "example", premiumData ) ).toEqual( false ); } ); it( "returns word as non-complex if its singular version is found in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "examples", morphologyData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "examples", premiumData ) ).toEqual( false ); } ); it( "returns singular word as non-complex if it is found in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "release", morphologyData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "release", premiumData ) ).toEqual( false ); } ); it( "returns plural word as non-complex if its singular version is found in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "releases", morphologyData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "releases", premiumData ) ).toEqual( false ); } ); it( "returns plural (with phonetical) change word as non-complex if its singular version is found in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "opportunities" ) ).toEqual( true ); - expect( checkIfWordIsComplex( wordComplexityConfig, "opportunities", morphologyData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "opportunities", premiumData ) ).toEqual( false ); } ); it( "returns long irregular plural word as complex if its singular version is not found in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "metamorphoses", morphologyData ) ).toEqual( true ); + expect( checkIfWordIsComplex( wordComplexityConfig, "metamorphoses", premiumData ) ).toEqual( true ); } ); it( "returns long plural word as complex if its singular version is not found in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "anesthesias", morphologyData ) ).toEqual( true ); + expect( checkIfWordIsComplex( wordComplexityConfig, "anesthesias", premiumData ) ).toEqual( true ); } ); it( "returns plural word as complex if it is not in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "refrigerators", morphologyData ) ).toEqual( true ); + expect( checkIfWordIsComplex( wordComplexityConfig, "refrigerators", premiumData ) ).toEqual( true ); } ); it( "returns plural word as non complex if the word starts with capital letter", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "Tortoiseshell", morphologyData ) ).toEqual( false ); - expect( checkIfWordIsComplex( wordComplexityConfig, "Outsiders", morphologyData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "Tortoiseshell", premiumData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "Outsiders", premiumData ) ).toEqual( false ); } ); it( "returns words as non complex if the word is less than 7 characters", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "cat", morphologyData ) ).toEqual( false ); - expect( checkIfWordIsComplex( wordComplexityConfig, "rabbit", morphologyData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "cat", premiumData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "rabbit", premiumData ) ).toEqual( false ); } ); it( "returns words as non complex if the word is less than 7 characters", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "cat", morphologyData ) ).toEqual( false ); - expect( checkIfWordIsComplex( wordComplexityConfig, "rabbit", morphologyData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "cat", premiumData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "rabbit", premiumData ) ).toEqual( false ); } ); } ); diff --git a/packages/yoastseo/spec/languageProcessing/languages/es/ResearcherSpec.js b/packages/yoastseo/spec/languageProcessing/languages/es/ResearcherSpec.js index 21272fbb300..3d95977b5cb 100644 --- a/packages/yoastseo/spec/languageProcessing/languages/es/ResearcherSpec.js +++ b/packages/yoastseo/spec/languageProcessing/languages/es/ResearcherSpec.js @@ -11,7 +11,7 @@ import checkIfWordIsComplex from "../../../../src/languageProcessing/languages/e import wordComplexityConfig from "../../../../src/languageProcessing/languages/es/config/wordComplexity"; import sentenceLength from "../../../../src/languageProcessing/languages/es/config/sentenceLength"; -const morphologyDataES = getMorphologyData( "es" ); +const premiumData = getMorphologyData( "es" ); describe( "a test for the Spanish Researcher", function() { const researcher = new Researcher( new Paper( "Este es un documento nuevo!" ) ); @@ -27,8 +27,8 @@ describe( "a test for the Spanish Researcher", function() { it( "checks if a word is complex in Spanish", function() { researcher.addHelper( "checkIfWordIsComplex", checkIfWordIsComplex ); - expect( researcher.getHelper( "checkIfWordIsComplex" )( wordComplexityConfig, "situados" ) ).toEqual( true ); - expect( researcher.getHelper( "checkIfWordIsComplex" )( wordComplexityConfig, "sobre" ) ).toEqual( false ); + expect( researcher.getHelper( "checkIfWordIsComplex" )( wordComplexityConfig, "situados", premiumData.es ) ).toEqual( true ); + expect( researcher.getHelper( "checkIfWordIsComplex" )( wordComplexityConfig, "sobre", premiumData.es ) ).toEqual( false ); } ); it( "returns the Spanish function words", function() { @@ -68,7 +68,7 @@ describe( "a test for the Spanish Researcher", function() { } ); it( "stems a word using the Spanish stemmer", function() { - researcher.addResearchData( "morphology", morphologyDataES ); + researcher.addResearchData( "morphology", premiumData ); expect( researcher.getHelper( "getStemmer" )( researcher )( "gatos" ) ).toEqual( "gat" ); } ); diff --git a/packages/yoastseo/spec/languageProcessing/languages/es/helpers/checkIfWordIsComplexSpec.js b/packages/yoastseo/spec/languageProcessing/languages/es/helpers/checkIfWordIsComplexSpec.js index e17adefad8c..be5bb6db23a 100644 --- a/packages/yoastseo/spec/languageProcessing/languages/es/helpers/checkIfWordIsComplexSpec.js +++ b/packages/yoastseo/spec/languageProcessing/languages/es/helpers/checkIfWordIsComplexSpec.js @@ -1,35 +1,37 @@ import checkIfWordIsComplex from "../../../../../src/languageProcessing/languages/es/helpers/checkIfWordIsComplex"; import wordComplexityConfig from "../../../../../src/languageProcessing/languages/es/config/wordComplexity"; +import getMorphologyData from "../../../../specHelpers/getMorphologyData"; +const premiumData = getMorphologyData( "es" ).es; describe( "a test checking if the word is complex in Spanish", function() { it( "returns singular word form as non-complex if it is found in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "original" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "original", premiumData ) ).toEqual( false ); } ); // eslint-disable-next-line max-len it( "returns plural word form as non-complex if its singular form is found in the list when the singular word form ends with a consonant", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "originales" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "originales", premiumData ) ).toEqual( false ); } ); // eslint-disable-next-line max-len it( "returns plural word form as non-complex if its singular form is found in the list when the singular word form ends with a vowel", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "parecidos" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "parecidos", premiumData ) ).toEqual( false ); } ); it( "returns word as non-complex if it starts with a capital (even if non capitalized form is complex)", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "Alhambra" ) ).toEqual( false ); - expect( checkIfWordIsComplex( wordComplexityConfig, "alhambra" ) ).toEqual( true ); + expect( checkIfWordIsComplex( wordComplexityConfig, "Alhambra", premiumData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "alhambra", premiumData ) ).toEqual( true ); } ); it( "returns plural word as complex if it (and its singular form) are not in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "situados" ) ).toEqual( true ); + expect( checkIfWordIsComplex( wordComplexityConfig, "situados", premiumData ) ).toEqual( true ); } ); it( "returns word longer than 7 characters as complex if it's not in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "contemplada" ) ).toEqual( true ); + expect( checkIfWordIsComplex( wordComplexityConfig, "contemplada", premiumData ) ).toEqual( true ); } ); it( "returns plural word as non complex if the word is less than 7 characters", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "cosas" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "cosas", premiumData ) ).toEqual( false ); } ); } ); diff --git a/packages/yoastseo/spec/languageProcessing/languages/fr/ResearcherSpec.js b/packages/yoastseo/spec/languageProcessing/languages/fr/ResearcherSpec.js index 92e118ad3d3..281d17148e8 100644 --- a/packages/yoastseo/spec/languageProcessing/languages/fr/ResearcherSpec.js +++ b/packages/yoastseo/spec/languageProcessing/languages/fr/ResearcherSpec.js @@ -9,7 +9,7 @@ import stopWords from "../../../../src/languageProcessing/languages/fr/config/st import syllables from "../../../../src/languageProcessing/languages/fr/config/syllables.json"; import checkIfWordIsComplex from "../../../../src/languageProcessing/languages/fr/helpers/checkIfWordIsComplex"; import wordComplexityConfig from "../../../../src/languageProcessing/languages/fr/config/wordComplexity"; -const morphologyDataFR = getMorphologyData( "fr" ); +const premiumData = getMorphologyData( "fr" ); describe( "a test for the French Researcher", function() { const researcher = new Researcher( new Paper( "This is another paper!" ) ); @@ -55,7 +55,7 @@ describe( "a test for the French Researcher", function() { } ); it( "stems a word using the French stemmer", function() { - researcher.addResearchData( "morphology", morphologyDataFR ); + researcher.addResearchData( "morphology", premiumData ); expect( researcher.getHelper( "getStemmer" )( researcher )( "chats" ) ).toEqual( "chat" ); } ); @@ -79,6 +79,6 @@ describe( "a test for the French Researcher", function() { it( "checks if a word is complex in French", function() { researcher.addHelper( "checkIfWordIsComplex", checkIfWordIsComplex ); - expect( researcher.getHelper( "checkIfWordIsComplex" )( wordComplexityConfig, "dictionnaire" ) ).toEqual( true ); + expect( researcher.getHelper( "checkIfWordIsComplex" )( wordComplexityConfig, "dictionnaire", premiumData.fr ) ).toEqual( true ); } ); } ); diff --git a/packages/yoastseo/spec/languageProcessing/languages/fr/helpers/checkIfWordIsComplexSpec.js b/packages/yoastseo/spec/languageProcessing/languages/fr/helpers/checkIfWordIsComplexSpec.js index 460c1dbd452..104ee2f35d2 100644 --- a/packages/yoastseo/spec/languageProcessing/languages/fr/helpers/checkIfWordIsComplexSpec.js +++ b/packages/yoastseo/spec/languageProcessing/languages/fr/helpers/checkIfWordIsComplexSpec.js @@ -1,51 +1,53 @@ import checkIfWordIsComplex from "../../../../../src/languageProcessing/languages/fr/helpers/checkIfWordIsComplex"; import wordComplexityConfig from "../../../../../src/languageProcessing/languages/fr/config/wordComplexity"; +import getMorphologyData from "../../../../specHelpers/getMorphologyData"; +const premiumData = getMorphologyData( "fr" ).fr; describe( "a test checking if the word is complex in French", function() { it( "returns singular words as non-complex if it is found in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "résidence" ) ).toEqual( false ); - expect( checkIfWordIsComplex( wordComplexityConfig, "signature" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "résidence", premiumData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "signature", premiumData ) ).toEqual( false ); } ); it( "returns a plural words as non-complex if its singular version is found in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "résidences" ) ).toEqual( false ); - expect( checkIfWordIsComplex( wordComplexityConfig, "signatures" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "résidences", premiumData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "signatures", premiumData ) ).toEqual( false ); } ); it( "returns plural words longer than 9 characters as complex if it is not in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "dictionnaires" ) ).toEqual( true ); + expect( checkIfWordIsComplex( wordComplexityConfig, "dictionnaires", premiumData ) ).toEqual( true ); } ); it( "returns singular words longer than 9 characters as complex if it is not in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "dictionnaire" ) ).toEqual( true ); + expect( checkIfWordIsComplex( wordComplexityConfig, "dictionnaire", premiumData ) ).toEqual( true ); } ); it( "returns plural words longer than 9 characters as non complex if the words start with capital letter", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "Opérations" ) ).toEqual( false ); - expect( checkIfWordIsComplex( wordComplexityConfig, "Éclairage" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "Opérations", premiumData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "Éclairage", premiumData ) ).toEqual( false ); } ); it( "returns words as non complex if the words are less than 9 characters", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "chanson" ) ).toEqual( false ); - expect( checkIfWordIsComplex( wordComplexityConfig, "ouvrir" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "chanson", premiumData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "ouvrir", premiumData ) ).toEqual( false ); } ); it( "returns words longer than 9 characters preceded by article l' or preposition d' as non complex if the words are in the list", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "l'ambassadeur" ) ).toEqual( false ); - expect( checkIfWordIsComplex( wordComplexityConfig, "d'échantillon" ) ).toEqual( false ); - expect( checkIfWordIsComplex( wordComplexityConfig, "s'appartient" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "l'ambassadeur", premiumData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "d'échantillon", premiumData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "s'appartient", premiumData ) ).toEqual( false ); } ); it( "returns word shorter than 9 characters as non complex even when it's preceded by an l' article or " + "a contracted preposition that increases its length", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "l'occident" ) ).toEqual( false ); - expect( checkIfWordIsComplex( wordComplexityConfig, "d'extension" ) ).toEqual( false ); - expect( checkIfWordIsComplex( wordComplexityConfig, "c'extension" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "l'occident", premiumData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "d'extension", premiumData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "c'extension", premiumData ) ).toEqual( false ); } ); it( "returns word longer than 9 characters which starts with capital letter as non complex even when it's preceded by an l' article " + "or a contracted preposition", function() { - expect( checkIfWordIsComplex( wordComplexityConfig, "l'Orthodoxie" ) ).toEqual( false ); - expect( checkIfWordIsComplex( wordComplexityConfig, "c'Égalisation" ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "l'Orthodoxie", premiumData ) ).toEqual( false ); + expect( checkIfWordIsComplex( wordComplexityConfig, "c'Égalisation", premiumData ) ).toEqual( false ); } ); } ); diff --git a/packages/yoastseo/spec/languageProcessing/researches/wordComplexitySpec.js b/packages/yoastseo/spec/languageProcessing/researches/wordComplexitySpec.js index 252c0cf0697..3711517bab3 100644 --- a/packages/yoastseo/spec/languageProcessing/researches/wordComplexitySpec.js +++ b/packages/yoastseo/spec/languageProcessing/researches/wordComplexitySpec.js @@ -1,3 +1,5 @@ +/* eslint-disable max-statements */ + import wordComplexity from "../../../src/languageProcessing/researches/wordComplexity.js"; import Paper from "../../../src/values/Paper"; import EnglishResearcher from "../../../src/languageProcessing/languages/en/Researcher"; @@ -14,7 +16,10 @@ import wordComplexityConfigSpanish from "../../../src/languageProcessing/languag import wordComplexityConfigFrench from "../../../src/languageProcessing/languages/fr/config/wordComplexity"; import getMorphologyData from "../../specHelpers/getMorphologyData"; -const morphologyData = getMorphologyData( "en" ); +const premiumDataEn = getMorphologyData( "en" ); +const premiumDataDe = getMorphologyData( "de" ); +const premiumDataEs = getMorphologyData( "es" ); +const premiumDataFr = getMorphologyData( "fr" ); describe( "a test for getting the complex words in the sentence and calculating their percentage", function() { let researcher; @@ -23,7 +28,7 @@ describe( "a test for getting the complex words in the sentence and calculating researcher = new EnglishResearcher(); researcher.addHelper( "checkIfWordIsComplex", wordComplexityHelperEnglish ); researcher.addConfig( "wordComplexity", wordComplexityConfigEnglish ); - researcher.addResearchData( "morphology", morphologyData ); + researcher.addResearchData( "morphology", premiumDataEn ); } ); it( "returns an array with the complex words from the text in English", function() { @@ -49,7 +54,7 @@ describe( "a test for getting the complex words in the sentence and calculating "either closely mixed or in larger patches.", }, { - complexWords: [ "typically", "reserved", "particolored", "markings" ], + complexWords: [ "reserved", "particolored", "markings" ], sentence: "\"Tortoiseshell\" is typically reserved for particolored cats with relatively small or no white markings.", }, { @@ -69,7 +74,7 @@ describe( "a test for getting the complex words in the sentence and calculating }, ] ); - expect( wordComplexity( paper, researcher ).percentage ).toEqual( 9.64 ); + expect( wordComplexity( paper, researcher ).percentage ).toEqual( 9.04 ); } ); it( "should return an empty array and 0% if there is no complex word found in the text", () => { const paper = new Paper( "This is short text. This is another short text. A text about Calico." ); @@ -130,6 +135,8 @@ describe( "test with different language specific helper and config", () => { let researcher = new EnglishResearcher( paper ); researcher.addHelper( "checkIfWordIsComplex", wordComplexityHelperEnglish ); researcher.addConfig( "wordComplexity", wordComplexityConfigEnglish ); + researcher.addResearchData( "morphology", premiumDataEn ); + expect( wordComplexity( paper, researcher ).complexWords ).toEqual( [] ); expect( wordComplexity( paper, researcher ).percentage ).toEqual( 0 ); @@ -137,6 +144,7 @@ describe( "test with different language specific helper and config", () => { researcher = new GermanResearcher( paper ); researcher.addHelper( "checkIfWordIsComplex", wordComplexityHelperGerman ); researcher.addConfig( "wordComplexity", wordComplexityConfigGerman ); + researcher.addResearchData( "morphology", premiumDataDe ); expect( wordComplexity( paper, researcher ).complexWords ).toEqual( [] ); expect( wordComplexity( paper, researcher ).percentage ).toEqual( 0 ); @@ -145,6 +153,7 @@ describe( "test with different language specific helper and config", () => { researcher = new SpanishResearcher( paper ); researcher.addHelper( "checkIfWordIsComplex", wordComplexityHelperSpanish ); researcher.addConfig( "wordComplexity", wordComplexityConfigSpanish ); + researcher.addResearchData( "morphology", premiumDataEs ); expect( wordComplexity( paper, researcher ).complexWords ).toEqual( [] ); expect( wordComplexity( paper, researcher ).percentage ).toEqual( 0 ); @@ -153,6 +162,7 @@ describe( "test with different language specific helper and config", () => { researcher = new FrenchResearcher( paper ); researcher.addHelper( "checkIfWordIsComplex", wordComplexityHelperFrench ); researcher.addConfig( "wordComplexity", wordComplexityConfigFrench ); + researcher.addResearchData( "morphology", premiumDataFr ); expect( wordComplexity( paper, researcher ).complexWords ).toEqual( [] ); expect( wordComplexity( paper, researcher ).percentage ).toEqual( 0 ); @@ -161,6 +171,7 @@ describe( "test with different language specific helper and config", () => { researcher = new GermanResearcher( paper ); researcher.addHelper( "checkIfWordIsComplex", wordComplexityHelperGerman ); researcher.addConfig( "wordComplexity", wordComplexityConfigGerman ); + researcher.addResearchData( "morphology", premiumDataDe ); expect( wordComplexity( paper, researcher ).complexWords ).toEqual( [] ); expect( wordComplexity( paper, researcher ).percentage ).toEqual( 0 ); @@ -172,6 +183,7 @@ describe( "test with different language specific helper and config", () => { const researcher = new GermanResearcher( paper ); researcher.addHelper( "checkIfWordIsComplex", wordComplexityHelperGerman ); researcher.addConfig( "wordComplexity", wordComplexityConfigGerman ); + researcher.addResearchData( "morphology", premiumDataDe ); expect( wordComplexity( paper, researcher ).complexWords ).toEqual( [] ); expect( wordComplexity( paper, researcher ).percentage ).toEqual( 0 ); diff --git a/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/cultureAssessmentsSpec.js b/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/cultureAssessmentsSpec.js index 795392e6665..75d68ed46fe 100644 --- a/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/cultureAssessmentsSpec.js +++ b/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/cultureAssessmentsSpec.js @@ -55,14 +55,16 @@ describe( "A test for Culture Assessments", () => { } ); } ); +// eslint-disable-next-line max-statements describe( "a test for targeting non-inclusive phrases in culture assessments", () => { it( "should return the appropriate score and feedback string for: 'Third World'", () => { const testData = [ { identifier: "thirdWorld", text: "There are bigger problems in the Third World.", - expectedFeedback: "Avoid using Third World as it is overgeneralizing. Consider using the specific name for the region " + - "or country instead. Learn more.", + expectedFeedback: "Avoid using Third World as it is potentially harmful. Consider using an alternative," + + " such as the specific name for the region or country." + + " Learn more.", expectedScore: 3, }, ]; @@ -320,8 +322,9 @@ describe( "a test for targeting non-inclusive phrases in culture assessments", ( { identifier: "gypsy", text: "In North America, the word Gypsy is most commonly used as a reference to Romani ethnicity.", - expectedFeedback: "Be careful when using gypsy as it is potentially harmful. Consider using an alternative, such as " + - "Romani, Romani person, unless referring to someone who explicitly wants to be referred to with this term. " + + expectedFeedback: "Be careful when using gypsy as it is potentially harmful. " + + "Consider using an alternative, such as Rom, Roma person, Romani, Romani person, " + + "unless referring to someone who explicitly wants to be referred to with this term. " + "If you are referring to a lifestyle rather than the ethnic group or their music, consider using " + "an alternative such as traveler, wanderer, free-spirited." + " Learn more.", @@ -330,8 +333,9 @@ describe( "a test for targeting non-inclusive phrases in culture assessments", ( { identifier: "gypsy", text: "In North America, the word Gipsy is most commonly used as a reference to Romani ethnicity.", - expectedFeedback: "Be careful when using gipsy as it is potentially harmful. Consider using an alternative, such as " + - "Romani, Romani person, unless referring to someone who explicitly wants to be referred to with this term. " + + expectedFeedback: "Be careful when using gipsy as it is potentially harmful. " + + "Consider using an alternative, such as Rom, Roma person, Romani, Romani person, " + + "unless referring to someone who explicitly wants to be referred to with this term. " + "If you are referring to a lifestyle rather than the ethnic group or their music, consider using " + "an alternative such as traveler, wanderer, free-spirited." + " Learn more.", @@ -341,7 +345,7 @@ describe( "a test for targeting non-inclusive phrases in culture assessments", ( identifier: "gypsies", text: "In the English language, the Romani people are widely known by the exonym Gypsies.", expectedFeedback: "Be careful when using gypsies as it is potentially harmful. Consider using an alternative, " + - "such as Romani, Romani people, unless referring to someone who explicitly wants to be referred to " + + "such as Roma, Romani, Romani people, unless referring to someone who explicitly wants to be referred to " + "with this term. If you are referring to a lifestyle rather than the ethnic group or their music, " + "consider using an alternative such as travelers, wanderers, free-spirited. " + "Learn more.", @@ -351,7 +355,7 @@ describe( "a test for targeting non-inclusive phrases in culture assessments", ( identifier: "gypsies", text: "In the English language, the Romani people are widely known by the exonym Gipsies.", expectedFeedback: "Be careful when using gipsies as it is potentially harmful. Consider using an alternative, " + - "such as Romani, Romani people, unless referring to someone who explicitly wants to be referred to " + + "such as Roma, Romani, Romani people, unless referring to someone who explicitly wants to be referred to " + "with this term. If you are referring to a lifestyle rather than the ethnic group or their music, " + "consider using an alternative such as travelers, wanderers, free-spirited. " + "Learn more.", @@ -531,7 +535,8 @@ describe( "a test for targeting non-inclusive phrases in culture assessments", ( const assessmentResult = assessor.getResult(); expect( assessmentResult.getScore() ).toEqual( 3 ); expect( assessmentResult.getText() ).toEqual( - "Avoid using first-world as it is overgeneralizing. Consider using the specific name for the country or region instead. " + + "Avoid using first-world as it is potentially harmful. Consider using an alternative," + + " such as the specific name for the region or country. " + "Learn more." ); expect( assessmentResult.hasMarks() ).toBeTruthy(); @@ -552,8 +557,8 @@ describe( "a test for targeting non-inclusive phrases in culture assessments", ( const assessmentResult = assessor.getResult(); expect( assessmentResult.getScore() ).toEqual( 3 ); expect( assessmentResult.getText() ).toEqual( - "Avoid using first world countries as it is overgeneralizing. " + - "Consider using the specific name for the countries or regions instead. " + + "Avoid using first world countries as it is potentially harmful. Consider using an alternative, " + + "such as the specific name for the regions or countries. " + "Learn more." ); expect( assessmentResult.hasMarks() ).toBeTruthy(); @@ -760,20 +765,6 @@ describe( "a test for targeting non-inclusive phrases in culture assessments", ( testInclusiveLanguageAssessments( testData ); } ); - it( "should return the appropriate score and feedback string for: 'ebonics'", () => { - const testData = [ - { - identifier: "ebonics", - text: "White North Americans do not always understand Ebonics.", - expectedFeedback: "Avoid using Ebonics as it is potentially harmful. " + - "Consider using an alternative, such as African American English, African American Language. " + - "Learn more.", - expectedScore: 3, - }, - ]; - - testInclusiveLanguageAssessments( testData ); - } ); it( "should return the appropriate score and feedback string for: 'low man on the totem pole'", () => { const testData = [ { @@ -835,8 +826,8 @@ describe( "a test for targeting non-inclusive phrases in culture assessments", ( { identifier: "firstWorldCountries", text: "It's natural that one would choose one of the first world countries to raise a child.", - expectedFeedback: "Avoid using first world countries as it is overgeneralizing. " + - "Consider using the specific name for the countries or regions instead. " + + expectedFeedback: "Avoid using first world countries as it is potentially harmful. " + + "Consider using an alternative, such as the specific name for the regions or countries. " + "Learn more.", expectedScore: 3, }, diff --git a/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/disabilityAssessmentsSpec.js b/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/disabilityAssessmentsSpec.js index d3d4446a09d..9a2d996446b 100644 --- a/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/disabilityAssessmentsSpec.js +++ b/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/disabilityAssessmentsSpec.js @@ -61,6 +61,17 @@ describe( "A test for Disability assessments", function() { expect( assessor.getMarks() ).toEqual( [] ); } ); + it( "should not target 'narcissistic' when followed by 'personality disorder'", () => { + const mockPaper = new Paper( "He was diagnosed with narcissistic personality disorder." ); + const mockResearcher = Factory.buildMockResearcher( [ "He was diagnosed with narcissistic personality disorder." ] ); + const assessor = new InclusiveLanguageAssessment( assessments.find( obj => obj.identifier === "narcissistic" ) ); + + const isApplicable = assessor.isApplicable( mockPaper, mockResearcher ); + + expect( isApplicable ).toBeFalsy(); + expect( assessor.getMarks() ).toEqual( [] ); + } ); + it( "should only target retarded if preceded by mentally.", () => { const assessment = new InclusiveLanguageAssessment( assessments.find( obj => obj.identifier === "retarded" ) ); @@ -898,7 +909,7 @@ describe( "a test for targeting non-inclusive phrases in disability assessments" ]; testInclusiveLanguageAssessments( testData ); } ); - it( "should not show the feedback for the non-negated form of 'crazy about' when the negated form is used.", () => { + it( "should not show the feedback for the negated form of 'crazy about' when the non-negated form is used.", () => { const mockPaper = new Paper( "I am so crazy about this album." ); const mockResearcher = Factory.buildMockResearcher( [ "I am so crazy about this album." ] ); const assessor = new InclusiveLanguageAssessment( assessments.find( obj => obj.identifier === "to be not crazy about" ) ); @@ -1196,11 +1207,12 @@ describe( "a test for targeting non-inclusive phrases in disability assessments" { identifier: "narcissistic", text: "We all know, the lovebombing narcissistic type.", - expectedFeedback: "Be careful when using narcissistic as it is potentially harmful. If you are referencing the " + - "medical condition, use person with narcissistic personality disorder instead. If you are not referencing the " + - "medical condition, consider other alternatives to describe the trait or behavior, such as selfish, egotistical, " + - "self-centered, self-absorbed, vain, toxic, manipulative. " + - "Learn more.", + expectedFeedback: "Be careful when using narcissistic as it is potentially harmful." + + " If you are referencing the medical condition, use person with narcissistic personality disorder" + + " instead, unless referring to someone who explicitly wants to be referred to with this term." + + " If you are not referencing the medical condition, consider other alternatives to describe the trait or behavior," + + " such as selfish, egotistical, self-centered, self-absorbed, vain, toxic, manipulative." + + " Learn more.", expectedScore: 6, }, ]; @@ -1211,8 +1223,8 @@ describe( "a test for targeting non-inclusive phrases in disability assessments" { identifier: "theMentallyIll", text: "There is growing compassion for the mentally ill.", - expectedFeedback: "Avoid using the mentally ill as it is generalizing. Consider using an alternative, " + - "such as people who are mentally ill, mentally ill people instead. " + + expectedFeedback: "Avoid using the mentally ill as it is potentially harmful. Consider using an alternative," + + " such as people who are mentally ill, mentally ill people. " + "Learn more.", expectedScore: 3, }, @@ -1225,9 +1237,9 @@ describe( "a test for targeting non-inclusive phrases in disability assessments" const mockResearcher = Factory.buildMockResearcher( [ "That's a daft idea!" ] ); expect( assessment.isApplicable( mockPaper, mockResearcher ) ).toBe( true ); - expect( assessment.getResult().score ).toBe( 6 ); - expect( assessment.getResult().text ).toBe( "Be careful when using daft as it is potentially harmful. " + - "Consider using an alternative, such as uninformed, ignorant, foolish, inconsiderate, irrational, reckless." + + expect( assessment.getResult().score ).toBe( 3 ); + expect( assessment.getResult().text ).toBe( "Avoid using daft as it is potentially harmful." + + " Consider using an alternative, such as uninformed, ignorant, foolish, inconsiderate, irrational, reckless." + " Learn more." ); } ); it( "should return the appropriate score and feedback string for: 'imbecile'", () => { diff --git a/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/otherAssessmentsSpec.js b/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/otherAssessmentsSpec.js index f4600fb824d..18b6ab7bfa3 100644 --- a/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/otherAssessmentsSpec.js +++ b/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/otherAssessmentsSpec.js @@ -27,15 +27,7 @@ describe( "Checks various conditions for the 'normal' and 'abnormal' assessments }, { identifier: "normal", - text: "This isn't normal behaviour children.", - expectedFeedback: "Avoid using normal as it is potentially harmful. " + - "Consider using an alternative, such as typical or a specific characteristic or experience if it is known. " + - "Learn more.", - expectedScore: 3, - }, - { - identifier: "normal", - text: "This isn't normal behavior children.", + text: "He is a mentally normal person.", expectedFeedback: "Avoid using normal as it is potentially harmful. " + "Consider using an alternative, such as typical or a specific characteristic or experience if it is known. " + "Learn more.", @@ -43,35 +35,29 @@ describe( "Checks various conditions for the 'normal' and 'abnormal' assessments }, { identifier: "normal", - text: "He is a mentally normal person.", + text: "I'm afraid this isn't psychologically normal.", expectedFeedback: "Avoid using normal as it is potentially harmful. " + "Consider using an alternative, such as typical or a specific characteristic or experience if it is known. " + "Learn more.", expectedScore: 3, }, { - identifier: "normal", + identifier: "behaviorallyNormal", text: "I'm afraid this isn't behaviorally normal.", - expectedFeedback: "Avoid using normal as it is potentially harmful. " + - "Consider using an alternative, such as typical or a specific characteristic or experience if it is known. " + + expectedFeedback: "Be careful when using behaviorally normal as it is potentially harmful. " + + "Unless you are referring to objects or animals, consider using an alternative, such as showing typical behavior " + + "or a specific characteristic or experience if it is known. " + "Learn more.", - expectedScore: 3, + expectedScore: 6, }, { - identifier: "normal", + identifier: "behaviorallyNormal", text: "I'm afraid this isn't behaviourally normal.", - expectedFeedback: "Avoid using normal as it is potentially harmful. " + - "Consider using an alternative, such as typical or a specific characteristic or experience if it is known. " + + expectedFeedback: "Be careful when using behaviourally normal as it is potentially harmful. " + + "Unless you are referring to objects or animals, consider using an alternative, such as showing typical behavior " + + "or a specific characteristic or experience if it is known. " + "Learn more.", - expectedScore: 3, - }, - { - identifier: "normal", - text: "I'm afraid this isn't psychologically normal.", - expectedFeedback: "Avoid using normal as it is potentially harmful. " + - "Consider using an alternative, such as typical or a specific characteristic or experience if it is known. " + - "Learn more.", - expectedScore: 3, + expectedScore: 6, }, ]; testInclusiveLanguageAssessments( testData ); @@ -96,15 +82,7 @@ describe( "Checks various conditions for the 'normal' and 'abnormal' assessments }, { identifier: "abnormal", - text: "This isn't abnormal behaviour.", - expectedFeedback: "Avoid using abnormal as it is potentially harmful. " + - "Consider using an alternative, such as atypical or a specific characteristic or experience if it is known. " + - "Learn more.", - expectedScore: 3, - }, - { - identifier: "abnormal", - text: "This isn't abnormal behavior.", + text: "He is a mentally abnormal person.", expectedFeedback: "Avoid using abnormal as it is potentially harmful. " + "Consider using an alternative, such as atypical or a specific characteristic or experience if it is known. " + "Learn more.", @@ -112,35 +90,41 @@ describe( "Checks various conditions for the 'normal' and 'abnormal' assessments }, { identifier: "abnormal", - text: "He is a mentally abnormal person.", + text: "I'm afraid this isn't psychologically abnormal.", expectedFeedback: "Avoid using abnormal as it is potentially harmful. " + "Consider using an alternative, such as atypical or a specific characteristic or experience if it is known. " + "Learn more.", expectedScore: 3, }, { - identifier: "abnormal", + identifier: "behaviorallyAbnormal", text: "I'm afraid this isn't behaviorally abnormal.", - expectedFeedback: "Avoid using abnormal as it is potentially harmful. " + - "Consider using an alternative, such as atypical or a specific characteristic or experience if it is known. " + + expectedFeedback: "Be careful when using behaviorally abnormal as it is potentially harmful. " + + "Unless you are referring to objects or animals, consider using an alternative, " + + "such as showing atypical behavior, showing dysfunctional behavior " + + "or a specific characteristic or experience if it is known. " + "Learn more.", - expectedScore: 3, + expectedScore: 6, }, { - identifier: "abnormal", + identifier: "behaviorallyAbnormal", text: "I'm afraid this isn't behaviourally abnormal.", - expectedFeedback: "Avoid using abnormal as it is potentially harmful. " + - "Consider using an alternative, such as atypical or a specific characteristic or experience if it is known. " + + expectedFeedback: "Be careful when using behaviourally abnormal as it is potentially harmful. " + + "Unless you are referring to objects or animals, consider using an alternative, " + + "such as showing atypical behavior, showing dysfunctional behavior " + + "or a specific characteristic or experience if it is known. " + "Learn more.", - expectedScore: 3, + expectedScore: 6, }, { - identifier: "abnormal", - text: "I'm afraid this isn't psychologically abnormal.", - expectedFeedback: "Avoid using abnormal as it is potentially harmful. " + - "Consider using an alternative, such as atypical or a specific characteristic or experience if it is known. " + + identifier: "abnormalBehavior", + text: "This isn't abnormal behaviour.", + expectedFeedback: "Be careful when using abnormal behaviour as it is potentially harmful. " + + "Unless you are referring to objects or animals, consider using an alternative, " + + "such as atypical behavior, unusual behavior " + + "or a specific characteristic or experience if it is known. " + "Learn more.", - expectedScore: 3, + expectedScore: 6, }, ]; testInclusiveLanguageAssessments( testData ); @@ -160,9 +144,10 @@ describe( "Checks highlighting for 'minorities' and a non-triggering condition f expect( isApplicable ).toBeTruthy(); expect( assessmentResult.getScore() ).toEqual( 6 ); expect( assessmentResult.getText() ).toEqual( - "Be careful when using minorities as it is potentially overgeneralizing. " + - "Consider using an alternative, such as marginalized groups, underrepresented groups or " + - "specific minorities, such as gender and sexuality minorities. " + + "Be careful when using minorities as it is potentially harmful. Consider using an alternative by being " + + "specific about which group(s) of people you are referring to. For example: members of the LGBTQ+ community, " + + "Indigenous peoples, marginalized groups. In case an alternative is not available, make sure to specify the type of " + + "minorities you are referring to, e.g., religious minorities. " + "Learn more." ); expect( assessmentResult.hasMarks() ).toBeTruthy(); expect( assessor.getMarks() ).toEqual( [ new Mark( { diff --git a/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/sesAssessmentsSpec.js b/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/sesAssessmentsSpec.js index c37c124cb07..c27c0224af2 100644 --- a/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/sesAssessmentsSpec.js +++ b/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/sesAssessmentsSpec.js @@ -15,10 +15,9 @@ describe( "A test for SES assessments", function() { expect( isApplicable ).toBeTruthy(); expect( assessmentResult.getScore() ).toEqual( 3 ); - expect( assessmentResult.getText() ).toEqual( - "Avoid using the poor as it is potentially overgeneralizing. " + - "Consider using people whose income is below the poverty threshold or people with low-income instead. " + - "Learn more." ); + expect( assessmentResult.getText() ).toEqual( "Avoid using the poor as it is potentially harmful. " + + "Consider using an alternative, such as people whose income is below the poverty threshold, people with low-income." + + " Learn more." ); expect( assessmentResult.hasMarks() ).toBeTruthy(); expect( assessor.getMarks() ).toEqual( [ new Mark( { original: "The poor worked, the better they are.", @@ -35,10 +34,9 @@ describe( "A test for SES assessments", function() { expect( isApplicable ).toBeTruthy(); expect( assessmentResult.getScore() ).toEqual( 3 ); - expect( assessmentResult.getText() ).toEqual( - "Avoid using the poor as it is potentially overgeneralizing. " + - "Consider using people whose income is below the poverty threshold or people with low-income instead. " + - "Learn more." ); + expect( assessmentResult.getText() ).toEqual( "Avoid using the poor as it is potentially harmful. " + + "Consider using an alternative, such as people whose income is below the poverty threshold, people with low-income." + + " Learn more." ); expect( assessmentResult.hasMarks() ).toBeTruthy(); expect( assessor.getMarks() ).toEqual( [ new Mark( { original: "The poor however, did not go to the zoo.", @@ -55,10 +53,9 @@ describe( "A test for SES assessments", function() { expect( isApplicable ).toBeTruthy(); expect( assessmentResult.getScore() ).toEqual( 3 ); - expect( assessmentResult.getText() ).toEqual( - "Avoid using the poor as it is potentially overgeneralizing. " + - "Consider using people whose income is below the poverty threshold or people with low-income instead. " + - "Learn more." ); + expect( assessmentResult.getText() ).toEqual( "Avoid using the poor as it is potentially harmful. " + + "Consider using an alternative, such as people whose income is below the poverty threshold, people with low-income." + + " Learn more." ); expect( assessmentResult.hasMarks() ).toBeTruthy(); expect( assessor.getMarks() ).toEqual( [ new Mark( { original: "I have always loved the poor!", @@ -182,18 +179,18 @@ describe( "a test for targeting non-inclusive phrases in other assessments", () { identifier: "felon", text: "That person is a felon", - expectedFeedback: "Be careful when using felon as it is potentially harmful. Consider using an alternative, such as " + - "person with felony convictions, person who has been incarcerated. " + + expectedFeedback: "Avoid using felon as it is potentially harmful. Consider using an alternative," + + " such as person with felony convictions, person who has been incarcerated. " + "Learn more.", - expectedScore: 6, + expectedScore: 3, }, { identifier: "felons", text: "Those group of people are all felons", - expectedFeedback: "Be careful when using felons as it is potentially harmful. Consider using an alternative, such as " + + expectedFeedback: "Avoid using felons as it is potentially harmful. Consider using an alternative, such as " + "people with felony convictions, people who have been incarcerated. " + "Learn more.", - expectedScore: 6, + expectedScore: 3, }, ]; @@ -247,49 +244,49 @@ describe( "a test for targeting non-inclusive phrases in other assessments", () { identifier: "theHomeless", text: "This ad is aimed at the homeless in LA. The target word is followed by a preposition.", - expectedFeedback: "Avoid using the homeless as it is generalizing. " + - "Consider using people experiencing homelessness instead. " + - "Learn more.", + expectedFeedback: "Avoid using the homeless as it is potentially harmful. Consider using an alternative, " + + "such as people experiencing homelessness. Learn more.", expectedScore: 3, }, { identifier: "theUndocumented", text: "This targets the undocumented across the US. The target word is followed by a preposition.", - expectedFeedback: "Avoid using the undocumented as it is potentially overgeneralizing. " + - "Consider using people who are undocumented, undocumented people, people without papers instead." + - " Learn more.", + expectedFeedback: "Avoid using the undocumented as it is potentially harmful. Consider using an alternative, such as " + + "people who are undocumented, undocumented people, people without papers. " + + "Learn more.", expectedScore: 3, }, { identifier: "theHomeless", text: "This ad is aimed at the homeless. The target word is followed by a punctuation mark.", - expectedFeedback: "Avoid using the homeless as it is generalizing. " + - "Consider using people experiencing homelessness instead. " + - "Learn more.", + expectedFeedback: "Avoid using the homeless as it is potentially harmful. Consider using an alternative, " + + "such as people experiencing homelessness. Learn more.", expectedScore: 3, }, { identifier: "theUndocumented", text: "This will be a major blow to the undocumented. The target word is followed by a punctuation mark.", - expectedFeedback: "Avoid using the undocumented as it is potentially overgeneralizing. " + - "Consider using people who are undocumented, undocumented people, people without papers instead." + - " Learn more.", + expectedFeedback: "Avoid using the undocumented as it is potentially harmful. Consider using an alternative, such as " + + "people who are undocumented, undocumented people, people without papers. " + + "Learn more.", expectedScore: 3, }, { identifier: "theHomeless", text: "The homeless faced staggering discrimination. The target word is followed by a past participle.", - expectedFeedback: "Avoid using the homeless as it is generalizing. " + - "Consider using people experiencing homelessness instead. " + - "Learn more.", + expectedFeedback: "Avoid using the homeless as it is potentially harmful. Consider using an alternative, " + + "such as people experiencing homelessness. Learn more.", expectedScore: 3, }, { identifier: "theUndocumented", text: "The undocumented didn't receive a fair trial. The target word is followed by a past participle.", - expectedFeedback: "Avoid using the undocumented as it is potentially overgeneralizing. " + - "Consider using people who are undocumented, undocumented people, people without papers instead." + - " Learn more.", + expectedFeedback: "Avoid using the undocumented as it is potentially harmful. Consider using an alternative, such as " + + "people who are undocumented, undocumented people, people without papers. " + + "Learn more.", expectedScore: 3, }, ]; @@ -306,10 +303,9 @@ describe( "a test for targeting non-inclusive phrases in other assessments", () expect( isApplicable ).toBeTruthy(); const assessmentResult = assessor.getResult(); expect( assessmentResult.getScore() ).toEqual( 3 ); - expect( assessmentResult.getText() ).toEqual( - "Avoid using the undocumented as it is potentially overgeneralizing. " + - "Consider using people who are undocumented, undocumented people, people without papers instead. " + - "Learn more." + expect( assessmentResult.getText() ).toEqual( "Avoid using the undocumented as it is potentially harmful. " + + "Consider using an alternative, such as people who are undocumented, undocumented people, people without papers." + + " Learn more." ); expect( assessmentResult.hasMarks() ).toBeTruthy(); expect( assessor.getMarks() ).toEqual( [ { _properties: { diff --git a/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/sexualOrientationAssessmentsSpec.js b/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/sexualOrientationAssessmentsSpec.js index 23f4a8227a9..1d6e966a03c 100644 --- a/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/sexualOrientationAssessmentsSpec.js +++ b/packages/yoastseo/spec/scoring/assessments/inclusiveLanguage/configuration/sexualOrientationAssessmentsSpec.js @@ -17,9 +17,10 @@ describe( "A test for Sexual orientation assessments", function() { expect( isApplicable ).toBeTruthy(); expect( assessmentResult.getScore() ).toEqual( 6 ); expect( assessmentResult.getText() ).toEqual( - "Be careful when using homosexuals as it may overgeneralize or be harmful. " + - "Instead, be specific about the group you are referring to (e.g. gay men, queer people, lesbians). " + - "Learn more." ); + "Be careful when using homosexuals as it is potentially harmful. Consider using an alternative," + + " such as gay people, queer people, lesbians, gay men, people in same-gender relationships, unless referring" + + " to someone who explicitly wants to be referred to with this term. Be as specific possible and use people's preferred" + + " labels if they are known. Learn more." ); expect( assessmentResult.hasMarks() ).toBeTruthy(); expect( assessor.getMarks() ).toEqual( [ new Mark( { original: mockText, diff --git a/packages/yoastseo/spec/scoring/assessments/readability/WordComplexityAssessmentSpec.js b/packages/yoastseo/spec/scoring/assessments/readability/WordComplexityAssessmentSpec.js index b9fc0d89acf..3895683c57f 100644 --- a/packages/yoastseo/spec/scoring/assessments/readability/WordComplexityAssessmentSpec.js +++ b/packages/yoastseo/spec/scoring/assessments/readability/WordComplexityAssessmentSpec.js @@ -70,7 +70,7 @@ describe( "a test for an assessment that checks complex words in a text", functi const result = assessment.getResult( runningPaper, researcher ); expect( result.getScore() ).toBe( 6 ); - expect( result.getText() ).toBe( "Word complexity: 10.64% of the words in " + + expect( result.getText() ).toBe( "Word complexity: 10.11% of the words in " + "your text are considered complex. Try to use shorter and more familiar words " + "to improve readability." ); expect( result.hasMarks() ).toBe( true ); @@ -87,7 +87,7 @@ describe( "a test for an assessment that checks complex words in a text", functi const result = assessment.getResult( runningPaper, researcher ); expect( result.getScore() ).toBe( 3 ); - expect( result.getText() ).toBe( "Word complexity: 10.64% of the words in " + + expect( result.getText() ).toBe( "Word complexity: 10.11% of the words in " + "your text are considered complex. Try to use shorter and more familiar words " + "to improve readability." ); expect( result.hasMarks() ).toBe( true ); diff --git a/packages/yoastseo/spec/scoring/collectionPages/fullTextTests/testTexts/en/englishPaper2.js b/packages/yoastseo/spec/scoring/collectionPages/fullTextTests/testTexts/en/englishPaper2.js index 291e40b1df2..338fdf97385 100644 --- a/packages/yoastseo/spec/scoring/collectionPages/fullTextTests/testTexts/en/englishPaper2.js +++ b/packages/yoastseo/spec/scoring/collectionPages/fullTextTests/testTexts/en/englishPaper2.js @@ -119,10 +119,9 @@ const expectedResults = { }, wordComplexity: { isApplicable: true, - score: 6, - // eslint-disable-next-line max-len - resultText: "Word complexity: 15.66% of the words in your text are considered complex. " + - "Try to use shorter and more familiar words to improve readability.", + score: 9, + resultText: "Word complexity: You are not using too many complex words, which makes " + + "your text easy to read. Good job!", }, }; diff --git a/packages/yoastseo/spec/scoring/collectionPages/fullTextTests/testTexts/en/englishPaper3.js b/packages/yoastseo/spec/scoring/collectionPages/fullTextTests/testTexts/en/englishPaper3.js index 6ea14ea2155..b537022a24f 100644 --- a/packages/yoastseo/spec/scoring/collectionPages/fullTextTests/testTexts/en/englishPaper3.js +++ b/packages/yoastseo/spec/scoring/collectionPages/fullTextTests/testTexts/en/englishPaper3.js @@ -127,10 +127,9 @@ const expectedResults = { }, wordComplexity: { isApplicable: true, - score: 6, - resultText: "Word complexity: 12.36% of the words in your text are " + - "considered complex. " + - "Try to use shorter and more familiar words to improve readability.", + score: 9, + resultText: "Word complexity: You are not using too many complex words, which makes " + + "your text easy to read. Good job!", }, }; diff --git a/packages/yoastseo/spec/scoring/productPages/fullTextTests/testTexts/en/englishPaper1.js b/packages/yoastseo/spec/scoring/productPages/fullTextTests/testTexts/en/englishPaper1.js index de938fbe5f4..1fad43ac2c0 100644 --- a/packages/yoastseo/spec/scoring/productPages/fullTextTests/testTexts/en/englishPaper1.js +++ b/packages/yoastseo/spec/scoring/productPages/fullTextTests/testTexts/en/englishPaper1.js @@ -162,10 +162,9 @@ const expectedResults = { }, wordComplexity: { isApplicable: true, - score: 6, - resultText: "Word complexity: 11.06% of the words in your " + - "text are considered complex. Try to use shorter and more" + - " familiar words to improve readability.", + score: 9, + resultText: "Word complexity: You are not using too many complex words, which makes " + + "your text easy to read. Good job!", }, }; diff --git a/packages/yoastseo/spec/scoring/productPages/fullTextTests/testTexts/en/englishPaper2.js b/packages/yoastseo/spec/scoring/productPages/fullTextTests/testTexts/en/englishPaper2.js index 896c2ad2eb1..43fb40c1193 100644 --- a/packages/yoastseo/spec/scoring/productPages/fullTextTests/testTexts/en/englishPaper2.js +++ b/packages/yoastseo/spec/scoring/productPages/fullTextTests/testTexts/en/englishPaper2.js @@ -177,11 +177,9 @@ const expectedResults = { }, wordComplexity: { isApplicable: true, - score: 6, - resultText: "Word complexity: 11.11% of the words in your " + - "text " + - "are considered complex." + - " Try to use shorter and more familiar words to improve readability.", + score: 9, + resultText: "Word complexity: You are not using too many complex words, which makes " + + "your text easy to read. Good job!", }, }; diff --git a/packages/yoastseo/spec/scoring/productPages/fullTextTests/testTexts/en/englishPaper3.js b/packages/yoastseo/spec/scoring/productPages/fullTextTests/testTexts/en/englishPaper3.js index 306725fc356..2eec09e2f75 100644 --- a/packages/yoastseo/spec/scoring/productPages/fullTextTests/testTexts/en/englishPaper3.js +++ b/packages/yoastseo/spec/scoring/productPages/fullTextTests/testTexts/en/englishPaper3.js @@ -176,10 +176,9 @@ const expectedResults = { }, wordComplexity: { isApplicable: true, - score: 6, - resultText: "Word complexity: 10.72% of the words in " + - "your text are considered complex. " + - "Try to use shorter and more familiar words to improve readability.", + score: 9, + resultText: "Word complexity: You are not using too many complex words, which makes " + + "your text easy to read. Good job!", }, }; diff --git a/packages/yoastseo/spec/specHelpers/getMorphologyData.js b/packages/yoastseo/spec/specHelpers/getMorphologyData.js index 15366f77448..2488af45eff 100644 --- a/packages/yoastseo/spec/specHelpers/getMorphologyData.js +++ b/packages/yoastseo/spec/specHelpers/getMorphologyData.js @@ -1,8 +1,8 @@ -import en from "../../premium-configuration/data/morphologyData-en-v4.json"; -import de from "../../premium-configuration/data/morphologyData-de-v9.json"; +import en from "../../premium-configuration/data/morphologyData-en-v5.json"; +import de from "../../premium-configuration/data/morphologyData-de-v10.json"; import nl from "../../premium-configuration/data/morphologyData-nl-v9.json"; -import es from "../../premium-configuration/data/morphologyData-es-v9.json"; -import fr from "../../premium-configuration/data/morphologyData-fr-v9.json"; +import es from "../../premium-configuration/data/morphologyData-es-v10.json"; +import fr from "../../premium-configuration/data/morphologyData-fr-v10.json"; import ru from "../../premium-configuration/data/morphologyData-ru-v10.json"; import it from "../../premium-configuration/data/morphologyData-it-v10.json"; import pt from "../../premium-configuration/data/morphologyData-pt-v9.json"; diff --git a/packages/yoastseo/src/languageProcessing/languages/de/config/internal/frequencyList.json b/packages/yoastseo/src/languageProcessing/languages/de/config/internal/frequencyList.json deleted file mode 100644 index 6cdd564c308..00000000000 --- a/packages/yoastseo/src/languageProcessing/languages/de/config/internal/frequencyList.json +++ /dev/null @@ -1,1514 +0,0 @@ -{ - "source": "This list is taken from the first 5000 words of this word list https://github.com/hermitdave/FrequencyWords/blob/master/content/2018/de/de_50k.txt. Out of the 5000 words, we exclude words that are less than 8 characters", - "list": [ - "selbstverständlich", - "krankenschwester", - "zusammenarbeiten", - "schwierigkeiten", - "wissenschaftler", - "missverständnis", - "geschwindigkeit", - "herausforderung", - "angelegenheiten", - "entschuldigung", - "wahrscheinlich", - "offensichtlich", - "verantwortlich", - "aufmerksamkeit", - "kennenzulernen", - "möglicherweise", - "herauszufinden", - "unterschreiben", - "herausgefunden", - "entscheidungen", - "öffentlichkeit", - "fingerabdrücke", - "identifizieren", - "amerikanischen", - "zurückgekommen", - "weihnachtsmann", - "unterschrieben", - "schauspielerin", - "eingeschlossen", - "ausgeschlossen", - "aufzeichnungen", - "krankenstation", - "entschuldigen", - "informationen", - "vergangenheit", - "einverstanden", - "verantwortung", - "funktionieren", - "normalerweise", - "bürgermeister", - "durcheinander", - "kontrollieren", - "konzentrieren", - "kennengelernt", - "unterstützung", - "gerechtigkeit", - "interessieren", - "abgeschlossen", - "ausgezeichnet", - "möglichkeiten", - "verabschieden", - "beeindruckend", - "angelegenheit", - "amerikanische", - "verschiedenen", - "wiederzusehen", - "kopfschmerzen", - "zurückbringen", - "eingeschlafen", - "schrecklichen", - "identifiziert", - "telefonnummer", - "nachbarschaft", - "hauptquartier", - "stimmengewirr", - "funktioniert", - "entschuldige", - "verschwinden", - "interessiert", - "entscheidung", - "verschwunden", - "überraschung", - "gesellschaft", - "herausfinden", - "irgendwelche", - "entschuldigt", - "hinterlassen", - "verschwindet", - "irgendjemand", - "erinnerungen", - "eifersüchtig", - "weitermachen", - "zurückkommen", - "untersuchung", - "freundschaft", - "schlafzimmer", - "schauspieler", - "verschiedene", - "gleichzeitig", - "unterstützen", - "unterhaltung", - "verdächtigen", - "kennenlernen", - "zurückkehren", - "krankenwagen", - "mademoiselle", - "schreckliche", - "durchgemacht", - "schreibtisch", - "verteidigung", - "wissenschaft", - "wirklichkeit", - "staatsanwalt", - "leidenschaft", - "verschwenden", - "ausgerechnet", - "telefonieren", - "menschlichen", - "interessante", - "aufgewachsen", - "organisation", - "hausaufgaben", - "ermittlungen", - "ungewöhnlich", - "hubschrauber", - "versicherung", - "angeschossen", - "hervorragend", - "vergewaltigt", - "handschellen", - "kontrolliert", - "entschlossen", - "wunderschöne", - "persönlichen", - "konsequenzen", - "führerschein", - "wiederkommen", - "vorbeikommen", - "verpflichtet", - "faszinierend", - "unterbrechen", - "verschlossen", - "unterschrift", - "persönliches", - "fortschritte", - "letztendlich", - "festgenommen", - "kontaktieren", - "zwischenzeit", - "nachzudenken", - "medizinische", - "verletzungen", - "nirgendwohin", - "respektieren", - "unschuldigen", - "beschreibung", - "verbindungen", - "thanksgiving", - "wiedersehen", - "krankenhaus", - "unglaublich", - "versprochen", - "tatsächlich", - "verheiratet", - "geschrieben", - "hoffentlich", - "irgendetwas", - "schrecklich", - "verschwinde", - "nachrichten", - "beschäftigt", - "weihnachten", - "wunderschön", - "interessant", - "entscheiden", - "miteinander", - "möglichkeit", - "glückwunsch", - "entschieden", - "schließlich", - "fantastisch", - "unternehmen", - "versprechen", - "unterhalten", - "nachgedacht", - "unterschied", - "neuigkeiten", - "gelegenheit", - "mitgebracht", - "geschlossen", - "anscheinend", - "angegriffen", - "geschichten", - "vorbereitet", - "geheimnisse", - "übersetzung", - "mitgenommen", - "untersuchen", - "präsidenten", - "vorstellung", - "kompliziert", - "akzeptieren", - "aufgenommen", - "beantworten", - "mittagessen", - "gegenseitig", - "verteidigen", - "deutschland", - "fähigkeiten", - "rechtzeitig", - "medikamente", - "menschliche", - "auseinander", - "vorgestellt", - "umzubringen", - "information", - "hergekommen", - "mitternacht", - "freundinnen", - "eingesperrt", - "erfolgreich", - "beziehungen", - "beschlossen", - "beeindruckt", - "stattdessen", - "aufgefallen", - "kalifornien", - "beigebracht", - "wiederholen", - "verstärkung", - "vorbereiten", - "meinetwegen", - "verzweifelt", - "anweisungen", - "erstaunlich", - "schwachsinn", - "aufgetaucht", - "französisch", - "mitarbeiter", - "jahrhundert", - "verabredung", - "kühlschrank", - "unglücklich", - "informieren", - "hierbleiben", - "eingestellt", - "weitergehen", - "bedingungen", - "aufzuhalten", - "persönliche", - "überraschen", - "terroristen", - "beschreiben", - "hintergrund", - "technologie", - "universität", - "katastrophe", - "vereinigten", - "einstellung", - "irgendeinem", - "unterstützt", - "dramatische", - "durchsuchen", - "botschafter", - "bewusstsein", - "präsentiert", - "zurückkommt", - "unschuldige", - "glücklicher", - "diskutieren", - "arschlöcher", - "enttäuschen", - "verdächtige", - "telefoniert", - "aufgehalten", - "schlimmsten", - "verständnis", - "christopher", - "irgendeinen", - "ausgegangen", - "zurückgeben", - "anwesenheit", - "absichtlich", - "entscheidet", - "unterwäsche", - "übertrieben", - "verschieben", - "erschrecken", - "verhandlung", - "ausschalten", - "koordinaten", - "herzinfarkt", - "veränderung", - "schlimmeres", - "vollständig", - "weggelaufen", - "kleinigkeit", - "intelligent", - "brieftasche", - "zurückgehen", - "erleichtert", - "spaziergang", - "durchführen", - "assistentin", - "geschnitten", - "deinetwegen", - "irgendwohin", - "entwicklung", - "vielleicht", - "eigentlich", - "verstanden", - "geschichte", - "willkommen", - "gesprochen", - "vorstellen", - "wenigstens", - "vorsichtig", - "sicherheit", - "verzeihung", - "umgebracht", - "gefährlich", - "augenblick", - "irgendwann", - "jedenfalls", - "verbindung", - "gearbeitet", - "vermutlich", - "beschützen", - "geburtstag", - "persönlich", - "geschlafen", - "verspreche", - "überrascht", - "untertitel", - "verstecken", - "allerdings", - "angefangen", - "lieutenant", - "übernehmen", - "abendessen", - "erschossen", - "verdammten", - "wochenende", - "verbrechen", - "prinzessin", - "schätzchen", - "eingeladen", - "lächerlich", - "geschlagen", - "besonderes", - "verbringen", - "überprüfen", - "nachmittag", - "nachdenken", - "restaurant", - "schlechter", - "vollkommen", - "verdammter", - "mindestens", - "erschießen", - "wahnsinnig", - "geschossen", - "besprechen", - "polizisten", - "amerikaner", - "langweilig", - "frankreich", - "erinnerung", - "großmutter", - "washington", - "unschuldig", - "geheiratet", - "verhindern", - "gebrauchen", - "enttäuscht", - "freundlich", - "herzlichen", - "beobachtet", - "überzeugen", - "angenommen", - "selbstmord", - "irgendeine", - "schlimmste", - "schwestern", - "merkwürdig", - "reinkommen", - "wundervoll", - "inzwischen", - "reparieren", - "beobachten", - "schlechten", - "wichtigste", - "angekommen", - "beerdigung", - "vernichten", - "champagner", - "entwickelt", - "überlassen", - "festhalten", - "menschheit", - "schlechtes", - "dunkelheit", - "gefangenen", - "entspannen", - "vernünftig", - "erschaffen", - "verursacht", - "bestätigen", - "erschreckt", - "heutzutage", - "begeistert", - "aufgegeben", - "verurteilt", - "gratuliere", - "unterricht", - "verarschen", - "gesundheit", - "freiwillig", - "sicherlich", - "verbrecher", - "verschwand", - "verdammtes", - "informiert", - "enterprise", - "behandlung", - "kommandant", - "verrückten", - "wiederhole", - "verwandelt", - "erscheinen", - "angestellt", - "rausfinden", - "rauskommen", - "gouverneur", - "gedächtnis", - "donnerstag", - "unheimlich", - "überfallen", - "verbrennen", - "untersucht", - "wunderbare", - "verrückter", - "reingelegt", - "aussteigen", - "schokolade", - "befreundet", - "beibringen", - "scheißkerl", - "zigaretten", - "geschnappt", - "verhandeln", - "gewöhnlich", - "großartige", - "unterlagen", - "auftauchen", - "betrachten", - "widerstand", - "bescheuert", - "revolution", - "besonderen", - "geschaffen", - "ausgesucht", - "ignorieren", - "scheißegal", - "vernichtet", - "ergebnisse", - "einstellen", - "verwandeln", - "bibliothek", - "badezimmer", - "milliarden", - "mitbringen", - "entwickeln", - "erwachsene", - "romantisch", - "verabredet", - "sekretärin", - "existieren", - "beschissen", - "ordentlich", - "aufgewacht", - "unangenehm", - "ausrüstung", - "garantiert", - "durchsucht", - "verfluchte", - "bestimmten", - "wohnzimmer", - "aufgepasst", - "raumschiff", - "ausbildung", - "hauptsache", - "glückliche", - "highschool", - "trainieren", - "verwickelt", - "mitglieder", - "diejenigen", - "experiment", - "versichere", - "überwachen", - "einsteigen", - "schüchtern", - "akzeptiert", - "königreich", - "kofferraum", - "geständnis", - "aufmerksam", - "entführung", - "ausgesetzt", - "generation", - "ausrichten", - "gefälligst", - "entscheide", - "bewusstlos", - "vermasselt", - "explodiert", - "verzichten", - "ohnmächtig", - "betrachtet", - "verhungern", - "versuchten", - "heilmittel", - "gestritten", - "übernommen", - "verspätung", - "übertragen", - "kompliment", - "mannschaft", - "dankeschön", - "eingesetzt", - "durchgehen", - "psychiater", - "entfernung", - "aufgehoben", - "besprochen", - "beunruhigt", - "öffentlich", - "verhältnis", - "ereignisse", - "verprügelt", - "geschworen", - "abgenommen", - "geschieden", - "wettbewerb", - "verfassung", - "quietschen", - "menschlich", - "eigenartig", - "beschädigt", - "grundstück", - "sauerstoff", - "angesichts", - "zerstörung", - "atmosphäre", - "schießerei", - "gemeinsame", - "verbessern", - "diskussion", - "natürlich", - "vergessen", - "schwester", - "verstehen", - "überhaupt", - "versuchen", - "verlassen", - "glücklich", - "irgendwie", - "irgendwas", - "verlieren", - "verstehst", - "vertrauen", - "geschafft", - "getroffen", - "nachricht", - "angerufen", - "schlüssel", - "passieren", - "gefängnis", - "schreiben", - "millionen", - "besonders", - "großartig", - "umbringen", - "gestorben", - "geschehen", - "schneller", - "unmöglich", - "verdammte", - "plötzlich", - "verkaufen", - "geschickt", - "unterwegs", - "niemanden", - "arschloch", - "schlimmer", - "erinnerst", - "wunderbar", - "unbedingt", - "kontrolle", - "zumindest", - "gestohlen", - "beziehung", - "versteckt", - "erreichen", - "verändert", - "professor", - "geheimnis", - "regierung", - "erledigen", - "gegenüber", - "richtigen", - "schlechte", - "antworten", - "präsident", - "detective", - "aufhalten", - "überleben", - "schicksal", - "vergnügen", - "situation", - "niemandem", - "zerstören", - "gemeinsam", - "furchtbar", - "verzeihen", - "mitnehmen", - "schwanger", - "verhaftet", - "zufrieden", - "schließen", - "fernsehen", - "schwierig", - "verdienen", - "betrunken", - "patienten", - "verhalten", - "interesse", - "frühstück", - "aufpassen", - "zeitpunkt", - "entkommen", - "gebrochen", - "mitkommen", - "ernsthaft", - "operation", - "schmerzen", - "erfahrung", - "commander", - "großvater", - "getrunken", - "behandelt", - "überlegen", - "schwarzen", - "beruhigen", - "geschieht", - "versuchte", - "abgesehen", - "geschäfte", - "überzeugt", - "arbeitest", - "geblieben", - "wichtiger", - "verfolgen", - "entlassen", - "spannende", - "erklärung", - "verlangen", - "außerhalb", - "aufstehen", - "gebraucht", - "nirgendwo", - "einfacher", - "schweigen", - "krankheit", - "verflucht", - "elizabeth", - "behandeln", - "passierte", - "erwachsen", - "derjenige", - "gentlemen", - "schnappen", - "flughafen", - "deutschen", - "begleiten", - "weiterhin", - "übersetzt", - "verrückte", - "botschaft", - "aufgeregt", - "irgendein", - "gegenteil", - "schwimmen", - "innerhalb", - "verletzen", - "verändern", - "definitiv", - "ebenfalls", - "überprüft", - "jederzeit", - "probieren", - "aufmachen", - "erlaubnis", - "verhaften", - "schönheit", - "existiert", - "gezwungen", - "verbunden", - "aufgehört", - "herkommen", - "angesehen", - "vorschlag", - "vermissen", - "riskieren", - "arbeitete", - "hinterher", - "verpassen", - "praktisch", - "versuchst", - "bedeutung", - "fernseher", - "offiziell", - "geschmack", - "charlotte", - "loswerden", - "bestätigt", - "übergeben", - "abteilung", - "inspektor", - "richtiger", - "aufnehmen", - "geschenkt", - "behauptet", - "kilometer", - "angeblich", - "spazieren", - "eindeutig", - "explosion", - "neugierig", - "wichtiges", - "einladung", - "verbracht", - "behaupten", - "aufregend", - "beschützt", - "entfernen", - "abgehauen", - "abgemacht", - "empfangen", - "scheidung", - "verwenden", - "aufwachen", - "verfügung", - "abenteuer", - "übernehme", - "bestellen", - "universum", - "geschenke", - "loslassen", - "berichten", - "verbrannt", - "klamotten", - "angreifen", - "schneiden", - "catherine", - "ausziehen", - "pünktlich", - "besondere", - "umständen", - "folgendes", - "erwischen", - "schlimmes", - "erscheint", - "angezogen", - "zigarette", - "hauptmann", - "identität", - "angelogen", - "verdienst", - "langsamer", - "bedrohung", - "einkaufen", - "nachsehen", - "verwendet", - "gekümmert", - "francisco", - "vermeiden", - "miststück", - "abgelehnt", - "abmachung", - "verbergen", - "reingehen", - "korrektur", - "rausholen", - "angeboten", - "belohnung", - "hurensohn", - "scheinbar", - "abschluss", - "bezweifle", - "versprich", - "gentleman", - "diamanten", - "anschauen", - "einfallen", - "kommissar", - "exzellenz", - "schuldest", - "womöglich", - "repariert", - "gestanden", - "maschinen", - "bekämpfen", - "verbinden", - "zeitungen", - "notwendig", - "höchstens", - "übersehen", - "spielchen", - "gesichter", - "anzeichen", - "keinerlei", - "ruinieren", - "unhöflich", - "anzurufen", - "derselben", - "mitmachen", - "reagieren", - "hinsetzen", - "erschöpft", - "vergleich", - "großzügig", - "einheiten", - "wichtigen", - "verärgert", - "unwichtig", - "franzosen", - "beleidigt", - "anstellen", - "beteiligt", - "hollywood", - "gefangene", - "alexander", - "diejenige", - "lieferung", - "studieren", - "christian", - "bewaffnet", - "amüsieren", - "weglaufen", - "vergiftet", - "president", - "schwarzer", - "schmutzig", - "liebhaber", - "verfahren", - "inspector", - "spielzeug", - "schreibst", - "aktiviert", - "hilfreich", - "jahrelang", - "denselben", - "widerlich", - "parkplatz", - "sozusagen", - "aufnahmen", - "gegenwart", - "protokoll", - "studenten", - "schmecken", - "ansonsten", - "gewünscht", - "möglichen", - "apartment", - "dieselben", - "interview", - "einzelnen", - "getrieben", - "bestimmte", - "laufenden", - "auftaucht", - "sebastian", - "vertragen", - "tradition", - "fähigkeit", - "attraktiv", - "mitteilen", - "gemütlich", - "versprach", - "verlierst", - "einsetzen", - "übernimmt", - "ausmachen", - "gesichert", - "begreifen", - "bezüglich", - "aufregung", - "bestimmen", - "geliebten", - "irgendwer", - "gewachsen", - "verlaufen", - "wegnehmen", - "benötigen", - "bestrafen", - "patientin", - "anzusehen", - "brauchten", - "engländer", - "September", - "bestanden", - "schluchzt", - "friedlich", - "richtiges", - "zuschauer", - "geliefert", - "lediglich", - "charakter", - "geräusche", - "befürchte", - "entdecken", - "loyalität", - "vertreten", - "verlierer", - "gelächter", - "einspruch", - "rausgehen", - "geleistet", - "fröhliche", - "verderben", - "blutdruck", - "aufgebaut", - "trainiert", - "zwillinge", - "erwartest", - "gründlich", - "vertraust", - "christine", - "testament", - "regisseur", - "zuständig", - "gespräche", - "vergebung", - "gefesselt", - "eventuell", - "entspannt", - "anständig", - "endgültig", - "zustimmen", - "katherine", - "vorfahren", - "aussuchen", - "fabelhaft", - "gestatten", - "ausgelöst", - "verarscht", - "werkstatt", - "überreden", - "bewundere", - "angeklagt", - "verlieben", - "tabletten", - "auftreten", - "dschungel", - "dokumente", - "schachtel", - "diebstahl", - "gegensatz", - "schultern", - "wirklich", - "passiert", - "menschen", - "zusammen", - "brauchen", - "sprechen", - "gefunden", - "verdammt", - "verstehe", - "bekommen", - "bisschen", - "arbeiten", - "verrückt", - "jemanden", - "ziemlich", - "solltest", - "verloren", - "versucht", - "gekommen", - "bedeutet", - "wahrheit", - "bestimmt", - "gefallen", - "manchmal", - "zwischen", - "freundin", - "erzählen", - "schlecht", - "schlafen", - "brauchst", - "nächsten", - "schaffen", - "trotzdem", - "geworden", - "wolltest", - "deswegen", - "erinnern", - "probleme", - "könntest", - "aufhören", - "richtige", - "versuche", - "heiraten", - "gebracht", - "erklären", - "gegangen", - "irgendwo", - "genommen", - "außerdem", - "verletzt", - "erfahren", - "möchtest", - "schicken", - "erwartet", - "geschäft", - "verdient", - "erinnere", - "arbeitet", - "liebling", - "behalten", - "anfangen", - "gewinnen", - "bezahlen", - "gerettet", - "bescheid", - "gedanken", - "bewegung", - "jemandem", - "wünschte", - "monsieur", - "hochzeit", - "benutzen", - "erledigt", - "gewonnen", - "chffffff", - "sekunden", - "schießen", - "beispiel", - "dasselbe", - "schlagen", - "vorsicht", - "beweisen", - "vermisst", - "richtung", - "geschenk", - "nächstes", - "verliebt", - "erwischt", - "verkauft", - "erwarten", - "majestät", - "aussehen", - "verraten", - "computer", - "ermordet", - "entfernt", - "zerstört", - "übrigens", - "hoffnung", - "flugzeug", - "entweder", - "schuldig", - "schützen", - "besuchen", - "erhalten", - "soldaten", - "gelassen", - "gefahren", - "verstand", - "erkennen", - "gegessen", - "geholfen", - "aussieht", - "beginnen", - "ungefähr", - "falschen", - "sergeant", - "erinnert", - "schlampe", - "bedeuten", - "gespielt", - "planeten", - "versteht", - "besorgen", - "klingelt", - "position", - "gleichen", - "gefangen", - "gewartet", - "zufällig", - "freunden", - "verpasst", - "wusstest", - "freiheit", - "geändert", - "schätzen", - "gespräch", - "schreien", - "polizist", - "konntest", - "maschine", - "bekommst", - "offenbar", - "gestellt", - "wünschen", - "gelaufen", - "schwarze", - "wahnsinn", - "gehalten", - "vorwärts", - "besseres", - "fräulein", - "brauchte", - "schaffst", - "deutsche", - "dringend", - "gewissen", - "erreicht", - "sprichst", - "einzigen", - "schmeckt", - "entdeckt", - "verfolgt", - "weiteren", - "vertraut", - "aufgeben", - "entführt", - "mistkerl", - "erzählte", - "verlangt", - "beruhige", - "direktor", - "karriere", - "kollegen", - "scheinen", - "woanders", - "geglaubt", - "gefeuert", - "schreibt", - "schulden", - "peinlich", - "überlebt", - "blödsinn", - "schatten", - "tatsache", - "hingehen", - "verboten", - "getrennt", - "programm", - "nachbarn", - "verlässt", - "vergeben", - "ausgehen", - "toilette", - "annehmen", - "genießen", - "erlauben", - "zulassen", - "komplett", - "einander", - "streiten", - "verliert", - "betrifft", - "immerhin", - "englisch", - "vermisse", - "überlegt", - "rechnung", - "dieselbe", - "familien", - "lebendig", - "heiligen", - "geöffnet", - "begraben", - "wichtige", - "leichter", - "priester", - "schreibe", - "anhalten", - "anziehen", - "ertragen", - "vertraue", - "entspann", - "eindruck", - "herrgott", - "springen", - "befreien", - "perfekte", - "erzählst", - "gekriegt", - "schnauze", - "sprachen", - "verräter", - "bestellt", - "deutlich", - "verwirrt", - "ch00ffff", - "schritte", - "gemeldet", - "befindet", - "ruiniert", - "jonathan", - "kleidung", - "besseren", - "dahinter", - "anführer", - "minister", - "personen", - "publikum", - "wechseln", - "begegnet", - "betrogen", - "geworfen", - "versteck", - "beruhigt", - "schlange", - "anfassen", - "beeilung", - "schließt", - "schläfst", - "schickte", - "mitglied", - "einziger", - "vermögen", - "befinden", - "internet", - "superman", - "kommando", - "erfunden", - "geträumt", - "caroline", - "musstest", - "liebsten", - "schlacht", - "offizier", - "verliere", - "tausende", - "begonnen", - "gelandet", - "vergisst", - "aufgrund", - "momentan", - "meistens", - "stimmung", - "geräusch", - "künstler", - "schweine", - "schulter", - "anbieten", - "dachtest", - "feigling", - "einladen", - "marshall", - "schenken", - "realität", - "schwerer", - "benehmen", - "verdacht", - "hübsches", - "einziges", - "schnappt", - "besitzer", - "michelle", - "besessen", - "bewahren", - "gekämpft", - "antworte", - "gesteckt", - "erfüllen", - "einfluss", - "weiteres", - "bereiten", - "besiegen", - "dienstag", - "fürchten", - "training", - "schönste", - "bestraft", - "bestehen", - "ewigkeit", - "hässlich", - "ausruhen", - "umstände", - "reaktion", - "reagiert", - "studiert", - "auftritt", - "begangen", - "geliebte", - "verlasse", - "umdrehen", - "lehrerin", - "zentrale", - "brachten", - "berühren", - "rückkehr", - "indianer", - "kindheit", - "aussagen", - "jungfrau", - "einfache", - "seltsame", - "heiratet", - "angenehm", - "nächster", - "betreten", - "aufnahme", - "hübscher", - "stellung", - "mögliche", - "sicherer", - "christus", - "dummkopf", - "gerüchte", - "gekostet", - "ergebnis", - "verdiene", - "weswegen", - "nützlich", - "vergesse", - "gemeinde", - "traurige", - "kürzlich", - "material", - "bereitet", - "fantasie", - "begrüßen", - "arbeiter", - "weggehen", - "original", - "hunderte", - "versetzt", - "heiliger", - "besitzen", - "darunter", - "derselbe", - "munition", - "geklappt", - "erwähnen", - "berichte", - "umziehen", - "zunächst", - "john-boy", - "getragen", - "tauschen", - "gedauert", - "reporter", - "schalten", - "gewöhnen", - "schieben", - "zweitens", - "verlange", - "spanisch", - "herzlich", - "besucher", - "scheiden", - "köstlich", - "russland", - "gesamten", - "geflogen", - "überfall", - "wehgetan", - "schwäche", - "ausdruck", - "schlimme", - "heutigen", - "heimlich", - "eingehen", - "williams", - "umgebung", - "vergesst", - "hinweise", - "ausreden", - "herrscht", - "flüstert", - "bedanken", - "scheisse", - "versehen", - "albtraum", - "margaret", - "personal", - "therapie", - "leutnant", - "zauberer", - "abnehmen", - "nirgends", - "ersetzen", - "jennifer", - "normaler", - "entgegen", - "schweren", - "behörden", - "mittwoch", - "abwarten", - "friedhof", - "klienten", - "reverend", - "durchaus", - "motorrad", - "hübschen", - "paradies", - "tagebuch", - "jenseits", - "macgyver", - "normalen", - "aussicht", - "victoria", - "bedenken", - "sicheren", - "verkaufe", - "abgeholt", - "abhalten", - "gebissen", - "geheimen", - "komische", - "einzelne", - "sandwich", - "gewinner", - "scheinst", - "pflanzen", - "müsstest", - "betrüger", - "chinesen", - "verteilt", - "bewiesen", - "ausnahme", - "herrlich", - "ankommen", - "falsches", - "täuschen", - "befragen", - "abschied", - "clarence", - "gestehen", - "religion", - "zugehört", - "vorhaben", - "existenz", - "drehbuch", - "football", - "virginia", - "verzeiht", - "fahrzeug", - "genossen", - "probiert", - "teenager", - "weiterer", - "flaschen", - "einbruch", - "versagen", - "riesigen", - "erkennst", - "benjamin", - "erledige", - "gesessen", - "gerissen", - "befohlen", - "überlege", - "hinlegen", - "geflohen", - "nebenbei", - "ausgeben", - "schwören", - "hühnchen", - "betrügen", - "schlägst", - "gestoßen", - "tragödie", - "verlegen", - "vielmals", - "losgehen", - "brillant", - "vorgehen", - "schnelle", - "normales", - "ekelhaft", - "gelangen", - "gespannt", - "vernunft", - "klingeln", - "gangster", - "aufgaben", - "blödmann", - "symptome", - "nochmals", - "sherlock", - "leistung", - "mitchell", - "eröffnen", - "unschuld", - "genügend", - "bräuchte", - "schließe", - "schläger", - "ausmacht", - "versager", - "charmant", - "aufbauen", - "samantha", - "begegnen", - "krawatte", - "gelöscht", - "niedlich", - "anwältin", - "fröhlich", - "eigentum", - "frühling", - "vergehen" - ] -} diff --git a/packages/yoastseo/src/languageProcessing/languages/de/config/wordComplexity.js b/packages/yoastseo/src/languageProcessing/languages/de/config/wordComplexity.js index 5f6d8045955..4254ece9c0f 100644 --- a/packages/yoastseo/src/languageProcessing/languages/de/config/wordComplexity.js +++ b/packages/yoastseo/src/languageProcessing/languages/de/config/wordComplexity.js @@ -1,7 +1,4 @@ -import frequencyList from "./internal/frequencyList.json"; - // This is a config for the Word Complexity assessment. As such, this helper is not bundled in Yoast SEO. export default { - frequencyList: frequencyList.list, wordLength: 10, }; diff --git a/packages/yoastseo/src/languageProcessing/languages/de/helpers/checkIfWordIsComplex.js b/packages/yoastseo/src/languageProcessing/languages/de/helpers/checkIfWordIsComplex.js index 40679ebf83b..387fe5fa6f5 100644 --- a/packages/yoastseo/src/languageProcessing/languages/de/helpers/checkIfWordIsComplex.js +++ b/packages/yoastseo/src/languageProcessing/languages/de/helpers/checkIfWordIsComplex.js @@ -5,18 +5,19 @@ const suffixesRegex = new RegExp( suffixes ); * Checks if a word is complex. * This is a helper for the Word Complexity assessment. As such, this helper is not bundled in Yoast SEO. * - * @param {object} config The configuration needed for assessing the word's complexity, e.g., the frequency list. - * @param {string} word The word to check. + * @param {object} config The configuration needed for assessing the word's complexity, e.g., the frequency list. + * @param {string} word The word to check. + * @param {object} premiumData The object that contains data for the assessment including the frequency list. * * @returns {boolean} Whether or not a word is complex. */ -export default function checkIfWordIsComplex( config, word ) { +export default function checkIfWordIsComplex( config, word, premiumData ) { const lengthLimit = config.wordLength; - const frequencyList = config.frequencyList; + const frequencyList = premiumData.frequencyList.list; // All words are converted to lower case before processing to avoid excluding complex words that start with a capital letter. word = word.toLowerCase(); - // The German word is not complex if its length is 10 characters or less. + // The German word is not complex if its length is 10 characters or fewer. if ( word.length <= lengthLimit ) { return false; } diff --git a/packages/yoastseo/src/languageProcessing/languages/en/config/functionWords.js b/packages/yoastseo/src/languageProcessing/languages/en/config/functionWords.js index 2a71b291470..41bb6d5bdb5 100644 --- a/packages/yoastseo/src/languageProcessing/languages/en/config/functionWords.js +++ b/packages/yoastseo/src/languageProcessing/languages/en/config/functionWords.js @@ -53,7 +53,7 @@ const prepositions = [ "in", "from", "with", "under", "throughout", "atop", "for "among", "apropos", "apud", "around", "as", "astride", "at", "ontop", "afore", "tofore", "behind", "ahind", "below", "ablow", "beneath", "neath", "beside", "between", "atween", "beyond", "ayond", "by", "chez", "circa", "spite", "down", "except", "into", "less", "like", "minus", "near", "nearer", "nearest", "anear", "notwithstanding", - "off", "onto", "opposite", "out", "outen", "over", "past", "per", "pre", "qua", "sans", "sauf", "sithence", "through", + "off", "onto", "opposite", "out", "outen", "over", "past", "per", "pre", "qua", "sans", "sithence", "through", "thru", "truout", "toward", "underneath", "up", "upon", "upside", "versus", "via", "vis-à-vis", "without", "ago", "apart", "aside", "aslant", "away", "withal", "towards", "amidst", "amongst", "midst", "whilst" ]; diff --git a/packages/yoastseo/src/languageProcessing/languages/en/config/internal/frequencyList.json b/packages/yoastseo/src/languageProcessing/languages/en/config/internal/frequencyList.json deleted file mode 100644 index 8cca7b791ab..00000000000 --- a/packages/yoastseo/src/languageProcessing/languages/en/config/internal/frequencyList.json +++ /dev/null @@ -1,2093 +0,0 @@ -{ - "source": "This list is taken from roughly the first 5000 words of this word list https://github.com/hermitdave/FrequencyWords/blob/master/content/2018/en/en_50k.txt. Some clean ups were also done, e.g. to remove pronouns", - "list": [ - "misunderstanding", - "congratulations", - "daughter-in-law", - "responsibility", - "brother-in-law", - "investigation", - "unfortunately", - "circumstances", - "understanding", - "international", - "extraordinary", - "uncomfortable", - "investigating", - "communication", - "entertainment", - "automatically", - "distinguished", - "relationship", - "conversation", - "professional", - "neighborhood", - "unbelievable", - "intelligence", - "disappointed", - "embarrassing", - "commissioner", - "construction", - "surveillance", - "headquarters", - "organization", - "instructions", - "consequences", - "fingerprints", - "indistinctly", - "thanksgiving", - "announcement", - "photographer", - "arrangements", - "instrumental", - "accidentally", - "conservative", - "psychologist", - "jurisdiction", - "supernatural", - "compensation", - "distribution", - "architecture", - "contribution", - "experiencing", - "unacceptable", - "appreciation", - "high-pitched", - "introduction", - "negotiations", - "information", - "interesting", - "responsible", - "opportunity", - "comfortable", - "disappeared", - "grandfather", - "competition", - "complicated", - "appointment", - "grandmother", - "performance", - "coincidence", - "explanation", - "approaching", - "possibility", - "embarrassed", - "considering", - "imagination", - "practically", - "electricity", - "underground", - "temperature", - "concentrate", - "environment", - "anniversary", - "personality", - "intelligent", - "authorities", - "technically", - "investigate", - "threatening", - "destruction", - "fascinating", - "experienced", - "development", - "appropriate", - "transferred", - "differently", - "magnificent", - "description", - "unfortunate", - "necessarily", - "traditional", - "independent", - "forgiveness", - "questioning", - "complaining", - "celebrating", - "celebration", - "unconscious", - "combination", - "communicate", - "application", - "significant", - "alternative", - "association", - "certificate", - "perspective", - "housekeeper", - "exceptional", - "condolences", - "humiliation", - "masterpiece", - "compartment", - "merchandise", - "achievement", - "frustrating", - "preparation", - "understand", - "government", - "interested", - "girlfriend", - "lieutenant", - "impossible", - "appreciate", - "experience", - "department", - "ridiculous", - "sweetheart", - "restaurant", - "incredible", - "indistinct", - "discovered", - "personally", - "permission", - "connection", - "university", - "downstairs", - "television", - "disgusting", - "washington", - "protection", - "friendship", - "technology", - "considered", - "successful", - "chattering", - "conference", - "remembered", - "reputation", - "confidence", - "background", - "whispering", - "revolution", - "impressive", - "threatened", - "production", - "punishment", - "suspicious", - "frightened", - "collection", - "protecting", - "impression", - "mysterious", - "experiment", - "generation", - "attractive", - "pretending", - "surrounded", - "confession", - "incredibly", - "conscience", - "officially", - "determined", - "reasonable", - "atmosphere", - "individual", - "helicopter", - "screeching", - "photograph", - "scientific", - "invitation", - "commercial", - "engagement", - "population", - "resistance", - "possession", - "commission", - "management", - "assignment", - "remarkable", - "ambassador", - "expression", - "basketball", - "appearance", - "foundation", - "introduced", - "prosecutor", - "medication", - "suggesting", - "discussion", - "undercover", - "recognized", - "passengers", - "kidnapping", - "registered", - "investment", - "conspiracy", - "struggling", - "forgetting", - "identified", - "vulnerable", - "excellency", - "physically", - "unexpected", - "whimpering", - "disturbing", - "electronic", - "excitement", - "assistance", - "journalist", - "commitment", - "profession", - "aggressive", - "surprising", - "motorcycle", - "activities", - "controlled", - "conclusion", - "importance", - "destroying", - "authorized", - "exclaiming", - "harassment", - "monitoring", - "stammering", - "celebrated", - "encouraged", - "babysitter", - "programmed", - "discharged", - "playground", - "peacefully", - "disrespect", - "underworld", - "invincible", - "industries", - "unbearable", - "footprints", - "consultant", - "applauding", - "collective", - "complained", - "processing", - "gentlemen", - "wonderful", - "president", - "happening", - "christmas", - "situation", - "dangerous", - "attention", - "detective", - "difficult", - "afternoon", - "screaming", - "boyfriend", - "apartment", - "professor", - "beginning", - "continues", - "listening", - "surprised", - "according", - "breakfast", - "wondering", - "excellent", - "commander", - "apologize", - "inspector", - "emergency", - "operation", - "challenge", - "fantastic", - "character", - "breathing", - "perfectly", - "forgotten", - "concerned", - "condition", - "recognize", - "destroyed", - "brilliant", - "happiness", - "interview", - "expecting", - "gentleman", - "introduce", - "community", - "expensive", - "secretary", - "assistant", - "mentioned", - "telephone", - "insurance", - "political", - "statement", - "delicious", - "knowledge", - "celebrate", - "carefully", - "direction", - "committed", - "chocolate", - "advantage", - "chuckling", - "christian", - "treatment", - "disappear", - "suffering", - "literally", - "desperate", - "convinced", - "announcer", - "champagne", - "elizabeth", - "explosion", - "cigarette", - "sacrifice", - "ambulance", - "equipment", - "searching", - "connected", - "newspaper", - "witnesses", - "education", - "authority", - "nightmare", - "emotional", - "hollywood", - "agreement", - "abandoned", - "guarantee", - "childhood", - "potential", - "committee", - "subtitles", - "impressed", - "sensitive", - "hopefully", - "miserable", - "kidnapped", - "charlotte", - "surrender", - "catherine", - "financial", - "influence", - "footsteps", - "goodnight", - "delivered", - "confirmed", - "principal", - "greetings", - "religious", - "recording", - "answering", - "someplace", - "interrupt", - "satisfied", - "tradition", - "defendant", - "adventure", - "territory", - "developed", - "favourite", - "francisco", - "existence", - "returning", - "confident", - "bothering", - "wednesday", - "policeman", - "precisely", - "underwear", - "traveling", - "signature", - "countries", - "companies", - "represent", - "terrorist", - "procedure", - "furniture", - "transport", - "protected", - "lightning", - "exhausted", - "scientist", - "intention", - "alexander", - "invisible", - "objection", - "separated", - "colleague", - "warehouse", - "honeymoon", - "testimony", - "whistling", - "depressed", - "resources", - "centuries", - "September", - "structure", - "paperwork", - "reception", - "recommend", - "complaint", - "satellite", - "temporary", - "effective", - "forbidden", - "discovery", - "suspected", - "delighted", - "valentine", - "christine", - "terrified", - "preparing", - "executive", - "regarding", - "technique", - "cellphone", - "backwards", - "promotion", - "permanent", - "interfere", - "recovered", - "ancestors", - "completed", - "recognise", - "radiation", - "candidate", - "immediate", - "organized", - "dismissed", - "halloween", - "continued", - "sebastian", - "christina", - "spiritual", - "rehearsal", - "overnight", - "determine", - "practical", - "operating", - "apologies", - "personnel", - "counselor", - "corrected", - "anonymous", - "reporting", - "described", - "attracted", - "believing", - "attacking", - "dedicated", - "corporate", - "requested", - "cooperate", - "worthless", - "relations", - "infection", - "suspended", - "volunteer", - "communist", - "blackmail", - "decorated", - "specially", - "producing", - "inventory", - "long-term", - "imaginary", - "artillery", - "telescope", - "shameless", - "worldwide", - "cafeteria", - "amsterdam", - "monastery", - "impatient", - "ignorance", - "predicted", - "civilized", - "competing", - "voiceover", - "carpenter", - "upsetting", - "narcotics", - "foreigner", - "travelled", - "microwave", - "groceries", - "imitating", - "informant", - "fantasies", - "fisherman", - "nightclub", - "overheard", - "happened", - "remember", - "together", - "business", - "thinking", - "daughter", - "children", - "supposed", - "question", - "chuckles", - "laughing", - "hospital", - "straight", - "speaking", - "building", - "watching", - "evidence", - "birthday", - "security", - "terrible", - "anywhere", - "finished", - "marriage", - "american", - "surprise", - "accident", - "personal", - "fighting", - "standing", - "starting", - "position", - "pleasure", - "involved", - "continue", - "decision", - "sleeping", - "laughter", - "computer", - "promised", - "suddenly", - "drinking", - "director", - "innocent", - "narrator", - "grunting", - "upstairs", - "sergeant", - "pregnant", - "favorite", - "applause", - "pressure", - "interest", - "bathroom", - "shooting", - "consider", - "military", - "cheering", - "princess", - "language", - "bullshit", - "shouting", - "murdered", - "possibly", - "powerful", - "practice", - "national", - "minister", - "bringing", - "strength", - "greatest", - "arrested", - "horrible", - "planning", - "breaking", - "nonsense", - "training", - "prepared", - "criminal", - "honestly", - "original", - "research", - "mountain", - "audience", - "universe", - "believed", - "realized", - "followed", - "distance", - "property", - "received", - "handsome", - "saturday", - "expected", - "medicine", - "returned", - "contract", - "good-bye", - "football", - "japanese", - "exciting", - "painting", - "murderer", - "goodness", - "memories", - "knocking", - "groaning", - "romantic", - "familiar", - "attacked", - "positive", - "attorney", - "families", - "location", - "changing", - "carrying", - "official", - "confused", - "checking", - "physical", - "shopping", - "midnight", - "vacation", - "violence", - "bleeding", - "grateful", - "treasure", - "governor", - "stronger", - "throwing", - "stealing", - "dramatic", - "properly", - "stranger", - "presence", - "internet", - "monsieur", - "precious", - "material", - "released", - "exchange", - "convince", - "ordinary", - "creature", - "separate", - "cleaning", - "darkness", - "solution", - "schedule", - "prisoner", - "progress", - "campaign", - "reporter", - "magazine", - "incident", - "sentence", - "friendly", - "charming", - "spending", - "learning", - "elevator", - "shoulder", - "highness", - "sometime", - "attitude", - "negative", - "gorgeous", - "movement", - "politics", - "approach", - "normally", - "growling", - "studying", - "entirely", - "accepted", - "district", - "disaster", - "terrific", - "identity", - "delivery", - "teaching", - "counting", - "behavior", - "pathetic", - "struggle", - "stopping", - "swimming", - "basement", - "transfer", - "cheating", - "sandwich", - "thursday", - "baseball", - "customer", - "terribly", - "reaction", - "ceremony", - "offering", - "suffered", - "reported", - "entrance", - "designed", - "neighbor", - "dreaming", - "enjoying", - "arranged", - "survived", - "champion", - "lifetime", - "margaret", - "describe", - "homework", - "betrayed", - "industry", - "coughing", - "religion", - "exercise", - "touching", - "division", - "valuable", - "standard", - "response", - "argument", - "everyday", - "generous", - "mistress", - "whispers", - "identify", - "michelle", - "divorced", - "doorbell", - "patience", - "visiting", - "electric", - "pleasant", - "starving", - "election", - "festival", - "jonathan", - "freaking", - "dropping", - "downtown", - "paradise", - "meantime", - "activity", - "jennifer", - "annoying", - "judgment", - "answered", - "chairman", - "mistaken", - "virginia", - "worrying", - "captured", - "occasion", - "invented", - "complain", - "listened", - "wondered", - "passport", - "homicide", - "discover", - "farewell", - "informed", - "humanity", - "producer", - "stubborn", - "gambling", - "absolute", - "marrying", - "increase", - "whirring", - "reverend", - "williams", - "engineer", - "caroline", - "punished", - "imagined", - "necklace", - "southern", - "supplies", - "strategy", - "compared", - "headache", - "internal", - "peaceful", - "talented", - "elephant", - "guessing", - "dressing", - "attached", - "required", - "victoria", - "fabulous", - "survival", - "tracking", - "maintain", - "recorded", - "marshall", - "critical", - "creating", - "scotland", - "enormous", - "covering", - "occurred", - "catching", - "facility", - "clicking", - "superior", - "potatoes", - "ultimate", - "obsessed", - "russians", - "freezing", - "rumbling", - "function", - "homeless", - "treating", - "entering", - "proposal", - "searched", - "blessing", - "bothered", - "catholic", - "creative", - "sticking", - "constant", - "analysis", - "employee", - "suitcase", - "chemical", - "advanced", - "chirping", - "sunshine", - "contrary", - "gathered", - "crossing", - "intended", - "delicate", - "grandson", - "weakness", - "european", - "northern", - "audition", - "chanting", - "superman", - "admitted", - "poisoned", - "inspired", - "crashing", - "assuming", - "guardian", - "immunity", - "priority", - "November", - "conflict", - "register", - "deserved", - "belonged", - "franklin", - "splendid", - "announce", - "borrowed", - "alliance", - "clothing", - "relative", - "produced", - "directed", - "republic", - "threaten", - "mitchell", - "document", - "elements", - "injuries", - "revealed", - "infected", - "relieved", - "adorable", - "floating", - "insisted", - "operator", - "anderson", - "roommate", - "giggling", - "hercules", - "faithful", - "cemetery", - "corporal", - "realised", - "hopeless", - "symptoms", - "aircraft", - "defeated", - "envelope", - "assigned", - "climbing", - "replaced", - "arriving", - "kindness", - "boarding", - "creation", - "affected", - "imperial", - "congress", - "recovery", - "handling", - "designer", - "glorious", - "executed", - "addition", - "gasoline", - "juliette", - "balloons", - "crawford", - "resolved", - "attended", - "employed", - "parallel", - "detected", - "coverage", - "macgyver", - "comedian", - "smashing", - "addicted", - "speeches", - "recorder", - "estimate", - "pentagon", - "contempt", - "speeding", - "bankrupt", - "marianne", - "slippery", - "numerous", - "currency", - "souvenir", - "stitches", - "referred", - "medieval", - "employer", - "slippers", - "repeated", - "apparent", - "rehearse", - "juvenile", - "breeding", - "settling", - "squadron", - "devotion", - "briefing", - "heritage", - "historic", - "thought", - "believe", - "talking", - "looking", - "morning", - "brother", - "tonight", - "problem", - "working", - "exactly", - "waiting", - "husband", - "married", - "started", - "playing", - "trouble", - "brought", - "welcome", - "telling", - "outside", - "country", - "captain", - "feeling", - "leaving", - "running", - "alright", - "promise", - "perfect", - "serious", - "company", - "control", - "happens", - "meeting", - "evening", - "calling", - "careful", - "changed", - "picture", - "darling", - "amazing", - "worried", - "goodbye", - "missing", - "wedding", - "strange", - "general", - "kidding", - "decided", - "officer", - "mistake", - "suppose", - "forgive", - "imagine", - "clothes", - "michael", - "history", - "station", - "forever", - "message", - "protect", - "sitting", - "present", - "quickly", - "wearing", - "stopped", - "america", - "bastard", - "service", - "killing", - "respect", - "english", - "private", - "realize", - "machine", - "walking", - "college", - "teacher", - "contact", - "driving", - "village", - "singing", - "support", - "partner", - "colonel", - "holding", - "patient", - "kitchen", - "address", - "nervous", - "mission", - "allowed", - "learned", - "arrived", - "destroy", - "chicken", - "helping", - "witness", - "writing", - "mention", - "figured", - "ringing", - "written", - "reading", - "excited", - "suspect", - "medical", - "majesty", - "deserve", - "goddamn", - "weekend", - "willing", - "justice", - "knowing", - "correct", - "grandma", - "hanging", - "somehow", - "hearing", - "account", - "manager", - "natural", - "dancing", - "freedom", - "dropped", - "student", - "breathe", - "monster", - "dressed", - "checked", - "noticed", - "project", - "example", - "science", - "grandpa", - "chinese", - "survive", - "sweetie", - "suicide", - "invited", - "discuss", - "nowhere", - "sheriff", - "turning", - "jealous", - "pretend", - "society", - "finding", - "meaning", - "release", - "prepare", - "opinion", - "soldier", - "program", - "command", - "selling", - "created", - "british", - "england", - "purpose", - "opening", - "falling", - "suggest", - "process", - "surgery", - "ancient", - "ordered", - "spanish", - "weather", - "covered", - "russian", - "sending", - "heading", - "silence", - "success", - "journey", - "stomach", - "divorce", - "funeral", - "reality", - "subject", - "growing", - "beeping", - "revenge", - "yelling", - "foreign", - "century", - "planned", - "warning", - "bedroom", - "defense", - "fortune", - "reached", - "burning", - "airport", - "pleased", - "ashamed", - "glasses", - "request", - "useless", - "deliver", - "offered", - "panting", - "watched", - "dealing", - "mystery", - "picking", - "traffic", - "courage", - "italian", - "disease", - "managed", - "council", - "healthy", - "victory", - "touched", - "license", - "cooking", - "concern", - "factory", - "central", - "miracle", - "beating", - "capable", - "passing", - "chatter", - "vehicle", - "illegal", - "pulling", - "curious", - "holiday", - "surface", - "hunting", - "germany", - "winning", - "popular", - "escaped", - "someday", - "smoking", - "treated", - "uniform", - "carried", - "receive", - "section", - "destiny", - "parking", - "staring", - "unusual", - "trapped", - "closing", - "emperor", - "leading", - "engaged", - "warrant", - "kingdom", - "fishing", - "gasping", - "collect", - "passion", - "gunshot", - "thunder", - "sobbing", - "alcohol", - "provide", - "fashion", - "episode", - "wanting", - "library", - "failure", - "hitting", - "knocked", - "beloved", - "federal", - "senator", - "robbery", - "theater", - "patrick", - "settled", - "garbage", - "blowing", - "pushing", - "ability", - "culture", - "custody", - "attempt", - "cutting", - "barking", - "violent", - "wasting", - "heavily", - "perform", - "advance", - "quietly", - "hurting", - "capital", - "whistle", - "chasing", - "massive", - "species", - "trusted", - "channel", - "quarter", - "article", - "accused", - "quality", - "greater", - "rolling", - "confess", - "unknown", - "crossed", - "package", - "trained", - "express", - "tuesday", - "refused", - "assault", - "charity", - "balance", - "nuclear", - "entered", - "degrees", - "network", - "version", - "concert", - "diamond", - "wounded", - "anytime", - "plastic", - "comfort", - "arrange", - "comrade", - "kissing", - "classic", - "selfish", - "therapy", - "servant", - "painful", - "drawing", - "realise", - "torture", - "blessed", - "removed", - "crystal", - "confirm", - "scratch", - "contest", - "distant", - "charged", - "begging", - "trigger", - "frankly", - "enjoyed", - "smiling", - "product", - "vampire", - "routine", - "related", - "sounded", - "proceed", - "landing", - "traitor", - "foolish", - "costume", - "injured", - "digging", - "awkward", - "cleaned", - "pattern", - "russell", - "western", - "warrior", - "complex", - "replace", - "unhappy", - "cleared", - "benefit", - "apology", - "comment", - "testing", - "shelter", - "prevent", - "anthony", - "buzzing", - "produce", - "laundry", - "actress", - "footage", - "monitor", - "wailing", - "fantasy", - "moaning", - "slipped", - "offense", - "citizen", - "messing", - "cheated", - "extreme", - "profile", - "theatre", - "intense", - "respond", - "tragedy", - "session", - "capture", - "stretch", - "grabbed", - "shocked", - "academy", - "succeed", - "joining", - "chamber", - "romance", - "jumping", - "testify", - "studied", - "loyalty", - "serving", - "surgeon", - "typical", - "kicking", - "dragged", - "rubbish", - "helpful", - "fighter", - "highway", - "liberty", - "thirsty", - "humming", - "painted", - "whiskey", - "eternal", - "dreamed", - "naughty", - "stabbed", - "sharing", - "propose", - "arguing", - "connect", - "admiral", - "disturb", - "hostage", - "causing", - "banging", - "happily", - "exposed", - "shaking", - "feeding", - "awfully", - "stepped", - "goddess", - "anxious", - "musical", - "payment", - "squeeze", - "magical", - "madness", - "battery", - "dessert", - "visited", - "halfway", - "abandon", - "concept", - "measure", - "privacy", - "chapter", - "recover", - "sighing", - "retired", - "various", - "counter", - "illness", - "require", - "washing", - "achieve", - "gravity", - "damaged", - "assumed", - "operate", - "wrapped", - "focused", - "blanket", - "limited", - "praying", - "gunfire", - "shining", - "marshal", - "massage", - "raising", - "mexican", - "packing", - "swallow", - "conduct", - "reverse", - "heather", - "leather", - "closely", - "happier", - "laughed", - "honking", - "raining", - "explode", - "closest", - "develop", - "retreat", - "muffled", - "jewelry", - "luggage", - "lighter", - "approve", - "roaring", - "arrival", - "scandal", - "shooter", - "instant", - "counsel", - "dignity", - "economy", - "impress", - "supreme", - "mankind", - "vietnam", - "cocaine", - "handled", - "deposit", - "autopsy", - "lecture", - "include", - "spotted", - "located", - "eastern", - "planted", - "visitor", - "protest", - "embrace", - "emotion", - "crushed", - "content", - "luckily", - "crashed", - "embassy", - "defence", - "cabinet", - "display", - "drowned", - "filming", - "penalty", - "bargain", - "speaker", - "compare", - "african", - "honored", - "storage", - "smarter", - "existed", - "primary", - "adopted", - "trailer", - "teenage", - "perfume", - "gallery", - "stuffed", - "improve", - "tension", - "twisted", - "martial", - "signing", - "filling", - "observe", - "psychic", - "pacific", - "fooling", - "athlete", - "convent", - "colored", - "dismiss", - "slavery", - "pyramid", - "rebuild", - "trumpet", - "matched", - "tougher", - "portion", - "despise", - "licence", - "impulse", - "penguin", - "cartoon", - "bidding", - "confuse", - "bathtub", - "lifting", - "scooter", - "brigade", - "lookout", - "ripping", - "glimpse", - "founded", - "compass", - "mercury", - "locking", - "dislike", - "denying", - "recruit", - "creator", - "dynamic", - "deceive", - "heating", - "advisor", - "tractor", - "plumber", - "promote", - "stalker", - "people", - "father", - "course", - "mother", - "listen", - "family", - "pretty", - "school", - "police", - "excuse", - "doctor", - "forget", - "change", - "happen", - "inside", - "afraid", - "chance", - "anyway", - "number", - "moment", - "sister", - "reason", - "office", - "couple", - "answer", - "stupid", - "dinner", - "murder", - "street", - "follow", - "master", - "coffee", - "return", - "secret", - "future", - "wonder", - "figure", - "strong", - "report", - "choice", - "finish", - "system", - "attack", - "expect", - "lovely", - "handle", - "middle", - "bought", - "letter", - "single", - "forgot", - "ground", - "charge", - "prison", - "record", - "public", - "killer", - "church", - "camera", - "honest", - "window", - "hungry", - "bloody", - "french", - "accept", - "lawyer", - "island", - "victim", - "christ", - "planet", - "search", - "arrest", - "summer", - "escape", - "choose", - "decide", - "bother", - "heaven", - "action", - "notice", - "london", - "battle", - "guilty", - "energy", - "prince", - "throat", - "hiding", - "engine", - "double", - "spirit", - "danger", - "memory", - "closer", - "flight", - "nature", - "client", - "bottle", - "famous", - "asleep", - "beauty", - "driver", - "common", - "german", - "corner", - "fellow", - "leader", - "health", - "advice", - "hardly", - "cousin", - "pardon", - "career", - "taught", - "breath", - "market", - "bridge", - "center", - "travel", - "target", - "belong", - "credit", - "strike", - "ticket", - "prefer", - "create", - "afford", - "france", - "social", - "bullet", - "season", - "shower", - "lonely", - "forced", - "settle", - "weight", - "slowly", - "member", - "garden", - "finger", - "access", - "insane", - "signal", - "speech", - "bright", - "remind", - "damage", - "amount", - "manage", - "safety", - "theory", - "spread", - "sudden", - "cheese", - "spring", - "castle", - "artist", - "forest", - "regret", - "lesson", - "pocket", - "square", - "europe", - "genius", - "winter", - "tongue", - "cancer", - "silver", - "toilet", - "priest", - "invite", - "walter", - "rachel", - "period", - "player", - "repeat", - "proper", - "assume", - "fought", - "temple", - "jacket", - "switch", - "affair", - "golden", - "sexual", - "suffer", - "clever", - "poison", - "yellow", - "indian", - "winner", - "threat", - "nation", - "source", - "palace", - "effect", - "modern", - "talent", - "honour", - "mirror", - "studio", - "desire", - "monkey", - "carter", - "rescue", - "result", - "remove", - "deeply", - "scream", - "desert", - "former", - "arrive", - "decent", - "flower", - "refuse", - "dragon", - "junior", - "silent", - "borrow", - "expert", - "direct", - "button", - "effort", - "garage", - "county", - "vision", - "defend", - "senior", - "freeze", - "shadow", - "screen", - "writer", - "empire", - "estate", - "device", - "design", - "object", - "valley", - "circle", - "agency", - "border", - "mental", - "secure", - "reward", - "commit", - "intend", - "ignore", - "useful", - "gather", - "policy", - "online", - "virgin", - "guitar", - "hunter", - "urgent", - "assure", - "unique", - "behave", - "closet", - "coward", - "supply", - "demand", - "museum", - "steady", - "option", - "recall", - "mighty", - "accent", - "mobile", - "wallet", - "favour", - "singer", - "defeat", - "league", - "orange", - "crisis", - "tunnel", - "stress", - "jordan", - "launch", - "legend", - "butter", - "insist", - "nathan", - "attend", - "script", - "degree", - "rabbit", - "jewish", - "russia", - "motion", - "centre", - "struck", - "inform", - "gentle", - "status", - "cancel", - "turkey", - "clinic", - "jungle", - "deputy", - "reckon", - "makeup", - "nephew", - "outfit", - "filthy", - "prayer", - "behalf", - "motive", - "bishop", - "dealer", - "backup", - "nearby", - "rotten", - "knight", - "cooper", - "sample", - "foster", - "tattoo", - "reveal", - "batman", - "colour", - "worker", - "impact", - "relief", - "patrol", - "circus", - "auntie", - "smooth", - "resist", - "hammer", - "oxygen", - "rocket", - "stable", - "unable", - "escort", - "corpse", - "worthy", - "softly", - "creepy", - "walker", - "blocks", - "deeper", - "dancer", - "remote", - "powder", - "supper", - "liquor", - "random", - "active", - "trauma", - "safely", - "serial", - "divine", - "punish", - "locker", - "global", - "string", - "bitter", - "granny", - "nicely", - "review", - "salary", - "wealth", - "profit", - "insult", - "appeal", - "praise", - "branch", - "muscle", - "blonde", - "canada", - "comedy", - "stroke", - "symbol", - "checks", - "throne", - "deadly", - "native", - "poetry", - "admire", - "injury", - "burden", - "racing", - "manner", - "norman", - "cinema", - "statue", - "fridge", - "bucket", - "waiter", - "combat", - "polish", - "jersey", - "wisdom", - "farmer", - "budget", - "affect", - "e-mail", - "betray", - "cowboy", - "cookie", - "finest", - "warren", - "marine", - "abroad", - "rising", - "height", - "editor", - "region", - "temper", - "horror", - "korean", - "tragic", - "tennis", - "needle", - "repair", - "method", - "permit", - "spider", - "gently", - "casino", - "unfair", - "polite", - "avenue", - "absurd", - "potato", - "terror", - "parade", - "soccer", - "cherry", - "cattle", - "turtle", - "hunger", - "severe", - "bureau", - "drawer", - "harper", - "pillow", - "galaxy", - "burger", - "basket", - "shield", - "heroin", - "barney", - "gossip", - "humble", - "tissue", - "vessel", - "coffin", - "cotton", - "advise", - "skinny", - "rubber", - "purple", - "carpet", - "breast", - "misery", - "banana", - "shitty", - "debate", - "liquid", - "visual", - "sorrow", - "pepper", - "helmet", - "collar", - "belief", - "psycho", - "ladder", - "dining", - "bailey", - "cruise", - "rhythm", - "barrel", - "cannon", - "ginger", - "kindly", - "narrow", - "forbid", - "pierce", - "scotch", - "tender", - "slight", - "campus", - "ritual", - "shrine", - "google", - "robber", - "cement", - "hamlet", - "cereal", - "humour", - "delete", - "nickel", - "marble", - "seduce", - "regime", - "tackle", - "hustle", - "potion", - "fiance", - "kettle", - "stroll", - "radius", - "verify", - "stitch", - "thrust", - "artery", - "stereo", - "bender", - "denial", - "ethics", - "glance", - "server" - ] -} diff --git a/packages/yoastseo/src/languageProcessing/languages/en/config/wordComplexity.js b/packages/yoastseo/src/languageProcessing/languages/en/config/wordComplexity.js index 4e1bbc672cf..bf3e0193f68 100644 --- a/packages/yoastseo/src/languageProcessing/languages/en/config/wordComplexity.js +++ b/packages/yoastseo/src/languageProcessing/languages/en/config/wordComplexity.js @@ -1,8 +1,5 @@ -import frequencyList from "./internal/frequencyList.json"; - // This is a config for the Word Complexity assessment. As such, this helper is not bundled in Yoast SEO. export default { - frequencyList: frequencyList.list, wordLength: 7, doesUpperCaseDecreaseComplexity: true, }; diff --git a/packages/yoastseo/src/languageProcessing/languages/en/helpers/checkIfWordIsComplex.js b/packages/yoastseo/src/languageProcessing/languages/en/helpers/checkIfWordIsComplex.js index bf94e555e36..2d8429da0ee 100644 --- a/packages/yoastseo/src/languageProcessing/languages/en/helpers/checkIfWordIsComplex.js +++ b/packages/yoastseo/src/languageProcessing/languages/en/helpers/checkIfWordIsComplex.js @@ -7,17 +7,18 @@ const { buildFormRule, createRulesFromArrays } = languageProcessing; * * @param {object} config The configuration needed for assessing the word's complexity, e.g., the frequency list. * @param {string} word The word to check. - * @param {Object} [morphologyData] Optional morphology data. + * @param {object} premiumData The object that contains data for the assessment including the frequency list. * * @returns {boolean} Whether or not a word is complex. */ -export default function checkIfWordIsComplex( config, word, morphologyData ) { +export default function checkIfWordIsComplex( config, word, premiumData ) { const lengthLimit = config.wordLength; - const frequencyList = config.frequencyList; + const frequencyList = premiumData.frequencyList.list; + // Whether uppercased beginning of a word decreases its complexity. const doesUpperCaseDecreaseComplexity = config.doesUpperCaseDecreaseComplexity; - // The word is not complex if it's less than the length limit, i.e. 7 characters for English. + // The word is not complex if it's less than or the same as the length limit, i.e. 7 characters for English. if ( word.length <= lengthLimit ) { return false; } @@ -32,9 +33,9 @@ export default function checkIfWordIsComplex( config, word, morphologyData ) { return false; } - // The word is not complex if it's singular form is in the frequency list. - if ( morphologyData ) { - const singular = buildFormRule( word, createRulesFromArrays( morphologyData.nouns.regexNoun.singularize ) ); + // The word is not complex if its singular form is in the frequency list. + if ( premiumData ) { + const singular = buildFormRule( word, createRulesFromArrays( premiumData.nouns.regexNoun.singularize ) ); return ! frequencyList.includes( singular ); } diff --git a/packages/yoastseo/src/languageProcessing/languages/es/config/internal/frequencyList.json b/packages/yoastseo/src/languageProcessing/languages/es/config/internal/frequencyList.json deleted file mode 100644 index 7464fc808d6..00000000000 --- a/packages/yoastseo/src/languageProcessing/languages/es/config/internal/frequencyList.json +++ /dev/null @@ -1,3261 +0,0 @@ -{ - "source": "This list is taken from roughly the first 5000 words of this word list https://github.com/hermitdave/FrequencyWords/blob/master/content/2018/en/es_50k.txt. Some clean ups were also done, e.g. to remove pronouns", - "list": [ - "abandonado", - "abandonar", - "abandon\u00f3", - "abierta", - "abierto", - "abiertos", - "abogada", - "abogado", - "abogados", - "abrazo", - "abrigo", - "absolutamente", - "absoluto", - "absurdo", - "abuela", - "abuelo", - "aburrida", - "aburrido", - "acabado", - "acabamos", - "acaban", - "acabar", - "acabar\u00e1", - "acabas", - "academia", - "acceso", - "accidente", - "acciones", - "acci\u00f3n", - "aceite", - "acento", - "acepta", - "aceptado", - "aceptar", - "acepto", - "acerca", - "acostumbrado", - "actitud", - "actividad", - "actores", - "actriz", - "actuaci\u00f3n", - "actual", - "actualmente", - "actuando", - "actuar", - "acuerdas", - "acuerdo", - "acusaci\u00f3n", - "acusado", - "adecuada", - "adecuado", - "adelante", - "adem\u00e1s", - "adentro", - "adivina", - "adivinar", - "admitir", - "adolescente", - "adonde", - "adorable", - "adrian", - "adulto", - "adultos", - "advertencia", - "advierto", - "ad\u00f3nde", - "aeropuerto", - "afortunado", - "afuera", - "agarra", - "agencia", - "agenda", - "agente", - "agentes", - "agosto", - "agrada", - "agradable", - "agradecido", - "agradezco", - "aguanta", - "aguantar", - "agujero", - "alarma", - "albert", - "alcalde", - "alcance", - "alcanzar", - "alcohol", - "alegra", - "alegre", - "alegro", - "alegr\u00eda", - "alejado", - "alemanes", - "alemania", - "alem\u00e1n", - "alerta", - "alfombra", - "alguien", - "alguna", - "algunas", - "alguno", - "algunos", - "alianza", - "alicia", - "aliento", - "alimentos", - "alivio", - "allison", - "almac\u00e9n", - "almirante", - "almorzar", - "almuerzo", - "alquiler", - "alrededor", - "alternativa", - "alteza", - "altura", - "alumnos", - "al\u00e9jate", - "amable", - "amanda", - "amanecer", - "amante", - "amantes", - "amarillo", - "ambiente", - "ambulancia", - "amenaza", - "americana", - "americano", - "americanos", - "amigas", - "amigos", - "amistad", - "am\u00e9rica", - "anciano", - "andando", - "andrew", - "angela", - "anillo", - "animal", - "animales", - "aniversario", - "anoche", - "antecedentes", - "anterior", - "anteriormente", - "anthony", - "antigua", - "antiguo", - "antiguos", - "antonio", - "anuncio", - "an\u00e1lisis", - "apagar", - "aparece", - "aparecer", - "apareci\u00f3", - "aparentemente", - "apariencia", - "apartamento", - "aparte", - "apellido", - "apenas", - "apesta", - "apetece", - "apostar", - "aprecio", - "aprender", - "aprendido", - "aprend\u00ed", - "apropiado", - "aproximadamente", - "apuesta", - "apuestas", - "apuesto", - "ap\u00farate", - "aquella", - "aquello", - "aquellos", - "archivo", - "archivos", - "armada", - "armado", - "armario", - "arreglado", - "arreglar", - "arreglarlo", - "arreglo", - "arrestado", - "arresto", - "arriba", - "arruinado", - "arruinar", - "arthur", - "artista", - "artistas", - "art\u00edculo", - "art\u00edculos", - "asalto", - "ascensor", - "asegurar", - "asegurarme", - "aseguro", - "aseg\u00farate", - "asesina", - "asesinada", - "asesinado", - "asesinar", - "asesinato", - "asesinatos", - "asesino", - "asesinos", - "asesin\u00f3", - "ashley", - "asiento", - "asientos", - "asistente", - "asombroso", - "aspecto", - "asqueroso", - "asumir", - "asunto", - "asuntos", - "asusta", - "asustada", - "asustado", - "atacar", - "ataque", - "ataques", - "atenci\u00f3n", - "atender", - "atractiva", - "atractivo", - "atrapado", - "atrapados", - "atrapar", - "atreves", - "audiencia", - "audrey", - "aumento", - "aunque", - "autob\u00fas", - "autopsia", - "autoridad", - "autoridades", - "aut\u00e9ntico", - "auxilio", - "aventura", - "averiguar", - "averiguarlo", - "aviones", - "ayudado", - "ayudando", - "ayudante", - "ayudar", - "ayudarla", - "ayudarle", - "ayudarlo", - "ayudarme", - "ayudarnos", - "ayudarte", - "ayudar\u00e1", - "ayudar\u00e9", - "ayudar\u00eda", - "ayudas", - "ay\u00fadame", - "ay\u00fadenme", - "azules", - "az\u00facar", - "bailando", - "bailar", - "bajando", - "bancos", - "bandera", - "barato", - "barcos", - "barrio", - "bastante", - "bastardo", - "basura", - "batalla", - "bater\u00eda", - "batman", - "bebida", - "bebidas", - "bebido", - "bebiendo", - "belleza", - "bendici\u00f3n", - "bendiga", - "beneficio", - "beneficios", - "berl\u00edn", - "bestia", - "biblia", - "biblioteca", - "bicicleta", - "bienes", - "bienvenida", - "bienvenido", - "bienvenidos", - "billete", - "billetes", - "blanca", - "blanco", - "blancos", - "bolsas", - "bolsillo", - "bombas", - "bomberos", - "bonita", - "bonitas", - "bonito", - "borracha", - "borracho", - "bosque", - "boston", - "botella", - "botellas", - "brandon", - "brazos", - "brillante", - "brindis", - "brit\u00e1nico", - "bromas", - "bromeando", - "bromeas", - "brujas", - "buenas", - "buenos", - "buscaba", - "buscado", - "buscamos", - "buscan", - "buscando", - "buscar", - "buscarla", - "buscarlo", - "buscarte", - "buscar\u00e9", - "buscas", - "b\u00e1sicamente", - "b\u00e9isbol", - "b\u00fasqueda", - "caballero", - "caballeros", - "caballo", - "caballos", - "caba\u00f1a", - "cabello", - "cabeza", - "cabezas", - "cabina", - "cabr\u00f3n", - "cadena", - "cad\u00e1ver", - "cad\u00e1veres", - "cafeter\u00eda", - "calidad", - "caliente", - "calientes", - "california", - "callej\u00f3n", - "calles", - "camarada", - "camarero", - "cambia", - "cambiado", - "cambian", - "cambiando", - "cambiar", - "cambie", - "cambio", - "cambios", - "cambi\u00f3", - "camina", - "caminando", - "caminar", - "camino", - "caminos", - "camioneta", - "camisa", - "camiseta", - "cami\u00f3n", - "campamento", - "campa\u00f1a", - "campe\u00f3n", - "campos", - "canad\u00e1", - "canciones", - "canci\u00f3n", - "cansada", - "cansado", - "cantando", - "cantante", - "cantar", - "cantidad", - "capaces", - "capacidad", - "capital", - "capit\u00e1n", - "cap\u00edtulo", - "carajo", - "caramba", - "cargar", - "cargos", - "caridad", - "cari\u00f1o", - "carlos", - "caroline", - "carrera", - "carreras", - "carretera", - "carrie", - "cartas", - "cartel", - "carter", - "cartera", - "car\u00e1cter", - "casada", - "casado", - "casados", - "casarme", - "casarse", - "casarte", - "casino", - "castigo", - "castillo", - "casualidad", - "catherine", - "causado", - "causar", - "cayendo", - "cazador", - "celebrar", - "celosa", - "celoso", - "celular", - "cementerio", - "cenizas", - "centavo", - "centavos", - "central", - "centro", - "cercano", - "cerdos", - "cerebral", - "cerebro", - "ceremonia", - "cerrada", - "cerrado", - "cerrar", - "cerveza", - "cervezas", - "champ\u00e1n", - "chaqueta", - "charla", - "charles", - "charlie", - "charlotte", - "chaval", - "cheque", - "chicago", - "chicas", - "chicos", - "chinos", - "chiste", - "chocolate", - "christine", - "cielos", - "ciencia", - "ciento", - "cientos", - "cient\u00edfico", - "cient\u00edficos", - "cierra", - "cierre", - "cierta", - "ciertamente", - "ciertas", - "cierto", - "ciertos", - "cigarrillo", - "cigarrillos", - "cincuenta", - "cintur\u00f3n", - "circunstancias", - "cirug\u00eda", - "cirujano", - "ciudad", - "ciudadano", - "ciudadanos", - "ciudades", - "civiles", - "claire", - "claramente", - "clases", - "cliente", - "clientes", - "cl\u00e1sico", - "cl\u00ednica", - "coartada", - "cobarde", - "coca\u00edna", - "coches", - "cocina", - "cocinar", - "cogido", - "coincidencia", - "cojones", - "colecci\u00f3n", - "colega", - "colegas", - "colegio", - "colgar", - "colina", - "collar", - "colores", - "columna", - "comandante", - "combate", - "combinaci\u00f3n", - "combustible", - "comentarios", - "comenzar", - "comenz\u00f3", - "comercial", - "cometer", - "cometido", - "comida", - "comido", - "comiendo", - "comienza", - "comienzo", - "comisario", - "comisar\u00eda", - "comisi\u00f3n", - "comit\u00e9", - "compartir", - "compasi\u00f3n", - "compa\u00f1era", - "compa\u00f1ero", - "compa\u00f1eros", - "compa\u00f1\u00eda", - "competencia", - "complejo", - "completa", - "completamente", - "completo", - "complicado", - "comportamiento", - "compra", - "comprado", - "comprar", - "compras", - "comprender", - "comprendes", - "comprendo", - "comprobar", - "compromiso", - "compr\u00e9", - "compr\u00f3", - "computadora", - "comunicaci\u00f3n", - "comunidad", - "conciencia", - "concierto", - "concurso", - "condado", - "condena", - "condenado", - "condicional", - "condiciones", - "condici\u00f3n", - "conduce", - "conduciendo", - "conducir", - "conducta", - "conductor", - "conectado", - "conejo", - "conexi\u00f3n", - "conferencia", - "confesi\u00f3n", - "confianza", - "confiar", - "confundido", - "conf\u00eda", - "conf\u00edas", - "conf\u00edo", - "congreso", - "conjunto", - "conmigo", - "connor", - "conoce", - "conocemos", - "conocen", - "conocer", - "conocerla", - "conocerlo", - "conocerte", - "conoces", - "conocida", - "conocido", - "conocimiento", - "conocimos", - "conociste", - "conoci\u00f3", - "conoc\u00ed", - "conoc\u00eda", - "conozca", - "conozco", - "consciente", - "consecuencias", - "conseguido", - "conseguimos", - "conseguir", - "conseguirlo", - "conseguir\u00e9", - "conseguiste", - "consegu\u00ed", - "consejo", - "consejos", - "considera", - "considerado", - "considerando", - "considerar", - "consiga", - "consigo", - "consigue", - "consigues", - "consigui\u00f3", - "constantemente", - "construcci\u00f3n", - "construir", - "contacto", - "contactos", - "contado", - "contando", - "contar", - "contarle", - "contarme", - "contarte", - "contar\u00e9", - "contaste", - "contenta", - "contento", - "contesta", - "contestar", - "contigo", - "continuaci\u00f3n", - "continuar", - "contin\u00faa", - "contra", - "contrario", - "contrato", - "control", - "controlar", - "convencer", - "convencido", - "conversaci\u00f3n", - "convertido", - "convertir", - "convertirse", - "convierte", - "convirti\u00f3", - "cooper", - "copias", - "coraje", - "corazones", - "coraz\u00f3n", - "corbata", - "corona", - "coronel", - "correcta", - "correcto", - "corredor", - "correo", - "correr", - "corriendo", - "corriente", - "cortado", - "cortar", - "costado", - "costumbre", - "creado", - "crecer", - "crecido", - "creemos", - "creerlo", - "criatura", - "criaturas", - "crimen", - "criminal", - "criminales", - "crisis", - "cristal", - "cristo", - "cruzar", - "cr\u00e1neo", - "cr\u00e9dito", - "cr\u00e9eme", - "cr\u00edmenes", - "cuadro", - "cuales", - "cualquier", - "cualquiera", - "cuando", - "cuantas", - "cuanto", - "cuantos", - "cuarenta", - "cuartel", - "cuarto", - "cuatro", - "cubierta", - "cubierto", - "cubrir", - "cuchillo", - "cuello", - "cuenta", - "cuentas", - "cuente", - "cuento", - "cuerda", - "cuerpo", - "cuerpos", - "cuesta", - "cuesti\u00f3n", - "cuidado", - "cuidar", - "culpable", - "cultura", - "cumplea\u00f1os", - "cumplido", - "cumplir", - "curiosidad", - "curioso", - "custodia", - "cu\u00e1les", - "cu\u00e1ndo", - "cu\u00e1nta", - "cu\u00e1ntas", - "cu\u00e1nto", - "cu\u00e1ntos", - "cu\u00e9ntame", - "cu\u00eddate", - "c\u00e1llate", - "c\u00e1lmate", - "c\u00e1mara", - "c\u00e1maras", - "c\u00e1ncer", - "c\u00e1rcel", - "c\u00e9lulas", - "c\u00edrculo", - "c\u00f3digo", - "c\u00f3moda", - "c\u00f3modo", - "daniel", - "daremos", - "darles", - "darnos", - "debajo", - "debemos", - "deberes", - "deber\u00eda", - "deber\u00edamos", - "deber\u00edan", - "deber\u00edas", - "debido", - "debilidad", - "debiste", - "decente", - "decide", - "decidido", - "decidimos", - "decidir", - "decidi\u00f3", - "decid\u00ed", - "decimos", - "decirle", - "decirles", - "decirlo", - "decirme", - "decirnos", - "decirte", - "decisiones", - "decisi\u00f3n", - "declaraci\u00f3n", - "dec\u00edan", - "dec\u00edas", - "dec\u00edrmelo", - "dec\u00edrselo", - "dec\u00edrtelo", - "defender", - "defensa", - "definitivamente", - "dejaba", - "dejado", - "dejame", - "dejamos", - "dejando", - "dejara", - "dejaremos", - "dejarla", - "dejarlo", - "dejarme", - "dejaron", - "dejarte", - "dejar\u00e1", - "dejar\u00e9", - "dejar\u00eda", - "dejaste", - "dejemos", - "delante", - "delicioso", - "delito", - "demanda", - "demasiada", - "demasiadas", - "demasiado", - "demasiados", - "demonio", - "demonios", - "demostrar", - "demuestra", - "dennis", - "dentro", - "departamento", - "depende", - "deporte", - "deportes", - "deprisa", - "dep\u00f3sito", - "derecha", - "derecho", - "derechos", - "desafortunadamente", - "desaf\u00edo", - "desagradable", - "desaparece", - "desaparecer", - "desaparecido", - "desapareci\u00f3", - "desarrollo", - "desastre", - "desayunar", - "desayuno", - "descansa", - "descansar", - "descanso", - "desconocido", - "descripci\u00f3n", - "descubierto", - "descubrir", - "descubri\u00f3", - "descubr\u00ed", - "desear\u00eda", - "deseas", - "deseos", - "desesperado", - "desgracia", - "desgraciado", - "desierto", - "desnuda", - "desnudo", - "despacho", - "despacio", - "despedida", - "despedido", - "despejado", - "despertar", - "despert\u00e9", - "despierta", - "despierto", - "despues", - "despu\u00e9s", - "destino", - "destrucci\u00f3n", - "destruido", - "destruir", - "detalle", - "detalles", - "detective", - "detectives", - "detener", - "detenerlo", - "detenido", - "detente", - "detr\u00e1s", - "detuvo", - "deudas", - "devolver", - "diablo", - "diablos", - "diamantes", - "diario", - "dibujo", - "diciendo", - "dientes", - "dieron", - "diferencia", - "diferente", - "diferentes", - "dificil", - "dif\u00edcil", - "dif\u00edciles", - "digamos", - "dijera", - "dijeron", - "dijimos", - "dijiste", - "dinero", - "dioses", - "direcci\u00f3n", - "directa", - "directamente", - "directo", - "director", - "directora", - "dirige", - "dirigir", - "dir\u00edas", - "discos", - "disculpa", - "disculparme", - "disculpas", - "disculpe", - "disculpen", - "discurso", - "discusi\u00f3n", - "discutir", - "disc\u00falpame", - "disc\u00falpeme", - "dise\u00f1o", - "disfraz", - "disfruta", - "disfrutar", - "dispara", - "disparado", - "disparar", - "dispararon", - "disparen", - "disparo", - "disparos", - "dispar\u00f3", - "disponible", - "dispositivo", - "dispuesta", - "dispuesto", - "distancia", - "distinto", - "distrito", - "diversi\u00f3n", - "divertida", - "divertido", - "divisi\u00f3n", - "divorcio", - "docena", - "doctor", - "doctora", - "doctores", - "documento", - "documentos", - "domingo", - "dormida", - "dormido", - "dormir", - "dormitorio", - "drag\u00f3n", - "drogas", - "duerme", - "dulces", - "durante", - "durmiendo", - "d\u00e1melo", - "d\u00e9jala", - "d\u00e9jalo", - "d\u00e9jame", - "d\u00e9jeme", - "d\u00e9jenme", - "d\u00edgale", - "d\u00edgame", - "d\u00edmelo", - "d\u00edselo", - "d\u00f3lares", - "echado", - "econom\u00eda", - "edificio", - "edificios", - "educaci\u00f3n", - "edward", - "ee.uu.", - "efectivo", - "efecto", - "efectos", - "ego\u00edsta", - "ejemplo", - "ejercicio", - "ej\u00e9rcito", - "elecciones", - "elecci\u00f3n", - "electricidad", - "elegante", - "elegido", - "elegir", - "eligi\u00f3", - "eliminar", - "elizabeth", - "elliot", - "el\u00e9ctrica", - "embajador", - "embarazada", - "embargo", - "emergencia", - "emocionado", - "emocional", - "emocionante", - "emociones", - "emoci\u00f3n", - "empecemos", - "empec\u00e9", - "emperador", - "empezado", - "empezamos", - "empezando", - "empezar", - "empezaron", - "empez\u00f3", - "empiece", - "empieces", - "empieza", - "empiezan", - "empiezas", - "empiezo", - "empleado", - "empleados", - "empleo", - "empresa", - "empresas", - "enamorada", - "enamorado", - "encanta", - "encantada", - "encantado", - "encantador", - "encantadora", - "encantan", - "encantar\u00eda", - "encanto", - "encargado", - "encargar\u00e9", - "encargo", - "encerrado", - "encima", - "encontrado", - "encontramos", - "encontrar", - "encontraremos", - "encontrarla", - "encontrarlo", - "encontrarme", - "encontraron", - "encontrarte", - "encontrar\u00e1", - "encontrar\u00e1s", - "encontrar\u00e9", - "encontraste", - "encontremos", - "encontr\u00e9", - "encontr\u00f3", - "encuentra", - "encuentran", - "encuentras", - "encuentre", - "encuentren", - "encuentro", - "enemigo", - "enemigos", - "energ\u00eda", - "enfadada", - "enfadado", - "enferma", - "enfermedad", - "enfermedades", - "enfermera", - "enfermo", - "enfermos", - "enfrentar", - "enfrente", - "enga\u00f1ado", - "enga\u00f1ar", - "enga\u00f1o", - "enhorabuena", - "enojada", - "enojado", - "enorme", - "enormes", - "ensalada", - "ensayo", - "enseguida", - "ense\u00f1ar", - "ense\u00f1arte", - "ense\u00f1ar\u00e9", - "ense\u00f1\u00f3", - "entender", - "entenderlo", - "entendido", - "entendiste", - "entend\u00ed", - "entera", - "enterado", - "entero", - "enterrado", - "enter\u00e9", - "entiende", - "entienden", - "entiendes", - "entiendo", - "entonces", - "entrada", - "entradas", - "entrado", - "entramos", - "entrando", - "entrar", - "entrega", - "entregar", - "entren", - "entrenador", - "entrenamiento", - "entrevista", - "enviado", - "enviar", - "enviaron", - "enviar\u00e9", - "episodio", - "equipaje", - "equipo", - "equipos", - "equivocada", - "equivocado", - "equivocas", - "errores", - "escala", - "escalera", - "escaleras", - "escapado", - "escapar", - "escape", - "escap\u00f3", - "escena", - "escenario", - "esclavos", - "escoger", - "esconder", - "escondido", - "escribe", - "escribiendo", - "escribir", - "escribi\u00f3", - "escrib\u00ed", - "escrito", - "escritor", - "escritorio", - "escuadr\u00f3n", - "escucha", - "escuchado", - "escuchando", - "escuchar", - "escucharme", - "escuchas", - "escuchaste", - "escuche", - "escuchen", - "escucho", - "escuch\u00e9", - "escuch\u00f3", - "escuela", - "esc\u00e1ndalo", - "esc\u00fachame", - "esfuerzo", - "espacial", - "espacio", - "espada", - "espalda", - "espaldas", - "espa\u00f1a", - "espa\u00f1ol", - "especial", - "especiales", - "especialmente", - "especie", - "espect\u00e1culo", - "espejo", - "espera", - "esperaba", - "esperad", - "esperado", - "esperamos", - "esperan", - "esperando", - "esperanza", - "esperanzas", - "esperar", - "esperar\u00e9", - "esperas", - "espere", - "esperemos", - "esperen", - "espero", - "esposa", - "esposas", - "esposo", - "esp\u00e9rame", - "esp\u00edritu", - "esp\u00edritus", - "esquina", - "estaba", - "estaban", - "estabas", - "estable", - "estacionamiento", - "estaci\u00f3n", - "estado", - "estados", - "estadounidense", - "estadounidenses", - "estamos", - "estando", - "estaremos", - "estar\u00e1", - "estar\u00e1n", - "estar\u00e1s", - "estar\u00e9", - "estar\u00eda", - "estar\u00edamos", - "estar\u00edas", - "estemos", - "estilo", - "estrategia", - "estrella", - "estrellas", - "estructura", - "estr\u00e9s", - "estudiando", - "estudiante", - "estudiantes", - "estudiar", - "estudio", - "estudios", - "estupenda", - "estupendo", - "estupidez", - "estuve", - "estuviera", - "estuvieras", - "estuvieron", - "estuvimos", - "estuviste", - "estuvo", - "est\u00e1bamos", - "est\u00e1is", - "est\u00f3mago", - "est\u00fapida", - "est\u00fapido", - "est\u00fapidos", - "eternidad", - "europa", - "evento", - "eventos", - "evidencia", - "evitar", - "evitarlo", - "exactamente", - "exacto", - "examen", - "excelencia", - "excelente", - "excepto", - "excusa", - "existe", - "existen", - "existencia", - "expediente", - "experiencia", - "experimento", - "experto", - "explica", - "explicaci\u00f3n", - "explicar", - "explicarlo", - "explosi\u00f3n", - "explotar", - "exposici\u00f3n", - "expresi\u00f3n", - "exterior", - "extranjero", - "extraordinario", - "extra\u00f1a", - "extra\u00f1as", - "extra\u00f1o", - "extra\u00f1os", - "extremadamente", - "extremo", - "ex\u00e1menes", - "fabuloso", - "faltan", - "familia", - "familiar", - "familiares", - "familias", - "famosa", - "famoso", - "fantasma", - "fantasmas", - "fantas\u00eda", - "fant\u00e1stica", - "fant\u00e1stico", - "fascinante", - "favorita", - "favorito", - "federal", - "federales", - "felices", - "felicidad", - "felicidades", - "felicitaciones", - "festival", - "fianza", - "fiebre", - "fiesta", - "fiestas", - "figura", - "finales", - "finalmente", - "fingir", - "firmado", - "firmar", - "fiscal", - "flores", - "florida", - "fondos", - "forense", - "formar", - "formas", - "fortuna", - "fotograf\u00eda", - "fotograf\u00edas", - "fracaso", - "francamente", - "francesa", - "franceses", - "francia", - "francis", - "francisco", - "franco", - "francos", - "franc\u00e9s", - "frankie", - "fraude", - "frecuencia", - "frente", - "fresca", - "fresco", - "frontera", - "fuente", - "fueran", - "fueras", - "fueron", - "fuerte", - "fuertes", - "fuerza", - "fuerzas", - "fuimos", - "fuiste", - "funciona", - "funcionan", - "funcionando", - "funcionar", - "funcionar\u00e1", - "funcione", - "funcion\u00f3", - "funci\u00f3n", - "funeral", - "furgoneta", - "futuro", - "f\u00e1brica", - "f\u00e1cilmente", - "f\u00edjate", - "f\u00edsica", - "f\u00edsico", - "f\u00fatbol", - "gabriel", - "galletas", - "gallina", - "ganado", - "ganador", - "ganamos", - "ganando", - "garaje", - "garganta", - "gasolina", - "gastar", - "gastos", - "generaci\u00f3n", - "general", - "generoso", - "genial", - "geniales", - "george", - "gerente", - "gigante", - "gilipollas", - "gimnasio", - "gloria", - "gobernador", - "gobierno", - "golpea", - "golpeado", - "golpear", - "golpes", - "golpe\u00f3", - "gordon", - "grabaci\u00f3n", - "gracia", - "gracias", - "graciosa", - "gracioso", - "grados", - "graduaci\u00f3n", - "grande", - "grandes", - "grandioso", - "granja", - "gratis", - "gravedad", - "gritando", - "gritar", - "gritos", - "grupos", - "guantes", - "guarda", - "guardar", - "guardia", - "guardias", - "guerra", - "guerrero", - "guitarra", - "gustaba", - "gustado", - "gustan", - "gustar", - "gustar\u00e1", - "gustar\u00eda", - "gustas", - "haberla", - "haberle", - "haberlo", - "haberme", - "haberse", - "haberte", - "habido", - "habilidad", - "habilidades", - "habitaciones", - "habitaci\u00f3n", - "habitual", - "hablaba", - "hablado", - "hablamos", - "hablan", - "hablando", - "hablar", - "hablaremos", - "hablarle", - "hablarme", - "hablarte", - "hablar\u00e9", - "hablas", - "hablaste", - "hablemos", - "hables", - "habr\u00e1n", - "habr\u00eda", - "habr\u00edan", - "habr\u00edas", - "hab\u00e9is", - "hab\u00edamos", - "hab\u00edan", - "hab\u00edas", - "hacemos", - "hacerla", - "hacerle", - "hacerlo", - "hacerme", - "hacernos", - "hacerse", - "hacerte", - "haciendo", - "haci\u00e9ndolo", - "hac\u00e9is", - "hac\u00edan", - "hac\u00edas", - "hagamos", - "hag\u00e1moslo", - "hallar", - "hambre", - "hannah", - "haremos", - "harold", - "harris", - "harvey", - "har\u00edan", - "har\u00edas", - "hayamos", - "hechizo", - "hechos", - "helado", - "helic\u00f3ptero", - "herida", - "heridas", - "herido", - "heridos", - "hermana", - "hermanas", - "hermano", - "hermanos", - "hermosa", - "hermosas", - "hermoso", - "hero\u00edna", - "herramientas", - "hiciera", - "hicieras", - "hicieron", - "hicimos", - "hiciste", - "hierba", - "hierro", - "historia", - "historial", - "historias", - "hitler", - "hollywood", - "holmes", - "hombre", - "hombres", - "hombro", - "hombros", - "homicidio", - "honesta", - "honestamente", - "honesto", - "horario", - "horrible", - "horribles", - "hospital", - "howard", - "hubiera", - "hubieran", - "hubieras", - "hubiese", - "hubi\u00e9ramos", - "huella", - "huellas", - "huesos", - "huevos", - "humana", - "humanidad", - "humano", - "humanos", - "huyendo", - "h\u00e1blame", - "h\u00e9roes", - "h\u00edgado", - "identidad", - "identificaci\u00f3n", - "identificar", - "idioma", - "idiota", - "idiotas", - "iglesia", - "iguales", - "igualmente", - "ilegal", - "imagen", - "imagina", - "imaginaci\u00f3n", - "imaginar", - "imaginas", - "imagino", - "imagin\u00e9", - "imb\u00e9cil", - "impacto", - "imperio", - "importa", - "importaba", - "importan", - "importancia", - "importante", - "importantes", - "importar", - "importar\u00eda", - "importe", - "imposible", - "impresionante", - "impresi\u00f3n", - "impuestos", - "im\u00e1genes", - "incendio", - "incidente", - "incluso", - "incluyendo", - "inconsciente", - "incre\u00edble", - "incre\u00edblemente", - "inc\u00f3modo", - "indica", - "indios", - "industria", - "infancia", - "infantil", - "infeliz", - "infierno", - "influencia", - "informaci\u00f3n", - "informado", - "informar", - "informe", - "informes", - "ingeniero", - "inglaterra", - "ingl\u00e9s", - "inmediatamente", - "inmediato", - "inmunidad", - "inocente", - "inocentes", - "inspector", - "instante", - "instinto", - "instituto", - "instrucciones", - "inteligencia", - "inteligente", - "intenciones", - "intenci\u00f3n", - "intenta", - "intentaba", - "intentado", - "intentamos", - "intentando", - "intentar", - "intentarlo", - "intentar\u00e9", - "intentas", - "intente", - "intento", - "intent\u00e9", - "intent\u00f3", - "interesa", - "interesada", - "interesado", - "interesante", - "intereses", - "interior", - "internacional", - "internet", - "interrumpir", - "inter\u00e9s", - "int\u00e9ntalo", - "investigaci\u00f3n", - "investigando", - "investigar", - "invierno", - "invisible", - "invitaci\u00f3n", - "invitado", - "invitados", - "invito", - "invit\u00f3", - "involucrado", - "in\u00fatil", - "iremos", - "isabel", - "italia", - "italiano", - "izquierda", - "izquierdo", - "jackie", - "jackson", - "japoneses", - "jard\u00edn", - "jennifer", - "jeremy", - "jersey", - "jessica", - "jesucristo", - "jodida", - "jodido", - "johnny", - "johnson", - "jonathan", - "jordan", - "joseph", - "jud\u00edos", - "juegos", - "jueves", - "jugada", - "jugador", - "jugadores", - "jugando", - "juguete", - "juguetes", - "juicio", - "julian", - "junior", - "juntas", - "juntos", - "jurado", - "justicia", - "justin", - "juventud", - "juzgado", - "juzgar", - "j\u00f3venes", - "kil\u00f3metros", - "labios", - "laboratorio", - "ladrones", - "ladr\u00f3n", - "lamento", - "lanzamiento", - "lanzar", - "largas", - "lauren", - "lealtad", - "lecci\u00f3n", - "lectura", - "lengua", - "lenguaje", - "lentamente", - "leonard", - "letras", - "levanta", - "levantar", - "lev\u00e1ntate", - "leyenda", - "leyendo", - "liberar", - "libertad", - "libras", - "libres", - "libros", - "licencia", - "lidiar", - "limpia", - "limpiar", - "limpieza", - "limpio", - "lincoln", - "listas", - "listos", - "literalmente", - "llamaba", - "llamada", - "llamadas", - "llamado", - "llamamos", - "llaman", - "llamando", - "llamar", - "llamarlo", - "llamarme", - "llamaron", - "llamarte", - "llamar\u00e9", - "llamas", - "llamaste", - "llamen", - "llames", - "llaves", - "llegada", - "llegado", - "llegamos", - "llegan", - "llegando", - "llegar", - "llegaremos", - "llegaron", - "llegar\u00e1", - "llegas", - "llegaste", - "llegue", - "lleguemos", - "lleguen", - "llegu\u00e9", - "llenar", - "llevaba", - "llevado", - "llevamos", - "llevan", - "llevando", - "llevar", - "llevaremos", - "llevarla", - "llevarlo", - "llevarme", - "llevaron", - "llevarte", - "llevar\u00e1", - "llevar\u00e9", - "llevas", - "lleven", - "llorando", - "llorar", - "llores", - "lluvia", - "ll\u00e1mame", - "ll\u00e9vame", - "locales", - "locura", - "logrado", - "logramos", - "lograr", - "londres", - "louise", - "luchando", - "luchar", - "lugares", - "l\u00e1grimas", - "l\u00e1rgate", - "l\u00e1stima", - "l\u00edmite", - "l\u00edmites", - "l\u00edneas", - "l\u00f3gica", - "madame", - "madera", - "madres", - "maestra", - "maestro", - "maggie", - "magn\u00edfico", - "majestad", - "malcolm", - "maldici\u00f3n", - "maldita", - "malditas", - "maldito", - "malditos", - "maleta", - "maletas", - "malvado", - "mandar", - "manejar", - "manera", - "maneras", - "mantener", - "mantenerlo", - "mantenga", - "mantente", - "mantequilla", - "mantiene", - "mant\u00e9n", - "manzana", - "manzanas", - "maquillaje", - "maravilla", - "maravillosa", - "maravilloso", - "marcas", - "marcha", - "marchar", - "marcus", - "margaret", - "marido", - "marihuana", - "marina", - "marshall", - "martes", - "martha", - "martin", - "matado", - "matando", - "matarla", - "matarlo", - "matarme", - "mataron", - "matarte", - "matar\u00e1", - "matar\u00e9", - "matar\u00eda", - "mataste", - "matem\u00e1ticas", - "materia", - "material", - "matrimonio", - "matthew", - "mayores", - "mayor\u00eda", - "ma\u00f1ana", - "medianoche", - "medias", - "medicina", - "medida", - "medidas", - "mediod\u00eda", - "medios", - "mejorar", - "mejores", - "memoria", - "mencionar", - "mencion\u00f3", - "menores", - "mensaje", - "mensajes", - "mental", - "mentes", - "mentido", - "mentir", - "mentira", - "mentiras", - "mentiroso", - "mentiste", - "menudo", - "mercado", - "merece", - "mereces", - "merezco", - "metido", - "metros", - "mezcla", - "michael", - "michelle", - "mickey", - "miembro", - "miembros", - "miente", - "mientras", - "mierda", - "miguel", - "milagro", - "militar", - "militares", - "millas", - "miller", - "millones", - "mill\u00f3n", - "ministerio", - "ministro", - "mintiendo", - "minti\u00f3", - "minuto", - "minutos", - "miraba", - "mirada", - "mirando", - "miserable", - "misi\u00f3n", - "mismas", - "mismos", - "misterio", - "mi\u00e9rcoles", - "modelo", - "molesta", - "molestar", - "moleste", - "molestia", - "molesto", - "momento", - "momentos", - "moneda", - "monedas", - "monsieur", - "monstruo", - "monstruos", - "montar", - "monta\u00f1a", - "monta\u00f1as", - "mont\u00f3n", - "morgan", - "morir\u00e1", - "mortal", - "mostrar", - "mostrarte", - "mostrar\u00e9", - "motivo", - "motivos", - "moverse", - "moviendo", - "movimiento", - "movimientos", - "muchacha", - "muchacho", - "muchachos", - "muchas", - "muchos", - "much\u00edsimo", - "muebles", - "muelle", - "mueren", - "muerta", - "muerte", - "muertes", - "muerto", - "muertos", - "muestra", - "muestras", - "muevas", - "mujeres", - "multitud", - "mundial", - "muriendo", - "murieron", - "musical", - "mu\u00e9strame", - "mu\u00e9vanse", - "mu\u00e9vete", - "mu\u00f1eca", - "m\u00e1gico", - "m\u00e1quina", - "m\u00e1quinas", - "m\u00e1scara", - "m\u00e1xima", - "m\u00e1ximo", - "m\u00e9dica", - "m\u00e9dico", - "m\u00e9dicos", - "m\u00e9xico", - "m\u00ednimo", - "m\u00edralo", - "m\u00edrame", - "m\u00edrate", - "m\u00fasica", - "nacido", - "nacimiento", - "nacional", - "naci\u00f3n", - "naranja", - "narices", - "natalie", - "nathan", - "natural", - "naturaleza", - "naturalmente", - "navidad", - "necesario", - "necesidad", - "necesidades", - "necesita", - "necesitaba", - "necesitamos", - "necesitan", - "necesitar", - "necesitaremos", - "necesitar\u00e9", - "necesitas", - "necesite", - "necesites", - "necesito", - "negativo", - "negociar", - "negocio", - "negocios", - "negros", - "nelson", - "nervios", - "nerviosa", - "nervioso", - "ninguna", - "ninguno", - "ning\u00fan", - "niveles", - "ni\u00f1era", - "noches", - "nombre", - "nombres", - "normal", - "normales", - "normalmente", - "norman", - "normas", - "nosotras", - "nosotros", - "notado", - "noticia", - "noticias", - "novela", - "noviembre", - "nuclear", - "nuestra", - "nuestras", - "nuestro", - "nuestros", - "nuevamente", - "nuevas", - "nuevos", - "n\u00famero", - "n\u00fameros", - "objetivo", - "objeto", - "objetos", - "obligado", - "obtener", - "obviamente", - "ocasi\u00f3n", - "octubre", - "ocultar", - "ocupada", - "ocupado", - "ocupados", - "ocurra", - "ocurre", - "ocurrido", - "ocurriendo", - "ocurrir", - "ocurri\u00f3", - "oc\u00e9ano", - "odiaba", - "oferta", - "oficial", - "oficiales", - "oficialmente", - "oficina", - "ofrece", - "ofrecer", - "ofreci\u00f3", - "oliver", - "olivia", - "olvida", - "olvidado", - "olvidar", - "olvidar\u00e9", - "olvidaste", - "olvide", - "olvides", - "olvido", - "olvid\u00e9", - "olvid\u00f3", - "olv\u00eddalo", - "olv\u00eddate", - "opciones", - "opci\u00f3n", - "operaciones", - "operaci\u00f3n", - "opinas", - "opini\u00f3n", - "oportunidad", - "oportunidades", - "ordenador", - "orden\u00f3", - "orejas", - "organizaci\u00f3n", - "orgullo", - "orgullosa", - "orgulloso", - "origen", - "original", - "oscura", - "oscuridad", - "oscuro", - "ox\u00edgeno", - "paciencia", - "paciente", - "pacientes", - "padres", - "pagado", - "pagando", - "pagar\u00e9", - "palabra", - "palabras", - "palacio", - "paliza", - "pandilla", - "pantalla", - "pantalones", - "papeles", - "paquete", - "parada", - "parado", - "para\u00edso", - "parece", - "parecen", - "parecer", - "pareces", - "parecido", - "pareci\u00f3", - "parec\u00eda", - "paredes", - "pareja", - "parejas", - "parezca", - "parezco", - "parker", - "parque", - "partes", - "participar", - "particular", - "partida", - "partido", - "partir", - "pasaba", - "pasada", - "pasado", - "pasajeros", - "pasamos", - "pasando", - "pasaporte", - "pasara", - "pasaron", - "pasar\u00e1", - "pasar\u00eda", - "pasaste", - "pasillo", - "pasi\u00f3n", - "pastel", - "pastillas", - "pastor", - "patatas", - "patrick", - "patrulla", - "patr\u00f3n", - "pat\u00e9tico", - "payaso", - "pa\u00edses", - "pecado", - "pecados", - "pechos", - "pedazo", - "pedazos", - "pedido", - "pedimos", - "pedirle", - "pedirte", - "pedir\u00e9", - "pediste", - "peleando", - "pelear", - "peleas", - "peligro", - "peligrosa", - "peligroso", - "pelota", - "pelotas", - "pel\u00edcula", - "pel\u00edculas", - "pensaba", - "pensabas", - "pensado", - "pensamiento", - "pensamientos", - "pensamos", - "pensando", - "pensar", - "pensarlo", - "pensaste", - "peores", - "peque\u00f1a", - "peque\u00f1as", - "peque\u00f1o", - "peque\u00f1os", - "perdedor", - "perder", - "perdida", - "perdido", - "perdidos", - "perdiendo", - "perdimos", - "perdiste", - "perdi\u00f3", - "perdona", - "perdone", - "perd\u00f3n", - "perd\u00f3name", - "perd\u00f3neme", - "perfecta", - "perfectamente", - "perfecto", - "perfil", - "periodista", - "peri\u00f3dico", - "peri\u00f3dicos", - "permanecer", - "permiso", - "permite", - "permitido", - "permitir", - "perm\u00edtame", - "perros", - "persona", - "personaje", - "personajes", - "personal", - "personales", - "personalidad", - "personalmente", - "personas", - "pertenece", - "per\u00edodo", - "pesadilla", - "pesado", - "pescado", - "pescar", - "petici\u00f3n", - "petr\u00f3leo", - "pidiendo", - "piedad", - "piedra", - "piedras", - "piensa", - "piensan", - "piensas", - "piense", - "pienses", - "pienso", - "pierdas", - "pierde", - "pierdes", - "pierdo", - "pierna", - "piernas", - "piezas", - "piloto", - "pintar", - "pintura", - "piscina", - "pistas", - "pistola", - "pi\u00e9nsalo", - "placer", - "planeado", - "planeando", - "planes", - "planeta", - "planta", - "plantas", - "platos", - "pl\u00e1stico", - "poblaci\u00f3n", - "pobres", - "podamos", - "podemos", - "poderes", - "poderosa", - "poderoso", - "podido", - "podremos", - "podria", - "podr\u00e1n", - "podr\u00e1s", - "podr\u00eda", - "podr\u00edamos", - "podr\u00edan", - "podr\u00edas", - "pod\u00e9is", - "pod\u00edamos", - "pod\u00edan", - "pod\u00edas", - "policia", - "policial", - "polic\u00eda", - "polic\u00edas", - "pol\u00edtica", - "pol\u00edtico", - "pol\u00edticos", - "pondr\u00e1", - "pondr\u00e9", - "ponemos", - "ponerle", - "ponerlo", - "ponerme", - "ponerse", - "ponerte", - "pongan", - "pongas", - "poniendo", - "popular", - "poquito", - "porque", - "porquer\u00eda", - "porqu\u00e9", - "posesi\u00f3n", - "posibilidad", - "posibilidades", - "posible", - "posiblemente", - "posici\u00f3n", - "positivo", - "postre", - "potencia", - "potencial", - "practicar", - "precio", - "preciosa", - "precioso", - "precisamente", - "preciso", - "preferir\u00eda", - "prefiere", - "prefieres", - "prefiero", - "pregunta", - "preguntaba", - "preguntado", - "preguntando", - "preguntar", - "preguntarle", - "preguntarte", - "preguntas", - "pregunte", - "preguntes", - "pregunto", - "pregunt\u00e9", - "pregunt\u00f3", - "preg\u00fantale", - "premio", - "prensa", - "preocupa", - "preocupaci\u00f3n", - "preocupada", - "preocupado", - "preocuparse", - "preocuparte", - "preocupe", - "preocupes", - "prepara", - "preparada", - "preparado", - "preparados", - "preparando", - "preparar", - "prep\u00e1rate", - "presencia", - "presenta", - "presentaci\u00f3n", - "presentar", - "presente", - "presento", - "present\u00f3", - "presidente", - "presi\u00f3n", - "prestado", - "presupuesto", - "primavera", - "primer", - "primera", - "primeras", - "primero", - "primeros", - "princesa", - "principal", - "principio", - "principios", - "prioridad", - "prisionero", - "prisioneros", - "prisi\u00f3n", - "privada", - "privado", - "probable", - "probablemente", - "probado", - "probar", - "probarlo", - "problema", - "problemas", - "procedimiento", - "proceso", - "producci\u00f3n", - "producto", - "productor", - "productos", - "profesional", - "profesionales", - "profesi\u00f3n", - "profesor", - "profesora", - "profunda", - "profundamente", - "profundo", - "programa", - "progreso", - "prohibido", - "promesa", - "prometida", - "prometido", - "prometiste", - "prometi\u00f3", - "prometo", - "promet\u00ed", - "pronto", - "propia", - "propias", - "propiedad", - "propietario", - "propio", - "propios", - "propuesta", - "prop\u00f3sito", - "prostituta", - "protecci\u00f3n", - "proteger", - "proyecto", - "prueba", - "pruebas", - "pr\u00e1ctica", - "pr\u00e1cticamente", - "pr\u00e9stamo", - "pr\u00edncipe", - "pr\u00f3xima", - "pr\u00f3ximo", - "pr\u00f3ximos", - "psiquiatra", - "publicidad", - "pudiera", - "pudieras", - "pudieron", - "pudimos", - "pudiste", - "pudi\u00e9ramos", - "pueblo", - "puedan", - "puedas", - "pueden", - "puedes", - "puente", - "puerta", - "puertas", - "puerto", - "puesta", - "puesto", - "puestos", - "pulmones", - "puntos", - "pusieron", - "pusiste", - "p\u00e1gina", - "p\u00e1ginas", - "p\u00e1jaro", - "p\u00e1jaros", - "p\u00e1nico", - "p\u00e9rdida", - "p\u00fablica", - "p\u00fablico", - "quedaba", - "quedado", - "quedamos", - "quedan", - "quedar", - "quedarme", - "quedarnos", - "quedarse", - "quedarte", - "quedar\u00e1", - "quedar\u00e9", - "quedas", - "quedes", - "quemado", - "quemar", - "queremos", - "querer", - "queria", - "querida", - "querido", - "queridos", - "querr\u00e1", - "querr\u00e1s", - "querr\u00eda", - "querr\u00edas", - "quer\u00e9is", - "quer\u00eda", - "quer\u00edamos", - "quer\u00edan", - "quer\u00edas", - "quienes", - "quiera", - "quieran", - "quieras", - "quiere", - "quieren", - "quieres", - "quiero", - "quieto", - "quince", - "quisiera", - "quisieras", - "quitar", - "quizas", - "quiz\u00e1s", - "qui\u00e9nes", - "qu\u00e9date", - "qu\u00e9dense", - "qu\u00e9dese", - "qu\u00edmica", - "qu\u00edtate", - "rachel", - "radiaci\u00f3n", - "rastro", - "raymond", - "razonable", - "razones", - "reacci\u00f3n", - "reales", - "realidad", - "realizar", - "realmente", - "rebecca", - "recepci\u00f3n", - "receta", - "recibe", - "recibido", - "recibiendo", - "recibir", - "recibi\u00f3", - "recibo", - "recib\u00ed", - "reciente", - "recientemente", - "reci\u00e9n", - "recoger", - "recompensa", - "reconoce", - "reconocer", - "reconocimiento", - "reconozco", - "recordar", - "recuerda", - "recuerdas", - "recuerde", - "recuerden", - "recuerdo", - "recuerdos", - "recuperar", - "recursos", - "refer\u00eda", - "refiere", - "refieres", - "refiero", - "refuerzos", - "refugio", - "regalo", - "regalos", - "registro", - "registros", - "regi\u00f3n", - "reglas", - "regresa", - "regresado", - "regresar", - "regresar\u00e9", - "regrese", - "regreso", - "regres\u00f3", - "rehenes", - "relacionado", - "relaciones", - "relaci\u00f3n", - "religi\u00f3n", - "rel\u00e1jate", - "remedio", - "renunciar", - "repente", - "repito", - "reporte", - "representa", - "representante", - "reputaci\u00f3n", - "requiere", - "rescate", - "reserva", - "residencia", - "resistencia", - "resolver", - "respecto", - "respeto", - "respira", - "respiraci\u00f3n", - "respirar", - "responde", - "responder", - "responsabilidad", - "responsable", - "respuesta", - "respuestas", - "restaurante", - "restos", - "resuelto", - "resulta", - "resultado", - "resultados", - "result\u00f3", - "retiro", - "retraso", - "reuniones", - "reuni\u00f3n", - "reverendo", - "revisar", - "revista", - "revoluci\u00f3n", - "richard", - "rid\u00edculo", - "riesgo", - "riesgos", - "robado", - "robando", - "robaron", - "robaste", - "robert", - "rodillas", - "romance", - "romper", - "rompi\u00f3", - "rom\u00e1ntico", - "rostro", - "ruedas", - "rumores", - "russell", - "rutina", - "r\u00e1pida", - "r\u00e1pidamente", - "r\u00e1pido", - "sabemos", - "saberlo", - "sabido", - "sabiendo", - "sabremos", - "sabr\u00e1s", - "sabr\u00eda", - "sab\u00e9is", - "sab\u00edamos", - "sab\u00edan", - "sab\u00edas", - "sacado", - "sacarlo", - "sacarte", - "sacaste", - "sacerdote", - "sacrificio", - "sagrado", - "saldr\u00e1", - "salgamos", - "salgan", - "salgas", - "salida", - "salido", - "saliendo", - "salieron", - "salimos", - "saliste", - "saltar", - "saludable", - "saludos", - "salvado", - "salvaje", - "salvajes", - "salvar", - "sangrando", - "sangre", - "santos", - "sargento", - "seamos", - "secci\u00f3n", - "secreta", - "secretaria", - "secretario", - "secreto", - "secretos", - "sector", - "secuestro", - "secundaria", - "seguido", - "seguimos", - "seguir", - "seguir\u00e1", - "seguir\u00e9", - "segunda", - "segundo", - "segundos", - "segura", - "seguramente", - "seguridad", - "seguro", - "seguros", - "segu\u00eda", - "semana", - "semanas", - "senador", - "sencillo", - "sensaci\u00f3n", - "sensible", - "sentada", - "sentado", - "sentados", - "sentarme", - "sentarse", - "sentarte", - "sentencia", - "sentido", - "sentimiento", - "sentimientos", - "sentimos", - "sentir", - "sentirme", - "sentirse", - "sent\u00eda", - "separados", - "septiembre", - "seremos", - "serpiente", - "servicio", - "servicios", - "servir", - "servir\u00e1", - "ser\u00edan", - "ser\u00edas", - "sesi\u00f3n", - "sexual", - "sexuales", - "se\u00f1ales", - "se\u00f1ora", - "se\u00f1oras", - "se\u00f1ores", - "se\u00f1orita", - "se\u00f1oritas", - "se\u00f1or\u00eda", - "sheriff", - "siempre", - "siendo", - "sienta", - "sientas", - "siente", - "sienten", - "sientes", - "siento", - "sigamos", - "siglos", - "significa", - "significado", - "signos", - "siguen", - "sigues", - "siguiendo", - "siguiente", - "sigui\u00f3", - "silencio", - "similar", - "simple", - "simplemente", - "sinceramente", - "sincero", - "sinti\u00f3", - "siquiera", - "sistema", - "sistemas", - "sitios", - "situaci\u00f3n", - "si\u00e9ntate", - "si\u00e9ntese", - "sobrevivir", - "sobrina", - "sobrino", - "social", - "sociales", - "sociedad", - "socios", - "socorro", - "solamente", - "soldado", - "soldados", - "solicitud", - "solitario", - "soltera", - "soltero", - "soluci\u00f3n", - "sombra", - "sombras", - "sombrero", - "sonido", - "sonrisa", - "sonr\u00ede", - "sophie", - "soportar", - "soporto", - "sorprende", - "sorprendente", - "sorprendido", - "sorpresa", - "sospecha", - "sospechoso", - "sospechosos", - "so\u00f1ando", - "spencer", - "stanley", - "stephen", - "steven", - "street", - "subiendo", - "subt\u00edtulos", - "suceda", - "sucede", - "suceder", - "suceder\u00e1", - "sucedido", - "sucediendo", - "sucedi\u00f3", - "sueldo", - "suelta", - "suerte", - "sue\u00f1os", - "suficiente", - "suficientemente", - "suficientes", - "sufrido", - "sufrimiento", - "sufrir", - "sugiero", - "suicidio", - "sujeto", - "superar", - "superficie", - "superior", - "supiera", - "supieras", - "supiste", - "supone", - "supongo", - "supon\u00eda", - "supuesto", - "su\u00e9ltame", - "s\u00e1bado", - "s\u00edgueme", - "s\u00edmbolo", - "s\u00edntomas", - "s\u00f3tano", - "talento", - "taller", - "tama\u00f1o", - "tambien", - "tambi\u00e9n", - "tampoco", - "tanque", - "tantas", - "tantos", - "tardes", - "tareas", - "tarjeta", - "tarjetas", - "tatuaje", - "taylor", - "teatro", - "tecnolog\u00eda", - "televisi\u00f3n", - "tel\u00e9fono", - "tel\u00e9fonos", - "temperatura", - "templo", - "temporada", - "temporal", - "temprano", - "tendremos", - "tendr\u00e1", - "tendr\u00e1n", - "tendr\u00e1s", - "tendr\u00e9", - "tendr\u00eda", - "tendr\u00edamos", - "tendr\u00edas", - "tenemos", - "tenerlo", - "tenerte", - "tengamos", - "tengan", - "tengas", - "tenido", - "teniendo", - "teniente", - "tensi\u00f3n", - "ten\u00e9is", - "ten\u00edamos", - "ten\u00edan", - "ten\u00edas", - "teor\u00eda", - "terapia", - "tercer", - "tercera", - "tercero", - "termina", - "terminado", - "terminamos", - "terminar", - "termine", - "termino", - "termin\u00e9", - "termin\u00f3", - "terreno", - "terrible", - "terribles", - "territorio", - "terror", - "terrorista", - "terroristas", - "tesoro", - "testamento", - "testigo", - "testigos", - "testimonio", - "thomas", - "tiempo", - "tiempos", - "tienda", - "tiendas", - "tienen", - "tienes", - "tierra", - "tierras", - "tirado", - "tiroteo", - "tocado", - "tocando", - "todavia", - "todav\u00eda", - "tomado", - "tomamos", - "tomando", - "tomaron", - "tomar\u00e1", - "tomar\u00e9", - "tomaste", - "tonter\u00eda", - "tonter\u00edas", - "tontos", - "toques", - "tormenta", - "tortura", - "totalmente", - "trabaja", - "trabajaba", - "trabajado", - "trabajadores", - "trabajamos", - "trabajan", - "trabajando", - "trabajar", - "trabajas", - "trabajo", - "trabajos", - "trabaj\u00e9", - "trabaj\u00f3", - "tradici\u00f3n", - "traducci\u00f3n", - "traducido", - "traer\u00e9", - "tragedia", - "traici\u00f3n", - "traidor", - "traiga", - "traigan", - "traigo", - "trajeron", - "trajes", - "trajiste", - "trampa", - "tranquila", - "tranquilo", - "tranquilos", - "transporte", - "trasera", - "trasero", - "trataba", - "tratado", - "tratamiento", - "tratamos", - "tratan", - "tratando", - "tratar", - "tratas", - "trauma", - "travis", - "trav\u00e9s", - "tra\u00eddo", - "treinta", - "tribunal", - "tripulaci\u00f3n", - "triste", - "tropas", - "trucos", - "tr\u00e1eme", - "tr\u00e1fico", - "tuviera", - "tuvieras", - "tuvieron", - "tuvimos", - "tuviste", - "t\u00e9cnica", - "t\u00e9cnicamente", - "t\u00e9rminos", - "t\u00edpico", - "t\u00edtulo", - "t\u00f3malo", - "t\u00f3mate", - "ubicaci\u00f3n", - "unidad", - "unidades", - "unidos", - "uniforme", - "universidad", - "universo", - "urgente", - "usamos", - "usando", - "usarlo", - "ustedes", - "utilizar", - "vacaciones", - "valiente", - "vampiro", - "vampiros", - "varias", - "varios", - "vayamos", - "veamos", - "vecindario", - "vecino", - "vecinos", - "veh\u00edculo", - "veinte", - "velocidad", - "vendedor", - "vender", - "vendido", - "vendiendo", - "vendi\u00f3", - "vendr\u00e1", - "vendr\u00e1n", - "vendr\u00e1s", - "vendr\u00eda", - "veneno", - "vengan", - "venganza", - "vengas", - "venido", - "venimos", - "ventaja", - "ventana", - "ventanas", - "ventas", - "verano", - "verdad", - "verdadera", - "verdaderamente", - "verdadero", - "verdes", - "veremos", - "verg\u00fcenza", - "verlos", - "vernos", - "versi\u00f3n", - "vestido", - "vestidos", - "viajar", - "viajes", - "victor", - "victoria", - "viejas", - "viejos", - "viendo", - "vienen", - "vienes", - "viento", - "viernes", - "vieron", - "vietnam", - "vigilancia", - "vigilando", - "vincent", - "viniendo", - "viniera", - "vinieron", - "vinimos", - "viniste", - "violaci\u00f3n", - "violencia", - "violento", - "virgen", - "virginia", - "visita", - "visitar", - "visitas", - "visi\u00f3n", - "vistazo", - "vivido", - "viviendo", - "vivimos", - "volando", - "voluntad", - "volvamos", - "volvemos", - "volver", - "volveremos", - "volver\u00e1", - "volver\u00e1s", - "volver\u00e9", - "volver\u00eda", - "volviendo", - "volviste", - "volvi\u00f3", - "vomitar", - "vosotros", - "vuelta", - "vueltas", - "vuelto", - "vuelva", - "vuelvan", - "vuelvas", - "vuelve", - "vuelven", - "vuelves", - "vuelvo", - "vuestra", - "vuestras", - "vuestro", - "vuestros", - "v\u00e1monos", - "v\u00e1yanse", - "v\u00e1yase", - "v\u00edctima", - "v\u00edctimas", - "walker", - "walter", - "warren", - "washington", - "watson", - "whisky", - "william", - "williams", - "willie", - "wilson", - "zapato", - "zapatos", - "\u00e1frica", - "\u00e1ngeles", - "\u00e1rboles", - "\u00e9ramos", - "\u00edbamos", - "\u00f3rdenes", - "\u00faltima", - "\u00faltimamente", - "\u00faltimas", - "\u00faltimo", - "\u00faltimos", - "\u00fanicos" - ] -} \ No newline at end of file diff --git a/packages/yoastseo/src/languageProcessing/languages/es/config/wordComplexity.js b/packages/yoastseo/src/languageProcessing/languages/es/config/wordComplexity.js index 203367523f8..ada2d90f311 100644 --- a/packages/yoastseo/src/languageProcessing/languages/es/config/wordComplexity.js +++ b/packages/yoastseo/src/languageProcessing/languages/es/config/wordComplexity.js @@ -1,7 +1,4 @@ -import frequencyList from "./internal/frequencyList.json"; - // This is a config for the Word Complexity assessment. As such, this helper is not bundled in Yoast SEO. export default { - frequencyList: frequencyList.list, wordLength: 7, }; diff --git a/packages/yoastseo/src/languageProcessing/languages/es/helpers/checkIfWordIsComplex.js b/packages/yoastseo/src/languageProcessing/languages/es/helpers/checkIfWordIsComplex.js index 4701ba0f102..195f9b76c38 100644 --- a/packages/yoastseo/src/languageProcessing/languages/es/helpers/checkIfWordIsComplex.js +++ b/packages/yoastseo/src/languageProcessing/languages/es/helpers/checkIfWordIsComplex.js @@ -16,12 +16,13 @@ const suffixesRegex = new RegExp( suffixes ); * * @param {object} config The configuration needed for assessing the word's complexity, e.g., the frequency list. * @param {string} word The word to check. + * @param {object} premiumData The object that contains data for the assessment including the frequency list. * * @returns {boolean} Whether or not a word is complex. */ -export default function checkIfWordIsComplex( config, word ) { +export default function checkIfWordIsComplex( config, word, premiumData ) { const lengthLimit = config.wordLength; - const frequencyList = config.frequencyList; + const frequencyList = premiumData.frequencyList.list; // The Spanish word is not complex if its length is 7 characters or fewer. if ( word.length <= lengthLimit ) { diff --git a/packages/yoastseo/src/languageProcessing/languages/fr/config/internal/frequencyList.json b/packages/yoastseo/src/languageProcessing/languages/fr/config/internal/frequencyList.json deleted file mode 100644 index 561b08db265..00000000000 --- a/packages/yoastseo/src/languageProcessing/languages/fr/config/internal/frequencyList.json +++ /dev/null @@ -1,797 +0,0 @@ -{ - "source": "This list is taken from the first 5000 words of this word list https://github.com/hermitdave/FrequencyWords/blob/master/content/2018/fr/fr_50k.txt. Out of the 5000 words, we exclude words that are less than 9 characters", - "list": [ - "particulièrement", - "malheureusement", - "personnellement", - "connaissez-vous", - "responsabilités", - "professionnelle", - "responsabilité", - "extraordinaire", - "impressionnant", - "officiellement", - "enregistrement", - "petit-déjeuner", - "renseignements", - "reconnaissance", - "définitivement", - "interrogatoire", - "administration", - "félicitations", - "immédiatement", - "pourriez-vous", - "dépêchez-vous", - "professionnel", - "circonstances", - "pardonnez-moi", - "communication", - "naturellement", - "souvenez-vous", - "rappelez-vous", - "environnement", - "reconnaissant", - "techniquement", - "effectivement", - "littéralement", - "préparez-vous", - "scientifiques", - "avertissement", - "contrairement", - "permettez-moi", - "probablement", - "complètement", - "anniversaire", - "gouvernement", - "sérieusement", - "asseyez-vous", - "certainement", - "informations", - "mademoiselle", - "conversation", - "parfaitement", - "heureusement", - "connaissance", - "surveillance", - "propriétaire", - "précédemment", - "sous-titrage", - "comportement", - "scientifique", - "intelligente", - "entraînement", - "regardez-moi", - "réveille-toi", - "bibliothèque", - "merveilleuse", - "organisation", - "profondément", - "suffisamment", - "conséquences", - "autorisation", - "portefeuille", - "pouvons-nous", - "souviens-toi", - "commissariat", - "actuellement", - "pratiquement", - "intelligence", - "instructions", - "intéressante", - "personnalité", - "commandement", - "correctement", - "laissez-nous", - "pardonne-moi", - "intervention", - "thanksgiving", - "dernièrement", - "construction", - "journalistes", - "rappelle-toi", - "responsables", - "condoléances", - "terriblement", - "différemment", - "soudainement", - "aujourd'hui", - "excusez-moi", - "voulez-vous", - "rendez-vous", - "laissez-moi", - "faites-vous", - "pouvez-vous", - "responsable", - "appartement", - "intéressant", - "apparemment", - "merveilleux", - "pensez-vous", - "assieds-toi", - "regarde-moi", - "intelligent", - "directement", - "franchement", - "débarrasser", - "fantastique", - "information", - "médicaments", - "dépêche-toi", - "connaissais", - "différentes", - "travaillait", - "particulier", - "disparaître", - "arrestation", - "écoutez-moi", - "grand-chose", - "journaliste", - "département", - "honnêtement", - "commissaire", - "recommencer", - "connaissait", - "déclaration", - "enterrement", - "calmez-vous", - "opportunité", - "allons-nous", - "accompagner", - "technologie", - "appelle-moi", - "explication", - "célibataire", - "normalement", - "appelez-moi", - "sommes-nous", - "prisonniers", - "entièrement", - "proposition", - "possibilité", - "reconnaître", - "disparition", - "connaissent", - "coïncidence", - "raisonnable", - "imagination", - "pourrais-je", - "extrêmement", - "personnelle", - "travaillent", - "température", - "compétition", - "transformer", - "terroristes", - "taisez-vous", - "laboratoire", - "électricité", - "interrompre", - "culpabilité", - "travaillais", - "détends-toi", - "ressemblait", - "sous-titres", - "parlez-vous", - "préférerais", - "croyez-vous", - "malédiction", - "sincèrement", - "regarde-toi", - "importantes", - "destruction", - "expériences", - "débrouiller", - "précisément", - "échantillon", - "funérailles", - "combinaison", - "ambassadeur", - "association", - "connaissiez", - "respiration", - "changements", - "coordonnées", - "amusez-vous", - "ressemblent", - "arrangement", - "réalisateur", - "circulation", - "hélicoptère", - "mettez-vous", - "remarquable", - "chaussettes", - "partenaires", - "personnages", - "magnifiques", - "attends-moi", - "communiquer", - "pourrais-tu", - "fonctionner", - "confortable", - "destination", - "maintenant", - "exactement", - "travailler", - "impossible", - "comprendre", - "laisse-moi", - "rencontrer", - "incroyable", - "connaissez", - "simplement", - "absolument", - "impression", - "magnifique", - "passe-t-il", - "inspecteur", - "professeur", - "allez-vous", - "tranquille", - "lieutenant", - "commandant", - "nourriture", - "expérience", - "savez-vous", - "grand-mère", - "importance", - "ordinateur", - "chaussures", - "nécessaire", - "finalement", - "grand-père", - "donnez-moi", - "excuse-moi", - "université", - "sentiments", - "après-midi", - "différence", - "restaurant", - "totalement", - "évidemment", - "partenaire", - "entreprise", - "appartient", - "recherches", - "rapidement", - "formidable", - "fonctionne", - "empreintes", - "importante", - "écoute-moi", - "pourraient", - "washington", - "couverture", - "abandonner", - "américains", - "changement", - "convaincre", - "conscience", - "traitement", - "protection", - "infirmière", - "différents", - "angleterre", - "surveiller", - "facilement", - "clairement", - "traduction", - "secrétaire", - "permission", - "romantique", - "construire", - "réellement", - "gouverneur", - "croyez-moi", - "différente", - "concernant", - "représente", - "réputation", - "californie", - "conférence", - "conseiller", - "états-unis", - "reviendrai", - "discussion", - "recommence", - "dites-vous", - "uniquement", - "américaine", - "communauté", - "plaisantes", - "suivez-moi", - "prisonnier", - "travailles", - "rencontrés", - "meilleures", - "poursuivre", - "travaillez", - "récompense", - "lâchez-moi", - "personnage", - "identifier", - "est-à-dire", - "excellente", - "concentrer", - "conditions", - "kilomètres", - "correspond", - "commençons", - "appellerai", - "interroger", - "accusation", - "étiez-vous", - "télévision", - "auparavant", - "faites-moi", - "voyez-vous", - "malheureux", - "accompagne", - "demi-heure", - "assistante", - "adaptation", - "territoire", - "difficiles", - "invitation", - "expression", - "électrique", - "devrais-je", - "avons-nous", - "participer", - "laissez-le", - "commission", - "souffrance", - "deviennent", - "production", - "témoignage", - "opérations", - "principale", - "semblerait", - "collection", - "nombreuses", - "terroriste", - "enregistré", - "révolution", - "cigarettes", - "evidemment", - "commencent", - "chirurgien", - "montre-moi", - "rencontrée", - "découverte", - "disponible", - "événements", - "accueillir", - "criminelle", - "etats-unis", - "militaires", - "commercial", - "ressources", - "énormément", - "ecoute-moi", - "équipement", - "génération", - "dangereuse", - "volontaire", - "plaisantez", - "importants", - "ressembler", - "résistance", - "population", - "patrouille", - "conducteur", - "présidente", - "possession", - "rembourser", - "engagement", - "producteur", - "déposition", - "occupe-toi", - "excellence", - "pathétique", - "mouvements", - "reviennent", - "médicament", - "douloureux", - "demoiselle", - "bouteilles", - "lesquelles", - "république", - "transformé", - "maquillage", - "enlèvement", - "historique", - "téléphoner", - "téléphones", - "libération", - "malentendu", - "silencieux", - "effraction", - "atmosphère", - "intentions", - "intéresser", - "parlez-moi", - "entraîneur", - "ressembles", - "politiques", - "prostituée", - "mystérieux", - "arriverait", - "exposition", - "demanderai", - "par-dessus", - "hémorragie", - "peut-être", - "comprends", - "seulement", - "avez-vous", - "longtemps", - "attention", - "tellement", - "confiance", - "téléphone", - "important", - "capitaine", - "personnes", - "êtes-vous", - "travaille", - "difficile", - "problèmes", - "nouvelles", - "questions", - "prochaine", - "meilleure", - "président", - "commencer", - "intérieur", - "messieurs", - "apprendre", - "retrouver", - "ressemble", - "bienvenue", - "situation", - "retourner", - "rencontré", - "expliquer", - "plusieurs", - "continuer", - "recherche", - "doucement", - "donne-moi", - "connaître", - "dangereux", - "compagnie", - "différent", - "là-dedans", - "récupérer", - "opération", - "dites-moi", - "découvert", - "directeur", - "certaines", - "toilettes", - "conneries", - "personnel", - "comprenez", - "vêtements", - "intéresse", - "présenter", - "programme", - "meilleurs", - "travaillé", - "spectacle", - "rencontre", - "découvrir", - "attendais", - "histoires", - "réfléchir", - "politique", - "contraire", - "continuez", - "descendre", - "excellent", - "dernières", - "remercier", - "rejoindre", - "direction", - "troisième", - "américain", - "intention", - "procureur", - "princesse", - "calme-toi", - "attendant", - "penses-tu", - "bouteille", - "justement", - "reprendre", - "demandais", - "résultats", - "au-dessus", - "souvenirs", - "également", - "inquiétez", - "extérieur", - "inquiéter", - "aidez-moi", - "crois-moi", - "amoureuse", - "compliqué", - "naissance", - "embrasser", - "sentiment", - "relations", - "abandonné", - "désormais", - "contrôler", - "rappelles", - "laisserai", - "mauvaises", - "détective", - "autrement", - "supporter", - "militaire", - "atteindre", - "récemment", - "réveiller", - "là-dessus", - "permettre", - "assurance", - "voulaient", - "attendent", - "véritable", - "mouvement", - "puissance", - "devraient", - "explosion", - "reviendra", - "principal", - "meurtrier", - "cardiaque", - "plaisante", - "réfléchis", - "chauffeur", - "quiconque", - "lâche-moi", - "délicieux", - "dites-lui", - "ambulance", - "traverser", - "cependant", - "reconnais", - "champagne", - "forcément", - "lendemain", - "vous-même", - "mensonges", - "pourrions", - "blessures", - "cherchais", - "surveille", - "abandonne", - "cauchemar", - "construit", - "centaines", - "propriété", - "trouverai", - "combattre", - "appellent", - "ascenseur", - "pardonner", - "frontière", - "cérémonie", - "remplacer", - "installer", - "étudiants", - "faites-le", - "vengeance", - "convaincu", - "retournez", - "technique", - "attendait", - "affronter", - "entretien", - "laisse-le", - "assistant", - "davantage", - "collègues", - "assassiné", - "lentement", - "classique", - "existence", - "maîtresse", - "nationale", - "contacter", - "cigarette", - "courageux", - "condition", - "étrangers", - "permettez", - "approcher", - "charlotte", - "procédure", - "catherine", - "etes-vous", - "carrément", - "criminels", - "organiser", - "documents", - "enchantée", - "intéressé", - "poussière", - "policiers", - "montagnes", - "printemps", - "faisaient", - "commencez", - "éducation", - "elizabeth", - "elle-même", - "charmante", - "décisions", - "objection", - "chirurgie", - "ordinaire", - "hollywood", - "entraîner", - "ouverture", - "trouverez", - "incapable", - "signature", - "officiers", - "emprunter", - "respecter", - "tentative", - "supérieur", - "allemagne", - "suffisant", - "approchez", - "cherchait", - "populaire", - "allemands", - "agression", - "cherchent", - "milliards", - "premières", - "rattraper", - "demi-tour", - "parle-moi", - "réception", - "témoigner", - "influence", - "regardais", - "ministère", - "effrayant", - "inquiètes", - "francisco", - "commander", - "apprécier", - "pouvaient", - "promotion", - "innocents", - "livraison", - "formation", - "autrefois", - "habitants", - "plastique", - "dégoûtant", - "réveillée", - "adorerais", - "nucléaire", - "descendez", - "vaisseaux", - "empreinte", - "identifié", - "trouveras", - "cimetière", - "exécution", - "autorités", - "processus", - "camarades", - "caractère", - "septembre", - "tradition", - "stratégie", - "améliorer", - "créatures", - "quatrième", - "ressentir", - "attendons", - "commandes", - "regardant", - "transfert", - "escaliers", - "serviette", - "passeport", - "sacrifice", - "interview", - "événement", - "considère", - "retrouvée", - "mentionné", - "solitaire", - "regardait", - "chevalier", - "continues", - "halloween", - "invisible", - "attendrai", - "déménager", - "christine", - "passe-moi", - "laisse-la", - "sensation", - "potentiel", - "maintenir", - "oublierai", - "regardent", - "activités", - "confirmer", - "utilisent", - "exception", - "commences", - "publicité", - "rends-moi", - "regretter", - "apparence", - "essentiel", - "moment-là", - "gentleman", - "demandent", - "règlement", - "satellite", - "passagers", - "transport", - "puissante", - "autoroute", - "remarquer", - "innocente", - "protocole", - "prendrais", - "quartiers", - "accomplir", - "symptômes", - "munitions", - "conseille", - "obscurité", - "horribles", - "cherchons", - "testament", - "connaisse", - "enveloppe", - "enseigner", - "demandait", - "lancement", - "ingénieur", - "infection", - "faiblesse", - "manhattan", - "détention", - "donne-lui", - "conscient", - "compromis", - "serait-ce", - "fascinant", - "française", - "imaginais", - "fusillade", - "connexion", - "équilibre", - "rapporter", - "industrie", - "promettre", - "curiosité", - "brillante", - "satisfait", - "connaitre", - "viendrais", - "résidence", - "arriverai", - "sorcières", - "parles-tu", - "naturelle", - "augmenter", - "grossesse", - "amuse-toi", - "fréquence" - ] -} diff --git a/packages/yoastseo/src/languageProcessing/languages/fr/config/wordComplexity.js b/packages/yoastseo/src/languageProcessing/languages/fr/config/wordComplexity.js index c9cb74b3f68..cc5018b8cd9 100644 --- a/packages/yoastseo/src/languageProcessing/languages/fr/config/wordComplexity.js +++ b/packages/yoastseo/src/languageProcessing/languages/fr/config/wordComplexity.js @@ -1,7 +1,4 @@ -import frequencyList from "./internal/frequencyList.json"; - // This is a config for the Word Complexity assessment. As such, this helper is not bundled in Yoast SEO. export default { - frequencyList: frequencyList.list, wordLength: 9, }; diff --git a/packages/yoastseo/src/languageProcessing/languages/fr/helpers/checkIfWordIsComplex.js b/packages/yoastseo/src/languageProcessing/languages/fr/helpers/checkIfWordIsComplex.js index 4780a2e413c..eb6c894e7bd 100644 --- a/packages/yoastseo/src/languageProcessing/languages/fr/helpers/checkIfWordIsComplex.js +++ b/packages/yoastseo/src/languageProcessing/languages/fr/helpers/checkIfWordIsComplex.js @@ -10,12 +10,13 @@ const contractionRegex = new RegExp( contractionPrefixes ); * * @param {object} config The configuration needed for assessing the word's complexity, e.g., the frequency list. * @param {string} word The word to check. + * @param {object} premiumData The object that contains data for the assessment including the frequency list. * * @returns {boolean} Whether or not a word is complex. */ -export default function checkIfWordIsComplex( config, word ) { +export default function checkIfWordIsComplex( config, word, premiumData ) { const lengthLimit = config.wordLength; - const frequencyList = config.frequencyList; + const frequencyList = premiumData.frequencyList.list; // Normalize single quotes before checking for contractions. word = normalizeSingle( word ); @@ -28,7 +29,7 @@ export default function checkIfWordIsComplex( config, word ) { word = word.replace( contractionRegex, "" ); } - // The word is not complex if it's less than the length limit, i.e. 9 characters for French. + // The word is not complex if it's less than or the same as the length limit, i.e. 9 characters for French. if ( word.length <= lengthLimit ) { return false; } diff --git a/packages/yoastseo/src/languageProcessing/researches/wordComplexity.js b/packages/yoastseo/src/languageProcessing/researches/wordComplexity.js index 97851eacaa0..c1d6792f21d 100644 --- a/packages/yoastseo/src/languageProcessing/researches/wordComplexity.js +++ b/packages/yoastseo/src/languageProcessing/researches/wordComplexity.js @@ -27,28 +27,33 @@ const { getWords, getSentences, helpers } = languageProcessing; * @returns {ComplexWordsResult} An object containing all complex words in a given sentence. */ const getComplexWords = function( currentSentence, researcher ) { + const language = researcher.getConfig( "language" ); const checkIfWordIsComplex = researcher.getHelper( "checkIfWordIsComplex" ); const functionWords = researcher.getConfig( "functionWords" ); const wordComplexityConfig = researcher.getConfig( "wordComplexity" ); const checkIfWordIsFunction = researcher.getHelper( "checkIfWordIsFunction" ); - const morphologyData = get( researcher.getData( "morphology" ), researcher.getConfig( "language" ), false ); + const premiumData = get( researcher.getData( "morphology" ), language, false ); const allWords = getWords( currentSentence ); // Filters out function words because function words are not complex. // Words are converted to lowercase before processing to avoid excluding function words that start with a capital letter. const words = allWords.filter( word => ! ( checkIfWordIsFunction ? checkIfWordIsFunction( word ) : functionWords.includes( word ) ) ); - const results = []; + const result = { + complexWords: [], + sentence: currentSentence, + }; + + if ( ! premiumData ) { + return result; + } words.forEach( word => { - if ( checkIfWordIsComplex( wordComplexityConfig, word, morphologyData ) ) { - results.push( word ); + if ( checkIfWordIsComplex( wordComplexityConfig, word, premiumData ) ) { + result.complexWords.push( word ); } } ); - return { - complexWords: results, - sentence: currentSentence, - }; + return result; }; /** diff --git a/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/cultureAssessments.js b/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/cultureAssessments.js index 5eb8f23d816..15c53c676c0 100644 --- a/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/cultureAssessments.js +++ b/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/cultureAssessments.js @@ -6,6 +6,7 @@ import { potentiallyHarmfulUnless, harmfulNonInclusive, harmfulPotentiallyNonInclusive, + potentiallyHarmfulUnlessAnimalsObjects, } from "./feedbackStrings"; /* @@ -17,12 +18,6 @@ import { const potentiallyHarmfulUnlessCulture = "Be careful when using %1$s as it is potentially harmful. " + "Consider using an alternative, such as %2$s instead, unless you are referring to the culture " + "in which this term originated."; -/* - * Used for overgeneralizing terms, such as 'First World' or 'Third World'. - * - * "Avoid using %1$s as it is overgeneralizing. Consider using %2$s instead. - */ -const overgeneralizing = "Avoid using %1$s as it is overgeneralizing. Consider using %2$s instead. "; const cultureAssessments = [ { @@ -30,7 +25,7 @@ const cultureAssessments = [ nonInclusivePhrases: [ "First World" ], inclusiveAlternatives: "the specific name for the region or country", score: SCORES.NON_INCLUSIVE, - feedbackFormat: overgeneralizing, + feedbackFormat: potentiallyHarmful, caseSensitive: true, rule: ( words, nonInclusivePhrase ) => includesConsecutiveWords( words, nonInclusivePhrase ) .filter( isNotFollowedByException( words, nonInclusivePhrase, [ "War", "war", "Assembly", "assembly" ] ) ), @@ -40,7 +35,7 @@ const cultureAssessments = [ nonInclusivePhrases: [ "Third World" ], inclusiveAlternatives: "the specific name for the region or country", score: SCORES.NON_INCLUSIVE, - feedbackFormat: overgeneralizing, + feedbackFormat: potentiallyHarmful, caseSensitive: true, rule: ( words, nonInclusivePhrase ) => includesConsecutiveWords( words, nonInclusivePhrase ) .filter( isNotFollowedByException( words, nonInclusivePhrase, [ "War", "war", "Quarterly", "quarterly", "country" ] ) ), @@ -112,8 +107,7 @@ const cultureAssessments = [ nonInclusivePhrases: [ "oriental" ], inclusiveAlternatives: "Asian. When possible, be more specific (e.g. East Asian)", score: SCORES.POTENTIALLY_NON_INCLUSIVE, - feedbackFormat: harmfulPotentiallyNonInclusive + " Unless you are referring to objects or animals, " + - "consider using an alternative, such as %2$s.", + feedbackFormat: potentiallyHarmfulUnlessAnimalsObjects, }, { identifier: "asianAmerican", @@ -242,15 +236,15 @@ const cultureAssessments = [ { identifier: "gypsy", nonInclusivePhrases: [ "gypsy", "gipsy" ], - inclusiveAlternatives: [ "Romani, Romani person", "traveler, wanderer, free-spirited" ], + inclusiveAlternatives: [ "Rom, Roma person, Romani, Romani person", "traveler, wanderer, free-spirited" ], score: SCORES.POTENTIALLY_NON_INCLUSIVE, feedbackFormat: [ potentiallyHarmfulUnless, "If you are referring to a lifestyle rather than the ethnic group or " + - "their music, consider using an alternative such as %3$s." ].join( " " ), + "their music, consider using an alternative such as %3$s." ].join( " " ), }, { identifier: "gypsies", nonInclusivePhrases: [ "gypsies", "gipsies" ], - inclusiveAlternatives: [ "Romani, Romani people", "travelers, wanderers, free-spirited" ], + inclusiveAlternatives: [ "Roma, Romani, Romani people", "travelers, wanderers, free-spirited" ], score: SCORES.POTENTIALLY_NON_INCLUSIVE, feedbackFormat: [ potentiallyHarmfulUnless, "If you are referring to a lifestyle rather than the ethnic group or " + "their music, consider using an alternative such as %3$s." ].join( " " ), @@ -312,14 +306,6 @@ const cultureAssessments = [ score: SCORES.NON_INCLUSIVE, feedbackFormat: potentiallyHarmful, }, - { - identifier: "ebonics", - nonInclusivePhrases: [ "Ebonics" ], - inclusiveAlternatives: "African American English, African American Language", - score: SCORES.NON_INCLUSIVE, - feedbackFormat: potentiallyHarmful, - caseSensitive: true, - }, { identifier: "powWow", nonInclusivePhrases: [ "pow-wow" ], @@ -344,16 +330,16 @@ const cultureAssessments = [ { identifier: "firstWorldCountries", nonInclusivePhrases: [ "first world countries" ], - inclusiveAlternatives: "the specific name for the countries or regions", + inclusiveAlternatives: "the specific name for the regions or countries", score: SCORES.NON_INCLUSIVE, - feedbackFormat: overgeneralizing, + feedbackFormat: potentiallyHarmful, }, { identifier: "firstWorldHyphen", nonInclusivePhrases: [ "first-world" ], - inclusiveAlternatives: "the specific name for the country or region", + inclusiveAlternatives: "the specific name for the region or country", score: SCORES.NON_INCLUSIVE, - feedbackFormat: overgeneralizing, + feedbackFormat: potentiallyHarmful, }, { identifier: "third-worldCountry", diff --git a/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/disabilityAssessments.js b/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/disabilityAssessments.js index a9218ba575d..c03d81a2a84 100644 --- a/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/disabilityAssessments.js +++ b/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/disabilityAssessments.js @@ -1,6 +1,5 @@ import { potentiallyHarmful, - potentiallyHarmfulCareful, potentiallyHarmfulUnless, harmfulPotentiallyNonInclusive, alternative, @@ -30,12 +29,7 @@ import { sprintf } from "@wordpress/i18n"; * "Avoid using %1$s as it is derogatory. Consider using an alternative, such as %2$s instead." */ const derogatory = "Avoid using %1$s as it is derogatory. Consider using an alternative, such as %2$s instead."; -/* - * Used for generalizing terms, such as 'the mentally ill'. - * - * "Avoid using %1$s as it is generalizing. Consider using an alternative, such as %2$s instead." - */ -const generalizing = "Avoid using %1$s as it is generalizing. Consider using an alternative, such as %2$s instead."; + /* * Used for terms that are inclusive only if you are referring to a medical condition, for example 'manic' or 'OCD'. * @@ -155,8 +149,8 @@ const disabilityAssessments = [ identifier: "daft", nonInclusivePhrases: [ "daft" ], inclusiveAlternatives: "uninformed, ignorant, foolish, inconsiderate, irrational, reckless", - score: SCORES.POTENTIALLY_NON_INCLUSIVE, - feedbackFormat: potentiallyHarmfulCareful, + score: SCORES.NON_INCLUSIVE, + feedbackFormat: potentiallyHarmful, }, { identifier: "handicapped", @@ -415,7 +409,7 @@ const disabilityAssessments = [ inclusiveAlternatives: "to be not impressed by, to be not enthusiastic about, to be not into, to not like", score: SCORES.NON_INCLUSIVE, feedbackFormat: phrasesWithCrazyFeedback, - // Target only when preceded by a form of "to be", the negation "not", and an an optional intensifier (e.g. "is not so crazy about" ). + // Target only when preceded by a form of "to be", the negation "not", and an optional intensifier (e.g. "is not so crazy about" ). rule: ( words, nonInclusivePhrase ) => { return includesConsecutiveWords( words, nonInclusivePhrase ) .filter( isNotPrecededByException( words, formsOfToBeNotWithOptionalIntensifier ) ); @@ -427,7 +421,7 @@ const disabilityAssessments = [ inclusiveAlternatives: "to love, to be obsessed with, to be infatuated with", score: SCORES.NON_INCLUSIVE, feedbackFormat: phrasesWithCrazyFeedback, - // Target only when preceded by a form of "to be" and an an optional intensifier (e.g. "am so crazy about") + // Target only when preceded by a form of "to be" and an optional intensifier (e.g. "am so crazy about") rule: ( words, nonInclusivePhrase ) => { return includesConsecutiveWords( words, nonInclusivePhrase ) .filter( isNotPrecededByException( words, formsOfToBeWithOptionalIntensifier ) ); @@ -575,8 +569,10 @@ const disabilityAssessments = [ "selfish, egotistical, self-centered, self-absorbed, vain, toxic, manipulative" ], score: SCORES.POTENTIALLY_NON_INCLUSIVE, feedbackFormat: "Be careful when using %1$s as it is potentially harmful. If you are referencing the " + - "medical condition, use %2$s instead. If you are not referencing the medical condition, consider other" + - " alternatives to describe the trait or behavior, such as %3$s.", + "medical condition, use %2$s instead, unless referring to someone who explicitly wants to be referred to with this term." + + " If you are not referencing the medical condition, consider other alternatives to describe the trait or behavior, such as %3$s.", + rule: ( words, nonInclusivePhrase ) => includesConsecutiveWords( words, nonInclusivePhrase ) + .filter( isNotFollowedByException( words, nonInclusivePhrase, [ "personality disorder" ] ) ), }, { identifier: "OCD", @@ -598,7 +594,7 @@ const disabilityAssessments = [ nonInclusivePhrases: [ "the mentally ill" ], inclusiveAlternatives: "people who are mentally ill, mentally ill people", score: SCORES.NON_INCLUSIVE, - feedbackFormat: [ generalizing ].join( " " ), + feedbackFormat: potentiallyHarmful, rule: ( words, nonInclusivePhrase ) => { return includesConsecutiveWords( words, nonInclusivePhrase ) .filter( notInclusiveWhenStandalone( words, nonInclusivePhrase ) ); @@ -609,7 +605,7 @@ const disabilityAssessments = [ nonInclusivePhrases: [ "the disabled" ], inclusiveAlternatives: "people who have a disability, disabled people", score: SCORES.NON_INCLUSIVE, - feedbackFormat: [ potentiallyHarmful ].join( " " ), + feedbackFormat: potentiallyHarmful, rule: ( words, nonInclusivePhrase ) => { return includesConsecutiveWords( words, nonInclusivePhrase ) .filter( notInclusiveWhenStandalone( words, nonInclusivePhrase ) ); diff --git a/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/feedbackStrings.js b/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/feedbackStrings.js index 320ddcfd9d2..1f005c8814d 100644 --- a/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/feedbackStrings.js +++ b/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/feedbackStrings.js @@ -53,3 +53,7 @@ export const potentiallyHarmfulUnlessNonInclusive = [ harmfulNonInclusive, alter * "Alternatively, if talking about a specific person, use their preferred descriptor if known." */ export const preferredDescriptorIfKnown = "Alternatively, if talking about a specific person, use their preferred descriptor if known."; + +// An additional string to target phrases that are potentially non-inclusive unless referring to animals or objects. +export const potentiallyHarmfulUnlessAnimalsObjects = [ harmfulPotentiallyNonInclusive, + "Unless you are referring to objects or animals, consider using an alternative, such as %2$s." ].join( " " ); diff --git a/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/otherAssessments.js b/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/otherAssessments.js index 88d3d5298ad..241141d4d52 100644 --- a/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/otherAssessments.js +++ b/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/otherAssessments.js @@ -1,32 +1,56 @@ import { SCORES } from "./scores"; +import { harmfulPotentiallyNonInclusive, potentiallyHarmfulUnlessAnimalsObjects } from "./feedbackStrings"; const otherAssessments = [ { identifier: "minorities", nonInclusivePhrases: [ "minorities" ], - inclusiveAlternatives: [ "marginalized groups", "underrepresented groups", "gender and sexuality minorities" ], + inclusiveAlternatives: [ "members of the LGBTQ+ community", "Indigenous peoples", "marginalized groups", + "religious minorities" ], score: SCORES.POTENTIALLY_NON_INCLUSIVE, - feedbackFormat: "Be careful when using %1$s as it is potentially overgeneralizing. " + - "Consider using an alternative, such as %2$s, %3$s or specific minorities, such as %4$s.", + feedbackFormat: [ harmfulPotentiallyNonInclusive, "Consider using an alternative" + + " by being specific about which group(s) of people you are referring to. For example: %2$s, %3$s, %4$s. " + + "In case an alternative is not available, make sure to specify the type of minorities you are referring to, e.g., %5$s." ].join( " " ), }, { identifier: "normal", - nonInclusivePhrases: [ "normal person", "normal people", "normal behaviour", "normal behavior", "mentally" + - " normal", "behaviorally normal", "behaviourally normal", "psychologically normal" ], + nonInclusivePhrases: [ "normal person", "normal people", "mentally normal", "psychologically normal" ], inclusiveAlternatives: [ "typical" ], score: SCORES.NON_INCLUSIVE, feedbackFormat: "Avoid using normal as it is potentially harmful. " + "Consider using an alternative, such as %2$s or a specific characteristic or experience if it is known.", }, + { + identifier: "behaviorallyNormal", + nonInclusivePhrases: [ "behaviorally normal", "behaviourally normal" ], + inclusiveAlternatives: [ "showing typical behavior or a specific characteristic or experience if it is known" ], + score: SCORES.POTENTIALLY_NON_INCLUSIVE, + feedbackFormat: potentiallyHarmfulUnlessAnimalsObjects, + }, { identifier: "abnormal", - nonInclusivePhrases: [ "abnormal person", "abnormal people", "abnormal behaviour", "abnormal behavior", "mentally" + - " abnormal", "behaviorally abnormal", "behaviourally abnormal", "psychologically abnormal" ], + nonInclusivePhrases: [ "abnormal person", "abnormal people", "mentally abnormal", "psychologically abnormal" ], inclusiveAlternatives: [ "atypical" ], score: SCORES.NON_INCLUSIVE, feedbackFormat: "Avoid using abnormal as it is potentially harmful. " + "Consider using an alternative, such as %2$s or a specific characteristic or experience if it is known.", }, + { + identifier: "behaviorallyAbnormal", + nonInclusivePhrases: [ "behaviorally abnormal", "behaviourally abnormal" ], + inclusiveAlternatives: [ "showing atypical behavior, showing dysfunctional behavior " + + "or a specific characteristic or experience if it is known" ], + score: SCORES.POTENTIALLY_NON_INCLUSIVE, + feedbackFormat: potentiallyHarmfulUnlessAnimalsObjects, + }, + { + identifier: "abnormalBehavior", + nonInclusivePhrases: [ "abnormal behavior", "abnormal behaviour" ], + inclusiveAlternatives: [ "atypical behavior, unusual behavior " + + "or a specific characteristic or experience if it is known" ], + score: SCORES.POTENTIALLY_NON_INCLUSIVE, + feedbackFormat: potentiallyHarmfulUnlessAnimalsObjects, + }, ]; otherAssessments.forEach( assessment => { diff --git a/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/sesAssessments.js b/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/sesAssessments.js index 3cbea2f7999..650499ffdf8 100644 --- a/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/sesAssessments.js +++ b/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/sesAssessments.js @@ -1,4 +1,4 @@ -import { potentiallyHarmful, potentiallyHarmfulCareful, potentiallyHarmfulUnless } from "./feedbackStrings"; +import { potentiallyHarmful, potentiallyHarmfulUnless } from "./feedbackStrings"; import { SCORES } from "./scores"; import { includesConsecutiveWords } from "../helpers/includesConsecutiveWords"; import notInclusiveWhenStandalone from "../helpers/notInclusiveWhenStandalone"; @@ -64,15 +64,15 @@ const sesAssessments = [ identifier: "felon", nonInclusivePhrases: [ "felon" ], inclusiveAlternatives: "person with felony convictions, person who has been incarcerated", - score: SCORES.POTENTIALLY_NON_INCLUSIVE, - feedbackFormat: potentiallyHarmfulCareful, + score: SCORES.NON_INCLUSIVE, + feedbackFormat: potentiallyHarmful, }, { identifier: "felons", nonInclusivePhrases: [ "felons" ], inclusiveAlternatives: "people with felony convictions, people who have been incarcerated", - score: SCORES.POTENTIALLY_NON_INCLUSIVE, - feedbackFormat: potentiallyHarmfulCareful, + score: SCORES.NON_INCLUSIVE, + feedbackFormat: potentiallyHarmful, }, { identifier: "ex-offender", @@ -91,9 +91,9 @@ const sesAssessments = [ { identifier: "theHomeless", nonInclusivePhrases: [ "the homeless" ], - inclusiveAlternatives: "people experiencing homelessness ", + inclusiveAlternatives: "people experiencing homelessness", score: SCORES.NON_INCLUSIVE, - feedbackFormat: "Avoid using %1$s as it is generalizing. Consider using %2$s instead.", + feedbackFormat: potentiallyHarmful, rule: ( words, nonInclusivePhrase ) => { return includesConsecutiveWords( words, nonInclusivePhrase ) .filter( notInclusiveWhenStandalone( words, nonInclusivePhrase ) ); @@ -102,9 +102,9 @@ const sesAssessments = [ { identifier: "theUndocumented", nonInclusivePhrases: [ "the undocumented" ], - inclusiveAlternatives: "people who are undocumented, undocumented people, people without papers ", + inclusiveAlternatives: "people who are undocumented, undocumented people, people without papers", score: SCORES.NON_INCLUSIVE, - feedbackFormat: "Avoid using %1$s as it is potentially overgeneralizing. Consider using %2$s instead.", + feedbackFormat: potentiallyHarmful, rule: ( words, nonInclusivePhrase ) => { return includesConsecutiveWords( words, nonInclusivePhrase ) .filter( notInclusiveWhenStandalone( words, nonInclusivePhrase ) ); @@ -113,9 +113,9 @@ const sesAssessments = [ { identifier: "thePoor", nonInclusivePhrases: [ "the poor" ], - inclusiveAlternatives: [ "people whose income is below the poverty threshold", "people with low-income" ], + inclusiveAlternatives: "people whose income is below the poverty threshold, people with low-income", score: SCORES.NON_INCLUSIVE, - feedbackFormat: "Avoid using %1$s as it is potentially overgeneralizing. Consider using %2$s or %3$s instead.", + feedbackFormat: potentiallyHarmful, rule: ( words, nonInclusivePhrase ) => { return includesConsecutiveWords( words, nonInclusivePhrase ) .filter( notInclusiveWhenStandalone( words, nonInclusivePhrase ) ); diff --git a/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/sexualOrientationAssessments.js b/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/sexualOrientationAssessments.js index 39671fcfc5c..832254584c3 100644 --- a/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/sexualOrientationAssessments.js +++ b/packages/yoastseo/src/scoring/assessments/inclusiveLanguage/configuration/sexualOrientationAssessments.js @@ -1,13 +1,13 @@ import { SCORES } from "./scores"; +import { potentiallyHarmfulUnless } from "./feedbackStrings"; const sexualOrientationAssessments = [ { identifier: "homosexuals", nonInclusivePhrases: [ "homosexuals" ], - inclusiveAlternatives: "gay men, queer people, lesbians", + inclusiveAlternatives: "gay people, queer people, lesbians, gay men, people in same-gender relationships", score: SCORES.POTENTIALLY_NON_INCLUSIVE, - feedbackFormat: "Be careful when using %1$s as it may overgeneralize or be harmful. " + - "Instead, be specific about the group you are referring to (e.g. %2$s).", + feedbackFormat: [ potentiallyHarmfulUnless, "Be as specific possible and use people's preferred labels if they are known." ].join( " " ), }, ]; diff --git a/readme.txt b/readme.txt index 0b168e48721..a311bda092a 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Donate link: https://yoa.st/1up License: GPLv3 License URI: http://www.gnu.org/licenses/gpl.html Tags: SEO, XML sitemap, Content analysis, Readability, Schema -Tested up to: 6.3 +Tested up to: 6.4 Stable tag: 21.4 Requires PHP: 7.2.5 @@ -38,15 +38,15 @@ These are the common struggles website owners face when trying to master the art With Yoast SEO, you can overcome these challenges and unlock extraordinary gains: -* Beat the competition: Leave your rivals in the dust with our powerful SEO tools. Outperform industry competitors and enjoy the traffic and recognition you deserve. +* **Beat the competition:** Leave your rivals in the dust with our powerful SEO tools. Outperform industry competitors and enjoy the traffic and recognition you deserve. -* Streamline your SEO strategy: Bid farewell to the complexities of SEO. Yoast SEO handles the technical aspects, such as canonical URLs and meta tags, automating essential optimizations behind the scenes. Unleash your focus on creating captivating content that connects with your audience. +* **Streamline your SEO strategy:** Bid farewell to the complexities of SEO. Yoast SEO handles the technical aspects, such as canonical URLs and meta tags, automating essential optimizations behind the scenes. Unleash your focus on creating captivating content that connects with your audience. -* Climb those rankings: Take advantage of advanced features like XML sitemaps, title and meta description templating, and Schema.org structured data integration. Empower search engines to fully understand and appreciate your website, helping you reach the top of search results. +* **Climb those rankings:** Take advantage of advanced features like XML sitemaps, title and meta description templating, and Schema.org structured data integration. Empower search engines to fully understand and appreciate your website, helping you reach the top of search results. -* Optimize content mastery: Yoast SEO offers comprehensive analysis tools that help elevate your content's SEO and readability. Get powerful insights and actionable recommendations to craft extraordinary content that resonates with readers and search engines. But there's more! Yoast SEO Premium has unique generative AI features to help write awesome titles and meta descriptions. +* **Optimize content mastery:** Yoast SEO offers comprehensive analysis tools that help elevate your content's SEO and readability. Get powerful insights and actionable recommendations to craft extraordinary content that resonates with readers and search engines. But there's more! Yoast SEO Premium has unique generative AI features to help write awesome titles and meta descriptions. -* Elevate user experience: Yoast SEO paves the way for an exceptional website experience. Engage your audience with intuitive site breadcrumbs, fast loading times, and great content! +* **Elevate user experience:** Yoast SEO paves the way for an exceptional website experience. Engage your audience with intuitive site breadcrumbs, fast loading times, and great content! ### LET'S GO OVER KEY FEATURES IN YOAST SEO @@ -67,63 +67,63 @@ Connecting your site to vital webmaster tools like Google's Search Console usual Although technical optimization is a big part of SEO, it's not easy.\ Yoast understands that only some people who work on SEO are experts or have the time to dive into the technical aspects of a website. That's why Yoast SEO handles much of the technical optimization, freeing up your time to work on other parts of your website, like writing awesome content that attracts visitors. -* Get automated technical SEO improvements, like optimized meta tags, right out of the box. +* **Get automated technical SEO improvements**, like optimized meta tags, right out of the box. -* Add canonical URLs to tell search engines which content they should show when you have pages with similar content. +* **Add canonical URLs** to tell search engines which content they should show when you have pages with similar content. -* Get advanced XML sitemaps, making it effortless for search engines to understand your site structure and index your web pages effectively. +* Get **advanced XML sitemaps**, making it effortless for search engines to understand your site structure and index your web pages effectively. -* Elevate your brand presence with customizable titles and meta description templating, ensuring consistent and compelling search result snippets that drive click-through rates. +* **Elevate your brand presence** with customizable titles and meta description templating, ensuring consistent and compelling search result snippets that drive click-through rates. -* Get best-in-class Schema.org structured data integration, significantly increasing your chances of getting visually rich search results that attract more users. +* **Get best-in-class Schema.org structured data integration**, significantly increasing your chances of getting visually rich search results that attract more users. -* Take complete control over your site's breadcrumbs, allowing visitors and search engines to navigate your website seamlessly. +* **Take complete control over your site's breadcrumbs**, allowing visitors and search engines to navigate your website seamlessly. -* Significantly improves your website's loading times, courtesy of Yoast SEO's innovative data management techniques tailored for WordPress. +* **Significantly improves your website's loading times**, courtesy of Yoast SEO's innovative data management techniques tailored for WordPress. -* [Advanced] Yoast SEO comes with a wide range of crawl settings that optimize how search engines crawl your site and reduce its carbon footprint. This lowers your site's environmental impact and contributes to a sustainable web. +* [Advanced] Yoast SEO comes with a wide range of crawl settings that **optimize how search engines crawl your site** and reduce its carbon footprint. This lowers your site's environmental impact and contributes to a sustainable web. #### WRITE AWESOME CONTENT THAT USERS AND SEARCH ENGINES LOVE -Unlock the full potential of your content with Yoast SEO's state-of-the-art content analysis. Crafting compelling content becomes easier with Yoast SEO's suite of features designed to help you increase your website's content performance. +Unlock the full potential of your content with Yoast SEO's **state-of-the-art content analysis**. Crafting compelling content becomes easier with Yoast SEO's suite of features designed to help you increase your website's content performance. -* Leverage detailed SEO analysis that guides you toward creating SEO-friendly content, allowing you to target the right keywords and boost your visibility in search results. +* **Leverage detailed SEO analysis** that guides you toward creating SEO-friendly content, allowing you to target the right keywords and boost your visibility in search results. -* Drive engagement and enhance readability with the integrated readability analysis. Ensure your content is clear, concise, and effortlessly readable by humans and search engines alike. +* **Drive engagement and enhance readability** with the integrated readability analysis. Ensure your content is clear, concise, and effortlessly readable by humans and search engines alike. -* To effectively cater to a global audience, benefit from Yoast SEO's full language support for English, German, French, Dutch, Spanish, Italian, Russian, Indonesian, Polish, Portuguese, Arabic, Swedish, Hebrew, Hungarian, Turkish, Czech, Norwegian, Slovak, and Greek. +* To **effectively cater to a global audience**, benefit from Yoast SEO's full language support for English, German, French, Dutch, Spanish, Italian, Russian, Indonesian, Polish, Portuguese, Arabic, Swedish, Hebrew, Hungarian, Turkish, Czech, Norwegian, Slovak, and Greek. -* Preview your content as it will appear in search results directly within Yoast SEO, even on mobile devices. This helps you to fine-tune your meta titles and descriptions to maximize click-through rates. +* Preview your content as it will appear in search results directly within Yoast SEO, even on mobile devices. This helps you to **fine-tune your meta titles and descriptions to maximize click-through rates**. -* Enable your HowTo content to be displayed in search results by using the innovative Schema structured data blocks for the WordPress block editor +* Enable your HowTo content to be displayed in search results by using the **innovative Schema structured data blocks** for the WordPress block editor -* A dedicated breadcrumbs block ensures your users always know their location within your website. +* **A dedicated breadcrumbs block** ensures your users always know their location within your website. -* Embrace inclusivity in your content creation process with the inclusive language analysis. This optional feature analyzes your text and provides suggestions to make your content more inclusive and considerate of different audiences. By using inclusive language, you can create a welcoming environment and ensure your content resonates with diverse groups of people. +* **Embrace inclusivity in your content creation process with the inclusive language analysis**. This optional feature analyzes your text and provides suggestions to make your content more inclusive and considerate of different audiences. By using inclusive language, you can create a welcoming environment and ensure your content resonates with diverse groups of people. -* Seamlessly do keyword research right within the plugin with the Semrush integration. Find out what related keywords people are searching for, so you can optimize your content to reach more audiences. +* **Seamlessly do keyword research** right within the plugin with the Semrush integration. Find out what related keywords people are searching for, so you can optimize your content to reach more audiences. -* Track your rankings in Yoast SEO with the Wincher integration. Yoast SEO and Wincher show how your content and keywords rank in Google. So that you immediately know if your optimizations are paying off or if you need to take more action! +* **Track your rankings in Yoast SEO** with the Wincher integration. Yoast SEO and Wincher show how your content and keywords rank in Google. So that you immediately know if your optimizations are paying off or if you need to take more action! -* Are you using Elementor to build your website? No worries because Yoast SEO integrates with Elementor. Take advantage of all Yoast SEO's benefits within your favorite website builder! +* Are you using Elementor to build your website? No worries because **Yoast SEO integrates with Elementor**. Take advantage of all Yoast SEO's benefits within your favorite website builder! -* Yoast SEO Premium even has advanced AI features, helping you write titles and meta descriptions at the touch of a button thanks to generative AI. We don't use a credit system for this, so this artificial intelligence tool is free to use once you have Yoast SEO Premium. +* **Yoast SEO Premium even has advanced AI features**, helping you write titles and meta descriptions at the touch of a button thanks to generative AI. We don't use a credit system for this, so this artificial intelligence tool is free to use once you have Yoast SEO Premium. #### KEEP YOUR SITE IN SHAPE FOR SEO Yoast SEO empowers you to keep your website in perfect shape, regardless of your role or expertise: -* Fine-tune your website's engine, allowing you to focus on creating engaging and valuable content. With Yoast SEO, technical optimization becomes effortless, allowing you to prioritize what truly matters. +* Fine-tune your website's engine, allowing you to focus on creating engaging and valuable content. With Yoast SEO, **technical optimization becomes effortless**, allowing you to prioritize what truly matters. -* Structure your website easily using Yoast SEO's cornerstone content features, enabling search engines to understand and index your most important pages effectively. +* **Structure your website easily** using Yoast SEO's cornerstone content features, enabling search engines to understand and index your most important pages effectively. -* Translate valuable content into structured data where applicable, allowing search engines to fully comprehend your website's meaning and context. +* **Translate valuable content into structured data** where applicable, allowing search engines to fully comprehend your website's meaning and context. -* Streamline collaboration and empower your team with SEO roles, granting specific access to colleagues and stakeholders. Efficiently manage your SEO strategy and ensure everyone is aligned toward achieving optimal results. +* Streamline collaboration and **empower your team with SEO roles**, granting specific access to colleagues and stakeholders. Efficiently manage your SEO strategy and ensure everyone is aligned toward achieving optimal results. -* Yoast SEO includes a powerful front-end SEO inspector that allows you to preview and fine-tune the SEO settings directly on your website's front end. With this intuitive tool, you can easily optimize elements such as meta titles, meta descriptions, URL slugs, robots meta tags, and structured data by seeing their appearance in real-time. +* Yoast SEO includes a **powerful front-end SEO inspector** that allows you to preview and fine-tune the SEO settings directly on your website's front end. With this intuitive tool, you can easily optimize elements such as meta titles, meta descriptions, URL slugs, robots meta tags, and structured data by seeing their appearance in real-time. -* Yoast SEO has a regular 2-week update cycle, ensuring you always stay up-to-date with the latest development and updates from search engines. +* **Yoast SEO has a regular 2-week update cycle**, ensuring you always stay up-to-date with the latest development and updates from search engines. #### POWERFUL INTEGRATION WITH OTHER TOOLS @@ -199,6 +199,8 @@ Not only do you get many additional benefits by upgrading to [Yoast SEO Premium] * Get 24/7 personalized e-mail support, so no matter when a question or issue arises, you're never left in the dark. Whether it's a technical hurdle or simply a need for guidance, our dedicated support team is always available to assist. +* Avoid that your content is used to train AI bots: Effortlessly safeguard your intellectual property, uphold data privacy, and maintain control over your valuable content by blocking AI bots from secretly scraping it. These AI web crawlers include OpenAI's GPTBot, Common Crawl's CCBot and Google-Extended, used to train Google Bard. + ### EXTEND YOUR WORDPRESS SEO Take your WordPress SEO to new heights with these powerful Yoast SEO add-ons: @@ -340,6 +342,38 @@ Your question has most likely been answered on our help center: [yoast.com/help/ == Changelog == += 21.5 = + +Release date: 2023-10-31 + +Yoast SEO 21.5 is out today! In this release, you'll find improvements to our inclusive language feature, updates to handling RSS feeds and much more. Find out more about what's new in Yoast SEO 21.5 in [our release post](https://yoa.st/release-31-10-23)! + +#### Enhancements + +* Adds support for the new `wp_attachment_pages_enabled` option introduced by WordPress 6.4, reducing the chances of inconsistencies with Yoast SEO's own \"Enable media pages\" setting. +* Improves the _inclusive language_ analysis by making the feedback more clear and consistent, refining the list of targeted phrases, and adding more alternatives for some of the non-inclusive phrases. Specifically, this includes the following changes: + * Aligns the traffic light color and written feedback for all phrases. + * Makes some feedback strings more accurate by replacing the word ‘overgeneralizing’ with ‘harmful’. + * Adds ‘Rom’ and ‘Roma’ as additional alternatives to ‘gypsy’. + * Adds additional alternatives to ‘homosexuals’. + * Improves the feedback shown for the phrases ‘abnormal behaviour’, ‘behaviourally normal’, and ‘behaviourally abnormal’. + * Improves the feedback shown for the word ‘minorities’. + * Removes ‘narcissistic’ as a targeted phrase when followed by ‘personality disorder’. + * Removes ‘Ebonics’ and ‘normal behaviour’ from the list of targeted phrases. +* Removes the automatic `rel=nofollow` attribute for links in the RSS feed. + +#### Bugfixes + +* Fixes a bug where console warnings about incorrect prop types would be shown on the integrations page. + +#### Other + +* Adds indexation exclusion for Gutenberg Patterns taxonomy. +* Improves the FAQ block description by removing any reference to the previous restriction of one block per post. +* Improves the inline documentation for the `WPSEO_Option` class. Props to [costdev](https://github.com/costdev). +* Leverages Script Strategy feature to add the async attribute to the `wordproof` script in case WordPress version is 6.3 or higher. Props to [adamsilverstein](https://github.com/adamsilverstein). +* Sets the WordPress tested up to version to 6.4. + = 21.4 = Release date: 2023-10-17 @@ -364,20 +398,5 @@ We've just released Yoast SEO 21.4. In this release, we've focused on general en * Fixes a bug where the first-time configuration' site representation logo button would not be translated. Props to [fxbenard](https://github.com/fxbenard). * Fixes a bug where the _single title_ assessment would be triggered when adding a H1 without text. -= 21.3 = - -Release date: 2023-10-03 - -Yoast SEO 21.3 is out! In this release, we've focused on improving the plugin's performance, especially regarding handling huge posts on complex websites. Find out more about what's new in Yoast SEO 21.3 in [our release post](https://yoa.st/release-3-10-23)! - -#### Enhancements - -* Enhances post-saving performance in certain conditions for a smoother and more efficient user experience. - -#### Bugfixes - -* Fixes a bug where the notifications counter of the admin bar menu would not show with the correct style on the frontend. -* Fixes a bug where the slug in the search appearance editor would not be set when published posts were edited in the classic editor and the "core/editor" store was available. - = Earlier versions = For the changelog of earlier versions, please refer to [the changelog on yoast.com](https://yoa.st/yoast-seo-changelog). diff --git a/src/actions/configuration/first-time-configuration-action.php b/src/actions/configuration/first-time-configuration-action.php index fc04bab966e..e9dc3c5ff60 100644 --- a/src/actions/configuration/first-time-configuration-action.php +++ b/src/actions/configuration/first-time-configuration-action.php @@ -58,19 +58,13 @@ public function __construct( Options_Helper $options_helper, Social_Profiles_Hel * @return object The response object. */ public function set_site_representation( $params ) { - $failures = []; + $failures = []; + $old_values = $this->get_old_values( self::SITE_REPRESENTATION_FIELDS ); foreach ( self::SITE_REPRESENTATION_FIELDS as $field_name ) { if ( isset( $params[ $field_name ] ) ) { - if ( $field_name === 'description' && \current_user_can( 'manage_options' ) ) { - $result = \update_option( 'blogdescription', $params['description'] ); - if ( ! $result && $params['description'] === \get_option( 'blogdescription' ) ) { - $result = true; - } - } - else { - $result = $this->options_helper->set( $field_name, $params[ $field_name ] ); - } + $result = $this->options_helper->set( $field_name, $params[ $field_name ] ); + if ( ! $result ) { $failures[] = $field_name; } @@ -81,6 +75,17 @@ public function set_site_representation( $params ) { $this->options_helper->set( 'company_logo_meta', false ); $this->options_helper->set( 'person_logo_meta', false ); + /** + * Action: 'wpseo_post_update_site_representation' - Allows for Hiive event tracking. + * + * @param array The new values of the options. + * @param array The old values of the options. + * @param array The options that failed to be saved. + * + * @internal + */ + \do_action( 'wpseo_ftc_post_update_site_representation', $params, $old_values, $failures ); + if ( \count( $failures ) === 0 ) { return (object) [ 'success' => true, @@ -104,7 +109,19 @@ public function set_site_representation( $params ) { * @return object The response object. */ public function set_social_profiles( $params ) { - $failures = $this->social_profiles_helper->set_organization_social_profiles( $params ); + $old_values = $this->get_old_values( \array_keys( $this->social_profiles_helper->get_organization_social_profile_fields() ) ); + $failures = $this->social_profiles_helper->set_organization_social_profiles( $params ); + + /** + * Action: 'wpseo_post_update_social_profiles' - Allows for Hiive event tracking. + * + * @param array The new values of the options. + * @param array The old values of the options. + * @param array The options that failed to be saved. + * + * @internal + */ + \do_action( 'wpseo_ftc_post_update_social_profiles', $params, $old_values, $failures ); if ( empty( $failures ) ) { return (object) [ @@ -186,6 +203,18 @@ public function set_enable_tracking( $params ) { $success = $this->options_helper->set( 'tracking', $params['tracking'] ); } + /** + * Action: 'wpseo_post_update_enable_tracking' - Allows for Hiive event tracking. + * + * @param array The new value. + * @param array The old value. + * @param bool Whether the option failed to be stored. + * + * @internal + */ + // $success is negated to be aligned with the other two actions which pass $failures. + \do_action( 'wpseo_ftc_post_update_enable_tracking', $params['tracking'], $option_value, ! $success ); + if ( $success ) { return (object) [ 'success' => true, @@ -295,4 +324,21 @@ public function get_configuration_state() { private function can_edit_profile( $person_id ) { return \current_user_can( 'edit_user', $person_id ); } + + /** + * Gets the old values for the given fields. + * + * @param array $fields_names The fields to get the old values for. + * + * @return array The old values. + */ + private function get_old_values( array $fields_names ) : array { + $old_values = []; + + foreach ( $fields_names as $field_name ) { + $old_values[ $field_name ] = $this->options_helper->get( $field_name ); + } + + return $old_values; + } } diff --git a/src/helpers/social-profiles-helper.php b/src/helpers/social-profiles-helper.php index dca95b53457..5d2186658a1 100644 --- a/src/helpers/social-profiles-helper.php +++ b/src/helpers/social-profiles-helper.php @@ -65,7 +65,7 @@ public function get_person_social_profile_fields() { */ $person_social_profile_fields = \apply_filters( 'wpseo_person_social_profile_fields', $this->person_social_profile_fields ); - return $person_social_profile_fields; + return (array) $person_social_profile_fields; } /** @@ -81,7 +81,7 @@ public function get_organization_social_profile_fields() { */ $organization_social_profile_fields = \apply_filters( 'wpseo_organization_social_profile_fields', $this->organization_social_profile_fields ); - return $organization_social_profile_fields; + return (array) $organization_social_profile_fields; } /** diff --git a/src/integrations/admin/indexables-exclude-taxonomy-integration.php b/src/integrations/admin/indexables-exclude-taxonomy-integration.php index 09e76662e87..4d1592b8d8f 100644 --- a/src/integrations/admin/indexables-exclude-taxonomy-integration.php +++ b/src/integrations/admin/indexables-exclude-taxonomy-integration.php @@ -41,13 +41,15 @@ public function register_hooks() { * * @param array $excluded_taxonomies The excluded taxonomies. * - * @return array The excluded post types, including the specific post type. + * @return array The excluded taxonomies, including specific taxonomies. */ public function exclude_taxonomies_for_indexation( $excluded_taxonomies ) { + $taxonomies_to_exclude = \array_merge( $excluded_taxonomies, [ 'wp_pattern_category' ] ); + if ( $this->options_helper->get( 'disable-post_format', false ) ) { - return \array_merge( $excluded_taxonomies, [ 'post_format' ] ); + return \array_merge( $taxonomies_to_exclude, [ 'post_format' ] ); } - return $excluded_taxonomies; + return $taxonomies_to_exclude; } } diff --git a/src/integrations/front-end/rss-footer-embed.php b/src/integrations/front-end/rss-footer-embed.php index 631e0bfd102..cce46ce8d87 100644 --- a/src/integrations/front-end/rss-footer-embed.php +++ b/src/integrations/front-end/rss-footer-embed.php @@ -182,13 +182,13 @@ protected function get_replace_vars( $link_template, $post ) { protected function get_link_template() { /** * Filter: 'nofollow_rss_links' - Allow the developer to determine whether or not to follow the links in - * the bits Yoast SEO adds to the RSS feed, defaults to true. + * the bits Yoast SEO adds to the RSS feed, defaults to false. * * @api bool $unsigned Whether or not to follow the links in RSS feed, defaults to true. * * @since 1.4.20 */ - if ( \apply_filters( 'nofollow_rss_links', true ) ) { + if ( \apply_filters( 'nofollow_rss_links', false ) ) { return '%2$s'; } diff --git a/src/integrations/settings-integration.php b/src/integrations/settings-integration.php index e5d851299cc..8033c93a8a1 100644 --- a/src/integrations/settings-integration.php +++ b/src/integrations/settings-integration.php @@ -90,6 +90,9 @@ class Settings_Integration implements Integration_Interface { 'deny_search_crawling', 'deny_wp_json_crawling', 'deny_adsbot_crawling', + 'deny_ccbot_crawling', + 'deny_google_extended_crawling', + 'deny_gptbot_crawling', ], ]; @@ -458,6 +461,7 @@ protected function get_preferences( $settings ) { 'isRtl' => \is_rtl(), 'isNetworkAdmin' => \is_network_admin(), 'isMainSite' => \is_main_site(), + 'isMultisite' => \is_multisite(), 'isWooCommerceActive' => $this->woocommerce_helper->is_active(), 'isLocalSeoActive' => \defined( 'WPSEO_LOCAL_FILE' ), 'isNewsSeoActive' => \defined( 'WPSEO_NEWS_FILE' ), diff --git a/src/integrations/third-party/wordproof.php b/src/integrations/third-party/wordproof.php index c9d63ba1d4b..2928bd1bdca 100644 --- a/src/integrations/third-party/wordproof.php +++ b/src/integrations/third-party/wordproof.php @@ -89,10 +89,19 @@ public function register_hooks() { */ \add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_assets' ], 10, 0 ); - /** - * Add async to the wordproof scripts. - */ - \add_filter( 'script_loader_tag', [ $this, 'add_async_to_script' ], 10, 3 ); + if ( version_compare( strtok( get_bloginfo( 'version' ), '-' ), '6.3', '>=' ) ) { + \add_action( + 'wp_enqueue_scripts', + function() { + \wp_script_add_data( WPSEO_Admin_Asset_Manager::PREFIX . 'wordproof-uikit', 'strategy', 'async' ); + }, + 11, + 0 + ); + } + else { + \add_filter( 'script_loader_tag', [ $this, 'add_async_to_script' ], 10, 3 ); + } /** * Removes the post meta timestamp key for the old privacy page. diff --git a/src/integrations/watchers/indexable-attachment-watcher.php b/src/integrations/watchers/indexable-attachment-watcher.php index ac97eb82cb7..6f34a43b95f 100644 --- a/src/integrations/watchers/indexable-attachment-watcher.php +++ b/src/integrations/watchers/indexable-attachment-watcher.php @@ -106,6 +106,11 @@ public function check_option( $old_value, $new_value ) { \delete_transient( Indexable_Post_Indexation_Action::UNINDEXED_COUNT_TRANSIENT ); \delete_transient( Indexable_Post_Indexation_Action::UNINDEXED_LIMITED_COUNT_TRANSIENT ); + // Set this core option (introduced in WP 6.4) to ensure consistency. + if ( \get_option( 'wp_attachment_pages_enabled' ) !== false ) { + \update_option( 'wp_attachment_pages_enabled', (int) ! $new_value['disable-attachment'] ); + } + switch ( $new_value['disable-attachment'] ) { case false: $this->indexing_helper->set_reason( Indexing_Reasons::REASON_ATTACHMENTS_MADE_ENABLED ); diff --git a/tests/integration/sitemaps/test-class-wpseo-taxonomy-sitemap-provider.php b/tests/integration/sitemaps/test-class-wpseo-taxonomy-sitemap-provider.php index 0f171869e82..8731d7ef87e 100644 --- a/tests/integration/sitemaps/test-class-wpseo-taxonomy-sitemap-provider.php +++ b/tests/integration/sitemaps/test-class-wpseo-taxonomy-sitemap-provider.php @@ -9,6 +9,7 @@ * Class WPSEO_Taxonomy_Sitemap_Provider_Test. * * @group sitemaps + * @coversDefaultClass WPSEO_Taxonomy_Sitemap_Provider */ class WPSEO_Taxonomy_Sitemap_Provider_Test extends WPSEO_UnitTestCase { @@ -31,7 +32,7 @@ public function set_up() { /** * Tests the retrieval of the index links. * - * @covers WPSEO_Taxonomy_Sitemap_Provider::get_index_links + * @covers ::get_index_links */ public function test_get_index_links() { @@ -57,7 +58,7 @@ public function test_get_index_links() { /** * Tests retrieval of the sitemap links. * - * @covers WPSEO_Taxonomy_Sitemap_Provider::get_sitemap_links + * @covers ::get_sitemap_links */ public function test_get_sitemap_links() { @@ -71,7 +72,7 @@ public function test_get_sitemap_links() { /** * Makes sure invalid sitemap pages return no contents (404). * - * @covers WPSEO_Taxonomy_Sitemap_Provider::get_index_links + * @covers ::get_index_links */ public function test_get_index_links_empty_sitemap() { // Fetch the global sitemap. @@ -87,4 +88,44 @@ public function test_get_index_links_empty_sitemap() { // Expect an empty page (404) to be returned. $this->expectOutputString( '' ); } + + /** + * Data provider for is_valid_taxonomy test. + * + * @return array + */ + public function data_provider_is_valis_taxonomy() { + return [ + 'Pattern Categories' => [ + 'taxonomy' => 'wp_pattern_category', + 'expected' => false, + ], + 'nav_menu' => [ + 'taxonomy' => 'nav_menu', + 'expected' => false, + ], + 'link_category' => [ + 'taxonomy' => 'link_category', + 'expected' => false, + ], + 'post_format' => [ + 'taxonomy' => 'post_format', + 'expected' => false, + ], + ]; + } + + /** + * Tetst of is_valid_taxonomy. + * + * @covers ::is_valid_taxonomy + * + * @dataProvider data_provider_is_valis_taxonomy + * + * @param string $taxonomy Taxonomy name. + * @param bool $expected Expected result. + */ + public function test_is_valid_taxonomy( $taxonomy, $expected ) { + $this->assertSame( $expected, self::$class_instance->is_valid_taxonomy( $taxonomy ) ); + } } diff --git a/tests/unit/actions/configuration/first-time-configuration-action-test.php b/tests/unit/actions/configuration/first-time-configuration-action-test.php index daf5fb367a1..f09a7fd8676 100644 --- a/tests/unit/actions/configuration/first-time-configuration-action-test.php +++ b/tests/unit/actions/configuration/first-time-configuration-action-test.php @@ -87,6 +87,10 @@ public function test_set_site_representation( $params, $times, $yoast_options_re ->times( $times ) ->andReturn( ...$yoast_options_results ); + $this->options_helper + ->expects( 'get' ) + ->times( \count( $this->instance::SITE_REPRESENTATION_FIELDS ) ); + Monkey\Functions\expect( 'current_user_can' ) ->with( 'manage_options' ) ->andReturnTrue(); @@ -113,7 +117,6 @@ public function site_representation_provider() { 'company_name' => 'Acme Inc.', 'company_logo' => 'https://acme.com/someimage.jpg', 'company_logo_id' => 123, - 'description' => 'A nice tagline', ], 'times' => 6, 'yoast_options_results' => [ true, true, true, true, true, true ], @@ -130,7 +133,6 @@ public function site_representation_provider() { 'person_logo' => 'https://acme.com/someimage.jpg', 'person_logo_id' => 123, 'company_or_person_user_id' => 321, - 'description' => 'A nice tagline', ], 'times' => 6, 'yoast_options_results' => [ true, true, true, true, true, true ], @@ -141,25 +143,6 @@ public function site_representation_provider() { ], ]; - $success_person_failure_tagline = [ - 'params' => [ - 'company_or_person' => 'person', - 'person_logo' => 'https://acme.com/someimage.jpg', - 'person_logo_id' => 123, - 'company_or_person_user_id' => 321, - 'description' => 'A tagline that will fail for some reason', - ], - 'times' => 6, - 'yoast_options_results' => [ true, true, true, true, true, true ], - 'wp_option_result' => false, - 'expected' => (object) [ - 'success' => false, - 'status' => 500, - 'error' => 'Could not save some options in the database', - 'failures' => [ 'description' ], - ], - ]; - $some_failures_company = [ 'params' => [ 'company_or_person' => 'company', @@ -168,7 +151,7 @@ public function site_representation_provider() { 'company_logo_id' => 123, 'description' => 'A nice tagline', ], - 'times' => 6, + 'times' => 7, 'yoast_options_results' => [ true, false, false, true, true, true ], 'wp_option_result' => true, 'expected' => (object) [ @@ -182,7 +165,6 @@ public function site_representation_provider() { return [ 'Successful call with company params' => $success_company, 'Successful call with person params' => $success_person, - 'Person params with failing description' => $success_person_failure_tagline, 'Company params with some failures' => $some_failures_company, ]; } @@ -195,9 +177,10 @@ public function site_representation_provider() { * @dataProvider social_profiles_provider * * @param array $set_profiles_results The expected results for set_organization_social_profiles(). + * @param array $get_profiles_results The expected results for get_organization_social_profile_fields(). * @param object $expected The expected result object. */ - public function test_set_social_profiles( $set_profiles_results, $expected ) { + public function test_set_social_profiles( $set_profiles_results, $get_profiles_results, $expected ) { $params = [ 'param1', 'param2', @@ -209,6 +192,15 @@ public function test_set_social_profiles( $set_profiles_results, $expected ) { ->once() ->andReturn( $set_profiles_results ); + $this->social_profiles_helper + ->expects( 'get_organization_social_profile_fields' ) + ->once() + ->andReturn( $get_profiles_results ); + + $this->options_helper + ->expects( 'get' ) + ->times( \count( $get_profiles_results ) ); + $this->assertEquals( $expected, $this->instance->set_social_profiles( $params ) @@ -223,6 +215,11 @@ public function test_set_social_profiles( $set_profiles_results, $expected ) { public function social_profiles_provider() { $success_all = [ 'set_profiles_results' => [], + 'get_profiles_results' => [ + 'facebook_site' => 'get_non_valid_url', + 'twitter_site' => 'get_non_valid_twitter', + 'other_social_urls' => 'get_non_valid_url_array', + ], 'expected' => (object) [ 'success' => true, 'status' => 200, @@ -231,6 +228,11 @@ public function social_profiles_provider() { $success_some = [ 'set_profiles_results' => [ 'param1' ], + 'get_profiles_results' => [ + 'facebook_site' => 'get_non_valid_url', + 'twitter_site' => 'get_non_valid_twitter', + 'other_social_urls' => 'get_non_valid_url_array', + ], 'expected' => (object) [ 'success' => false, 'status' => 200, @@ -241,6 +243,11 @@ public function social_profiles_provider() { $success_none = [ 'yoast_options_results' => [ 'param1', 'param2' ], + 'get_profiles_results' => [ + 'facebook_site' => 'get_non_valid_url', + 'twitter_site' => 'get_non_valid_twitter', + 'other_social_urls' => 'get_non_valid_url_array', + ], 'expected' => (object) [ 'success' => false, 'status' => 200, diff --git a/tests/unit/bootstrap.php b/tests/unit/bootstrap.php index 4538a077a9d..4fc6bfb17b0 100644 --- a/tests/unit/bootstrap.php +++ b/tests/unit/bootstrap.php @@ -36,7 +36,7 @@ define( 'YOAST_VENDOR_PREFIX_DIRECTORY', 'vendor_prefixed' ); define( 'YOAST_SEO_PHP_REQUIRED', '7.2.5' ); -define( 'YOAST_SEO_WP_TESTED', '6.3.2' ); +define( 'YOAST_SEO_WP_TESTED', '6.4' ); define( 'YOAST_SEO_WP_REQUIRED', '6.2' ); if ( ! defined( 'WPSEO_NAMESPACES' ) ) { diff --git a/tests/unit/integrations/watchers/indexable-attachment-watcher-test.php b/tests/unit/integrations/watchers/indexable-attachment-watcher-test.php index b87ad0e2d08..af47983d9e7 100644 --- a/tests/unit/integrations/watchers/indexable-attachment-watcher-test.php +++ b/tests/unit/integrations/watchers/indexable-attachment-watcher-test.php @@ -21,7 +21,7 @@ * @group integrations * @group watchers * - * @coversDefaultClass Yoast\WP\SEO\Integrations\Watchers\Indexable_Attachment_Watcher + * @coversDefaultClass \Yoast\WP\SEO\Integrations\Watchers\Indexable_Attachment_Watcher */ class Indexable_Attachment_Watcher_Test extends TestCase { @@ -208,6 +208,10 @@ public function test_check_option( $old_value, $new_value, $delete_transient_tim ->with( Indexable_Post_Indexation_Action::UNINDEXED_LIMITED_COUNT_TRANSIENT ) ->times( $delete_transient_times ); + Monkey\Functions\expect( 'update_option' ) + ->with( 'wp_attachment_pages_enabled', (int) ! $new_value ) + ->times( $delete_transient_times ); + $this->indexing_helper ->expects( 'set_reason' ) ->with( Indexing_Reasons::REASON_ATTACHMENTS_MADE_ENABLED ) diff --git a/wp-seo-main.php b/wp-seo-main.php index b140710f026..34bf056e95a 100644 --- a/wp-seo-main.php +++ b/wp-seo-main.php @@ -15,7 +15,7 @@ * {@internal Nobody should be able to overrule the real version number as this can cause * serious issues with the options, so no if ( ! defined() ).}} */ -define( 'WPSEO_VERSION', '21.4' ); +define( 'WPSEO_VERSION', '21.5-RC4' ); if ( ! defined( 'WPSEO_PATH' ) ) { @@ -35,7 +35,7 @@ define( 'YOAST_VENDOR_PREFIX_DIRECTORY', 'vendor_prefixed' ); define( 'YOAST_SEO_PHP_REQUIRED', '7.2.5' ); -define( 'YOAST_SEO_WP_TESTED', '6.3.2' ); +define( 'YOAST_SEO_WP_TESTED', '6.4' ); define( 'YOAST_SEO_WP_REQUIRED', '6.2' ); if ( ! defined( 'WPSEO_NAMESPACES' ) ) { diff --git a/wp-seo.php b/wp-seo.php index 8f5d85c2d42..e1cfb103a6d 100644 --- a/wp-seo.php +++ b/wp-seo.php @@ -8,7 +8,7 @@ * * @wordpress-plugin * Plugin Name: Yoast SEO - * Version: 21.4 + * Version: 21.5-RC4 * Plugin URI: https://yoa.st/1uj * Description: The first true all-in-one SEO solution for WordPress, including on-page content analysis, XML sitemaps and much more. * Author: Team Yoast