Skip to content

Commit 47bc82b

Browse files
committed
port over RenderExtension
1 parent 62c5502 commit 47bc82b

File tree

5 files changed

+58
-15
lines changed

5 files changed

+58
-15
lines changed

packages/dev/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"serve": "serve public"
1010
},
1111
"dependencies": {
12-
"@patternfly/quickstarts": "1.0.0-rc.20",
12+
"@patternfly/quickstarts": "1.0.0-rc.21",
1313
"@patternfly/react-core": "^4.101.3",
1414
"asciidoctor": "^2.2.1",
1515
"react": "^16.14.0",

packages/module/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@patternfly/quickstarts",
3-
"version": "1.0.0-rc.20",
3+
"version": "1.0.0-rc.21",
44
"description": "PatternFly quick starts",
55
"files": [
66
"dist"

packages/module/src/ConsoleInternal/components/markdown-view.tsx

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import * as React from 'react';
22
import { Converter } from 'showdown';
33
import { QuickStartContext, QuickStartContextValues } from '../../utils/quick-start-context';
4-
// import _truncate from 'lodash-es/truncate.js';
5-
// import _uniqueId from 'lodash-es/uniqueId.js';
64
import cx from 'classnames';
5+
import { useForceRender } from '@console/shared';
76

87
import './_markdown-view.scss';
98

@@ -97,18 +96,11 @@ export const SyncMarkdownView: React.FC<SyncMarkdownProps> = ({
9796
}) => {
9897
const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
9998
const markup = React.useMemo(() => {
100-
const truncatedContent = /*truncateContent
101-
? _truncate(content, {
102-
length: 256,
103-
separator: ' ',
104-
omission: '\u2026',
105-
})
106-
: */ content;
10799
return markdownConvert(
108-
truncatedContent || emptyMsg || getResource('Not available'),
100+
content || emptyMsg || getResource('Not available'),
109101
extensions,
110102
);
111-
}, [content, emptyMsg, extensions, getResource /*, truncateContent*/]);
103+
}, [content, emptyMsg, extensions, getResource]);
112104
const innerProps: InnerSyncMarkdownProps = {
113105
renderExtension: extensions?.length > 0 ? renderExtension : undefined,
114106
exactHeight,
@@ -128,6 +120,43 @@ const uniqueId = (function () {
128120
};
129121
})();
130122

123+
type RenderExtensionProps = {
124+
renderExtension: (contentDocument: HTMLDocument, rootSelector: string) => React.ReactNode;
125+
selector: string;
126+
markup: string;
127+
docContext?: HTMLDocument;
128+
};
129+
130+
const RenderExtension: React.FC<RenderExtensionProps> = ({
131+
renderExtension,
132+
selector,
133+
markup,
134+
docContext,
135+
}) => {
136+
const forceRender = useForceRender();
137+
const markupRef = React.useRef<string>(null);
138+
const shouldRenderExtension = React.useCallback(() => {
139+
if (markupRef.current === markup) {
140+
return true;
141+
}
142+
markupRef.current = markup;
143+
return false;
144+
}, [markup]);
145+
/**
146+
* During a render cycle in which markup changes, renderExtension receives an old copy of document
147+
* because react is still updating the dom using `dangerouslySetInnerHTML` with latest markdown markup
148+
* which causes the component rendered by renderExtension to receive old copy of document
149+
* use forceRender to delay the rendering of extension by one render cycle
150+
*/
151+
React.useEffect(() => {
152+
renderExtension && forceRender();
153+
// eslint-disable-next-line react-hooks/exhaustive-deps
154+
}, [markup]);
155+
return (
156+
<>{shouldRenderExtension() ? renderExtension?.(docContext ?? document, selector) : null}</>
157+
);
158+
};
159+
131160
const InlineMarkdownView: React.FC<InnerSyncMarkdownProps> = ({
132161
markup,
133162
isEmpty,
@@ -138,7 +167,7 @@ const InlineMarkdownView: React.FC<InnerSyncMarkdownProps> = ({
138167
return (
139168
<div className={cx('co-markdown-view', { ['is-empty']: isEmpty }, className)} id={id}>
140169
<div dangerouslySetInnerHTML={{ __html: markup }} />
141-
{renderExtension && renderExtension(document, `#${id}`)}
170+
{renderExtension && <RenderExtension renderExtension={renderExtension} selector={`#${id}`} markup={markup} />}
142171
</div>
143172
);
144173
};
@@ -232,7 +261,14 @@ const IFrameMarkdownView: React.FC<InnerSyncMarkdownProps> = ({
232261
onLoad={() => onLoad()}
233262
className={className}
234263
/>
235-
{loaded && frame && renderExtension && renderExtension(frame.contentDocument, '')}
264+
{loaded && frame && renderExtension && (
265+
<RenderExtension
266+
markup={markup}
267+
selector={''}
268+
renderExtension={renderExtension}
269+
docContext={frame.contentDocument}
270+
/>
271+
)}
236272
</>
237273
);
238274
};

packages/module/src/ConsoleShared/src/hooks/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export * from './scroll';
22
export * from './useResizeObserver';
33
export * from './useScrollShadows';
44
export * from './useBoundingClientRect';
5+
export * from './useForceRender';
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import * as React from 'react';
2+
3+
/**
4+
* React hook that forces component render.
5+
*/
6+
export const useForceRender = () => React.useReducer((s: boolean) => !s, false)[1] as VoidFunction;

0 commit comments

Comments
 (0)