-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
[JEWEL-746] Load inline markdown images using Coil3 #2924
base: master
Are you sure you want to change the base?
Conversation
b0ba3c3
to
7fdb5ac
Compare
They look like entirely different images... Are you sure it's the same image it's being displayed, and that it's loading correctly in the first case? That to me looks like a "broken image" placeholder (which also is way too big) SVG files have an intrinsic size declared in their root node, and any renderer should adhere to that |
images I posted earlier are examples of how JCEF renders my "README.md" which this is how compose shows the same things: |
I see. I had misinterpreted the original message, sorry 🙏 The first image (the broken square) has a declared size of 800x800 px, encoded as As for the latter, I think it's because the text for whatever reason just doesn't get rendered: <g text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
<use x="5.5" y="2" fill="#010101" fill-opacity=".3" href="#logo" />
<use x="5.5" y="1" fill="#fff" href="#logo" />
<text x="40.5" y="15" fill="#010101" fill-opacity=".3">build</text>
<text x="40.5" y="14" fill="#fff">build</text>
<text x="83.5" y="15" fill="#010101" fill-opacity=".3">passing</text>
<text x="83.5" y="14" fill="#fff">passing</text>
</g> Again, possibly some unsupported value in there that Skia ignores. That's sort of weird since Skia can interpret image sizes with units, and render text — it does in Chrome! But maybe there is some setup that is missing, or Chrome does some magic stuff. Either way, these are either CMP or Skiko bugs :) |
I'm going to create a separate issue for SVG regressions. Should it go to youtrack? |
.../core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/DefaultMarkdownBlockRenderer.kt
Outdated
Show resolved
Hide resolved
Please, no. Stick with GH until further notice. You'll know together with everyone else when YT is usable. We're still waiting. |
@@ -76,6 +80,7 @@ public fun Markdown( | |||
markdownStyling: MarkdownStyling = JewelTheme.markdownStyling, | |||
blockRenderer: MarkdownBlockRenderer = DefaultMarkdownBlockRenderer(markdownStyling), | |||
) { | |||
setSingletonImageLoaderFactory(::createImageLoader) |
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.
Does this belong here? It feels like it's init code, so having it once only (e.g., in ProvideMarkdownStyling
?) would make more sense to me
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.
ProvideMarkdownStyling
is in a different module and it's not guaranteed that a user will wrap Markdown into a style provider, so it may be confusing for debugging.
Will it attempt to invoke this code on each rerender or on each markdown usage in the app? I don't mind moving it somewhere, I just haven't figured out how exactly.
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.
Will it attempt to invoke this code on each rerender or on each markdown usage in the app?
It won't attempt to invoke, it will invoke it. That's why I'm saying it'd make more sense to do it elsewhere. I think we should even consider not using a singleton factory since users may want to use different ones; can we create one that we store in a composition local, and set it up in ProvideMarkdownStyling?
We can instruct users to use ProvideMarkdownStyling in the error message for when the composition local is not set up, like we do for other mandatory composition locals.
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.
In the message, I assume you're referring to invocation on each markdown usage?
The code itself is checking if an image loader already set before using compareAndSet to invoke a factory. I've set a debugger to see what's going on there. I assume one defererence on each markdown frame is not bad and I still don't completely follow the ProvideMarkdownStyling
approach.
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 assume one defererence on each markdown frame is not bad
Yeah, that's ok, thanks for clarifying. But it's not my main concern. What happens if this is used in a context where the user has set their own loader? Seems to me like setting up a singleton image loader sets some expectations on our part that could be broken if the user had already done the same, with a different loader.
It also feels like we're leaking the loader outside Jewel, which is not very good either. We might be causing problems for our users because they expect to be able to set their own singleton IL, and it doesn't do anything if any Markdown composable just happened to be composed before then.
Is there no way to use composition locals to have a Jewel-only image loader that does not leak externally, and that we know we can trust? Of course, users can override it, but it's fine if they do it knowingly. It's the magical, undocumented side effect that is not acceptable.
platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/Markdown.kt
Show resolved
Hide resolved
...l/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/processing/MarkdownProcessor.kt
Outdated
Show resolved
Hide resolved
...core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/DefaultInlineMarkdownRenderer.kt
Outdated
Show resolved
Hide resolved
.../core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/DefaultMarkdownBlockRenderer.kt
Outdated
Show resolved
Hide resolved
.../core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/DefaultMarkdownBlockRenderer.kt
Outdated
Show resolved
Hide resolved
.../core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/DefaultMarkdownBlockRenderer.kt
Outdated
Show resolved
Hide resolved
.../core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/DefaultMarkdownBlockRenderer.kt
Show resolved
Hide resolved
Out of curiosity, have you filed the issues for SVG rendering? I think the size one is caused by https://github.com/coil-kt/coil/blob/main/coil-svg/src/commonMain/kotlin/coil3/svg/SvgDecoder.kt#L39 this parameter being true by default. Ideally, users should be able to override the Coil loader with one they want, but we can keep it for a follow up (it'd be nice to have an issue tracking this in our YouTrack, if you can file it). The text one is the more baffling one. If you can look into it, maybe you can figure out what is the cause, or at least where it should happen, and file an issue for that in the right place. |
@obask ping |
Thanks for doing initial investigation. I filed a tracking issue, but not the one in a coil repository yet. |
97a2f31
to
96b68a0
Compare
It supports every image as an inline node; Using built-in coroutine library and ktor2 from the platform; Added SVG support using a coil dependency.
It supports every image as an inline node