</Helmet>
<HeaderList headers={realHeadingsList} />
<h1>{pageTitle || mainTitle}</h1>
- <div className="markdown-content" dangerouslySetInnerHTML={{ __html: htmlPageContent }} />
+ <div
+ className="markdown-content"
+ // Safe: comes from the backend
+ dangerouslySetInnerHTML={{ __html: htmlPageContent }}
+ />
</>
);
}
"repository": "SonarSource/sonarqube",
"license": "LGPL-3.0",
"dependencies": {
+ "@types/dompurify": "^0.0.32",
"classnames": "2.2.6",
"clipboard": "2.0.1",
"core-js": "3.0.0",
"d3-shape": "1.2.2",
"d3-zoom": "1.7.3",
"date-fns": "1.29.0",
+ "dompurify": "^1.0.11",
"formik": "1.2.0",
"history": "3.3.0",
"intl-relativeformat": "2.1.0",
"@types/react-router": "3.0.20",
"@types/react-select": "1.2.6",
"@types/react-virtualized": "9.21.0",
+ "@types/sanitize-html": "1.20.0",
"@types/valid-url": "1.0.2",
"@typescript-eslint/parser": "1.5.0",
"autoprefixer": "9.5.0",
{component.match ? (
<span
className="navbar-search-item-match"
+ // Safe: comes from the backend
dangerouslySetInnerHTML={{ __html: component.match }}
/>
) : (
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
import * as classNames from 'classnames';
import DeferredSpinner from '../../../components/common/DeferredSpinner';
-import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { translate } from '../../../helpers/l10n';
interface Props {
allowMore: boolean;
href="#"
onClick={this.handleMoreClick}
onMouseEnter={this.handleMoreMouseEnter}>
- <div
- className="pull-right text-muted-2 menu-footer-note"
- dangerouslySetInnerHTML={{
- __html: translateWithParameters(
- 'search.show_more.hint',
- '<span class="shortcut-button shortcut-button-small">Enter</span>'
- )
- }}
- />
+ <div className="pull-right text-muted-2 menu-footer-note">
+ <FormattedMessage
+ defaultMessage={translate('search.show_more.hint')}
+ id={'search.show_more.hint'}
+ values={{
+ key: <span className="shortcut-button shortcut-button-small">Enter</span>
+ }}
+ />
+ </div>
<span>{translate('show_more')}</span>
</a>
</DeferredSpinner>
>
<div
className="pull-right text-muted-2 menu-footer-note"
- dangerouslySetInnerHTML={
- Object {
- "__html": "search.show_more.hint.<span class=\\"shortcut-button shortcut-button-small\\">Enter</span>",
+ >
+ <FormattedMessage
+ defaultMessage="search.show_more.hint"
+ id="search.show_more.hint"
+ values={
+ Object {
+ "key": <span
+ className="shortcut-button shortcut-button-small"
+ >
+ Enter
+ </span>,
+ }
}
- }
- />
+ />
+ </div>
<span>
show_more
</span>
</div>
{customText && (
- <div className="about-page-section" dangerouslySetInnerHTML={{ __html: customText }} />
+ <div
+ className="about-page-section"
+ // Safe: Defined by instance admin
+ dangerouslySetInnerHTML={{ __html: customText }}
+ />
)}
<AboutLanguages />
)}
<div
className="note"
+ // Safe: defined by rule creator (instance admin?)
dangerouslySetInnerHTML={{ __html: param.htmlDesc || '' }}
/>
</div>
)}
<div
className="modal-field-description"
+ // Safe: defined by rule creator (instance admin?)
dangerouslySetInnerHTML={{ __html: param.htmlDesc || '' }}
/>
</div>
{this.props.ruleDetails.htmlNote !== undefined && (
<div
className="rule-desc spacer-bottom markdown"
+ // Safe: defined by rule creator (instance admin?)
dangerouslySetInnerHTML={{ __html: this.props.ruleDetails.htmlNote }}
/>
)}
{hasDescription ? (
<div
className="coding-rules-detail-description rule-desc markdown"
+ // Safe: defined by rule creator (instance admin?)
dangerouslySetInnerHTML={{ __html: ruleDetails.htmlDesc || '' }}
/>
) : (
<tr className="coding-rules-detail-parameter" key={param.key}>
<td className="coding-rules-detail-parameter-name">{param.key}</td>
<td className="coding-rules-detail-parameter-description">
- <p dangerouslySetInnerHTML={{ __html: param.htmlDesc || '' }} />
+ <p // Safe: defined by rule creator (instance admin?)
+ dangerouslySetInnerHTML={{ __html: param.htmlDesc || '' }}
+ />
{param.defaultValue !== undefined && (
<div className="note spacer-top">
{translate('coding_rules.parameters.default_value')}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import { shallow } from 'enzyme';
+import RuleDetailsParameters from '../RuleDetailsParameters';
+import { mockRuleDetailsParameter } from '../../../../helpers/testMocks';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<RuleDetailsParameters['props']> = {}) {
+ const params = [mockRuleDetailsParameter(), mockRuleDetailsParameter()];
+
+ return shallow(<RuleDetailsParameters params={params} {...props} />);
+}
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<div
+ className="js-rule-parameters"
+>
+ <h3
+ className="coding-rules-detail-title"
+ >
+ coding_rules.parameters
+ </h3>
+ <table
+ className="coding-rules-detail-parameters"
+ >
+ <tbody>
+ <tr
+ className="coding-rules-detail-parameter"
+ key="1"
+ >
+ <td
+ className="coding-rules-detail-parameter-name"
+ >
+ 1
+ </td>
+ <td
+ className="coding-rules-detail-parameter-description"
+ >
+ <p
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "description",
+ }
+ }
+ />
+ <div
+ className="note spacer-top"
+ >
+ coding_rules.parameters.default_value
+ <br />
+ <span
+ className="coding-rules-detail-parameter-value"
+ >
+ 1
+ </span>
+ </div>
+ </td>
+ </tr>
+ <tr
+ className="coding-rules-detail-parameter"
+ key="1"
+ >
+ <td
+ className="coding-rules-detail-parameter-name"
+ >
+ 1
+ </td>
+ <td
+ className="coding-rules-detail-parameter-description"
+ >
+ <p
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "description",
+ }
+ }
+ />
+ <div
+ className="note spacer-top"
+ >
+ coding_rules.parameters.default_value
+ <br />
+ <span
+ className="coding-rules-detail-parameter-value"
+ >
+ 1
+ </span>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+</div>
+`;
const component = selectedLocation ? selectedLocation.component : openIssue.component;
const allMessagesEmpty =
locations !== undefined && locations.every(location => !location.msg);
+
const highlightedLocations = locations.filter(location => location.component === component);
// do not load issues when open another file for a location
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import * as classNames from 'classnames';
import Helmet from 'react-helmet';
+import { FormattedMessage } from 'react-intl';
+import * as classNames from 'classnames';
import { getMigrationStatus, getSystemStatus, migrateDatabase } from '../../../api/system';
import DateFromNow from '../../../components/intl/DateFromNow';
import TimeFormatter from '../../../components/intl/TimeFormatter';
</h1>
{!isSonarCloud() && (
<>
- <p
- className="maintenance-text"
- dangerouslySetInnerHTML={{
- __html: translate('maintenance.sonarqube_is_under_maintenance.1')
- }}
- />
- <p
- className="maintenance-text"
- dangerouslySetInnerHTML={{
- __html: translate('maintenance.sonarqube_is_under_maintenance.2')
- }}
- />
+ <p className="maintenance-text">
+ <FormattedMessage
+ defaultMessage={translate('maintenance.sonarqube_is_under_maintenance.1')}
+ id="maintenance.sonarqube_is_under_maintenance.1"
+ values={{
+ link: (
+ <a href="https://redirect.sonarsource.com/doc/plugin-library.html">
+ {translate('maintenance.sonarqube_is_under_maintenance_link.1')}
+ </a>
+ )
+ }}
+ />
+ </p>
+ <p className="maintenance-text">
+ <FormattedMessage
+ defaultMessage={translate('maintenance.sonarqube_is_under_maintenance.2')}
+ id="maintenance.sonarqube_is_under_maintenance.2"
+ values={{
+ link: (
+ <a href="https://redirect.sonarsource.com/doc/upgrading.html">
+ {translate('maintenance.sonarqube_is_under_maintenance_link.2')}
+ </a>
+ )
+ }}
+ />
+ </p>
</>
)}
</>
</h1>
<p
className="maintenance-text"
- dangerouslySetInnerHTML={
- Object {
- "__html": "maintenance.sonarqube_is_under_maintenance.1",
+ >
+ <FormattedMessage
+ defaultMessage="maintenance.sonarqube_is_under_maintenance.1"
+ id="maintenance.sonarqube_is_under_maintenance.1"
+ values={
+ Object {
+ "link": <a
+ href="https://redirect.sonarsource.com/doc/plugin-library.html"
+ >
+ maintenance.sonarqube_is_under_maintenance_link.1
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
<p
className="maintenance-text"
- dangerouslySetInnerHTML={
- Object {
- "__html": "maintenance.sonarqube_is_under_maintenance.2",
+ >
+ <FormattedMessage
+ defaultMessage="maintenance.sonarqube_is_under_maintenance.2"
+ id="maintenance.sonarqube_is_under_maintenance.2"
+ values={
+ Object {
+ "link": <a
+ href="https://redirect.sonarsource.com/doc/upgrading.html"
+ >
+ maintenance.sonarqube_is_under_maintenance_link.2
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
</div>
</div>
</Fragment>
</h1>
<p
className="maintenance-text"
- dangerouslySetInnerHTML={
- Object {
- "__html": "maintenance.sonarqube_is_under_maintenance.1",
+ >
+ <FormattedMessage
+ defaultMessage="maintenance.sonarqube_is_under_maintenance.1"
+ id="maintenance.sonarqube_is_under_maintenance.1"
+ values={
+ Object {
+ "link": <a
+ href="https://redirect.sonarsource.com/doc/plugin-library.html"
+ >
+ maintenance.sonarqube_is_under_maintenance_link.1
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
<p
className="maintenance-text"
- dangerouslySetInnerHTML={
- Object {
- "__html": "maintenance.sonarqube_is_under_maintenance.2",
+ >
+ <FormattedMessage
+ defaultMessage="maintenance.sonarqube_is_under_maintenance.2"
+ id="maintenance.sonarqube_is_under_maintenance.2"
+ values={
+ Object {
+ "link": <a
+ href="https://redirect.sonarsource.com/doc/upgrading.html"
+ >
+ maintenance.sonarqube_is_under_maintenance_link.2
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
</div>
</div>
</Fragment>
import { setSimpleSettingValue, resetSettingValue } from '../../../api/settings';
import { Button, SubmitButton, ResetButtonLink } from '../../../components/ui/buttons';
import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { sanitizeTranslation } from '../../settings/utils';
interface Props {
branch?: string;
<div className="modal-body">
<div
className="big-spacer-bottom markdown"
- dangerouslySetInnerHTML={{ __html: translate(`property.${setting.key}.description`) }}
+ dangerouslySetInnerHTML={{
+ __html: sanitizeTranslation(translate(`property.${setting.key}.description`))
+ }}
/>
<div className="modal-field">
<input
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { getEmptyValue, getDefaultValue } from '../utils';
+import { getEmptyValue, getDefaultValue, sanitizeTranslation } from '../utils';
const fields = [
{ key: 'foo', type: 'STRING' } as T.SettingFieldDefinition,
it('should work for boolean field when passing "false"', () =>
check('false', 'settings.boolean.false'));
});
+
+describe('sanitizeTranslation', () => {
+ it('should preserve formatting tags', () => {
+ const allowed = `
+ Hi this is <i>in italics</i> and <ul>
+ <li> lists </li>
+ <li> are allowed</li>
+ </ul>
+ <p>
+ as well. This is <b>Amazing</b> and this <strong>bold</strong> <br>
+ and <code>code.is.accepted too</code>
+ </p>
+ `;
+
+ const clean = sanitizeTranslation(allowed);
+ expect(clean).toBe(allowed);
+ });
+
+ /*
+ * Test code borrowed from OWASP's sanitizer tests
+ * https://github.com/OWASP/java-html-sanitizer/blob/master/src/test/resources/org/owasp/html/htmllexerinput1.html
+ */
+ it('should strip everything else', () => {
+ const clean = sanitizeTranslation(`<?xml version="not-even-close"?>
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+ <!-- a test input for HtmlLexer -->
+
+ <html>
+ <head>
+ <title>Test File For HtmlLexer & HtmlParser</title>
+ <link rel=stylesheet type="text/css" src=foo/bar.css />
+ <body
+ bgcolor=white
+ linkcolor = "blue"
+ onload="document.writeln(
+ "<p>properly escaped code in a handler</p>");"
+ >
+
+ <script type="text/javascript"><!--
+ document.writeln("<p>Some initialization code in global context</p>");
+ --></script>
+
+ <script type="text/javascript">
+ // hi there
+ document.writeln("<p>More initialization</p>");
+ </script>
+
+ <div id=clickydiv onclick="handleClicky(event)"
+ ondblclick=this.onclick(event);return(false)>
+ Clicky
+ </div>
+
+ <input id=foo>
+ <gxp:attr name="onchange">alert("<b>hi</b>");</gxp:attr>
+ </input>
+
+ <pre><div id=notarealtag onclick=notcode()></pre>
+
+ <!-- some tokenization corner cases -->
+
+ < notatag <atag/>
+
+ </ notatag> </redundantlyclosed/>
+
+ <messyattributes a=b=c d="e"f=g h =i j= k l = m checked n="o"/>
+
+ < < < all in one text block > > >
+
+ <xmp>Make sure that <!-- comments don't obscure the xmp close</xmp>
+ <% # some php code here
+ write("<pre>$horriblySyntacticConstruct1</pre>\n\n");
+ %>
+ <script type="text/javascript"><!--
+ alert("hello world");
+ // --></script>
+
+ <script>/* </script> */alert('hi');</script>
+ <script><!--/* </script> */alert('hi');--></script>
+
+ <xmp style=color:blue><!--/* </xmp> */alert('hi');--></xmp>
+
+ <style><!-- p { contentf: '</style>' } --></style>
+ <style>Foo<!-- > </style> --></style>
+ <textarea><!-- Zoicks </textarea>--></textarea>
+ <!-- An escaping text span start may share its U+002D HYPHEN-MINUS characters
+ - with its corresponding escaping text span end. -->
+ <script><!--></script>
+ <script><!---></script>
+ <script><!----></script>
+ </body>
+ </html>
+ <![CDATA[ No such thing as a CDATA> section in HTML ]]>
+ <script>a<b</script>
+ <img src=foo.gif /><a href=><a href=/>
+ <span title=malformed attribs' do=don't id=foo checked onclick="a<b">Bar</span>`);
+
+ expect(clean.replace(/\s+/g, '')).toBe(
+ `Clickyalert("<b>hi</b>");<divid=notarealtagonclick=notcode()><notatag<<<allinonetextblock>>>Makesurethat<%#somephpcodeherewrite("$horriblySyntacticConstruct1");%>*/alert('hi');*/alert('hi');-->*/alert('hi');-->'}-->--><!--Zoicks-->sectioninHTML]]>Bar`
+ );
+ });
+});
getPropertyName,
getPropertyDescription,
getSettingValue,
- isDefaultOrInherited
+ isDefaultOrInherited,
+ sanitizeTranslation
} from '../utils';
import AlertErrorIcon from '../../../components/icons-components/AlertErrorIcon';
import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessIcon';
{description && (
<div
className="markdown small spacer-top"
- dangerouslySetInnerHTML={{ __html: description }}
+ dangerouslySetInnerHTML={{ __html: sanitizeTranslation(description) }}
/>
)}
import { groupBy, isEqual, sortBy } from 'lodash';
import DefinitionsList from './DefinitionsList';
import EmailForm from './EmailForm';
-import { getSubCategoryName, getSubCategoryDescription } from '../utils';
+import { getSubCategoryName, getSubCategoryDescription, sanitizeTranslation } from '../utils';
interface Props {
category: string;
{subCategory.description != null && (
<div
className="settings-sub-category-description markdown"
- dangerouslySetInnerHTML={{ __html: subCategory.description }}
+ dangerouslySetInnerHTML={{ __html: sanitizeTranslation(subCategory.description) }}
/>
)}
<DefinitionsList
<ClipboardButton className="little-spacer-left" copyValue={secretKey} />
</div>
<h3 className="spacer-bottom">{translate('encryption.how_to_use')}</h3>
- <div
- className="markdown"
- dangerouslySetInnerHTML={{ __html: translate('encryption.how_to_use.content') }}
- />
+ <div className="markdown">
+ <ul>
+ <li>
+ <FormattedMessage
+ defaultMessage={translate('encryption.how_to_use.content1')}
+ id="encryption.how_to_use.content1"
+ values={{
+ secret_file: <code>~/.sonar/sonar-secret.txt</code>,
+ property: <code>sonar.secretKeyPath</code>,
+ propreties_file: <code>conf/sonar.properties</code>
+ }}
+ />
+ </li>
+ <li>{translate('encryption.how_to_use.content2')}</li>
+ <li>
+ <FormattedMessage
+ defaultMessage={translate('encryption.how_to_use.content3')}
+ id="encryption.how_to_use.content3"
+ values={{
+ property: <code>sonar.secretKeyPath</code>
+ }}
+ />
+ </li>
+ <li>{translate('encryption.how_to_use.content4')}</li>
+ </ul>
+ </div>
</>
) : (
<form id="generate-secret-key-form" onSubmit={this.handleSubmit}>
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { sanitize } from 'dompurify';
import { translate, hasMessage } from '../../helpers/l10n';
export const DEFAULT_CATEGORY = 'general';
value: any;
}
+export function sanitizeTranslation(html: string) {
+ return sanitize(html, {
+ ALLOWED_TAGS: ['b', 'br', 'code', 'i', 'li', 'p', 'strong', 'ul']
+ });
+}
+
export function getPropertyName(definition: T.SettingDefinition) {
const key = `property.${definition.key}.name`;
return hasMessage(key) ? translate(key) : definition.name;
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
import { translate } from '../../../../helpers/l10n';
import { getBaseUrl } from '../../../../helpers/urls';
<h4 className="spacer-bottom">
{translate('onboarding.analysis.build_wrapper.header', props.os)}
</h4>
- <p
- className="spacer-bottom markdown"
- dangerouslySetInnerHTML={{
- __html: translate('onboarding.analysis.build_wrapper.text', props.os)
- }}
- />
+ <p className="spacer-bottom markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.build_wrapper.text')}
+ id="onboarding.analysis.build_wrapper.text"
+ values={{
+ env_var: <code>{props.os === 'win' ? '%PATH%' : 'PATH'}</code>
+ }}
+ />
+ </p>
<p>
<a
className="button"
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
import SQScanner from './SQScanner';
import BuildWrapper from './BuildWrapper';
import CodeSnippet from '../../../../components/common/CodeSnippet';
{translate('onboarding.analysis.sq_scanner.execute')}
</h4>
<InstanceMessage message={translate('onboarding.analysis.sq_scanner.execute.text')}>
- {transformedMessage => (
- <p
- className="spacer-bottom markdown"
- dangerouslySetInnerHTML={{ __html: transformedMessage }}
- />
- )}
+ {transformedMessage => <p className="spacer-bottom markdown">{transformedMessage}</p>}
</InstanceMessage>
<CodeSnippet isOneLine={props.small} snippet={command1} />
<CodeSnippet isOneLine={props.os === 'win'} snippet={command2} />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.sq_scanner.docs') }}
- />
+ <p className="big-spacer-top markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.sq_scanner.docs')}
+ id="onboarding.analysis.sq_scanner.docs"
+ values={{
+ link: (
+ <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('onboarding.analysis.sq_scanner.docs_link')}
+ </a>
+ )
+ }}
+ />
+ </p>
</div>
);
}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
import MSBuildScanner from './MSBuildScanner';
import CodeSnippet from '../../../../components/common/CodeSnippet';
import InstanceMessage from '../../../../components/common/InstanceMessage';
{translate('onboarding.analysis.msbuild.execute')}
</h4>
<InstanceMessage message={translate('onboarding.analysis.msbuild.execute.text')}>
- {transformedMessage => (
- <p
- className="spacer-bottom markdown"
- dangerouslySetInnerHTML={{ __html: transformedMessage }}
- />
- )}
+ {transformedMessage => <p className="spacer-bottom markdown">{transformedMessage}</p>}
</InstanceMessage>
<CodeSnippet isOneLine={true} snippet={command1} />
<CodeSnippet isOneLine={false} snippet={command2} />
<CodeSnippet isOneLine={props.small} snippet={command3} />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.msbuild.docs') }}
- />
+ <p className="big-spacer-top markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.docs')}
+ id="onboarding.analysis.docs"
+ values={{
+ link: (
+ <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('onboarding.analysis.msbuild.docs_link')}
+ </a>
+ )
+ }}
+ />
+ </p>
</div>
);
}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
import CodeSnippet from '../../../../components/common/CodeSnippet';
import InstanceMessage from '../../../../components/common/InstanceMessage';
import { translate } from '../../../../helpers/l10n';
<h4 className="spacer-bottom">{translate('onboarding.analysis.java.gradle.header')}</h4>
<InstanceMessage message={translate('onboarding.analysis.java.gradle.text.1')}>
{transformedMessage => (
- <p
- className="spacer-bottom markdown"
- dangerouslySetInnerHTML={{ __html: transformedMessage }}
- />
+ <p className="spacer-bottom markdown">
+ <FormattedMessage
+ defaultMessage={transformedMessage}
+ id="onboarding.analysis.java.gradle.text.1"
+ values={{
+ plugin_code: <code>org.sonarqube</code>,
+ filename: <code>build.gradle</code>
+ }}
+ />
+ </p>
)}
</InstanceMessage>
<CodeSnippet snippet={config} />
{translate('onboarding.analysis.java.gradle.text.2')}
</p>
<CodeSnippet snippet={command} />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.java.gradle.docs') }}
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={{
- __html: props.projectKey
- ? translate('onboarding.analysis.auto_refresh_after_analysis')
- : translate('onboarding.analysis.browse_url_after_analysis')
- }}
- />
+ <p className="big-spacer-top markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.docs')}
+ id="onboarding.analysis.docs"
+ values={{
+ link: (
+ <a
+ href="http://redirect.sonarsource.com/doc/gradle.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('onboarding.analysis.java.gradle.docs_link')}
+ </a>
+ )
+ }}
+ />
+ </p>
+ <p className="big-spacer-top markdown">
+ {props.projectKey
+ ? translate('onboarding.analysis.auto_refresh_after_analysis')
+ : translate('onboarding.analysis.browse_url_after_analysis')}
+ </p>
</div>
);
}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
import CodeSnippet from '../../../../components/common/CodeSnippet';
import InstanceMessage from '../../../../components/common/InstanceMessage';
import { translate } from '../../../../helpers/l10n';
<InstanceMessage message={translate('onboarding.analysis.java.maven.text')} />
</p>
<CodeSnippet snippet={command} />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.java.maven.docs') }}
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={{
- __html: props.projectKey
- ? translate('onboarding.analysis.auto_refresh_after_analysis')
- : translate('onboarding.analysis.browse_url_after_analysis')
- }}
- />
+ <p className="big-spacer-top markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.docs')}
+ id="onboarding.analysis.docs"
+ values={{
+ link: (
+ <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('onboarding.analysis.java.maven.docs_link')}
+ </a>
+ )
+ }}
+ />
+ </p>
+ <p className="big-spacer-top markdown">
+ {props.projectKey
+ ? translate('onboarding.analysis.auto_refresh_after_analysis')
+ : translate('onboarding.analysis.browse_url_after_analysis')}
+ </p>
</div>
);
}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
import { translate } from '../../../../helpers/l10n';
interface Props {
return (
<div className={props.className}>
<h4 className="spacer-bottom">{translate('onboarding.analysis.msbuild.header')}</h4>
- <p
- className="spacer-bottom markdown"
- dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.msbuild.text') }}
- />
+ <p className="spacer-bottom markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.msbuild.text')}
+ id="onboarding.analysis.msbuild.text"
+ values={{ code: <code>%PATH%</code> }}
+ />
+ </p>
<p>
<a
className="button"
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
import MSBuildScanner from './MSBuildScanner';
import BuildWrapper from './BuildWrapper';
import CodeSnippet from '../../../../components/common/CodeSnippet';
{translate('onboarding.analysis.msbuild.execute')}
</h4>
<InstanceMessage message={translate('onboarding.analysis.msbuild.execute.text')}>
- {transformedMessage => (
- <p
- className="spacer-bottom markdown"
- dangerouslySetInnerHTML={{ __html: transformedMessage }}
- />
- )}
+ {transformedMessage => <p className="spacer-bottom markdown">{transformedMessage}</p>}
</InstanceMessage>
<CodeSnippet isOneLine={true} snippet={command1} />
<CodeSnippet isOneLine={props.small} snippet={command2} />
<CodeSnippet isOneLine={props.small} snippet={command3} />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.msbuild.docs') }}
- />
+ <p className="big-spacer-top markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.docs')}
+ id="onboarding.analysis.docs"
+ values={{
+ link: (
+ <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('onboarding.analysis.msbuild.docs_link')}
+ </a>
+ )
+ }}
+ />
+ </p>
</div>
);
}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
import SQScanner from './SQScanner';
import CodeSnippet from '../../../../components/common/CodeSnippet';
import InstanceMessage from '../../../../components/common/InstanceMessage';
{translate('onboarding.analysis.sq_scanner.execute')}
</h4>
<InstanceMessage message={translate('onboarding.analysis.sq_scanner.execute.text')}>
- {transformedMessage => (
- <p
- className="spacer-bottom markdown"
- dangerouslySetInnerHTML={{ __html: transformedMessage }}
- />
- )}
+ {transformedMessage => <p className="spacer-bottom markdown">{transformedMessage}</p>}
</InstanceMessage>
<CodeSnippet isOneLine={props.os === 'win'} snippet={command} />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.sq_scanner.docs') }}
- />
+ <p className="big-spacer-top markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.sq_scanner.docs')}
+ id="onboarding.analysis.sq_scanner.docs"
+ values={{
+ link: (
+ <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('onboarding.analysis.sq_scanner.docs_link')}
+ </a>
+ )
+ }}
+ />
+ </p>
</div>
);
}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
import { translate } from '../../../../helpers/l10n';
interface Props {
<h4 className="spacer-bottom">
{translate('onboarding.analysis.sq_scanner.header', props.os)}
</h4>
- <p
- className="spacer-bottom markdown"
- dangerouslySetInnerHTML={{
- __html: translate('onboarding.analysis.sq_scanner.text', props.os)
- }}
- />
+ <p className="spacer-bottom markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.sq_scanner.text')}
+ id="onboarding.analysis.sq_scanner.text"
+ values={{
+ dir: <code>bin</code>,
+ env_var: <code>{props.os === 'win' ? '%PATH%' : 'PATH'}</code>
+ }}
+ />
+ </p>
<p>
<a
className="button"
</h4>
<p
className="spacer-bottom markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.build_wrapper.text.win",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.build_wrapper.text"
+ id="onboarding.analysis.build_wrapper.text"
+ values={
+ Object {
+ "env_var": <code>
+ %PATH%
+ </code>,
+ }
}
- }
- />
+ />
+ </p>
<p>
<a
className="button"
</h4>
<p
className="spacer-bottom markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.build_wrapper.text.linux",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.build_wrapper.text"
+ id="onboarding.analysis.build_wrapper.text"
+ values={
+ Object {
+ "env_var": <code>
+ PATH
+ </code>,
+ }
}
- }
- />
+ />
+ </p>
<p>
<a
className="button"
</h4>
<p
className="spacer-bottom markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.build_wrapper.text.mac",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.build_wrapper.text"
+ id="onboarding.analysis.build_wrapper.text"
+ values={
+ Object {
+ "env_var": <code>
+ PATH
+ </code>,
+ }
}
- }
- />
+ />
+ </p>
<p>
<a
className="button"
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.docs"
+ id="onboarding.analysis.sq_scanner.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.sq_scanner.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
</div>
`;
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.docs"
+ id="onboarding.analysis.sq_scanner.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.sq_scanner.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
</div>
`;
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.docs"
+ id="onboarding.analysis.sq_scanner.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.sq_scanner.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
</div>
`;
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.msbuild.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.msbuild.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
</div>
`;
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.msbuild.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.msbuild.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
</div>
`;
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.java.gradle.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/gradle.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.java.gradle.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.browse_url_after_analysis",
- }
- }
- />
+ >
+ onboarding.analysis.browse_url_after_analysis
+ </p>
</div>
`;
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.java.gradle.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/gradle.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.java.gradle.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.browse_url_after_analysis",
- }
- }
- />
+ >
+ onboarding.analysis.browse_url_after_analysis
+ </p>
</div>
`;
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.java.gradle.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/gradle.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.java.gradle.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.auto_refresh_after_analysis",
- }
- }
- />
+ >
+ onboarding.analysis.auto_refresh_after_analysis
+ </p>
</div>
`;
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.java.maven.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.java.maven.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.browse_url_after_analysis",
- }
- }
- />
+ >
+ onboarding.analysis.browse_url_after_analysis
+ </p>
</div>
`;
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.java.maven.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.java.maven.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.browse_url_after_analysis",
- }
- }
- />
+ >
+ onboarding.analysis.browse_url_after_analysis
+ </p>
</div>
`;
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.java.maven.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.java.maven.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.auto_refresh_after_analysis",
- }
- }
- />
+ >
+ onboarding.analysis.auto_refresh_after_analysis
+ </p>
</div>
`;
</h4>
<p
className="spacer-bottom markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.msbuild.text",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.msbuild.text"
+ id="onboarding.analysis.msbuild.text"
+ values={
+ Object {
+ "code": <code>
+ %PATH%
+ </code>,
+ }
}
- }
- />
+ />
+ </p>
<p>
<a
className="button"
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.msbuild.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.msbuild.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
</div>
`;
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.msbuild.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.msbuild.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
</div>
`;
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.docs"
+ id="onboarding.analysis.sq_scanner.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.sq_scanner.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
</div>
`;
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.docs"
+ id="onboarding.analysis.sq_scanner.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.sq_scanner.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
</div>
`;
/>
<p
className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.docs",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.docs"
+ id="onboarding.analysis.sq_scanner.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.sq_scanner.docs_link
+ </a>,
+ }
}
- }
- />
+ />
+ </p>
</div>
`;
</h4>
<p
className="spacer-bottom markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.text.win",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.text"
+ id="onboarding.analysis.sq_scanner.text"
+ values={
+ Object {
+ "dir": <code>
+ bin
+ </code>,
+ "env_var": <code>
+ %PATH%
+ </code>,
+ }
}
- }
- />
+ />
+ </p>
<p>
<a
className="button"
</h4>
<p
className="spacer-bottom markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.text.linux",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.text"
+ id="onboarding.analysis.sq_scanner.text"
+ values={
+ Object {
+ "dir": <code>
+ bin
+ </code>,
+ "env_var": <code>
+ PATH
+ </code>,
+ }
}
- }
- />
+ />
+ </p>
<p>
<a
className="button"
</h4>
<p
className="spacer-bottom markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.text.mac",
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.text"
+ id="onboarding.analysis.sq_scanner.text"
+ values={
+ Object {
+ "dir": <code>
+ bin
+ </code>,
+ "env_var": <code>
+ PATH
+ </code>,
+ }
}
- }
- />
+ />
+ </p>
<p>
<a
className="button"
<div className="boxed-group-inner">
<div
className="web-api-action-description markdown"
+ // Safe: comes from the backend
dangerouslySetInnerHTML={{ __html: action.description }}
/>
{domain.description && (
<div
className="web-api-domain-description markdown"
+ // Safe: comes from the backend
dangerouslySetInnerHTML={{ __html: domain.description }}
/>
)}
<td>
<div
className="markdown"
+ // Safe: comes from the backend
dangerouslySetInnerHTML={{ __html: param.description }}
/>
</td>
const isTextVisible = this.props.width >= 40 && this.props.height >= 45;
const isIconVisible = this.props.width >= 24 && this.props.height >= 26;
- const label = this.props.prefix
- ? `${this.props.prefix}<br>${this.props.label.substr(this.props.prefix.length)}`
- : this.props.label;
-
return (
<div
className="treemap-cell"
{this.props.icon}
</span>
)}
- {isTextVisible && (
- <span className="treemap-text" dangerouslySetInnerHTML={{ __html: label }} />
- )}
+ {isTextVisible &&
+ (this.props.prefix ? (
+ <span className="treemap-text">
+ {this.props.prefix}
+ <br />
+ {this.props.label.substr(this.props.prefix.length)}
+ </span>
+ ) : (
+ <span className="treemap-text">{this.props.label}</span>
+ ))}
</div>
{this.renderLink()}
</div>
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { shallow } from 'enzyme';
+import { mount } from 'enzyme';
import TreeMap from '../TreeMap';
+import TreeMapRect from '../TreeMapRect';
+import { mockEvent } from '../../../helpers/testMocks';
-it('should display', () => {
+it('should render correctly', () => {
const items = [
{ key: '1', size: 10, color: '#777', label: 'SonarQube :: Server' },
{ key: '2', size: 30, color: '#777', label: 'SonarQube :: Web' },
{ key: '3', size: 20, color: '#777', label: 'SonarQube :: Search' }
];
- const chart = shallow(
- <TreeMap height={100} items={items} onRectangleClick={() => {}} width={100} />
+ const onRectClick = jest.fn();
+ const chart = mount(
+ <TreeMap height={100} items={items} onRectangleClick={onRectClick} width={100} />
);
- expect(chart.find('TreeMapRect')).toHaveLength(3);
+ const rects = chart.find(TreeMapRect);
+ expect(rects).toHaveLength(3);
+
+ const event: React.MouseEvent<HTMLAnchorElement> = mockEvent({ stopPropagation: jest.fn() });
+ (rects.first().instance() as TreeMapRect).handleLinkClick(event);
+ expect(event.stopPropagation).toHaveBeenCalled();
+
+ (rects.first().instance() as TreeMapRect).handleRectClick();
+ expect(onRectClick).toHaveBeenCalledWith('2');
});
</div>
<div
className="issue-comment-text markdown"
+ // Safe: Comes from the backend, after markdown transformation to html
dangerouslySetInnerHTML={{ __html: comment.htmlText }}
/>
<div className="issue-comment-age">
};
}
+export function mockRuleDetailsParameter(
+ overrides: Partial<T.RuleParameter> = {}
+): T.RuleParameter {
+ return {
+ defaultValue: '1',
+ htmlDesc: 'description',
+ key: '1',
+ type: 'number',
+ ...overrides
+ };
+}
+
export function mockShortLivingBranch(
overrides: Partial<T.ShortLivingBranch> = {}
): T.ShortLivingBranch {
"@types/d3-interpolate" "*"
"@types/d3-selection" "*"
+"@types/domhandler@*":
+ version "2.4.1"
+ resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/domhandler/-/domhandler-2.4.1.tgz#7b3b347f7762180fbcb1ece1ce3dd0ebbb8c64cf"
+ integrity sha1-ezs0f3diGA+8sezhzj3Q67uMZM8=
+
+"@types/dompurify@^0.0.32":
+ version "0.0.32"
+ resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/dompurify/-/dompurify-0.0.32.tgz#ccc4148d7f2e0598006611e82e840806fab4b268"
+ integrity sha1-zMQUjX8uBZgAZhHoLoQIBvq0smg=
+
+"@types/domutils@*":
+ version "1.7.2"
+ resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/domutils/-/domutils-1.7.2.tgz#89422e579c165994ad5c09ce90325da596cc105d"
+ integrity sha1-iUIuV5wWWZStXAnOkDJdpZbMEF0=
+ dependencies:
+ "@types/domhandler" "*"
+
"@types/enzyme@3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.9.1.tgz#3a0ce07e30066dbc26cd3474c8e680af2d249e26"
resolved "https://registry.yarnpkg.com/@types/history/-/history-3.2.3.tgz#2416fee5cac641da2d05a905de5af5cb50162f60"
integrity sha512-s4SNWd31cmFP52ilv3LKCh344ayIXmfmcfExsegGspgnk/pQh75Yo6v49uzSE1oFMXp+Sz4GVnesL7rgybX9tQ==
+"@types/htmlparser2@*":
+ version "3.10.0"
+ resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/htmlparser2/-/htmlparser2-3.10.0.tgz#b94d3b08f813c9eec12990ac6a34d8b17a7aebc9"
+ integrity sha1-uU07CPgTye7BKZCsajTYsXp668k=
+ dependencies:
+ "@types/domhandler" "*"
+ "@types/domutils" "*"
+ "@types/node" "*"
+
"@types/istanbul-lib-coverage@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz#2cc2ca41051498382b43157c8227fea60363f94a"
"@types/prop-types" "*"
csstype "^2.2.0"
+"@types/sanitize-html@1.20.0":
+ version "1.20.0"
+ resolved "https://repox.jfrog.io/repox/api/npm/npm/@types/sanitize-html/-/sanitize-html-1.20.0.tgz#b3beaa9eacab0e0fa5022d5faa727fea8fb9fc5d"
+ integrity sha1-s76qnqyrDg+lAi1fqnJ/6o+5/F0=
+ dependencies:
+ "@types/htmlparser2" "*"
+
"@types/stack-utils@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
dependencies:
domelementtype "1"
+dompurify@^1.0.11:
+ version "1.0.11"
+ resolved "https://repox.jfrog.io/repox/api/npm/npm/dompurify/-/dompurify-1.0.11.tgz#fe0f4a40d147f7cebbe31a50a1357539cfc1eb4d"
+ integrity sha1-/g9KQNFH98674xpQoTV1Oc/B600=
+
domutils@1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
property.error.notInOptions=Not a valid option
property.category.scm=SCM
property.sonar.leak.period.description=Period used to compare measures and track new issues. Values are:<ul class='bullet'><li>Number of days before analysis, for example 5.</li><li>A custom date. Format is yyyy-MM-dd, for example 2010-12-25</li><li>'previous_version' to compare to the previous version in the project history</li><li>A version, for example '1.2' or 'BASELINE'</li></ul><p>When specifying a number of days or a date, the snapshot selected as the baseline for comparison is the first one available inside the corresponding time range. Specifically, the first analysis in the range is considered to be before the New Code Period. </p><p>Changing this property only takes effect after subsequent project analyses.<p/>
+property.sonar.leak.period.description.intro=Period used to compare measures and track new issues. Values are:
+property.sonar.leak.period.description.item1=Number of days before analysis, for example 5.
+property.sonar.leak.period.description.item2=A custom date. Format is yyyy-MM-dd, for example 2010-12-25
+property.sonar.leak.period.description.item3='previous_version' to compare to the previous version in the project history
+property.sonar.leak.period.description.item4=A version, for example '1.2' or 'BASELINE'
+property.sonar.leak.period.description.details1=When specifying a number of days or a date, the snapshot selected as the baseline for comparison is the first one available inside the corresponding time range. Specifically, the first analysis in the range is considered to be before the New Code Period.
+property.sonar.leak.period.description.details2=Changing this property only takes effect after subsequent project analyses.
property.sonar.branch.longLivedBranches.regex.description=Regular expression used to detect whether a branch is a long living branch (as opposed to short living branch), based on its name. This applies only during first analysis, the type of a branch cannot be changed later.
#
#------------------------------------------------------------------------------
search.shortcut_hint=Hint: Press {shortcut} from anywhere to open this search bar.
-search.show_more.hint=Press {0} to display
+search.show_more.hint=Press {key} to display
search.placeholder=Search for projects and files...
search.search_for_projects=Search for projects...
search.search_for_users=Search for users...
onboarding.language.os.mac=macOS
onboarding.language.project_key=Define a unique project key
+onboarding.analysis.docs=Please visit the {link} for more details.
+
onboarding.analysis.java.maven.header=Execute the Scanner for Maven from your computer
onboarding.analysis.java.maven.text=Running a {instance} analysis with Maven is straighforward. You just need to run the following command in your project's folder.
-onboarding.analysis.java.maven.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html" target="_blank">official documentation of the Scanner for Maven</a> for more details.
+onboarding.analysis.java.maven.docs_link=official documentation of the Scanner for Maven
onboarding.analysis.java.gradle.header=Execute the Scanner for Gradle from your computer
-onboarding.analysis.java.gradle.text.1=Running an analysis with Gradle is straighforward. You just need to declare the <code>org.sonarqube</code> plugin in your <code>build.gradle</code> file:
+onboarding.analysis.java.gradle.text.1=Running an analysis with Gradle is straighforward. You just need to declare the {plugin_code} plugin in your {filename} file:
onboarding.analysis.java.gradle.text.2=and run the following command:
-onboarding.analysis.java.gradle.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/gradle.html" target="_blank">official documentation of the Scanner for Gradle</a> for more details.
+onboarding.analysis.java.gradle.docs_link=official documentation of the Scanner for Gradle
onboarding.analysis.msbuild.header=Download and unzip the Scanner for MSBuild
-onboarding.analysis.msbuild.text=And add the executable's directory to the <code>%PATH%</code> environment variable
+onboarding.analysis.msbuild.text=And add the executable's directory to the {code} environment variable
onboarding.analysis.msbuild.execute=Execute the Scanner for MSBuild from your computer
onboarding.analysis.msbuild.execute.text=Running a {instance} analysis is straighforward. You just need to execute the following commands at the root of your solution.
-onboarding.analysis.msbuild.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html" target="_blank">official documentation of the Scanner for MSBuild</a> for more details.
+onboarding.analysis.msbuild.docs_link=official documentation of the Scanner for MSBuild
onboarding.analysis.build_wrapper.header.linux=Download and unzip the Build Wrapper for Linux
onboarding.analysis.build_wrapper.header.win=Download and unzip the Build Wrapper for Windows
onboarding.analysis.build_wrapper.header.mac=Download and unzip the Build Wrapper for macOS
-onboarding.analysis.build_wrapper.text.linux=And add the executable's directory to the <code>PATH</code> environment variable
-onboarding.analysis.build_wrapper.text.win=And add the executable's directory to the <code>%PATH%</code> environment variable
-onboarding.analysis.build_wrapper.text.mac=And add the executable's directory to the <code>PATH</code> environment variable
+onboarding.analysis.build_wrapper.text=And add the executable's directory to the {env_var} environment variable
onboarding.analysis.sq_scanner.header.linux=Download and unzip the Scanner for Linux
onboarding.analysis.sq_scanner.header.win=Download and unzip the Scanner for Windows
onboarding.analysis.sq_scanner.header.mac=Download and unzip the Scanner for macOS
-onboarding.analysis.sq_scanner.text.linux=And add the <code>bin</code> directory to the <code>PATH</code> environment variable
-onboarding.analysis.sq_scanner.text.win=And add the <code>bin</code> directory to the <code>%PATH%</code> environment variable
-onboarding.analysis.sq_scanner.text.mac=And add the <code>bin</code> directory to the <code>PATH</code> environment variable
+onboarding.analysis.sq_scanner.text=And add the {dir} directory to the {env_var} environment variable
onboarding.analysis.sq_scanner.execute=Execute the Scanner from your computer
onboarding.analysis.sq_scanner.execute.text=Running a {instance} analysis is straighforward. You just need to execute the following commands in your project's folder.
-onboarding.analysis.sq_scanner.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/install-configure-scanner.html" target="_blank">official documentation of the Scanner</a> for more details.
+onboarding.analysis.sq_scanner.docs=Please visit the {link} for more details.
+onboarding.analysis.sq_scanner.docs_link=official documentation of the Scanner
onboarding.project_watcher.not_started=Once your project is analyzed, this page will refresh automatically.
onboarding.project_watcher.in_progress=Analysis is in progress, please wait...
encryption.secret_key_description=Secret key is required to be able to encrypt properties. {moreInformationLink}
encryption.secret_key=Secret Key
encryption.how_to_use=How To Use
-encryption.how_to_use.content=<ul><li>Store the secret key in the file <code>~/.sonar/sonar-secret.txt</code> of the server. This file can be relocated by defining the property <code>sonar.secretKeyPath</code> in <code>conf/sonar.properties</code></li><li>Restrict access to this file by making it readable and by owner only</li><li>Restart the server if the property <code>sonar.secretKeyPath</code> has been set or changed.</li><li>For each property that you want to encrypt, generate the encrypted value and replace the original value wherever it is stored (configuration files, command lines).</li></ul>
-
+encryption.how_to_use.content1=Store the secret key in the file {secret_file} of the server. This file can be relocated by defining the property {property} in {propreties_file}
+encryption.how_to_use.content2=Restrict access to this file by making it readable and by owner only
+encryption.how_to_use.content3=Restart the server if the property {property} has been set or changed.
+encryption.how_to_use.content4=For each property that you want to encrypt, generate the encrypted value and replace the original value wherever it is stored (configuration files, command lines).
#------------------------------------------------------------------------------
#
maintenance.sonarqube_is_down.text=Something went wrong. Please contact your system administrator.
maintenance.try_again=Try Again
maintenance.is_under_maintenance={instance} is under maintenance
-maintenance.sonarqube_is_under_maintenance.1=While waiting, you might want to investigate <a href="https://redirect.sonarsource.com/doc/plugin-library.html">new plugins</a> to extend the current functionality.
-maintenance.sonarqube_is_under_maintenance.2=If you are an administrator and have no idea why this message is being shown, you should read the <a href="https://redirect.sonarsource.com/doc/upgrading.html">upgrade guide</a>.
+maintenance.sonarqube_is_under_maintenance.1=While waiting, you might want to investigate {link} to extend the current functionality.
+maintenance.sonarqube_is_under_maintenance_link.1=new plugins
+maintenance.sonarqube_is_under_maintenance.2=If you are an administrator and have no idea why this message is being shown, you should read the {link}.
+maintenance.sonarqube_is_under_maintenance_link.2=upgrade guide
maintenance.is_starting={instance} is starting
maintenance.is_up={instance} is up
maintenance.all_systems_opetational=All systems operational.