@happeouikit/content-renderer 3.2.2 → 3.2.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.
@@ -0,0 +1,2 @@
1
+ export const mentioningRegex: RegExp;
2
+ export const extraMentioning: string[];
@@ -0,0 +1,27 @@
1
+ import { decode as decodeHtmlEntities } from "html-entities";
2
+ /**
3
+ * @name toSafeText
4
+ * @description Returns filtered text with filterXSS library
5
+ * @author Antero Hanhirova
6
+ * @param {String} - Text to whitelist
7
+ * @returns {String}
8
+ */
9
+ declare const toSafeText: (text?: string) => string;
10
+ /**
11
+ * Adds spans with `color-block` class after color codes hex, rgb and rgba
12
+ */
13
+ declare const addColorSpanAfterColorCodes: (text?: string) => string;
14
+ /**
15
+ * @name toHtml
16
+ * @description Converts markdown to html, adds space to end of String
17
+ * The non-breaking space helps users to add text if last word is mention item
18
+ * @author Antero Hanhirova
19
+ * @param {String} - Markdown
20
+ * @returns {String} - Html
21
+ */
22
+ declare const toHtml: (str?: string, type?: string) => string;
23
+ declare const loadCodeFont: () => void;
24
+ declare const getNearestRelativeParent: (el: HTMLElement) => HTMLElement | null;
25
+ declare const removeSpecialCharacters: (str?: string) => string;
26
+ declare const replacePTagsInCodeBlocks: (html?: string) => string;
27
+ export { toHtml, toSafeText, loadCodeFont, decodeHtmlEntities, getNearestRelativeParent, removeSpecialCharacters, addColorSpanAfterColorCodes, replacePTagsInCodeBlocks, };
package/package.json CHANGED
@@ -1,38 +1,44 @@
1
1
  {
2
2
  "name": "@happeouikit/content-renderer",
3
- "version": "3.2.2",
3
+ "version": "3.2.3",
4
4
  "description": "Rendering html and markdown content",
5
- "main": "dist/index.js",
6
- "module": "src/index.js",
5
+ "type": "module",
6
+ "jsnext:main": "dist/index.es.js",
7
+ "module": "dist/index.es.js",
8
+ "types": "dist/index.d.ts",
7
9
  "files": [
8
- "dist"
10
+ "/dist"
9
11
  ],
10
12
  "scripts": {
11
- "test": "echo \"Error: no test specified\" && exit 1"
13
+ "build": "tsc && vite build"
12
14
  },
13
15
  "public": true,
14
16
  "author": "Happeo Oy",
15
17
  "license": "MIT",
16
18
  "dependencies": {
17
- "@happeouikit/colors": "^1.0.4",
18
- "@happeouikit/copy-to-clipboard-button": "^3.0.0",
19
- "@happeouikit/emojis": "^1.3.0",
20
- "@happeouikit/layout": "^1.1.11",
21
- "@happeouikit/typography": "^1.1.0",
22
19
  "html-entities": "^2.3.2",
23
- "linkifyjs": "^2.1.8",
24
- "loadjs": "^4.2.0",
20
+ "linkify-html": "^4.1.3",
21
+ "linkifyjs": "^4.1.3",
22
+ "loadjs": "^4.3.0",
25
23
  "react-dom": "^17.0.2",
26
24
  "showdown": "^2.1.0",
27
- "xss": "^1.0.14"
25
+ "xss": "^1.0.15"
28
26
  },
29
27
  "peerDependencies": {
28
+ "@happeouikit/colors": "^1.0.4",
29
+ "@happeouikit/copy-to-clipboard-button": "^3.0.0",
30
+ "@happeouikit/emojis": "^1.3.0",
31
+ "@happeouikit/layout": "^1.1.11",
32
+ "@happeouikit/typography": "^1.1.0",
30
33
  "prop-types": "^15.6.2",
31
34
  "react": "^17.0.2",
32
- "styled-components": "^5.3.1"
35
+ "styled-components": "^5.3.3"
33
36
  },
34
37
  "publishConfig": {
35
38
  "access": "public"
36
39
  },
37
- "gitHead": "152fa0259db0e622a09ecde31144336842834787"
40
+ "devDependencies": {
41
+ "@types/loadjs": "^4.0.4"
42
+ },
43
+ "gitHead": "4a97052ead5b4c60aaf1bb9227d7b118ec74d5fe"
38
44
  }
