chore: For v1.33.0 release - #786
Merged
surajshetty3416 merged 927 commits intoAug 28, 2026
Merged
Conversation
…-sync fix: sync the root lockfile with the workspace manifests
The chart has been blank since 9afded2 (frappe#728) resolved echarts to 6.1.0 over the ^5.6.0 frappe-ui asks for. frappe-ui always emits `color: config.colors`, and no caller here sets `colors`; echarts 5 ignored the resulting `color: undefined` and kept its own palette, echarts 6 lets the key win, so every series drew with no fill and no stroke while the axes, legend and tooltip carried on as usual. Pin the series colors, and fix what became visible with them: - style the axes through `xAxis.echartOptions` / `yAxis.echartOptions`. A top-level `echartOptions.yAxis` array replaces frappe-ui's own axis config rather than merging into it, which is why the left axis was blank and ticks read `4,000` instead of `4K`. - drop the y2 axis and its "Timeline" title. Both series count views, so they belong on one axis. - repeat the color in each series' emphasis state. echarts derives the hover color by parsing the series color, cannot parse a css var, and paints nothing, so hovering wiped the chart. - drop the chart's padding and the negative margin that compensated for it. zrender sizes the svg minus padding but positions it at the padding box, so padding offsets pointer hit-testing and swallowed the click-to-drill-down. Co-Authored-By: Claude <noreply@anthropic.com>
…t-colors fix(analytics): restore the site analytics chart under echarts 6
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
CodeMirrorEditor created an EditorView in onMounted but never destroyed it. CodeMirror does not release its view tree, DOM or document observer on its own, so every remount leaked the whole editor and left its DOMObserver polling the selection. Selecting a block that has innerHTML mounts this editor on the block's raw source in the HTML Options panel, so working with such a block leaked continuously. On a page whose block held a 205 KB inline SVG, 20 rounds of select, copy, delete and paste grew the tab by 56,420 DOM nodes and 12,633 event listeners, none of which a forced GC reclaimed. The same run with the view destroyed grows by zero. Co-Authored-By: Claude <noreply@anthropic.com>
Every history record is a full serialisation of the block tree, so a heavy page reached hundreds of MB long before it reached the 500 entry cap. On a 743 KB page each edit cost 1.55 MB and the stack was heading for roughly 775 MB before it would evict anything. Cap on total bytes as well, whichever limit is hit first, keeping a floor of 10 entries so undo stays usable on a page too big for the budget. The same trim runs on redo. Measured over 120 edits the stack now settles at 29 entries and 20.6 MB, and the cost per edit drops from 1.55 MB to 0.35 MB. Also copy the selection into each record. It stored the live set by reference, so every stacked entry tracked the current selection instead of the one it was taken with, and undo restored the wrong blocks. Co-Authored-By: Claude <noreply@anthropic.com>
An inline SVG lives in the page JSON, so it is re-serialised on every save, walked by every deep watcher and copied into every history entry. Figma exports are routinely hundreds of KB, and one page here carried 645 KB of inline SVG across five blocks, 87% of its total weight. Pasting an SVG over 20 KB now asks whether to upload it as a file and reference it, or keep it inline. Taking the offer moves it out of the page entirely and lets the browser cache it: a 68 KB paste leaves zero inline bytes behind and becomes an image block that keeps the SVG's own width and height. An SVG that paints from a Builder token is never offered, because an <img> cannot read CSS variables and the theming would break. Both paste routes are covered, whether the SVG lands in a new block or replaces the content of an HTML block that is already selected. Co-Authored-By: Claude <noreply@anthropic.com>
…xt menu Pasting now offers to upload a large SVG, but pages built before that still carry theirs inline. One page here holds 653 KB of inline SVG across 34 blocks, 87% of its weight, and there was no way to get it out. Adds "Upload SVG as File" to the block context menu, offered only on an SVG block big enough to be worth moving. The block keeps its id, position and styles and simply repoints at the uploaded file, so nothing downstream has to move. Converting the largest block on that page took the inline total from 653,863 to 449,170 bytes. The intrinsic size is read off the <svg> tag before it leaves the page and applied only where the block has no size of its own, and object-fit is set to contain: an inline <svg> letterboxes inside its box by default while an <img> stretches, so without it the artwork would skew on conversion. Co-Authored-By: Claude <noreply@anthropic.com>
The context menu already offered this, but the panel is where you are when you are looking at a block's inline SVG, and there was nothing there. A 205 KB SVG showed its source in the code editor with no hint that it could be moved out of the page. Adds a "Convert to Image File (200 KB)" button under the HTML editor, showing the size so the cost is visible, and renames the context menu entry to match so one action is not called two different things. Co-Authored-By: Claude <noreply@anthropic.com>
Measured it: converting the five big SVGs on a 743 KB page leaves per-edit time unchanged (~66 ms either way). Vue's deep-watch traverse does not descend into strings, so a large innerHTML is one property either way. The wins are autosave payload, history size and canvas DOM, not watcher cost. Co-Authored-By: Claude <noreply@anthropic.com>
getImageBlock supplies objectFit "cover" from the image template, and it was spread after the block's own styles, so it won. An SVG whose viewBox aspect differs from its width/height attributes was then cropped, where inline it would have letterboxed. Verified with a 400x120 box around a 559x553 viewBox: object-fit is now contain, matching convertSVGBlockToImage. Reported by Greptile on frappe#784. Co-Authored-By: Claude <noreply@anthropic.com>
onMounted awaits twice before constructing the view. If the component unmounts in that window, onBeforeUnmount has already run and finds no editor to destroy, and the continuation then builds one into a detached container where nothing will ever dispose it. Guarded with a disposed flag checked after the awaits. I could not reproduce an actual leak from this, including a deterministic mount/unmount race swept across 2-25 ms windows, most likely because defineAsyncComponent means the inner component never mounts at all when the parent unmounts first. Keeping it as a cheap guard against a real lifecycle hazard rather than a measured fix. Reported by Greptile on frappe#784. Co-Authored-By: Claude <noreply@anthropic.com>
resetEditor guards on `editor` up front, then awaits createStartingState and dereferences `editor` again for setState, focus and dom. Teardown can land in that window, and since unmount now nulls the view, the continuation would throw instead of quietly working on a stale one. Reachable through PageClientScriptManager, whose selectScript is the only caller passing resetHistory: true, which is the branch that awaits. Re-checks after the await and returns early. Document swapping on the non-awaiting path verified unchanged: switching between blocks still reuses the same view and swaps the document. Reported by Greptile on frappe#784. Co-Authored-By: Claude <noreply@anthropic.com>
Most of what I added restated the code or explained rationale that belongs in the commit history. Cut 24 comment lines to 8, keeping only the non-obvious constraints: why a token-painted SVG stays inline, why object-fit is forced, why the history record copies the selection, and the two async-teardown guards. Co-Authored-By: Claude <noreply@anthropic.com>
…tor-leak fix(editor): stop the editor leaking memory, and stop pages carrying SVGs inline
feat: published status across dashboard and editor
# Conflicts: # frontend/src/types/doctypes.ts
Contributor
|
Tick the box to add this pull request to the merge queue (same as
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #786 +/- ##
==========================================
+ Coverage 57.59% 66.06% +8.47%
==========================================
Files 35 93 +58
Lines 4271 10386 +6115
==========================================
+ Hits 2460 6862 +4402
- Misses 1811 3524 +1713 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
export_dir_name scrubbed the name and replaced slashes, but let "." and ".." through as a whole segment. Route it through safe_segment, which already guards the template fixture paths, and move that helper into utils so both exporters share one implementation. Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
|
🎉 This PR is included in version 1.33.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
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.
Bob, the AI assistant
Builder gets a chat assistant that builds and edits pages directly on the canvas (#671). Bob orients itself in the site on demand, reads existing pages as references, researches online when it needs to, and works with the component system, props and bindings. The canvas follows along as it builds, and cancelling mid-generation keeps whatever has landed so far.
Design Tokens
Builder Variable is now Builder Token, with Font and Dimension tokens alongside colours (#676). Font tokens pick their value from the font dropdown, which previews every family, and every token row, in its own typeface.
Translatable UI
The editor is translatable end to end (#706, #721): user-facing strings are wrapped, translations are served from boot data, and 35 language catalogs are synced from Crowdin.
Image controls
Cover images get a focus point control with zoom crop and a visible-part frame, inside a redesigned image popover that the background tab now shares (#768). Stored images are capped at 2048px on the long edge, and a pasted page brings its images and fonts into the site with it.
Editor
Fixes and maintenance
builder_filesstays in sync when pages and scripts are renamed or deleted (feat: Syncbuilder_fileswith page/script delete and rename operations #507).