From f2072acfc01791c5352c4148e39c4b25b020f9b8 Mon Sep 17 00:00:00 2001 From: HannesOberreiter Date: Tue, 9 Apr 2024 11:00:02 +0200 Subject: [PATCH] feat: :sparkles: add a link parser to tasks --- client/package-lock.json | 6 ++++ client/package.json | 1 + .../src/components/CardModal/Tasks/Item.jsx | 32 ++++++++++++++----- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 62cebb9..2e4ebf8 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -10,6 +10,7 @@ "classnames": "^2.3.2", "date-fns": "^2.30.0", "dequal": "^2.0.3", + "dompurify": "^3.1.0", "easymde": "^2.18.0", "history": "^5.3.0", "i18next": "^23.7.6", @@ -7016,6 +7017,11 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/dompurify": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.0.tgz", + "integrity": "sha512-yoU4rhgPKCo+p5UrWWWNKiIq+ToGqmVVhk0PmMYBK4kRsR3/qhemNFL8f6CFmBd4gMwm3F4T7HBoydP5uY07fA==" + }, "node_modules/domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", diff --git a/client/package.json b/client/package.json index 25cdce0..7fb0164 100755 --- a/client/package.json +++ b/client/package.json @@ -63,6 +63,7 @@ "classnames": "^2.3.2", "date-fns": "^2.30.0", "dequal": "^2.0.3", + "dompurify": "^3.1.0", "easymde": "^2.18.0", "history": "^5.3.0", "i18next": "^23.7.6", diff --git a/client/src/components/CardModal/Tasks/Item.jsx b/client/src/components/CardModal/Tasks/Item.jsx index a34beb0..ecaa059 100755 --- a/client/src/components/CardModal/Tasks/Item.jsx +++ b/client/src/components/CardModal/Tasks/Item.jsx @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import classNames from 'classnames'; import { Draggable } from 'react-beautiful-dnd'; import { Button, Checkbox, Icon } from 'semantic-ui-react'; +import { sanitize } from 'dompurify'; import { usePopup } from '../../../lib/popup'; import NameEdit from './NameEdit'; @@ -15,11 +16,14 @@ const Item = React.memo( ({ id, index, name, isCompleted, isPersisted, canEdit, onUpdate, onDelete }) => { const nameEdit = useRef(null); - const handleClick = useCallback(() => { - if (isPersisted && canEdit) { - nameEdit.current.open(); - } - }, [isPersisted, canEdit]); + const handleClick = useCallback( + (event) => { + if (!event.target.closest('a') && isPersisted && canEdit) { + nameEdit.current.open(); + } + }, + [isPersisted, canEdit], + ); const handleNameUpdate = useCallback( (newName) => { @@ -40,6 +44,16 @@ const Item = React.memo( nameEdit.current.open(); }, []); + const parseLinks = (text) => { + const regex = /(http[s]?:\/\/[^\s]+)/g; + return sanitize(text).replace(regex, (match) => { + const url = new URL(match); + return `${ + url.hostname === window.location.hostname ? url.pathname : match + }`; + }); + }; + const ActionsPopup = usePopup(ActionsStep); return ( @@ -64,9 +78,11 @@ const Item = React.memo( className={classNames(styles.text, canEdit && styles.textEditable)} onClick={handleClick} > - - {name} - + {isPersisted && canEdit && (