*/
import styled from '@emotion/styled';
import * as React from 'react';
+import tw from 'twin.macro';
import { themeColor } from '../helpers';
export interface MessageFormatting {
export function IssueMessageHighlighting(props: IssueMessageHighlightingProps) {
const { message, messageFormattings } = props;
- if (!message) {
+ if (message === undefined || message === '') {
return null;
}
<React.Fragment key={`${message}-${start}-${end}`}>
{message.slice(beginning, start)}
{type === MessageFormattingType.CODE ? (
- <SingleLineSnippet className="sw-code sw-rounded-1 sw-py-1/2 sw-px-1 sw-border sw-border-solid">
+ <SingleLineSnippet className="sw-code sw-rounded-1 sw-px-1 sw-border sw-border-solid">
{message.slice(start, end)}
</SingleLineSnippet>
) : (
background: ${themeColor('codeSnippetBackground')};
border-color: ${themeColor('codeSnippetBorder')};
color: ${themeColor('codeSnippetInline')};
+ ${tw`sw-py-1/2`}
+
+ a & {
+ ${tw`sw-pb-0`}
+ }
`;
background: rgb(252,252,253);
border-color: rgb(225,230,243);
color: rgb(62,67,87);
+ padding-top: 0.125rem;
+ padding-bottom: 0.125rem;
+}
+
+a .emotion-0 {
+ padding-bottom: 0;
}
<span>
m
<span
- class="sw-code sw-rounded-1 sw-py-1/2 sw-px-1 sw-border sw-border-solid emotion-0 emotion-1"
+ class="sw-code sw-rounded-1 sw-px-1 sw-border sw-border-solid emotion-0 emotion-1"
>
ess
</span>
a
<span
- class="sw-code sw-rounded-1 sw-py-1/2 sw-px-1 sw-border sw-border-solid emotion-0 emotion-1"
+ class="sw-code sw-rounded-1 sw-px-1 sw-border sw-border-solid emotion-0 emotion-1"
>
g
</span>
background: rgb(252,252,253);
border-color: rgb(225,230,243);
color: rgb(62,67,87);
+ padding-top: 0.125rem;
+ padding-bottom: 0.125rem;
+}
+
+a .emotion-0 {
+ padding-bottom: 0;
}
<span>
a somewhat longer message with overlapping range
<span
- class="sw-code sw-rounded-1 sw-py-1/2 sw-px-1 sw-border sw-border-solid emotion-0 emotion-1"
+ class="sw-code sw-rounded-1 sw-px-1 sw-border sw-border-solid emotion-0 emotion-1"
>
s
</span>
background: rgb(252,252,253);
border-color: rgb(225,230,243);
color: rgb(62,67,87);
+ padding-top: 0.125rem;
+ padding-bottom: 0.125rem;
+}
+
+a .emotion-0 {
+ padding-bottom: 0;
}
<span>
a
<span
- class="sw-code sw-rounded-1 sw-py-1/2 sw-px-1 sw-border sw-border-solid emotion-0 emotion-1"
+ class="sw-code sw-rounded-1 sw-px-1 sw-border sw-border-solid emotion-0 emotion-1"
>
somewhat longer message
</span>
background: rgb(252,252,253);
border-color: rgb(225,230,243);
color: rgb(62,67,87);
+ padding-top: 0.125rem;
+ padding-bottom: 0.125rem;
+}
+
+a .emotion-0 {
+ padding-bottom: 0;
}
<span>
a
<span
- class="sw-code sw-rounded-1 sw-py-1/2 sw-px-1 sw-border sw-border-solid emotion-0 emotion-1"
+ class="sw-code sw-rounded-1 sw-px-1 sw-border sw-border-solid emotion-0 emotion-1"
>
somewhat longer message with
</span>
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import styled from '@emotion/styled';
-import { BareButton, SubnavigationItem, themeColor, themeContrast } from 'design-system';
+import {
+ BareButton,
+ IssueMessageHighlighting,
+ SubnavigationItem,
+ themeColor,
+ themeContrast,
+} from 'design-system';
import { noop } from 'lodash';
import * as React from 'react';
import { Issue } from '../../../types/types';
>
<div className="sw-w-full">
<StyledIssueTitle aria-current={selected} className="sw-mb-2">
- {issue.message}
+ <IssueMessageHighlighting
+ message={issue.message}
+ messageFormattings={issue.messageFormattings}
+ />
</StyledIssueTitle>
<IssueInfo className="sw-flex sw-justify-between sw-gap-2">
<IssueItemLocationsQuantity issue={issue} />
import styled from '@emotion/styled';
import {
ClipboardIconButton,
+ IssueMessageHighlighting,
LAYOUT_GLOBAL_NAV_HEIGHT,
LAYOUT_PROJECT_NAV_HEIGHT,
LightLabel,
themeShadow,
} from 'design-system';
import React from 'react';
-import { IssueMessageHighlighting } from '../../../components/issue/IssueMessageHighlighting';
import { getBranchLikeQuery } from '../../../helpers/branch-like';
import { translate } from '../../../helpers/l10n';
import {
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { LineFinding } from 'design-system';
+import { IssueMessageHighlighting, LineFinding } from 'design-system';
import * as React from 'react';
-import { IssueMessageHighlighting } from '../../../components/issue/IssueMessageHighlighting';
import { Hotspot } from '../../../types/security-hotspots';
const SCROLL_DELAY = 100;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 classNames from 'classnames';
-import * as React from 'react';
-import { MessageFormatting, MessageFormattingType } from '../../types/issues';
-
-export interface IssueMessageHighlightingProps {
- message?: string;
- messageFormattings?: MessageFormatting[];
-}
-
-export function IssueMessageHighlighting(props: IssueMessageHighlightingProps) {
- const { message, messageFormattings } = props;
-
- if (!message) {
- return null;
- }
-
- if (!(messageFormattings && messageFormattings.length > 0)) {
- return <>{message}</>;
- }
-
- let previousEnd = 0;
-
- const sanitizedFormattings = [...messageFormattings]
- .sort((a, b) => a.start - b.start)
- .reduce((acc, messageFormatting) => {
- const { type } = messageFormatting;
-
- if (type !== MessageFormattingType.CODE) {
- return acc;
- }
-
- const { start } = messageFormatting;
- let { end } = messageFormatting;
-
- end = Math.min(message.length, end);
-
- if (start < 0 || end === start || end < start) {
- return acc;
- }
-
- if (acc.length > 0) {
- const { start: previousStart, end: previousEnd } = acc[acc.length - 1];
-
- if (start <= previousEnd) {
- acc[acc.length - 1] = {
- start: previousStart,
- end: Math.max(previousEnd, end),
- type,
- };
-
- return acc;
- }
- }
-
- acc.push({ start, end, type });
-
- return acc;
- }, [] as typeof messageFormattings);
-
- return (
- <span>
- {sanitizedFormattings.map(({ start, end, type }) => {
- const beginning = previousEnd;
- previousEnd = end;
-
- return (
- <React.Fragment key={`${message}-${start}-${end}`}>
- {message.slice(beginning, start)}
- <span
- className={classNames({
- 'issue-message-highlight-CODE': type === MessageFormattingType.CODE,
- })}
- >
- {message.slice(start, end)}
- </span>
- </React.Fragment>
- );
- })}
-
- {message.slice(previousEnd)}
- </span>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 React from 'react';
-import { renderComponent } from '../../../helpers/testReactTestingUtils';
-import { MessageFormattingType } from '../../../types/issues';
-import {
- IssueMessageHighlighting,
- IssueMessageHighlightingProps,
-} from '../IssueMessageHighlighting';
-
-it.each([
- [undefined, undefined],
- ['message', undefined],
- ['message', []],
- ['message', [{ start: 1, end: 4, type: 'something else' as MessageFormattingType }]],
- [
- 'message',
- [
- { start: 5, end: 6, type: MessageFormattingType.CODE },
- { start: 1, end: 4, type: MessageFormattingType.CODE },
- ],
- ],
- [
- 'a somewhat longer message with overlapping ranges',
- [{ start: -1, end: 1, type: MessageFormattingType.CODE }],
- ],
- [
- 'a somewhat longer message with overlapping ranges',
- [{ start: 48, end: 70, type: MessageFormattingType.CODE }],
- ],
- [
- 'a somewhat longer message with overlapping ranges',
- [{ start: 0, end: 0, type: MessageFormattingType.CODE }],
- ],
- [
- 'a somewhat longer message with overlapping ranges',
- [
- { start: 11, end: 17, type: MessageFormattingType.CODE },
- { start: 2, end: 25, type: MessageFormattingType.CODE },
- { start: 25, end: 2, type: MessageFormattingType.CODE },
- ],
- ],
- [
- 'a somewhat longer message with overlapping ranges',
- [
- { start: 18, end: 30, type: MessageFormattingType.CODE },
- { start: 2, end: 25, type: MessageFormattingType.CODE },
- ],
- ],
-])('should format the string with highlights', (message, messageFormattings) => {
- const { asFragment } = renderIssueMessageHighlighting({ message, messageFormattings });
- expect(asFragment()).toMatchSnapshot();
-});
-
-function renderIssueMessageHighlighting(props: Partial<IssueMessageHighlightingProps> = {}) {
- return renderComponent(<IssueMessageHighlighting {...props} />);
-}
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should format the string with highlights 1`] = `<DocumentFragment />`;
-
-exports[`should format the string with highlights 2`] = `
-<DocumentFragment>
- message
-</DocumentFragment>
-`;
-
-exports[`should format the string with highlights 3`] = `
-<DocumentFragment>
- message
-</DocumentFragment>
-`;
-
-exports[`should format the string with highlights 4`] = `
-<DocumentFragment>
- <span>
- message
- </span>
-</DocumentFragment>
-`;
-
-exports[`should format the string with highlights 5`] = `
-<DocumentFragment>
- <span>
- m
- <span
- class="issue-message-highlight-CODE"
- >
- ess
- </span>
- a
- <span
- class="issue-message-highlight-CODE"
- >
- g
- </span>
- e
- </span>
-</DocumentFragment>
-`;
-
-exports[`should format the string with highlights 6`] = `
-<DocumentFragment>
- <span>
- a somewhat longer message with overlapping ranges
- </span>
-</DocumentFragment>
-`;
-
-exports[`should format the string with highlights 7`] = `
-<DocumentFragment>
- <span>
- a somewhat longer message with overlapping range
- <span
- class="issue-message-highlight-CODE"
- >
- s
- </span>
- </span>
-</DocumentFragment>
-`;
-
-exports[`should format the string with highlights 8`] = `
-<DocumentFragment>
- <span>
- a somewhat longer message with overlapping ranges
- </span>
-</DocumentFragment>
-`;
-
-exports[`should format the string with highlights 9`] = `
-<DocumentFragment>
- <span>
- a
- <span
- class="issue-message-highlight-CODE"
- >
- somewhat longer message
- </span>
- with overlapping ranges
- </span>
-</DocumentFragment>
-`;
-
-exports[`should format the string with highlights 10`] = `
-<DocumentFragment>
- <span>
- a
- <span
- class="issue-message-highlight-CODE"
- >
- somewhat longer message with
- </span>
- overlapping ranges
- </span>
-</DocumentFragment>
-`;
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { StandoutLink } from 'design-system';
+import { IssueMessageHighlighting, StandoutLink } from 'design-system';
import * as React from 'react';
import { ComponentContext } from '../../../app/components/componentContext/ComponentContext';
import { areMyIssuesSelected, parseQuery, serializeQuery } from '../../../apps/issues/utils';
import { BranchLike } from '../../../types/branch-like';
import { Issue } from '../../../types/types';
import { useLocation } from '../../hoc/withRouter';
-import { IssueMessageHighlighting } from '../IssueMessageHighlighting';
export interface IssueMessageProps {
issue: Issue;
*/
import styled from '@emotion/styled';
import classNames from 'classnames';
-import { LocationMarker, StyledMarker, themeColor } from 'design-system';
+import { IssueMessageHighlighting, LocationMarker, StyledMarker, themeColor } from 'design-system';
import * as React from 'react';
import { translateWithParameters } from '../../helpers/l10n';
import { MessageFormatting } from '../../types/issues';
import LocationMessage from '../common/LocationMessage';
-import { IssueMessageHighlighting } from '../issue/IssueMessageHighlighting';
import './SingleFileLocationNavigator.css';
interface Props {