Repository navigation
Conversation
Modernizes the toolchain and dependency set so the repo builds and tests cleanly on the current Flutter stable release. - Bump Dart/Flutter SDK constraints per package to match what the upgraded dependencies actually require, and raise dependency floors (flutter_lints 6, meta 1.19, melos 8, video_player 2.14, webview_flutter 4.14, flutter_svg 2.3, chewie 1.16, flutter_layout_grid 2.0.8, html 0.15.7). - Migrate the monorepo from the legacy melos.yaml layout to Dart pub workspaces, which Melos 8 requires: the root pubspec now declares the workspace members plus a `melos:` config block, and each member declares `resolution: workspace`. Scripts are ported to the Melos 8 `exec.command` schema. - Fix StyledElement.matches for html 0.15.7, which no longer exposes a top-level `matches(Element, String)`. The selector is now parsed with csslib and evaluated through SelectorEvaluator. - Fix a semantics assertion that made <details> crash on current Flutter. The ExpansionTile's semantics config conflicted with the sibling text fragments of the enclosing paragraph; marking it as its own semantics container keeps it out of that merge group. - Replace repeated `_` parameters with wildcards for the new unnecessary_underscores lint, and reformat with the Dart 3.7+ tall style so the CI format check passes. Verified on Flutter 3.47.2: melos analyze --fatal-infos is clean across all nine packages, all 242 tests pass, and dart format reports no changes.
…latforms The example app's native projects had drifted years behind the Flutter templates: the iOS project was objectVersion 50 with a deployment target of 9.0 and a mixed ObjC/Swift Runner, Android was on Gradle 6.5/AGP 4.1.1 with the shut-down jcenter repository, and the checked-in Podfile.lock still referenced the long-removed wakelock plugin. None of it builds under current Flutter, so the platform directories are regenerated from the Flutter 3.47.2 templates. Swift Package Manager is the default in Flutter 3.47, so the regenerated iOS and macOS projects carry a FlutterGeneratedPluginSwiftPackage local package reference instead of a Podfile. Both Podfiles and Podfile.locks are gone, and the obsolete Flutter.podspec ignore rule with them. All four Darwin plugins the example pulls in (package_info_plus, video_player_avfoundation, wakelock_plus, webview_flutter_wkwebview) ship a Package.swift, so nothing needs a CocoaPods fallback. Alongside that, the regeneration brings iOS 15 / macOS 12 deployment targets, a Swift-only Runner with SceneDelegate, the Kotlin DSL Android build with Kotlin 2.4 and JDK 17, and the flutter_bootstrap.js web loader. The two genuine customizations in the old projects are re-applied on top: the Android INTERNET permission and the macOS network client entitlement, both of which the example needs to render network images, video and web content. The macOS release entitlements previously lacked the network client, so sandboxed release builds could not load them at all. Also fixes two web bugs uncovered while verifying the build: - flutter_html_iframe used ui.platformViewRegistry through a local dart:ui shim. platformViewRegistry now lives in dart:ui_web, so the shim is deleted and the web implementation imports dart:ui_web directly. - The conditional import selected the web implementation on dart.library.html, which is false under Wasm. Wasm builds therefore fell back to the "unsupported" stub and silently rendered no iframes. It now keys off dart.library.js_interop, which is true for both dart2js and Wasm. Verified on Flutter 3.47.2: `flutter build web` and `flutter build web --wasm` both succeed for the example, analysis is clean across all nine packages, and all 242 tests pass. The iOS/macOS projects are verbatim Flutter 3.47.2 template output, so they could not be compiled here (no macOS/Xcode); the Linux desktop build was likewise not exercised because GTK development headers are not installed in this environment.
Adds a SessionStart hook so Claude Code on the web sessions come up with a working toolchain instead of starting from a container with no Flutter at all. The hook pins Flutter 3.47.2 to match the revision in .metadata, installs it only when it is missing or the wrong version, puts it on PATH for the rest of the session via CLAUDE_ENV_FILE, resolves the pub workspace, and warms the web artifacts so that download lands in the cached container image rather than mid-session. It exits immediately outside the remote environment, so local checkouts keep using whatever Flutter the developer already has. The CI workflow is updated for the Melos 8 / pub workspace layout. Melos is a dev_dependency now, so `flutter pub global activate melos` and the separate bootstrap step are gone: a single `flutter pub get` resolves every package and installs the pinned Melos, which is then invoked with `dart run melos`. The Flutter version is pinned to 3.47.2 with SDK and pub caching enabled, and the format check moved into a melos script so it can be run the same way locally. Verified locally on Flutter 3.47.2: the hook succeeds both on a clean install into an empty prefix and on the already-installed path, and is a no-op when CLAUDE_CODE_REMOTE is unset. Every workflow step was run by hand — analyze, test, gen_coverage (39 source files in the combined lcov report) and format:check all pass.
…s-h2k3w2 Reformat code to match Dart style guide conventions
Captures the things that take reading several files to work out: the five-stage HtmlParser pipeline and why the processTree passes are ordered as they are, the extension resolution order that lets user extensions override built-ins, the style cascade, and the tree element hierarchy. Also records the setup that is easy to get wrong. Melos 7+ dropped melos.yaml, so the configuration lives under the `melos:` key in the root pubspec with the workspace member list; Melos is a dev_dependency and must be invoked through `dart run`. Notes the deliberate `implementation_imports` suppression in StyledElement.matchesSelector as the thing to re-check after an `html` package upgrade, the iframe package's dart:ui_web / dart.library.js_interop requirement, the two hand-applied edits in the otherwise stock example platform directories, and the fact that golden_test.dart's matchesGoldenFile calls are commented out so a passing golden test proves nothing visual. Every command in the file was run against Flutter 3.47.2 before writing it down.
Running the example app on current Flutter threw
`renderBoxDoingDryBaseline == null` during performLayout and then cascaded into
a dozen "RenderBox was not laid out" failures. The minimal trigger is an <img>
inside a <table>; the error names RenderSemanticsAnnotations, which is a red
herring, and the reported stack contains no dry-baseline frame at all.
The underlying problem is a Flutter framework gap: RenderImage implements
neither computeDryBaseline nor computeDistanceToActualBaseline, and the default
computeDryBaseline throws via debugCannotComputeDryLayout. That throw escapes
from inside getDryBaseline, which permanently leaves the framework's
_computingThisDryBaseline debug flag set on an ancestor, so every subsequent
layout of that subtree trips an assertion pointing at the wrong object. It
reproduces with no flutter_html involved at all:
IntrinsicHeight(child: Text.rich(TextSpan(children: [
WidgetSpan(alignment: PlaceholderAlignment.baseline, child: Image(...)),
])))
Table layout is what makes this reachable, because it sizes rows intrinsically
and so asks the baseline-aligned image placeholder for a dry baseline.
Two fixes, both needed:
- Images are replaced content. CSS aligns replaced content by its bottom margin
edge rather than a text baseline, so PlaceholderAlignment.baseline was never
meaningful for them; requesting it is what walks into the RenderImage gap.
ImageBuiltIn now maps baseline to bottom for the image placeholder.
- RenderCSSBox had the same class of bug as RenderImage: computeDryBaseline
returned a bare null while computeDistanceToActualBaseline deferred to the
child. Flutter's _debugVerifyDryBaselines throws on exactly that mismatch. It
now resolves the child's dry baseline against the same constraints
performLayout uses, and returns null for replaced children, where the real
baseline is null too. The child constraint calculation is factored out of
_computeSize so both paths cannot drift apart.
Declaring the limitation with debugCannotComputeDryLayout was tried and does
not work here: it also throws for the caller that matters, Flutter's own
_RenderScaledInlineWidget laying out a baseline-aligned WidgetSpan with
debugCheckingIntrinsics false.
The example package's only test was a `2 + 2 == 4` placeholder, which is why CI
stayed green while the app itself could not render a frame. It now pumps the
real example page and asserts the rendering pipeline reports no errors, plus a
focused case for an image inside a table.
Verified on Flutter 3.47.2: the full example page renders with zero exceptions,
analysis is clean across all nine packages, all 243 tests pass, and dart format
reports no changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.