+
Skip to content

Conversation

arendjr
Copy link
Contributor

@arendjr arendjr commented Sep 23, 2025

Summary

This adds the ability to format <script type="importmap"> and <script type="application/json> tags in HTML files.

Contains minor refactoring to make it a little easier to add additional languages. Embedded nodes are now also collected in a single pass over the source tree, instead of one per embedded language.

Test Plan

Added a test. The rest should stay green.

Docs

@ematipico Does this require a changeset? I'm not sure to which extend the HTML formatting is stable yet...

Copy link

changeset-bot bot commented Sep 23, 2025

⚠️ No Changeset found

Latest commit: 0821738

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions github-actions bot added A-Project Area: project A-Parser Area: parser A-Formatter Area: formatter L-JSON Language: JSON and super languages L-HTML Language: HTML labels Sep 23, 2025
}

#[test]
fn test_is_javascript_tag() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved these tests from biome_html_syntax, because having the tests in that crate depend on biome_html_parser created a circular dependency.

let documents = self.documents.pin();

documents
fn get_parse_with_embedded_format_nodes(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I created a combined method for this, so that we only need to do a single Papaya lookup to retrieve both the parsed tree and the embedded nodes.

Copy link
Contributor

coderabbitai bot commented Sep 23, 2025

Walkthrough

This PR centralises script-type handling and embedded content across the repo: adds ScriptType and script-type helpers, introduces JsonScript/offset-aware JSON types and formatting (JsonSyntaxNodeWithOffset, JsonOffsetParse, new formatter entry), replaces per-language embedded structs with generic EmbeddedContent and EmbeddedLanguageSnippets, updates workspace/server flows and exports, swaps is_javascript_tag checks for is_supported_script_tag at call sites, and removes unnecessary clones in formatter transform calls. Tests and Cargo dev-deps adjusted accordingly.

Possibly related PRs

Suggested reviewers

  • dyc3
  • ematipico

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title "feat: implemented embedded JSON parsing" is concise and accurately reflects the primary change in the changeset — adding embedded JSON/importmap parsing and related formatting/refactor work — so it correctly summarises the main intent for reviewers.
Description Check ✅ Passed The PR description accurately summarises the work (formatting importmap/application/json script tags, single-pass embedded-node collection refactor, and a new test) and is directly related to the changes in the diff, so it meets the lenient description criteria.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/biome_formatter/src/lib.rs (1)

449-451: IndentWidth error docs/bounds reference the wrong type (copy/paste slip).

Docstring says LineWidth/u16 and Display uses LineWidth::{MIN,MAX}; should be IndentWidth/u8.

Apply:

-/// Error type returned when converting a u16 to a [LineWidth] fails
+/// Error type returned when converting a u8 to an [IndentWidth] fails
 #[derive(Clone, Copy, Debug)]
 pub struct IndentWidthFromIntError(pub u8);

 impl std::fmt::Display for IndentWidthFromIntError {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         writeln!(
             f,
             "The indent width should be between {} and {}, got {}",
-            LineWidth::MIN,
-            LineWidth::MAX,
+            IndentWidth::MIN,
+            IndentWidth::MAX,
             self.0,
         )
     }
 }

Also applies to: 453-463

🧹 Nitpick comments (5)
crates/biome_html_syntax/src/script_type.rs (1)

30-45: Normalise MIME values; treat +json as JSON and ignore parameters

Real‑world type values often include parameters (e.g. application/json; charset=utf-8) or JSON subtypes (e.g. application/ld+json). Trim, strip params, and recognise +json subtypes. Also consider text/ecmascript as classic JS.

Apply this diff:

 pub fn from_type_value(type_value: &str) -> Self {
-        if type_value.eq_ignore_ascii_case("module") {
+        // Normalise: trim and drop parameters after ';'
+        let mime = type_value.split(';').next().unwrap_or(type_value).trim();
+
+        if mime.eq_ignore_ascii_case("module") {
             Self::Module
-        } else if type_value.eq_ignore_ascii_case("text/javascript")
-            || type_value.eq_ignore_ascii_case("application/javascript")
-            || type_value.eq_ignore_ascii_case("application/ecmascript")
+        } else if mime.eq_ignore_ascii_case("text/javascript")
+            || mime.eq_ignore_ascii_case("application/javascript")
+            || mime.eq_ignore_ascii_case("application/ecmascript")
+            || mime.eq_ignore_ascii_case("text/ecmascript")
         {
             Self::Classic
-        } else if type_value.eq_ignore_ascii_case("importmap") {
+        } else if mime.eq_ignore_ascii_case("importmap") {
             Self::ImportMap
-        } else if type_value.eq_ignore_ascii_case("application/json") {
+        } else if mime.eq_ignore_ascii_case("application/json") || mime.to_ascii_lowercase().ends_with("+json") {
             Self::JSON
         } else {
             Self::Unsupported
         }
     }
crates/biome_html_syntax/src/element_ext.rs (1)

132-154: Tiny DRY: factor tag-name check helper

is_style_tag and is_script_tag duplicate the same token extraction. Consider a small helper like fn has_tag_name(&self, name: &str) -> bool and reuse it.

