diff --git a/src/inscriptions/media.rs b/src/inscriptions/media.rs index de41de2571..bb30062066 100644 --- a/src/inscriptions/media.rs +++ b/src/inscriptions/media.rs @@ -18,6 +18,7 @@ pub(crate) enum Media { Markdown, Model, Pdf, + Source, Text, Unknown, Video, @@ -97,8 +98,8 @@ impl Media { ("model/gltf-binary", GENERIC, Model, &["glb"]), ("model/stl", GENERIC, Unknown, &["stl"]), ("text/css", TEXT, Code(Css), &["css"]), - ("text/html", TEXT, Iframe, &[]), - ("text/html;charset=utf-8", TEXT, Iframe, &["html"]), + ("text/html", TEXT, Source, &[]), + ("text/html;charset=utf-8", TEXT, Source, &["html"]), ("text/javascript", TEXT, Code(JavaScript), &["js"]), ("text/markdown", TEXT, Markdown, &[]), ("text/markdown;charset=utf-8", TEXT, Markdown, &["md"]), diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index ce8eaebea5..2e6c9a3d7e 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -10,7 +10,7 @@ use { templates::{ BlockHtml, BlocksHtml, ChildrenHtml, ClockSvg, CollectionsHtml, HomeHtml, InputHtml, InscriptionHtml, InscriptionsBlockHtml, InscriptionsHtml, OutputHtml, PageContent, PageHtml, - PreviewAudioHtml, PreviewCodeHtml, PreviewFontHtml, PreviewImageHtml, PreviewMarkdownHtml, + PreviewAudioHtml, PreviewCodeHtml, PreviewSourceHtml, PreviewFontHtml, PreviewImageHtml, PreviewMarkdownHtml, PreviewModelHtml, PreviewPdfHtml, PreviewTextHtml, PreviewUnknownHtml, PreviewVideoHtml, RangeHtml, RareTxt, RuneBalancesHtml, RuneHtml, RunesHtml, SatHtml, TransactionHtml, }, @@ -1378,6 +1378,18 @@ impl Server { ) .into_response(), ), + Media::Source => Ok( + ( + [( + header::CONTENT_SECURITY_POLICY, + "script-src-elem 'self' https://cdn.jsdelivr.net", + )], + PreviewSourceHtml { + inscription_id, + }, + ) + .into_response(), + ), Media::Font => Ok( ( [( diff --git a/src/templates.rs b/src/templates.rs index e0474c34a3..10ffe1fcc4 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -14,7 +14,7 @@ pub(crate) use { metadata::MetadataHtml, output::OutputHtml, preview::{ - PreviewAudioHtml, PreviewCodeHtml, PreviewFontHtml, PreviewImageHtml, PreviewMarkdownHtml, + PreviewAudioHtml, PreviewCodeHtml, PreviewFontHtml, PreviewSourceHtml, PreviewImageHtml, PreviewMarkdownHtml, PreviewModelHtml, PreviewPdfHtml, PreviewTextHtml, PreviewUnknownHtml, PreviewVideoHtml, }, range::RangeHtml, diff --git a/src/templates/preview.rs b/src/templates/preview.rs index 4dd9e5f21c..59fccbf9fa 100644 --- a/src/templates/preview.rs +++ b/src/templates/preview.rs @@ -11,7 +11,12 @@ pub(crate) struct PreviewCodeHtml { pub(crate) language: media::Language, } -#[derive(Boilerplate)] +#[derive(boilerplate::Boilerplate)] +pub(crate) struct PreviewSourceHtml { + pub(crate) inscription_id: InscriptionId, +} + +#[derive(boilerplate::Boilerplate)] pub(crate) struct PreviewFontHtml { pub(crate) inscription_id: InscriptionId, } diff --git a/static/preview-source.js b/static/preview-source.js new file mode 100644 index 0000000000..ab4efa888b --- /dev/null +++ b/static/preview-source.js @@ -0,0 +1,22 @@ + +const definition = await import(`https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11/build/es/languages/xml.min.js`); + +hljs.registerLanguage('xml', definition.default); + +const inscription = document.documentElement.dataset.inscription; + +const escapeHtml = (htmlCode) => { + return htmlCode + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +} + + +const response = await fetch(`/content/${inscription}`); +const text = await response.text(); +const code = document.querySelector('code'); + +code.innerHTML = escapeHtml(text) \ No newline at end of file diff --git a/templates/preview-source.html b/templates/preview-source.html new file mode 100644 index 0000000000..65a44c09da --- /dev/null +++ b/templates/preview-source.html @@ -0,0 +1,11 @@ + + + + + + + + +
+ +