Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,5 +112,6 @@
"!**/node_modules/**"
],
"resolver": "./jest-resolver.js"
}
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
2 changes: 1 addition & 1 deletion packages/dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"react-dom": "^16.14.0",
"react-i18next": "^11.7.3",
"react-router-dom": "^5.2.0",
"showdown": "2.1.0",
"marked": "^4.0.0",
"lodash-es": "^4.17.21"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/module/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"@patternfly/react-core": ">=4.115.2",
"react": ">=16.8.0",
"react-dom": ">=16.8.0",
"showdown": ">=2.1.0"
"marked": "^4.0.0"
},
"dependencies": {
"@patternfly/react-catalog-view-extension": "^4.93.15",
Expand Down
84 changes: 34 additions & 50 deletions packages/module/src/ConsoleInternal/components/markdown-view.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { css } from '@patternfly/react-styles';
import { Converter } from 'showdown';
import { marked } from 'marked';
import { useForceRender } from '@console/shared';
import { QuickStartContext, QuickStartContextValues } from '../../utils/quick-start-context';
import './_markdown-view.scss';
Expand All @@ -16,18 +16,7 @@ type ShowdownExtension = {
replace?: (...args: any[]) => string;
};

export const markdownConvert = (markdown, extensions?: ShowdownExtension[]) => {
const converter = new Converter({
tables: true,
openLinksInNewWindow: true,
strikethrough: true,
emoji: false,
});

if (extensions) {
converter.addExtension(extensions);
}

export const markdownConvert = async (markdown: string, extensions?: ShowdownExtension[]) => {
DOMPurify.addHook('beforeSanitizeElements', function(node) {
// nodeType 1 = element type

Expand Down Expand Up @@ -62,40 +51,26 @@ export const markdownConvert = (markdown, extensions?: ShowdownExtension[]) => {
}
});

return DOMPurify.sanitize(converter.makeHtml(markdown), {
USE_PROFILES: {
html: true,
svg: true,
},
// ALLOWED_TAGS: [
// 'b',
// 'i',
// 'strike',
// 's',
// 'del',
// 'em',
// 'strong',
// 'a',
// 'p',
// 'h1',
// 'h2',
// 'h3',
// 'h4',
// 'ul',
// 'ol',
// 'li',
// 'code',
// 'pre',
// 'button',
// ...tableTags,
// 'div',
// 'img',
// 'span',
// 'svg',
// ],
// ALLOWED_ATTR: ['href', 'target', 'rel', 'class', 'src', 'alt', 'id'],
// ALLOWED_URI_REGEXP: /^(?:(?:https?|mailto|didact):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i,
});
// Replace code fences with non markdown formatting relates tokens so that marked doesn't try to parse them as code spans
const markdownWithSubstitutedCodeFences = markdown.replace(/```/g, '@@@');
const parsedMarkdown = await marked.parse(markdownWithSubstitutedCodeFences);
// Swap the temporary tokens back to code fences before we run the extensions
let md = parsedMarkdown.replace(/@@@/g, '```');

if (extensions) {
// Convert code spans back to md format before we run the custom extension regexes
md = md.replace(/<code>(.*)<\/code>/g, '`$1`');

extensions.forEach(({ regex, replace }) => {
if (regex) {
md = md.replace(regex, replace);
}
});

// Convert any remaining backticks back into code spans
md = md.replace(/`(.*)`/g, '<code>$1</code>');
}
return DOMPurify.sanitize(md);
};

type SyncMarkdownProps = {
Expand Down Expand Up @@ -126,9 +101,18 @@ export const SyncMarkdownView: React.FC<SyncMarkdownProps> = ({
className,
}) => {
const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
const markup = React.useMemo(() => {
return markdownConvert(content || emptyMsg || getResource('Not available'), extensions);
}, [content, emptyMsg, extensions, getResource]);
const [markup, setMarkup] = React.useState<string>('');

React.useEffect(() => {
async function getMd() {
const md = await markdownConvert(
content || emptyMsg || getResource('Not available'),
extensions,
);
setMarkup(md);
}
getMd();
}, [content, emptyMsg, getResource, extensions]);
const innerProps: InnerSyncMarkdownProps = {
renderExtension: extensions?.length > 0 ? renderExtension : undefined,
exactHeight,
Expand Down
11 changes: 10 additions & 1 deletion packages/module/src/QuickStartPanelContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const QuickStartPanelContent: React.FC<QuickStartPanelContentProps> = ({
QuickStartContext,
);
const [contentRef, setContentRef] = React.useState<HTMLDivElement>();
const [displayName, setDisplayName] = React.useState<string>('');
const shadows = useScrollShadows(contentRef);
const quickStart = quickStarts.find((qs) => qs.metadata.name === activeQuickStartID);
const taskNumber = activeQuickStartState?.taskNumber;
Expand Down Expand Up @@ -96,6 +97,14 @@ const QuickStartPanelContent: React.FC<QuickStartPanelContentProps> = ({
}
}, [quickStart]);

React.useEffect(() => {
async function getDisplayName() {
const convertedMdDisplayName = await markdownConvert(quickStart?.spec.displayName);
setDisplayName(removeParagraphWrap(convertedMdDisplayName));
}
getDisplayName();
}, [quickStart]);

const content = quickStart ? (
<DrawerPanelContent
isResizable={isResizable}
Expand All @@ -116,7 +125,7 @@ const QuickStartPanelContent: React.FC<QuickStartPanelContentProps> = ({
>
<span
dangerouslySetInnerHTML={{
__html: removeParagraphWrap(markdownConvert(quickStart?.spec.displayName)),
__html: displayName,
}}
/>{' '}
<small className="pfext-quick-start-panel-content__duration">
Expand Down
13 changes: 12 additions & 1 deletion packages/module/src/controller/QuickStartTaskHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,23 @@ const QuickStartTaskHeader: React.FC<QuickStartTaskHeaderProps> = ({
children,
}) => {
const titleRef = React.useRef(null);
const [parsedTitle, setParsedTitle] = React.useState<string>('');

React.useEffect(() => {
if (isActiveTask) {
// Focus the WizardNavItem button element that contains the title
titleRef.current.parentNode.focus();
}
}, [isActiveTask]);

React.useEffect(() => {
async function getParsedTitle() {
const convertedMdTitle = await markdownConvert(title);
setParsedTitle(removeParagraphWrap(convertedMdTitle));
}
getParsedTitle();
}, [title]);

const classNames = css('pfext-quick-start-task-header__title', {
'pfext-quick-start-task-header__title-success': taskStatus === QuickStartTaskStatus.SUCCESS,
'pfext-quick-start-task-header__title-failed':
Expand All @@ -92,7 +103,7 @@ const QuickStartTaskHeader: React.FC<QuickStartTaskHeaderProps> = ({
<div className="pfext-quick-start-task-header" ref={titleRef}>
<TaskIcon taskIndex={taskIndex} taskStatus={taskStatus} />
<Title headingLevel="h3" size={size} className={classNames}>
<span dangerouslySetInnerHTML={{ __html: removeParagraphWrap(markdownConvert(title)) }} />
<span dangerouslySetInnerHTML={{ __html: parsedTitle }} />
{isActiveTask && subtitle && (
<span
className="pfext-quick-start-task-header__subtitle"
Expand Down
1 change: 1 addition & 0 deletions packages/module/src/declaration.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
declare module '*.scss';
declare module '*.json';
declare module 'marked';
17 changes: 5 additions & 12 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4630,11 +4630,6 @@ commander@^7.0.0, commander@~7.2.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==

commander@^9.0.0:
version "9.5.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30"
integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==

common-log-format@~0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/common-log-format/-/common-log-format-0.1.4.tgz#39ba6ccb5c46c2f89aa92f232866d18f18075ba9"
Expand Down Expand Up @@ -10650,6 +10645,11 @@ markdown-table@^2.0.0:
dependencies:
repeat-string "^1.0.0"

marked@^4.0.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3"
integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==

matcher-collection@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/matcher-collection/-/matcher-collection-2.0.1.tgz#90be1a4cf58d6f2949864f65bb3b0f3e41303b29"
Expand Down Expand Up @@ -14263,13 +14263,6 @@ shortid@^2.2.8:
dependencies:
nanoid "^2.1.0"

showdown@2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/showdown/-/showdown-2.1.0.tgz#1251f5ed8f773f0c0c7bfc8e6fd23581f9e545c5"
integrity sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==
dependencies:
commander "^9.0.0"

side-channel@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
Expand Down