@@ -1,223 +0,0 @@
1
- import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
- import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
3
- import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
- var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5;
5
- /* eslint-disable no-nested-ternary */
6
- /* eslint-disable no-param-reassign */
7
- /**
8
- *
9
- * ContentRenderer
10
- *
11
- */
12
-
13
- import React, { useRef, useEffect, useState, useCallback, useMemo } from "react";
14
- import ReactDOM from "react-dom";
15
- import PropTypes from "prop-types";
16
- import styled, { css } from "styled-components";
17
- import loadjs from "loadjs";
18
- import { CopyToClipboardButton } from "@happeouikit/copy-to-clipboard-button";
19
- import { BodyUI, sansFamily } from "@happeouikit/typography";
20
- import { margin200, media, padding200 } from "@happeouikit/layout";
21
- import { active, gray04, gray07, gray09, lighten, warn } from "@happeouikit/colors";
22
- import { toHtml, loadCodeFont, decodeHtmlEntities, removeSpecialCharacters, toSafeText, addColorSpanAfterColorCodes } from "./utils";
23
- import { ELEMENT_TYPE_PRE, ELEMENT_TYPE_CODE, HIGHLIGHJS_CSS, HIGHLIGHJS_JS, CODE_BLOCK_AVAILABLE_LANGUAGES } from "./constants";
24
- import { jsx as _jsx } from "react/jsx-runtime";
25
- import { Fragment as _Fragment } from "react/jsx-runtime";
26
- import { jsxs as _jsxs } from "react/jsx-runtime";
27
- var ContentRenderer = function ContentRenderer(_ref) {
28
- var content = _ref.content,
29
- type = _ref.type,
30
- _ref$widgetType = _ref.widgetType,
31
- widgetType = _ref$widgetType === void 0 ? "post" : _ref$widgetType,
32
- createAnchors = _ref.createAnchors,
33
- useHashAutoscroll = _ref.useHashAutoscroll,
34
- _ref$hashAutoscrollTo = _ref.hashAutoscrollTopMargin,
35
- hashAutoscrollTopMargin = _ref$hashAutoscrollTo === void 0 ? 0 : _ref$hashAutoscrollTo,
36
- decodeHtmlEntitiesOnRender = _ref.decodeHtmlEntitiesOnRender,
37
- forceDefaultLinkTarget = _ref.forceDefaultLinkTarget,
38
- _ref$inheritBrandingS = _ref.inheritBrandingStyles,
39
- inheritBrandingStyles = _ref$inheritBrandingS === void 0 ? false : _ref$inheritBrandingS,
40
- _ref$addColorBlocks = _ref.addColorBlocks,
41
- addColorBlocks = _ref$addColorBlocks === void 0 ? false : _ref$addColorBlocks;
42
- var element = useRef({});
43
- var _useState = useState([]),
44
- _useState2 = _slicedToArray(_useState, 2),
45
- copyBtns = _useState2[0],
46
- setCopyBtns = _useState2[1];
47
-
48
- // Autoscroll to hashes
49
- var scrollAndHighlightHash = useCallback(function () {
50
- try {
51
- var hash = window.location.hash;
52
- if (hash) {
53
- var hashEl = element.current.querySelector(hash);
54
- if (hashEl) {
55
- setTimeout(function () {
56
- window.scrollTo({
57
- top: hashEl.getBoundingClientRect().top - hashAutoscrollTopMargin,
58
- behavior: "smooth"
59
- });
60
- hashEl.classList.add("highlight");
61
- setTimeout(function () {
62
- hashEl.classList.remove("highlight");
63
- }, 5000);
64
- }, 500);
65
- }
66
- }
67
- } catch (error) {
68
- /* In some cases the hash may be cause this function to fail. In this case, handle and do nothing */
69
- }
70
- }, [hashAutoscrollTopMargin]);
71
- useEffect(function () {
72
- if (!element.current) return;
73
- var headerElems = createAnchors ? element.current.querySelectorAll("h1, h2, h3, h4, h5, h6") : [];
74
- if (headerElems.length > 0) {
75
- headerElems.forEach(function (header) {
76
- var _header$textContent = header.textContent,
77
- textContent = _header$textContent === void 0 ? "" : _header$textContent;
78
- if (textContent.length > 0) {
79
- header.id = header.id || removeSpecialCharacters(textContent.toLowerCase().replace(/\s/g, "-"));
80
- }
81
- });
82
- }
83
- var linkElems = forceDefaultLinkTarget ? element.current.querySelectorAll("a") : [];
84
- if (linkElems.length > 0) {
85
- var currentOrigin = window.origin;
86
- linkElems.forEach(function (link) {
87
- var href = link.href;
88
- if (href.startsWith(currentOrigin)) {
89
- delete link.target;
90
- } else {
91
- link.target = "_blank";
92
- }
93
- });
94
- }
95
- var blockElems = element.current.querySelectorAll(ELEMENT_TYPE_PRE);
96
- if (blockElems.length > 0) {
97
- if (!loadjs.isDefined("highlightjs")) {
98
- loadCodeFont();
99
- loadjs([].concat(_toConsumableArray(HIGHLIGHJS_JS), _toConsumableArray(HIGHLIGHJS_CSS)), "highlightjs");
100
- }
101
- loadjs.ready("highlightjs", function () {
102
- // highlight.js register only languages we want to support?
103
- window.hljs.configure({
104
- languages: CODE_BLOCK_AVAILABLE_LANGUAGES,
105
- useBr: true
106
- });
107
- blockElems.forEach(function (elem) {
108
- var plainCode = elem.innerText;
109
-
110
- // Take the inner content and put inside single code block
111
- // This will ensure nice readability.
112
- // Needs to be done since editor will generate multiple lines for code for ease of editing
113
- var codeBlock = document.createElement(ELEMENT_TYPE_CODE);
114
- var decodedText = decodeHtmlEntities(plainCode);
115
- codeBlock.textContent = decodedText; // Done like this to prevent xss
116
- elem.innerHTML = ""; // Clear content so we can set just the single code block there
117
- elem.appendChild(codeBlock);
118
- window.hljs.highlightBlock(elem);
119
- });
120
- setCopyBtns(function (prevState) {
121
- return [].concat(_toConsumableArray(prevState), _toConsumableArray(blockElems));
122
- });
123
- });
124
- }
125
- setCopyBtns(_toConsumableArray(headerElems));
126
- if (useHashAutoscroll) {
127
- scrollAndHighlightHash();
128
- }
129
- }, [element, createAnchors, forceDefaultLinkTarget, useHashAutoscroll, scrollAndHighlightHash]);
130
- var safeText = useMemo(function () {
131
- var lowercaseType = type && typeof type === "string" ? type.toLowerCase() : "html";
132
- var transformedContent = lowercaseType === "text" ? toSafeText("<p>".concat(content, "</p>")) : toHtml(content, lowercaseType);
133
- if (addColorBlocks) {
134
- transformedContent = addColorSpanAfterColorCodes(transformedContent);
135
- }
136
- if (decodeHtmlEntitiesOnRender) {
137
- transformedContent = decodeHtmlEntities(transformedContent);
138
- }
139
- return transformedContent;
140
- }, [content, type, addColorBlocks, decodeHtmlEntitiesOnRender]);
141
-
142
- // Use dangerouslySetInnerHTML as there might be nested <p>'s header etc
143
- // This requires that all content is run through the toSafeText filter
144
- // before displaying. This will run it through xss filter.
145
- return /*#__PURE__*/_jsxs(_Fragment, {
146
- children: [/*#__PURE__*/_jsx(Wrapper, {
147
- className: "content-renderer ".concat(widgetType === "page" ? "fr-view pages-text" : ""),
148
- ref: element,
149
- widgetType: widgetType,
150
- createAnchors: createAnchors,
151
- dangerouslySetInnerHTML: {
152
- __html: safeText
153
- },
154
- inheritBrandingStyles: inheritBrandingStyles
155
- }), copyBtns.map(function (el) {
156
- var clipboardContent = el.textContent || "";
157
- if (el.tagName !== ELEMENT_TYPE_PRE) {
158
- clipboardContent = "".concat(window.location.href.split("#")[0], "#").concat(el.id);
159
- }
160
-
161
- // eslint-disable-next-line no-control-regex
162
- clipboardContent = removeSpecialCharacters(clipboardContent);
163
- return /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/_jsx(BtnContainer, {
164
- className: "content-copy-btn",
165
- children: /*#__PURE__*/_jsx(CopyToClipboardButton, {
166
- clipboardContent: clipboardContent
167
- })
168
- }), el);
169
- })]
170
- });
171
- };
172
- var BtnContainer = styled.div.withConfig({
173
- displayName: "ContentRenderer__BtnContainer",
174
- componentId: "sc-110nzgm-0"
175
- })(["display:inline-flex;margin-left:", ";button{opacity:0;transition-property:opacity;transition-duration:150ms;transition-timing-function:ease-in;}button:hover,button:active,button:focus{opacity:1 !important;}div p{font-size:12px;line-height:16px;}"], margin200);
176
- var Wrapper = styled(BodyUI).attrs({
177
- as: "div"
178
- }).withConfig({
179
- displayName: "ContentRenderer__Wrapper",
180
- componentId: "sc-110nzgm-1"
181
- })(["", " h1.highlight,h2.highlight,h3.highlight,h4.highlight,h5.highlight,h6.highlight{border-radius:6px;position:relative;:after{content:\" \";position:absolute;top:-8px;bottom:-8px;left:-8px;right:-8px;border-radius:6px;border:5px solid ", ";}}pre{border-radius:4px;background:", ";padding:8px;margin-bottom:10px;overflow:auto;white-space:pre;position:relative;overflow:visible;*:not(p){font-weight:inherit;font-family:\"IBM Plex Mono\",monospace !important;}.content-copy-btn{position:absolute;top:0;right:0;padding:", " 0;}:hover button{opacity:1;}}.mention{border-radius:0.2em;background-color:#fff5cc;border:1px solid #fff5cc;color:#0f1621;font-weight:400;&:hover{text-decoration:none;border:1px solid #fabd24;}}.extraMention{cursor:inherit;}.color-block{display:inline-block;width:18px;height:18px;margin-left:2px;transform:translateY(4px);margin-right:2px;border-radius:4px;border:1px solid var(--color-gray100);}", " ", "}"], function (_ref2) {
182
- var createAnchors = _ref2.createAnchors;
183
- return createAnchors ? "\n h1, h2, h3, h4, h5, h6 {\n display: flex;\n align-items: center;\n :hover button {\n opacity: 0.4;\n }\n }\n " : "";
184
- }, lighten(warn, 0.8), gray09, padding200, function (_ref3) {
185
- var widgetType = _ref3.widgetType,
186
- inheritBrandingStyles = _ref3.inheritBrandingStyles;
187
- return widgetType === "page" ? "" : "\n * {\n font-family: ".concat(sansFamily, ";\n }\n\n h1 {\n font-family: ").concat(inheritBrandingStyles ? "var(--channels-h1-font-family, revert)" : "revert", "; \n font-weight: ").concat(inheritBrandingStyles ? "var(--channels-h1-font-weight, 500)" : "500", ";\n font-size: 24px;\n letter-spacing: -0.5px;\n line-height: 32px;\n + h1,\n + h2,\n + h3,\n + h4,\n + p {\n margin-top: 16px;\n }\n & * {\n font-family: ").concat(inheritBrandingStyles ? "var(--channels-h1-font-family, revert)" : "revert", "; \n }\n }\n h2 {\n font-family: ").concat(inheritBrandingStyles ? "var(--channels-h2-font-family, revert)" : "revert", "; \n font-weight: ").concat(inheritBrandingStyles ? "var(--channels-h2-font-weight, 500)" : "500", ";\n font-size: 20px;\n line-height: 28px;\n + h1,\n + h2,\n + h3,\n + h4,\n + p {\n margin-top: 14px;\n }\n & * {\n font-family: ").concat(inheritBrandingStyles ? "var(--channels-h2-font-family, revert)" : "revert", "; \n }\n }\n h3 {\n font-family: ").concat(inheritBrandingStyles ? "var(--channels-h3-font-family, revert)" : "revert", "; \n font-weight: ").concat(inheritBrandingStyles ? "var(--channels-h3-font-weight, 500)" : "500", ";\n font-size: 16px;\n line-height: 24px;\n + h1,\n + h2,\n + h3,\n + h4,\n + p {\n margin-top: 12px;\n }\n & * {\n font-family: ").concat(inheritBrandingStyles ? "var(--channels-h3-font-family, revert);" : "revert", " \n }\n }\n h4 {\n font-size: 16px;\n line-height: 24px;\n + h1,\n + h2,\n + h3,\n + h4,\n + p {\n margin-top: 12px;\n }\n }\n p {\n font-family: ").concat(inheritBrandingStyles ? "var(--channels-body-font-family, revert)" : "revert", "; \n font-weight: ").concat(inheritBrandingStyles ? "var(--channels-body-font-weight, revert)" : "revert", ";\n font-size: 16px;\n line-height: 24px;\n letter-spacing: 0px;\n + h1,\n + h2,\n + h3,\n + h4,\n + p {\n margin-top: 12px;\n }\n\n & * {\n font-family: ").concat(inheritBrandingStyles ? "var(--channels-body-font-family, revert)" : "revert", "; \n }\n }\n }\n a {\n color: ").concat(active, ";\n text-decoration: none;\n :hover {\n text-decoration: underline;\n }\n }\n ul {\n list-style-type: disc;\n }\n ol {\n list-style-type: decimal;\n counter-reset: item;\n li {\n padding-left: 12px;\n text-indent: -33px;\n list-style-type: none;\n counter-increment: item;\n &:before {\n display: inline-block;\n width: 13px;\n padding-right: 15px;\n padding-left: 5px;\n font-weight: bold;\n text-align: right;\n content: counter(item) \".\";\n }\n font-family: ").concat(inheritBrandingStyles ? "var(--channels-body-font-family, revert)" : "revert", "; \n font-weight: ").concat(inheritBrandingStyles ? "var(--channels-body-font-weight, revert)" : "revert", ";\n }\n }\n ol,\n ul {\n font-size: 16px;\n line-height: 24px;\n margin: 18px 16px;\n display: block;\n -webkit-margin-before: 0.5em;\n -webkit-margin-after: 0.5em;\n -webkit-padding-start: 0.5em;\n li,\n li {\n margin-bottom: 5px;\n padding-left: 10px;\n > ul,\n > ol {\n -webkit-margin-before: 8px !important;\n -webkit-margin-after: 8px !important;\n }\n\n font-family: ").concat(inheritBrandingStyles ? "var(--channels-body-font-family, revert);" : "revert", ";\n font-weight: ").concat(inheritBrandingStyles ? "var(--channels-body-font-weight, revert)" : "revert", ";\n }\n\n &:first-child,\n &:first-child {\n -webkit-margin-before: 0;\n }\n &:last-child,\n &:last-child {\n -webkit-margin-after: 0;\n }\n }\n hr {\n -webkit-margin-before: 16px;\n -webkit-margin-after: 13px;\n border-color: @border-color;\n border-style: solid;\n height: 0px;\n border-width: 1px 0 0 0;\n }\n table {\n width: 100%;\n margin: 15px 0;\n text-align: left;\n thead th {\n background: @white;\n }\n th,\n td {\n border-width: 1px;\n border-style: solid;\n border-color: @border-color;\n padding: 0.5em;\n }\n tr:nth-child(even) {\n background: @almost-white;\n }\n tr:nth-child(odd) {\n background: @white;\n }\n }\n table.no-borders {\n th,\n td {\n border: none;\n }\n }\n table.padded-2 {\n th,\n td {\n padding: 2em;\n }\n }\n table.padded-1 {\n th,\n td {\n padding: 1em;\n }\n }\n img {\n max-width: 100%;\n margin: 15px 0;\n & + img {\n margin-top: 0;\n }\n }\n .xl-emoji * {\n font-size: 40px;\n line-height: 1.2;\n }\n \n blockquote {\n border-top: 2px solid ").concat(gray07, ";\n border-bottom: 2px solid ").concat(gray07, ";\n font-size: 18px;\n padding: 24px 48px;\n position: relative;\n text-align: center;\n margin: 48px 0;\n }\n ");
188
- }, function (_ref4) {
189
- var widgetType = _ref4.widgetType,
190
- inheritBrandingStyles = _ref4.inheritBrandingStyles;
191
- return widgetType === "article" && css(["h1{font-family:", ";& *{font-family:", ";}}h2{font-family:", ";& *{font-family:", ";}}h3{font-family:", ";& *{font-family:", ";}}h4,h5,h6,p,ul,ol,li,table{font-family:", ";& *{font-family:", ";}}h1{font-size:32px;line-height:1.13;margin:0 0 20px;letter-spacing:-0.75px;}h2{font-size:24px;line-height:1.17;margin:0 0 16px;letter-spacing:-0.5px;}h3{font-size:20px;line-height:1.2;margin:0 0 14px;}h4,h5,h6,p,ul,ol,li{font-size:18px;line-height:1.56;margin-bottom:13px;margin-top:0;}hr{border-color:", ";}table{width:100% !important;margin:15px 0;font-size:18px !important;text-align:left;border-collapse:collapse;border-spacing:0;thead th{background:@white;}th,td{border-width:1px;border-style:solid;border-color:", ";padding:0.5em;word-wrap:break-word;}tr:nth-child(odd){background:", ";}tr:nth-child(even){background:@white;}}table.no-borders{th,td{border:none;}tr:nth-child(odd){background:", ";}tr:nth-child(even){background:@white;}}pre{position:relative;background-color:", ";padding:1em;margin:1em 0;border-radius:4px;white-space:pre;}img,span.fr-img-caption,span.fr-video{display:block;margin:30px auto;", ";&.article-align-left{display:block;max-width:100%;", "}&.article-align-center{display:block;}&.article-align-right{display:block;max-width:100%;", "}&.article-align-overflow{display:block;max-width:100%;", " img{width:100%;}}}img{&.image-border-radius{border-radius:6px;}&.image-box-shadow{box-shadow:0 4px 16px 0 #bacad5;}}span.fr-img-caption{&.image-border-radius img{border-radius:6px;}&.image-box-shadow img{box-shadow:0 4px 16px 0 #bacad5;}}p{img:first-child,span.fr-img-caption:first-child{&.article-align-left,&.article-align-right{", "}}}span.fr-img-caption{text-align:center;img{margin:0;}.fr-inner{font-weight:400;font-size:16px;margin:8px auto 0 auto;padding:0 8px;color:", ";display:block;max-width:671px;}}span.fr-video{position:relative;padding-bottom:56.25%;padding-top:30px;height:0;overflow:hidden;border-radius:6px;&.article-align-overflow{padding-top:170px;}iframe{position:absolute;top:0;left:0;width:100% !important;height:100% !important;}}blockquote{border-left:0 !important;padding-left:0 !important;margin:0 !important;color:inherit !important;p{line-height:30px;font-size:26px;text-align:center;margin:0 auto;}}.content-attachments{width:100%;}"], inheritBrandingStyles ? "var(--channels-h1-font-family, revert)" : "revert", inheritBrandingStyles ? "var(--channels-h1-font-family, revert)" : "revert", inheritBrandingStyles ? "var(--channels-h2-font-family, revert)" : "revert", inheritBrandingStyles ? "var(--channels-h2-font-family, revert)" : "revert", inheritBrandingStyles ? "var(--channels-h3-font-family, revert)" : "revert", inheritBrandingStyles ? "var(--channels-h3-font-family, revert)" : "revert", inheritBrandingStyles ? "var(--channels-body-font-family, revert)" : "revert", inheritBrandingStyles ? "var(--channels-body-font-family, revert)" : "revert", gray07, gray07, gray09, gray09, gray09, media.only.xs(_templateObject || (_templateObject = _taggedTemplateLiteral([" \n max-width: 100%;\n "]))), media.min.md(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n margin: 30px 30px 10px 0px;\n float: left;\n max-width: 75%;\n "]))), media.min.md(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n margin: 30px 0px 10px 30px;\n float: right;\n max-width: 75%;\n "]))), media.min.md(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n margin: 30px -150px;\n width: calc(100% + 300px) !important;\n max-width: none;\n "]))), media.min.md(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n margin-top: 8px;\n "]))), gray04);
192
- });
193
- ContentRenderer.propTypes = {
194
- content: PropTypes.string,
195
- type: function type(props, propName) {
196
- if (propName === "type" && props[propName] !== props[propName].toUpperCase()) {
197
- // eslint-disable-next-line no-console
198
- console.warn("Please use uppercase type 'HTML', 'MARKDOWN' or 'TEXT'");
199
- }
200
- if (propName === "type" && !["HTML", "MARKDOWN", "TEXT"].includes(props[propName].toUpperCase())) {
201
- throw new Error("Invalid type, use 'HTML', 'MARKDOWN' or 'TEXT'");
202
- }
203
- },
204
- widgetType: PropTypes.oneOf(["post", "article", "page"]),
205
- decodeHtmlEntitiesOnRender: PropTypes.bool,
206
- createAnchors: PropTypes.bool,
207
- forceDefaultLinkTarget: PropTypes.bool,
208
- useHashAutoscroll: PropTypes.bool,
209
- hashAutoscrollTopMargin: PropTypes.number,
210
- addColorBlocks: PropTypes.bool
211
- };
212
- ContentRenderer.defaultProps = {
213
- content: "",
214
- type: "html",
215
- widgetType: "post",
216
- decodeHtmlEntitiesOnRender: false,
217
- createAnchors: false,
218
- useHashAutoscroll: true,
219
- forceDefaultLinkTarget: false,
220
- hashAutoscrollTopMargin: 0,
221
- addColorBlocks: false
222
- };
223
- export default ContentRenderer;
package/dist/constants.js DELETED
@@ -1,73 +0,0 @@
1
- export var safeTagsAndAttributes = {
2
- a: ["class", "target", "href", "title", "data-collection-id", "data-page-id", "rel", "data-user-id", "data-user-id-old"],
3
- abbr: ["title"],
4
- address: [],
5
- area: ["shape", "coords", "href", "alt"],
6
- article: [],
7
- aside: [],
8
- audio: ["autoplay", "controls", "loop", "preload", "src"],
9
- b: [],
10
- bdi: ["dir"],
11
- bdo: ["dir"],
12
- big: [],
13
- blockquote: ["cite"],
14
- br: [],
15
- caption: [],
16
- center: [],
17
- cite: [],
18
- code: [],
19
- col: ["align", "valign", "span", "width"],
20
- colgroup: ["align", "valign", "span", "width"],
21
- dd: [],
22
- del: ["datetime"],
23
- details: ["open"],
24
- div: ["style"],
25
- dl: [],
26
- dt: [],
27
- em: [],
28
- font: ["color", "size", "face", "style"],
29
- footer: [],
30
- h1: ["style"],
31
- h2: ["style"],
32
- h3: ["style"],
33
- h4: ["style"],
34
- h5: ["style"],
35
- h6: ["style"],
36
- header: ["style"],
37
- hr: ["style", "class"],
38
- i: [],
39
- img: ["src", "alt", "title", "width", "height", "style", "class", "type"],
40
- ins: ["datetime"],
41
- li: ["style"],
42
- mark: [],
43
- nav: [],
44
- ol: ["style"],
45
- p: ["style"],
46
- pre: ["style"],
47
- s: [],
48
- section: [],
49
- small: [],
50
- span: ["style", "class"],
51
- sub: [],
52
- sup: [],
53
- strong: [],
54
- table: ["width", "border", "align", "valign", "style", "class"],
55
- tbody: ["align", "valign", "style", "class"],
56
- td: ["width", "rowspan", "colspan", "align", "valign", "style", "class"],
57
- tfoot: ["align", "valign", "style", "class"],
58
- th: ["width", "rowspan", "colspan", "align", "valign", "style", "class"],
59
- thead: ["align", "valign", "style", "class"],
60
- tr: ["rowspan", "align", "valign", "style", "class"],
61
- tt: [],
62
- u: [],
63
- ul: ["style", "class"],
64
- video: ["style", "autoplay", "controls", "loop", "preload", "src", "height", "width"],
65
- iframe: ["src", "frameborder", "allow", "sandbox", "referrerpolicy", "allowfullscreen", "style", "class"]
66
- };
67
- var HIGHLIGHT_JS_THEME = "a11y-light";
68
- export var MONOSPACE_FONT_URL = "https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap";
69
- export var HIGHLIGHJS_JS = ["https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.6.0/highlight.min.js"];
70
- export var HIGHLIGHJS_CSS = ["https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.6.0/styles/default.min.css", "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.6.0/styles/".concat(HIGHLIGHT_JS_THEME, ".min.css")];
71
- export var ELEMENT_TYPE_PRE = "PRE";
72
- export var ELEMENT_TYPE_CODE = "CODE";
73
- export var CODE_BLOCK_AVAILABLE_LANGUAGES = ["javascript", "html", "css", "xml", "json", "java", "php", "typescript"];
@@ -1,56 +0,0 @@
1
- import showdown from "showdown";
2
- import { extraMentioning, mentioningRegex } from "./mentioningUtils";
3
- var mentioningRegexCaseInsensitive = new RegExp(mentioningRegex, "i");
4
- var mentioningRegexGroupCaseInsensitive = new RegExp(mentioningRegex, "gi");
5
- var converter;
6
- var customRules = {
7
- color: {
8
- type: "lang",
9
- regex: /\((.*?)\)\[(rgb\((?:([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5]), ?)(?:([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5]), ?)(?:([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5]))\))\]/gi,
10
- replace: function replace(s, val) {
11
- var color = s.match(/\[(rgb\((?:([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5]), ?)(?:([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5]), ?)(?:([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5]))\))\]/gi)[0].replace("[", "").replace("]", "");
12
- return "<span style=\"color:".concat(color, "\">").concat(val, "</span>");
13
- }
14
- },
15
- mention: {
16
- type: "lang",
17
- regex: mentioningRegexGroupCaseInsensitive,
18
- replace: function replace(s) {
19
- var r = s.match(mentioningRegexCaseInsensitive);
20
- var id = r && r.length > 1 && r[1];
21
- var name = r && r.length > 2 && r[2];
22
- if (extraMentioning.find(function (mentioning) {
23
- return mentioning.toLowerCase() === String(id).toLowerCase();
24
- })) {
25
- return "<a class=\"mention extraMention\" data-user-id=\"".concat(id, "\">@").concat(name, "</a>");
26
- }
27
- return "<a class=\"mention\" data-user-id=\"".concat(id, "\">@").concat(name, "</a>");
28
- }
29
- },
30
- userMentioTag: {
31
- type: "lang",
32
- regex: /<user-mentio[^>]*>(.+?)<\/user-mentio>/gi,
33
- replace: function replace(s) {
34
- var r = s.match(/<user-mentio[^>]*>(.+?)<\/user-mentio>/);
35
- var attr = s.match(/data-user-id=["']([^"]+)["']/);
36
- var name = r && r.length > 1 && r[1];
37
- var id = attr && attr.length > 1 && attr[1];
38
- return "<a class=\"mention\" data-user-id=\"".concat(id, "\">").concat(name, "</a>");
39
- }
40
- }
41
- };
42
- function getConverter() {
43
- if (converter) return converter;
44
- showdown.extension("color", customRules.color);
45
- showdown.extension("mention", customRules.mention);
46
- showdown.extension("usermentiotag", customRules.userMentioTag);
47
- converter = new showdown.Converter({
48
- extensions: ["color", "mention", "usermentiotag"]
49
- });
50
- converter.setOption("strikethrough", true); // <del>
51
- converter.setOption("tables", true); // <table>
52
- converter.setOption("openLinksInNewWindow", true);
53
- converter.setOption("disableForced4SpacesIndentedSublists", true);
54
- return converter;
55
- }
56
- export default getConverter();
package/dist/index.js DELETED
@@ -1 +0,0 @@
1
- export { default as ContentRenderer } from "./ContentRenderer";
@@ -1,2 +0,0 @@
1
- export var mentioningRegex = /@(\d*|channel|editors):\((.*?)\)/;
2
- export var extraMentioning = ["channel", "editors"];
package/dist/utils.js DELETED
@@ -1,113 +0,0 @@
1
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
- import linkifyHtml from "linkifyjs/html";
5
- import xss from "xss";
6
- import { decode as decodeHtmlEntities } from "html-entities";
7
- import { fixEmojioneBug, shortToUnicode } from "@happeouikit/emojis";
8
- import { MONOSPACE_FONT_URL, safeTagsAndAttributes } from "./constants";
9
- import htmlConverter from "./htmlConverter";
10
- import { extraMentioning, mentioningRegex } from "./mentioningUtils";
11
- var mentioningRegexGroupCaseInsensitive = new RegExp(mentioningRegex, "gi");
12
- var mentioningHtmlRegexGroupCaseInsensitive = new RegExp(/<user-mentio[^>]*data-user-id=["']([^"]+)["'][^>]*>(?:@|(?:&#64;))(.+?)<\/user-mentio>/, "gi");
13
- var processMatch = function processMatch(match, id, name) {
14
- if (extraMentioning.find(function (mentioning) {
15
- return mentioning.toLowerCase() === String(id).toLowerCase();
16
- })) {
17
- return "<a class=\"mention extraMention\" data-user-id=\"".concat(id, "\">@").concat(name, "</a>");
18
- }
19
- return "<a class=\"mention\" data-user-id=\"".concat(id, "\">@").concat(name, "</a>");
20
- };
21
- var processMentions = function processMentions() {
22
- var str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
23
- return str.replace(mentioningRegexGroupCaseInsensitive, processMatch).replace(mentioningHtmlRegexGroupCaseInsensitive, processMatch);
24
- };
25
-
26
- /**
27
- * @name toSafeText
28
- * @description Returns filtered text with filterXSS library
29
- * @author Antero Hanhirova
30
- * @param {String} - Text to whitelist
31
- * @returns {String}
32
- */
33
- var toSafeText = function toSafeText(text) {
34
- return xss(text, {
35
- whiteList: safeTagsAndAttributes,
36
- css: {
37
- whiteList: _objectSpread(_objectSpread({}, xss.getDefaultCSSWhiteList()), {}, {
38
- "vertical-align": true
39
- })
40
- },
41
- stripIgnoreTag: true
42
- }).replace(/&nbsp;/g, " ").replace(/\u2060/g, ""); // Replaces a hidden character that resulted in a "?"-character in backend
43
- };
44
-
45
- /**
46
- * Adds spans with `color-block` class after color codes hex, rgb and rgba
47
- */
48
- var addColorSpanAfterColorCodes = function addColorSpanAfterColorCodes() {
49
- var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
50
- var colorRegex = /#(?:[0-9a-fA-F]{3}){1,2}|\brgb\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\)|\brgba\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d*(?:\.\d+)?\s*\)/gi;
51
- return text.replace(colorRegex, function (match) {
52
- return "".concat(match, "<span class=\"color-block\" style=\"background-color: ").concat(match, ";\"></span>");
53
- });
54
- };
55
-
56
- /**
57
- * @name toHtml
58
- * @description Converts markdown to html, adds space to end of String
59
- * The non-breaking space helps users to add text if last word is mention item
60
- * @author Antero Hanhirova
61
- * @param {String} - Markdown
62
- * @returns {String} - Html
63
- */
64
-
65
- var toHtml = function toHtml() {
66
- var str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
67
- var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "html";
68
- var newString = shortToUnicode(str);
69
- newString = fixEmojioneBug(newString);
70
- if (type === "markdown") {
71
- newString = htmlConverter.makeHtml(newString);
72
- } else {
73
- newString = processMentions(newString);
74
- }
75
- newString = toSafeText(newString);
76
- return linkifyHtml(newString, {
77
- target: "_blank",
78
- ignoreTags: ["pre", "code", "script", "style"],
79
- validate: {
80
- url: function url(value) {
81
- return /^(http|ftp)s?:\/\//.test(value);
82
- }
83
- }
84
- });
85
- };
86
- var loadCodeFont = function loadCodeFont() {
87
- var id = "ibmMonoOnDemand";
88
- if (!document.getElementById(id)) {
89
- var style = document.createElement("style");
90
- style.id = id;
91
- style.appendChild(document.createTextNode("@import url(".concat(MONOSPACE_FONT_URL, ");")));
92
- document.head.appendChild(style);
93
- }
94
- };
95
- var getNearestRelativeParent = function getNearestRelativeParent(el) {
96
- if (!el) return null;
97
- var elStyle = el.currentStyle || window.getComputedStyle(el, "");
98
- var positionStyle = elStyle.position;
99
- if (["relative", "absolute"].includes(positionStyle)) {
100
- return el;
101
- }
102
- return getNearestRelativeParent(el.parentNode);
103
- };
104
-
105
- // Remove special and hidden characters from string
106
- var removeSpecialCharacters = function removeSpecialCharacters() {
107
- var str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
108
- return (
109
- // eslint-disable-next-line no-control-regex
110
- str.replace(/[^\u0000-\u007E]/g, "")
111
- );
112
- };
113
- export { toHtml, toSafeText, loadCodeFont, decodeHtmlEntities, getNearestRelativeParent, removeSpecialCharacters, addColorSpanAfterColorCodes };