--- /dev/null
+import PropTypes from 'prop-types';
+import React from 'react';
+import { useNavigate } from 'react-router-dom';
+
+const RawHTML = ({ html }) => {
+ const navigate = useNavigate();
+
+ const onClick = e => {
+ if (e.defaultPrevented) return;
+ if (e.metaKey || e.ctrlKey || e.shiftKey) return;
+ if (e.button !== 0) return;
+
+ let el = e.target;
+ while (el && el.nodeName !== 'A') {
+ el = el.parentNode;
+ }
+ if (!el) return;
+
+ if (el.target && el.target !== '_self') return;
+ if (el.attributes.download) return;
+ if (el.rel && /(?:^|\s+)external(?:\s+|$)/.test(el.rel)) return;
+
+ const href = el.getAttribute('href');
+
+ if (href.startsWith('#')) return;
+ if (href.startsWith('http')) return;
+ if (href.startsWith('mailto')) return;
+ if (href.startsWith('tel')) return;
+
+ el.blur();
+ e.preventDefault();
+
+ setTimeout(() => {
+ // scroll to top on location change
+ scrollTo({ top: 0, behavior: 'smooth' });
+ }, 50);
+
+ navigate(href);
+ };
+
+ return <div onClick={onClick} dangerouslySetInnerHTML={{ __html: html }} />;
+};
+
+RawHTML.propTypes = {
+ html: PropTypes.string,
+};
+
+export default RawHTML;
import { withTranslation } from 'react-i18next';
import Outline from './Outline';
+import RawHTML from '../common/RawHTML';
import { getTranslation } from '../../helpers/Technique';
import i18n from '../../i18n';
const Detail = ({ technique }) => <Container as="article">
<h1>{getTranslation(technique, 'title', i18n.language)}</h1>
<Outline technique={technique} />
- <div dangerouslySetInnerHTML={{
- __html: getTranslation(technique, 'description', i18n.language),
- }} />
+ <RawHTML html={getTranslation(technique, 'description', i18n.language)} />
{technique.chapters ? technique.chapters.map(chapter =>
<section id={`c${chapter.id}`} key={`c${chapter.id}`}>
{chapter.pivot.level ?
getTranslation(chapter, 'title', i18n.language),
)
: null}
- <div dangerouslySetInnerHTML={{
- __html: getTranslation(chapter, 'description', i18n.language),
- }} />
+ <RawHTML html={getTranslation(chapter, 'description', i18n.language)} />
</section>
) : null}
</Container>;