• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Yoast / wordpress-seo / b2cdb4a8bbaeaf115e11e0be25203fb1c767dcea

24 Jul 2025 06:59AM UTC coverage: 52.536% (+0.3%) from 52.203%
b2cdb4a8bbaeaf115e11e0be25203fb1c767dcea

Pull #22381

github

web-flow
Merge 46a96d07b into d7b01156a
Pull Request #22381: JS: Solve react/require-default-props warnings

8376 of 15389 branches covered (54.43%)

Branch coverage included in aggregate %.

26 of 127 new or added lines in 57 files covered. (20.47%)

27 existing lines in 22 files now uncovered.

30975 of 59514 relevant lines covered (52.05%)

40119.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/packages/js/src/components/contentAnalysis/InclusiveLanguageAnalysis.js
1
/* global wpseoAdminL10n */
2
import { withSelect } from "@wordpress/data";
3
import { Fragment } from "@wordpress/element";
4
import { __, sprintf } from "@wordpress/i18n";
5
import { Alert, SvgIcon } from "@yoast/components";
6
import { LocationConsumer } from "@yoast/externals/contexts";
7
import { isNil } from "lodash";
8
import PropTypes from "prop-types";
9
import styled from "styled-components";
10
import getIndicatorForScore from "../../analysis/getIndicatorForScore";
11
import isMultilingualPluginActive from "../../analysis/isMultilingualPluginActive";
12
import Results from "../../containers/Results";
13
import { safeCreateInterpolateElement } from "../../helpers/i18n";
14
import HelpLink from "../HelpLink";
15
import Portal from "../portals/Portal";
16
import ScoreIconPortal from "../portals/ScoreIconPortal";
17
import Collapsible from "../SidebarCollapsible";
18
import { getIconForScore } from "./mapResults";
19

20
const AnalysisHeader = styled.span`
×
21
        font-size: 1em;
22
        font-weight: bold;
23
        margin: 0 0 8px;
24
        display: block;
25
`;
26

27
const InclusiveLanguageResultsTabContainer = styled.div`
×
28
        padding: 16px;
29
`;
30

31
const StyledHelpLink = styled( HelpLink )`
×
32
        margin: -8px 0 -4px 4px;
33
`;
34

35
const GoodJobAnalysisResult = styled.p`
×
36
        min-height: 24px;
37
        margin: 12px 0 0 0;
38
        padding: 0;
39
        display: flex;
40
        align-items: flex-start;
41
`;
42
const ScoreIcon = styled( SvgIcon )`
×
43
        margin: 3px 11px 0 0; // icon 13 + 11 right margin = 24 for the 8px grid.
44
`;
45

46
/**
47
 * The inclusive language analysis component.
48
 *
49
 * @param {MappedResult[]} [results=[]] The assessment results.
50
 * @param {?number} [overallScore=null] The overall analysis score.
51
 * @param {"enabled"|"disabled"} marksButtonStatus The status of the mark buttons.
52
 * @param {boolean} [shouldUpsellHighlighting=false] Whether to upsell highlighting.
53
 *
54
 * @returns {JSX.Element} The inclusive language analysis component.
55
 */
