diff --git a/package.json b/package.json index dd02e8616..0f3bfd920 100644 --- a/package.json +++ b/package.json @@ -175,6 +175,7 @@ "three": "^0.93.0", "three-full": "^17.1.0", "tree-kill": "^1.1.0", + "unist-util-visit": "^1.4.1", "video.js": "^7.2.2", "villain": "btzr-io/Villain", "wavesurfer.js": "^2.2.1", diff --git a/src/ui/component/common/markdown-preview-internal.jsx b/src/ui/component/common/markdown-preview-internal.jsx index f04a73e63..f5d4e551c 100644 --- a/src/ui/component/common/markdown-preview-internal.jsx +++ b/src/ui/component/common/markdown-preview-internal.jsx @@ -1,12 +1,12 @@ // @flow import * as React from 'react'; import remark from 'remark'; -import remarkLBRY from 'util/remark-lbry'; import remarkStrip from 'strip-markdown'; import remarkEmoji from 'remark-emoji'; import reactRenderer from 'remark-react'; import ExternalLink from 'component/externalLink'; import defaultSchema from 'hast-util-sanitize/lib/github.json'; +import { formatedLinks, inlineLinks } from 'util/remark-lbry'; type SimpleTextProps = { children?: React.Node, @@ -77,7 +77,11 @@ const MarkdownPreview = (props: MarkdownProps) => {
{ remark() - .use(remarkLBRY) + // Remark plugins for lbry urls + // Note: The order is important + .use(formatedLinks) + .use(inlineLinks) + // Emojis .use(remarkEmoji) .use(reactRenderer, remarkOptions) .processSync(content).contents diff --git a/src/ui/util/remark-lbry.js b/src/ui/util/remark-lbry.js index 14cc9fc16..a4e7a9835 100644 --- a/src/ui/util/remark-lbry.js +++ b/src/ui/util/remark-lbry.js @@ -1,4 +1,5 @@ import { parseURI } from 'lbry-redux'; +import visit from 'unist-util-visit'; const protocol = 'lbry://'; const locateURI = (value, fromIndex) => value.indexOf(protocol, fromIndex); @@ -46,16 +47,44 @@ function tokenizeURI(eat, value, silent) { // Configure tokenizer for lbry urls tokenizeURI.locator = locateURI; +tokenizeURI.notInList = true; tokenizeURI.notInLink = true; tokenizeURI.notInBlock = true; // Configure tokenizer for lbry channels tokenizeMention.locator = locateMention; +tokenizeMention.notInList = true; tokenizeMention.notInLink = true; tokenizeMention.notInBlock = true; +const visitor = (node, index, parent) => { + if (node.type === 'link') { + try { + const url = parseURI(node.url); + // Handle lbry link + if (!url.isChannel || (url.isChannel && url.path)) { + // Auto-embed lbry url + if (parent && parent.type === 'paragraph' && !node.data) { + node.data = { + hProperties: { 'data-preview': true }, + }; + } + } + } catch (err) { + // Silent errors: console.error(err) + } + } +}; + +// transform +const transform = tree => { + visit(tree, ['link'], visitor); +}; + +export const formatedLinks = () => transform; + // Main module -export default function remarkLBRY() { +export function inlineLinks() { const Parser = this.Parser; const tokenizers = Parser.prototype.inlineTokenizers; const methods = Parser.prototype.inlineMethods; diff --git a/yarn.lock b/yarn.lock index 7a7093dd7..a41eebb45 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11528,7 +11528,7 @@ unist-util-visit-parents@^2.0.0: dependencies: unist-util-is "^2.1.2" -unist-util-visit@^1.0.0, unist-util-visit@^1.1.0, unist-util-visit@^1.3.0, unist-util-visit@^1.4.0: +unist-util-visit@^1.0.0, unist-util-visit@^1.1.0, unist-util-visit@^1.3.0, unist-util-visit@^1.4.0, unist-util-visit@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.4.1.tgz#4724aaa8486e6ee6e26d7ff3c8685960d560b1e3" integrity sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==