import { Link } from '../MdToHtml';
import { toForwardSlashes } from '@joplin/utils/path';
import { LinkIndexes } from './rules/link_close';
import { RendererTheme } from '../types';
import { AllHtmlEntities as Entities } from 'html-entities';
const htmlentities = new Entities().encode;
export interface Options {
audioPlayerEnabled: boolean;
videoPlayerEnabled: boolean;
autoplayVideo?: boolean;
pdfViewerEnabled: boolean;
useCustomPdfViewer: boolean;
noteId: string;
vendorDir: string;
theme: RendererTheme;
}
function resourceUrl(resourceFullPath: string): string {
if (
resourceFullPath.indexOf('http://') === 0 || resourceFullPath.indexOf('https://') === 0 || resourceFullPath.indexOf('joplin-content://') === 0 ||
resourceFullPath.indexOf('file://') === 0 ||
// On web, resources are loaded as blob URLs.
resourceFullPath.startsWith('blob:null/')
) {
return resourceFullPath;
}
return `file://${toForwardSlashes(resourceFullPath)}`;
}
const resourceHash = (link: string) => {
// Preserve certain #hash strings when rendering resources.
// These patterns can be used to customize the starting/ending points for
// audio/video/PDF embeds:
const patterns = [
// Starting PDF page
/#page=\d+$/,
// Staring/ending playback time
/#t=[0-9:,]+$/,
];
for (const pattern of patterns) {
const match = link.match(pattern);
if (match) {
return match[0];
}
}
return '';
};
export default function(link: Link, options: Options, linkIndexes: LinkIndexes) {
const resource = link.resource;
if (!link.resourceReady || !resource || !resource.mime) return '';
const escapedResourcePath = htmlentities(
resourceUrl(link.resourceFullPath) + resourceHash(link.href),
);
const escapedMime = htmlentities(resource.mime);
const escapedTitle = htmlentities(resource.title || resource.mime);
const resourceIdAttribute = resource.id ? ` data-resource-id="${htmlentities(resource.id)}"` : '';
if (options.videoPlayerEnabled && resource.mime.indexOf('video/') === 0) {
const playbackAttributes = options.autoplayVideo ? 'autoplay muted playsinline preload="auto"' : 'preload="metadata"';
return `
`;
}
if (options.audioPlayerEnabled && resource.mime.indexOf('audio/') === 0) {
// We want to support both audio/x-flac and audio/flac MIME types, but chromium only supports audio/flac
// https://github.com/laurent22/joplin/issues/6434
const escapedAudioMime = escapedMime === 'audio/x-flac' ? 'audio/flac' : escapedMime;
return `
`;
}
if (options.pdfViewerEnabled && resource.mime === 'application/pdf') {
if (options.useCustomPdfViewer) {
const resourceId = resource.id;
let anchorPageNo = null;
let id = `${options.noteId}.${resourceId}`;
if (linkIndexes && linkIndexes[resourceId]) {
linkIndexes[resourceId]++;
} else {
linkIndexes[resourceId] = 1;
}
id += `.${linkIndexes[resourceId]}`;
if (link.href.indexOf('#') > 0) {
anchorPageNo = Number(link.href.split('#').pop());
if (anchorPageNo < 1) anchorPageNo = null;
}
const src = `${options.vendorDir}/lib/@joplin/pdf-viewer/index.html`;
return ``;
}
return ``;
}
return '';
}