-
- Notifications
You must be signed in to change notification settings - Fork 145
feat(grid): part2 & part3 #762
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
Conversation
| The latest updates on your projects. Learn more about Vercel for GitHub.
|
| Caution Review failedThe pull request is closed. WalkthroughAdds comprehensive CSS Grid support: parser, data models (named lines, repeats, minmax, fit-content, template-areas), serialization, layout algorithm (auto-placement, named-area resolution, alignment), shorthand expansion, tests, and minor config/doc updates. Changes
Sequence Diagram(s)sequenceDiagram participant Parser as CSSGridParser participant Style as RenderStyle / CSSStyleDeclaration participant Layout as RenderGridLayout participant DOM as Document / Children participant Test as Test Runner / Snapshot Note over Parser,Style: Parsing & serialization Test->>Style: set shorthand/property (grid, grid-template, grid-area, place-*) Style->>Parser: parse value → tracks, repeats, areas, placements Parser-->>Style: model (GridTrackSize, GridRepeat, TemplateAreas, Placement) Note over Style,Layout: Invalidation Style->>Layout: invalidate layout (justify/align changes) Layout->>Style: request resolved track list & placements Layout->>DOM: measure children, perform auto-placement (named lines, areas, dense/auto-fit) Layout-->>DOM: position/size children Test->>DOM: capture snapshot / geometry checks Test-->>Style: read computed styles for assertions Estimated code review effort🎯 4 (Complex) | ⏱️ ~45–60 minutes Areas requiring extra attention:
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (9)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Actionable comments posted: 13
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
integration_tests/specs/css/css-text/line-join.ts (1)
162-197: Prevent hangs: add cleanup + failure paths; don’t mixasyncwithdoneThese tests can hang (image load error / snapshot error) and they leak DOM nodes. Prefer
it('...', (done) => { ... })+try/finallycleanup +done.fail(...).- it('works with join two inline element and img', async (done) => { + it('works with join two inline element and img', (done) => { let img; let div = createElement( 'div', { style: { width: '100px', backgroundColor:'#ff2' }, }, [ createElement('span', { style: { }, },[createText(`A`)]), createElement('span', { style: { }, },[ img = createElement('img', { src: 'assets/blue15x15.png', width: '15', height: '15', style: { }, }), createText(`In this article`), ]), ] ); document.body.appendChild(div); - onImageLoad(img, async () => { - await snapshot(0.1); - done(); - }); + onImageLoad(img, async () => { + try { + await snapshot(0.1); + done(); + } catch (e) { + done.fail(e); + } finally { + div.remove(); + } + }); });Apply the same pattern to the other two updated tests (and consider adding an
onerror/timeout path to calldone.fail(...)ifonImageLoaddoesn’t already handle it). Based on coding guidelines.Also applies to: 199-234, 236-272
.github/workflows/release.yml (1)
4-6: Defineworkflow_dispatchinputs (actionlint) and harden publish step
inputs.versionis referenced multiple times throughout the workflow (lines 537, 623, 853, 866, 909) butworkflow_dispatchdoesn't define any inputs, which triggers actionlint warnings. Additionally, harden the token piping and add validation before publishing.on: workflow_dispatch: + inputs: + version: + description: 'Release version (e.g. 0.23.10)' + required: false + type: string ... - name: Authenticate pub.dev for WebF run: | echo "🔐 Setting up pub.dev authentication..." - echo '${{ secrets.PUB_DEV_TOKEN }}' | dart pub token add https://pub.dev + printf '%s' '${{ secrets.PUB_DEV_TOKEN }}' | dart pub token add https://pub.dev echo "✅ pub.dev authentication configured" ... - name: Publish to pub.dev run: | echo "🚀 Publishing WebF to pub.dev..." cd webf flutter pub get + dart pub publish --dry-run dart pub publish --forcewebf/lib/src/rendering/grid.dart (2)
812-1097:fit-content()handling is inverted when applying preferred child width (can exceed the limit).
In theGridFitContentbranch,target = math.max(limit, preferred)(Line 1091) grows the track beyond thefit-content()limit, which is opposite of expected behavior (should be capped by the limit).@@ final GridFitContent fitTrack = resolvedColumnDefs[colIndex] as GridFitContent; final double limit = _resolveLengthValue(fitTrack.limit, adjustedInnerWidth); - final double target = math.max(limit, preferred); + final double target = math.min(limit, preferred); if (target > colSizes[colIndex]) { colSizes[colIndex] = target; }
656-700: GridFraction and GridMinMax resolution are incorrect for CSS Grid semantics.
GridFraction (lines 679–683): Currently resolves isolated fractional tracks to a proportional portion of
innerAvailable(e.g.,innerAvailable * (1fr / 1fr)= full space). This breaks implicit track sizing in_resolveAutoTrackAt()and_ensureImplicitColumns(), where a single1frpattern should not expand to consume all available space in isolation. Fractional tracks must be distributed as part of the full track sizing algorithm, not resolved independently.GridMinMax (lines 689–692): Returns
math.max(minValue, maxValue), which selects the larger bound rather than clamping the resolved value into the[min, max]range. This violates CSS Gridminmax(a, b)semantics where the track size should be constrained between the two bounds, not defaulting to the maximum.Fix by returning 0 for isolated
GridFractionresolution and implementing proper[min, max]clamping forGridMinMax.
🧹 Nitpick comments (9)
.github/workflows/contributors.yml (1)
2-3: Good: least-privilege permissions added; consider modernizing EOL runner/tooling
permissions: contents: readis a solid hardening step. Separately, this workflow still usesubuntu-18.04and Node 14 (both EOL); consider upgrading runner/action versions to reduce breakage and security risk.integration_tests/specs/css/css-grid/dense-flow-dashboard.ts (1)
1-48: Make cleanup unconditional (try/finally) to avoid DOM leaks on assertion failureRight now
grid.remove()is skipped ifexpect(...)throws. Wrap the body intry/finally.document.body.appendChild(grid); - await waitForFrame(); - await snapshot(); - - const wideRect = (grid as any)['wide'].getBoundingClientRect(); - const tallRect = (grid as any)['tall'].getBoundingClientRect(); - const compactRect = (grid as any)['compact'].getBoundingClientRect(); - - expect(Math.round(tallRect.left)).toBeGreaterThanOrEqual(Math.round(wideRect.right)); - expect(Math.round(compactRect.top)).toBeGreaterThan(Math.round(wideRect.top)); - grid.remove(); + try { + await waitForFrame(); + await snapshot(); + + const wideRect = (grid as any)['wide'].getBoundingClientRect(); + const tallRect = (grid as any)['tall'].getBoundingClientRect(); + const compactRect = (grid as any)['compact'].getBoundingClientRect(); + + expect(Math.round(tallRect.left)).toBeGreaterThanOrEqual(Math.round(wideRect.right)); + expect(Math.round(compactRect.top)).toBeGreaterThan(Math.round(wideRect.top)); + } finally { + grid.remove(); + }integration_tests/specs/css/css-grid/basic-concepts.ts (1)
1-39: Use try/finally sogrid.remove()always executesBoth tests should remove DOM even if
snapshot()fails.document.body.appendChild(grid); - - await waitForFrame(); - await snapshot(); - - grid.remove(); + try { + await waitForFrame(); + await snapshot(); + } finally { + grid.remove(); + }Also applies to: 41-99
webf/lib/src/css/grid.dart (1)
223-229: Consider excluding CSS-wide keywords from custom ident validation.The
isCustomIdentmethod correctly rejectsautoandspan, but CSS-wide keywords likeinherit,initial,unset, andrevertshould also be excluded per CSS Values spec for<custom-ident>.static bool isCustomIdent(String token) { if (token.isEmpty) return false; final String lower = token.toLowerCase(); - if (lower == 'auto' || lower == 'span') return false; + if (lower == 'auto' || lower == 'span' || + lower == 'inherit' || lower == 'initial' || + lower == 'unset' || lower == 'revert') return false; return _customIdentRegExp.hasMatch(token); }integration_tests/specs/css/css-grid/template-areas-overlap.ts (1)
1-41: Test definition creates non-rectangular area, not overlap.The template
"alpha alpha" "alpha beta"definesalphaspanning cells (row 1, col 1), (row 1, col 2), and (row 2, col 1) - this forms an L-shape, not a rectangle. Per CSS Grid spec, this is invalid because named areas must be rectangular. The test name suggests "overlap" but the actual issue is non-rectangularity.Consider renaming or adjusting the test to match the actual validation being performed:
-describe('CSS Grid template areas overlap handling', () => { - xit('treats overlapping template definitions as none', async () => { +describe('CSS Grid template areas non-rectangular handling', () => { + xit('treats non-rectangular template definitions as invalid', async () => {Additionally, the test is marked
xit(pending). Was this intentional to defer implementation, or should it beitonce the feature is complete?integration_tests/specs/css/css-grid/template-areas.ts (1)
45-64: Consider using more precise assertions or documenting the expected layout.The range-based assertions (e.g.,
toBeGreaterThanOrEqual(9)/toBeLessThanOrEqual(10)) account for minor rendering variations, but the magic numbers (9, 10, 68, 168, 176) are not self-documenting.Consider adding comments explaining the expected layout calculation:
// Expected: padding(8px) + border(1px) = 9-10px offset const headerOffset = Math.round(headerRect.left - gridRect.left); expect(headerOffset).toBeGreaterThanOrEqual(9);webf/lib/src/css/style_declaration.dart (1)
326-343: Indentation inconsistency in switch cases.Lines 326-334 use different indentation (no leading spaces) compared to surrounding cases (which use 8-space indentation). This appears to be a formatting issue.
- case BORDER_RADIUS: - CSSStyleProperty.setShorthandBorderRadius(longhandProperties, normalizedValue); - break; - case GRID_TEMPLATE: - CSSStyleProperty.setShorthandGridTemplate(longhandProperties, normalizedValue); - break; - case GRID: - CSSStyleProperty.setShorthandGrid(longhandProperties, normalizedValue); - break; - case PLACE_CONTENT: - CSSStyleProperty.setShorthandPlaceContent(longhandProperties, normalizedValue); - break; + case BORDER_RADIUS: + CSSStyleProperty.setShorthandBorderRadius(longhandProperties, normalizedValue); + break; + case GRID_TEMPLATE: + CSSStyleProperty.setShorthandGridTemplate(longhandProperties, normalizedValue); + break; + case GRID: + CSSStyleProperty.setShorthandGrid(longhandProperties, normalizedValue); + break; + case PLACE_CONTENT: + CSSStyleProperty.setShorthandPlaceContent(longhandProperties, normalizedValue); + break;webf/lib/src/rendering/grid.dart (2)
64-85: Profiling/logging utilities look fine; consider avoiding noisyinfoby default.
_gridLog()now correctly gates onDebugFlags.enableCssGridLayout, and profiling is independently gated. If profiling is intended for developer builds only, considerfiner/fineinstead ofinfo, or additionally gate on!kReleaseMode.
334-528: Repeat materialization: good direction; beware arbitrary repeat cap + unusedaxisparameter.
_repeatCountFor()clamps to<=100(Line 427). If this is a safety limit, consider documenting it and/or making it configurable; otherwise it can break legitimate layouts._materializeTrackList(..., Axis axis)doesn’t useaxis(Line 338). Remove it or use it (e.g., for axis-specific sizing semantics).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (46)
integration_tests/snapshots/css/css-grid/auto-fit-place-content.ts.a6c2222e1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-fit-place-content.ts.f087def31.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.3227b02f1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.3388b1411.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.4a877ef31.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.5f7d60ae1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.668a020a1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.6d96d8481.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.727b4eaf1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.820677411.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.8d64c3a21.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.8e58c9291.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.a10effd91.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.b113a44f1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.b85971bd1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.bafeabf01.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.cb1f36ea1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.dd0f2f661.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.e3974eb21.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.e54a53621.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.ec87fd651.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.fe967fa01.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/basic-concepts.ts.4d9996cd1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/basic-concepts.ts.5379f9931.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/dense-flow-dashboard.ts.b4a69b6a1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/grid-shorthand.ts.31c543121.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/grid-shorthand.ts.84c447fb1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/grid-shorthand.ts.f3df68fd1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/grid-template-shorthand.ts.838de3931.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/grid-template-shorthand.ts.f7314e031.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/template-areas.ts.532facab1.pngis excluded by!**/*.pngintegration_tests/snapshots/dom/elements/canvas/line_dash.ts.11b5b7ab1.pngis excluded by!**/*.pngintegration_tests/snapshots/dom/elements/canvas/line_dash.ts.bce7d9111.pngis excluded by!**/*.pngwebf_apps/nextjs-ssr-project/public/file.svgis excluded by!**/*.svgwebf_apps/nextjs-ssr-project/public/globe.svgis excluded by!**/*.svgwebf_apps/nextjs-ssr-project/public/next.svgis excluded by!**/*.svgwebf_apps/nextjs-ssr-project/public/vercel.svgis excluded by!**/*.svgwebf_apps/nextjs-ssr-project/public/window.svgis excluded by!**/*.svgwebf_apps/nextjs-ssr-project/src/app/favicon.icois excluded by!**/*.icowebf_apps/react_project/public/favicon.icois excluded by!**/*.icowebf_apps/react_project/public/logo192.pngis excluded by!**/*.pngwebf_apps/react_project/public/logo512.pngis excluded by!**/*.pngwebf_apps/react_project/src/logo.svgis excluded by!**/*.svgwebf_apps/vue_project/public/favicon.icois excluded by!**/*.icowebf_apps/vue_project/src/assets/positioned_layout.pngis excluded by!**/*.pngwebf_apps/vue_project/src/assets/todomvc.pngis excluded by!**/*.png
📒 Files selected for processing (91)
.github/workflows/contributors.yml(1 hunks).github/workflows/release.yml(5 hunks).gitignore(1 hunks)CLAUDE.md(1 hunks)COPYING.LIB(0 hunks)CSS_GRID_PLAN.md(2 hunks)README.md(2 hunks)integration_tests/specs/css/css-grid/auto-fit-place-content.ts(1 hunks)integration_tests/specs/css/css-grid/auto-placement.ts(3 hunks)integration_tests/specs/css/css-grid/basic-concepts.ts(1 hunks)integration_tests/specs/css/css-grid/dense-flow-dashboard.ts(1 hunks)integration_tests/specs/css/css-grid/grid-shorthand.ts(1 hunks)integration_tests/specs/css/css-grid/grid-template-shorthand.ts(1 hunks)integration_tests/specs/css/css-grid/template-areas-overlap.ts(1 hunks)integration_tests/specs/css/css-grid/template-areas.ts(1 hunks)integration_tests/specs/css/css-grid/track-sizing.ts(1 hunks)integration_tests/specs/css/css-text/line-join.ts(7 hunks)webf/example/pubspec.yaml(1 hunks)webf/integration_test/pubspec.yaml(1 hunks)webf/lib/src/css/computed_style_declaration.dart(2 hunks)webf/lib/src/css/flexbox.dart(4 hunks)webf/lib/src/css/grid.dart(6 hunks)webf/lib/src/css/keywords.dart(1 hunks)webf/lib/src/css/render_style.dart(10 hunks)webf/lib/src/css/style_declaration.dart(5 hunks)webf/lib/src/css/style_property.dart(3 hunks)webf/lib/src/foundation/debug_flags.dart(1 hunks)webf/lib/src/rendering/grid.dart(16 hunks)webf/pubspec.yaml(1 hunks)webf/test/src/css/grid_computed_style_test.dart(3 hunks)webf/test/src/rendering/css_grid_basic_layout_test.dart(2 hunks)webf_apps/nextjs-ssr-project/.gitignore(0 hunks)webf_apps/nextjs-ssr-project/README.md(0 hunks)webf_apps/nextjs-ssr-project/WEBF_TESTING.md(0 hunks)webf_apps/nextjs-ssr-project/next.config.ts(0 hunks)webf_apps/nextjs-ssr-project/package.json(0 hunks)webf_apps/nextjs-ssr-project/src/app/client-component/page.tsx(0 hunks)webf_apps/nextjs-ssr-project/src/app/globals.css(0 hunks)webf_apps/nextjs-ssr-project/src/app/hybrid/client-counter.tsx(0 hunks)webf_apps/nextjs-ssr-project/src/app/hybrid/page.tsx(0 hunks)webf_apps/nextjs-ssr-project/src/app/layout.tsx(0 hunks)webf_apps/nextjs-ssr-project/src/app/page.module.css(0 hunks)webf_apps/nextjs-ssr-project/src/app/page.tsx(0 hunks)webf_apps/nextjs-ssr-project/src/app/server-component/page.tsx(0 hunks)webf_apps/nextjs-ssr-project/tsconfig.json(0 hunks)webf_apps/react_project/.gitignore(0 hunks)webf_apps/react_project/README.md(0 hunks)webf_apps/react_project/package.json(0 hunks)webf_apps/react_project/public/index.html(0 hunks)webf_apps/react_project/public/manifest.json(0 hunks)webf_apps/react_project/public/robots.txt(0 hunks)webf_apps/react_project/src/App.css(0 hunks)webf_apps/react_project/src/App.test.tsx(0 hunks)webf_apps/react_project/src/App.tsx(0 hunks)webf_apps/react_project/src/Home.tsx(0 hunks)webf_apps/react_project/src/Pages/ArrayBufferDemo.tsx(0 hunks)webf_apps/react_project/src/Pages/LandingPage.tsx(0 hunks)webf_apps/react_project/src/Pages/ModalPopupDemo.tsx(0 hunks)webf_apps/react_project/src/index.css(0 hunks)webf_apps/react_project/src/index.tsx(0 hunks)webf_apps/react_project/src/react-app-env.d.ts(0 hunks)webf_apps/react_project/src/reportWebVitals.ts(0 hunks)webf_apps/react_project/src/setupTests.ts(0 hunks)webf_apps/react_project/src/utils/CreateComponent.tsx(0 hunks)webf_apps/react_project/tsconfig.json(0 hunks)webf_apps/vue_project/.gitignore(0 hunks)webf_apps/vue_project/README.md(0 hunks)webf_apps/vue_project/babel.config.js(0 hunks)webf_apps/vue_project/jsconfig.json(0 hunks)webf_apps/vue_project/package.json(0 hunks)webf_apps/vue_project/public/index.html(0 hunks)webf_apps/vue_project/src/App.vue(0 hunks)webf_apps/vue_project/src/Components/PositionExample.vue(0 hunks)webf_apps/vue_project/src/Components/TodoMVC/TodoFooter.vue(0 hunks)webf_apps/vue_project/src/Components/TodoMVC/TodoHeader.vue(0 hunks)webf_apps/vue_project/src/Components/TodoMVC/TodoItem.vue(0 hunks)webf_apps/vue_project/src/Components/TodoMVC/TodosComponent.vue(0 hunks)webf_apps/vue_project/src/Components/ViewCard.vue(0 hunks)webf_apps/vue_project/src/Pages/HomePage.vue(0 hunks)webf_apps/vue_project/src/Pages/PositionedLayout.vue(0 hunks)webf_apps/vue_project/src/Pages/TodoMVC.vue(0 hunks)webf_apps/vue_project/src/main.css(0 hunks)webf_apps/vue_project/src/main.js(0 hunks)webf_apps/vue_project/vue.config.js(0 hunks)webf_cupertino_ui/example/pubspec.yaml(1 hunks)webf_cupertino_ui/pubspec.yaml(2 hunks)webf_modules/README.md(2 hunks)webf_modules/deeplink/README.md(1 hunks)webf_modules/deeplink/pubspec.yaml(2 hunks)webf_modules/share/README.md(1 hunks)webf_modules/share/pubspec.yaml(2 hunks)
💤 Files with no reviewable changes (54)
- webf_apps/react_project/README.md
- webf_apps/react_project/src/Pages/LandingPage.tsx
- webf_apps/vue_project/src/Pages/HomePage.vue
- webf_apps/nextjs-ssr-project/src/app/hybrid/page.tsx
- webf_apps/nextjs-ssr-project/src/app/page.tsx
- webf_apps/nextjs-ssr-project/package.json
- webf_apps/vue_project/src/App.vue
- webf_apps/react_project/src/index.tsx
- webf_apps/react_project/.gitignore
- webf_apps/nextjs-ssr-project/src/app/page.module.css
- webf_apps/nextjs-ssr-project/src/app/hybrid/client-counter.tsx
- webf_apps/nextjs-ssr-project/src/app/server-component/page.tsx
- webf_apps/react_project/src/index.css
- webf_apps/vue_project/src/Components/TodoMVC/TodoHeader.vue
- webf_apps/vue_project/README.md
- webf_apps/nextjs-ssr-project/WEBF_TESTING.md
- webf_apps/vue_project/src/Components/ViewCard.vue
- webf_apps/vue_project/babel.config.js
- webf_apps/react_project/src/reportWebVitals.ts
- webf_apps/nextjs-ssr-project/README.md
- webf_apps/nextjs-ssr-project/src/app/client-component/page.tsx
- webf_apps/react_project/src/Home.tsx
- webf_apps/nextjs-ssr-project/src/app/layout.tsx
- webf_apps/react_project/src/App.test.tsx
- webf_apps/vue_project/jsconfig.json
- webf_apps/vue_project/src/Components/TodoMVC/TodoItem.vue
- webf_apps/vue_project/src/main.css
- webf_apps/vue_project/vue.config.js
- webf_apps/react_project/package.json
- webf_apps/vue_project/src/main.js
- webf_apps/vue_project/src/Components/TodoMVC/TodosComponent.vue
- webf_apps/react_project/src/App.css
- webf_apps/react_project/public/manifest.json
- webf_apps/vue_project/src/Pages/PositionedLayout.vue
- webf_apps/react_project/src/App.tsx
- webf_apps/nextjs-ssr-project/src/app/globals.css
- webf_apps/react_project/public/index.html
- webf_apps/react_project/src/Pages/ModalPopupDemo.tsx
- webf_apps/vue_project/public/index.html
- webf_apps/vue_project/src/Pages/TodoMVC.vue
- webf_apps/vue_project/src/Components/PositionExample.vue
- webf_apps/vue_project/package.json
- webf_apps/nextjs-ssr-project/tsconfig.json
- COPYING.LIB
- webf_apps/react_project/tsconfig.json
- webf_apps/nextjs-ssr-project/next.config.ts
- webf_apps/react_project/src/react-app-env.d.ts
- webf_apps/nextjs-ssr-project/.gitignore
- webf_apps/vue_project/.gitignore
- webf_apps/react_project/src/setupTests.ts
- webf_apps/react_project/src/utils/CreateComponent.tsx
- webf_apps/react_project/src/Pages/ArrayBufferDemo.tsx
- webf_apps/vue_project/src/Components/TodoMVC/TodoFooter.vue
- webf_apps/react_project/public/robots.txt
🧰 Additional context used
📓 Path-based instructions (10)
**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.dart: Always free allocated memory in Dart FFI
Usemalloc.free()fortoNativeUtf8()allocations in Dart FFI
Files:
webf/lib/src/css/flexbox.dartwebf/lib/src/css/keywords.dartwebf/test/src/css/grid_computed_style_test.dartwebf/lib/src/foundation/debug_flags.dartwebf/lib/src/css/style_declaration.dartwebf/lib/src/css/render_style.dartwebf/lib/src/css/grid.dartwebf/test/src/rendering/css_grid_basic_layout_test.dartwebf/lib/src/css/computed_style_declaration.dartwebf/lib/src/css/style_property.dartwebf/lib/src/rendering/grid.dart
**/*.{dart,cc,h}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{dart,cc,h}: Track pointer ownership in callbacks
Document memory ownership clearly in FFI code
Files:
webf/lib/src/css/flexbox.dartwebf/lib/src/css/keywords.dartwebf/test/src/css/grid_computed_style_test.dartwebf/lib/src/foundation/debug_flags.dartwebf/lib/src/css/style_declaration.dartwebf/lib/src/css/render_style.dartwebf/lib/src/css/grid.dartwebf/test/src/rendering/css_grid_basic_layout_test.dartwebf/lib/src/css/computed_style_declaration.dartwebf/lib/src/css/style_property.dartwebf/lib/src/rendering/grid.dart
webf/**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
Use
flutter testcommand to run Dart tests in the webf package
webf/**/*.dart: Follow rules in webf/analysis_options.yaml for Dart code style
Use single quotes for strings in Dart code
File names must use snake_case in Dart
Class names must use PascalCase in Dart
Variables and functions must use camelCase in Dart
Prefer final fields when applicable in Dart code
Lines should be max 120 characters in Dart code
Always free allocated memory in Dart FFI using malloc.free() for toNativeUtf8() allocations
Free FFI allocated memory in finally blocks to ensure cleanup on exceptions
Track ownership of allocated pointers in FFI callbacks
Free NativeValue pointers after converting with fromNativeValue in FFI code
Document memory ownership clearly in FFI async callbacks
Implement WidgetElement to create custom Flutter widgets integrated into WebF's DOM tree
Register custom WidgetElements using WidgetElementRegistry.register(tagName, builder)
Override buildWidget(BuildContext context) method in WidgetElement to build the Flutter widget
Call updateWidget() when attributes change in WidgetElement implementations
Dispose controllers and subscriptions in WidgetElement for memory management
Follow W3C event standards when dispatching events from WidgetElement
Minimize widget rebuilds in WidgetElement for performance optimization
Implement ARIA attributes in WidgetElement when applicable for accessibilityDart code in webf module must follow naming conventions: snake_case for file names, PascalCase for classes, and camelCase for class members
Files:
webf/lib/src/css/flexbox.dartwebf/lib/src/css/keywords.dartwebf/test/src/css/grid_computed_style_test.dartwebf/lib/src/foundation/debug_flags.dartwebf/lib/src/css/style_declaration.dartwebf/lib/src/css/render_style.dartwebf/lib/src/css/grid.dartwebf/test/src/rendering/css_grid_basic_layout_test.dartwebf/lib/src/css/computed_style_declaration.dartwebf/lib/src/css/style_property.dartwebf/lib/src/rendering/grid.dart
webf/lib/src/css/**/*.dart
📄 CodeRabbit inference engine (webf/CLAUDE.md)
Use CSSRenderStyle for style computation and storage in Dart CSS code
Files:
webf/lib/src/css/flexbox.dartwebf/lib/src/css/keywords.dartwebf/lib/src/css/style_declaration.dartwebf/lib/src/css/render_style.dartwebf/lib/src/css/grid.dartwebf/lib/src/css/computed_style_declaration.dartwebf/lib/src/css/style_property.dart
integration_tests/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
integration_tests/**/*.ts: Write integration tests for visual regression testing in TypeScript
Use snapshot testing for integration tests
Files:
integration_tests/specs/css/css-text/line-join.tsintegration_tests/specs/css/css-grid/dense-flow-dashboard.tsintegration_tests/specs/css/css-grid/track-sizing.tsintegration_tests/specs/css/css-grid/grid-shorthand.tsintegration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/basic-concepts.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/template-areas-overlap.tsintegration_tests/specs/css/css-grid/auto-fit-place-content.tsintegration_tests/specs/css/css-grid/template-areas.ts
integration_tests/specs/**/*.ts
📄 CodeRabbit inference engine (integration_tests/CLAUDE.md)
integration_tests/specs/**/*.ts: Place tests in appropriate directories underspecs/(css/, dom/, or window/)
Use TypeScript (.ts extension) for test files
Usedone()callback for async tests
Usesnapshot()for visual regression tests to capture current rendering
UsesimulateClickwith coordinates for hit testing tests
Test assets should reference files inassets/directory
Usefdescribe()instead ofdescribe()to run only specific test specs (Jasmine feature)
Usefit()instead ofit()to run only specific test cases
Snapshots are stored as images for comparison and failed snapshots generate diff images
The max width of testing window is 340px
Test specs will always pass if there are no existing snapshots
Group related tests in describe blocks
Each test should be independent
Remove created elements after tests (test cleanup)
Use clear, descriptive test names
Test behavior, not implementation
Include edge cases and error conditions in tests
Batch DOM operations to minimize reflows
Use async/await and proper async patterns for asynchronous operations in tests
Measure operations usingperformance.now()for timing in performance-critical tests
Files:
integration_tests/specs/css/css-text/line-join.tsintegration_tests/specs/css/css-grid/dense-flow-dashboard.tsintegration_tests/specs/css/css-grid/track-sizing.tsintegration_tests/specs/css/css-grid/grid-shorthand.tsintegration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/basic-concepts.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/template-areas-overlap.tsintegration_tests/specs/css/css-grid/auto-fit-place-content.tsintegration_tests/specs/css/css-grid/template-areas.ts
webf/**/*_test.dart
📄 CodeRabbit inference engine (CLAUDE.md)
Use Flutter widget testing for Dart code in the webf package
Files:
webf/test/src/css/grid_computed_style_test.dartwebf/test/src/rendering/css_grid_basic_layout_test.dart
webf/test/**/*_test.dart
📄 CodeRabbit inference engine (webf/CLAUDE.md)
webf/test/**/*_test.dart: Use WebFWidgetTestUtils.prepareWidgetTest() to test HTML/CSS rendering in widget unit tests
Access render objects in tests to verify layout calculations
Call setupTest() in setUpAll() method for one-time setup in unit tests
When testing with WebFController, wait for initialization with: await controller.controlledInitCompleter.future
Use mock bundles from test/src/foundation/mock_bundle.dart for testing in unit tests
Files:
webf/test/src/css/grid_computed_style_test.dartwebf/test/src/rendering/css_grid_basic_layout_test.dart
webf/test/**/*.dart
📄 CodeRabbit inference engine (AGENTS.md)
Dart/Flutter widget and unit tests must be placed in
webf/test/and useWebFWidgetTestUtilsandpumpAndSettle()where needed
Files:
webf/test/src/css/grid_computed_style_test.dartwebf/test/src/rendering/css_grid_basic_layout_test.dart
webf/lib/src/rendering/**/*.dart
📄 CodeRabbit inference engine (webf/CLAUDE.md)
Use RenderBoxModel as base class for layout in Dart rendering code
Files:
webf/lib/src/rendering/grid.dart
🧠 Learnings (47)
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: No build needed for Dart-only changes in webf/ Applied to files:
webf_modules/deeplink/README.mdwebf/pubspec.yaml.github/workflows/release.ymlwebf_cupertino_ui/example/pubspec.yamlwebf/integration_test/pubspec.yamlwebf_modules/deeplink/pubspec.yamlCLAUDE.mdwebf_modules/share/README.mdwebf_cupertino_ui/pubspec.yamlwebf_modules/README.mdREADME.mdwebf_modules/share/pubspec.yamlwebf/example/pubspec.yaml
📚 Learning: 2025-12-08T23:26:54.692Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-08T23:26:54.692Z Learning: Applies to webf/**/*_test.dart : Use Flutter widget testing for Dart code in the webf package Applied to files:
webf_modules/deeplink/README.mdwebf/pubspec.yamlwebf/test/src/css/grid_computed_style_test.dartwebf_cupertino_ui/example/pubspec.yamlwebf/integration_test/pubspec.yamlwebf_modules/deeplink/pubspec.yamlCLAUDE.mdwebf_modules/share/README.mdwebf_cupertino_ui/pubspec.yamlwebf_modules/README.mdREADME.mdwebf_modules/share/pubspec.yamlwebf/test/src/rendering/css_grid_basic_layout_test.dartwebf/example/pubspec.yaml
📚 Learning: 2025-12-08T23:26:54.692Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-08T23:26:54.692Z Learning: Applies to webf/**/*.dart : Use `flutter test` command to run Dart tests in the webf package Applied to files:
webf_modules/deeplink/README.mdwebf/pubspec.yaml.github/workflows/release.ymlwebf_cupertino_ui/example/pubspec.yamlwebf/integration_test/pubspec.yamlwebf_modules/deeplink/pubspec.yamlCLAUDE.mdwebf_modules/share/README.mdwebf_cupertino_ui/pubspec.yamlwebf_modules/README.mdwebf_modules/share/pubspec.yamlwebf/example/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/**/*.dart : Follow rules in webf/analysis_options.yaml for Dart code style Applied to files:
webf_modules/deeplink/README.mdwebf/pubspec.yamlwebf/test/src/css/grid_computed_style_test.dartwebf_cupertino_ui/example/pubspec.yamlwebf/integration_test/pubspec.yamlwebf_modules/deeplink/pubspec.yamlCLAUDE.mdwebf_modules/share/README.mdwebf_cupertino_ui/pubspec.yamlwebf_modules/README.mdwebf_modules/share/pubspec.yamlwebf/lib/src/css/grid.dartwebf/example/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Run Flutter dart tests with: cd webf && flutter test Applied to files:
webf_modules/deeplink/README.mdwebf/pubspec.yaml.github/workflows/release.ymlwebf_cupertino_ui/example/pubspec.yamlwebf/integration_test/pubspec.yamlwebf_modules/deeplink/pubspec.yamlCLAUDE.mdwebf_modules/share/README.mdwebf_cupertino_ui/pubspec.yamlwebf_modules/README.mdwebf_modules/share/pubspec.yamlwebf/example/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/lib/src/rendering/**/*.dart : Use RenderBoxModel as base class for layout in Dart rendering code Applied to files:
webf/lib/src/css/flexbox.dartwebf/lib/src/css/grid.dartwebf/test/src/rendering/css_grid_basic_layout_test.dartwebf/lib/src/rendering/grid.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/lib/src/css/**/*.dart : Use CSSRenderStyle for style computation and storage in Dart CSS code Applied to files:
webf/lib/src/css/flexbox.dartwebf/lib/src/css/keywords.dartwebf/test/src/css/grid_computed_style_test.dartwebf/lib/src/foundation/debug_flags.dartwebf/lib/src/css/style_declaration.dartwebf/lib/src/css/render_style.dartwebf/lib/src/css/grid.dartwebf/test/src/rendering/css_grid_basic_layout_test.dartwebf/lib/src/css/computed_style_declaration.dartwebf/lib/src/css/style_property.dartwebf/lib/src/rendering/grid.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/test/**/*_test.dart : Access render objects in tests to verify layout calculations Applied to files:
webf/lib/src/css/flexbox.dartwebf/test/src/css/grid_computed_style_test.dartwebf/test/src/rendering/css_grid_basic_layout_test.dartwebf/lib/src/rendering/grid.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/**/*.dart : Call updateWidget() when attributes change in WidgetElement implementations Applied to files:
webf/lib/src/css/flexbox.dart
📚 Learning: 2025-12-08T23:26:54.693Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-08T23:26:54.693Z Learning: Clarify in documentation that WebF builds Flutter apps, not web apps Applied to files:
webf/pubspec.yaml.github/workflows/release.ymlwebf_modules/deeplink/pubspec.yamlwebf_cupertino_ui/pubspec.yamlwebf_modules/README.mdREADME.mdwebf_modules/share/pubspec.yamlwebf/example/pubspec.yaml
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Use async/await and proper async patterns for asynchronous operations in tests Applied to files:
integration_tests/specs/css/css-text/line-join.tsintegration_tests/specs/css/css-grid/auto-placement.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Use `done()` callback for async tests Applied to files:
integration_tests/specs/css/css-text/line-join.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Use `snapshot()` for visual regression tests to capture current rendering Applied to files:
integration_tests/specs/css/css-text/line-join.tsintegration_tests/specs/css/css-grid/dense-flow-dashboard.tsintegration_tests/specs/css/css-grid/track-sizing.tsintegration_tests/specs/css/css-grid/grid-shorthand.tsintegration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/basic-concepts.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/template-areas-overlap.tsintegration_tests/specs/css/css-grid/auto-fit-place-content.tsintegration_tests/specs/css/css-grid/template-areas.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Snapshots are stored as images for comparison and failed snapshots generate diff images Applied to files:
integration_tests/specs/css/css-text/line-join.tsintegration_tests/specs/css/css-grid/dense-flow-dashboard.tsintegration_tests/specs/css/css-grid/grid-shorthand.tsintegration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/basic-concepts.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/template-areas-overlap.tsintegration_tests/specs/css/css-grid/auto-fit-place-content.tsintegration_tests/specs/css/css-grid/template-areas.ts
📚 Learning: 2025-12-08T23:26:54.692Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-08T23:26:54.692Z Learning: Applies to integration_tests/**/*.ts : Use snapshot testing for integration tests Applied to files:
integration_tests/specs/css/css-text/line-join.tsintegration_tests/specs/css/css-grid/dense-flow-dashboard.tsintegration_tests/specs/css/css-grid/grid-shorthand.tsintegration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/basic-concepts.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/template-areas-overlap.tsintegration_tests/specs/css/css-grid/auto-fit-place-content.tsintegration_tests/specs/css/css-grid/template-areas.ts
📚 Learning: 2025-12-08T23:26:54.692Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-08T23:26:54.692Z Learning: Applies to integration_tests/**/*.ts : Write integration tests for visual regression testing in TypeScript Applied to files:
integration_tests/specs/css/css-text/line-join.tsintegration_tests/specs/css/css-grid/dense-flow-dashboard.tsintegration_tests/specs/css/css-grid/track-sizing.tsintegration_tests/specs/css/css-grid/grid-shorthand.tsintegration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/basic-concepts.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/template-areas-overlap.tsintegration_tests/specs/css/css-grid/auto-fit-place-content.tsintegration_tests/specs/css/css-grid/template-areas.ts
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/integration_tests/specs/**/*.dart : Use snapshot tests in integration_tests/specs/ for visual regression testing with await snapshot() Applied to files:
integration_tests/specs/css/css-text/line-join.tswebf/test/src/rendering/css_grid_basic_layout_test.dart
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Batch DOM operations to minimize reflows Applied to files:
integration_tests/specs/css/css-text/line-join.tsintegration_tests/specs/css/css-grid/dense-flow-dashboard.tsintegration_tests/specs/css/css-grid/track-sizing.tsintegration_tests/specs/css/css-grid/grid-shorthand.tsintegration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/basic-concepts.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/template-areas-overlap.tsintegration_tests/specs/css/css-grid/auto-fit-place-content.tsintegration_tests/specs/css/css-grid/template-areas.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Test specs will always pass if there are no existing snapshots Applied to files:
integration_tests/specs/css/css-text/line-join.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/template-areas-overlap.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Place tests in appropriate directories under `specs/` (css/, dom/, or window/) Applied to files:
integration_tests/specs/css/css-text/line-join.tsintegration_tests/specs/css/css-grid/dense-flow-dashboard.tsintegration_tests/specs/css/css-grid/track-sizing.tsintegration_tests/specs/css/css-grid/grid-shorthand.tsintegration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/basic-concepts.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/template-areas-overlap.tsintegration_tests/specs/css/css-grid/auto-fit-place-content.tsintegration_tests/specs/css/css-grid/template-areas.ts
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Use widget unit tests to verify rendering changes with: cd webf && flutter test test/src/rendering/ Applied to files:
webf/test/src/css/grid_computed_style_test.dartwebf/integration_test/pubspec.yamlwebf/test/src/rendering/css_grid_basic_layout_test.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/test/**/*_test.dart : Use WebFWidgetTestUtils.prepareWidgetTest() to test HTML/CSS rendering in widget unit tests Applied to files:
webf/test/src/css/grid_computed_style_test.dartwebf/test/src/rendering/css_grid_basic_layout_test.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Run widget unit tests with: cd webf && flutter test test/src/rendering/ Applied to files:
webf/test/src/css/grid_computed_style_test.dartwebf_cupertino_ui/example/pubspec.yamlwebf/test/src/rendering/css_grid_basic_layout_test.dart
📚 Learning: 2025-12-08T23:28:11.643Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-12-08T23:28:11.643Z Learning: Applies to webf/test/**/*.dart : Dart/Flutter widget and unit tests must be placed in `webf/test/` and use `WebFWidgetTestUtils` and `pumpAndSettle()` where needed Applied to files:
webf/test/src/css/grid_computed_style_test.dartwebf/integration_test/pubspec.yamlwebf_modules/deeplink/pubspec.yamlwebf_modules/share/pubspec.yamlwebf/test/src/rendering/css_grid_basic_layout_test.dart
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : The max width of testing window is 340px Applied to files:
integration_tests/specs/css/css-grid/dense-flow-dashboard.tsintegration_tests/specs/css/css-grid/track-sizing.tsintegration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/auto-fit-place-content.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Test behavior, not implementation Applied to files:
integration_tests/specs/css/css-grid/dense-flow-dashboard.tsintegration_tests/specs/css/css-grid/track-sizing.tsintegration_tests/specs/css/css-grid/grid-shorthand.tsintegration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/basic-concepts.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/template-areas-overlap.tsintegration_tests/specs/css/css-grid/auto-fit-place-content.tsintegration_tests/specs/css/css-grid/template-areas.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Remove created elements after tests (test cleanup) Applied to files:
integration_tests/specs/css/css-grid/dense-flow-dashboard.tsintegration_tests/specs/css/css-grid/basic-concepts.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/template-areas-overlap.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Use clear, descriptive test names Applied to files:
integration_tests/specs/css/css-grid/dense-flow-dashboard.tsintegration_tests/specs/css/css-grid/track-sizing.tsintegration_tests/specs/css/css-grid/grid-shorthand.tsintegration_tests/specs/css/css-grid/basic-concepts.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/template-areas.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Measure operations using `performance.now()` for timing in performance-critical tests Applied to files:
integration_tests/specs/css/css-grid/track-sizing.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Include edge cases and error conditions in tests Applied to files:
integration_tests/specs/css/css-grid/track-sizing.tsintegration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/template-areas-overlap.tsintegration_tests/specs/css/css-grid/template-areas.ts
📚 Learning: 2025-12-08T23:28:11.643Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-12-08T23:28:11.643Z Learning: Applies to cli/test/**/*.test.ts : TypeScript test files must use `.test.ts` extension and target at least 70% code coverage for core modules Applied to files:
integration_tests/specs/css/css-grid/track-sizing.ts
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Lint with: npm run lint (runs flutter analyze in webf directory) Applied to files:
.github/workflows/release.ymlwebf_modules/deeplink/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Run integration tests with: cd webf && flutter test integration_test/ Applied to files:
.github/workflows/release.ymlwebf_cupertino_ui/example/pubspec.yamlwebf/integration_test/pubspec.yamlwebf_modules/deeplink/pubspec.yamlwebf_cupertino_ui/pubspec.yamlwebf_modules/share/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/**/*.dart : Prefer final fields when applicable in Dart code Applied to files:
webf_cupertino_ui/example/pubspec.yamlwebf_modules/deeplink/pubspec.yamlCLAUDE.mdwebf_cupertino_ui/pubspec.yamlwebf_modules/README.mdwebf_modules/share/pubspec.yaml
📚 Learning: 2025-11-26T10:24:24.258Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf_apps/vue-cupertino-gallery/CLAUDE.md:0-0 Timestamp: 2025-11-26T10:24:24.258Z Learning: Applies to webf_apps/vue-cupertino-gallery/**/*.vue : Use WebF Cupertino components with the `flutter-cupertino-` prefix Applied to files:
webf_cupertino_ui/example/pubspec.yamlwebf/integration_test/pubspec.yamlwebf_cupertino_ui/pubspec.yamlwebf_modules/README.mdwebf_modules/share/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/**/*.dart : Implement WidgetElement to create custom Flutter widgets integrated into WebF's DOM tree Applied to files:
webf_cupertino_ui/example/pubspec.yamlwebf/integration_test/pubspec.yamlwebf_modules/deeplink/pubspec.yamlwebf_modules/share/README.mdwebf_cupertino_ui/pubspec.yamlwebf_modules/README.mdREADME.mdwebf_modules/share/pubspec.yamlwebf/example/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Run a single Flutter test with: cd webf && flutter test test/path/to/test_file.dart Applied to files:
webf_cupertino_ui/example/pubspec.yamlwebf/integration_test/pubspec.yamlwebf_modules/deeplink/pubspec.yamlwebf_cupertino_ui/pubspec.yamlwebf_modules/share/pubspec.yamlwebf/example/pubspec.yaml
📚 Learning: 2025-12-08T23:28:11.643Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-12-08T23:28:11.643Z Learning: Applies to webf/integration_test/**/*.dart : Dart/Flutter integration tests must be placed in `webf/integration_test/` directory Applied to files:
webf/integration_test/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Use integration tests for end-to-end verification with: cd webf && flutter test integration_test/ Applied to files:
webf/integration_test/pubspec.yaml
📚 Learning: 2025-12-08T23:28:11.643Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-12-08T23:28:11.643Z Learning: Applies to webf/**/*.dart : Dart code in webf module must follow naming conventions: snake_case for file names, PascalCase for classes, and camelCase for class members Applied to files:
webf/integration_test/pubspec.yamlwebf_modules/deeplink/pubspec.yamlCLAUDE.mdwebf_cupertino_ui/pubspec.yamlwebf_modules/README.mdwebf_modules/share/pubspec.yamlwebf/example/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/**/*.dart : Use single quotes for strings in Dart code Applied to files:
webf_modules/deeplink/pubspec.yamlwebf_cupertino_ui/pubspec.yamlwebf_modules/share/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/**/*.dart : Minimize widget rebuilds in WidgetElement for performance optimization Applied to files:
webf/lib/src/foundation/debug_flags.dart
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Group related tests in describe blocks Applied to files:
integration_tests/specs/css/css-grid/basic-concepts.tsintegration_tests/specs/css/css-grid/auto-fit-place-content.tsintegration_tests/specs/css/css-grid/template-areas.ts
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/**/*.dart : Variables and functions must use camelCase in Dart Applied to files:
webf_cupertino_ui/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/lib/bridge.dart : lib/bridge.dart contains FFI bindings to C++ bridge Applied to files:
webf_modules/README.md
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Use `fit()` instead of `it()` to run only specific test cases Applied to files:
integration_tests/specs/css/css-grid/auto-fit-place-content.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Test assets should reference files in `assets/` directory Applied to files:
integration_tests/specs/css/css-grid/auto-fit-place-content.ts
🧬 Code graph analysis (1)
integration_tests/specs/css/css-text/line-join.ts (1)
integration_tests/tools/spec-preview/runtime.js (1)
done(547-553)
🪛 actionlint (1.7.9)
.github/workflows/release.yml
840-840: property "version" is not defined in object type {}
(expression)
🪛 LanguageTool
README.md
[uncategorized] ~250-~250: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...exibility for different use cases: ### Open Source License (GPL-3.0) WebF is licensed und...
(EN_COMPOUND_ADJECTIVE_INTERNAL)
🪛 markdownlint-cli2 (0.18.1)
CSS_GRID_PLAN.md
81-81: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
README.md
135-135: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
136-136: Unordered list indentation
Expected: 0; Actual: 3
(MD007, ul-indent)
137-137: Unordered list indentation
Expected: 0; Actual: 3
(MD007, ul-indent)
139-139: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
145-145: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
152-152: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
153-153: Unordered list indentation
Expected: 0; Actual: 3
(MD007, ul-indent)
154-154: Unordered list indentation
Expected: 0; Actual: 3
(MD007, ul-indent)
155-155: Unordered list indentation
Expected: 0; Actual: 3
(MD007, ul-indent)
242-242: Images should have alternate text (alt text)
(MD045, no-alt-text)
290-290: Bare URL used
(MD034, no-bare-urls)
301-301: Bare URL used
(MD034, no-bare-urls)
⏰ 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). (4)
- GitHub Check: build_windows_bridge (Debug)
- GitHub Check: Analyze (rust)
- GitHub Check: Analyze (c-cpp)
- GitHub Check: Analyze (javascript-typescript)
| webf: | ||
| hosted: https://dart.cloudsmith.io/openwebf/packages/ | ||
| version: ^0.23.7 | ||
| webf: ^0.23.7 |
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.
🧩 Analysis chain
🏁 Script executed:
# Find all pubspec.yaml files and examine webf version constraints find . -name "pubspec.yaml" -type f | head -20Repository: openwebf/webf
Length of output: 533
🏁 Script executed:
# Search for webf version constraints across pubspec.yaml files rg 'webf:\s*\^' --type yamlRepository: openwebf/webf
Length of output: 467
🏁 Script executed:
# Check publish_to settings across the repo rg 'publish_to' --type yamlRepository: openwebf/webf
Length of output: 660
🏁 Script executed:
# Check if there's a reason for the version difference in webf_cupertino_ui cd webf_cupertino_ui && git log --oneline -20 pubspec.yaml 2>/dev/null || echo "No git history available"Repository: openwebf/webf
Length of output: 84
🏁 Script executed:
# Compare webf_cupertino_ui/pubspec.yaml with webf_modules/deeplink/pubspec.yaml structure echo "=== webf_cupertino_ui/pubspec.yaml (lines with webf) ===" && \ rg -A 2 -B 2 'webf:' webf_cupertino_ui/pubspec.yaml && \ echo -e "\n=== webf_modules/deeplink/pubspec.yaml (lines with webf) ===" && \ rg -A 2 -B 2 'webf:' webf_modules/deeplink/pubspec.yamlRepository: openwebf/webf
Length of output: 327
🏁 Script executed:
# Check what changed in this PR for webf_cupertino_ui/pubspec.yaml git diff HEAD~1 webf_cupertino_ui/pubspec.yaml 2>/dev/null || echo "No prior commit available"Repository: openwebf/webf
Length of output: 82
Align webf dependency constraint with other modules
webf_cupertino_ui specifies ^0.23.7 while all other packages in the monorepo (webf_modules/deeplink, webf_modules/share, and tests) use ^0.23.10. This version skew can cause inconsistent dependency resolution. Notably, even webf_cupertino_ui/example uses ^0.23.10, suggesting the main package should be updated.
Update to ^0.23.10 to align with the rest of the codebase.
🤖 Prompt for AI Agents
In webf_cupertino_ui/pubspec.yaml around line 12, the webf dependency is pinned to ^0.23.7 which is out of sync with the rest of the monorepo that uses ^0.23.10; update the webf constraint to ^0.23.10 in this pubspec (and verify example and lockfiles if present) so all packages use the same version and run flutter pub get to refresh dependencies. | int? _resolveGridLineNumber( | ||
| GridPlacement placement, | ||
| int trackCount, { | ||
| Map<String, List<int>>? namedLines, | ||
| }) { | ||
| if (placement.kind != GridPlacementKind.line) return null; | ||
| if (placement.lineName != null && namedLines != null) { | ||
| final List<int>? indices = namedLines[placement.lineName!]; | ||
| if (indices != null && indices.isNotEmpty) { | ||
| final int occurrence = placement.lineNameOccurrence ?? 1; | ||
| if (occurrence == 0) return null; | ||
| int selectedIndex; | ||
| if (occurrence > 0) { | ||
| if (occurrence > indices.length) return null; | ||
| selectedIndex = indices[occurrence - 1]; | ||
| } else { | ||
| final int absOccurrence = -occurrence; | ||
| if (absOccurrence > indices.length) return null; | ||
| selectedIndex = indices[indices.length - absOccurrence]; | ||
| } | ||
| return selectedIndex + 1; | ||
| } | ||
| } | ||
| return null; | ||
| if (placement.line == null) return null; | ||
| final int raw = placement.line!; | ||
| if (raw > 0) { | ||
| return raw; | ||
| } | ||
| final int totalLines = math.max(trackCount, 0) + 1; | ||
| final int candidate = totalLines + 1 + raw; | ||
| return candidate.clamp(1, totalLines); | ||
| } | ||
| | ||
| int _resolveSpan(GridPlacement start, GridPlacement end) { | ||
| int? _resolveTrackIndexFromPlacement( | ||
| GridPlacement placement, | ||
| int trackCount, { | ||
| Map<String, List<int>>? namedLines, | ||
| }) { | ||
| final int? lineNumber = _resolveGridLineNumber(placement, trackCount, namedLines: namedLines); | ||
| if (lineNumber == null) return null; | ||
| return math.max(0, lineNumber - 1); | ||
| } | ||
| | ||
| int? _resolveLineRequirementIndex( | ||
| GridPlacement placement, | ||
| int trackCount, { | ||
| Map<String, List<int>>? namedLines, | ||
| }) { | ||
| if (placement.kind != GridPlacementKind.line) return null; | ||
| if (placement.lineName != null && namedLines != null) { | ||
| final List<int>? indices = namedLines[placement.lineName!]; | ||
| if (indices != null && indices.isNotEmpty) { | ||
| final int occurrence = placement.lineNameOccurrence ?? 1; | ||
| if (occurrence == 0) return null; | ||
| int selectedIndex; | ||
| if (occurrence > 0) { | ||
| if (occurrence > indices.length) return null; | ||
| selectedIndex = indices[occurrence - 1]; | ||
| } else { | ||
| final int absOccurrence = -occurrence; | ||
| if (absOccurrence > indices.length) return null; | ||
| selectedIndex = indices[indices.length - absOccurrence]; | ||
| } | ||
| return selectedIndex; | ||
| } | ||
| } | ||
| if (placement.line == null) return null; | ||
| final int raw = placement.line!; | ||
| if (raw > 0) { | ||
| return raw - 1; | ||
| } | ||
| final int totalLines = math.max(trackCount, 0) + 1; | ||
| final int candidate = totalLines + 1 + raw; | ||
| return math.max(candidate - 1, 0); | ||
| } |
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.
Cap/guard implicit track growth from extreme grid line numbers (potential DoS/OOM).
_resolveLineRequirementIndex() can return arbitrarily large indices for large positive placement.line, which later feeds _ensureImplicitColumns() and can allocate huge lists. Even if the spec allows implicit track creation, renderers typically enforce practical limits.
@@ int? _resolveLineRequirementIndex( @@ if (placement.line == null) return null; final int raw = placement.line!; + // Prevent pathological implicit track allocation from extreme line numbers. + const int kMaxGridLine = 1000; // consider centralizing as a DebugFlag or constant if (raw > 0) { - return raw - 1; + if (raw > kMaxGridLine) return null; + return raw - 1; } @@ final int totalLines = math.max(trackCount, 0) + 1; final int candidate = totalLines + 1 + raw; - return math.max(candidate - 1, 0); + final int clampedLine = candidate.clamp(1, totalLines); + return math.max(clampedLine - 1, 0); }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.
Actionable comments posted: 5
🧹 Nitpick comments (4)
integration_tests/specs/css/css-grid/auto-placement.ts (1)
645-645: Use strict equality operator.Prefer
===over==for type-safe comparisons.Apply this diff:
- if (i == 0) { + if (i === 0) {- if (i == 0) { + if (i === 0) {Also applies to: 675-675
webf/test/src/rendering/css_grid_basic_layout_test.dart (3)
115-166: Potential flake: singlepump()may not settle WebF layout before reading render offsets.
Most widget tests here immediately readRenderGridLayoutsizes/transforms afterawait tester.pump();. If WebF’s style/layout work completes in a later microtask/frame, these can become timing-sensitive.Consider switching to
await tester.pumpAndSettle();(or at least an additionalpump()) afterprepareWidgetTest()in these new tests.- await tester.pump(); + await tester.pumpAndSettle();
183-286: Avoid hardcodingrenderer.size.width == 360in layout tests.
These assertions can become brittle if the test harness viewport changes. If possible, derive the expected width from the prepared test environment (or just assert relative placement/offsets, which you already do well).- expect(renderer.size.width, equals(360)); + // Prefer asserting against the harness viewport width (if exposed by the test utils), + // or remove this and keep the placement assertions below.
481-750: Alignment/placement coverage is comprehensive; considerpumpAndSettle()for stability.
These tests coverjustify-content/*,align-content,justify-items/self,align-items/self, andplace-*well using offsets. Same timing note as earlier: switching topumpAndSettle()would reduce intermittent failures when reading transforms immediately after layout.- await tester.pump(); + await tester.pumpAndSettle();
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
integration_tests/snapshots/css/css-grid/auto-placement.ts.50195dd31.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.5ee42bbf1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.fc51ca2e1.pngis excluded by!**/*.png
📒 Files selected for processing (3)
integration_tests/specs/css/css-grid/auto-placement.ts(3 hunks)webf/lib/src/rendering/grid.dart(16 hunks)webf/test/src/rendering/css_grid_basic_layout_test.dart(2 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
integration_tests/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
integration_tests/**/*.ts: Write integration tests for visual regression testing in TypeScript
Use snapshot testing for integration tests
Files:
integration_tests/specs/css/css-grid/auto-placement.ts
integration_tests/specs/**/*.ts
📄 CodeRabbit inference engine (integration_tests/CLAUDE.md)
integration_tests/specs/**/*.ts: Place tests in appropriate directories underspecs/(css/, dom/, or window/)
Use TypeScript (.ts extension) for test files
Usedone()callback for async tests
Usesnapshot()for visual regression tests to capture current rendering
UsesimulateClickwith coordinates for hit testing tests
Test assets should reference files inassets/directory
Usefdescribe()instead ofdescribe()to run only specific test specs (Jasmine feature)
Usefit()instead ofit()to run only specific test cases
Snapshots are stored as images for comparison and failed snapshots generate diff images
The max width of testing window is 340px
Test specs will always pass if there are no existing snapshots
Group related tests in describe blocks
Each test should be independent
Remove created elements after tests (test cleanup)
Use clear, descriptive test names
Test behavior, not implementation
Include edge cases and error conditions in tests
Batch DOM operations to minimize reflows
Use async/await and proper async patterns for asynchronous operations in tests
Measure operations usingperformance.now()for timing in performance-critical tests
Files:
integration_tests/specs/css/css-grid/auto-placement.ts
**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.dart: Always free allocated memory in Dart FFI
Usemalloc.free()fortoNativeUtf8()allocations in Dart FFI
Files:
webf/test/src/rendering/css_grid_basic_layout_test.dartwebf/lib/src/rendering/grid.dart
**/*.{dart,cc,h}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{dart,cc,h}: Track pointer ownership in callbacks
Document memory ownership clearly in FFI code
Files:
webf/test/src/rendering/css_grid_basic_layout_test.dartwebf/lib/src/rendering/grid.dart
webf/**/*_test.dart
📄 CodeRabbit inference engine (CLAUDE.md)
Use Flutter widget testing for Dart code in the webf package
Files:
webf/test/src/rendering/css_grid_basic_layout_test.dart
webf/**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
Use
flutter testcommand to run Dart tests in the webf package
webf/**/*.dart: Follow rules in webf/analysis_options.yaml for Dart code style
Use single quotes for strings in Dart code
File names must use snake_case in Dart
Class names must use PascalCase in Dart
Variables and functions must use camelCase in Dart
Prefer final fields when applicable in Dart code
Lines should be max 120 characters in Dart code
Always free allocated memory in Dart FFI using malloc.free() for toNativeUtf8() allocations
Free FFI allocated memory in finally blocks to ensure cleanup on exceptions
Track ownership of allocated pointers in FFI callbacks
Free NativeValue pointers after converting with fromNativeValue in FFI code
Document memory ownership clearly in FFI async callbacks
Implement WidgetElement to create custom Flutter widgets integrated into WebF's DOM tree
Register custom WidgetElements using WidgetElementRegistry.register(tagName, builder)
Override buildWidget(BuildContext context) method in WidgetElement to build the Flutter widget
Call updateWidget() when attributes change in WidgetElement implementations
Dispose controllers and subscriptions in WidgetElement for memory management
Follow W3C event standards when dispatching events from WidgetElement
Minimize widget rebuilds in WidgetElement for performance optimization
Implement ARIA attributes in WidgetElement when applicable for accessibilityDart code in webf module must follow naming conventions: snake_case for file names, PascalCase for classes, and camelCase for class members
Files:
webf/test/src/rendering/css_grid_basic_layout_test.dartwebf/lib/src/rendering/grid.dart
webf/test/**/*_test.dart
📄 CodeRabbit inference engine (webf/CLAUDE.md)
webf/test/**/*_test.dart: Use WebFWidgetTestUtils.prepareWidgetTest() to test HTML/CSS rendering in widget unit tests
Access render objects in tests to verify layout calculations
Call setupTest() in setUpAll() method for one-time setup in unit tests
When testing with WebFController, wait for initialization with: await controller.controlledInitCompleter.future
Use mock bundles from test/src/foundation/mock_bundle.dart for testing in unit tests
Files:
webf/test/src/rendering/css_grid_basic_layout_test.dart
webf/test/**/*.dart
📄 CodeRabbit inference engine (AGENTS.md)
Dart/Flutter widget and unit tests must be placed in
webf/test/and useWebFWidgetTestUtilsandpumpAndSettle()where needed
Files:
webf/test/src/rendering/css_grid_basic_layout_test.dart
webf/lib/src/rendering/**/*.dart
📄 CodeRabbit inference engine (webf/CLAUDE.md)
Use RenderBoxModel as base class for layout in Dart rendering code
Files:
webf/lib/src/rendering/grid.dart
🧠 Learnings (18)
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Place tests in appropriate directories under `specs/` (css/, dom/, or window/) Applied to files:
integration_tests/specs/css/css-grid/auto-placement.ts
📚 Learning: 2025-12-08T23:26:54.692Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-08T23:26:54.692Z Learning: Applies to integration_tests/**/*.ts : Write integration tests for visual regression testing in TypeScript Applied to files:
integration_tests/specs/css/css-grid/auto-placement.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Batch DOM operations to minimize reflows Applied to files:
integration_tests/specs/css/css-grid/auto-placement.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Use async/await and proper async patterns for asynchronous operations in tests Applied to files:
integration_tests/specs/css/css-grid/auto-placement.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Include edge cases and error conditions in tests Applied to files:
integration_tests/specs/css/css-grid/auto-placement.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Use `snapshot()` for visual regression tests to capture current rendering Applied to files:
integration_tests/specs/css/css-grid/auto-placement.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Test behavior, not implementation Applied to files:
integration_tests/specs/css/css-grid/auto-placement.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Group related tests in describe blocks Applied to files:
integration_tests/specs/css/css-grid/auto-placement.ts
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/test/**/*_test.dart : Access render objects in tests to verify layout calculations Applied to files:
webf/test/src/rendering/css_grid_basic_layout_test.dartwebf/lib/src/rendering/grid.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Use widget unit tests to verify rendering changes with: cd webf && flutter test test/src/rendering/ Applied to files:
webf/test/src/rendering/css_grid_basic_layout_test.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/test/**/*_test.dart : Use WebFWidgetTestUtils.prepareWidgetTest() to test HTML/CSS rendering in widget unit tests Applied to files:
webf/test/src/rendering/css_grid_basic_layout_test.dart
📚 Learning: 2025-12-08T23:26:54.692Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-08T23:26:54.692Z Learning: Applies to webf/**/*_test.dart : Use Flutter widget testing for Dart code in the webf package Applied to files:
webf/test/src/rendering/css_grid_basic_layout_test.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/lib/src/rendering/**/*.dart : Use RenderBoxModel as base class for layout in Dart rendering code Applied to files:
webf/test/src/rendering/css_grid_basic_layout_test.dartwebf/lib/src/rendering/grid.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/integration_tests/specs/**/*.dart : Use snapshot tests in integration_tests/specs/ for visual regression testing with await snapshot() Applied to files:
webf/test/src/rendering/css_grid_basic_layout_test.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Run widget unit tests with: cd webf && flutter test test/src/rendering/ Applied to files:
webf/test/src/rendering/css_grid_basic_layout_test.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/lib/src/css/**/*.dart : Use CSSRenderStyle for style computation and storage in Dart CSS code Applied to files:
webf/test/src/rendering/css_grid_basic_layout_test.dartwebf/lib/src/rendering/grid.dart
📚 Learning: 2025-12-08T23:28:11.643Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-12-08T23:28:11.643Z Learning: Applies to webf/test/**/*.dart : Dart/Flutter widget and unit tests must be placed in `webf/test/` and use `WebFWidgetTestUtils` and `pumpAndSettle()` where needed Applied to files:
webf/test/src/rendering/css_grid_basic_layout_test.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/test/**/*_test.dart : Use mock bundles from test/src/foundation/mock_bundle.dart for testing in unit tests Applied to files:
webf/test/src/rendering/css_grid_basic_layout_test.dart
⏰ 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). (4)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: build_bridge
- GitHub Check: Analyze (c-cpp)
- GitHub Check: Analyze (rust)
🔇 Additional comments (22)
webf/test/src/rendering/css_grid_basic_layout_test.dart (3)
288-343: Dense auto-placement coverage looks solid.
The “gap fill” assertions validate both axis placement (dx/dy) and are resilient (no dependency on internal grid state).
344-403: Good end-to-end checks forgrid-template-areasandgrid-areashorthand.
Using render sizes + offsets provides stronger coverage than just parsing/serialization.
404-453: Please verify spec intent for invalid/reversed line ranges fallback.
grid-column: 5 / 2is treated as “auto placement” here (ending up in the second column). That’s plausible, but since this bakes in behavior, it’s worth validating against the CSS Grid spec / Chromium for the exact fallback rule you want WebF to match.webf/lib/src/rendering/grid.dart (19)
69-85: LGTM: Profiling infrastructure.The profiling infrastructure is well-designed with minimal overhead when disabled and a configurable threshold to reduce log noise.
87-161: LGTM: Line resolution with bounds clamping.The line resolution methods properly handle named lines, negative indices, and edge cases. The
clamp()calls (lines 117, 160) prevent out-of-bounds access, addressing the previously flagged DoS risk from extreme line numbers.
163-187: LGTM: Span resolution with invalid range handling.The span resolution correctly returns
0as a sentinel value whenendLine <= startLine(line 182), which the caller handles by resetting to auto-placement (lines 989-998). This addresses the past review feedback about reverse line ranges.
208-252: LGTM: Content alignment shift calculations.The justify-content and align-content shift methods now properly handle
spaceAroundandspaceEvenlycases (lines 221-226, 246-247), computing the correct leading offsets. This addresses the previously flagged missing distribution logic, which is fully implemented alongside the between-track distribution at lines 1323-1343.
273-342: LGTM: Alignment resolution helpers.The justify-self/align-self resolution and intra-cell alignment offset calculations are correctly implemented, properly handling auto, stretch, start, center, and end values.
344-462: LGTM: Track materialization with safety bounds.The track materialization logic properly handles repeat patterns, including auto-fill and auto-fit. The repeat count is sensibly clamped to [1, 100] (line 437) to prevent excessive memory allocation, and the breadth calculations correctly distinguish between flexible and rigid patterns.
464-538: LGTM: Track cloning and line name mapping.The track cloning logic correctly preserves leading/trailing line names and propagates the auto-fit flag. The line name map construction properly associates names with line indices for later resolution.
666-773: LGTM: Track sizing with flexible track support.The track resolution logic correctly handles all track types including GridMinMax and GridFitContent. The fraction distribution properly accounts for minimum sizes when max is flexible (lines 729-734, 756-758), ensuring tracks don't shrink below their minimums.
776-792: LGTM: Layout wrapper with error handling.The try-catch wrapper properly logs errors in non-release mode while still rethrowing, which aids debugging without swallowing exceptions.
794-920: LGTM: Layout initialization and track materialization.The initialization properly computes constraints, materializes track lists with profiling, and sets up auto-fit tracking arrays. The template areas support is correctly integrated (lines 822-824).
959-972: LGTM: Template area mapping.The template area override correctly maps
gridAreaNameto explicit line placements when a matching area is found intemplateAreaMap, with appropriate logging for matched and fallback cases.
974-1001: LGTM: Span resolution with invalid range handling.The span resolution correctly handles invalid column/row ranges (span <= 0) by resetting the placement to auto (lines 991-998), which is the appropriate behavior per the CSS Grid spec.
1072-1083: LGTM: Auto-fit usage tracking.The code correctly marks auto-fit columns and rows as used when items are placed in them, which is necessary for the subsequent collapse logic.
1105-1117: LGTM: GridFitContent dynamic sizing.The code correctly updates GridFitContent column sizes based on the preferred child width clamped by the fit-content limit, ensuring the track grows to accommodate content while respecting the specified limit.
1150-1171: LGTM: Stretch alignment constraints.The stretch alignment logic correctly computes min/max constraints based on cell dimensions and alignment settings, ensuring children stretch to fill their cells when appropriate.
1195-1215: LGTM: Alignment offset calculation.The intra-cell alignment offsets are correctly computed using the alignment helpers, properly positioning children within their cells according to justify-self and align-self values.
1265-1309: LGTM: Final size determination with definite dimensions.The final size computation correctly handles definite width/height from the style tree (lines 1277-1283, 1300-1304) and falls back to auto sizing rules for indefinite dimensions. The logic properly accounts for border-box sizing and ensures alignment properties operate against the correct container dimensions.
1314-1386: LGTM: Content alignment distribution.The justify-content and align-content distribution logic correctly computes the leading shift and between-track spacing for space-between, space-around, and space-evenly values (lines 1323-1369), and applies the offsets to all children (lines 1373-1386).
Note: This approval is for the distribution logic itself; the row count used for align-content distribution may be incorrect when auto-fit rows are collapsed (see separate comment).
1408-1459: LGTM: Helper methods.The helper methods for collecting children, resolving auto tracks, and ensuring implicit columns are straightforward and correctly implemented.
| | ||
| const cell = document.createElement('div'); | ||
| cell.style.height = '20px'; | ||
| cell.style.backgroundColor = 'red' |
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.
Fix syntax error: missing semicolon.
Missing semicolon after the string value 'red' in the backgroundColor assignment.
Apply this diff:
- cell.style.backgroundColor = 'red' + cell.style.backgroundColor = 'red';📝 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.
| cell.style.backgroundColor = 'red' | |
| cell.style.backgroundColor = 'red'; |
🤖 Prompt for AI Agents
In integration_tests/specs/css/css-grid/auto-placement.ts around line 269, the statement assigning cell.style.backgroundColor is missing a terminating semicolon; update the line to end with a semicolon (cell.style.backgroundColor = 'red';) so the file has valid syntax and no lint parse errors. | 'style', | ||
| 'display:grid;width:200px;grid-template-columns:repeat(auto-fit,40px);justify-content:center;column-gap:0;', | ||
| ); | ||
| grid.style.backgroundColor = 'lightgray' |
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.
Fix syntax errors: missing semicolons.
Missing semicolons after the string value 'lightgray' in the backgroundColor assignments.
Apply this diff:
- grid.style.backgroundColor = 'lightgray' + grid.style.backgroundColor = 'lightgray';- grid.style.backgroundColor = 'lightgray' + grid.style.backgroundColor = 'lightgray';Also applies to: 670-670
🤖 Prompt for AI Agents
In integration_tests/specs/css/css-grid/auto-placement.ts around line 640 (and also at line 670), there are missing semicolons after the backgroundColor assignment(s); add a trailing semicolon to each statement (e.g., change assignments ending with 'lightgray' to end with 'lightgray';) so the file has valid TypeScript/JavaScript syntax. | _GridCellPlacement _placeAutoItem({ | ||
| required List<List<bool>> occupancy, | ||
| required int columnCount, | ||
| required List<double> columnSizes, | ||
| required int explicitColumnCount, | ||
| required List<GridTrackSize> autoColumns, | ||
| required double? adjustedInnerWidth, | ||
| required int columnSpan, | ||
| required int rowSpan, | ||
| required int? explicitRow, | ||
| required int? explicitColumn, | ||
| required GridAutoFlow autoFlow, | ||
| required _GridAutoCursor cursor, | ||
| required bool hasDefiniteColumn, | ||
| required bool hasDefiniteRow, | ||
| required int explicitRowCount, | ||
| required int rowTrackCountForPlacement, | ||
| }) { | ||
| final bool dense = autoFlow == GridAutoFlow.rowDense || autoFlow == GridAutoFlow.columnDense; | ||
| final bool rowFlow = autoFlow == GridAutoFlow.row || autoFlow == GridAutoFlow.rowDense; | ||
| | ||
| final int colSpan = columnSpan.clamp(1, columnCount); | ||
| int columnCount = columnSizes.length; | ||
| final int colSpan = columnSpan.clamp(1, math.max(1, columnCount)); | ||
| final int rowSpanClamped = math.max(1, rowSpan); | ||
| | ||
| int startRow; | ||
| if (explicitRow != null) { | ||
| startRow = explicitRow; | ||
| } else if (rowFlow) { | ||
| if (dense || hasDefiniteColumn) { | ||
| if (rowFlow) { | ||
| int startRow; | ||
| if (explicitRow != null) { | ||
| startRow = explicitRow; | ||
| } else if (dense || hasDefiniteColumn) { | ||
| startRow = 0; | ||
| } else { | ||
| startRow = cursor.row; | ||
| } | ||
| } else { | ||
| startRow = cursor.row; | ||
| int row = math.max(0, startRow); | ||
| | ||
| while (true) { | ||
| _ensureOccupancyRows(occupancy, row + rowSpanClamped, columnCount); | ||
| final int columnStart = explicitColumn ?? | ||
| (!dense && explicitRow == null && !hasDefiniteColumn && row == cursor.row ? cursor.column : 0); | ||
| | ||
| for (int col = math.max(0, columnStart); col <= columnCount - colSpan; col++) { | ||
| if (_canPlace(occupancy, row, col, rowSpanClamped, colSpan, columnCount)) { | ||
| _markPlacement(occupancy, row, col, rowSpanClamped, colSpan); | ||
| if (explicitRow == null && !hasDefiniteColumn) { | ||
| cursor.row = row; | ||
| cursor.column = col + colSpan; | ||
| if (cursor.column >= columnCount) { | ||
| cursor.row += 1; | ||
| cursor.column = 0; | ||
| } | ||
| } | ||
| return _GridCellPlacement(row, col); | ||
| } | ||
| } | ||
| row++; | ||
| } | ||
| } | ||
| int row = math.max(0, startRow); | ||
| | ||
| final bool useCursorColumn = | ||
| !dense && explicitRow == null && explicitColumn == null && !hasDefiniteRow; | ||
| int column = explicitColumn ?? (useCursorColumn ? cursor.column : 0); | ||
| bool cursorApplied = false; | ||
| | ||
| while (true) { | ||
| _ensureOccupancyRows(occupancy, row + rowSpanClamped, columnCount); | ||
| final int columnStart = explicitColumn ?? | ||
| (rowFlow && !dense && explicitRow == null && row == cursor.row ? cursor.column : 0); | ||
| | ||
| for (int col = math.max(0, columnStart); col <= columnCount - colSpan; col++) { | ||
| if (_canPlace(occupancy, row, col, rowSpanClamped, colSpan, columnCount)) { | ||
| _markPlacement(occupancy, row, col, rowSpanClamped, colSpan); | ||
| if (explicitRow == null && !hasDefiniteColumn && rowFlow) { | ||
| cursor.row = row; | ||
| cursor.column = col + colSpan; | ||
| if (cursor.column >= columnCount) { | ||
| cursor.row += 1; | ||
| cursor.column = 0; | ||
| } | ||
| if (column < 0) column = 0; | ||
| if (column + colSpan > columnCount) { | ||
| _ensureImplicitColumns( | ||
| colSizes: columnSizes, | ||
| requiredCount: column + colSpan, | ||
| explicitCount: explicitColumnCount, | ||
| autoColumns: autoColumns, | ||
| innerAvailable: adjustedInnerWidth, | ||
| ); | ||
| columnCount = columnSizes.length; | ||
| } | ||
| | ||
| final int desiredRowStart = | ||
| explicitRow ?? ((useCursorColumn && !cursorApplied && column == cursor.column) ? cursor.row : 0); | ||
| final int rowTrackLimit = | ||
| math.max(rowTrackCountForPlacement, rowSpanClamped + math.max(0, desiredRowStart)); | ||
| final int maxRowIndex = math.max(0, rowTrackLimit - rowSpanClamped); | ||
| | ||
| int row = math.max(0, math.min(desiredRowStart, maxRowIndex)); | ||
| bool placed = false; | ||
| | ||
| while (row <= maxRowIndex) { | ||
| _ensureOccupancyRows(occupancy, row + rowSpanClamped, columnCount); | ||
| if (_canPlace(occupancy, row, column, rowSpanClamped, colSpan, columnCount)) { | ||
| placed = true; | ||
| break; | ||
| } | ||
| row++; | ||
| } | ||
| | ||
| if (!placed && dense && explicitRow == null) { | ||
| int wrapRow = 0; | ||
| final int wrapLimit = math.min(math.max(0, desiredRowStart), maxRowIndex + 1); | ||
| while (wrapRow < wrapLimit) { | ||
| _ensureOccupancyRows(occupancy, wrapRow + rowSpanClamped, columnCount); | ||
| if (_canPlace(occupancy, wrapRow, column, rowSpanClamped, colSpan, columnCount)) { | ||
| row = wrapRow; | ||
| placed = true; | ||
| break; | ||
| } | ||
| wrapRow++; | ||
| } | ||
| } | ||
| | ||
| if (placed) { | ||
| _markPlacement(occupancy, row, column, rowSpanClamped, colSpan); | ||
| if (explicitRow == null && !hasDefiniteRow) { | ||
| cursor.column = column; | ||
| cursor.row = row + rowSpanClamped; | ||
| if (!dense && cursor.row >= math.max(explicitRowCount, occupancy.length)) { | ||
| cursor.row = 0; | ||
| cursor.column = column + colSpan; | ||
| } | ||
| return _GridCellPlacement(row, col); | ||
| } | ||
| return _GridCellPlacement(row, column); | ||
| } | ||
| | ||
| cursorApplied = true; | ||
| column++; | ||
| } | ||
| } |
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.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash # First, let's see the full context of the variable definitions and call site grep -n "explicitRowCount" webf/lib/src/rendering/grid.dart | head -20Repository: openwebf/webf
Length of output: 836
🏁 Script executed:
#!/bin/bash # Now let's look at the actual definitions and the call site with context sed -n '900,930p' webf/lib/src/rendering/grid.dartRepository: openwebf/webf
Length of output: 1596
🏁 Script executed:
#!/bin/bash # Check the call site around line 1066 sed -n '1020,1070p' webf/lib/src/rendering/grid.dartRepository: openwebf/webf
Length of output: 2114
🏁 Script executed:
#!/bin/bash # Look at how rowTrackCountForPlacement is used after the call sed -n '1066,1080p' webf/lib/src/rendering/grid.dartRepository: openwebf/webf
Length of output: 753
🏁 Script executed:
#!/bin/bash # Check if there are any comments or documentation about cursor wrapping semantics grep -B5 -A5 "cursor.*wrap\|wrap.*cursor" webf/lib/src/rendering/grid.dartRepository: openwebf/webf
Length of output: 39
🏁 Script executed:
#!/bin/bash # Look for grid spec references or similar patterns in CSS Grid implementations grep -i "dense\|auto.*placement\|cursor" webf/lib/src/rendering/grid.dart | grep -i "comment\|spec\|css" | head -10Repository: openwebf/webf
Length of output: 39
🏁 Script executed:
#!/bin/bash # Check if there are test cases that verify cursor wrapping behavior find webf -name "*.dart" -type f | xargs grep -l "grid\|placement" | grep testRepository: openwebf/webf
Length of output: 301
🏁 Script executed:
#!/bin/bash # Look for any CSS Grid spec references or comments about cursor semantics grep -n "spec\|css.*grid\|cursor.*wrap\|placement.*count" webf/lib/src/rendering/grid.dart | head -30Repository: openwebf/webf
Length of output: 319
🏁 Script executed:
#!/bin/bash # Check if the parameter naming convention is consistent throughout the method sed -n '540,570p' webf/lib/src/rendering/grid.dartRepository: openwebf/webf
Length of output: 1195
🏁 Script executed:
#!/bin/bash # Search for all uses of rowTrackCountForPlacement within _placeAutoItem method (lines 540-664) sed -n '540,664p' webf/lib/src/rendering/grid.dart | grep -n "rowTrackCountForPlacement"Repository: openwebf/webf
Length of output: 200
🏁 Script executed:
#!/bin/bash # Let's see the full method to verify parameter usage sed -n '540,664p' webf/lib/src/rendering/grid.dart | tail -100Repository: openwebf/webf
Length of output: 3551
🏁 Script executed:
#!/bin/bash # Check test cases for grid auto placement to understand expected behavior head -100 webf/test/src/rendering/css_grid_basic_layout_test.dartRepository: openwebf/webf
Length of output: 4105
🏁 Script executed:
#!/bin/bash # Look for any git history or comments explaining the parameter design git log --oneline -n 20 -- webf/lib/src/rendering/grid.dart 2>/dev/null | head -10Repository: openwebf/webf
Length of output: 111
🏁 Script executed:
#!/bin/bash # Check what the original review comment from past review said (if available in git) git log --all --grep="explicitRowCount" --oneline 2>/dev/null | head -5Repository: openwebf/webf
Length of output: 39
🏁 Script executed:
#!/bin/bash # Look at the actual semantics: check if explicit count and placement count should differ # by examining what they represent sed -n '905,915p' webf/lib/src/rendering/grid.dartRepository: openwebf/webf
Length of output: 606
🏁 Script executed:
#!/bin/bash # Verify the semantic difference between the two counts echo "=== explicitRowCount definition (line 909) ===" sed -n '909p' webf/lib/src/rendering/grid.dart echo "" echo "=== rowTrackCountForPlacement definition (line 1027) ===" sed -n '1027p' webf/lib/src/rendering/grid.dart echo "" echo "=== How they're used at call site (line 1066) ===" sed -n '1065,1068p' webf/lib/src/rendering/grid.dartRepository: openwebf/webf
Length of output: 554
🏁 Script executed:
#!/bin/bash # Check the usage of explicitRowCount post-call to understand intended semantics sed -n '1075,1085p' webf/lib/src/rendering/grid.dartRepository: openwebf/webf
Length of output: 444
Fix parameter wiring in _placeAutoItem call.
The explicitRowCount parameter at line 1066 should receive the true explicit count (explicitRowCount from line 909), not rowTrackCountForPlacement. Currently both parameters receive the same value:
explicitRowCount: rowTrackCountForPlacement, rowTrackCountForPlacement: rowTrackCountForPlacement, The method has two semantically distinct row count parameters: explicitRowCount (grid definition count, needed for cursor wrap logic at line 653) and rowTrackCountForPlacement (computed placement limit, needed for placement boundary at line 619). The post-call code at line 1078 uses the outer explicitRowCount variable, confirming the method needs to receive the true explicit count, not the computed placement count.
Correct the call to:
explicitRowCount: explicitRowCount, rowTrackCountForPlacement: rowTrackCountForPlacement, 🤖 Prompt for AI Agents
In webf/lib/src/rendering/grid.dart around lines 540 to 664, the `_placeAutoItem` invocation is wiring the two row-count parameters incorrectly; change the call so the named argument explicitRowCount receives the actual explicitRowCount variable (not rowTrackCountForPlacement) while leaving rowTrackCountForPlacement passed its computed value, i.e. pass explicitRowCount: explicitRowCount and rowTrackCountForPlacement: rowTrackCountForPlacement to fix the cursor wrap/placement logic. 42d261e to edf76be Compare 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.
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 (2)
webf/lib/src/css/style_declaration.dart (1)
296-368: Fix case-sensitive grid identifier handling to comply with CSS Grid specification.Grid identifiers (area names and line names) are case-sensitive per CSS Grid spec, but
_toLowerCasein the property setter lowercasesgrid-areavalues before shorthand expansion. This causes a mismatch withgrid-template-areas, where quoted area names preserve their original case.For example:
grid-template-areas: "HeaderArea header side"→ area key stored as"HeaderArea"grid-area: HeaderArea→ lowercased to"headerarea"→ lookup fails withtemplateAreaMap["headerarea"]The fix is to exempt
GRID_AREA,GRID_ROW, andGRID_COLUMNproperties from_toLowerCase(similar to the existing exemptions forANIMATIONandCONTENT), or normalize only known keywords while preserving custom identifiers.webf/lib/src/css/grid.dart (1)
189-489: Line-name token parsing strategy is solid, but_cloneTrackWithLineNamesshould preserveisAutoFit.
Right now clones created when applying trailing line names can dropsource.isAutoFit, which can later affect auto-fit collapsing logic.if (source is GridFixed) { return GridFixed( source.length, leadingLineNames: resolvedLeading, trailingLineNames: resolvedTrailing, + isAutoFit: source.isAutoFit, ); } else if (source is GridFraction) { return GridFraction( source.fr, leadingLineNames: resolvedLeading, trailingLineNames: resolvedTrailing, + isAutoFit: source.isAutoFit, ); } else if (source is GridAuto) { return GridAuto( leadingLineNames: resolvedLeading, trailingLineNames: resolvedTrailing, + isAutoFit: source.isAutoFit, ); } else if (source is GridMinMax) { return GridMinMax( source.minTrack, source.maxTrack, leadingLineNames: resolvedLeading, trailingLineNames: resolvedTrailing, + isAutoFit: source.isAutoFit, ); } else if (source is GridFitContent) { return GridFitContent( source.limit, leadingLineNames: resolvedLeading, trailingLineNames: resolvedTrailing, + isAutoFit: source.isAutoFit, ); } else if (source is GridRepeat) { return GridRepeat._( source.kind, count: source.count, tracks: source.tracks, leadingLineNames: resolvedLeading, trailingLineNames: resolvedTrailing, + isAutoFit: source.isAutoFit, ); }
♻️ Duplicate comments (5)
integration_tests/specs/css/css-grid/auto-placement.ts (2)
260-281: Fix missing semicolon to avoid ASI/lint hazards (already flagged previously).Line 269:
cell.style.backgroundColor = 'red'should end with;.
634-692: Fix missing semicolons in bothlightgrayassignments (already flagged previously).Lines 640 and 670:
grid.style.backgroundColor = 'lightgray'should end with;in both tests.webf/lib/src/rendering/grid.dart (3)
87-161: Cap/guard extreme grid line numbers to prevent pathological implicit track allocation (DoS/OOM).
_resolveLineRequirementIndex()can return arbitrarily large values for large positiveplacement.line, which then drives_ensureImplicitColumns()growth.int? _resolveLineRequirementIndex( @@ if (placement.line == null) return null; final int raw = placement.line!; + // Prevent pathological implicit track allocation from extreme line numbers. + const int kMaxGridLine = 1000; if (raw > 0) { - return raw - 1; + if (raw > kMaxGridLine) return null; + return raw - 1; }
540-664: Auto-placement:explicitRowCountis wired incorrectly at the call site.
At Line 1066 you passexplicitRowCount: rowTrackCountForPlacement, but_placeAutoItemusesexplicitRowCountfor cursor wrap semantics (Line 653). This should receive the real explicit row count.final _GridCellPlacement placement = _placeAutoItem( @@ - explicitRowCount: rowTrackCountForPlacement, + explicitRowCount: explicitRowCount, rowTrackCountForPlacement: rowTrackCountForPlacement, );
1249-1387: Auto-fit row collapse updates used height, butalign-content: space-*still uses pre-collapsetotalRows.
After subtractingcollapsedHeight,totalRows(Line 1243) remains unchanged and is used to computerowDistributionBetween/Leading(Lines 1347-1365), producing visible misalignment.- final int totalRows = math.max(rowSizes.length, implicitRowHeights.length); + int totalRows = math.max(rowSizes.length, implicitRowHeights.length); @@ if (explicitAutoFitRows != null && explicitAutoFitRowUsage != null) { @@ if (collapsedHeight > 0) { usedContentHeight = math.max(0.0, usedContentHeight - collapsedHeight); + // Recompute effective row count for space-* distribution after collapse. + int lastUsed = -1; + for (int i = 0; i < explicitAutoFitRowUsage.length; i++) { + if (explicitAutoFitRowUsage[i]) lastUsed = i; + } + if (lastUsed >= 0) { + totalRows = math.max(1, lastUsed + 1); + } } }
🧹 Nitpick comments (6)
integration_tests/specs/css/css-grid/grid-shorthand.ts (1)
1-106: Integration tests:grid: nonetest should also snapshot; and please verifydone()vsasyncexpectation.
- The
grid: nonetest (Lines 31-53) doesn’t callsnapshot(), unlike the other cases; adding one would keep visual regression coverage consistent.- As above, guidelines mention
done()for async tests; please confirm the harness accepts promise-returning specs.integration_tests/specs/css/css-grid/auto-placement.ts (1)
642-681: Prefer strict equality in TypeScript tests.In both loops,
if (i == 0)should beif (i === 0)to avoid coercion surprises.webf/test/src/css/grid_computed_style_test.dart (1)
88-136: Potential flake guard: considerpumpAndSettle()(or an extrapump) before reading computed styles.These tests do a single
await tester.pump();beforegetComputedStyle(...). If any style/layout work is scheduled post-frame, addingpumpAndSettle()(or a secondpump) can reduce intermittent failures.webf/lib/src/css/render_style.dart (2)
1404-1434:getProperty()wiring is correct; confirm computed-style code handlesGridTemplateAreasDefinition?null/none properly.Returning
gridTemplateAreasDefinitionforGRID_TEMPLATE_AREASis fine, but it relies on downstream serialization to mapnull/empty to'none'deterministically. Worth confirming with a small unit test if not already covered.
2291-2297: Alignment parsing: confirmallowAutochoices match spec for each property.
justify-itemsdisallowsautowhilejustify-selfallows it here. Please verify this aligns with WebF’s intended model (and the behavior you want exposed viagetComputedStyle).webf/lib/src/css/style_property.dart (1)
1443-1496: place-content / place-items / place-self shorthands: good coverage, but consider input validation symmetry.
These setters accept any tokens; if other shorthands validate, you may want minimal validation (or explicitly rely on downstream parsing).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (38)
integration_tests/pnpm-lock.yamlis excluded by!**/pnpm-lock.yamlintegration_tests/snapshots/css/css-grid/auto-fit-place-content.ts.a6c2222e1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-fit-place-content.ts.f087def31.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.3227b02f1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.3388b1411.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.4a877ef31.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.50195dd31.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.5ee42bbf1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.5f7d60ae1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.668a020a1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.6d96d8481.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.727b4eaf1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.820677411.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.8d64c3a21.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.8e58c9291.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.a10effd91.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.b113a44f1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.b85971bd1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.bafeabf01.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.cb1f36ea1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.dd0f2f661.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.e3974eb21.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.e54a53621.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.ec87fd651.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.fc51ca2e1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/auto-placement.ts.fe967fa01.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/basic-concepts.ts.4d9996cd1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/basic-concepts.ts.5379f9931.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/dense-flow-dashboard.ts.b4a69b6a1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/grid-shorthand.ts.31c543121.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/grid-shorthand.ts.84c447fb1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/grid-shorthand.ts.f3df68fd1.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/grid-template-shorthand.ts.838de3931.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/grid-template-shorthand.ts.f7314e031.pngis excluded by!**/*.pngintegration_tests/snapshots/css/css-grid/template-areas.ts.532facab1.pngis excluded by!**/*.pngintegration_tests/snapshots/dom/elements/canvas/line_dash.ts.11b5b7ab1.pngis excluded by!**/*.pngintegration_tests/snapshots/dom/elements/canvas/line_dash.ts.bce7d9111.pngis excluded by!**/*.pngpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (24)
.gitignore(1 hunks)CSS_GRID_PLAN.md(2 hunks)integration_tests/pubspec.yaml(1 hunks)integration_tests/specs/css/css-grid/auto-fit-place-content.ts(1 hunks)integration_tests/specs/css/css-grid/auto-placement.ts(3 hunks)integration_tests/specs/css/css-grid/basic-concepts.ts(1 hunks)integration_tests/specs/css/css-grid/dense-flow-dashboard.ts(1 hunks)integration_tests/specs/css/css-grid/grid-shorthand.ts(1 hunks)integration_tests/specs/css/css-grid/grid-template-shorthand.ts(1 hunks)integration_tests/specs/css/css-grid/template-areas-overlap.ts(1 hunks)integration_tests/specs/css/css-grid/template-areas.ts(1 hunks)integration_tests/specs/css/css-grid/track-sizing.ts(1 hunks)integration_tests/specs/css/css-text/line-join.ts(7 hunks)webf/lib/src/css/computed_style_declaration.dart(2 hunks)webf/lib/src/css/flexbox.dart(4 hunks)webf/lib/src/css/grid.dart(6 hunks)webf/lib/src/css/keywords.dart(1 hunks)webf/lib/src/css/render_style.dart(10 hunks)webf/lib/src/css/style_declaration.dart(5 hunks)webf/lib/src/css/style_property.dart(3 hunks)webf/lib/src/foundation/debug_flags.dart(1 hunks)webf/lib/src/rendering/grid.dart(16 hunks)webf/test/src/css/grid_computed_style_test.dart(3 hunks)webf/test/src/rendering/css_grid_basic_layout_test.dart(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (12)
- webf/lib/src/foundation/debug_flags.dart
- webf/lib/src/css/flexbox.dart
- integration_tests/specs/css/css-grid/auto-fit-place-content.ts
- webf/test/src/rendering/css_grid_basic_layout_test.dart
- webf/lib/src/css/keywords.dart
- integration_tests/specs/css/css-text/line-join.ts
- integration_tests/specs/css/css-grid/dense-flow-dashboard.ts
- integration_tests/specs/css/css-grid/track-sizing.ts
- integration_tests/specs/css/css-grid/basic-concepts.ts
- integration_tests/specs/css/css-grid/template-areas.ts
- .gitignore
- integration_tests/specs/css/css-grid/template-areas-overlap.ts
🧰 Additional context used
📓 Path-based instructions (10)
integration_tests/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
integration_tests/**/*.ts: Write integration tests for visual regression testing in TypeScript
Use snapshot testing for integration tests
Files:
integration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/grid-shorthand.ts
integration_tests/specs/**/*.ts
📄 CodeRabbit inference engine (integration_tests/CLAUDE.md)
integration_tests/specs/**/*.ts: Place tests in appropriate directories underspecs/(css/, dom/, or window/)
Use TypeScript (.ts extension) for test files
Usedone()callback for async tests
Usesnapshot()for visual regression tests to capture current rendering
UsesimulateClickwith coordinates for hit testing tests
Test assets should reference files inassets/directory
Usefdescribe()instead ofdescribe()to run only specific test specs (Jasmine feature)
Usefit()instead ofit()to run only specific test cases
Snapshots are stored as images for comparison and failed snapshots generate diff images
The max width of testing window is 340px
Test specs will always pass if there are no existing snapshots
Group related tests in describe blocks
Each test should be independent
Remove created elements after tests (test cleanup)
Use clear, descriptive test names
Test behavior, not implementation
Include edge cases and error conditions in tests
Batch DOM operations to minimize reflows
Use async/await and proper async patterns for asynchronous operations in tests
Measure operations usingperformance.now()for timing in performance-critical tests
Files:
integration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/grid-shorthand.ts
**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.dart: Always free allocated memory in Dart FFI
Usemalloc.free()fortoNativeUtf8()allocations in Dart FFI
Files:
webf/lib/src/css/render_style.dartwebf/lib/src/css/computed_style_declaration.dartwebf/lib/src/css/style_declaration.dartwebf/test/src/css/grid_computed_style_test.dartwebf/lib/src/css/style_property.dartwebf/lib/src/rendering/grid.dartwebf/lib/src/css/grid.dart
**/*.{dart,cc,h}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{dart,cc,h}: Track pointer ownership in callbacks
Document memory ownership clearly in FFI code
Files:
webf/lib/src/css/render_style.dartwebf/lib/src/css/computed_style_declaration.dartwebf/lib/src/css/style_declaration.dartwebf/test/src/css/grid_computed_style_test.dartwebf/lib/src/css/style_property.dartwebf/lib/src/rendering/grid.dartwebf/lib/src/css/grid.dart
webf/**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
Use
flutter testcommand to run Dart tests in the webf package
webf/**/*.dart: Follow rules in webf/analysis_options.yaml for Dart code style
Use single quotes for strings in Dart code
File names must use snake_case in Dart
Class names must use PascalCase in Dart
Variables and functions must use camelCase in Dart
Prefer final fields when applicable in Dart code
Lines should be max 120 characters in Dart code
Always free allocated memory in Dart FFI using malloc.free() for toNativeUtf8() allocations
Free FFI allocated memory in finally blocks to ensure cleanup on exceptions
Track ownership of allocated pointers in FFI callbacks
Free NativeValue pointers after converting with fromNativeValue in FFI code
Document memory ownership clearly in FFI async callbacks
Implement WidgetElement to create custom Flutter widgets integrated into WebF's DOM tree
Register custom WidgetElements using WidgetElementRegistry.register(tagName, builder)
Override buildWidget(BuildContext context) method in WidgetElement to build the Flutter widget
Call updateWidget() when attributes change in WidgetElement implementations
Dispose controllers and subscriptions in WidgetElement for memory management
Follow W3C event standards when dispatching events from WidgetElement
Minimize widget rebuilds in WidgetElement for performance optimization
Implement ARIA attributes in WidgetElement when applicable for accessibilityDart code in webf module must follow naming conventions: snake_case for file names, PascalCase for classes, and camelCase for class members
Files:
webf/lib/src/css/render_style.dartwebf/lib/src/css/computed_style_declaration.dartwebf/lib/src/css/style_declaration.dartwebf/test/src/css/grid_computed_style_test.dartwebf/lib/src/css/style_property.dartwebf/lib/src/rendering/grid.dartwebf/lib/src/css/grid.dart
webf/lib/src/css/**/*.dart
📄 CodeRabbit inference engine (webf/CLAUDE.md)
Use CSSRenderStyle for style computation and storage in Dart CSS code
Files:
webf/lib/src/css/render_style.dartwebf/lib/src/css/computed_style_declaration.dartwebf/lib/src/css/style_declaration.dartwebf/lib/src/css/style_property.dartwebf/lib/src/css/grid.dart
webf/**/*_test.dart
📄 CodeRabbit inference engine (CLAUDE.md)
Use Flutter widget testing for Dart code in the webf package
Files:
webf/test/src/css/grid_computed_style_test.dart
webf/test/**/*_test.dart
📄 CodeRabbit inference engine (webf/CLAUDE.md)
webf/test/**/*_test.dart: Use WebFWidgetTestUtils.prepareWidgetTest() to test HTML/CSS rendering in widget unit tests
Access render objects in tests to verify layout calculations
Call setupTest() in setUpAll() method for one-time setup in unit tests
When testing with WebFController, wait for initialization with: await controller.controlledInitCompleter.future
Use mock bundles from test/src/foundation/mock_bundle.dart for testing in unit tests
Files:
webf/test/src/css/grid_computed_style_test.dart
webf/test/**/*.dart
📄 CodeRabbit inference engine (AGENTS.md)
Dart/Flutter widget and unit tests must be placed in
webf/test/and useWebFWidgetTestUtilsandpumpAndSettle()where needed
Files:
webf/test/src/css/grid_computed_style_test.dart
webf/lib/src/rendering/**/*.dart
📄 CodeRabbit inference engine (webf/CLAUDE.md)
Use RenderBoxModel as base class for layout in Dart rendering code
Files:
webf/lib/src/rendering/grid.dart
🧠 Learnings (30)
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Place tests in appropriate directories under `specs/` (css/, dom/, or window/) Applied to files:
integration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/grid-shorthand.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Batch DOM operations to minimize reflows Applied to files:
integration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/grid-shorthand.ts
📚 Learning: 2025-12-08T23:26:54.692Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-08T23:26:54.692Z Learning: Applies to integration_tests/**/*.ts : Write integration tests for visual regression testing in TypeScript Applied to files:
integration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/grid-shorthand.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Use async/await and proper async patterns for asynchronous operations in tests Applied to files:
integration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/grid-shorthand.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Use `snapshot()` for visual regression tests to capture current rendering Applied to files:
integration_tests/specs/css/css-grid/auto-placement.tsintegration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/grid-shorthand.ts
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/lib/src/css/**/*.dart : Use CSSRenderStyle for style computation and storage in Dart CSS code Applied to files:
webf/lib/src/css/render_style.dartwebf/lib/src/css/computed_style_declaration.dartwebf/lib/src/css/style_declaration.dartwebf/test/src/css/grid_computed_style_test.dartwebf/lib/src/css/style_property.dartwebf/lib/src/rendering/grid.dartwebf/lib/src/css/grid.dart
📚 Learning: 2025-12-08T23:28:11.643Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-12-08T23:28:11.643Z Learning: Applies to webf/integration_test/**/*.dart : Dart/Flutter integration tests must be placed in `webf/integration_test/` directory Applied to files:
integration_tests/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: No build needed for Dart-only changes in webf/ Applied to files:
integration_tests/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Run integration tests with: cd webf && flutter test integration_test/ Applied to files:
integration_tests/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/integration_tests/specs/**/*.dart : Use snapshot tests in integration_tests/specs/ for visual regression testing with await snapshot() Applied to files:
integration_tests/pubspec.yaml
📚 Learning: 2025-12-08T23:28:11.643Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-12-08T23:28:11.643Z Learning: Applies to webf/test/**/*.dart : Dart/Flutter widget and unit tests must be placed in `webf/test/` and use `WebFWidgetTestUtils` and `pumpAndSettle()` where needed Applied to files:
integration_tests/pubspec.yamlwebf/test/src/css/grid_computed_style_test.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Use integration tests for end-to-end verification with: cd webf && flutter test integration_test/ Applied to files:
integration_tests/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Use widget unit tests to verify rendering changes with: cd webf && flutter test test/src/rendering/ Applied to files:
integration_tests/pubspec.yamlwebf/test/src/css/grid_computed_style_test.dart
📚 Learning: 2025-12-08T23:26:54.692Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-08T23:26:54.692Z Learning: Applies to webf/**/*_test.dart : Use Flutter widget testing for Dart code in the webf package Applied to files:
integration_tests/pubspec.yamlwebf/test/src/css/grid_computed_style_test.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Run Flutter dart tests with: cd webf && flutter test Applied to files:
integration_tests/pubspec.yaml
📚 Learning: 2025-12-08T23:26:54.692Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-08T23:26:54.692Z Learning: Applies to webf/**/*.dart : Use `flutter test` command to run Dart tests in the webf package Applied to files:
integration_tests/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Run a single Flutter test with: cd webf && flutter test test/path/to/test_file.dart Applied to files:
integration_tests/pubspec.yaml
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Run widget unit tests with: cd webf && flutter test test/src/rendering/ Applied to files:
integration_tests/pubspec.yamlwebf/test/src/css/grid_computed_style_test.dart
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Test behavior, not implementation Applied to files:
integration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/grid-shorthand.ts
📚 Learning: 2025-12-08T23:26:54.692Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-08T23:26:54.692Z Learning: Applies to integration_tests/**/*.ts : Use snapshot testing for integration tests Applied to files:
integration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/grid-shorthand.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Use clear, descriptive test names Applied to files:
integration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/grid-shorthand.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Snapshots are stored as images for comparison and failed snapshots generate diff images Applied to files:
integration_tests/specs/css/css-grid/grid-template-shorthand.tsintegration_tests/specs/css/css-grid/grid-shorthand.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Test specs will always pass if there are no existing snapshots Applied to files:
integration_tests/specs/css/css-grid/grid-template-shorthand.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : Remove created elements after tests (test cleanup) Applied to files:
integration_tests/specs/css/css-grid/grid-template-shorthand.ts
📚 Learning: 2025-12-08T23:27:27.879Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.879Z Learning: Applies to integration_tests/specs/**/*.ts : The max width of testing window is 340px Applied to files:
integration_tests/specs/css/css-grid/grid-shorthand.ts
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/test/**/*_test.dart : Access render objects in tests to verify layout calculations Applied to files:
webf/test/src/css/grid_computed_style_test.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/test/**/*_test.dart : Use WebFWidgetTestUtils.prepareWidgetTest() to test HTML/CSS rendering in widget unit tests Applied to files:
webf/test/src/css/grid_computed_style_test.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/**/*.dart : Follow rules in webf/analysis_options.yaml for Dart code style Applied to files:
webf/test/src/css/grid_computed_style_test.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/**/*.dart : Lines should be max 120 characters in Dart code Applied to files:
webf/test/src/css/grid_computed_style_test.dart
📚 Learning: 2025-12-08T23:28:00.808Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.808Z Learning: Applies to webf/lib/src/rendering/**/*.dart : Use RenderBoxModel as base class for layout in Dart rendering code Applied to files:
webf/lib/src/rendering/grid.dartwebf/lib/src/css/grid.dart
🪛 markdownlint-cli2 (0.18.1)
CSS_GRID_PLAN.md
81-81: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
⏰ 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). (4)
- GitHub Check: build_windows_bridge (Debug)
- GitHub Check: Analyze (rust)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (c-cpp)
🔇 Additional comments (20)
integration_tests/pubspec.yaml (1)
37-39: Path override change looks fine; please ensure the relative path is correct in CI/worktrees.This switches
webf_cupertino_uito../webf_cupertino_ui; please confirm that path exists in all developer/CI layouts (and isn’t only valid locally).webf/test/src/css/grid_computed_style_test.dart (1)
31-86: Good coverage addition for computed-style serialization (named lines, repeats, minmax, place-*).The assertions for template tracks +
place-content/place-itemsand the item-sideplace-self/grid-areaserialization are a strong regression net.webf/lib/src/css/style_declaration.dart (2)
23-58: Shorthand registration for grid-related properties looks consistent.Adding
GRID_TEMPLATE,GRID,PLACE_CONTENT,PLACE_SELF,GRID_AREAinto_CSSShorthandPropertymatches the intended expansion behavior.
203-242: Removal paths for new shorthands are correctly wired.
removeProperty(...)dispatch toCSSStyleProperty.removeShorthandGrid*/removeShorthandPlace*/removeShorthandGridAreais the right integration point.webf/lib/src/css/render_style.dart (2)
309-356: Public surface expansion for grid alignment + template areas is reasonable; ensure defaults are spec-aligned.New getters (
justifyItems,justifySelf,gridTemplateAreasDefinition,gridAreaName) are expected for grid support. Please verify default values and initial serialization match expectations (e.g.,justify-items: stretchvs other engine defaults) for both grid containers and items.
1755-1786: [rewritten comment]
[classification tag]integration_tests/specs/css/css-grid/grid-template-shorthand.ts (1)
1-79: Adddone()callback parameter and set explicitwidthon grid container for test determinism.These tests should follow the pattern
it('...', async (done) => {...})and includedone()calls after assertions, even when usingawait snapshot(). Additionally, set an explicitwidth(≤340px) on thegridelement in both tests—other grid tests in this directory consistently do this to ensure snapshot stability.webf/lib/src/css/computed_style_declaration.dart (5)
917-950: Line-name occurrence logic is reasonable; nested repeat counting is handled.
Counting both leading/trailing names and recursing intoGridRepeat.tracksmatches the intended ambiguity detection.
1003-1036: Placement serialization w/ forced occurrences looks correct.
TheforceIncludeOccurrencepath + “omit1unless needed” should keep computed values stable while disambiguating repeated line names.
1148-1286: Grid property coverage expansion is solid (template-areas, grid-area, place-*).
Nice consolidation of the “force occurrence only when ambiguous/explicit” policy across longhands/shorthands.
1038-1146: The review comment is incorrect. AllJustifyContentenum variants (flexStart, start, flexEnd, end, center, spaceBetween, spaceAround, spaceEvenly) are explicitly handled in_justifyContentToCss. The default case is unreachable and does not mask any missing enum values.Likely an incorrect or invalid review comment.
899-915: No changes needed. The track serialization correctly handles all GridTrackSize variants: GridRepeat is serialized at the list level in_gridTrackListToCsswith therepeat(kind, tracks)format, while_gridTrackValueToCssappropriately returns'auto'for GridAuto instances. All six GridTrackSize subtypes (GridFixed, GridFraction, GridMinMax, GridFitContent, GridRepeat, GridAuto) are properly accounted for.webf/lib/src/rendering/grid.dart (3)
64-86: Profiling scaffold is clean and low-risk.
Thresholding viaDebugFlags.cssGridProfilingMinMsavoids log spam.
163-187: Good: reverse/invalid line ranges now resolve as “invalid” (0) instead of silently forcing span=1.
Thediff <= 0 => 0behavior pairs well with your later “fall back to auto-placement” logic.
208-233: justify-content leading shift math aligns with your distribution logic.
space-around/space-evenlyare consistent with the latercolumnDistributionBetweenrules.webf/lib/src/css/style_property.dart (2)
1222-1251:grid-areashorthand expansion is consistent with your template-area mapping approach.
Storing a single custom-ident inGRID_AREA_INTERNALkeeps the placement longhands clean.
1253-1317:grid-templateshorthand: heuristic quote slicing is OK for partial support—ensure it can’t include/ <columns>in the extracted area text.
Given the “partial support” intent this is acceptable, but consider adding a regression test for multiple quoted rows + trailing/ colsto ensureGRID_TEMPLATE_AREASstays just the strings.webf/lib/src/css/grid.dart (3)
12-187: Grid model expansion (repeat/minmax/fit-content/template-areas + metadata) is cohesive.
TheleadingLineNames/trailingLineNamesfields line up well with both parsing and computed-style serialization needs.
509-568: Named line placements parsing looks correct, including negative occurrences.
Good job rejectingoccurrence == 0and falling back toautowhen invalid.
696-770: CSSGridMixin additions for justify and template areas are well-scoped.*
Normalization (auto->stretch) forjustifyItemsis a good default for computed behavior.
| **TODOs** | ||
| - [x] Capture overview/goals/scope plus risks and rollout strategy. | ||
| - [ ] Land Phase 1 plumbing (display enum, CSSGridMixin, shorthand parsing, auxiliary helpers). | ||
| - [ ] Add Phase 1 widget + integration tests (parsing/computed style) and wire to spec group. | ||
| - [x] Land Phase 1 plumbing (display enum, CSSGridMixin, shorthand parsing, auxiliary helpers). | ||
| - [x] Add Phase 1 widget + integration tests (parsing/computed style) and wire to spec group. | ||
| - [x] Implement `RenderGridLayout` skeleton and hook creation paths. | ||
| - [ ] Implement full track sizing/placement (Phase 3) with tests. | ||
| - [ ] Extend alignment/template features (Phase 4) with serialization and coverage. | ||
| - [x] Implement full track sizing/placement (Phase 3) with tests. | ||
| - [x] Extend alignment/template features (Phase 4) with serialization and coverage (per-item alignment + computed styles partially landed). | ||
| - [x] Complete computed-style serialization and integration specs for grid properties. | ||
| - [ ] Profile and harden grid layout (Phase 5), updating docs/examples. | ||
| - [ ] Add `grid` and `grid-template` shorthands on top of existing longhands, with focused integration specs under `integration_tests/specs/css/css-grid`. |
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.
Replace bold “TODOs” label with a real heading to satisfy markdownlint.
**TODOs** should be a heading (e.g., ## TODOs) to avoid MD036 (“no-emphasis-as-heading”). Based on static analysis hints, this is currently failing markdownlint.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
81-81: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
🤖 Prompt for AI Agents
In CSS_GRID_PLAN.md around lines 81 to 90, the section label "**TODOs**" is formatted as bold text which triggers markdownlint rule MD036; replace the bold inline emphasis with a proper Markdown heading (for example change "**TODOs**" to "## TODOs" or another appropriate heading level) so the list becomes under a real heading and the lint rule is satisfied. | static GridTemplateAreasDefinition? parseTemplateAreas(String value) { | ||
| final String trimmed = value.trim(); | ||
| if (trimmed.isEmpty || trimmed.toLowerCase() == 'none') { | ||
| return const GridTemplateAreasDefinition( | ||
| areas: <String, GridTemplateAreaRect>{}, | ||
| rowCount: 0, | ||
| columnCount: 0, | ||
| cssText: 'none', | ||
| ); | ||
| } | ||
| | ||
| final RegExp rowPattern = RegExp(r'"([^"]*)"'); | ||
| final List<RegExpMatch> matches = rowPattern.allMatches(trimmed).toList(); | ||
| if (matches.isEmpty) return null; | ||
| | ||
| final List<List<String>> rows = <List<String>>[]; | ||
| for (final RegExpMatch match in matches) { | ||
| final String rowText = match.group(1)!; | ||
| final String normalized = rowText.trim(); | ||
| if (normalized.isEmpty) return null; | ||
| final List<String> tokens = | ||
| normalized.split(RegExp(r'\s+')).map((token) => token.trim()).where((token) => token.isNotEmpty).toList(); | ||
| if (tokens.isEmpty) return null; | ||
| rows.add(tokens); | ||
| } | ||
| | ||
| final int columnCount = rows.first.length; | ||
| if (columnCount == 0) return null; | ||
| for (final List<String> tokens in rows) { | ||
| if (tokens.length != columnCount) return null; | ||
| } | ||
| | ||
| final Map<String, _GridAreaBuilder> builders = <String, _GridAreaBuilder>{}; | ||
| for (int r = 0; r < rows.length; r++) { | ||
| final List<String> tokens = rows[r]; | ||
| for (int c = 0; c < tokens.length; c++) { | ||
| final String name = tokens[c]; | ||
| if (name == '.' || name.isEmpty) continue; | ||
| final _GridAreaBuilder builder = builders.putIfAbsent(name, () => _GridAreaBuilder(r + 1, c + 1)); | ||
| builder.include(r + 1, c + 1); | ||
| } | ||
| } | ||
| | ||
| final Map<String, GridTemplateAreaRect> rects = <String, GridTemplateAreaRect>{}; | ||
| for (final MapEntry<String, _GridAreaBuilder> entry in builders.entries) { | ||
| final _GridAreaBuilder builder = entry.value; | ||
| for (int r = builder.minRow; r <= builder.maxRow; r++) { | ||
| for (int c = builder.minCol; c <= builder.maxCol; c++) { | ||
| if (rows[r - 1][c - 1] != entry.key) { | ||
| return null; | ||
| } | ||
| } | ||
| } | ||
| rects[entry.key] = | ||
| GridTemplateAreaRect(builder.minRow, builder.maxRow + 1, builder.minCol, builder.maxCol + 1); | ||
| } | ||
| | ||
| return GridTemplateAreasDefinition( | ||
| areas: rects, | ||
| rowCount: rows.length, | ||
| columnCount: columnCount, | ||
| cssText: trimmed, | ||
| ); | ||
| } | ||
| } |
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.
Bug: grid-template-areas parsing ignores single-quoted strings.
CSS strings can be single- or double-quoted; current regex only matches "...".
- final RegExp rowPattern = RegExp(r'"([^"]*)"'); + final RegExp rowPattern = RegExp(r'"([^"]*)"|\'([^\']*)\''); @@ - final String rowText = match.group(1)!; + final String rowText = (match.group(1) ?? match.group(2))!;📝 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.
| static GridTemplateAreasDefinition? parseTemplateAreas(String value) { | |
| final String trimmed = value.trim(); | |
| if (trimmed.isEmpty || trimmed.toLowerCase() == 'none') { | |
| return const GridTemplateAreasDefinition( | |
| areas: <String, GridTemplateAreaRect>{}, | |
| rowCount: 0, | |
| columnCount: 0, | |
| cssText: 'none', | |
| ); | |
| } | |
| final RegExp rowPattern = RegExp(r'"([^"]*)"'); | |
| final List<RegExpMatch> matches = rowPattern.allMatches(trimmed).toList(); | |
| if (matches.isEmpty) return null; | |
| final List<List<String>> rows = <List<String>>[]; | |
| for (final RegExpMatch match in matches) { | |
| final String rowText = match.group(1)!; | |
| final String normalized = rowText.trim(); | |
| if (normalized.isEmpty) return null; | |
| final List<String> tokens = | |
| normalized.split(RegExp(r'\s+')).map((token) => token.trim()).where((token) => token.isNotEmpty).toList(); | |
| if (tokens.isEmpty) return null; | |
| rows.add(tokens); | |
| } | |
| final int columnCount = rows.first.length; | |
| if (columnCount == 0) return null; | |
| for (final List<String> tokens in rows) { | |
| if (tokens.length != columnCount) return null; | |
| } | |
| final Map<String, _GridAreaBuilder> builders = <String, _GridAreaBuilder>{}; | |
| for (int r = 0; r < rows.length; r++) { | |
| final List<String> tokens = rows[r]; | |
| for (int c = 0; c < tokens.length; c++) { | |
| final String name = tokens[c]; | |
| if (name == '.' || name.isEmpty) continue; | |
| final _GridAreaBuilder builder = builders.putIfAbsent(name, () => _GridAreaBuilder(r + 1, c + 1)); | |
| builder.include(r + 1, c + 1); | |
| } | |
| } | |
| final Map<String, GridTemplateAreaRect> rects = <String, GridTemplateAreaRect>{}; | |
| for (final MapEntry<String, _GridAreaBuilder> entry in builders.entries) { | |
| final _GridAreaBuilder builder = entry.value; | |
| for (int r = builder.minRow; r <= builder.maxRow; r++) { | |
| for (int c = builder.minCol; c <= builder.maxCol; c++) { | |
| if (rows[r - 1][c - 1] != entry.key) { | |
| return null; | |
| } | |
| } | |
| } | |
| rects[entry.key] = | |
| GridTemplateAreaRect(builder.minRow, builder.maxRow + 1, builder.minCol, builder.maxCol + 1); | |
| } | |
| return GridTemplateAreasDefinition( | |
| areas: rects, | |
| rowCount: rows.length, | |
| columnCount: columnCount, | |
| cssText: trimmed, | |
| ); | |
| } | |
| } | |
| static GridTemplateAreasDefinition? parseTemplateAreas(String value) { | |
| final String trimmed = value.trim(); | |
| if (trimmed.isEmpty || trimmed.toLowerCase() == 'none') { | |
| return const GridTemplateAreasDefinition( | |
| areas: <String, GridTemplateAreaRect>{}, | |
| rowCount: 0, | |
| columnCount: 0, | |
| cssText: 'none', | |
| ); | |
| } | |
| final RegExp rowPattern = RegExp(r'"([^"]*)"|' + "'" + r'([^' + "'" + r']*)' + "'"); | |
| final List<RegExpMatch> matches = rowPattern.allMatches(trimmed).toList(); | |
| if (matches.isEmpty) return null; | |
| final List<List<String>> rows = <List<String>>[]; | |
| for (final RegExpMatch match in matches) { | |
| final String rowText = (match.group(1) ?? match.group(2))!; | |
| final String normalized = rowText.trim(); | |
| if (normalized.isEmpty) return null; | |
| final List<String> tokens = | |
| normalized.split(RegExp(r'\s+')).map((token) => token.trim()).where((token) => token.isNotEmpty).toList(); | |
| if (tokens.isEmpty) return null; | |
| rows.add(tokens); | |
| } | |
| final int columnCount = rows.first.length; | |
| if (columnCount == 0) return null; | |
| for (final List<String> tokens in rows) { | |
| if (tokens.length != columnCount) return null; | |
| } | |
| final Map<String, _GridAreaBuilder> builders = <String, _GridAreaBuilder>{}; | |
| for (int r = 0; r < rows.length; r++) { | |
| final List<String> tokens = rows[r]; | |
| for (int c = 0; c < tokens.length; c++) { | |
| final String name = tokens[c]; | |
| if (name == '.' || name.isEmpty) continue; | |
| final _GridAreaBuilder builder = builders.putIfAbsent(name, () => _GridAreaBuilder(r + 1, c + 1)); | |
| builder.include(r + 1, c + 1); | |
| } | |
| } | |
| final Map<String, GridTemplateAreaRect> rects = <String, GridTemplateAreaRect>{}; | |
| for (final MapEntry<String, _GridAreaBuilder> entry in builders.entries) { | |
| final _GridAreaBuilder builder = entry.value; | |
| for (int r = builder.minRow; r <= builder.maxRow; r++) { | |
| for (int c = builder.minCol; c <= builder.maxCol; c++) { | |
| if (rows[r - 1][c - 1] != entry.key) { | |
| return null; | |
| } | |
| } | |
| } | |
| rects[entry.key] = | |
| GridTemplateAreaRect(builder.minRow, builder.maxRow + 1, builder.minCol, builder.maxCol + 1); | |
| } | |
| return GridTemplateAreasDefinition( | |
| areas: rects, | |
| rowCount: rows.length, | |
| columnCount: columnCount, | |
| cssText: trimmed, | |
| ); | |
| } | |
| } |
🤖 Prompt for AI Agents
In webf/lib/src/css/grid.dart around lines 570 to 634, the rowPattern RegExp only matches double-quoted strings so single-quoted template rows are ignored; change the regex to accept either single or double quotes (for example RegExp(r'(["\'])(.*?)\1', dotAll: true)) and update the code to use match.group(2) as the captured row text; keep the rest of the parsing logic the same so both '...' and "..." template-area rows are handled.
Summary by CodeRabbit
New Features
Tests
Documentation
Chore
✏️ Tip: You can customize this high-level summary in your review settings.