@patternfly/quickstarts 5.4.1 → 5.4.3

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 @@ interface 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
  interface SyncMarkdownProps {
10
10
  content?: string;
11
11
  emptyMsg?: string;
package/dist/index.es.js CHANGED
@@ -3,7 +3,7 @@ import React__default, { createContext, useCallback, useEffect, useState } from
3
3
  import { getUniqueId, Card, CardHeader, CardTitle, CardBody, CardFooter, Modal as Modal$1, useIsomorphicLayoutEffect, Tooltip, Alert, CodeBlock, Accordion, AccordionItem, AccordionToggle, AccordionContent, Popover, PopoverPosition, Button, Icon, Text, TextVariants, TextList, TextListItem, Flex, FlexItem, Title, Label, Gallery, GalleryItem, ToolbarItem, SearchInput, Select, SelectList, SelectOption, MenuToggle, Badge, Toolbar, ToolbarContent, EmptyState, EmptyStateHeader, EmptyStateIcon, EmptyStateBody, EmptyStateFooter, EmptyStateActions, Divider, ModalVariant, WizardNavItem, List, ExpandableSection, ListItem, Radio, DrawerPanelContent, DrawerHead, DrawerActions, DrawerCloseButton, DrawerPanelBody, Drawer, DrawerContent, DrawerContentBody, Stack, StackItem } from '@patternfly/react-core';
4
4
  import SearchIcon from '@patternfly/react-icons/dist/js/icons/search-icon';
5
5
  import { css } from '@patternfly/react-styles';
6
- import { __rest } from 'tslib';
6
+ import { __rest, __awaiter } from 'tslib';
7
7
  import '@patternfly/react-styles/css/components/Form/form';
8
8
  import RocketIcon from '@patternfly/react-icons/dist/js/icons/rocket-icon';
9
9
  import * as ReactDOM from 'react-dom';
@@ -11,7 +11,7 @@ import { renderToStaticMarkup } from 'react-dom/server';
11
11
  import CopyIcon from '@patternfly/react-icons/dist/js/icons/copy-icon';
12
12
  import LightbulbIcon from '@patternfly/react-icons/dist/js/icons/lightbulb-icon';
13
13
  import FireIcon from '@patternfly/react-icons/dist/js/icons/fire-icon';
14
- import { Converter } from 'showdown';
14
+ import { marked } from 'marked';
15
15
  import SyncAltIcon from '@patternfly/react-icons/dist/js/icons/sync-alt-icon';
16
16
  import CheckCircleIcon from '@patternfly/react-icons/dist/js/icons/check-circle-icon';
17
17
  import ExclamationCircleIcon from '@patternfly/react-icons/dist/js/icons/exclamation-circle-icon';
@@ -1276,16 +1276,7 @@ const useMultilineCopyClipboardShowdownExtension = () => {
1276
1276
 
1277
1277
  // eslint-disable-next-line @typescript-eslint/no-require-imports
1278
1278
  const DOMPurify = require('dompurify');
1279
- const markdownConvert = (markdown, extensions) => {
1280
- const converter = new Converter({
1281
- tables: true,
1282
- openLinksInNewWindow: true,
1283
- strikethrough: true,
1284
- emoji: false,
1285
- });
1286
- if (extensions) {
1287
- converter.addExtension(extensions);
1288
- }
1279
+ const markdownConvert = (markdown, extensions) => __awaiter(void 0, void 0, void 0, function* () {
1289
1280
  DOMPurify.addHook('beforeSanitizeElements', function (node) {
1290
1281
  // nodeType 1 = element type
1291
1282
  // transform anchor tags
@@ -1312,16 +1303,43 @@ const markdownConvert = (markdown, extensions) => {
1312
1303
  node.setAttribute('xlink:show', 'new');
1313
1304
  }
1314
1305
  });
1315
- return DOMPurify.sanitize(converter.makeHtml(markdown), {
1316
- USE_PROFILES: {
1317
- html: true,
1318
- svg: true,
1319
- },
1320
- });
1321
- };
1306
+ const reverseString = (str) => str.split('').reverse().join('');
1307
+ // replace code fences that end in a double curly brace (which are used by our custom md extensions) with non
1308
+ // markdown formatting related tokens so that marked doesn't try to parse them as code spans
1309
+ //
1310
+ // we want to reverse the string before we do the substitution so that we only match the opening code fence which
1311
+ // corresponds to the closing code fence with the double curly brace
1312
+ const reversedMarkdown = reverseString(markdown);
1313
+ const reverseMarkdownWithSubstitutedCodeFences = reversedMarkdown.replace(/{{```((.|\n)*?)```/g, '{{@@@$1@@@');
1314
+ const markdownWithSubstitutedCodeFences = reverseString(reverseMarkdownWithSubstitutedCodeFences);
1315
+ const parsedMarkdown = yield marked.parse(markdownWithSubstitutedCodeFences);
1316
+ // Swap the temporary tokens back to code fences before we run the extensions
1317
+ let md = parsedMarkdown.replace(/@@@/g, '```');
1318
+ if (extensions) {
1319
+ // Convert code spans back to md format before we run the custom extension regexes
1320
+ md = md.replace(/<code>(.*)<\/code>/g, '`$1`');
1321
+ extensions.forEach(({ regex, replace }) => {
1322
+ if (regex) {
1323
+ md = md.replace(regex, replace);
1324
+ }
1325
+ });
1326
+ // Convert any remaining backticks back into code spans
1327
+ md = md.replace(/`(.*)`/g, '<code>$1</code>');
1328
+ }
1329
+ return DOMPurify.sanitize(md);
1330
+ });
1322
1331
  const SyncMarkdownView = ({ content, emptyMsg, extensions, renderExtension, exactHeight, inline, className, }) => {
1323
1332
  const { getResource } = React.useContext(QuickStartContext);
1324
- const markup = React.useMemo(() => markdownConvert(content || emptyMsg || getResource('Not available'), extensions), [content, emptyMsg, extensions, getResource]);
1333
+ const [markup, setMarkup] = React.useState('');
1334
+ React.useEffect(() => {
1335
+ function getMd() {
1336
+ return __awaiter(this, void 0, void 0, function* () {
1337
+ const md = yield markdownConvert(content || emptyMsg || getResource('Not available'), extensions);
1338
+ setMarkup(md);
1339
+ });
1340
+ }
1341
+ getMd();
1342
+ }, [content, emptyMsg, getResource, extensions]);
1325
1343
  const innerProps = {
1326
1344
  renderExtension: (extensions === null || extensions === void 0 ? void 0 : extensions.length) > 0 ? renderExtension : undefined,
1327
1345
  exactHeight,
@@ -1986,12 +2004,22 @@ const TaskIcon = ({ taskIndex, taskStatus }) => {
1986
2004
  const QuickStartTaskHeader = ({ title, taskIndex, subtitle, taskStatus, size, isActiveTask, onTaskSelect, children, }) => {
1987
2005
  const titleRef = React.useRef(null);
1988
2006
  const { focusOnQuickStart } = React.useContext(QuickStartContext);
2007
+ const [parsedTitle, setParsedTitle] = React.useState('');
1989
2008
  React.useEffect(() => {
1990
2009
  if (focusOnQuickStart && isActiveTask) {
1991
2010
  // Focus the WizardNavItem button element that contains the title
1992
2011
  titleRef.current.parentNode.focus();
1993
2012
  }
1994
2013
  }, [focusOnQuickStart, isActiveTask]);
2014
+ React.useEffect(() => {
2015
+ function getParsedTitle() {
2016
+ return __awaiter(this, void 0, void 0, function* () {
2017
+ const convertedMdTitle = yield markdownConvert(title);
2018
+ setParsedTitle(removeParagraphWrap(convertedMdTitle));
2019
+ });
2020
+ }
2021
+ getParsedTitle();
2022
+ }, [title]);
1995
2023
  const classNames = css('pfext-quick-start-task-header__title', {
1996
2024
  'pfext-quick-start-task-header__title-success': taskStatus === QuickStartTaskStatus.SUCCESS,
1997
2025
  'pfext-quick-start-task-header__title-failed': taskStatus === (QuickStartTaskStatus.FAILED || QuickStartTaskStatus.VISITED),
@@ -2007,7 +2035,7 @@ const QuickStartTaskHeader = ({ title, taskIndex, subtitle, taskStatus, size, is
2007
2035
  const content = (React.createElement("div", { className: "pfext-quick-start-task-header", ref: titleRef },
2008
2036
  React.createElement(TaskIcon, { taskIndex: taskIndex, taskStatus: taskStatus }),
2009
2037
  React.createElement(Title, { headingLevel: "h3", size: size, className: classNames },
2010
- React.createElement("span", { dangerouslySetInnerHTML: { __html: removeParagraphWrap(markdownConvert(title)) } }),
2038
+ React.createElement("span", { dangerouslySetInnerHTML: { __html: parsedTitle } }),
2011
2039
  isActiveTask && subtitle && (React.createElement("span", { className: "pfext-quick-start-task-header__subtitle", "data-test-id": "quick-start-task-subtitle" },
2012
2040
  ' ',
2013
2041
  subtitle))),
@@ -2204,6 +2232,7 @@ const QuickStartPanelContent = (_a) => {
2204
2232
  const titleRef = React.useRef(null);
2205
2233
  const { getResource, activeQuickStartState, focusOnQuickStart } = React.useContext(QuickStartContext);
2206
2234
  const [contentRef, setContentRef] = React.useState();
2235
+ const [displayName, setDisplayName] = React.useState('');
2207
2236
  const shadows = useScrollShadows(contentRef);
2208
2237
  const quickStart = quickStarts.find((qs) => qs.metadata.name === activeQuickStartID);
2209
2238
  const taskNumber = activeQuickStartState === null || activeQuickStartState === void 0 ? void 0 : activeQuickStartState.taskNumber;
@@ -2231,13 +2260,22 @@ const QuickStartPanelContent = (_a) => {
2231
2260
  titleRef.current.focus();
2232
2261
  }
2233
2262
  }, [focusOnQuickStart, quickStart]);
2263
+ React.useEffect(() => {
2264
+ function getDisplayName() {
2265
+ return __awaiter(this, void 0, void 0, function* () {
2266
+ const convertedMdDisplayName = yield markdownConvert(quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.displayName);
2267
+ setDisplayName(removeParagraphWrap(convertedMdDisplayName));
2268
+ });
2269
+ }
2270
+ getDisplayName();
2271
+ }, [quickStart]);
2234
2272
  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),
2235
2273
  React.createElement("div", { className: headerClasses },
2236
2274
  React.createElement(DrawerHead, null,
2237
2275
  React.createElement("div", { className: "pfext-quick-start-panel-content__title", tabIndex: -1, ref: titleRef },
2238
2276
  React.createElement(Title, { headingLevel: "h2", size: "xl", className: "pfext-quick-start-panel-content__name", style: { marginRight: 'var(--pf-v5-global--spacer--md)' } },
2239
2277
  React.createElement("span", { dangerouslySetInnerHTML: {
2240
- __html: removeParagraphWrap(markdownConvert(quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.displayName)),
2278
+ __html: displayName,
2241
2279
  } }),
2242
2280
  ' ',
2243
2281
  React.createElement("small", { className: "pfext-quick-start-panel-content__duration" }, (quickStart === null || quickStart === void 0 ? void 0 : quickStart.spec.durationMinutes)