Conversation
parseSections now walks all direct children of a section (not just div[class] blocks), grouping contiguous runs of loose content (p, h1-h6, ul/ol, picture) into read-only "Default content" entries so a section with only body text no longer shows as empty. Adds editorProseSelectChange, a generalized position-based select/scroll channel (separate from the block-index-based editorSelectChange), and wires it into ew-editor-doc.js to scroll to an arbitrary prose position when a default-content entry is clicked. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Hello, I'm the AEM Code Sync Bot and I will run some actions to deploy your branch.
|
|
Thanks a lot for the PR! I'm not sure grouping adjacent default content into a single Default Content group makes sense. If we want to allow users to edit the page 100% from the layout view, we'd need to allow them to also move, add and delete default content, which means we'd have to show each paragraph/image etc separately. Maybe we could make the current Default Content groups that this PR adds expandable to show all the actual content, so it doesn't become a giant list? |
|
I like the idea of a root section that can be expanded or collapsed. That lends itself if we eventually want to do something similar for items in collection blocks. will make that change and let you know. |
…t children Default content in the outline is now a collapsed-by-default group listing each consecutive loose item's kind, instead of one opaque entry. Clicking an image child also selects it as a NodeSelection and broadcasts it to the layout-view iframe, matching block selection; text kinds stay doc-view only pending a cross-repo follow-up. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…utline Changing a heading's level (or list ordered/unordered) only nudged the WYSIWYG mini-editor via getEditor(), never emitting editorHtmlChange — so the outline (and other listeners) never re-parsed. createTrackingPlugin now forces a full rerenderPage() whenever a change is 'attrs' or 'replaced', reserving the lightweight sync path for plain text edits. Also recognizes <pre> code blocks in the outline's default-content group (stamped with data-prose-index like other loose nodes), and renames "Bulleted list" to "Bullet list" to match the slash-command menu wording. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- getDefaultContentProseIndex: for kind 'image', prefer the nested data-image-index over a wrapping <p>'s own data-prose-index so the image node resolves correctly in the doc - getDefaultContentKind: classify <blockquote> as 'quote' and make the fallback content-aware so text-bearing tags aren't mislabeled 'image'; drop the now-redundant <p> branch - prose-diff: narrow the full-rerender trigger to attrs/replaced changes on EDITABLE_TYPES nodes; image/table attr edits take the lightweight getEditor sync path - ew-page-outline: drop redundant blocks comparison from sectionsEqual - rename loose* helpers to defaultContent* to match the AEM term - trim verbose comments to why-only, matching file conventions - add coverage: _scrollDocToProseIndex, blockquote classification, image proseIndex, and image-attr rerender path Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…roups ArrowRight expands a collapsed "Default content" group header, ArrowLeft collapses an expanded one, by re-firing the header's existing click handler so no extra proseIndex plumbing is needed. Falls through to the existing treeKeydown nav otherwise. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
@hannessolo This probably warrants additional sets of eyes and testing before merging. Here is what this looks like There are several known gaps here still:
|
|
Nice!
|
Lets default-content children (paragraph/heading/list/image/code/quote) be dragged anywhere in the doc — within a group, across groups in a section, or into a different section entirely (including one with no default content yet) — and deleted individually, matching the existing block/section drag+delete UI. Cross-type moves land as siblings only (never merged into a block). blocks.js gains getContentItemRange/deleteContentItem/moveContentItem and getSectionEndOffset; moveBlock's delete+insert math is extracted into a shared spliceNode helper (no behavior change, now covered by regression tests since it previously had none). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…s/content interoperate as drop targets getContentItemRange assumed proseIndex already pointed at a content item's own node start. In reality getInstrumentedHTML stamps it at the node's content-start (view.posAtDOM(el, 0)), which only coincided with the node start for the image case already special-cased. Every other kind was broken: moving/deleting a paragraph, heading, or code block would only touch its inner text (orphaning an empty wrapper), a quote would drop two levels too deep, and a multi-item list would only ever move/delete its first item. Fixed generally via doc.resolve(proseIndex).before(1), which recovers the true top-level node regardless of kind or nesting depth. Also closes a gap where blocks and content items couldn't target each other when dragging: content rows/groups only accepted content-type drags, and a block dragged into a section with no blocks (including a wholly empty one) had nowhere to land. Adds moveBlockToContentItem and moveBlockToSection so blocks and content items are drop targets for each other in both directions. Supersedes PR #1166 (dropempt), which fixed only the empty-section case in isolation. Rewrote blocks.js/ew-page-outline test coverage to build child descriptors via a real EditorView + getInstrumentedHTML + parseSections (makeRealView in test-helpers.js) instead of hand-picked node positions, since that gap is exactly what let the original bug through untested. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Several comments from the previous commit restated the same point across multiple lines instead of saying it once, directly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
.content-item's pointer cursor (for the group-toggle header) was overriding .block-item's grab cursor on draggable content-child rows, since it comes later in the cascade. Scope it to the header only. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Blocks and content-group headers now start at the same left edge (blocks previously lacked the chevron's reserved indent). Content-child rows also show a truncated text snippet under the type label so similarly-typed nodes (Paragraph, Heading, etc.) are distinguishable. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Selecting a default-content item (paragraph/heading/list/code/quote) from the outline now scrolls and highlights it in both the content and layout views, matching existing block/image behavior. Also fixes the reverse direction: editing or selecting content directly in the content view (or via layout, once synced) now highlights the matching row in the outline, which previously only tracked block selections. Adds blockquote to EDITABLES so quote items get their own data-prose-index instead of falling back to a nested paragraph's. Co-Authored-By: Claude <noreply@anthropic.com>
.content-label and .content-snippet had their own explicit gray color, which overrode the blue text .block-item.selected already applies — blocks don't hit this since .block-name has no such override. Co-Authored-By: Claude <noreply@anthropic.com>
Previously showed the full concatenated text of a content child, which overflowed for long paragraphs/lists. Now derives a per-kind first-line snippet (first list item, first quote paragraph, text before any <br>) and relies on existing CSS text-overflow: ellipsis for visual truncation. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ty, move/delete selection Replaces the fragile proseIndex-persistence model for default-content expand/collapse with one that resets on every selection change: block selection collapses all runs, content selection expands only its own run, and manual expand/collapse persists only until the next selection change. This shrinks proseIndex drift exposure to within a single selection instead of indefinitely across arbitrary doc edits. Also: - Empty default-content nodes (e.g. an empty heading/paragraph) now stay in the parsed tree flagged `empty`, hidden in the outline unless currently selected — so a node being actively edited is visible/selectable. Required keeping empty <p> tags alive through prose2aem's canvas-only instrumented-HTML path (keepEmptyParagraphs), and fixing getDefaultContentKind's "no text = image" heuristic, which broke once genuinely empty (imageless) paragraphs could reach it. - Drag/drop reorder now selects the moved item (via tr.setSelection inside the same transaction); deleting a content item selects the next/previous sibling in the same run; block/section delete leave selection untouched. - Fixed a pre-existing bug where handleCursorMove's redundant blockIndex-only editorSelectChange emit clobbered the correct proseIndex-carrying 'doc' emit immediately after it, breaking outline sync on the first WYSIWYG cursor move. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Cut redundant/verbose comments added in this PR: dropped one that restated what the name/body already conveyed, deduped a proseIndex convention explained twice across files, and tightened several multi-line comments down to their essential point. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reverts the keepEmptyParagraphs flag added to the shared prose2aem module (used by save/publish/live-preview/diff) and moves empty-node handling entirely into canvas's getInstrumentedHTML. Emptiness is now determined from the actual ProseMirror node (content.size === 0) rather than a flag threaded through shared code, and empty <p>s are masked with a placeholder comment before serialization, then stripped back out — so the outline can still see/select an empty node being edited, while SET_BODY to the layout view and all other prose2aem callers are unaffected. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reverts the keepEmptyParagraphs plumbing and outline visibility logic that kept empty paragraphs/headings alive through instrumented HTML so they could be seen and selected in the outline. Too much complexity for the value; empty nodes are skipped again when building content runs, same as before PR #1167 introduced the feature. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… selection/delete Replaces the per-selection collapse/expand-only-one-run model with a simpler one: expansion only resets on a real reparse (a structural edit that changes _sections); selection changes only additively expand the run holding the new selection, never collapse anything else. A range-based fallback in _findRunKeyForProseIndex also expands a run when the selection lands on a node that has no row of its own (e.g. a fresh empty paragraph from pressing Enter, filtered out of parseSections), not just an exact child match. Also drops the now-vestigial sibling-select-on-delete workaround in deleteContentItem (it stopped being what kept a run visible once expansion became reparse-driven) and replaces it with a direct fix: _onDelete captures the deleted content item's run by array position and re-expands it after the delete's reparse, so deleting a child no longer collapses its own run. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ead prose2aem arg getDefaultContentKind now explicitly checks for a nested/matching <img> before falling back to 'paragraph', instead of assuming a text-less element is always an image. Also reverts the getInstrumentedHTML->prose2aem call's trailing arg back to what main already has (unused since before this PR, prose2aem never read a 4th param) so that line doesn't show up as an unnecessary diff. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
@sharanyavinod addressed both your items, agree it looks way better with those. Here is how it looks now
As I was testing this more, found myself increasingly annoyed that selection wasn't consistent and expansion was super fragile to other edits because it shifts the prose mirror index of items. Where this stands now is that if we merge adobe/da-nx#627 with this:
more feedback is welcome, but I think this is ready to go. |
_scrollDocToProseIndex's dispatch synchronously triggers the tracking plugin's onSelectionChange, which broadcasts a null node payload (only image/table are recognized by selectedNodePayload) an instant before the correct content payload overwrites it, briefly flashing the layout-view highlight to nothing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>






requires adobe/da-nx#627 to land as well for the selection/scroll into view to work
Summary
parseSectionsineditor-utils.js).editor-utils/blocks.js).editorSelectChange/editorProseSelectChangepub/sub — so the doc editor, WYSIWYG view, and outline all stay in sync.Why
Default content (loose paragraphs/headings/etc. not wrapped in a block) previously had no representation in the outline, making it hard to see, reorder, or delete relative to blocks. This closes that gap while keeping the outline's selection and expansion behavior predictable across edits.
fix #1159
https://outldflt--da-live--adobe.aem.live/
Test plan
npm run lintpasses (JS + CSS)npm testpasses (1779 tests, 0 failures, 4 skipped)🤖 Generated with Claude Code