Skip to content

Tags: cdpath/SwiftStreamingMarkdown

Tags

v0.6.0

Toggle v0.6.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Document image support; add Images demo and snapshot test (microsoft#146

)

* Document image support; add Images demo and snapshot test

Finalize block-level image support (parts 1-4 already shipped) with the
non-rendering deliverables:

- README: move Images into the supported list with an accurate description
  of the experimental ImageConfig source types and fullscreen viewer.
- Sample app: add an Images demonstration (enum case, subtitle, fixture)
  showcasing asset-catalog, bundled-resource, and remote sources, plus
  image-alongside-text splitting and an unresolved-source placeholder.
- Tests: add ImageBlockSnapshotTests rendering a deterministic bundled
  image via Image(mdImage:); bundle test resources via Package.swift and
  record the iOS reference snapshots.

Refs microsoft#89

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 17e2748f-66c1-4deb-b557-df65a17c84f5

* Add MarkdownListener bundled-resource fallback; address review

Addresses review comments on the image-support PR:

- Add `MarkdownListener.resolveBundledResource(fileName:ext:)` (default
  returns nil). The renderer now resolves bundled-resource images from the
  app's main bundle first and falls back to the listener when absent, so
  consumers can serve images that live in a dependency package or framework
  bundle rather than the app target. Threaded through BundledResourceImage,
  the fullscreen viewer, and the image-tap payload.
- README: move Images up under Paragraphs in the supported list.
- Tests: parse Markdown containing a bundled image and verify end-to-end
  resolution via the listener (the resource lives only in the test bundle);
  cover the no-listener case; render the image deterministically via
  Image(mdImage:) for the visual snapshot. Replace the helper's fatalError
  with throwing XCTUnwrap so a missing resource is a normal test failure.

Refs microsoft#89

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 17e2748f-66c1-4deb-b557-df65a17c84f5

* Snapshot the image failure case; make image controller non-optional

Addresses the second review round on PR microsoft#146:

- Replace the bundled-image snapshot with the deterministic failure case: a
  remote image whose host is not in the allowed domains resolves to nil and
  renders BlockImageFailureView synchronously. The remote and bundled loading
  paths render asynchronously via `.task`, which the synchronous snapshot
  harness captures as the loading placeholder, so they can't be snapshotted
  deterministically.
- Remove the direct Image(mdImage:) snapshot and the bundled-resource
  pipeline-logic tests from the snapshot file; move listener-fallback
  resolution coverage into ImageTapTests as a fast unit test.
- Make ImageData.makeMarkdownImage(controller:) take a non-optional
  MarkdownController (the default only existed for test convenience); unwrap
  the environment controller in BlockImageView before building the payload.

Refs microsoft#89

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 17e2748f-66c1-4deb-b557-df65a17c84f5

* Add macOS snapshot references for the image failure test

Recorded via the Record macOS Snapshots workflow (runs/29458940981) so the
macOS SPM CI job has references for the new failure-placeholder snapshot.

Refs microsoft#89

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 17e2748f-66c1-4deb-b557-df65a17c84f5

* Surround snapshot image with text; keep image controller optional

Addresses the latest review comments on PR microsoft#146:

- Snapshot: the failure-placeholder test now parses a paragraph before and
  after the image, so the rendered DocumentView shows text/image/text.
- Revert makeMarkdownImage(controller:) to an optional MarkdownController.
  SwiftUI's environment injection does not guarantee a non-nil controller, so
  BlockImageView optionally chains onImageTap rather than guarding out.

Refs microsoft#89

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 17e2748f-66c1-4deb-b557-df65a17c84f5

* Re-record macOS snapshot references for the text-wrapped image test

Regenerated via the Record macOS Snapshots workflow (runs/29460803999) after
surrounding the snapshot image with text.

Refs microsoft#89

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 17e2748f-66c1-4deb-b557-df65a17c84f5

---------

