-
-
Notifications
You must be signed in to change notification settings - Fork 466
Enabling Markdown for GristDocTour #1653
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me. Thank you very much!
I just wondered why the iframe were allowed in sanitizeTutorialHTML
. Sounds like it is required and used in the official tutorial to embed a Youtube video.
We will ask for an official review from Grist Labs.
app/client/ui/DocTour.ts
Outdated
import sortBy = require('lodash/sortBy'); | ||
import {marked} from "marked"; | ||
import {renderer} from 'app/client/ui/DocTutorialRenderer'; | ||
import {sanitizeTutorialHTML} from "./sanitizeHTML"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import {sanitizeTutorialHTML} from "./sanitizeHTML"; | |
import {sanitizeHTML} from "app/client/ui/sanitizeHTML"; |
You can use this variant instead, unless you need to tweak the default sanitization behavior, in which case you can just add a new variant like sanitizeTourHTML
.
If no tweaking is necessary, you can just use the markdown
helper from app/client/lib/markdown.ts
.
Minor lint: absolute module path is preferred over relative.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback, I'm going the new variant way with 'sanitizeTourHTML' (with absolute module path) to keep things clear and have the ability to embed videos as @fflorent noted earlier.
import {dom} from 'grainjs'; | ||
import sortBy = require('lodash/sortBy'); | ||
import {marked} from "marked"; | ||
import {renderer} from 'app/client/ui/DocTutorialRenderer'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import {renderer} from 'app/client/ui/DocTutorialRenderer'; | |
import {renderer} from 'app/client/ui/DocTourRenderer'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DocTourRenderer
isn't being imported here.
|
||
const bodyHtmlContent = sanitizeTutorialHTML(marked.parse(getValue("Body"), { | ||
async: false, renderer | ||
})); | ||
const element = document.createElement('div'); | ||
element.innerHTML = bodyHtmlContent; | ||
|
||
|
||
let body: HTMLElement = element; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can replace the dom('p', body),
below to something like dom('p', markdown(body)),
or dom('p', el => el.innerHTML = bodyHtmlContent)
, depending on whether you're using the markdown
helper or your own renderer. This way, you only need at most bodyHtmlContent
and none of the other changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @georgegevoian for the feedback.
I'm going to look into incorporating these changes and adding tests to check for MarkDown content rendering.
Thanks for the PR @ogui11aume. For tests, we'll work on moving some tour-related browser tests to this repo by next week. That way, you can test your changes against them and add a test. A test that asserts a tour containing Markdown text added the expected HTML to the DOM should be enough, but you're welcome to add more. |
Tests are now in grist-core: 2997ca8. |
391b30b
to
5c4f6a7
Compare
All contributors have signed the CLA ✍️ ✅ |
@ogui11aume 1) DocTour
should create correct popups from a GristDocTour table: You're modifications do not produce the same html has before, can you fix it ? An can you add the mail you're signing your commits with in your email account and verify it? you will need It to sign the new CLA. |
5c4f6a7
to
a3d0ab6
Compare
|
||
export const renderer = new marked.Renderer(); | ||
|
||
renderer.link = ({href, text}) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that the default marked.Renderer
allows arbitrary html, which potentially allows some phishing attacks. For example with <div style="position: fixed; color: red; inset: 0">Boo</div>
you can cover whole Grist layout and provide your own.
What do you think about reusing the renderer from app/client/ui/MarkdownCellRenderer.ts
? It clears out any html content.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used ALLOWED_TAGS with marked.Renderer in app/client/ui/sanitizeHTML.ts to limit abuse and only allow those HTML elements that have been tested (+ table).
- Agreed, this does not yet avoid the problem you described ( covering div ). To avoid the problem in your example, I would also need to limit the usage of style at least in div, should I go that far ?
- The problem with app/client/ui/MarkdownCellRenderer.ts is that, according to comment, it will not permit images or other HTML elements. So I didn't go that way.
* This does not support HTML or images in the markdown value, and renders those as text.
This does not support HTML or images in the markdown value, and renders those as text.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ogui11aume, what if we disallowed HTML for the time being?
renderer.html = ({raw}) => escape(raw);
Would there be an immediate need for tours to support arbitrary HTML?
Having a robust and shared sanitization approach across different UI components like tutorials, tours, etc. seems desirable, but could perhaps be reconciled later. (Tutorials in particular should probably also disallow HTML outside of the specific iframe that's permitted, but that's unrelated to your proposed changes.)
a3d0ab6
to
c8fb883
Compare
I have read the CLA Document and I hereby sign the CLA |
@ogui11aume Do you need our review again? |
1b18447
to
4c3ddcd
Compare
For my commits I have :
Most other Markdown extended syntax are not currently being rendered so I didn't create tests for them. Let me know if you thinki other tests would be useful. |
4c3ddcd
to
26d9687
Compare
Hi, please help ... |
Discussion regarding the changes gristlabs#1653 (comment)
Refactor using DOM_FRAGMENT like in sanitizeHTMLIntoDOM gristlabs#1653 (comment) and specify allowed HTML tags to limit abuse according to gristlabs#1653 (comment)
@ogui11aume The LeftPanel test is unstable, not related to your work (though I can't make it fail locally). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ogui11aume I don't seem to be able to make the test file fail locally (I ran the DocTour
tests 20 times with no failure).
Do you reproduce the failure on your side?
Hi @fflorent
With my latest commit, all tests pass. If you refer to my previous call for help then @georgegevoian suggested that the test was the wrong way around and I provided confirmation with the actual intended purpose of the test. I then fixed the problem 😄 .
What that the test failure you were trying to reproduce ? |
@ogui11aume I was trying to reproduce this failure your mentioned earlier: As Github collapses the resolved comments, I miss that point (I should be more vigilant next time). Anyway, glad you fixed the issue :) |
import {dom} from 'grainjs'; | ||
import sortBy = require('lodash/sortBy'); | ||
import {marked} from "marked"; | ||
import {renderer} from 'app/client/ui/DocTutorialRenderer'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DocTourRenderer
isn't being imported here.
if (!title && !(bodyValue.trim()) ) { | ||
return null; | ||
} | ||
//const bodyHtmlContent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
//const bodyHtmlContent |
|
||
export const renderer = new marked.Renderer(); | ||
|
||
renderer.link = ({href, text}) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ogui11aume, what if we disallowed HTML for the time being?
renderer.html = ({raw}) => escape(raw);
Would there be an immediate need for tours to support arbitrary HTML?
Having a robust and shared sanitization approach across different UI components like tutorials, tours, etc. seems desirable, but could perhaps be reconciled later. (Tutorials in particular should probably also disallow HTML outside of the specific iframe that's permitted, but that's unrelated to your proposed changes.)
Context
So far Grist only permits raw text to appear as a one-liner in modal during a document tour : not a very nice user experience for somebody to get a first impression of your super Grist document. 🙁
With Markdown, the document tours are much better:
Proposed solution
Technically :
Just parsing the
Body
cell fromGristDocTour
table with already availablemarked
library, sanitize and following the renderer approach to better select which aspect of markdown to render.Documentation : https://github.com/ogui11aume/hackdays2025/blob/ergonogrist/submissions/ergonogrist/assets/markdown-for-gristdoctour/deliverable1.md
Related issues
Didn't find any issue ( and I didn't open one although I made the change at the request of other users).
Has this been tested?
Screenshots / Screencasts
https://github.com/ogui11aume/hackdays2025/blob/ergonogrist/submissions/ergonogrist/assets/markdown-for-gristdoctour/deliverable1.md