simplify auto-embed syntax
This commit is contained in:
parent
20ef65540d
commit
19c8e55d08
3 changed files with 31 additions and 18 deletions
|
@ -43,7 +43,7 @@ const schema = { ...defaultSchema };
|
||||||
|
|
||||||
// Extend sanitation schema to support lbry protocol
|
// Extend sanitation schema to support lbry protocol
|
||||||
schema.protocols.href.push('lbry');
|
schema.protocols.href.push('lbry');
|
||||||
schema.attributes.a.push('data-preview');
|
schema.attributes.a.push('embed');
|
||||||
|
|
||||||
const MarkdownPreview = (props: MarkdownProps) => {
|
const MarkdownPreview = (props: MarkdownProps) => {
|
||||||
const { content, strip, promptLinks } = props;
|
const { content, strip, promptLinks } = props;
|
||||||
|
@ -61,7 +61,7 @@ const MarkdownPreview = (props: MarkdownProps) => {
|
||||||
const remarkAttrOpts = {
|
const remarkAttrOpts = {
|
||||||
scope: 'extended',
|
scope: 'extended',
|
||||||
elements: ['link'],
|
elements: ['link'],
|
||||||
extend: { link: ['data-preview'] },
|
extend: { link: ['embed'] },
|
||||||
defaultValue: true,
|
defaultValue: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,19 +9,20 @@ import ClaimLink from 'component/claimLink';
|
||||||
type Props = {
|
type Props = {
|
||||||
href: string,
|
href: string,
|
||||||
title?: string,
|
title?: string,
|
||||||
|
embed?: boolean,
|
||||||
children: React.Node,
|
children: React.Node,
|
||||||
openModal: (id: string, { uri: string }) => void,
|
openModal: (id: string, { uri: string }) => void,
|
||||||
'data-preview'?: boolean,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExternalLink extends React.PureComponent<Props> {
|
class ExternalLink extends React.PureComponent<Props> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
href: null,
|
href: null,
|
||||||
title: null,
|
title: null,
|
||||||
|
embed: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
createLink() {
|
createLink() {
|
||||||
const { href, title, children, openModal } = this.props;
|
const { href, title, embed, children, openModal } = this.props;
|
||||||
// Regex for url protocol
|
// Regex for url protocol
|
||||||
const protocolRegex = new RegExp('^(https?|lbry|mailto)+:', 'i');
|
const protocolRegex = new RegExp('^(https?|lbry|mailto)+:', 'i');
|
||||||
const protocol = href ? protocolRegex.exec(href) : null;
|
const protocol = href ? protocolRegex.exec(href) : null;
|
||||||
|
@ -43,7 +44,7 @@ class ExternalLink extends React.PureComponent<Props> {
|
||||||
// Return local link if protocol is lbry uri
|
// Return local link if protocol is lbry uri
|
||||||
if (protocol && protocol[0] === 'lbry:' && isURIValid(href)) {
|
if (protocol && protocol[0] === 'lbry:' && isURIValid(href)) {
|
||||||
element = (
|
element = (
|
||||||
<ClaimLink uri={href} autoEmbed={this.props['data-preview']}>
|
<ClaimLink uri={href} autoEmbed={embed}>
|
||||||
{children}
|
{children}
|
||||||
</ClaimLink>
|
</ClaimLink>
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,12 +6,12 @@ const locateURI = (value, fromIndex) => value.indexOf(protocol, fromIndex);
|
||||||
const locateMention = (value, fromIndex) => value.indexOf('@', fromIndex);
|
const locateMention = (value, fromIndex) => value.indexOf('@', fromIndex);
|
||||||
|
|
||||||
// Generate a valid markdown link
|
// Generate a valid markdown link
|
||||||
const createURI = (text, uri, autoEmbed = false) => ({
|
const createURI = (text, uri, embed = false) => ({
|
||||||
type: 'link',
|
type: 'link',
|
||||||
url: (uri.startsWith(protocol) ? '' : protocol) + uri,
|
url: (uri.startsWith(protocol) ? '' : protocol) + uri,
|
||||||
data: {
|
data: {
|
||||||
// Custom attribute
|
// Custom attribute
|
||||||
hProperties: { 'data-preview': autoEmbed },
|
hProperties: { embed },
|
||||||
},
|
},
|
||||||
children: [{ type: 'text', value: text }],
|
children: [{ type: 'text', value: text }],
|
||||||
});
|
});
|
||||||
|
@ -21,12 +21,17 @@ const validateURI = (match, eat) => {
|
||||||
try {
|
try {
|
||||||
const text = match[0];
|
const text = match[0];
|
||||||
const uri = parseURI(text);
|
const uri = parseURI(text);
|
||||||
// Create channel link
|
const isValid = uri && uri.claimName;
|
||||||
if (uri.isChannel && !uri.path) {
|
const isChannel = uri.isChannel && !uri.path;
|
||||||
return eat(text)(createURI(uri.claimName, text, false));
|
|
||||||
|
if (isValid) {
|
||||||
|
// Create channel link
|
||||||
|
if (isChannel) {
|
||||||
|
return eat(text)(createURI(uri.claimName, text, false));
|
||||||
|
}
|
||||||
|
// Create claim link
|
||||||
|
return eat(text)(createURI(text, text, true));
|
||||||
}
|
}
|
||||||
// Create uri link
|
|
||||||
return eat(text)(createURI(text, text, true));
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Silent errors: console.error(err)
|
// Silent errors: console.error(err)
|
||||||
}
|
}
|
||||||
|
@ -60,13 +65,20 @@ tokenizeMention.notInBlock = true;
|
||||||
const visitor = (node, index, parent) => {
|
const visitor = (node, index, parent) => {
|
||||||
if (node.type === 'link' && parent && parent.type === 'paragraph') {
|
if (node.type === 'link' && parent && parent.type === 'paragraph') {
|
||||||
try {
|
try {
|
||||||
const url = parseURI(node.url);
|
const uri = parseURI(node.url);
|
||||||
// Handle lbry link
|
const isValid = uri && uri.claimName;
|
||||||
if (!url.isChannel || (url.isChannel && url.path)) {
|
const isChannel = uri.isChannel && !uri.path;
|
||||||
// Auto-embed lbry url
|
if (isValid && !isChannel) {
|
||||||
if (!node.data) {
|
if (!node.data || !node.data.hProperties) {
|
||||||
|
// Create new node data
|
||||||
node.data = {
|
node.data = {
|
||||||
hProperties: { 'data-preview': true },
|
hProperties: { embed: true },
|
||||||
|
};
|
||||||
|
} else if (node.data.hProperties) {
|
||||||
|
// Don't overwrite current attributes
|
||||||
|
node.data.hProperties = {
|
||||||
|
embed: true,
|
||||||
|
...node.data.hProperties,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue