2020-11-05 18:58:23 +02:00
import { RuleOptions } from '../../MdToHtml' ;
2020-10-21 01:23:55 +02:00
2020-01-30 23:05:23 +02:00
const Entities = require ( 'html-entities' ) . AllHtmlEntities ;
const htmlentities = new Entities ( ) . encode ;
const utils = require ( '../../utils' ) ;
const urlUtils = require ( '../../urlUtils.js' ) ;
const { getClassNameForMimeType } = require ( 'font-awesome-filetypes' ) ;
2020-11-12 21:13:28 +02:00
function plugin ( markdownIt : any , ruleOptions : RuleOptions ) {
markdownIt . renderer . rules . link_open = function ( tokens : any [ ] , idx : number ) {
2020-01-30 23:05:23 +02:00
const token = tokens [ idx ] ;
let href = utils . getAttr ( token . attrs , 'href' ) ;
const resourceHrefInfo = urlUtils . parseResourceUrl ( href ) ;
2020-07-15 00:27:12 +02:00
const isResourceUrl = ruleOptions . resources && ! ! resourceHrefInfo ;
2020-01-30 23:05:23 +02:00
let title = utils . getAttr ( token . attrs , 'title' , isResourceUrl ? '' : href ) ;
let resourceIdAttr = '' ;
let icon = '' ;
let hrefAttr = '#' ;
let mime = '' ;
2020-05-30 14:25:05 +02:00
let resourceId = '' ;
2020-01-30 23:05:23 +02:00
if ( isResourceUrl ) {
2020-05-30 14:25:05 +02:00
resourceId = resourceHrefInfo . itemId ;
2020-01-30 23:05:23 +02:00
const result = ruleOptions . resources [ resourceId ] ;
const resourceStatus = utils . resourceStatus ( ruleOptions . ResourceModel , result ) ;
if ( result && result . item ) {
title = utils . getAttr ( token . attrs , 'title' , result . item . title ) ;
mime = result . item . mime ;
}
if ( result && resourceStatus !== 'ready' && ! ruleOptions . plainResourceRendering ) {
const icon = utils . resourceStatusFile ( resourceStatus ) ;
return ` <a class="not-loaded-resource resource-status- ${ resourceStatus } " data-resource-id=" ${ resourceId } "> ` + ` <img src="data:image/svg+xml;utf8, ${ htmlentities ( icon ) } "/> ` ;
} else {
href = ` joplin:// ${ resourceId } ` ;
if ( resourceHrefInfo . hash ) href += ` # ${ resourceHrefInfo . hash } ` ;
resourceIdAttr = ` data-resource-id=' ${ resourceId } ' ` ;
let iconType = getClassNameForMimeType ( mime ) ;
if ( ! mime ) {
iconType = 'fa-joplin' ;
}
2020-10-21 01:23:55 +02:00
// Icons are defined in lib/renderers/noteStyle using inline svg
2020-01-30 23:05:23 +02:00
// The icons are taken from fork-awesome but use the font-awesome naming scheme in order
// to be more compatible with the getClass library
icon = ` <span class="resource-icon ${ iconType } "></span> ` ;
}
} else {
// If the link is a plain URL (as opposed to a resource link), set the href to the actual
// link. This allows the link to be exported too when exporting to PDF.
hrefAttr = href ;
}
// A single quote is valid in a URL but we don't want any because the
// href is already enclosed in single quotes.
// https://github.com/laurent22/joplin/issues/2030
href = href . replace ( /'/g , '%27' ) ;
2020-05-30 14:25:05 +02:00
let js = ` ${ ruleOptions . postMessageSyntax } ( ${ JSON . stringify ( href ) } , { resourceId: ${ JSON . stringify ( resourceId ) } }); return false; ` ;
2020-10-12 11:25:59 +02:00
if ( ruleOptions . enableLongPress && ! ! resourceId ) {
const onClick = ` ${ ruleOptions . postMessageSyntax } ( ${ JSON . stringify ( href ) } ) ` ;
const onLongClick = ` ${ ruleOptions . postMessageSyntax } ("longclick: ${ resourceId } ") ` ;
2020-10-21 01:23:55 +02:00
const touchStart = ` t=setTimeout(()=>{t=null; ${ onLongClick } ;}, ${ ruleOptions . longPressDelay } ); ` ;
2020-10-20 12:48:10 +02:00
const cancel = 'if (!!t) {clearTimeout(t); t=null;' ;
const touchEnd = ` ${ cancel } ${ onClick } ;} ` ;
js = ` ontouchstart=' ${ touchStart } ' ontouchend=' ${ touchEnd } ' ontouchcancel=' ${ cancel } ontouchmove=" ${ cancel } ' ` ;
2020-10-17 14:56:41 +02:00
} else {
js = ` onclick=' ${ js } ' ` ;
2020-10-12 11:25:59 +02:00
}
2020-01-30 23:05:23 +02:00
if ( hrefAttr . indexOf ( '#' ) === 0 && href . indexOf ( '#' ) === 0 ) js = '' ; // If it's an internal anchor, don't add any JS since the webview is going to handle navigating to the right place
2020-11-05 18:58:23 +02:00
const attrHtml = [ ] ;
attrHtml . push ( 'data-from-md' ) ;
if ( resourceIdAttr ) attrHtml . push ( resourceIdAttr ) ;
if ( title ) attrHtml . push ( ` title=' ${ htmlentities ( title ) } ' ` ) ;
if ( mime ) attrHtml . push ( ` type=' ${ htmlentities ( mime ) } ' ` ) ;
2020-10-21 01:23:55 +02:00
if ( ruleOptions . plainResourceRendering || ruleOptions . linkRenderingType === 2 ) {
2020-11-05 18:58:23 +02:00
icon = '' ;
attrHtml . push ( ` href=' ${ htmlentities ( href ) } ' ` ) ;
// return `<a data-from-md ${resourceIdAttr} title='${htmlentities(title)}' href='${htmlentities(href)}' type='${htmlentities(mime)}'>`;
2020-01-30 23:05:23 +02:00
} else {
2020-11-05 18:58:23 +02:00
attrHtml . push ( ` href=' ${ hrefAttr } ' ` ) ;
if ( js ) attrHtml . push ( js ) ;
// return `<a data-from-md ${resourceIdAttr} title='${htmlentities(title)}' href='${hrefAttr}' ${js} type='${htmlentities(mime)}'>${icon}`;
2020-01-30 23:05:23 +02:00
}
2020-11-05 18:58:23 +02:00
return ` <a ${ attrHtml . join ( ' ' ) } > ${ icon } ` ;
2020-01-30 23:05:23 +02:00
} ;
}
2020-10-21 01:23:55 +02:00
export default { plugin } ;