mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
ui: update pdf link processing
This commit is contained in:
1 file changed
+23
-10
@@ -3,7 +3,6 @@
|
||||
/* eslint-disable regexp/no-useless-non-capturing-group */
|
||||
/* eslint-disable regexp/optimal-quantifier-concatenation */
|
||||
|
||||
import _ from 'lodash';
|
||||
import type MarkdownIt from 'markdown-it';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
@@ -77,13 +76,22 @@ function resourceUrl(service: string, src: string, url: string) {
|
||||
if (service === 'vimeo') return `https://player.vimeo.com/video/${src}`;
|
||||
if (service === 'vine') return `https://vine.co/v/${src}/embed/simple`;
|
||||
if (service === 'prezi') {
|
||||
return `https://prezi.com/embed/${src}/?bgcolor=ffffff&lock_to_path=0&autoplay=0&autohide_ctrls=0&`
|
||||
+ 'landing_data=bHVZZmNaNDBIWnNjdEVENDRhZDFNZGNIUE43MHdLNWpsdFJLb2ZHanI5N1lQVHkxSHFxazZ0UUNCRHloSXZROHh3PT0&'
|
||||
return `https://prezi.com/embed/${src}/?bgcolor=ffffff&lock_to_path=0&autoplay=0&autohide_ctrls=0&`
|
||||
+ 'landing_data=bHVZZmNaNDBIWnNjdEVENDRhZDFNZGNIUE43MHdLNWpsdFJLb2ZHanI5N1lQVHkxSHFxazZ0UUNCRHloSXZROHh3PT0&'
|
||||
+ 'landing_sign=1kD6c0N6aYpMUS0wxnQjxzSqZlEB8qNFdxtdjYhwSuI';
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
function pdfUrlKind(src: string) {
|
||||
const normalizedSrc = src.replace(/\s/g, '').replace(/\\/g, '/');
|
||||
if (/^data:application\/pdf(?:;[^,]*)?,/i.test(normalizedSrc)) return 'data';
|
||||
if (/^file:\/\//i.test(normalizedSrc)) return 'local';
|
||||
if (/^https?:\/\//i.test(normalizedSrc)) return 'external';
|
||||
if (normalizedSrc.startsWith('//') || /^[a-z][a-z\d+.-]*:/i.test(normalizedSrc)) return 'invalid';
|
||||
return 'local';
|
||||
}
|
||||
|
||||
declare module 'hydrooj' {
|
||||
interface ModuleInterfaces {
|
||||
richmedia: {
|
||||
@@ -95,21 +103,26 @@ declare module 'hydrooj' {
|
||||
export function Media(md: MarkdownIt, { pdfToolbar = false }: { pdfToolbar?: boolean } = {}) {
|
||||
const supported = ['youtube', 'vimeo', 'vine', 'prezi', 'bilibili', 'youku', 'msoffice'];
|
||||
md.renderer.rules.video = function tokenizeReturn(tokens, idx) {
|
||||
let src = md.utils.escapeHtml(tokens[idx].attrGet('src'));
|
||||
const src = tokens[idx].attrGet('src');
|
||||
const service = tokens[idx].attrGet('service').replace(/[^A-Z0-9]/gi, '').toLowerCase();
|
||||
if (Hydro?.module?.richmedia?.[service]) {
|
||||
const result = Hydro?.module?.richmedia[service].get(service, src, md);
|
||||
if (result) return result;
|
||||
}
|
||||
if (service === 'pdf') {
|
||||
if (['file://', './', '../'].some((i) => src.startsWith(i)) || (src[1] === '/' && src[2] !== '/')) src += src.includes('?') ? '&noDisposition=1' : '?noDisposition=1';
|
||||
const kind = pdfUrlKind(src);
|
||||
// A response with has content-disposition header causes the browser to download the file automatically.
|
||||
// As we cannot control response header from external sites, we block embedding external PDFs.
|
||||
else return `<p>Embedding an external PDF is no longer supported.</p> <a href="${_.escape(src)}">Download</a>`;
|
||||
if (kind === 'external') return `<p>Embedding an external PDF is no longer supported.</p> <a href="${md.utils.escapeHtml(src)}">Download</a>`;
|
||||
if (kind === 'invalid') return '<p>Embedding this PDF URL is not supported.</p>';
|
||||
const fragmentPos = src.indexOf('#');
|
||||
const pdfUrl = fragmentPos === -1 ? src : src.slice(0, fragmentPos);
|
||||
const fragment = fragmentPos === -1 ? '' : src.slice(fragmentPos);
|
||||
const pdfSrc = kind === 'data' ? src : `${pdfUrl}${pdfUrl.includes('?') ? '&' : '?'}noDisposition=1${fragment}`;
|
||||
return `\
|
||||
<object classid="clsid:${uuid().toUpperCase()}">
|
||||
<param name="SRC" value="${src}">
|
||||
<embed type="application/pdf" width="100%" style="min-height:100vh;border:none;" fullscreen="yes" src="${src}#toolbar=${pdfToolbar ? '0' : '1'}&navpanes=0&view=FitH">
|
||||
<param name="SRC" value="${md.utils.escapeHtml(pdfSrc)}">
|
||||
<embed type="application/pdf" width="100%" style="min-height:100vh;border:none;" fullscreen="yes" src="${md.utils.escapeHtml(`${pdfSrc}#toolbar=${pdfToolbar ? '0' : '1'}&navpanes=0&view=FitH`)}">
|
||||
<noembed></noembed>
|
||||
</embed>
|
||||
</object>`;
|
||||
@@ -117,7 +130,7 @@ export function Media(md: MarkdownIt, { pdfToolbar = false }: { pdfToolbar?: boo
|
||||
if (['url', 'video'].includes(service)) {
|
||||
return `\
|
||||
<video width="100%" controls>
|
||||
<source src="${src}" type="${src.endsWith('ogg') ? 'video/ogg' : 'video/mp4'}">
|
||||
<source src="${md.utils.escapeHtml(src)}" type="${src.endsWith('ogg') ? 'video/ogg' : 'video/mp4'}">
|
||||
Your browser doesn't support video tag.
|
||||
</video>`;
|
||||
}
|
||||
@@ -125,7 +138,7 @@ export function Media(md: MarkdownIt, { pdfToolbar = false }: { pdfToolbar?: boo
|
||||
return `\
|
||||
<iframe class="embed-responsive-item ${service}-player" type="text/html" \
|
||||
width="100%" style="min-height: 500px" ${allowFullScreen} \
|
||||
src="${resourceUrl(service, src, tokens[idx].attrGet('url'))}"
|
||||
src="${md.utils.escapeHtml(resourceUrl(service, src, tokens[idx].attrGet('url')))}"
|
||||
scrolling="no" border="0" frameborder="no" framespacing="0"></iframe>`;
|
||||
}
|
||||
return `<div data-${service}>${md.utils.escapeHtml(src)}</div>`;
|
||||
|
||||
Reference in new issue
Block a user