Repository navigation
Layout editor: four rounds of bug fixes - import, generator, canvas, runtime parity - #6
Merged
Merged
Conversation
Bugs - Open: a saved .design.json was read as an ABAP class (its indented lines start with a quote, an ABAP comment); JSON is checked first - Import view / Open class: a text that does not parse closed the dialog and lost what was pasted; the dialog now closes only once it is read - Create attributes after an import: a binding path of more than 30 characters looped for ever (no number made the name valid) - An imported class renamed in the editor kept its old CLASS name, so file and class differed; the CLASS statements follow the rename - An imported 7.02 class with its own builder variable got `view =` written over it, undeclared; the chain keeps the author's head - Command palette: Copy ABAP generated the class anew and dropped the author's code of an imported class; Open design took no .abap - Share link: a large design overflowed the stack (one spread of all bytes); chunked as the playground link is - An edit that throws half way (a building block dropped where it does not fit) left the design half changed; commit restores and says why - Focusing an event field (Tab) named the event and added a WHEN branch; the suggestion is taken by a click or Enter - A field switched between table and scalar kept the old row values, which reached the class and the canvas - An attribute named view_display, on_event, model_init or main clashed with the method of that name; now refused - A design file with an attribute without fields crashed the checks; normalizeDesign gives every attribute its shape - Opening a new design kept the merge key of the last typing, so the next keystrokes merged into the replacement's undo step Improvements - An attribute named in a UI5 expression counts as used and is renamed with it; switching a binding to ƒx keeps its path - Event names show upper case while typing; Enter adds a property and inserts a control by class name; Enter on the class URL opens it - Escape closes the File / Export menus; menus update aria-expanded - A link pasted into an open editor (#d=) opens its design - The outline shows #field bindings and the bound dot for them - A list added from Children gets the offer of its rows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NJdCHJULfqVBdruCtKNUm2
Class import and export (src/clas.js) - A rename together with a new attribute wrote the declaration into the middle of a line (the rename shifted the offsets the insertion uses); the rename now comes last - A view built on after an IF (page->tag( ) past another statement) was half imported, and the export left a call to an undeclared variable; such a class is now refused with the reason - A new WHEN branch could land in a CASE nested in a branch; CASE depth is tracked - WHEN `A` OR `B` counted only A as handled, B got a second branch - A 7.02 class with a builder variable other than `view` was taken for 7.40 and patched with string templates - DATA ... VALUE `Walldorf, DE` lost its value (split at the comma in the literal); VALUE 5 READ-ONLY lost it too - A seed row with cl_abap_char_utilities=>newline cut the operand at => Generator and view (src/abap.js, src/xml.js) - A text of backticks was cut by its raw length; doubled, a piece passed 255 characters per line (abapGit refuses that). Cut by the written width, and by code point, so an emoji is never torn in two - A line break or tab in a value was written as it is; XML turns it into a space, so the canvas showed one line where the app shows two. Now 
 / 
 / 	, as z2ui5_cl_ui5_util_context=>c_escape_xml( ) - The xmlns order followed the order aggregations were filled, so the same view could give different classes; now the order of the view - A pasted view with two root elements dropped the second silently Canvas (src/preview/init.js) - After a render that failed, the next new view could get the id of the view still on screen and fail too; ids are now busy until destroyed, and a view that fails to place is destroyed - The preview took render messages from any window; only the editor that frames it now (a view's XML can carry script) Also - parseClassName took sap.m. and sap..Button - tools/serve.mjs served sibling folders whose name starts like the root - Ctrl+S saves the design; the class name shows upper case as typed; a click beside the command palette closes it; the offer of rows for a control deleted meanwhile creates nothing; a class URL says it loads Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NJdCHJULfqVBdruCtKNUm2
- The rows of a grid table (sap.ui.table.Table) took any control - a drop on the table could land there, and UI5 refuses: the table manages its rows from the binding. The aggregation now takes nothing - After a view that failed to render (a SimpleForm keeps its labels registered then), a later view could get the same id and fail with "duplicate id"; every view gets an id of its own now - A new Wizard had two steps, UI5 wants three to eight - A static value UI5 cannot take for its property type went unchecked: text in an int (columnsM = abc) failed the whole view with a GridSpan error, 1.5 as a width was dropped by UI5. Checks says it - an error for a number or an enum, which fail the view, a warning for a size or a flag, which UI5 logs - and the property field turns red as it is typed. The CSS size is UI5 1.71's own pattern Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NJdCHJULfqVBdruCtKNUm2
Random designs - every attribute type, tables with table fields, odd
values, 7.40 and 7.02 - generated, transpiled against abap2UI5 and
started: the view and the model the app sends compared with the canvas,
and the class imported again. What did not match:
- Midnight (00:00:00) is ABAP's initial time: the class cannot tell it
from no time, abap2UI5 sends ''. The canvas showed 00:00:00; it shows
what the app gets now, and Checks says why
- A decimal the number field takes - .5, 1e3, " 2.5 " - was dropped by
the class (0 in the app) and shown on the canvas; written now
- -0 showed as -0 on the canvas, abap2UI5 sends 0
- An initial date or time in a seed row ('00000000', written to keep
the columns) came back from an import as 0000-00-00 / 00:00:00
- A table whose fields are all tables bound a list's text to a table
field - an error right after one click; the template gets static
text instead
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NJdCHJULfqVBdruCtKNUm2
…nor onto the canvas A text with a control character (pasted, imported) was written raw into the ABAP source - invisible there, and the importer's mask read it as a literal of its own - and shown on the canvas, while abap2UI5 drops it on the way to the browser. Both drop it now. Found by running 31 odd texts (quotes, braces, escapes, line breaks, entities, emoji, 300 characters) through the real abap2UI5 runtime in both releases: every other one builds exactly the view and the model the canvas shows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NJdCHJULfqVBdruCtKNUm2
Binding a table (sap.m.Table or the grid table) to a table attribute, or creating one with + Table, replaces its columns with a template built from the fields - and the check that asks first looked at the row template only: hand-made columns went without a word, and a grid table, whose template lives in its columns alone, never asked. The check now covers every aggregation the binding replaces, and knows what the current binding generated by generating it again; + Table asks too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NJdCHJULfqVBdruCtKNUm2
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.
Four rounds of bug hunting in the layout editor. The bugs were found by:
Every fix has a test that fails without it.
Opening, importing, exporting
.design.jsonwas read as an ABAP class: its indented lines start with", which is an ABAP comment.CLASSname;viewwas taken for 7.40;view =.IFwas half imported, and the export called a variable it no longer declared. Such a class is now refused with the reason.WHENcould land in a nestedCASE, andWHEN \A` OR `B`` counted only A.VALUE \Walldorf, DE`,VALUE 5 READ-ONLYand=>` in seed rows lost their values.0000-00-00/00:00:00.Generator and canvas
escapeXmlnow escapes asc_escape_xmldoes.xmlnsorder depended on the order the view was built in, so the same view could give different classes..5and1e3;-0;Editing
rows, which UI5 refuses.on_event,view_display,model_initandmainclashed with the class's methods.parseClassNameacceptedsap.m.;tools/serve.mjsserved sibling folders.Small improvements
#d=link opens in an editor that is already open.#fieldbindings.Checks
npm test: 377 tests.npm run check:abap: 23 files, 0 failing.npm run check:abap702: 0 issues.npm run verify:abap: 23/23 classes.npm run test:e2e:local: 55/55 tests on UI5 1.144 and 1.71.🤖 Generated with Claude Code
https://claude.ai/code/session_01NJdCHJULfqVBdruCtKNUm2
Generated by Claude Code