crates/biome_service/src/file_handlers/html.rs (1)

300-343: Nit: function name reads redundantly

parse_embedded_js_script is a bit tautological. parse_embedded_js would do.

crates/biome_service/src/workspace/document.rs (1)

99-124: Docs reference JavaScript in a generic type

EmbeddedContent<L> comments still talk about JavaScript. Reword to be language‑agnostic to avoid confusion.

Apply this diff to the doc comments:

-/// Represents embedded content extracted from HTML documents.
-///
-/// This struct stores parsing metadata and provides access to the parsed
-/// content with offset-aware positioning to maintain correct source locations.
+/// Represents embedded content extracted from HTML documents.
+///
+/// Stores parsing metadata and provides access to the parsed content
+/// with offset-aware positioning to maintain correct source locations.
@@
-    /// The JavaScript source code extracted from the script element.
+    /// The embedded source code extracted from the element.
@@
-    /// The range of the entire script element in the HTML document,
-    /// including the opening and closing tags.
+    /// The range of the entire element in the HTML document,
+    /// including opening/closing tags.
@@
-    /// The range of just the JavaScript content within the script element,
-    /// excluding the script tags themselves.
+    /// The range of just the embedded content within the element,
+    /// excluding the tags themselves.
@@
-    /// The offset where the JavaScript content starts in the parent document.
-    /// This is used for offset-aware parsing.
+    /// The offset where the embedded content starts in the parent document
+    /// (used for offset-aware parsing).
crates/biome_service/src/workspace/server.rs (1)

526-526: Prefer explicit imports over wildcard inside function.

Importing parse_embedded_js_script/parse_embedded_json/parse_embedded_style explicitly (at module scope) avoids pulling in unrelated items and improves grep-ability.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ab8b6c and ee3988c.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock and included by **
📒 Files selected for processing (16)
  • crates/biome_formatter/src/lib.rs (2 hunks)
  • crates/biome_html_formatter/src/html/auxiliary/element.rs (1 hunks)
  • crates/biome_html_formatter/src/html/auxiliary/embedded_content.rs (1 hunks)
  • crates/biome_html_parser/tests/spec_tests.rs (1 hunks)
  • crates/biome_html_syntax/Cargo.toml (0 hunks)
  • crates/biome_html_syntax/src/element_ext.rs (3 hunks)
  • crates/biome_html_syntax/src/lib.rs (1 hunks)
  • crates/biome_html_syntax/src/script_type.rs (1 hunks)
  • crates/biome_json_formatter/src/lib.rs (2 hunks)
  • crates/biome_json_parser/src/lib.rs (3 hunks)
  • crates/biome_json_syntax/src/syntax_node.rs (1 hunks)
  • crates/biome_service/src/file_handlers/html.rs (4 hunks)
  • crates/biome_service/src/workspace.rs (1 hunks)
  • crates/biome_service/src/workspace/document.rs (5 hunks)
  • crates/biome_service/src/workspace/server.rs (7 hunks)
  • crates/biome_service/src/workspace/server.tests.rs (3 hunks)
💤 Files with no reviewable changes (1)
  • crates/biome_html_syntax/Cargo.toml
🧰 Additional context used
📓 Path-based instructions (6)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_html_syntax/src/lib.rs
  • crates/biome_html_syntax/src/script_type.rs
  • crates/biome_html_parser/tests/spec_tests.rs
  • crates/biome_json_formatter/src/lib.rs
  • crates/biome_html_formatter/src/html/auxiliary/element.rs
  • crates/biome_html_syntax/src/element_ext.rs
  • crates/biome_json_syntax/src/syntax_node.rs
  • crates/biome_html_formatter/src/html/auxiliary/embedded_content.rs
  • crates/biome_json_parser/src/lib.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_html_syntax/src/lib.rs
  • crates/biome_html_syntax/src/script_type.rs
  • crates/biome_html_parser/tests/spec_tests.rs
  • crates/biome_json_formatter/src/lib.rs
  • crates/biome_formatter/src/lib.rs
  • crates/biome_html_formatter/src/html/auxiliary/element.rs
  • crates/biome_service/src/workspace.rs
  • crates/biome_html_syntax/src/element_ext.rs
  • crates/biome_json_syntax/src/syntax_node.rs
  • crates/biome_service/src/file_handlers/html.rs
  • crates/biome_html_formatter/src/html/auxiliary/embedded_content.rs
  • crates/biome_json_parser/src/lib.rs
  • crates/biome_service/src/workspace/server.rs
  • crates/biome_service/src/workspace/document.rs
  • crates/biome_service/src/workspace/server.tests.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_html_syntax/src/lib.rs
  • crates/biome_html_syntax/src/script_type.rs
  • crates/biome_html_parser/tests/spec_tests.rs
  • crates/biome_json_formatter/src/lib.rs
  • crates/biome_formatter/src/lib.rs
  • crates/biome_html_formatter/src/html/auxiliary/element.rs
  • crates/biome_service/src/workspace.rs
  • crates/biome_html_syntax/src/element_ext.rs
  • crates/biome_json_syntax/src/syntax_node.rs
  • crates/biome_service/src/file_handlers/html.rs
  • crates/biome_html_formatter/src/html/auxiliary/embedded_content.rs
  • crates/biome_json_parser/src/lib.rs
  • crates/biome_service/src/workspace/server.rs
  • crates/biome_service/src/workspace/document.rs
  • crates/biome_service/src/workspace/server.tests.rs
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_html_parser/tests/spec_tests.rs
crates/biome_service/src/workspace.rs

