Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion platform/jewel/markdown/core/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jvm_library(
name = "core",
module_name = "intellij.platform.jewel.markdown.core",
visibility = ["//visibility:public"],
srcs = glob(["src/main/kotlin/**/*.kt", "src/main/kotlin/**/*.java", "src/main/kotlin/**/*.form"], allow_empty = True),
srcs = glob(["src/main/kotlin/**/*.kt", "src/main/kotlin/**/*.java", "src/main/kotlin/**/*.form", "src/testFixtures/kotlin/**/*.kt", "src/testFixtures/kotlin/**/*.java", "src/testFixtures/kotlin/**/*.form"], allow_empty = True),
resources = [":core_resources"],
kotlinc_opts = ":custom_core",
deps = [
Expand Down
33 changes: 32 additions & 1 deletion platform/jewel/markdown/core/api-dump-experimental.txt
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,39 @@
- a:getInlineContent():java.util.List
*:org.jetbrains.jewel.markdown.WithTextContent
- a:getContent():java.lang.String
*a:org.jetbrains.jewel.markdown.extensions.ImageRenderResult
- sf:$stable:I
*f:org.jetbrains.jewel.markdown.extensions.ImageRenderResult$Failed
- org.jetbrains.jewel.markdown.extensions.ImageRenderResult
- sf:$stable:I
- sf:INSTANCE:org.jetbrains.jewel.markdown.extensions.ImageRenderResult$Failed
- equals(java.lang.Object):Z
- hashCode():I
*f:org.jetbrains.jewel.markdown.extensions.ImageRenderResult$Loading
- org.jetbrains.jewel.markdown.extensions.ImageRenderResult
- sf:$stable:I
- <init>():V
- <init>(androidx.compose.foundation.text.InlineTextContent):V
- b:<init>(androidx.compose.foundation.text.InlineTextContent,I,kotlin.jvm.internal.DefaultConstructorMarker):V
- f:component1():androidx.compose.foundation.text.InlineTextContent
- f:copy(androidx.compose.foundation.text.InlineTextContent):org.jetbrains.jewel.markdown.extensions.ImageRenderResult$Loading
- bs:copy$default(org.jetbrains.jewel.markdown.extensions.ImageRenderResult$Loading,androidx.compose.foundation.text.InlineTextContent,I,java.lang.Object):org.jetbrains.jewel.markdown.extensions.ImageRenderResult$Loading
- equals(java.lang.Object):Z
- f:getContent():androidx.compose.foundation.text.InlineTextContent
- hashCode():I
*f:org.jetbrains.jewel.markdown.extensions.ImageRenderResult$Success
- org.jetbrains.jewel.markdown.extensions.ImageRenderResult
- sf:$stable:I
- <init>(androidx.compose.foundation.text.InlineTextContent):V
- f:component1():androidx.compose.foundation.text.InlineTextContent
- f:copy(androidx.compose.foundation.text.InlineTextContent):org.jetbrains.jewel.markdown.extensions.ImageRenderResult$Success
- bs:copy$default(org.jetbrains.jewel.markdown.extensions.ImageRenderResult$Success,androidx.compose.foundation.text.InlineTextContent,I,java.lang.Object):org.jetbrains.jewel.markdown.extensions.ImageRenderResult$Success
- equals(java.lang.Object):Z
- f:getContent():androidx.compose.foundation.text.InlineTextContent
- hashCode():I
*:org.jetbrains.jewel.markdown.extensions.ImageRendererExtension
- a:renderImageContent(org.jetbrains.jewel.markdown.InlineMarkdown$Image,androidx.compose.runtime.Composer,I):androidx.compose.foundation.text.InlineTextContent
- renderImage(org.jetbrains.jewel.markdown.InlineMarkdown$Image,androidx.compose.runtime.Composer,I):org.jetbrains.jewel.markdown.extensions.ImageRenderResult

Check warning on line 260 in platform/jewel/markdown/core/api-dump-experimental.txt

View workflow job for this annotation

GitHub Actions / Annotate breaking API changes with IJP dumps

Breaking experimental API change

This looks like a breaking API change, make sure it's intended.
- renderImageContent(org.jetbrains.jewel.markdown.InlineMarkdown$Image,androidx.compose.runtime.Composer,I):androidx.compose.foundation.text.InlineTextContent
*:org.jetbrains.jewel.markdown.extensions.MarkdownBlockProcessorExtension
- a:canProcess(org.commonmark.node.CustomBlock):Z
- a:processMarkdownBlock(org.commonmark.node.CustomBlock,org.jetbrains.jewel.markdown.processing.MarkdownProcessor):org.jetbrains.jewel.markdown.MarkdownBlock$CustomBlock
Expand Down
4 changes: 4 additions & 0 deletions platform/jewel/markdown/core/api-dump.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ f:org.jetbrains.jewel.markdown.MarkdownKt
f:org.jetbrains.jewel.markdown.MarkdownModeKt
f:org.jetbrains.jewel.markdown.MarkdownTextKt
f:org.jetbrains.jewel.markdown.SemanticsKt
f:org.jetbrains.jewel.markdown.TestThemeKt
- sf:CODE_TEXT_SIZE:I
- sf:createMarkdownStyling():org.jetbrains.jewel.markdown.rendering.MarkdownStyling
- sf:createThemeDefinition():org.jetbrains.jewel.foundation.theme.ThemeDefinition
f:org.jetbrains.jewel.markdown.extensions.MarkdownKt
f:org.jetbrains.jewel.markdown.processing.ProcessingUtilKt
f:org.jetbrains.jewel.markdown.rendering.ImageSourceResolverKt
Expand Down
4 changes: 4 additions & 0 deletions platform/jewel/markdown/core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
jewel
`jewel-check-public-api`
`java-test-fixtures`
alias(libs.plugins.composeDesktop)
alias(libs.plugins.compose.compiler)
}
Expand All @@ -10,6 +11,9 @@ dependencies {
api(libs.commonmark.core)
api(libs.jsoup)

testFixturesImplementation(projects.foundation)

testImplementation(testFixtures(project))
testImplementation(compose.desktop.uiTestJUnit4)
testImplementation(projects.ui)
testImplementation(compose.desktop.currentOs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/kotlin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/testFixtures/kotlin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/kotlin" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<excludeFolder url="file://$MODULE_DIR$/bin" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package org.jetbrains.jewel.markdown

import androidx.compose.runtime.Stable
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.jewel.foundation.ExperimentalJewelApi

/** An inline Markdown node that contains other [InlineMarkdown] nodes. */
@ApiStatus.Experimental
@ExperimentalJewelApi
@Stable
public interface WithInlineMarkdown {
/** Child inline Markdown nodes. */
public val inlineContent: List<InlineMarkdown>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.jetbrains.jewel.markdown.extensions

import androidx.compose.foundation.text.InlineTextContent
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.jewel.foundation.ExperimentalJewelApi
import org.jetbrains.jewel.markdown.InlineMarkdown
Expand All @@ -12,7 +13,7 @@ import org.jetbrains.jewel.markdown.InlineMarkdown
* Implement this interface to provide a custom renderer for images. This is useful for handling image loading from
* different sources (e.g., network, local files) or for applying custom visual treatments to images.
*
* The [renderImageContent] function will be called for each image found in the Markdown content.
* The [renderImage] function will be called for each image found in the Markdown content.
*/
@ApiStatus.Experimental
@ExperimentalJewelApi
Expand All @@ -21,7 +22,61 @@ public interface ImageRendererExtension {
* Renders an image from a Markdown document.
*
* @param image The image data, containing information like the image URL and alt text.
* @return An [InlineTextContent] that will be embedded in the text flow, which will be used to display the image.
* @return An [InlineTextContent] that will be embedded in the text flow, which will be used to display the image,
* or `null` if the image could not be loaded.
* @see renderImage
*/
@Composable public fun renderImageContent(image: InlineMarkdown.Image): InlineTextContent?
@Deprecated(
message = "Use renderImage instead, which provides explicit loading/success/failed states",
replaceWith = ReplaceWith("renderImage(image)"),
)
@Composable
public fun renderImageContent(image: InlineMarkdown.Image): InlineTextContent? = null

/**
* Renders an image from a Markdown document.
*
* Override this function to provide custom image rendering with explicit state handling. The default implementation
* delegates to the deprecated [renderImageContent] for backward compatibility.
*
* @param image The image data, containing information like the image URL and alt text.
* @return An [ImageRenderResult] indicating the current state of the image: [ImageRenderResult.Loading] while the
* image is being fetched, [ImageRenderResult.Success] with the content when loaded, or [ImageRenderResult.Failed]
* if loading failed.
*/
@Composable
public fun renderImage(image: InlineMarkdown.Image): ImageRenderResult {
@Suppress("DEPRECATION") val content = renderImageContent(image)
return if (content != null) {
ImageRenderResult.Success(content)
} else {
ImageRenderResult.Failed
}
}
}

/**
* Represents the result of rendering an image in Markdown.
*
* This sealed class allows callers to distinguish between loading, success, and failure states, enabling appropriate UI
* handling for each case (e.g., showing a loading indicator during loading, the image on success, or a fallback link on
* failure).
*/
@ApiStatus.Experimental
@ExperimentalJewelApi
@Immutable
public sealed class ImageRenderResult {
/**
* The image is currently loading.
*
* @param content Optional inline content to display while loading (e.g., a loading indicator). If null, the
* placeholder text from the markdown will be shown.
*/
public data class Loading(val content: InlineTextContent? = null) : ImageRenderResult()

/** The image loaded successfully. */
public data class Success(val content: InlineTextContent) : ImageRenderResult()

/** The image failed to load. */
public data object Failed : ImageRenderResult()
}
Loading
Loading