Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .codegraph/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# CodeGraph data files — local to each machine, not for committing.
# Ignore everything in .codegraph/ except this file itself, so transient
# files (the database, daemon.pid, sockets, logs) never show up in git.
*
!.gitignore
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do 0.3.0 - 1.0 for JabRef 6.0

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I don't get what you want?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I change the version in changelog here or separate?

@Siedlerchr Siedlerchr Sep 17, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it back to 0.3.0


- Migrated the RichTextArea renderer to the JavaFX 27 incubator APIs.
- Baseline for JavaFX is jdk25 and thus this project now requires Java 25.

## [0.2.0] - 2026-07-22

### Added
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# html-to-node

[![APIdia](https://apidia.net/mvn/org.jabref/html-to-node/badge.svg)](https://apidia.net/mvn/org.jabref/html-to-node)

A JavaFX library that renders HTML as plain scene-graph nodes (`TextFlow`, `Text`, `ImageView`),
Expand All @@ -13,8 +14,8 @@ markup.

## Requirements

- Java 24 or later
- JavaFX 26 or later, provided by the consuming application: `javafx.base`, `javafx.graphics`,
- Java 25 or later
- JavaFX 27 or later, provided by the consuming application: `javafx.base`, `javafx.graphics`,
and — for the RichTextArea renderer — `javafx.controls`, `jfx.incubator.input`, and
`jfx.incubator.richtext`

Expand All @@ -30,7 +31,7 @@ Released versions are available from [Maven Central](https://central.sonatype.co

```kotlin
dependencies {
implementation("org.jabref:html-to-node:0.2.0")
implementation("org.jabref:html-to-node:0.3.0")
}
```

Expand Down
10 changes: 5 additions & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {
}

group = "org.jabref"
// -PversionSuffix=PR17 turns 0.3.0-SNAPSHOT into 0.3.0-PR17-SNAPSHOT, so a pull request
// -PversionSuffix=PR17 turns 1.0.0-SNAPSHOT into 1.0.0-PR17-SNAPSHOT, so a pull request
// snapshot is identifiable and does not clobber the one built from main
version = "0.3.0" + (findProperty("versionSuffix")?.let { "-$it" } ?: "") + "-SNAPSHOT"

Expand All @@ -23,13 +23,13 @@ java {
}

tasks.withType<JavaCompile>().configureEach {
// JavaFX 26 ships Java-24 class files; 24 keeps the library usable one release below JabRef's 25
options.release = 24
// JavaFX 27 baseline is now jdk 25
options.release = 25
options.encoding = "UTF-8"
}

// JavaFX artifacts are platform-specific; consumers provide their own JavaFX (hence compileOnly)
val javafxVersion = "26.0.1"
val javafxVersion = "27"
Comment thread
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.
val jfxPlatform = run {
val osName = System.getProperty("os.name").lowercase()
val arch = System.getProperty("os.arch").lowercase()
Expand Down Expand Up @@ -136,7 +136,7 @@ tasks.test {
}

// Tests of the RichTextArea renderer need the JavaFX toolkit: a display or xvfb-run
val guiTest by tasks.registering(Test::class) {
val guiTest = tasks.register<Test>("guiTest") {
Comment thread
Siedlerchr marked this conversation as resolved.
description = "Runs tests requiring the JavaFX toolkit (tag 'gui'); needs a display or xvfb-run"
group = "verification"
testClassesDirs = sourceSets.test.get().output.classesDirs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
public final class RichTextRenderer {

/// Character attribute carrying a link target; resolved on mouse click.
public static final StyleAttribute<String> HREF = new StyleAttribute<>("HREF", String.class, false);
public static final StyleAttribute<String> HREF = StyleAttribute.character("HREF", String.class);

/// Fallback link color; matches FxRenderer's un-themed link fill.
private static final Color LINK_COLOR = Color.web("#0b66c3");
Expand Down Expand Up @@ -98,7 +98,7 @@ public static void configure(RichTextArea area, HtmlRenderOptions options) {
if (position != null) {
// Node segments (embedded images, tables) carry no character attributes, so the
// model returns null there — only text runs can hold an HREF.
StyleAttributeMap attributes = area.getModel().getStyleAttributeMap(null, position);
StyleAttributeMap attributes = area.getStyleAttributeMap(position, false);
String href = attributes != null ? attributes.get(HREF) : null;
if (href != null) {
options.linkHandler().accept(href);
Expand All @@ -114,7 +114,7 @@ public static void configure(RichTextArea area, HtmlRenderOptions options) {
/// returns a null attribute map there — only text runs can hold an [#HREF]. Clicking an
/// image therefore lands on a null map, which this method tolerates.
public static @Nullable String hrefAt(StyledTextModel model, TextPos position) {
StyleAttributeMap attributes = model.getStyleAttributeMap(null, position);
StyleAttributeMap attributes = model.getStyleAttributeMap(null, position, false);
return attributes != null ? attributes.get(HREF) : null;
}

Expand Down
6 changes: 6 additions & 0 deletions src/test/java/org/jabref/htmltonode/HtmlRichTextAreaTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.jabref.htmltonode.rich.HtmlRichTextArea;
import org.jabref.htmltonode.rich.RichTextRenderer;

import jfx.incubator.scene.control.richtext.model.StyleAttribute;
import jfx.incubator.scene.control.richtext.model.StyleAttributeMap;
import jfx.incubator.scene.control.richtext.skin.CellContext;
import org.junit.jupiter.api.BeforeAll;
Expand Down Expand Up @@ -62,6 +63,11 @@ public StyleAttributeMap getAttributes() {
return StyleAttributeMap.builder().build();
}

@Override
public <T> void decorateRun(StyleAttribute<T> attribute, RunDecor type, String styleName) {
// Decorations are not involved in the cursor-style handler under test.
}

String style() {
return style.toString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
@Tag("gui")
class RichTextAreaSpikeTest {

private static final StyleAttribute<String> HREF = new StyleAttribute<>("HREF", String.class, false);
private static final StyleAttribute<String> HREF = StyleAttribute.character("HREF", String.class);

@BeforeAll
static void startToolkit() throws InterruptedException {
Expand Down Expand Up @@ -83,7 +83,7 @@ void styledModelCarriesSegmentsHighlightsAndCustomAttributes() {
assertEquals("Kopp, O.: Some Paper", model.getPlainText(0));
assertEquals("doi.org/10.1/x", model.getPlainText(1));

StyleAttributeMap linkAttrs = model.getStyleAttributeMap(null, jfx.incubator.scene.control.richtext.TextPos.ofLeading(1, 3));
StyleAttributeMap linkAttrs = model.getStyleAttributeMap(null, jfx.incubator.scene.control.richtext.TextPos.ofLeading(1, 3), false);
assertEquals("https://doi.org/10.1/x", linkAttrs.get(HREF));
assertEquals(Boolean.TRUE, linkAttrs.get(StyleAttributeMap.UNDERLINE));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ private static StyledTextModel model(String html) {
}

private static StyleAttributeMap attributesAt(StyledTextModel model, int paragraph, int offset) {
return model.getStyleAttributeMap(null, TextPos.ofLeading(paragraph, offset));
return model.getStyleAttributeMap(null, TextPos.ofLeading(paragraph, offset), false);
}

@Test
Expand Down