📄 CodeRabbit inference engine (crates/biome_service/CONTRIBUTING.md)

Implement the Workspace trait in src/workspace.rs

Files:

  • crates/biome_service/src/workspace.rs
crates/biome_service/src/workspace/server.rs

📄 CodeRabbit inference engine (crates/biome_service/CONTRIBUTING.md)

Use WorkspaceServer (src/workspace/server.rs) to maintain workspace state in daemon and CLI daemonless modes

Files:

  • crates/biome_service/src/workspace/server.rs
🧠 Learnings (23)
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors

Applied to files:

  • crates/biome_html_syntax/src/lib.rs
  • crates/biome_html_syntax/src/script_type.rs
  • crates/biome_html_syntax/src/element_ext.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/src/cst.rs : Define FormatHtmlSyntaxNode in cst.rs and implement FormatRule<HtmlSyntaxNode>, plus AsFormat and IntoFormat for HtmlSyntaxNode using the provided mapping code

Applied to files:

  • crates/biome_html_syntax/src/lib.rs
  • crates/biome_json_formatter/src/lib.rs
  • crates/biome_formatter/src/lib.rs
  • crates/biome_html_syntax/src/element_ext.rs
  • crates/biome_service/src/file_handlers/html.rs
  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/tests/spec_test.rs : Create tests/spec_test.rs implementing the run(spec_input_file, _expected_file, test_directory, _file_type) function as shown and include!("language.rs")

Applied to files:

  • crates/biome_html_parser/tests/spec_tests.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/tests/spec_tests.rs : Create tests/spec_tests.rs in the biome_html_formatter crate that generates tests via tests_macros::gen_tests! for all HTML files at tests/specs/html/**/*.html

Applied to files:

  • crates/biome_html_parser/tests/spec_tests.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/tests/language.rs : Create tests/language.rs defining HtmlTestFormatLanguage and implement TestFormatLanguage for it

Applied to files:

  • crates/biome_html_parser/tests/spec_tests.rs
  • crates/biome_formatter/src/lib.rs
  • crates/biome_html_syntax/src/element_ext.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import the FormatNode trait and implement it for your Node

Applied to files:

  • crates/biome_json_formatter/src/lib.rs
  • crates/biome_formatter/src/lib.rs
  • crates/biome_html_syntax/src/element_ext.rs
  • crates/biome_service/src/file_handlers/html.rs
  • crates/biome_json_parser/src/lib.rs
  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Use the generic Format trait and FormatNode for AST nodes when implementing the formatter

Applied to files:

  • crates/biome_json_formatter/src/lib.rs
  • crates/biome_formatter/src/lib.rs
  • crates/biome_html_syntax/src/element_ext.rs
  • crates/biome_service/src/file_handlers/html.rs
  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/src/lib.rs : Expose a documented public function format_node(options: HtmlFormatOptions, root: &HtmlSyntaxNode) -> FormatResult<Formatted<HtmlFormatContext>> delegating to biome_formatter::format_node

Applied to files:

  • crates/biome_json_formatter/src/lib.rs
  • crates/biome_formatter/src/lib.rs
  • crates/biome_service/src/file_handlers/html.rs
  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/Cargo.toml : Add biome_js_formatter as a path dependency in Cargo.toml: biome_js_formatter = { version = "0.0.1", path = "../biome_js_formatter" }

Applied to files:

  • crates/biome_json_formatter/src/lib.rs
  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Build an intermediate IR via the provided helper APIs when formatting

Applied to files:

  • crates/biome_json_formatter/src/lib.rs
  • crates/biome_formatter/src/lib.rs
  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/src/lib.rs : Place the plumbing traits and impls (AsFormat, IntoFormat, FormattedIterExt, and their Iterator adapters) in the biome_html_formatter crate’s lib.rs

Applied to files:

  • crates/biome_json_formatter/src/lib.rs
  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/src/cst.rs : Provide the FormatNodeRule trait wiring (fmt, fmt_fields, is_suppressed, fmt_leading_comments, fmt_dangling_comments, fmt_trailing_comments) used to start node formatting

Applied to files:

  • crates/biome_json_formatter/src/lib.rs
  • crates/biome_formatter/src/lib.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : When a token is mandatory and present in the AST, use the AST-provided token (e.g., node.l_paren_token().format()) instead of hardcoded tokens

Applied to files:

  • crates/biome_json_formatter/src/lib.rs
  • crates/biome_formatter/src/lib.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/src/context.rs : Define HtmlFormatContext in context.rs with fields comments: Rc<HtmlComments> and source_map: Option<TransformSourceMap>, and implement FormatContext and CstFormatContext

Applied to files:

  • crates/biome_json_formatter/src/lib.rs
  • crates/biome_html_syntax/src/element_ext.rs
  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to fix code: if a mandatory token/node is missing, return None instead