NEW
56
const InclusiveLanguageAnalysis = ( {
×
57
        results = [],
×
58
        overallScore = null,
×
59
        marksButtonStatus,
60
        shouldUpsellHighlighting = false,
×
61
} ) => {
UNCOV
62
        const analysisInfoLink = wpseoAdminL10n[ "shortlinks.inclusive_language_analysis_info" ];
×
63

64
        /**
65
         * Renders the results of the analysis.
66
         *
67
         * @returns {JSX.Element} The results of the analysis.
68
         */
69
        function renderResults() {
70
                const highlightingUpsellLink = "shortlinks.upsell.sidebar.highlighting_inclusive_analysis";
×
71

72
                return (
×
73
                        <Fragment>
74
                                <AnalysisHeader>
75
                                        { __( "Analysis results", "wordpress-seo" ) }
76
                                        <StyledHelpLink
77
                                                href={ analysisInfoLink }
78
                                                className="dashicons"
79
                                        >
80
                                                <span className="screen-reader-text">
81
                                                        {
82
                                                                /* translators: Hidden accessibility text. */
83
                                                                __( "Learn more about the inclusive language analysis", "wordpress-seo" )
84
                                                        }
85
                                                </span>
86
                                        </StyledHelpLink>
87
                                </AnalysisHeader>
88
                                <Results
89
                                        results={ results }
90
                                        marksButtonClassName="yoast-tooltip yoast-tooltip-w"
91
                                        marksButtonStatus={ marksButtonStatus }
92
                                        resultCategoryLabels={ {
93
                                                problems: __( "Non-inclusive", "wordpress-seo" ),
94
                                                improvements: __( "Potentially non-inclusive", "wordpress-seo" ),
95
                                        } }
96
                                        highlightingUpsellLink={ highlightingUpsellLink }
97
                                        shouldUpsellHighlighting={ shouldUpsellHighlighting }
98
                                />
99
                        </Fragment>
100
                );
101
        }
102

103
        const goodJobFeedback = safeCreateInterpolateElement(
×
104
                sprintf(
105
                        /* Translators: %1$s expands to a link on yoast.com, %2$s expands to the anchor end tag. */
106
                        __( "%1$sInclusive language%2$s: We haven't detected any potentially non-inclusive phrases. Great work!", "wordpress-seo" ),
107
                        "<a>",
108
                        "</a>"
109
                ),
110
                {
111
                        // eslint-disable-next-line jsx-a11y/anchor-has-content
112
                        a: <a href={ analysisInfoLink } target="_blank" rel="noreferrer" />,
113
                }
114
        );
115

116

117
        /**
118
         * Renders a notice that a multilingual plugin has been
119
         * detected and the analysis is run in English.
120
         *
121
         * @returns {JSX.Element} The multilingual plugin detected notice.
122
         */
123
        function renderMultilingualPluginDetectedNotice() {
124
                const notice = __(
×
125
                        "We noticed that you are using a multilingual plugin. Please be aware that this analysis feedback is intended only for texts written in English.",
126
                        "wordpress-seo"
127
                );
128
                return <Alert type={ "info" }>
×
129
                        { notice }
130
                </Alert>;
131
        }
132

133
        /**
134
         * Renders a feedback string for when no non-inclusive phrases are detected.
135
         *
136
         * @returns {JSX.Element} The feedback string.
137
         */
138
        function renderGoodJob() {
139
                return (
×
140
                        <Fragment>
141
                                <AnalysisHeader>
142
                                        { __( "Analysis results", "wordpress-seo" ) }
143
                                        <StyledHelpLink
144
                                                href={ analysisInfoLink }
145
                                                className="dashicons"
146
                                        >
147
                                                <span className="screen-reader-text">
148
                                                        {
149
                                                                /* translators: Hidden accessibility text. */
150
                                                                __( "Learn more about the inclusive language analysis", "wordpress-seo" )
151
                                                        }
152
                                                </span>
153
                                        </StyledHelpLink>
154
                                </AnalysisHeader>
155
                                <GoodJobAnalysisResult>
156
                                        <ScoreIcon
157
                                                icon={ "circle" }
158
                                                color={ "#7ad03a" }
159
                                                size="13px"
160
                                        />
161
                                        <span>{ goodJobFeedback }</span>
162
                                </GoodJobAnalysisResult>
163
                        </Fragment>
164
                );
165
        }
166

167
        /**
168
         * Renders the inclusive language analysis for the sidebar.
169
         *
170
         * @param {Array} results                                         The inclusive language assessment results.
171
         * @param {number} inclusiveLanguageScore         The inclusive language score.
172
         *
173
         * @returns {JSX.Element} The inclusive language for the sidebar.
174
         */
175
        function renderSidebar( results, inclusiveLanguageScore ) {
176
                return (
×
177
                        <Collapsible
178
                                title={ __( "Inclusive language", "wordpress-seo" ) }
179
                                titleScreenReaderText={ inclusiveLanguageScore.screenReaderInclusiveLanguageText }
180
                                prefixIcon={ getIconForScore( inclusiveLanguageScore.className ) }
181
                                prefixIconCollapsed={ getIconForScore( inclusiveLanguageScore.className ) }
182
                                id={ "yoast-inclusive-language-analysis-collapsible-sidebar" }
183
                        >
184
                                { isMultilingualPluginActive() ? renderMultilingualPluginDetectedNotice() : null }
×
185
                                { results.length >= 1 ? renderResults() : renderGoodJob() }
×
186
                        </Collapsible>
187
                );
188
        }
189

190
        /**
191
         * Renders the inclusive language analysis for the metabox.
192
         *
193
         * @param {Array} results                                         The inclusive language assessment results.
194
         * @param {number} inclusiveLanguageScore         The inclusive language score.
195
         *
196
         * @returns {JSX.Element} The inclusive language for the metabox.
197
         */
198
        function renderMetabox( results, inclusiveLanguageScore ) {
199
                return (
×
200
                        <Portal target="wpseo-metabox-inclusive-language-root">
201
                                <InclusiveLanguageResultsTabContainer>
202
                                        <ScoreIconPortal
203
                                                target="wpseo-inclusive-language-score-icon"
204
                                                scoreIndicator={ inclusiveLanguageScore.className }
205
                                        />
206
                                        { isMultilingualPluginActive() ? renderMultilingualPluginDetectedNotice() : null }
×
207
                                        { results.length >= 1 ? renderResults() : renderGoodJob() }
×
208
                                </InclusiveLanguageResultsTabContainer>
209
                        </Portal>
210
                );
211
        }
212

NEW
213
        const score = getIndicatorForScore( overallScore );
×
214

NEW
215
        if ( isNil( overallScore ) ) {
×
216
                score.className = "loading";
×
217
        }
218

219
        return (
×
220
                <LocationConsumer>
221
                        { location => {
222
                                if ( location === "sidebar" ) {
×
NEW
223
                                        return renderSidebar( results, score );
×
224
                                }
225

226
                                if ( location === "metabox" ) {
×
NEW
227
                                        return renderMetabox( results, score );
×
228
                                }
229
                        } }
230
                </LocationConsumer>
231
        );
232
};
233

234
InclusiveLanguageAnalysis.propTypes = {
×
235
        results: PropTypes.array,
236
        marksButtonStatus: PropTypes.oneOf( [ "enabled", "disabled", "hidden" ] ).isRequired,
237
        overallScore: PropTypes.number,
238
        shouldUpsellHighlighting: PropTypes.bool,
239
};
240

241
export default withSelect( select => {
242
        const {
243
                getInclusiveLanguageResults,
244
                getMarkButtonStatus,
245
        } = select( "yoast-seo/editor" );
×
246

247
        return {
×
248
                ...getInclusiveLanguageResults(),
249
                marksButtonStatus: getMarkButtonStatus(),
250
        };
251
} )( InclusiveLanguageAnalysis );
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc