@patternfly/quickstarts 2.4.3 → 2.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,7 @@ declare type ShowdownExtension = {
5
5
  regex?: RegExp;
6
6
  replace?: (...args: any[]) => string;
7
7
  };
8
- export declare const markdownConvert: (markdown: any, extensions?: ShowdownExtension[]) => any;
8
+ export declare const markdownConvert: (markdown: string, extensions?: ShowdownExtension[]) => Promise<any>;
9
9
  declare type SyncMarkdownProps = {
10
10
  content?: string;
11
11
  emptyMsg?: string;
package/dist/index.es.js CHANGED
@@ -4,13 +4,13 @@ import { Card, CardHeader, CardActions, CardTitle, CardBody, CardFooter, Modal a
4
4
  import SearchIcon from '@patternfly/react-icons/dist/js/icons/search-icon';
5
5
  import { css } from '@patternfly/react-styles';
6
6
  import RocketIcon from '@patternfly/react-icons/dist/js/icons/rocket-icon';
7
- import { __rest } from 'tslib';
7
+ import { __rest, __awaiter } from 'tslib';
8
8
  import * as ReactDOM from 'react-dom';
9
9
  import { renderToStaticMarkup } from 'react-dom/server';
10
10
  import CopyIcon from '@patternfly/react-icons/dist/js/icons/copy-icon';
11
11
  import LightbulbIcon from '@patternfly/react-icons/dist/js/icons/lightbulb-icon';
12
12
  import FireIcon from '@patternfly/react-icons/dist/js/icons/fire-icon';
13
- import { Converter } from 'showdown';
13
+ import { marked } from 'marked';
14
14
  import SyncAltIcon from '@patternfly/react-icons/dist/js/icons/sync-alt-icon';
15
15
  import CheckCircleIcon from '@patternfly/react-icons/dist/js/icons/check-circle-icon';
16
16
  import ExclamationCircleIcon from '@patternfly/react-icons/dist/js/icons/exclamation-circle-icon';
@@ -1287,16 +1287,7 @@ const useMultilineCopyClipboardShowdownExtension = () => {
1287
1287
 
1288
1288
  // eslint-disable-next-line @typescript-eslint/no-require-imports
1289
1289
  const DOMPurify = require('dompurify');
1290
- const markdownConvert = (markdown, extensions) => {
1291
- const converter = new Converter({
1292
- tables: true,
1293
- openLinksInNewWindow: true,
1294
- strikethrough: true,
1295
- emoji: false,
1296
- });
1297
- if (extensions) {
1298
- converter.addExtension(extensions);
1299
- }
1290
+ const markdownConvert = (markdown, extensions) => __awaiter(void 0, void 0, void 0, function* () {
1300
1291
  DOMPurify.addHook('beforeSanitizeElements', function (node) {
1301
1292
  // nodeType 1 = element type
1302
1293
  // transform anchor tags
@@ -1323,20 +1314,48 @@ const markdownConvert = (markdown, extensions) => {
1323
1314
  node.setAttribute('xlink:show', 'new');
1324
1315
  }
1325
1316
  });
1326
- return DOMPurify.sanitize(converter.makeHtml(markdown), {
1327
- USE_PROFILES: {
1328
- html: true,
1329
- svg: true,
1330
- },
1331
- });
1332
- };
1317
+ const reverseString = (str) => str
1318
+ .split('')
1319
+ .reverse()
1320
+ .join('');
1321
+ // replace code fences that end in a double curly brace (which are used by our custom md extensions) with non
1322
+ // markdown formatting related tokens so that marked doesn't try to parse them as code spans
1323
+ //
1324
+ // we want to reverse the string before we do the substitution so that we only match the opening code fence which
1325
+ // corresponds to the closing code fence with the double curly brace
1326
+ const reversedMarkdown = reverseString(markdown);
1327
+ const reverseMarkdownWithSubstitutedCodeFences = reversedMarkdown.replace(/{{```((.|\n)*?)```/g, '{{@@@$1@@@');
1328
+ const markdownWithSubstitutedCodeFences = reverseString(reverseMarkdownWithSubstitutedCodeFences);
1329
+ const parsedMarkdown = yield marked.parse(markdownWithSubstitutedCodeFences);
1330
+ // Swap the temporary tokens back to code fences before we run the extensions
1331
+ let md = parsedMarkdown.replace(/@@@/g, '```');
1332
+ if (extensions) {
1333
+ // Convert code spans back to md format before we run the custom extension regexes
1334
+ md = md.replace(/<code>(.*)<\/code>/g, '`$1`');
1335
+ extensions.forEach(({ regex, replace }) => {
1336
+ if (regex) {
1337
+ md = md.replace(regex, replace);
1338
+ }
1339
+ });
1340
+ // Convert any remaining backticks back into code spans
1341
+ md = md.replace(/`(.*)`/g, '<code>$1</code>');
1342
+ }
1343
+ return DOMPurify.sanitize(md);
1344
+ });
1333
1345
  const SyncMarkdownView = ({
1334
1346
  // truncateContent,
1335
1347
  content, emptyMsg, extensions, renderExtension, exactHeight, inline, className, }) => {
1336
1348
  const { getResource } = React.useContext(QuickStartContext);
1337
- const markup = React.useMemo(() => {
1338
- return markdownConvert(content || emptyMsg || getResource('Not available'), extensions);
1339
- }, [content, emptyMsg, extensions, getResource]);
1349
+ const [markup, setMarkup] = React.useState('');
1350
+ React.useEffect(() => {
1351
+ function getMd() {
1352
+ return __awaiter(this, void 0, void 0, function* () {
1353
+ const md = yield markdownConvert(content || emptyMsg || getResource('Not available'), extensions);
1354
+ setMarkup(md);
1355
+ });
1356
+ }
1357
+ getMd();
1358
+ }, [content, emptyMsg, getResource, extensions]);
1340
1359
  const innerProps = {
1341
1360
  renderExtension: (extensions === null || extensions === void 0 ? void 0 : extensions.length) > 0 ? renderExtension : undefined,
1342
1361
  exactHeight,
@@ -2003,12 +2022,22 @@ const TaskIcon = ({ taskIndex, taskStatus }) => {
2003
2022
  };
2004
2023
  const QuickStartTaskHeader = ({ title, taskIndex, subtitle, taskStatus, size, isActiveTask, onTaskSelect, children, }) => {
2005
2024
  const titleRef = React.useRef(null);
2025
+ const [parsedTitle, setParsedTitle] = React.useState('');
2006
2026
  React.useEffect(() => {
2007
2027
  if (isActiveTask) {
2008
2028
  // Focus the WizardNavItem button element that contains the title
2009
2029
  titleRef.current.parentNode.focus();
2010
2030
  }
2011
2031
  }, [isActiveTask]);
2032
+ React.useEffect(() => {
2033
+ function getParsedTitle() {
2034
+ return __awaiter(this, void 0, void 0, function* () {
2035
+ const convertedMdTitle = yield markdownConvert(title);
2036
+ setParsedTitle(removeParagraphWrap(convertedMdTitle));
2037
+ });
2038
+ }
2039
+ getParsedTitle();
2040
+ }, [title]);
2012
2041
  const classNames = css('pfext-quick-start-task-header__title', {
2013
2042
  'pfext-quick-start-task-header__title-success': taskStatus === QuickStartTaskStatus.SUCCESS,
2014
2043
  'pfext-quick-start-task-header__title-failed': taskStatus === (QuickStartTaskStatus.FAILED || QuickStartTaskStatus.VISITED),
@@ -2024,7 +2053,7 @@ const QuickStartTaskHeader = ({ title, taskIndex, subtitle, taskStatus, size, is
2024
2053
  const content = (React.createElement("div", { className: "pfext-quick-start-task-header", ref: titleRef },
2025
2054
  React.createElement(TaskIcon, { taskIndex: taskIndex, taskStatus: taskStatus }),
2026
2055
  React.createElement(Title, { headingLevel: "h3", size: size, className: classNames },
2027
- React.createElement("span", { dangerouslySetInnerHTML: { __html: removeParagraphWrap(markdownConvert(title)) } }),
2056
+ React.createElement("span", { dangerouslySetInnerHTML: { __html: parsedTitle } }),
2028
2057
  isActiveTask && subtitle && (React.createElement("span", { className: "pfext-quick-start-task-header__subtitle", "data-test-id": "quick-start-task-subtitle" },
2029
2058
  ' ',
2030
2059
  subtitle))),
@@ -2231,6 +2260,7 @@ const QuickStartPanelContent = (_a) => {
2231
2260
  const titleRef = React.useRef(null);
2232
2261
  const { getResource, activeQuickStartState } = React.useContext(QuickStartContext);
2233
2262
  const [contentRef, setContentRef] = React.useState();
2263
+ const [displayName, setDisplayName] = React.useState('');
2234
2264
  const shadows = useScrollShadows(contentRef);
2235
2265
  const quickStart = quickStarts.find((qs) => qs.metadata.name === activeQuickStartID);
2236
2266
  const taskNumber = activeQuickStartState === null || activeQuickStartState === void 0 ? void 0 : activeQuickStartState.taskNumber;
@@ -2258,13 +2288,22 @@ const QuickStartPanelContent = (_a) => {
2258
2288
  titleRef.current.focus();
2259
2289
  }
2260
2290
  }, [quickStart]);
2291
+ React.useEffect(() => {
2292
+ function getDisplayName() {
2293
+ return __awaiter(this, void 0, void 0, function* () {
2294
+ const convertedMdDisplayName = yield markdownConvert(quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.displayName);
2295
+ setDisplayName(removeParagraphWrap(convertedMdDisplayName));
2296
+ });
2297
+ }
2298
+ getDisplayName();
2299
+ }, [quickStart]);
2261
2300
  const content = quickStart ? (React.createElement(DrawerPanelContent, Object.assign({ isResizable: isResizable, className: "pfext-quick-start__base", "data-testid": `qs-drawer-${camelize(quickStart.spec.displayName)}`, "data-qs": `qs-step-${getStep()}`, "data-test": "quickstart drawer" }, props),
2262
2301
  React.createElement("div", { className: headerClasses },
2263
2302
  React.createElement(DrawerHead, null,
2264
2303
  React.createElement("div", { className: "pfext-quick-start-panel-content__title", tabIndex: -1, ref: titleRef },
2265
2304
  React.createElement(Title, { headingLevel: "h2", size: "xl", className: "pfext-quick-start-panel-content__name", style: { marginRight: 'var(--pf-global--spacer--md)' } },
2266
2305
  React.createElement("span", { dangerouslySetInnerHTML: {
2267
- __html: removeParagraphWrap(markdownConvert(quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.displayName)),
2306
+ __html: displayName,
2268
2307
  } }),
2269
2308
  ' ',
2270
2309
  React.createElement("small", { className: "pfext-quick-start-panel-content__duration" }, (quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.durationMinutes) ? getResource('{{type}} • {{duration, number}} minutes', quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.durationMinutes)