Applied to files:

  • crates/biome_formatter/src/lib.rs
  • crates/biome_html_syntax/src/element_ext.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: After scaffolding, replace uses of format_verbatim_node with proper biome_formatter IR to implement real formatting

Applied to files:

  • crates/biome_formatter/src/lib.rs
📚 Learning: 2025-08-11T11:53:15.299Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:53:15.299Z
Learning: Applies to crates/biome_service/src/workspace.rs : Implement the Workspace trait in src/workspace.rs

Applied to files:

  • crates/biome_service/src/workspace.rs
  • crates/biome_service/src/workspace/server.tests.rs
📚 Learning: 2025-08-11T11:53:15.299Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:53:15.299Z
Learning: Applies to crates/biome_service/src/workspace/watcher.tests.rs : Place watcher tests for workspace methods in src/workspace/watcher.tests.rs

Applied to files:

  • crates/biome_service/src/workspace.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/src/comments.rs : Define HtmlComments alias and HtmlCommentStyle in comments.rs, and implement CommentStyle for the language

Applied to files:

  • crates/biome_html_syntax/src/element_ext.rs
📚 Learning: 2025-08-17T08:57:34.751Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:57:34.751Z
Learning: Applies to crates/biome_parser/xtask/codegen/*.ungram : Union node names must start with Any* (e.g., AnyHtmlAttribute)

Applied to files:

  • crates/biome_html_syntax/src/element_ext.rs
📚 Learning: 2025-08-17T08:55:30.118Z
Learnt from: CR
PR: biomejs/biome#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-17T08:55:30.118Z
Learning: Applies to crates/biome_html_formatter/benches/html_formatter.rs : Maintain the HTML formatter benchmark at benches/html_formatter.rs within the biome_html_formatter crate

Applied to files:

  • crates/biome_html_syntax/src/element_ext.rs
  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Use dbg_write! to debug and inspect the written IR elements during formatter development

Applied to files:

  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-11T11:53:15.299Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:53:15.299Z
Learning: Applies to crates/biome_service/src/workspace_watcher.rs : Keep workspace state in sync with the filesystem using WorkspaceWatcher; only active in daemon mode

Applied to files:

  • crates/biome_service/src/workspace/server.tests.rs
🧬 Code graph analysis (8)
crates/biome_html_parser/tests/spec_tests.rs (2)
crates/biome_html_parser/src/lib.rs (2)
  • syntax (73-75)
  • parse_html (37-40)
crates/biome_html_syntax/src/element_ext.rs (3)
  • is_javascript_tag (26-34)
  • is_javascript_tag (95-98)
  • get_script_type (111-130)
crates/biome_json_formatter/src/lib.rs (3)
crates/biome_formatter/src/lib.rs (11)
  • format_node_with_offset (1522-1592)
  • options (754-754)
  • options (816-818)
  • options (1431-1431)
  • new (808-810)
  • new (883-885)
  • new (967-979)
  • new (1204-1206)
  • new (1254-1256)
  • new (2023-2031)
  • new (2150-2152)
crates/biome_css_formatter/src/lib.rs (3)
  • format_node_with_offset (388-393)
  • options (284-286)
  • new (256-258)
crates/biome_js_formatter/src/lib.rs (3)
  • format_node_with_offset (570-575)
  • options (523-525)
  • new (490-492)
crates/biome_html_formatter/src/html/auxiliary/element.rs (2)
crates/biome_service/src/file_handlers/html.rs (3)
  • node (476-476)
  • node (504-504)
  • node (531-531)
crates/biome_service/src/workspace/document.rs (1)
  • node (146-148)
crates/biome_html_syntax/src/element_ext.rs (2)
crates/biome_html_syntax/src/lib.rs (1)
  • inner_string_text (118-127)
crates/biome_html_syntax/src/script_type.rs (3)
  • is_javascript (50-52)
  • is_supported (67-69)
  • from_type_value (30-45)
crates/biome_service/src/file_handlers/html.rs (4)
crates/biome_service/src/file_handlers/json.rs (2)
  • workspace (574-574)
  • parse (381-396)
crates/biome_json_parser/src/lib.rs (3)
  • parse_json_with_offset_and_cache (119-136)
  • new (58-63)
  • new (146-148)
crates/biome_json_formatter/src/lib.rs (2)
  • options (266-268)
  • format_node_with_offset (357-362)
crates/biome_service/src/workspace/document.rs (3)
  • parse (147-147)
  • new (128-143)
  • node (146-148)
crates/biome_json_parser/src/lib.rs (3)
crates/biome_rowan/src/syntax/node.rs (3)
  • new (1152-1154)
  • base_offset (1169-1171)
  • into_inner (1179-1181)
crates/biome_parser/src/tree_sink.rs (4)
  • new (83-95)
  • new (191-196)
  • with_cache (99-111)
  • with_cache (199-209)
crates/biome_parser/src/event.rs (1)
  • process (48-104)
crates/biome_service/src/workspace/server.rs (1)
crates/biome_service/src/file_handlers/html.rs (4)
  • parse_embedded_js_script (300-343)
  • parse_embedded_json (345-378)
  • parse_embedded_style (380-413)
  • parse (284-298)
crates/biome_service/src/workspace/document.rs (5)
crates/biome_json_parser/src/lib.rs (5)
  • diagnostics (71-73)
  • diagnostics (175-177)
  • from (201-209)
  • new (58-63)
  • new (146-148)
crates/biome_service/src/workspace/server.rs (7)
  • diagnostics (1345-1348)
  • settings (530-530)
  • settings (542-542)
  • settings (553-553)
  • get_file_source (221-228)
  • new (121-143)
  • parse (570-600)
crates/biome_service/src/file_handlers/html.rs (16)
  • settings (269-269)
  • settings (273-273)
  • settings (277-277)
  • settings (291-291)
  • settings (430-430)
  • settings (446-446)
  • settings (464-464)
  • settings (475-475)
  • settings (503-503)
  • settings (530-530)
  • from (53-57)
  • from (76-89)
  • node (476-476)
  • node (504-504)
  • node (531-531)
  • parse (284-298)
crates/biome_service/src/file_handlers/json.rs (2)
  • workspace (574-574)
  • parse (381-396)
crates/biome_service/src/file_handlers/mod.rs (12)
  • from (89-91)
  • from (95-97)
  • from (101-103)
  • from (107-109)
  • from (113-115)
  • from (119-121)
  • from (125-127)
  • new (516-529)
  • new (733-747)
  • new (1002-1020)
  • new (1318-1332)
  • new (1471-1481)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (22)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Check Dependencies
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: autofix
🔇 Additional comments (28)
crates/biome_formatter/src/lib.rs (2)

1453-1457: Cloning removed — neat micro‑optimisation, no semantic change.

Passing root by reference directly to transform avoids a pointless clone and keeps lifetimes identical. All good.


1527-1531: Consistent no‑clone on the offset path — looks good.

&root.node matches the trait signature; behaviour unchanged, less noise.

crates/biome_json_syntax/src/syntax_node.rs (1)

25-25: LGTM!

The new type alias for JsonSyntaxNodeWithOffset follows the established pattern and enables offset-aware JSON formatting.

crates/biome_html_syntax/src/lib.rs (2)

7-7: LGTM!

Adding the script_type module declaration is consistent with the PR's goal of supporting different script types.


12-13: Minor: Simplified re-export syntax.

The change from self::generated::* to generated::* is a clean simplification since the module is already in scope. The addition of the script_type re-export aligns with the new ScriptType API.

crates/biome_html_formatter/src/html/auxiliary/element.rs (1)

49-50: Good generalisation of script support.

The change from is_javascript_tag()? to is_supported_script_tag() properly extends support beyond JavaScript to include JSON scripts (importmap, application/json). The removal of the ? operator is correct as the new method returns a direct boolean.

crates/biome_service/src/workspace.rs (1)

58-58: LGTM!

The updated re-exports correctly reflect the new unified embedding model, replacing the language-specific EmbeddedCssContent and EmbeddedJsContent with the generic EmbeddedContent and SendEmbeddedParse.

crates/biome_html_parser/tests/spec_tests.rs (2)

3-6: LGTM!

Good test organisation with the necessary imports for testing script type detection.


16-104: Comprehensive test coverage for script type detection.

Excellent test coverage that validates is_javascript_tag() behaviour across various script types. The test properly verifies:

  • Classic JavaScript detection (text/javascript, application/javascript, application/ecmascript)
  • Module script detection (type="module")
  • ImportMap exclusion (correctly returns false)
  • Default script behaviour (no type attribute)

This aligns well with the new ScriptType categorisation system.

crates/biome_html_formatter/src/html/auxiliary/embedded_content.rs (1)

24-24: LGTM!

The condition update to is_supported_script_tag() correctly extends embedded content formatting to all supported script types, not just JavaScript.

crates/biome_json_formatter/src/lib.rs (2)

27-29: LGTM!

The import now includes JsonSyntaxNodeWithOffset to support the new offset-aware formatting API.


354-362: Well-structured offset-aware formatting API.

The new format_node_with_offset function follows the established pattern from other formatters (CSS, JS) and provides the necessary entry point for formatting embedded JSON content with proper offset tracking.

crates/biome_service/src/workspace/server.tests.rs (3)

102-106: LGTM!

Test assertions correctly updated to use the new embedded_snippets structure with its nested scripts and styles fields.


122-124: Good test for importmap handling.

The addition of the importmap script block effectively tests that the formatter correctly handles and preserves JSON script content.


162-169: Verify importmap formatting preserves valid JSON.

The expected output shows correct formatting of the importmap JSON content. Good to see it maintains valid JSON structure whilst applying consistent indentation.

crates/biome_json_parser/src/lib.rs (2)

50-104: Solid offset-aware wrapper API

The JsonOffsetParse container and accessors look correct and align with existing offset sinks. Nice.

These are new public APIs; do we want to include a changeset entry for the JSON parser crate? If yes, please add one under the appropriate package name.


115-136: Offset parsing path mirrors non-offset; LGTM

Construction via OffsetLosslessTreeSink::with_cache and return of JsonOffsetParse is consistent.

crates/biome_service/src/file_handlers/html.rs (1)

473-528: Nice JSON embed formatting parity with JS/CSS

Consistent indentation handling and offset‑aware formatting. Well done.

crates/biome_service/src/workspace/document.rs (3)

34-41: Good: JSON offset parse wired into SendEmbeddedParse

Matches JS/CSS conversions and keeps diagnostics. LGTM.


74-97: Format node aggregation reads clean

Merges scripts/JSON/styles uniformly for the formatter. Looks good.


177-179: Document now hosts unified embedded snippets

Field addition aligns with the new flow. LGTM.

crates/biome_service/src/workspace/server.rs (7)

17-38: Imports for embedded content look consistent.

Brings in the new snippets type and required language crates. All good.


366-383: Single-pass embedded parsing hook: nice integration.

Switching to parse_embedded_language_snippets here is tidy and sets up future extensions cleanly.


418-433: Persisting embedded_snippets in Document is fine.

The clone here is acceptable; payloads should stay small. Just ensure Document’s new field is covered by (de)serialisation/tests.


458-469: get_parse simplification LGTM.

The transpose() handling is clearer and preserves previous behaviour.


497-568: Overall embedded snippets collector reads well.

Single tree walk, language‑specific option derivation, and offset‑aware parsing are all spot on.


1299-1316: Change file: mirrored embedded parsing path looks good.

Consistent with open‑file path; good separation with a fresh NodeCache.


1542-1563: Formatting path correctly feeds embedded nodes.

Graceful early return to format_embedded when present is the right call.

Please confirm that HTML capabilities register formatter.format_embedded for the workspace so this path is always available when snippets exist.

Comment on lines +484 to +491
Ok(syntax) => Ok((
syntax.clone(),
doc.embedded_snippets.get_format_nodes(|file_source_index| {
self.get_source(file_source_index)
.expect("Document source must exist")
}),
)),
Err(FileTooLarge { .. }) => Err(WorkspaceError::file_ignored(path.to_string())),
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid panic in workspace path: replace expect with a safe fallback.

WorkspaceServer is intended to be unwind‑safe; an expect here can still take the process down if an invariant slips. Use a non‑panicking fallback.

Apply this diff:

-                    Ok((
-                        syntax.clone(),
-                        doc.embedded_snippets.get_format_nodes(|file_source_index| {
-                            self.get_source(file_source_index)
-                                .expect("Document source must exist")
-                        }),
-                    )),
+                    Ok((
+                        syntax.clone(),
+                        doc.embedded_snippets.get_format_nodes(|file_source_index| {
+                            // Fallback to the file's own source if the index is missing.
+                            self.get_source(file_source_index)
+                                .unwrap_or_else(|| self.get_file_source(path))
+                        }),
+                    )),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Ok(syntax) => Ok((
syntax.clone(),
doc.embedded_snippets.get_format_nodes(|file_source_index| {
self.get_source(file_source_index)
.expect("Document source must exist")
}),
)),
Err(FileTooLarge { .. }) => Err(WorkspaceError::file_ignored(path.to_string())),
Ok(syntax) => Ok((
syntax.clone(),
doc.embedded_snippets.get_format_nodes(|file_source_index| {
// Fallback to the file's own source if the index is missing.
self.get_source(file_source_index)
.unwrap_or_else(|| self.get_file_source(path))
}),
)),
Err(FileTooLarge { .. }) => Err(WorkspaceError::file_ignored(path.to_string())),
🤖 Prompt for AI Agents
In crates/biome_service/src/workspace/server.rs around lines 484 to 491, the
closure passed to get_format_nodes uses self.get_source(...).expect(...), which
can panic; replace the expect with a non-panicking fallback by returning a
Result or Option that propagates a workspace-safe error instead — e.g., change
the closure to map the Option from get_source to an
Err(WorkspaceError::file_ignored(path.to_string())) (or other appropriate
WorkspaceError) using ok_or_else and propagate that error out of the surrounding
call so no panic occurs.

Copy link

codspeed-hq bot commented Sep 23, 2025

CodSpeed Performance Report

Merging #7571 will not alter performance

Comparing arendjr:implement-nested-json-parsing (0821738) with next (8ab8b6c)

Summary

✅ 133 untouched

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
crates/biome_html_syntax/src/attr_ext.rs (2)

6-15: Don’t mask token failures as empty strings

Returning Some(Text::default()) on token extraction failure can misclassify the attribute (e.g. treat an error as an unsupported type). Propagate None instead.

-            Self::HtmlString(string) => Some(
-                string
-                    .value_token()
-                    .map(|token| inner_string_text(&token).into())
-                    .unwrap_or_default(),
-            ),
+            Self::HtmlString(string) => {
+                string
+                    .value_token()
+                    .ok()
+                    .map(|token| inner_string_text(&token).into())
+            }

6-16: Consider returning a borrowed view to avoid allocation

If this ends up hot, a TokenText (or Cow<str>) variant would avoid allocating a fresh Text. Alternatively, offer a second method returning a borrowed view.

crates/biome_html_syntax/src/element_ext.rs (2)

101-122: Normalise type values before mapping (and pass as &str explicitly)

Some authors include MIME parameters (e.g. application/json; charset=utf-8). Normalise before mapping, and pass &str explicitly to avoid relying on implicit coercions.

-        let script_type = self
+        let script_type = self
             .find_attribute_by_name("type")
             .and_then(|attribute| {
                 let initializer = attribute.initializer()?;
-                let value = initializer.value().ok()?.string_value()?;
-                Some(ScriptType::from_type_value(&value))
+                let value = initializer.value().ok()?.string_value()?;
+                let value = value.as_str();
+                let type_value = value.split(';').next().unwrap_or(value);
+                Some(ScriptType::from_type_value(type_value))
             })
             .unwrap_or_default();

Note: If string_value() is changed to propagate None on token errors (suggested in attr_ext.rs), this will also avoid misclassifying error cases.


124-135: Style tags: consider guarding by type in future

Today any <style> returns true. If you later support non‑CSS type values (e.g. type="text/x-less"), you may want to gate this similarly to scripts.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ee3988c and 097349e.

📒 Files selected for processing (4)
  • crates/biome_html_parser/tests/spec_tests.rs (1 hunks)
  • crates/biome_html_syntax/src/attr_ext.rs (1 hunks)
  • crates/biome_html_syntax/src/element_ext.rs (3 hunks)
  • crates/biome_html_syntax/src/lib.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/biome_html_parser/tests/spec_tests.rs
  • crates/biome_html_syntax/src/lib.rs
🧰 Additional context used
📓 Path-based instructions (3)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_html_syntax/src/element_ext.rs
  • crates/biome_html_syntax/src/attr_ext.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_html_syntax/src/element_ext.rs
  • crates/biome_html_syntax/src/attr_ext.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_html_syntax/src/element_ext.rs
  • crates/biome_html_syntax/src/attr_ext.rs
🧠 Learnings (1)
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/src/cst.rs : Define FormatHtmlSyntaxNode in cst.rs and implement FormatRule<HtmlSyntaxNode>, plus AsFormat and IntoFormat for HtmlSyntaxNode using the provided mapping code

Applied to files:

  • crates/biome_html_syntax/src/element_ext.rs
🧬 Code graph analysis (2)
crates/biome_html_syntax/src/element_ext.rs (1)
crates/biome_html_syntax/src/script_type.rs (3)
  • is_javascript (50-52)
  • is_supported (67-69)
  • from_type_value (30-45)
crates/biome_html_syntax/src/attr_ext.rs (1)
crates/biome_html_syntax/src/lib.rs (1)
  • inner_string_text (119-128)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: autofix
🔇 Additional comments (5)
crates/biome_html_syntax/src/element_ext.rs (5)

33-41: LGTM: consistent boolean API for style tags

Same simplification here; looks good.


92-95: LGTM: centralise JS detection via ScriptType

Using get_script_type().is_some_and(ScriptType::is_javascript) keeps logic in one place.


97-99: LGTM: supported script tag helper

Handy helper for call sites; no concerns.


136-146: LGTM: robust name check for script tags

Graceful fallback on missing tokens; no issues.


23-31: LGTM — callers now use bool

Grep shows only the impl and test usages (crates/biome_html_syntax/src/element_ext.rs and crates/biome_html_parser/tests/spec_tests.rs); no remaining SyntaxResult call sites.

@arendjr arendjr force-pushed the implement-nested-json-parsing branch from 86e6410 to 0821738 Compare September 24, 2025 09:27
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (5)
crates/biome_service/src/file_handlers/html.rs (5)

300-314: Minor readability: use match for script type to file source mapping.

A small tidy-up makes the intent crisper.

Apply this diff:

-    let file_source = if script_type.is_javascript_module() {
-        JsFileSource::js_module()
-    } else if script_type.is_javascript() {
-        JsFileSource::js_script()
-    } else {
-        return None;
-    };
+    let file_source = match () {
+        _ if script_type.is_javascript_module() => JsFileSource::js_module(),
+        _ if script_type.is_javascript() => JsFileSource::js_script(),
+        _ => return None,
+    };

345-378: JSON embedding: confirm MIME coverage and call-site gating.

  • Do we also want to support application/ld+json? It’s commonly used for structured data and is JSON.
  • As with JS, please confirm callers only route supported <script type="application/json" | "importmap"> here.

If you want, I can add script-type checks (or extend ScriptType) and corresponding tests for ld+json/importmap.


469-472: Lookup is O(n) per embed; pre-index by range to avoid quadratic scans.

Likely fine for small n, but cheap to improve.

Apply this diff to the closure:

-    formatted.format_embedded(move |range| {
-        let mut iter = embedded_nodes.iter();
-        let node = iter.find(|node| node.range == range)?;
+    formatted.format_embedded(move |range| {
+        let node = by_range.get(&range)?;

And add this initialisation just above the closure:

let by_range: std::collections::HashMap<_, _> =
    embedded_nodes.iter().map(|n| (n.range, n)).collect();

If TextRange isn’t Hash, switch to BTreeMap.


473-492: Potential extra blank line before embedded content.

Two Hard line breaks before the content likely insert a blank line. Trim one for tighter output.

Apply this diff:

-            if indent_script_and_style {
-                let elements = vec![
-                    FormatElement::Line(LineMode::Hard),
-                    FormatElement::Tag(Tag::StartIndent),
-                    FormatElement::Line(LineMode::Hard),
-                    FormatElement::Interned(Interned::new(document.into_elements())),
-                    FormatElement::Tag(Tag::EndIndent),
-                ];
-                Document::new(elements)
-            } else {
+            if indent_script_and_style {
+                let elements = vec![
+                    FormatElement::Line(LineMode::Hard),
+                    FormatElement::Tag(Tag::StartIndent),
+                    FormatElement::Interned(Interned::new(document.into_elements())),
+                    FormatElement::Tag(Tag::EndIndent),
+                ];
+                Document::new(elements)
+            } else {

Please sanity-check with the new HTML+JSON test to ensure no unintended spacing changes.


496-515: Avoid shadowing node for clarity in each branch.

Rename the inner node binding to reduce cognitive load.

Apply these diffs:

@@
-                let node = node.node.root.clone().into_node::<JsLanguage>();
-                let formatted =
-                    biome_js_formatter::format_node_with_offset(js_options, &node).ok()?;
+                let embedded = node.node.root.clone().into_node::<JsLanguage>();
+                let formatted =
+                    biome_js_formatter::format_node_with_offset(js_options, &embedded).ok()?;
@@
-                let node = node.node.root.clone().into_node::<JsonLanguage>();
-                let formatted =
-                    biome_json_formatter::format_node_with_offset(json_options, &node).ok()?;
+                let embedded = node.node.root.clone().into_node::<JsonLanguage>();
+                let formatted =
+                    biome_json_formatter::format_node_with_offset(json_options, &embedded).ok()?;
@@
-                let node = node.node.root.clone().into_node::<CssLanguage>();
-                let formatted =
-                    biome_css_formatter::format_node_with_offset(css_options, &node).ok()?;
+                let embedded = node.node.root.clone().into_node::<CssLanguage>();
+                let formatted =
+                    biome_css_formatter::format_node_with_offset(css_options, &embedded).ok()?;
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 097349e and 0821738.

📒 Files selected for processing (1)
  • crates/biome_service/src/file_handlers/html.rs (4 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_service/src/file_handlers/html.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_service/src/file_handlers/html.rs
🧠 Learnings (5)
📚 Learning: 2025-09-23T21:33:00.819Z
Learnt from: arendjr
PR: biomejs/biome#7571
File: crates/biome_service/src/file_handlers/html.rs:360-368
Timestamp: 2025-09-23T21:33:00.819Z
Learning: Don't flag potential move/borrow issues in Rust code reviews since the Rust compiler catches these at compile time. Focus on logic, design, and issues that the toolchain doesn't automatically detect.

Applied to files:

  • crates/biome_service/src/file_handlers/html.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/src/lib.rs : Expose a documented public function format_node(options: HtmlFormatOptions, root: &HtmlSyntaxNode) -> FormatResult<Formatted<HtmlFormatContext>> delegating to biome_formatter::format_node

Applied to files:

  • crates/biome_service/src/file_handlers/html.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import the FormatNode trait and implement it for your Node

Applied to files:

  • crates/biome_service/src/file_handlers/html.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/src/cst.rs : Define FormatHtmlSyntaxNode in cst.rs and implement FormatRule<HtmlSyntaxNode>, plus AsFormat and IntoFormat for HtmlSyntaxNode using the provided mapping code

Applied to files:

  • crates/biome_service/src/file_handlers/html.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Use the generic Format trait and FormatNode for AST nodes when implementing the formatter

Applied to files:

  • crates/biome_service/src/file_handlers/html.rs
🧬 Code graph analysis (1)
crates/biome_service/src/file_handlers/html.rs (3)
crates/biome_js_parser/src/parse.rs (4)
  • parse_js_with_offset_and_cache (382-395)
  • parse (173-178)
  • parse (219-220)
  • parse (247-250)
crates/biome_json_parser/src/lib.rs (3)
  • parse_json_with_offset_and_cache (119-136)
  • new (58-63)
  • new (146-148)
crates/biome_service/src/workspace/document.rs (3)
  • parse (147-147)
  • new (128-143)
  • node (146-148)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: autofix
🔇 Additional comments (4)
crates/biome_service/src/file_handlers/html.rs (4)

7-7: LGTM: unified embedded content import.

Importing EmbeddedContent here aligns with the new generic embedding model.


35-39: LGTM: ScriptType and JSON imports are correctly wired.

These enable the new JSON embedding path without leaking concerns into callers.


317-341: Call-site contract: ensure only <script> elements land here.

This parses any element’s embedded content as JS if invoked. Please confirm the caller guarantees this is only invoked for supported <script> tags.


380-413: LGTM: CSS path mirrors JS/JSON and uses offset-aware parsing.

@arendjr arendjr merged commit f890861 into biomejs:next Sep 24, 2025
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Formatter Area: formatter A-Parser Area: parser A-Project Area: project L-HTML Language: HTML L-JSON Language: JSON and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载