Repository navigation
MarkdownRenderer 1.0 native renderer and JitHub integration - #103
Draft
Xueyang-Song wants to merge 18 commits into
Draft
Xueyang-Song wants to merge 18 commits into
Xueyang-Song wants to merge 18 commits into
Conversation
The native WinUI Markdown renderer: GFM parsing, layout and painting, selection and copy, accessibility, virtualized viewport, images, HTML subset, GitHub profile styling, and the package metadata. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Optional packs: native TeX math, Mermaid diagrams via committed merman DLLs, SVG and raster decode through isolated resvg worker processes (vendored crates pinned by provenance), and TextMate syntax highlighting with bundled grammars. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Behavior, conformance, pixel and pack test projects for the renderer and its feature packs, plus NativeAOT smoke apps that publish each pack. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sample app and its automation helper used by the UI test scripts, the WinUI performance harness, and BenchmarkDotNet benchmarks used by the CI performance gates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Packaging, release-readiness and performance-gate scripts, the Windows Sandbox UI test runners and their self-tests, and the MarkdownRenderer preview CI workflow. The product performance gate now runs on push only for main, since pull requests already cover feature branches. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
JitHub renders README and Markdown previews with the new renderer and its packs: runtime and theme wiring, the viewer lifecycle, the leased image admission pipeline (Camo, raw CDN and Git LFS sources), SVG previews on resvg, NativeAOT dependency pins and notices, and host contract tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Architecture, API, feature-pack, testing, performance and release documentation for MarkdownRenderer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
zhuowcui
reviewed
Oct 27, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Xueyang-Song
marked this pull request as draft
October 27, 2026 17:48
…ublic API and structure checks (#104) * Add code structure standards to AGENTS.md Rules for project ownership, dependency direction, InternalsVisibleTo, public API tracking, file and class size, and test structure, so changes are reviewed against an explicit bar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Move MarkdownRenderer projects into src, tests, samples, perf and tools Pure moves: shipping libraries to src/, tests to tests/ (AOT smoke apps to tests/aot/), the sample apps to samples/, the harness and benchmarks to perf/, and the conformance runner to tools/. Also removes 243 old SVG pixel-diff images that were committed into the Git-ignored artifacts folder. Path fixes follow in the next commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Update paths for the new MarkdownRenderer layout Fixes project references, linked items, workflow paths, scripts, runtime path lookups in tests and tools, and docs for the moved projects. Adds MarkdownRenderer.slnx with solution folders that mirror the disk layout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Allow benchmark projects and an executable's own tests in the standards Matches established .NET practice: microbenchmark projects may see internals, and an executable may be referenced by its own test project only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Fix resvg supply-chain policy path after the move Generate-/Verify-ResvgSupplyChain.ps1 found the repository license policy relative to the provider's parent folder, which is now src/. Both scripts are listed inputs of the worker source fingerprint, so RESVG_WORKER_IDENTITY.json gets new source and build fingerprints computed by ResvgWorkerIdentity.psm1. The worker executables and their hashes are unchanged; CI rebuilds all three workers from source and compares them with the committed binaries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Make every source file owned by the project that compiles it - MarkdownRenderer.Core now physically holds the document model, engine, extensions, SourceSpan and MarkdownStyleRole instead of compiling them out of the WinUI project's folder. The WinUI project no longer removes them, and Core has one AssemblyInfo file. - The 8 Performance files and the 3 SVG snapshot/budget files move into MarkdownRenderer.Performance and MarkdownRenderer.Svg.Resvg, the only assemblies that compiled them. - GfmChildBuilder becomes one internal class in the WinUI renderer instead of two copies (Gfm and Html) behind an #if that switched its namespace. HtmlBlockRenderer and HtmlPreformattedTextProjection move into Html; AlertRenderer and FootnoteRenderer into GitHub. - New perf/MarkdownRenderer.PerformanceHarness.Core holds the harness's WinUI-free measurement logic, referenced by the harness and the tests. - New tests/MarkdownRenderer.Svg.Resvg.TestSupport holds raster fixtures shared by the resvg tests and its AOT smoke app. - MarkdownRenderer.Tests references the real assemblies instead of compiling 112 product files with diagnostics forced on. Tests move to the project that owns their subject (resvg budget tests to Svg.Resvg.Tests, TextMate highlighter tests to TextMate.Tests, process-exit tests to a new Sample.Automation.Tests). Duplicate runs in GitHub.Tests are removed. - JitHub.WinUI.Tests references the renderer instead of linking 10 of its files. Benchmarks reference the renderer instead of linking a file. - Deleted SvgThemeInjector and RasterImageTilePlanner, which no shipping assembly compiled, with their 23 tests, and 11 tests of the sample app's link-routing glue. Two links remain, each documented in its project file with a removal plan: the TextMate grammar loader shared by both grammar packs, and the harness performance listener compiled into GitHub.Tests. Both need a public API decision (step 2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Share renderer build settings and pin package versions centrally - MarkdownRenderer/Directory.Build.props imports the repository props instead of repeating the build-tools version, so the renderer follows the same lock-file, audit and locked-restore policy as the app. - Folder props for src, tests, tests/aot, samples, perf and tools hold what each kind of project shares. Project files keep only what is unique to them (691 lines removed, 100 added). - Directory.Packages.props turns on central package management with one version per package. WindowsAppSDK and its runtime are unified on 1.8.260710003. - Every renderer package ships as 1.0.0-preview.1. Html, Math and Mermaid were 0.1.0-preview.1. - The package icon lives in MarkdownRenderer/assets instead of being taken from JitHub.Web. - Shipping libraries treat warnings as errors, and the trim and AOT warnings fail every AOT-compatible library and smoke. Non-shipping projects are not packable. - Removed a dead variable in MarkdownPerformanceSession that only compiled in the layout-diagnostics build. Lock files change format (CPM writes v2 and marks centrally managed indirect packages CentralTransitive). Resolved versions and hashes are unchanged apart from the WindowsAppSDK unification and the Html version bump. Packed nuspecs and file lists are identical apart from the version change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Track the public API with PublicApiAnalyzers - Every shipping assembly declares its public and protected surface in PublicAPI.Shipped.txt and PublicAPI.Unshipped.txt, checked by Microsoft.CodeAnalysis.PublicApiAnalyzers 5.6.0. Nothing has shipped, so every entry is unshipped. Undeclared, removed, duplicate and nullability-oblivious entries are errors (src/PublicApiAnalyzers .globalconfig), and a shipping project without the files fails the build (src/Directory.Build.targets). - The generated files cover all 2,532 symbols of the old reflection baselines with the same modifiers, nullability, defaults and constant values, plus the 29 implicit struct constructors reflection missed. - Removed the custom gate: PublicApiSurface.cs, PublicApiBaselineTests, StablePublicApiTests, the 12 baseline files and Update-PublicApiBaselines.ps1. Three theming behaviour tests from it moved to ThemingCompatibilityContractTests. - New MarkdownRenderer.PublicApi.Tests checks the design rules the API files cannot express: no third-party or renderer-internal types in public signatures, readonly structs with default layout, sealed or static classes, paired IEquatable/Equals, unique resource keys. It uses only reflection over exported types. Binary compatibility beyond signatures is left to SDK package validation once a version ships (release checklist). - RS0026 and RS0027 are suggestions until step 2 fixes the three Core constructors that break them. - Removed the obj-*/bin-* DefaultItemExcludes from the repository and renderer props, five renderer projects and JitHub.WinUI.Tests. They only existed for the baseline script's separate output tree; builds that need one use ArtifactsPath. - Removed the ManagedPacksOnly lane from GitHub.Tests. Nothing set it, and it existed only to Compile Remove 16 test files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Make renderer structure exceptions explicit and fail the build on new ones - Every InternalsVisibleTo grant is an item in the owning project file. The eight AssemblyInfo.cs files that held only grants are deleted. - Two unused grants are removed: Core to MarkdownRenderer.Conformance.Tests and Performance to JitHub.WinUI. Their grantees build without them, and the compiled assemblies differ from before only by these two attributes. - Grants to an assembly that is not a .Tests or .Benchmarks project carry ProjectStructureException metadata with the reason and the step that removes them (public extension API in step 2, the PixelTests rename in step 6). So do the two remaining compile links, whose reasons move from comments into the metadata. - MarkdownRenderer/Directory.Build.targets checks every renderer project before PrepareForBuild: MRS0001 fails on a Compile, Page or ApplicationDefinition item outside the project folder, MRS0002 on a grant to a non-test, non-benchmark assembly, unless the item declares an exception. Generated sources in the intermediate output and sources that NuGet packages add are skipped by path. Design-time builds skip the check. - eng/Test-ProjectStructure.ps1 checks what one project build cannot see: no [assembly: InternalsVisibleTo] in source (MRS0003), no source folder without a project unless a declared exception compiles it (MRS0004), the solution lists every project and each entry exists (MRS0005, MRS0006), and exceptions name literal files (MRS0007). It runs first in the preview workflow; its self-test runs with the other engineering self-tests. - testing-and-diagnostics.md describes the layout, both checks and the exception metadata. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Check central package versions in the release security gate Verify-DependencySecurity.ps1 required a Version attribute on every PackageReference, so the JitHub.WinUI Release build failed once the renderer moved its versions to Directory.Packages.props. The gate now checks each PackageVersion in every Directory.Packages.props with the same floating and prerelease rules, accepts VersionOverride, and still fails a PackageReference that has no version in the project or in the central file above it. The gate's nested test run also built JitHub.WinUI.Tests as AnyCPU: its x64 default only applied to an empty Platform, but the SDK sets AnyCPU first. Now that the tests reference the renderer, Win2D warned about it. The default now covers AnyCPU, as the renderer props already do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Give the TextMate AOT smoke the SDK build tools The smoke reaches the Windows App SDK through the renderer, whose self-contained manifest step runs mt.exe. Without the build-tools package mt.exe had to be on PATH, so MarkdownRenderer.slnx only built from a Developer PowerShell. The Svg.Resvg smoke already references the package for the same reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…nsion and lifetime API (#105) * Ship the engine, profiles and WinUI renderer as one MarkdownRenderer assembly The WinUI layout walks the parser's Markdig syntax tree. With that tree kept out of the public API, and no internals grants allowed between shipping assemblies, Core and the renderer could not stay separate assemblies. Gfm, GitHub, Html and Performance were renderer code in their own DLLs, plugged in through internal types. Core, Gfm, GitHub, Html and Performance now live in src/MarkdownRenderer, in folders that match their namespaces. Namespaces are unchanged. The package that ships MarkdownRenderer.dll is now called MarkdownRenderer (it was MarkdownRenderer.WinUI), and the dependency-only MarkdownRenderer package is gone. Packages drop from 14 to 8: MarkdownRenderer, the Math, Mermaid, resvg and TextMate packs, the two grammar packs and MarkdownRenderer.All. Consequences: - Math and Mermaid reference the renderer package, so they pull in the Windows App SDK and Win2D. Their test projects reference the Windows App SDK runtime like the other renderer tests, and the Math, Mermaid and conformance executables reference the SDK build tools for mt.exe. - Core.AotSmoke and ManagedPacks.AotSmoke covered the same assembly and are now one MarkdownRenderer.AotSmoke that runs both sets of checks. - The performance harness no longer records a Core DLL hash. - SafeHtmlFeature.PackageId and SafeHtmlCapabilityDescriptor.PackageId named a package that no longer exists and are removed. - Tests that asserted which assembly a type lived in now assert the behavior instead, or are removed where the strict-GFM and GitHub registry tests already cover it. Lock files are regenerated for the new project graph. No resolved package version or hash changed; the only additions are the Windows App SDK and Win2D packages, at their pinned versions, in the projects that used to reference only Core. The remaining internals grants are listed with reasons in the renderer project and are removed by the next commits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Give Math and Mermaid a public API for deferred scenes Math and Mermaid read the internal MarkdownExtensionContext. ShouldDeferOffscreenScenes and tagged their placeholders with an undocumented "renderer.internal.deferred-scene" attribute. The renderer kept its own copy of that string in four files, and each pack kept its own marker counter. The protocol is now public and documented: - MarkdownExtensionContext.CanDeferOffscreenScenes says whether this render pass may emit a placeholder. - MarkdownExtensionContext.CreateDeferredSceneMarker() returns a new marker, unique across the engine's documents and prefixed with the node kind, as the progressive scene plan expects. It throws when the pass cannot defer. - MarkdownContentAttributes.DeferredScene is the attribute key, next to the other declarative attribute keys. The attribute stays a plain attribute, so the progressive-scene tests can still feed malformed markers to the renderer's defensive paths. The Math and Mermaid internals grants are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Remove the TextMate pack's compatibility helpers and internal hooks The TextMate pack reached internal control and builder hooks (SetOwnedCodeHighlighter, WithOwnedCodeHighlighterFactory) only from its [Obsolete] compatibility overloads, which created and owned a highlighter per view. Those overloads also found grammar packs by type name through TextMateGrammarProviderFactory, which needed RequiresUnreferencedCode. Removed: - the six obsolete UseTextMateSyntaxHighlighting overloads, - the parameterless TextMateCodeBlockSyntaxHighlighter constructor, - TextMateGrammarProviderFactory, - the control's owned-highlighter fields, transfer and retirement code, the builder's owned-highlighter factory, and OwnedCodeHighlighterAssignment, which only they used. The three UseTextMateSyntaxHighlighting overloads that take an explicit TextMateCodeBlockSyntaxHighlighter stay; the caller owns the highlighter. Tests that only checked the removed members are removed, and the highlighter tests construct CommonTextMateGrammarProvider directly. The TextMate internals grant is removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Update scripts, CI and docs for the single MarkdownRenderer package - CI publishes MarkdownRenderer.AotSmoke with NativeAOT in place of the Core smoke, restoring it for the target RID because it now consumes the Windows App SDK. The package-consumption step tests only the MarkdownRenderer package, and the restore and pack lists name the eight shipping projects. - Release, compliance, architecture and performance-gate scripts use the new package set. Math's release evidence expects one dependency, MarkdownRenderer, and the Math and Mermaid evidence scripts put mt.exe on PATH like the resvg script. The size-gate package lookup no longer treats every feature pack as a MarkdownRenderer package. - The MarkdownRenderer managed-size budget is the measured DLL plus about 10%, the rule the other budgets follow. The GFM, GitHub, HTML and performance code it now holds never had a managed budget, so the earlier engine and viewer budget did not cover it. - Docs describe one MarkdownRenderer package plus feature packs, with a decision note on why the renderer is one assembly. The deleted GitHub and Html package READMEs are folded into supported-markdown.md, and the AOT section no longer describes the removed grammar-pack discovery. - The line-ending rule for the fingerprinted Primer CSS follows the files to their new folder. - The standards in AGENTS.md describe the new dependency order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Move the conformance harness and pixel tests to ordinary test projects Both needed internals grants with exceptions: - The conformance harness was an executable in tools/ that called the engine's internal spec-HTML oracle. It is test code, so it now lives in MarkdownRenderer.Conformance.Tests. Its command-line run over the official corpora is now an opt-in test (MARKDOWN_RENDERER_CONFORMANCE=1, Category=Conformance) that writes the same report. The tools folder is gone. All 1,322 official CommonMark and GFM examples pass. - MarkdownRenderer.PixelTests is now MarkdownRenderer.Pixel.Tests, so its name ends in .Tests like every other test project. The renderer grants both test projects internals without an exception. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Delete the obsolete members and make the renderer control an abstract base Nothing has shipped, so a 1.0 should not start with [Obsolete] surface. - MarkdownRendererControl was an obsolete class (MR1001) that apps could construct, and the base of MarkdownScrollView and MarkdownDocumentView. It is now an abstract base with a private protected constructor, so only the two views derive from it. MarkdownRendererControlBuilder.Build() is removed; BuildScrollView and BuildDocumentView remain. The MR1001 suppressions in the renderer, tests, sample and app are gone. - ICodeBlockSyntaxHighlighter, the CodeBlockSyntaxHighlighter property and dependency property, WithCodeBlockSyntaxHighlighter and the adapter that bridged them are removed. ICodeHighlighter now declares Revision itself, and CreateDefault takes an ICodeHighlighter. - CodeBlockHighlightRequest no longer carries a cancellation token; the token is passed only to HighlightAsync. The TextMate highlighter drops its single-argument overload and the code that linked the two tokens, and still throws ObjectDisposedException after disposal. The API test that allowed one reviewed inheritable class now checks the rule itself: an exported class is sealed, static, or has no constructor that code outside its assembly can call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Give the views a public disposal API and drop the app's internals grant The JitHub app reached two internal members to shut a view down: the DisposalCompleted event, to learn that Dispose had finished teardown, and DrainRetiredSnapshotsAsync, to wait until the released Win2D resources were freed. The sample used the same event. The library had to name the app in an internals grant. MarkdownRendererControl now implements IAsyncDisposable: - DisposeAsync() disposes the view and returns a task that completes when the resources it released are freed, or faults if one could not be released. It throws when teardown did not finish, including after an earlier Dispose that failed part way, which a plain Dispose retry cannot report. - The public Disposed event replaces the internal DisposalCompleted event, for teardown that the view's window starts. The app feeds DisposeAsync into its existing retirement sequence and no longer tracks the event; the sample's disposal evidence uses Disposed. The JitHub.WinUI internals grant is removed, so the library no longer names the app. One app test that asserts on source text is updated to the new calls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Brings in #108, which refreshed main's Native AOT lock files and the AOT dependency ledger from 10.0.12 to 10.0.14. This branch had already regenerated the same files for its new project layout at 10.0.14, so every conflict resolves to this branch's side. Locked Native AOT restore (x64) and Update-NativeAotDependencyLedger.ps1 -Verify pass on the merged tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#106) The resvg pack plugged into the renderer through internal types in three groups. Each is now public API in MarkdownRenderer.Images, and resvg uses only public API. Memory admission and render priority. These are optional capabilities an IMarkdownSvgRenderer can implement; the views detect them: - IMarkdownSvgAdmission (TryOpenAsync, WaitForCapacityAsync), so the view waits for capacity instead of failing an image when the provider is full. - IMarkdownSvgPreparationAdmission and IMarkdownSvgPreparationLease, for PrepareSource scratch memory from the same capacity. - IMarkdownSvgPrioritizedDocument and MarkdownSvgRenderDemand, so queued renders move ahead when their image scrolls into view. Only Priority and RegisterPromotion are public; the view creates and raises demands. - MarkdownSvgAdmissionResult and MarkdownSvgAdmissionStatus. The internal names said "host" (OpenForHostAsync, MarkdownSvgDemandTicket and so on); the public names drop it. Raster checks. MarkdownRasterImageInspection.Inspect applies the renderer's own decode budget to encoded bytes without decoding them. resvg uses it before sending WebP and SVG-embedded rasters to its worker, instead of calling the renderer's internal budget parser. MarkdownRasterFormat gains Ico, which the parser already recognized. SVG source information. resvg reads an SVG's title, description and root size during its own validation pass, which a test holds to at least 30% fewer allocations than separate passes. It now does that with the public MarkdownSvgSourceInfoReader and hands the result over with MarkdownSvgSourcePreparation.Admit(bytes, info). The view's own fallback uses the same collector, so there is still one implementation. The opt-in layout-diagnostics build, which was already failing and is not part of CI, still stops in resvg: its #if diagnostics blocks write worker events into the renderer's internal event source and read its correlation ID. Step 4 replaces those blocks. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…st (#110) The sample app and the performance harness were the last projects that read renderer internals through ProjectStructureException grants. Sample: public API only. - MarkdownTheme.ForcedContrastColors (MarkdownContrastColors) replaces the process-wide ThemeResolver.SystemThemeProviderOverride. Setting it raises the theme's Changed notification, so views restyle as for a Windows contrast switch. - MarkdownRendererControl.RenderedContentSize and RenderedThemeVariant report what the view last displayed, which the sample's UI-test status and touch layout capture use as checks. - The touch capture reads scroll position through the UI Automation scroll pattern. - CodeBlockThemeVariant becomes MarkdownThemeVariant in Theming, shared by RenderedThemeVariant and CodeBlockHighlightRequest.ThemeVariant. Performance harness: a white-box performance test. - MRS0002 now allows grants only to the renderer's own projects at tests\<name>\<name>.csproj or perf\<name>\<name>.csproj, which never ship, instead of to any name ending in .Tests or .Benchmarks. - PerformanceEventListener moves into PerformanceHarness.Core, which GitHub.Tests references instead of linking the harness's source file. - The harness's measured code is unchanged, so results stay comparable with the existing baselines. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…th expose configuration only (#112) * Give the sample public diagnostics and class the perf harness as a test The sample app and the performance harness were the last projects that read renderer internals through ProjectStructureException grants. Sample: public API only. - MarkdownTheme.ForcedContrastColors (MarkdownContrastColors) replaces the process-wide ThemeResolver.SystemThemeProviderOverride. Setting it raises the theme's Changed notification, so views restyle as for a Windows contrast switch. - MarkdownRendererControl.RenderedContentSize and RenderedThemeVariant report what the view last displayed, which the sample's UI-test status and touch layout capture use as checks. - The touch capture reads scroll position through the UI Automation scroll pattern. - CodeBlockThemeVariant becomes MarkdownThemeVariant in Theming, shared by RenderedThemeVariant and CodeBlockHighlightRequest.ThemeVariant. Performance harness: a white-box performance test. - MRS0002 now allows grants only to the renderer's own projects at tests\<name>\<name>.csproj or perf\<name>\<name>.csproj, which never ship, instead of to any name ending in .Tests or .Benchmarks. - PerformanceEventListener moves into PerformanceHarness.Core, which GitHub.Tests references instead of linking the harness's source file. - The harness's measured code is unchanged, so results stay comparable with the existing baselines. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * MarkdownRenderer structure step 2d: enforce optional-parameter overload rules, hide Mermaid and Math processors Turn RS0026/RS0027 back into errors and fix what they find: one constructor each for MarkdownVectorTextStyle, MarkdownStyleContext and MarkdownStyleSelector with the role/ancestor qualifier as a trailing optional parameter, and explicit MarkdownVectorScene overloads. The feature extension classes suppress the rules at class level, and a new PublicApi test checks the property they rely on for each receiver. Mermaid and Math now expose only host configuration. The headless processors, their results, diagnostics, scene formats and decoders become internal; Math grants internal access to its tests and the benchmarks. The Mermaid and Math NativeAOT smokes now render through UseMermaid/UseMathematics. EmbedVisibility becomes internal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…hrough an engine package (#113) * Give the sample public diagnostics and class the perf harness as a test The sample app and the performance harness were the last projects that read renderer internals through ProjectStructureException grants. Sample: public API only. - MarkdownTheme.ForcedContrastColors (MarkdownContrastColors) replaces the process-wide ThemeResolver.SystemThemeProviderOverride. Setting it raises the theme's Changed notification, so views restyle as for a Windows contrast switch. - MarkdownRendererControl.RenderedContentSize and RenderedThemeVariant report what the view last displayed, which the sample's UI-test status and touch layout capture use as checks. - The touch capture reads scroll position through the UI Automation scroll pattern. - CodeBlockThemeVariant becomes MarkdownThemeVariant in Theming, shared by RenderedThemeVariant and CodeBlockHighlightRequest.ThemeVariant. Performance harness: a white-box performance test. - MRS0002 now allows grants only to the renderer's own projects at tests\<name>\<name>.csproj or perf\<name>\<name>.csproj, which never ship, instead of to any name ending in .Tests or .Benchmarks. - PerformanceEventListener moves into PerformanceHarness.Core, which GitHub.Tests references instead of linking the harness's source file. - The harness's measured code is unchanged, so results stay comparable with the existing baselines. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * MarkdownRenderer structure step 2d: enforce optional-parameter overload rules, hide Mermaid and Math processors Turn RS0026/RS0027 back into errors and fix what they find: one constructor each for MarkdownVectorTextStyle, MarkdownStyleContext and MarkdownStyleSelector with the role/ancestor qualifier as a trailing optional parameter, and explicit MarkdownVectorScene overloads. The feature extension classes suppress the rules at class level, and a new PublicApi test checks the property they rely on for each receiver. Mermaid and Math now expose only host configuration. The headless processors, their results, diagnostics, scene formats and decoders become internal; Math grants internal access to its tests and the benchmarks. The Mermaid and Math NativeAOT smokes now render through UseMermaid/UseMathematics. EmbedVisibility becomes internal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * MarkdownRenderer structure step 2e: share the TextMateSharp adapter through an engine package Move the TextMateSharp-backed grammar provider that Grammars.Common and Grammars.All compiled from one linked source file into a new shipping package, MarkdownRenderer.SyntaxHighlighting.TextMate.Engine, as the public TextMateSharpGrammarProvider. Both packs reference it, and no file link or ProjectStructureException remains. The engine is the one package whose public API names TextMateSharp types; the forbidden-contract test allows that for this assembly only and fails if the exception stops being needed. Wire the ninth package into both solutions, CI restore and pack lists, the release package set, the managed-architecture map, the TextMate release evidence (dependency rules and the Common selected-RID payload), the compliance self-tests, the app security gate test, lock files and the packaging docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
HealthyBusySnapshotIsRetryableAndDoesNotClaimRecovery queued its blocking measure on the thread pool and gave it 2 s to start. In CI's parallel GitHub testhost the pool can be saturated for longer, so the handshake timed out before the snapshot was ever busy. The measure now runs on a LongRunning task, which gets its own thread. The file's 2 s waits were hang guards, not deadlines under test, so they share one 30 s HangGuard. Every assertion is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keeps the integration branch's removal of SkiaSharp and Svg.Skia from JitHub.WinUI.Tests and adds main's Microsoft.Extensions.TimeProvider.Testing reference. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces #99 with a clean history and a smaller scope. It keeps the renderer, its feature packs, and what's needed to keep developing them (tests, harness, UI test runners, performance gates, CI, docs), plus the JitHub integration the renderer needs. It drops the dev-time material from the correctness campaign.
Commits
markdown-renderer-preview.yml.Not in this PR (vs #99)
eng/readme-audit, the audit app, the top-500 audit runners, and the audit code in JitHub (same-byte resolvers, first-viewport probes, launch/auth audit hooks, audit automation probes)Local verification (Release x64, SDK 10.0.403)
Renderer tests, 0 failures in each:
PerformanceExternalGateFixtureTestsskipped locally; CI runs it)JitHub.WinUI.Tests: 3141 passed (Debug x64, as in CI).
App builds: Debug and Release builds of JitHub.WinUI pass, including the release security gate. The x64 NativeAOT publish and
Verify-NativeAotArtifactpass.Other builds and checks: the Sample, PerformanceHarness, Automation and PerformanceGate builds pass, and all 5 engineering script self-tests pass.
Binaries: the committed native binaries are byte-identical to Complete MarkdownRenderer 1.0 native feature set #99.
Not run locally: PixelTests (Edge headless times out on this machine), MSIX packaging, and the live Sandbox UI runners.
🤖 Generated with Claude Code