From 6c68ead4db1e75be62961f373b9ea74fb2a51c6a Mon Sep 17 00:00:00 2001 From: Eyo Okon Eyo Date: Fri, 22 Mar 2024 17:25:03 +0100 Subject: [PATCH] remove deprecated markdown component --- src/plugins/kibana_react/public/index.ts | 3 - .../__snapshots__/markdown.test.tsx.snap | 60 ---- .../public/markdown/_markdown.scss | 328 ------------------ .../kibana_react/public/markdown/index.scss | 1 - .../kibana_react/public/markdown/index.tsx | 34 -- .../public/markdown/markdown.test.tsx | 83 ----- .../kibana_react/public/markdown/markdown.tsx | 109 ------ .../public/markdown/markdown_simple.tsx | 23 -- 8 files changed, 641 deletions(-) delete mode 100644 src/plugins/kibana_react/public/markdown/__snapshots__/markdown.test.tsx.snap delete mode 100644 src/plugins/kibana_react/public/markdown/_markdown.scss delete mode 100644 src/plugins/kibana_react/public/markdown/index.scss delete mode 100644 src/plugins/kibana_react/public/markdown/index.tsx delete mode 100644 src/plugins/kibana_react/public/markdown/markdown.test.tsx delete mode 100644 src/plugins/kibana_react/public/markdown/markdown.tsx delete mode 100644 src/plugins/kibana_react/public/markdown/markdown_simple.tsx diff --git a/src/plugins/kibana_react/public/index.ts b/src/plugins/kibana_react/public/index.ts index 93480cd3cf9457..510d57fc6c09a9 100644 --- a/src/plugins/kibana_react/public/index.ts +++ b/src/plugins/kibana_react/public/index.ts @@ -56,9 +56,6 @@ export { ValidatedDualRange } from './validated_range'; export type { ToastInput, KibanaReactNotifications } from './notifications'; export { createNotifications } from './notifications'; -/** @deprecated use `Markdown` from `@kbn/shared-ux-markdown` */ -export { Markdown, MarkdownSimple } from './markdown'; - export { toMountPoint } from './util'; export type { ToMountPointOptions } from './util'; diff --git a/src/plugins/kibana_react/public/markdown/__snapshots__/markdown.test.tsx.snap b/src/plugins/kibana_react/public/markdown/__snapshots__/markdown.test.tsx.snap deleted file mode 100644 index 4299acdd32c9e8..00000000000000 --- a/src/plugins/kibana_react/public/markdown/__snapshots__/markdown.test.tsx.snap +++ /dev/null @@ -1,60 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`props markdown 1`] = ` -
I am some content with markdown

-", - } - } -/> -`; - -exports[`props openLinksInNewTab 1`] = ` -
I am some content with markdown

-", - } - } -/> -`; - -exports[`props whiteListedRules 1`] = ` -
I am some [content](https://en.wikipedia.org/wiki/Content) with markdown

-", - } - } -/> -`; - -exports[`render 1`] = ` -
-`; - -exports[`should never render html tags 1`] = ` -
<div>I may be dangerous if rendered as html</div>

-", - } - } -/> -`; diff --git a/src/plugins/kibana_react/public/markdown/_markdown.scss b/src/plugins/kibana_react/public/markdown/_markdown.scss deleted file mode 100644 index a3bba38509bcdb..00000000000000 --- a/src/plugins/kibana_react/public/markdown/_markdown.scss +++ /dev/null @@ -1,328 +0,0 @@ -// Default styles for Markdown element -// -// 1. Links -// 2. Headings -// 3. Images -// 4. Blockquotes -// 5. Horizontal rules -// 6. Lists -// 7. Tables -// 8. Code blocks - -// Functions -// Note: The inlined base font size is set in common/functions/font.js. It should match $kbnMdFontSize. -$kbnDefaultFontSize: 14px; - -@function canvasToEm($size) { - @return #{calc($size / $kbnDefaultFontSize)}em; -} - -.kbnMarkdown__body { - // Font size variables - $kbnMarkdownFontSizeS: canvasToEm(12px); - $kbnMarkdownFontSize: canvasToEm(14px); - $kbnMarkdownFontSizeL: canvasToEm(20px); - $kbnMarkdownFontSizeXL: canvasToEm(28px); - $kbnMarkdownFontSizeXXL: canvasToEm(36px); - - // Spacing variables - $kbnMarkdownSizeL: canvasToEm(24px); - $kbnMarkdownSize: canvasToEm(16px); - $kbnMarkdownSizeS: canvasToEm(12px); - $kbnMarkdownSizeXS: canvasToEm(8px); - $kbnMarkdownSizeXXS: canvasToEm(4px); - - // Grayscale variables - $kbnMarkdownAlphaLightestShade: rgba($euiColorFullShade, .05); - $kbnMarkdownAlphaLightShade: rgba($euiColorFullShade, .15); - $kbnMarkdownAlphaDarkShade: rgba($euiColorFullShade, .65); - - // Reverse grayscale for opposite of theme - $kbnMarkdownAlphaLightestShadeReversed: rgba($euiColorEmptyShade, .05); - $kbnMarkdownAlphaLightShadeReversed: rgba($euiColorEmptyShade, .15); - $kbnMarkdownAlphaDarkShadeReversed: rgba($euiColorEmptyShade, .65); - - &--reversed { - color: $euiColorLightestShade; - } - - > *:first-child { - margin-top: 0 !important; - } - - > *:last-child { - margin-bottom: 0 !important; - } - - p, - blockquote, - ul, - ol, - dl, - table, - pre { - margin-top: 0; - margin-bottom: $kbnMarkdownSize; - line-height: 1.5em; - } - - strong { - font-weight: 600; - } - - // 1. Links - a { - color: inherit; - text-decoration: underline; - } - - a:hover { - text-decoration: underline dotted; - } - - a:active, - a:hover { - outline-width: 0; - } - - a:not([href]) { - color: inherit; - text-decoration: none; - } - - // 2. Headings - h1, - h2, - h3, - h4, - h5, - h6 { - margin-top: 0; - margin-bottom: $kbnMarkdownSizeXS; - } - - h1 { - font-size: $kbnMarkdownFontSizeXXL; - line-height: 1.333333em; - font-weight: 300; - } - - h2 { - font-size: $kbnMarkdownFontSizeXL; - line-height: 1.428571em; - font-weight: 300; - } - - h3 { - font-size: $kbnMarkdownFontSizeL; - line-height: 1.6em; - font-weight: 600; - } - - h4 { - font-size: $kbnMarkdownSize; - line-height: 1.5em; - font-weight: 600; - } - - h5 { - font-size: $kbnMarkdownFontSize; - line-height: 1.142857em; - font-weight: 700; - } - - h6 { - font-size: $kbnMarkdownFontSizeS; - line-height: 1.333333em; - font-weight: 700; - text-transform: uppercase; - } - - // 3. Images - img { - max-width: 100%; - box-sizing: content-box; - border-style: none; - pointer-events: auto; - } - - // 4. Blockquotes - blockquote { - padding: 0 1em; - border-left: $kbnMarkdownSizeXXS solid $kbnMarkdownAlphaLightShade; - } - &--reversed blockquote { - border-left-color: $kbnMarkdownAlphaLightShadeReversed; - } - - // 5. Horizontal rules - hr { - overflow: hidden; - background: transparent; - height: 2px; - padding: 0; - margin: $kbnMarkdownSizeL 0; - background-color: $kbnMarkdownAlphaLightShade; - border: 0; - } - &--reversed hr { - background-color: $kbnMarkdownAlphaLightShadeReversed; - } - - hr::before { - display: table; - content: ''; - } - - hr::after { - display: table; - clear: both; - content: ''; - } - - // 6. Lists - ul, - ol { - padding-left: $kbnMarkdownSizeL; - margin-top: 0; - margin-bottom: $kbnMarkdownSize; - } - - ul { - list-style-type: disc; - } - ol { - list-style-type: decimal; - } - - ul ul { - list-style-type: circle; - } - - ol ol, - ul ol { - list-style-type: lower-roman; - } - - ul ul ol, - ul ol ol, - ol ul ol, - ol ol ol { - list-style-type: lower-alpha; - } - - dd { - margin-left: 0; - } - - ul ul, - ul ol, - ol ol, - ol ul { - margin-top: 0; - margin-bottom: 0; - } - - li > p { - margin-bottom: $kbnMarkdownSizeXS; - } - - li + li { - margin-top: $kbnMarkdownSizeXXS; - } - - // 7. Tables - table { - display: block; - width: 100%; - overflow: auto; - border-left: 1px solid $kbnMarkdownAlphaLightShade; - border-spacing: 0; - border-collapse: collapse; - } - &--reversed table { - border-left-color: $kbnMarkdownAlphaLightShadeReversed; - } - - td, - th { - padding: 0; - } - - table th, - table td { - padding: $kbnMarkdownSizeXXS $kbnMarkdownSizeS; - border-top: 1px solid $kbnMarkdownAlphaLightShade; - border-bottom: 1px solid $kbnMarkdownAlphaLightShade; - - &:last-child { - border-right: 1px solid $kbnMarkdownAlphaLightShade; - } - } - &--reversed table th, - &--reversed table td { - border-color: $kbnMarkdownAlphaLightShadeReversed; - } - - table tr { - background-color: transparent; - border-top: 1px solid $kbnMarkdownAlphaLightShade; - } - &--reversed table tr { - border-top-color: $kbnMarkdownAlphaLightShadeReversed; - } - - // 8. Code blocks - code, - pre { - margin-bottom: $kbnMarkdownSizeXS; - font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace; - font-size: $kbnMarkdownFontSizeS; - } - - code { - padding: $kbnMarkdownSizeXXS 0; - margin: 0; - background-color: $kbnMarkdownAlphaLightestShade; - border-radius: $kbnMarkdownSizeXXS; - } - &--reversed code { - background-color: $kbnMarkdownAlphaLightestShadeReversed; - } - - code::before, - code::after { - letter-spacing: -.2em; - content: '\00a0'; - } - - pre { - padding: $kbnMarkdownSize; - overflow: auto; - font-size: $kbnMarkdownFontSizeS; - line-height: 1.333333em; - background-color: $kbnMarkdownAlphaLightestShade; - border-radius: $kbnMarkdownSizeXXS; - word-wrap: normal; - } - &--reversed pre { - background-color: $kbnMarkdownAlphaLightestShadeReversed; - } - - pre code { - display: inline; - max-width: auto; - padding: 0; - overflow: visible; - line-height: inherit; - word-wrap: normal; - white-space: pre; - background-color: transparent; - border: 0; - } - - pre code::before, - pre code::after { - content: normal; - } -} diff --git a/src/plugins/kibana_react/public/markdown/index.scss b/src/plugins/kibana_react/public/markdown/index.scss deleted file mode 100644 index f997ea5384eacd..00000000000000 --- a/src/plugins/kibana_react/public/markdown/index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './markdown'; diff --git a/src/plugins/kibana_react/public/markdown/index.tsx b/src/plugins/kibana_react/public/markdown/index.tsx deleted file mode 100644 index c15d4269cf3c07..00000000000000 --- a/src/plugins/kibana_react/public/markdown/index.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React from 'react'; -import { EuiSkeletonText, EuiDelayRender } from '@elastic/eui'; -import type { MarkdownSimpleProps } from './markdown_simple'; -import type { MarkdownProps } from './markdown'; - -const Fallback = () => ( - - - -); - -/** @deprecated use `Markdown` from `@kbn/shared-ux-markdown` */ -const LazyMarkdownSimple = React.lazy(() => import('./markdown_simple')); -export const MarkdownSimple = (props: MarkdownSimpleProps) => ( - }> - - -); - -/** @deprecated use `Markdown` from `@kbn/shared-ux-markdown` */ -const LazyMarkdown = React.lazy(() => import('./markdown')); -export const Markdown = (props: MarkdownProps) => ( - }> - - -); diff --git a/src/plugins/kibana_react/public/markdown/markdown.test.tsx b/src/plugins/kibana_react/public/markdown/markdown.test.tsx deleted file mode 100644 index 1dda072be9e5fd..00000000000000 --- a/src/plugins/kibana_react/public/markdown/markdown.test.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React from 'react'; -import { shallow } from 'enzyme'; - -import { Markdown } from './markdown'; - -test('render', () => { - const component = shallow(); - expect(component).toMatchSnapshot(); -}); - -test('should never render html tags', () => { - const component = shallow( - - ); - expect(component).toMatchSnapshot(); -}); - -test('should render links with parentheses correctly', () => { - const component = shallow( - - ); - expect(component.render().find('a').prop('href')).toBe( - 'https://example.com/foo/bar?group=(()filters:!t)' - ); -}); - -test('should add `noreferrer` and `nooopener` to all links in new tabs', () => { - const component = shallow( - - ); - expect(component.render().find('a').prop('rel')).toBe('noopener noreferrer'); -}); - -describe('props', () => { - const markdown = 'I am *some* [content](https://en.wikipedia.org/wiki/Content) with `markdown`'; - - test('markdown', () => { - const component = shallow(); - expect(component).toMatchSnapshot(); - }); - - test('openLinksInNewTab', () => { - const component = shallow(); - expect(component).toMatchSnapshot(); - }); - - test('whiteListedRules', () => { - const component = shallow( - - ); - expect(component).toMatchSnapshot(); - }); - - test('should update markdown when openLinksInNewTab prop change', () => { - const component = shallow(); - expect(component.render().find('a').prop('target')).not.toBe('_blank'); - component.setProps({ openLinksInNewTab: true }); - expect(component.render().find('a').prop('target')).toBe('_blank'); - }); - - test('should update markdown when whiteListedRules prop change', () => { - const md = '*emphasis* `backticks`'; - const component = shallow( - - ); - expect(component.render().find('em')).toHaveLength(1); - expect(component.render().find('code')).toHaveLength(1); - component.setProps({ whiteListedRules: ['backticks'] }); - expect(component.render().find('code')).toHaveLength(1); - expect(component.render().find('em')).toHaveLength(0); - }); -}); diff --git a/src/plugins/kibana_react/public/markdown/markdown.tsx b/src/plugins/kibana_react/public/markdown/markdown.tsx deleted file mode 100644 index 62f2564daf1f55..00000000000000 --- a/src/plugins/kibana_react/public/markdown/markdown.tsx +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import classNames from 'classnames'; -import React, { useEffect } from 'react'; -import MarkdownIt from 'markdown-it'; -import { memoize } from 'lodash'; -import { getSecureRelForTarget } from '@elastic/eui'; - -import './index.scss'; -/** - * Return a memoized markdown rendering function that use the specified - * whiteListedRules and openLinksInNewTab configurations. - * @param {Array of Strings} whiteListedRules - white list of markdown rules - * list of rules can be found at https://github.com/markdown-it/markdown-it/issues/361 - * @param {Boolean} openLinksInNewTab - * @return {Function} Returns an Object to use with dangerouslySetInnerHTML - * with the rendered markdown HTML - */ -export const markdownFactory = memoize( - (whiteListedRules: string[] = [], openLinksInNewTab: boolean = false) => { - let markdownIt: MarkdownIt; - - // It is imperative that the html config property be set to false, to mitigate XSS: the output of markdown-it is - // fed directly to the DOM via React's dangerouslySetInnerHTML below. - - if (whiteListedRules && whiteListedRules.length > 0) { - markdownIt = new MarkdownIt('zero', { html: false, linkify: true }); - markdownIt.enable(whiteListedRules); - } else { - markdownIt = new MarkdownIt({ html: false, linkify: true }); - } - - if (openLinksInNewTab) { - // All links should open in new browser tab. - // Define custom renderer to add 'target' attribute - // https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md#renderer - const originalLinkRender = - markdownIt.renderer.rules.link_open || - function (tokens, idx, options, env, self) { - return self.renderToken(tokens, idx, options); - }; - markdownIt.renderer.rules.link_open = function (tokens, idx, options, env, self) { - const href = tokens[idx].attrGet('href'); - const target = '_blank'; - const rel = getSecureRelForTarget({ href: href === null ? undefined : href, target }); - - // https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/ - tokens[idx].attrPush(['target', target]); - if (rel) { - tokens[idx].attrPush(['rel', rel]); - } - return originalLinkRender(tokens, idx, options, env, self); - }; - } - /** - * This method is used to render markdown from the passed parameter - * into HTML. It will just return an empty string when the markdown is empty. - * @param {String} markdown - The markdown String - * @return {String} - Returns the rendered HTML as string. - */ - return (markdown: string) => { - return markdown ? markdownIt.render(markdown) : ''; - }; - }, - (whiteListedRules: string[] = [], openLinksInNewTab: boolean = false) => { - return `${whiteListedRules.join('_')}${openLinksInNewTab}`; - } -); - -export interface MarkdownProps extends React.HTMLAttributes { - className?: string; - markdown?: string; - openLinksInNewTab?: boolean; - whiteListedRules?: string[]; - onRender?: () => void; -} - -export const Markdown = (props: MarkdownProps) => { - useEffect(() => { - props.onRender?.(); - }, [props]); - - const { className, markdown = '', openLinksInNewTab, whiteListedRules, ...rest } = props; - const classes = classNames('kbnMarkdown__body', className); - const markdownRenderer = markdownFactory(whiteListedRules, openLinksInNewTab); - const renderedMarkdown = markdownRenderer(markdown); - return ( -
- ); -}; - -// Needed for React.lazy -// eslint-disable-next-line import/no-default-export -export default Markdown; diff --git a/src/plugins/kibana_react/public/markdown/markdown_simple.tsx b/src/plugins/kibana_react/public/markdown/markdown_simple.tsx deleted file mode 100644 index 24b9eee7b1ca5d..00000000000000 --- a/src/plugins/kibana_react/public/markdown/markdown_simple.tsx +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React from 'react'; -import ReactMarkdown from 'react-markdown'; - -export interface MarkdownSimpleProps { - children: string; -} - -// Render markdown string into JSX inside of a Fragment. -export const MarkdownSimple = ({ children }: MarkdownSimpleProps) => ( - {children} -); - -// Needed for React.lazy -// eslint-disable-next-line import/no-default-export -export default MarkdownSimple;