Co-authored-by: Jun Yan <yanjun@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

v0.5.0

Toggle v0.5.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Fixed ambiguous Document type on Xcode 27 (microsoft#137)

New SwiftUI introduces a Document type which causes conflicts. https://developer.apple.com/documentation/swiftui/document

v0.4.0

Toggle v0.4.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Fix macOS crash when rendering markdown links (microsoft#130)

* Fix macOS crash when rendering markdown links

Link.convert stored an empty Swift array as the .underlineStyle
attribute value: in a [NSAttributedString.Key: Any] context the []
literal infers as an empty array, not NSUnderlineStyle. TextKit expects
an NSNumber there and AppKit calls -integerValue on it during layout,
crashing NSTextView with -[Swift.__EmptyArrayStorage integerValue].
UIKit tolerates the bad value, which is why iOS never crashed. Store
NSUnderlineStyle([]).rawValue instead and add a regression test
asserting the attribute bridges to NSNumber.

Fixes microsoft#128

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add attribute type-safety audit test

Walks every attribute the conversion pipeline emits across paragraphs,
lists, and tables (bold, strikethrough, links, inline code, LaTeX,
citations, task lists) and asserts the value types TextKit expects:
NSNumber for numeric keys, platform color/font for styling keys, URL,
NSTextAttachment, and NSParagraphStyle. Fails on any platform when a
wrongly-typed attribute enters the pipeline, so the crash class fixed
in the previous commit cannot silently return through another key.

Refs microsoft#128

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

v0.3.0

Toggle v0.3.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Update macOS snapshots from CI runner (macOS 26.4) (microsoft#116)

Replace locally-recorded macOS snapshots with those generated on the
CI runner to ensure pixel-perfect match during CI validation.

Recorded via the Record macOS Snapshots workflow on macos-26 runner.

Co-authored-by: Jun Yan <yanjun@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

v0.2.0

Toggle v0.2.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat: make block spacing configurable via MarkdownRenderConfig (micro…

…soft#90)

v0.1.0

Toggle v0.1.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Restore sample streaming demo controls (microsoft#80)

* Restore sample streaming demo controls

Adds the sample app streaming drawer, playback speed controls, performance metrics, theme picker, and simulator destination selection improvements for local demo builds.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Tighten drawer reveal scroll threshold

Only auto-scroll completed content when revealing the controls drawer if the scroll view is effectively at the bottom, avoiding jumps after the user scrolls up slightly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update new sample file headers

Matches the new SwiftLint file_header pattern from main for the sample streaming demo files added by this branch.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address streaming demo review feedback

Derive the preferred simulator runtime from the active iPhoneSimulator SDK and preserve simulated stream delay while playback is paused.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Consolidate sample playback, metrics, and streamed source into DemonstrationViewModel

- Merge StreamingPlaybackController + StreamingPerformanceModel +
  TextSimulatedStreamSource into a single @mainactor
  DemonstrationViewModel that conforms to StreamedMarkdownSource.
- Switch scroll-bottom detection to iOS 18's .onScrollGeometryChange
  (drops the GeometryReader + PreferenceKey + coordinate-space plumbing).
- Rewrite waitUntilPlaying() as an event-driven for-await over
  $isPlaying.values instead of a 75ms busy-poll.
- Replace the fastForwardRequest version counter with a Bool flag
  (isFastForwarding) reset in the existing reset() chokepoint.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Move drawer + scroll-bottom UI state onto DemonstrationViewModel

Pull isAtScrollBottom and isControlDrawerPresented out of
DemonstrationView's local @State and onto the shared viewmodel as
@published properties. Drops the @binding chain that threaded
isPresented through StreamingControlDrawerView and
StreamingControlPanelView; both views now read/write
viewModel.isControlDrawerPresented directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Mahyar (Mac) McDonald <252041286+mamcdonald_microsoft@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Jun Yan <junyan.cpp@gmail.com>