From a16100895ce28850c8e77a56167ac66c76d9f820 Mon Sep 17 00:00:00 2001 From: Eloc <42568538+elocremarc@users.noreply.github.com> Date: Sat, 12 Aug 2023 14:20:50 -0700 Subject: [PATCH 01/14] preview-markdown init --- src/media.rs | 5 +++-- src/subcommand/server.rs | 35 ++++++++++++++++++++++++++++++++- src/templates/preview.rs | 5 +++++ static/preview-markdown.js | 15 ++++++++++++++ templates/preview-markdown.html | 10 ++++++++++ 5 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 static/preview-markdown.js create mode 100644 templates/preview-markdown.html diff --git a/src/media.rs b/src/media.rs index 7f4647b8a3..7af1c66e8d 100644 --- a/src/media.rs +++ b/src/media.rs @@ -11,6 +11,7 @@ pub(crate) enum Media { Image, Model, Pdf, + Markdown, Text, Unknown, Video, @@ -40,8 +41,8 @@ impl Media { ("text/html", Media::Iframe, &[]), ("text/html;charset=utf-8", Media::Iframe, &["html"]), ("text/javascript", Media::Text, &["js"]), - ("text/markdown", Media::Text, &[]), - ("text/markdown;charset=utf-8", Media::Text, &["md"]), + ("text/markdown", Media::Markdown, &[]), + ("text/markdown;charset=utf-8", Media::Markdown, &["md"]), ("text/plain", Media::Text, &[]), ("text/plain;charset=utf-8", Media::Text, &["txt"]), ("video/mp4", Media::Video, &["mp4"]), diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index 7ca59b7714..49cae5417c 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -10,7 +10,7 @@ use { crate::templates::{ BlockHtml, ClockSvg, HomeHtml, InputHtml, InscriptionHtml, InscriptionJson, InscriptionsBlockHtml, InscriptionsHtml, InscriptionsJson, OutputHtml, OutputJson, PageContent, - PageHtml, PreviewAudioHtml, PreviewImageHtml, PreviewModelHtml, PreviewPdfHtml, + PageHtml, PreviewAudioHtml, PreviewImageHtml, PreviewModelHtml, PreviewPdfHtml, PreviewMarkdownHtml, PreviewTextHtml, PreviewUnknownHtml, PreviewVideoHtml, RangeHtml, RareTxt, SatHtml, SatJson, TransactionHtml, }, @@ -963,6 +963,16 @@ impl Server { ) .into_response(), ), + Media::Markdown => Ok( + ( + [( + header::CONTENT_SECURITY_POLICY, + "default-src 'self' https://cdn.jsdelivr.net", + )], + PreviewMarkdownHtml { inscription_id }, + ) + .into_response(), + ), Media::Text => { let content = inscription .body() @@ -2558,6 +2568,29 @@ mod tests { ); } + #[test] + fn markdown_preview() { + let server = TestServer::new_with_regtest(); + server.mine_blocks(1); + + let txid = server.bitcoin_rpc_server.broadcast_tx(TransactionTemplate { + inputs: &[(1, 0, 0)], + witness: inscription("text/markdown", "hello").to_witness(), + ..Default::default() + }); + let inscription_id = InscriptionId::from(txid); + + server.mine_blocks(1); + + server.assert_response_regex( + format!("/preview/{inscription_id}"), + StatusCode::OK, + format!(r".*
.*"), + ); + } + + + #[test] fn image_preview() { let server = TestServer::new_with_regtest(); diff --git a/src/templates/preview.rs b/src/templates/preview.rs index 74cb0261dd..93e07246cf 100644 --- a/src/templates/preview.rs +++ b/src/templates/preview.rs @@ -20,6 +20,11 @@ pub(crate) struct PreviewPdfHtml { pub(crate) inscription_id: InscriptionId, } +#[derive(boilerplate::Boilerplate)] +pub(crate) struct PreviewMarkdownHtml { + pub(crate) inscription_id: InscriptionId, +} + #[derive(boilerplate::Boilerplate)] pub(crate) struct PreviewTextHtml<'a> { pub(crate) text: &'a str, diff --git a/static/preview-markdown.js b/static/preview-markdown.js new file mode 100644 index 0000000000..f5e886f14d --- /dev/null +++ b/static/preview-markdown.js @@ -0,0 +1,15 @@ +import marked from 'https://cdn.jsdelivr.net/npm/marked/marked.min.js'; + +async function renderMarkdown() { + const contentDiv = document.getElementById('content'); + + const inscriptionId = contentDiv.dataset.inscription; + const response = await fetch(`/content/${inscriptionId}`); + const markdownContent = await response.text(); + + const htmlContent = marked.parse(markdownContent); + + contentDiv.innerHTML = htmlContent; +} + +window.addEventListener('DOMContentLoaded', renderMarkdown); diff --git a/templates/preview-markdown.html b/templates/preview-markdown.html new file mode 100644 index 0000000000..e26d4e908b --- /dev/null +++ b/templates/preview-markdown.html @@ -0,0 +1,10 @@ + + + + + + + + + + From bf353b86faf670c74ea91e2d22db7efe95aa5b9a Mon Sep 17 00:00:00 2001 From: Eloc <42568538+elocremarc@users.noreply.github.com> Date: Sun, 3 Sep 2023 21:29:34 -0700 Subject: [PATCH 02/14] Fixed build, added Dompurify, Marked working --- src/subcommand/server.rs | 6 +++--- src/templates.rs | 2 +- static/preview-markdown.css | 4 ++++ static/preview-markdown.js | 11 ++++++----- templates/preview-markdown.html | 3 ++- 5 files changed, 16 insertions(+), 10 deletions(-) create mode 100644 static/preview-markdown.css diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index 49cae5417c..555517880f 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -966,9 +966,9 @@ impl Server { Media::Markdown => Ok( ( [( - header::CONTENT_SECURITY_POLICY, - "default-src 'self' https://cdn.jsdelivr.net", - )], + header::CONTENT_SECURITY_POLICY, + "script-src-elem 'self' https://cdn.jsdelivr.net", + )], PreviewMarkdownHtml { inscription_id }, ) .into_response(), diff --git a/src/templates.rs b/src/templates.rs index 7df7f4442a..11f3fdc9e9 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -12,7 +12,7 @@ pub(crate) use { output::{OutputHtml, OutputJson}, page_config::PageConfig, preview::{ - PreviewAudioHtml, PreviewImageHtml, PreviewModelHtml, PreviewPdfHtml, PreviewTextHtml, + PreviewAudioHtml, PreviewImageHtml, PreviewModelHtml, PreviewPdfHtml, PreviewMarkdownHtml, PreviewTextHtml, PreviewUnknownHtml, PreviewVideoHtml, }, range::RangeHtml, diff --git a/static/preview-markdown.css b/static/preview-markdown.css new file mode 100644 index 0000000000..ed33c23dec --- /dev/null +++ b/static/preview-markdown.css @@ -0,0 +1,4 @@ + html { + color: #98a3ad; + background-color: #131516; +} diff --git a/static/preview-markdown.js b/static/preview-markdown.js index f5e886f14d..3db35bc680 100644 --- a/static/preview-markdown.js +++ b/static/preview-markdown.js @@ -1,15 +1,16 @@ -import marked from 'https://cdn.jsdelivr.net/npm/marked/marked.min.js'; +import { marked } from 'https://cdn.jsdelivr.net/npm/marked@8.0.0/+esm' +import DOMPurify from 'https://cdn.jsdelivr.net/npm/dompurify@3.0.5/+esm' async function renderMarkdown() { const contentDiv = document.getElementById('content'); const inscriptionId = contentDiv.dataset.inscription; const response = await fetch(`/content/${inscriptionId}`); - const markdownContent = await response.text(); + const rawMarkdown = await response.text(); - const htmlContent = marked.parse(markdownContent); - - contentDiv.innerHTML = htmlContent; + const html = DOMPurify.sanitize(marked.parse(rawMarkdown)); + + contentDiv.innerHTML = html; } window.addEventListener('DOMContentLoaded', renderMarkdown); diff --git a/templates/preview-markdown.html b/templates/preview-markdown.html index e26d4e908b..9d608a77c9 100644 --- a/templates/preview-markdown.html +++ b/templates/preview-markdown.html @@ -2,9 +2,10 @@ - + + From 5c75775e6d0c2a01b6d1850432f7205689e94635 Mon Sep 17 00:00:00 2001 From: Eloc <42568538+elocremarc@users.noreply.github.com> Date: Sun, 3 Sep 2023 23:03:17 -0700 Subject: [PATCH 03/14] Fix lint issue --- src/subcommand/server.rs | 38 ++++++++++++++++----------------- src/templates.rs | 4 ++-- static/preview-markdown.js | 3 ++- templates/preview-markdown.html | 10 ++++----- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index 555517880f..9e2a1b82eb 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -10,9 +10,9 @@ use { crate::templates::{ BlockHtml, ClockSvg, HomeHtml, InputHtml, InscriptionHtml, InscriptionJson, InscriptionsBlockHtml, InscriptionsHtml, InscriptionsJson, OutputHtml, OutputJson, PageContent, - PageHtml, PreviewAudioHtml, PreviewImageHtml, PreviewModelHtml, PreviewPdfHtml, PreviewMarkdownHtml, - PreviewTextHtml, PreviewUnknownHtml, PreviewVideoHtml, RangeHtml, RareTxt, SatHtml, SatJson, - TransactionHtml, + PageHtml, PreviewAudioHtml, PreviewImageHtml, PreviewMarkdownHtml, PreviewModelHtml, + PreviewPdfHtml, PreviewTextHtml, PreviewUnknownHtml, PreviewVideoHtml, RangeHtml, RareTxt, + SatHtml, SatJson, TransactionHtml, }, axum::{ body, @@ -966,9 +966,9 @@ impl Server { Media::Markdown => Ok( ( [( - header::CONTENT_SECURITY_POLICY, - "script-src-elem 'self' https://cdn.jsdelivr.net", - )], + header::CONTENT_SECURITY_POLICY, + "script-src-elem 'self' https://cdn.jsdelivr.net", + )], PreviewMarkdownHtml { inscription_id }, ) .into_response(), @@ -2572,24 +2572,22 @@ mod tests { fn markdown_preview() { let server = TestServer::new_with_regtest(); server.mine_blocks(1); - + let txid = server.bitcoin_rpc_server.broadcast_tx(TransactionTemplate { - inputs: &[(1, 0, 0)], - witness: inscription("text/markdown", "hello").to_witness(), - ..Default::default() - }); - let inscription_id = InscriptionId::from(txid); - + inputs: &[(1, 0, 0)], + witness: inscription("text/markdown", "hello").to_witness(), + ..Default::default() + }); + let inscription_id = InscriptionId { txid, index: 0 }; + server.mine_blocks(1); - + server.assert_response_regex( - format!("/preview/{inscription_id}"), - StatusCode::OK, - format!(r".*.*"), - ); + format!("/preview/{inscription_id}"), + StatusCode::OK, + format!(r".*.*"), + ); } - - #[test] fn image_preview() { diff --git a/src/templates.rs b/src/templates.rs index 11f3fdc9e9..7967b7dffa 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -12,8 +12,8 @@ pub(crate) use { output::{OutputHtml, OutputJson}, page_config::PageConfig, preview::{ - PreviewAudioHtml, PreviewImageHtml, PreviewModelHtml, PreviewPdfHtml, PreviewMarkdownHtml, PreviewTextHtml, - PreviewUnknownHtml, PreviewVideoHtml, + PreviewAudioHtml, PreviewImageHtml, PreviewMarkdownHtml, PreviewModelHtml, PreviewPdfHtml, + PreviewTextHtml, PreviewUnknownHtml, PreviewVideoHtml, }, range::RangeHtml, rare::RareTxt, diff --git a/static/preview-markdown.js b/static/preview-markdown.js index 3db35bc680..10f38d91b8 100644 --- a/static/preview-markdown.js +++ b/static/preview-markdown.js @@ -2,7 +2,8 @@ import { marked } from 'https://cdn.jsdelivr.net/npm/marked@8.0.0/+esm' import DOMPurify from 'https://cdn.jsdelivr.net/npm/dompurify@3.0.5/+esm' async function renderMarkdown() { - const contentDiv = document.getElementById('content'); + const divElements = document.getElementsByTagName('div'); + const contentDiv = divElements[0]; const inscriptionId = contentDiv.dataset.inscription; const response = await fetch(`/content/${inscriptionId}`); diff --git a/templates/preview-markdown.html b/templates/preview-markdown.html index 9d608a77c9..77d9051917 100644 --- a/templates/preview-markdown.html +++ b/templates/preview-markdown.html @@ -1,11 +1,11 @@ - + - - + + - - + + From 5382ab61f96130843dc50dd3bb27fab4289395a7 Mon Sep 17 00:00:00 2001 From: Eloc <42568538+elocremarc@users.noreply.github.com> Date: Mon, 4 Sep 2023 00:33:32 -0700 Subject: [PATCH 04/14] update recursion.md for markdown --- docs/src/inscriptions/recursion.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/src/inscriptions/recursion.md b/docs/src/inscriptions/recursion.md index d11e1bef99..f80f013824 100644 --- a/docs/src/inscriptions/recursion.md +++ b/docs/src/inscriptions/recursion.md @@ -20,6 +20,10 @@ This has a number of interesting use-cases: inscribed as individual images, or in a shared texture atlas, and then combined, collage-style, in unique combinations in multiple inscriptions. +- Markdown documents that reference other inscriptions + - Images: `![alt text](/content/