Apply Butil improvements (#12393)#12419
Conversation
|
Important Review skippedToo many files! This PR contains 225 files, which is 75 over the limit of 150. To get a review, narrow the scope: ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (225)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
|
@coderabbitai re-review |
|
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Pull request overview
This PR delivers a large set of "Butil improvements" (closes #12393). It expands the Bit.Butil JS-interop surface with many new Web-API wrappers (Battery, BroadcastChannel, ContactPicker, EyeDropper, Fetch, FileReader, Geolocation, IdleDetector, IndexedDb, MediaDevices, Mutation/Resize/Intersection Observers, NetworkInformation, Nfc, ObjectUrls, Performance, Permissions, Push, Reporting, SpeechRecognition/Synthesis, StorageManager, WakeLock, WebAudio, WebLocks, CookieStore, etc.), refactors the demo project (new MainLayout/NavMenu, DemoCard/DemoConsole/PageHeader shared components, redesigned Index/Keyboard/UserAgent pages), and adds a new end-to-end test project plus a CI workflow.
Changes:
- Adds ~40 new public service classes plus matching listener managers, DTOs, and TypeScript modules implementing the wrappers.
- Reworks the Butil demo UI shell and several pages, drops the old
Header.razor/CSS, and swaps_content/Bit.Butil.Demo.Core/app.cssinto the host HTML. - Adds
Bit.Butil.E2ETestsPlaywright/NUnit suite (and CI workflow) plus tweaksJSRuntimeExtensions/BitButil.cs(service lifetime change toScoped, simplified runtime-validity check, no longer swallowingJsonException).
Reviewed changes
Copilot reviewed 225 out of 225 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Butil/Bit.Butil/BitButil.cs | Switches all service registrations from Transient to Scoped and registers the many new services. |
| src/Butil/Bit.Butil/Extensions/{InternalJSRuntimeExtensions,JSRuntimeExtensions}.cs | Simplifies runtime-validity detection and stops swallowing JsonException in FastInvoke*. |
| src/Butil/Bit.Butil/Publics/**/*.cs | Adds wrapper classes (Fetch, Push, Permissions, WakeLock, MediaDevices, Nfc, …) and DTOs/handles. |
| src/Butil/Bit.Butil/Internals/**/*ListenersManager.cs | New static managers for the corresponding listener types, with [JSInvokable] callbacks. |
| src/Butil/Bit.Butil/Scripts/*.ts | New TS modules implementing every JS-side counterpart, plus tweaks to existing events.ts, keyboard.ts, navigator.ts, storage.ts, userAgent.ts, utils.ts, document.ts. |
| src/Butil/Bit.Butil/Publics/{History,Screen,ScreenOrientation,VisualViewport,Keyboard,Notification}.cs | Adds Subscribe* variants returning ButilSubscription, plus tracked-notification and element-scoped keyboard. |
| src/Butil/Bit.Butil/Publics/Cookie.cs | Hardens parsing of empty / malformed cookie strings. |
| src/Butil/Demo/Bit.Butil.Demo.Core/Shared/* | Replaces Header.razor with new MainLayout/NavMenu and adds DemoCard/DemoConsole/PageHeader. |
| src/Butil/Demo/Bit.Butil.Demo.Core/Pages/{Index,Keyboard,UserAgent}.razor | Redesigns landing and a couple of demo pages around the new shared components. |
| src/Butil/Demo/Bit.Butil.Demo.{Web,Maui}/wwwroot/index.html | Pulls in the new shared app.css. |
| src/Butil/tests/Bit.Butil.E2ETests/** | New Playwright/NUnit test project, infrastructure, page-scoped bases, README, CI workflow. |
|
@coderabbitai re-review |
|
✅ Actions performedFull review triggered. |
| async function readAsBytes(input: HTMLInputElement, index: number) { | ||
| const f = file(input, index); | ||
| if (!f) return null; | ||
| const buf = await f.arrayBuffer(); | ||
| return new Uint8Array(buf); | ||
| } |
| async getStatus() { | ||
| const nav = window.navigator as any; | ||
| if (typeof nav.getBattery !== 'function') { | ||
| return { charging: true, chargingTime: 0, dischargingTime: Infinity, level: 1 }; | ||
| } | ||
| const b = await nav.getBattery(); | ||
| return { | ||
| charging: !!b.charging, | ||
| chargingTime: b.chargingTime, | ||
| dischargingTime: b.dischargingTime, | ||
| level: b.level | ||
| }; |
| /// <summary>Seconds remaining until fully charged. <see cref="double.PositiveInfinity"/> when unknown.</summary> | ||
| public double ChargingTime { get; set; } | ||
|
|
||
| /// <summary>Seconds remaining until discharged. <see cref="double.PositiveInfinity"/> when unknown.</summary> | ||
| public double DischargingTime { get; set; } |
| /// Object URLs leak memory if not revoked. The instance tracks every URL it creates so | ||
| /// disposal automatically revokes outstanding ones. Use <see cref="Create"/> when you want | ||
| /// the URL to outlive disposal and call <see cref="Revoke"/> yourself. | ||
| /// </remarks> |
| /// <summary> | ||
| /// Starts the request and immediately returns an <see cref="AbortableFetch"/>. Await | ||
| /// <see cref="AbortableFetch"/> won't give you the response — use this when you only | ||
| /// need fire-and-forget abort control. For typical use prefer <see cref="Send"/>. | ||
| /// </summary> |
|
|
||
| <div class="app-content"> | ||
| <div class="topbar"> | ||
| <button class="menu-btn" @onclick="ToggleNav">☰</button> |
| } | ||
| @if (!string.IsNullOrWhiteSpace(MdnUrl)) | ||
| { | ||
| <a class="mdn-link" href="@MdnUrl" target="_blank" rel="noopener"> |
closes #12393