Skip to content

Import Loop components and apps from Microsoft Whiteboard (1.7.4) - #177

Merged
marcosqlbi merged 1 commit into
mainfrom
feature/ms-whiteboard-loop-and-apps
Sep 30, 2026
Merged

marcosqlbi merged 1 commit into
mainfrom
feature/ms-whiteboard-loop-and-apps

Conversation

@marcosqlbi

Copy link
Copy Markdown
Collaborator

Loop components (LoopObject, and HostedFluidObject or GroupFluidObject holding one) and apps made by Copilot (AppIframeHost) were reported as left out. No sample holds either, so the markup was read from the Microsoft Whiteboard web client's public code, as for #174 to #176.

The export keeps neither kind of content. Its export code (replaceLoopIFramesWithPlaceholders and replaceAppFrameIFramesWithPlaceholders) does this:

  • Loop component. The export replaces the content of each div.loopParentDiv with an a to the component's data-loop-url around the picture LoopExportThumbnail.svg, which it does not embed. The importer makes it a Markdown text container titled Loop with a link to that address, as wide as the component, or the words Loop component when there is no address. HostedFluidObject and GroupFluidObject are read the same way when they hold a Loop element and are reported otherwise.
  • App. AppIframeHost is an app that Copilot generated, running in a sandboxed iframe, not a video. The export replaces the frame with a #faf9f8 panel and keeps the div.appFrameContainer with its size and its header, whose title reads App in the board's language; the app's name, code, and state are not in the export. The importer makes it a rectangle of that size in the panel's color with the header's title as its text, so the space it took stays on the board.

Both are placed by the anchor's alignment: Anchor now records whether its center class is present.

A new Core smoke test builds a sized Loop component with its link, a centered one without an address or a size, an app frame, and a HostedFluidObject without a Loop element, which is still reported. All 19 samples still import unchanged. The solution builds clean and both harnesses pass.

1.7.4 is not released yet, so this joins its notes as a second entry and the version stays 1.7.4. The import doc and the site's export page describe both.

🤖 Generated with Claude Code

The export keeps neither. A Loop component leaves its element with the component's
address, and becomes Markdown titled Loop that links to it. An app made by Copilot leaves
its frame's box and header around a plain panel, and becomes a rectangle of that size in
the panel's color with the header's title. Anchors now know whether they are centered.

Read from the web client's Loop component, app frame component, and export code,
because no sample holds either. They join the 1.7.4 notes, which is not released yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@marcosqlbi
marcosqlbi merged commit f17a7a7 into main Sep 30, 2026
5 checks passed
@marcosqlbi
marcosqlbi deleted the feature/ms-whiteboard-loop-and-apps branch September 30, 2026 16:48
marcosqlbi added a commit that referenced this pull request Sep 30, 2026
#178)

Azure DevOps work items (`WorkItem`) and frames that Copilot draws
around the objects it groups (`Frame`) were reported as left out. No
sample holds either, so the markup was read from the Microsoft
Whiteboard web client's public code, as for #174 to #177.

**Work items.** `WorkItemConnected` draws a `div.WorkItem` card, 220 ×
145 pixels in the exported stylesheet, when the web client's
`EnableWorkItems` flag is on. A `span.WorkItemTextField` holds a
`strong` with the type's `img.WorkItemIcon` (its `alt` names the type)
and the ID, then the title; after it come the assignee and, in
`span.WorkItemText`, the localized word *State* and the state. The
importer makes it a Markdown text container titled *Work item*: the type
and ID in bold before the title, then the assignee and the state, as
wide as the card.

The title follows `</strong>`, and `HtmlTags` kept only the text that
follows a start tag. It now also yields the non-blank text that follows
an end tag as a tag named `#text`. No reader matches that name, and all
19 samples import with the same items before and after the change.

**Copilot frames.** The frame component draws a
`section.whiteboardFrame` with its size and a theme class (neutral,
blue, green, purple, orange) when `EnableFrames` is on. The stylesheet
gives it a 3-pixel border, a translucent fill, 14-pixel corners, and a
44-pixel title bar with bold 15-pixel text. The importer makes it a
rectangle with the theme's border and fill and its title as a bold label
in the theme's text color. It is square rather than rounded, because 14
pixels on a frame is close to square while the board's rounded rectangle
scales its corners with the shape and crowded the title. The sources are
left out: the export keeps only the first one's name in a pill, and the
list is a popover drawn only when open.

A work item or a frame drawn as a placeholder is still reported.

A new Core smoke test covers a work item card, a blue frame with a
source pill, and both drawn as placeholders; the page was also drawn
through the application's renderer. The solution builds clean and both
harnesses pass.

1.7.4 is not released yet, so its notes entry now covers work items and
frames, and the version stays 1.7.4. The import doc and the site's
export page describe them.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
marcosqlbi added a commit that referenced this pull request Sep 30, 2026
`GroupFluidObject` is how the Microsoft Whiteboard web client writes a
**group of objects**: it is the `toWhiteboardType` of its `Group`
content type. #177 took the name for live Fluid content and gave it the
Loop reader, so a group and everything in it was reported as left out.
No sample holds a group, because the Windows client does not offer
grouping; the markup was read from the web client's public code.

**How a group is drawn.** Its conversion makes a collection, as for a
legacy template, without a title: a `div` with the role `collection`,
and for each member a wrapper `div` holding a `div` named after the
member's own origin (`topLeft` or `center`) with its `left`, `top`, and
`transform`, holding the member's content. A member can be a group.

**What changed.**
- `ReadTemplate` became `ReadCollection`, used for templates and groups.
It reads only the collection's own children and recurses into a child
that is a collection. `HtmlTags` now yields the end of each `div` as a
tag named `/div` so that depth can be counted; no reader matches that
name, and all 19 samples import with the same items.
- A child keeps its own origin: a centered one is read as centered, and
a corner-placed picture, shape, or sticker moves by half its size,
because those are centered at the top level. `Anchor.Inside` now keeps
the child's alignment.
- The child dispatcher reads every kind as its top-level counterpart is
read: besides ink, notes, grids, lists, text, pictures, and shapes, now
tables, sticker captions, connectors, link cards, Loop content, apps,
work items, custom objects, placeholders, and nested collections. This
also closes the gap where a connector, a link card, or a sticker's
caption inside a legacy template was lost.
- The placeholder check now steps aside for any object that holds a
collection, so a group whose children are all centered is not taken for
a placeholder.

**Flattened.** The board has no groups (grouping as a saved object is
out of scope in `docs/design-objects.md`), so a group becomes its
members, each where it was and in its drawing order. The import doc has
a new section, *When the board has groups*, listing what to change once
grouping exists, and the design doc's out-of-scope line links to it.

A new Core smoke test covers a scaled group holding a note, a centered
picture, a nested group with a centered ellipse and ink, and a member of
an unknown kind. The template tests pass on the new reader. The solution
builds clean and both harnesses pass.

1.7.4 is not released yet, so this adds an entry to its notes and the
version stays 1.7.4. The site's export page lists groups.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant