Skip to content

Commit 0bd87b8

Browse files
Merge pull request #855 from neo4j-labs/issue/848-html-rendering
#848 Render HTML strings
2 parents 37970ed + 6416b06 commit 0bd87b8

File tree

5 files changed

+27
-7
lines changed

5 files changed

+27
-7
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"d3-scale-chromatic": "^3.0.0",
6666
"dayjs": "^1.11.7",
6767
"dom-to-image": "^2.6.0",
68+
"dompurify": "^3.1.0",
6869
"leaflet": "^1.7.1",
6970
"lodash.debounce": "^4.0.8",
7071
"lodash.isequal": "^4.5.0",

src/chart/graph/component/GraphEntityInspectionTable.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@ import React from 'react';
22
import ShowMoreText from 'react-show-more-text';
33
import { Checkbox, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material';
44
import { TextLink } from '@neo4j-ndl/react';
5+
import DOMPurify from 'dompurify';
56

67
export const formatProperty = (property) => {
7-
if (property.startsWith('http://') || property.startsWith('https://')) {
8+
const str = property?.toString() || '';
9+
if (str.startsWith('http://') || str.startsWith('https://')) {
810
return (
9-
<TextLink externalLink href={property}>
10-
{property}
11+
<TextLink externalLink href={str}>
12+
{str}
1113
</TextLink>
1214
);
1315
}
14-
return property;
16+
const cleanValue = DOMPurify.sanitize(str);
17+
return <div dangerouslySetInnerHTML={{ __html: cleanValue }} />;
1518
};
1619

1720
/**
@@ -88,7 +91,7 @@ export const GraphEntityInspectionTable = ({
8891
{key}
8992
</TableCell>
9093
<TableCell align={'left'} style={{ color: tableTextColor }}>
91-
<ShowMoreText lines={2}>{formatProperty(entity && entity.properties[key].toString())}</ShowMoreText>
94+
<ShowMoreText lines={2}>{formatProperty(entity?.properties[key])}</ShowMoreText>
9295
</TableCell>
9396
{checklistEnabled ? (
9497
<TableCell align={'center'}>

src/chart/table/TableChart.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ const fallbackRenderer = (value) => {
3838
return JSON.stringify(value);
3939
};
4040

41+
function htmlToPlainText(html): string {
42+
// Create a temporary div element to hold the sanitized HTML content
43+
const tempElement = document.createElement('div');
44+
// Set the HTML content directly as innerHTML of the temporary element
45+
tempElement.innerHTML = html.props.dangerouslySetInnerHTML.__html;
46+
// Extract plain text using textContent
47+
return tempElement.textContent ?? '';
48+
}
49+
4150
function renderAsButtonWrapper(renderer) {
4251
return function renderAsButton(value) {
4352
const outputValue = renderer(value, true);
@@ -50,7 +59,7 @@ function renderAsButtonWrapper(renderer) {
5059
style={{ width: '100%', marginLeft: '5px', marginRight: '5px' }}
5160
variant='contained'
5261
color='primary'
53-
>{`${outputValue}`}</Button>
62+
>{`${htmlToPlainText(outputValue)}`}</Button>
5463
);
5564
};
5665
}

src/report/ReportRecordProcessing.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
valueIsPath,
1111
valueIsRelationship,
1212
} from '../chart/ChartUtils';
13+
import DOMPurify from 'dompurify';
1314

1415
/**
1516
* Collects all node labels and node properties in a set of Neo4j records.
@@ -266,7 +267,8 @@ function RenderString(value) {
266267
</TextLink>
267268
);
268269
}
269-
return str;
270+
const cleanValue = DOMPurify.sanitize(str);
271+
return <div dangerouslySetInnerHTML={{ __html: cleanValue }} />;
270272
}
271273

272274
function RenderLink(value, disabled = false) {

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7068,6 +7068,11 @@ dom-to-image@^2.6.0:
70687068
resolved "https://registry.yarnpkg.com/dom-to-image/-/dom-to-image-2.6.0.tgz#8a503608088c87b1c22f9034ae032e1898955867"
70697069
integrity sha512-Dt0QdaHmLpjURjU7Tnu3AgYSF2LuOmksSGsUcE6ItvJoCWTBEmiMXcqBdNSAm9+QbbwD7JMoVsuuKX6ZVQv1qA==
70707070

7071+
dompurify@^3.1.0:
7072+
version "3.1.0"
7073+
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.0.tgz#8c6b9fe986969a33aa4686bd829cbe8e14dd9445"
7074+
integrity sha512-yoU4rhgPKCo+p5UrWWWNKiIq+ToGqmVVhk0PmMYBK4kRsR3/qhemNFL8f6CFmBd4gMwm3F4T7HBoydP5uY07fA==
7075+
70717076
dotenv@^16.3.1:
70727077
version "16.3.1"
70737078
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e"

0 commit comments

Comments
 (0)