Commit b8a06bd
feat: ASCX and Custom WebControl migration support (FritzAndFriends#559)
* Removed wingtip message files
* docs(ai-team): ASCX/custom-control review — decisions merged and archived
Session: 2026-05-30-ascx-custom-control-review
Requested by: Jeffrey T. Fritz
Changes:
- Archived 10 decisions from 2026-04-27 to 2026-05-16 (older than 7 days)
- Merged 6 decisions from inbox: Executive Summary pattern, CLI code-behind fixes (Bishop x4), helper transforms, L1 quality, SSR form contract, MasterPage bridge contract
- Updated cross-agent history for Beast, Bishop, Cyclops, Forge
- Archived Beast and Bishop history files (exceeded 15KB each)
- Created orchestration log and session log
* docs(ai-team): Merge ASCX→.razor user directive + control-migration session
Session: 2026-05-30-control-migration
Requested by: Jeffrey T. Fritz
Changes:
- Merged user directive on ASCX user control conversion preference
- Logged control-migration issue planning session
- Updated Forge history with team decision
- Documented ASCX→.razor.cs backing approach in team memory
* docs(forge): ASCX/custom-control migration planning and roadmap
- Create dev-docs/control-migration/ folder with comprehensive planning
- Add README.md with work breakdown, priority matrix, and acceptance criteria
- Add track documents for P0+P1 work:
- track-webconfig-parser.md: Parse Web.config custom control registrations
- track-ascx-analyzer.md: Extract properties/events from ASCX code-behind
- track-contenttemplate.md: Unwrap template markup to Blazor equivalents
- track-findcontrol.md: Rewrite FindControl calls to @ref references
This unblocks the #1 CLI gap: ASCX and custom-control support. Implementation
tracks P0 (foundation: parser + analyzer) → P1 (transforms) → P2 (scaffolding).
GitHub issues created: FritzAndFriends#555-FritzAndFriends#558 (P0 foundation + P1 transforms)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs(ai-team): ASCX/Custom-Control Migration Planning completed
Session: 2026-05-30-control-migration-completion
Requested by: Copilot
Changes:
- Merged Forge's ASCX/custom-control migration roadmap to decisions.md
- Created session log for control-migration planning completion
- Appended team update to Forge's history tracking
- No entries archived (all within 30-day window)
- Processed 1 inbox file, 0 duplicates
Team decision: 3-stream ASCX migration plan established (P0 infrastructure, P1 transforms, P2-P3 deferred tooling)
* Advance ASCX/custom-control migration P1 coverage
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(cli): add Bind(), DataBinder.Eval() support + lifecycle test coverage
- ContentTemplateUnwrapperTransform now handles <%# Bind(...) %> expressions
- ContentTemplateUnwrapperTransform now handles DataBinder.Eval(Container.DataItem, ...)
- Added tests for Bind with format strings, DataBinder.Eval with/without format
- Added PageLifecycleTransform tests for Page_Init and Page_PreRender conversions
- Updated dev-docs to reflect lifecycle transforms are now complete
- CLI tests: 869 → 875 (all passing)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(runtime): promote FindControl to formal BWFC runtime contract
- Harden BaseWebFormsComponent with dictionary-indexed child lookup (O(1))
- Add RegisterChildControl/UnregisterChildControl for lifecycle management
- Unregister children on disposal to prevent stale references
- Add OnControlTreeReadyAsync lifecycle hook for controls-ready phase
- Remove FindControlComponentRefTransform from CLI pipeline (no more rewriting)
- Replace rewrite tests with preservation tests (verify calls stay unchanged)
- Add 7 bUnit tests: direct/nested/chained lookup, case-insensitive, casts
FindControl is now a runtime feature — migrated code keeps its original
FindControl syntax and it works without CLI code-behind rewriting.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(samples): add FindControl live demo, Playwright tests, and doc update
- Create /migration/findcontrol sample page with 4 live demos:
direct child lookup, nested/recursive, chained, case-insensitive
- Add Playwright integration tests (4 tests) in AfterBlazorServerSide.Tests
- Register in ComponentCatalog under Migration Helpers
- Update docs/Migration/FindControl-Migration.md:
- Rename from 'Migrating Away' to 'FindControl in BWFC'
- Lead with runtime support (zero code rewrites)
- Document hardened runtime contract (O(1) index, lifecycle hook)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(samples): rename Wizard.razor to WizardSample.razor to resolve naming conflict
The page component type 'Wizard' in namespace
AfterBlazorServerSide.Components.Pages.ControlSamples.Wizard collided with
BlazorWebFormsComponents.Wizard, causing RZ9985 errors. Renaming the sample
page to WizardSample.razor resolves the ambiguity while keeping the same
@page route (/ControlSamples/Wizard).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(samples): make FindControl demo interactive with code-beside-result layout
- Each demo now shows code on the left and live result on the right
- FindControl actually sets Text values (matching the code samples)
- TextBoxes start empty and get populated by FindControl calls
- Updated Playwright assertions to match new result text
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: mark P1 complete — FindControl is runtime, ContentTemplate done
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(cli): handle static methods and Server.MapPath ordering in HttpContextAccessorTransform
- Skip HttpContext.Current.Server patterns (leave for ServerShimTransform at order 330)
- Detect static method usage and emit static field + Configure() pattern
instead of instance field + constructor injection
- Early-exit when no accessor references remain after skip logic
- Add 4 new tests: static method pattern, Server.MapPath skip,
mixed patterns, and pipeline integration (ExceptionUtility end-to-end)
Fixes the malformed _httpContextAccessor.HttpContext?.Path.Combine(...)
output and the static-method-can't-access-instance-field compile error
exposed by WingtipToys run93.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(P2): add WebControl/UserControl/Control compat classes and lifecycle auto-wiring
P2-A: Namespace remap instead of base-class swap
- Add UserControl.cs and Control.cs compatibility classes
- UsingStripTransform replaces System.Web.UI.* with BlazorWebFormsComponents.CustomControls
- BaseClassStripTransform preserves WebControl/CompositeControl/UserControl/Control inheritance
- Update L1 golden files (TC21, TC29, TC31) for new using statement
P2-B: Lifecycle auto-wiring via virtual methods in BaseWebFormsComponent
- Add virtual Page_Init, Page_Load, Page_PreRender, Page_Unload methods
- Subclasses override directly — no reflection needed
- Called at correct Blazor lifecycle points alongside EventCallback equivalents
- Add 5 bUnit tests for lifecycle auto-wiring
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(cli): only add CustomControls using for control-derived files
Move 'using BlazorWebFormsComponents.CustomControls;' insertion from
UsingStripTransform to BaseClassStripTransform so it is only added when
the file actually inherits a CustomControls base class (WebControl,
CompositeControl, UserControl, Control). This prevents ambiguous
reference errors with Panel, PlaceHolder, and Literal which exist in
both BlazorWebFormsComponents and BlazorWebFormsComponents.CustomControls.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: add WTT run94 benchmark report (26/26 passing)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(cli): inject @inherits directive for CustomControls base classes
When a code-behind inherits WebControl, CompositeControl, UserControl,
or Control, the transform now injects @inherits and @using directives
into the .razor markup. This prevents CS0263 (partial class base class
conflict) since the Razor compiler defaults to ComponentBase when no
@inherits directive is present.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: add WebControl RenderContents tests, sample page, and documentation
- Add StatusBadge and InfoCard test components demonstrating the
TagKey + RenderContents + AddAttributesToRender pattern
- Add 15 bUnit tests covering rendering, attributes, styles, visibility
- Add sample page at /ControlSamples/Migration/CustomWebControl
- Add Playwright integration tests for the sample page
- Add docs/Migration/CustomWebControl.md documentation
- Register in ComponentCatalog and mkdocs.yml
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: promote custom WebControl migration message to README
Highlight the key tenet: change one using statement, keep your
RenderContents/TagKey/AddAttributesToRender code unchanged. Reinforces
the principle that developers rewrite as little code as possible.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(toolkit): add ASCX and Custom WebControl migration skills
- bwfc-ascx-migration: guides .ascx → .razor conversion, code-behind
preservation, tag prefix resolution, property/event mapping
- bwfc-custom-control-migration: guides RenderContents/HtmlTextWriter
preservation, TagKey mapping, the one-using-change pattern
- Updated migration-toolkit README with new skill references
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(toolkit): wire ASCX and Custom WebControl skills into migration pipeline
Connect the new skills to the migration workflow by adding them to:
- wingtip-migration-test Phase 2 skill table + reference docs
- contoso-migration-test Phase 2 skill table + description
- migration-standards Layer 2 work items
- copilot-instructions-template References section
Skills are now automatically loaded during L2 repair when .ascx or
custom WebControl files are encountered during benchmark runs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(skills): benchmark skills reference migration-toolkit directly
Benchmark workflow skills should simulate what end-users do: use the
migration-toolkit as a whole, not enumerate individual skills. The
toolkit itself knows which skills to apply based on what's encountered.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: mark all ASCX/custom-control migration items complete
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: add WTT run95 benchmark report (26/26 passing)
Validates feature/ascx-custom-control-migration branch does not regress
the WingtipToys migration. Same L2 repairs as run94 needed (ExceptionUtility
DI, SQLite switch, seed data restore).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 2398866 commit b8a06bd
118 files changed
Lines changed: 5862 additions & 2828 deletions
File tree
- .github/skills
- contoso-migration-test
- wingtip-migration-test
- .squad
- agents
- beast
- bishop
- cyclops
- forge
- decisions
- dev-docs
- control-migration
- migration-tests/wingtiptoys
- run94
- images
- run95
- images
- docs
- Migration
- cli
- migration-toolkit
- skills
- bwfc-ascx-migration
- bwfc-custom-control-migration
- migration-standards
- samples
- AfterBlazorServerSide.Tests/Migration
- AfterBlazorServerSide
- Components/Pages/ControlSamples
- Migration
- Wizard
- AfterWingtipToys
- migration-artifacts/codebehind
- src
- BlazorWebFormsComponents.Cli
- Analysis
- Config
- Pipeline
- Scaffolding
- Transforms
- CodeBehind
- Markup
- BlazorWebFormsComponents.Test
- BaseWebFormsComponent
- CustomControls
- TestComponents
- FindControl
- BlazorWebFormsComponents
- CustomControls
- tests/BlazorWebFormsComponents.Cli.Tests
- Analysis
- Scaffolding
- TestData/expected
- TransformUnit
- Transforms
- CodeBehind
- Markup
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
54 | | - | |
| 54 | + | |
55 | 55 | | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
| 56 | + | |
| 57 | + | |
62 | 58 | | |
63 | 59 | | |
64 | 60 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
108 | 108 | | |
109 | 109 | | |
110 | 110 | | |
111 | | - | |
| 111 | + | |
112 | 112 | | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
| 113 | + | |
| 114 | + | |
119 | 115 | | |
120 | 116 | | |
121 | 117 | | |
| |||
249 | 245 | | |
250 | 246 | | |
251 | 247 | | |
252 | | - | |
253 | | - | |
254 | | - | |
255 | | - | |
256 | | - | |
257 | | - | |
| 248 | + | |
258 | 249 | | |
259 | 250 | | |
0 commit comments