@coolms/image-editor-angular 2.0.0-alpha.2 → 2.0.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ATTRIBUTION.md ADDED
@@ -0,0 +1,43 @@
1
+ # Attribution
2
+
3
+ `@coolms/image-editor-angular` builds on one open-source canvas
4
+ library. This file acknowledges it and records the license under
5
+ which it is used. The entry is MIT-compatible with CoolMS's own
6
+ MIT license.
7
+
8
+ ## fabric.js
9
+
10
+ - **Project**: `fabric`
11
+ - **Version**: `^6.9.1` (peer dependency)
12
+ - **Copyright**: Printio (Juriy Zaytsev, Maxim Chernyak) and the
13
+ fabric.js contributors
14
+ - **License**: MIT
15
+ - **Repository**: https://github.com/fabricjs/fabric.js
16
+ - **Role**: Provides the canvas rendering surface (`Canvas`), the
17
+ image object (`FabricImage`), interactive corner / rotation
18
+ controls, and the filter pipeline (WebGL primary, Canvas2D
19
+ fallback) wrapped by `FabricEngineAdapter`. Imported via
20
+ `from 'fabric/es'` for tree-shaking.
21
+ - **Notes**: zero runtime dependencies, ESM-first, Promise-based
22
+ image loading, ships its own TypeScript types.
23
+
24
+ ## Why this file exists
25
+
26
+ Even though every dependency is MIT and CoolMS itself ships under
27
+ MIT, the project policy is to track each transitive vendor surfaced
28
+ through public-facing packages. When `@coolms/image-editor` is
29
+ consumed by downstream CoolMS deployments, this file documents the
30
+ upstream chain without forcing operators to crawl `node_modules` to
31
+ assemble it.
32
+
33
+ ## History
34
+
35
+ Prior to (May 3-4, 2026) this package wrapped Toast UI
36
+ Image Editor in headless mode. Toast UI in turn embedded fabric.js
37
+ v4. replaced the Toast UI layer with a direct
38
+ `FabricEngineAdapter` against fabric.js v6, and removed the
39
+ `tui-image-editor`, `tui-color-picker`, and `tui-code-snippet`
40
+ dependencies. See `docs/adr/079-toast-ui-rejection.md` for the
41
+ rationale and `docs/adr/081-image-editor-engine-swap.md` for the
42
+ journey. Toast UI Image Editor was MIT-licensed (NHN Cloud Corp,
43
+ https://github.com/nhn/tui.image-editor).
package/CHANGELOG.md ADDED
@@ -0,0 +1,120 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@coolms/image-editor-angular` are recorded here.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
+
7
+ This file starts at the version named below, which is what the registry
8
+ currently serves. Earlier alphas are deliberately not reconstructed: entries are written
9
+ in the same commit as the work they describe, and inventing the ones that
10
+ predate this file would be a worse record than not having them.
11
+
12
+ ## 2.0.0-alpha.4 -- 2026-10-22
13
+
14
+ ### Added
15
+
16
+ - **A tool rail on the left and a properties panel on the right.** The rail
17
+ draws the tools in their groups (Transform, Insert, Filters, Layers), with
18
+ their names or as icons whose names and shortcuts are tooltips; the
19
+ person switches at its foot, and the host remembers the choice through
20
+ `IMAGE_EDITOR_RAIL_MODE` (for this page load when it provides none). The
21
+ active tool is always scrolled into view. The panel shows the active
22
+ tool's properties under its name, or, with no tool, the image's own: its
23
+ size, its format and how many layers it has.
24
+ - **Each tool has a shortcut**: C crop, R rotate, F flip, I resize, M mask,
25
+ U shapes, T text, L layers. A tool's key selects it and, when it is the
26
+ active one, closes it; only while the editor has the keyboard, never from a
27
+ field, and never with Ctrl, Alt or Meta.
28
+ - **The editor's text goes through keys.** `IMAGE_EDITOR_TRANSLATOR` answers
29
+ them; without a host translator the base catalogue's English does
30
+ (`IMAGE_EDITOR_MESSAGES`), and `catalogueTranslator()` puts a host's
31
+ catalogue in front of it, never showing a key or an empty label for a
32
+ message it lacks or holds blank.
33
+ - **`src/core/` holds the tools and the text as data, with no framework**, so
34
+ a React host uses them as they are; a lint rule refuses any import there
35
+ from outside it, and any package at all.
36
+ - Delete acts on the editor's own selection: it removes the selected shape or
37
+ text layer, and does nothing when nothing, or the base image, is selected.
38
+ It is bound to the editor's own layer through the keyboard scope, so it never
39
+ reaches a page beneath the editor. Needs `@coolms/ui-angular` 2.0.0-alpha.4.
40
+ - A save names the version it opened (`If-Match`): when the image changed
41
+ meanwhile (412) or was deleted (404), the editor says so and offers Save as,
42
+ never writing over the newer file or making the deleted one again; a change
43
+ made elsewhere is said at once, through the host's `VFS_NODE_WATCH`. Needs
44
+ `@coolms/ui-angular` with `VFS_NODE_WATCH`.
45
+ - Declares `bugs` so a page imported from this package, and the catalogue,
46
+ know where a correction is filed. The registry filled the gap from GitHub when
47
+ the manifest was silent; the declared field is the one that holds on any
48
+ registry.
49
+
50
+ ### Changed
51
+
52
+ - **Breaking: `engines.node` names exactly the Node lines CI runs.** It moves from
53
+ `^22.22.3 || ^24.15.0 || >=26` to `^22.22.3 || ^24.15.0 || ^26.0.0`: Node 27
54
+ and later are not declared until CI runs them. Within each line the floor is
55
+ the highest one any package in the lockfile declares. CI checks both, from
56
+ the matrix and the lockfile. The published code does not change.
57
+
58
+ - The right sidebar is gone: tools are picked on the rail and their properties
59
+ shown in the panel. A tool registers a name key, a group, an order and a
60
+ shortcut instead of a label and a category.
61
+ - The version an overwrite names is the version of the pixels the editor
62
+ opened: the host reads the file's bytes and takes their version from the
63
+ same response (its `ETag`). The listing's version, a separate and earlier
64
+ read, is no longer part of the VFS host data (`node.version` is removed). A
65
+ file changed between the listing and the open is edited as it is now, and
66
+ bytes served from a cache name their own older version, so saving them over
67
+ the newer file is refused. A read that names no version leaves Save off;
68
+ Save as still works.
69
+ - The same for a media asset: given `asset.sourceUrl`, the host reads the
70
+ asset's bytes and their version from one response, and the replace names
71
+ that version (`If-Match`, which the replace now requires). An asset replaced
72
+ meanwhile (412) or deleted (404) is not overwritten: the editor says so and
73
+ offers Save as. Without `sourceUrl` the image is shown from `originalUrl`,
74
+ which names no version, and Save is off.
75
+
76
+ ## 2.0.0-alpha.3 -- 2026-09-03
77
+
78
+ **A pre-release, carrying no compatibility promise.** Published under the
79
+ `alpha` dist-tag.
80
+
81
+ The image editor: a fabric.js v6 engine behind a framework-agnostic adapter,
82
+ with transform tools (crop, rotate, flip, resize), seven filters, insert tools
83
+ (shapes, text, mask), a layers panel over the object stack, and a save flow
84
+ wired to the Media Library and the VFS.
85
+
86
+ The adapter is the reason the engine could be replaced without touching the UI
87
+ shell or any tool component, and it is why the editor loads as its own lazy
88
+ chunk.
89
+
90
+ ### Fixed
91
+
92
+ - **Save overwrites only a PNG or a JPEG.** Save wrote JPEG bytes over every
93
+ source that was not a PNG: an SVG's vectors became pixels, a GIF lost its
94
+ animation, and the file's name and type no longer said what it held. Save
95
+ now overwrites only a PNG or a JPEG, which the editor writes back in the
96
+ same format; every other format -- GIF, SVG, TIFF, HEIC, BMP, and WebP until
97
+ its export is verified in every supported browser -- has Save as only, and
98
+ the Save button says why. A JPEG whose edit gained transparent areas is not
99
+ written over as PNG under its name: Save says so and opens Save as.
100
+ `writtenBackAs(mimeType)` names the format Save writes a source back as.
101
+ - **A photo is saved upright.** Its EXIF orientation is applied when the
102
+ editor opens it, so the saved pixels are turned upright themselves. The
103
+ export carries no EXIF of its own; a JPEG export embeds an sRGB colour
104
+ profile, a PNG export none. The canvas the editor draws on is sRGB: a
105
+ Display P3 photo saved as JPEG loses its own profile, and its colours
106
+ beyond sRGB are clipped (measured, not yet changed). On a JPEG overwrite, a CoolMS backend that
107
+ carries the replaced photo's EXIF into the new file keeps the camera, the
108
+ dates and the location, sets the orientation to normal and removes the stale
109
+ embedded thumbnail. The location is kept: removing it is an action of its
110
+ own, never a side effect of a save.
111
+ - The Shapes tool had no icon. Its class named an icon Bootstrap Icons does not
112
+ define, which renders nothing and reports nothing -- measured, it behaved
113
+ identically to a class invented at random.
114
+ - The roadmap listed Shapes as planned when it ships, and the feature list
115
+ omitted the insert tools entirely.
116
+ - The licence section pointed at `ATTRIBUTION.md`, which the package did not
117
+ copy into the tarball. The file now ships.
118
+ - The package described itself as being for "CoolMS DXP", which is not what the
119
+ platform is called, and claimed the package was framework-agnostic when it is
120
+ the engine adapter behind it that is.
package/README.md CHANGED
@@ -1,12 +1,16 @@
1
1
  # @coolms/image-editor-angular
2
2
 
3
- Modern image editor for CoolMS DXP. Built on fabric.js v6 via a
3
+ Modern image editor for CoolMS. Built on fabric.js v6 via a
4
4
  custom `FabricEngineAdapter`, wrapped by a CoolMS-native UI shell.
5
5
 
6
+ ## Tests
7
+
8
+ This package has no test runner of its own, so CI finds no tests in it: only typecheck, lint and build guard it here, and a check of "the same number of tests before and after" proves nothing for it. Its 10 spec files run in the admin suite of [coolms/theme-admin](https://github.com/coolms/theme-admin), which compiles this package from source. A change here is tested there, not by this repository's CI.
9
+
6
10
  ## Status
7
11
 
8
12
  **Feature-complete on the fabric.js v6 engine.** The shell
9
- (top toolbar, canvas mount, right sidebar, properties panel) drives
13
+ (top toolbar, tool rail, canvas mount, properties panel) drives
10
14
  all editing operations through the engine API. The save flow is
11
15
  integrated end-to-end with the Media Library and the VFS file
12
16
  manager: open an image asset (or any VFS image file), edit, Save
@@ -54,6 +58,16 @@ Slider filters live-preview during drag with a coalesced
54
58
  preview session. `clearRedoStack()` on commit prevents stale preview
55
59
  entries from leaking into the redo stack.
56
60
 
61
+ **Insert** (3 tools):
62
+ - **Shapes** — rectangle, ellipse, triangle, line and arrow, each
63
+ added as its own fabric object with solid, linear-gradient or
64
+ radial-gradient fill, stroke width and colour
65
+ - **Text** — editable text layers with font, size, weight and colour
66
+ - **Mask** — shape masks applied to the image
67
+
68
+ **Layers** — the object stack for everything Insert adds: select,
69
+ reorder, and remove without disturbing the underlying image.
70
+
57
71
  ### Top toolbar
58
72
 
59
73
  - **Undo** / **Redo** — bound to engine history events. The custom
@@ -125,11 +139,18 @@ Three layers, separated for swappability:
125
139
  (interface) (this package) (npm peer dep)
126
140
  ```
127
141
 
128
- 1. **UI shell** — `<coolms-image-editor>` host component with three
129
- panes (top toolbar, canvas mount, right sidebar). Tools register
130
- themselves into a `ToolRegistryService`; the right sidebar uses
131
- `NgComponentOutlet` with `inputs` to render the active tool's
132
- properties panel.
142
+ 1. **UI shell** — `<coolms-image-editor>` host component: a top
143
+ toolbar, then the tool rail on the left, the canvas mount, and the
144
+ properties panel on the right. Tools register themselves into a
145
+ `ToolRegistryService` with a definition from `src/core/` (name key,
146
+ icon, group, order, shortcut) and the component that shows their
147
+ properties; the panel uses `NgComponentOutlet` with `inputs` to
148
+ render the active tool's, or the image's own when no tool is
149
+ active. The rail draws the tools with their names or as icons;
150
+ the host remembers which (`IMAGE_EDITOR_RAIL_MODE`). The editor's
151
+ text goes through `IMAGE_EDITOR_TRANSLATOR`, which falls back to
152
+ the base catalogue (`IMAGE_EDITOR_MESSAGES`). `src/core/` imports
153
+ no framework, so a React host uses the same tools and text.
133
154
  2. **Engine adapter** — `FabricEngineAdapter` implements
134
155
  `ImageEditorEngine`. Owns canvas dimensions (no vendor CSS
135
156
  auto-fit layer), normalises the public API (lowercase filter
@@ -311,7 +332,7 @@ Two intentionally hard-coded values exist:
311
332
 
312
333
  ## Performance
313
334
 
314
- Measured on Chrome for Windows (, NVIDIA GTX
335
+ Measured on Chrome for Windows (NVIDIA GTX
315
336
  1650 via ANGLE D3D11, `WebGLFilterBackend` confirmed,
316
337
  `MAX_TEXTURE_SIZE=16384`):
317
338
 
@@ -356,7 +377,8 @@ fraction of that — most is Angular CD + paint.
356
377
 
357
378
  ### Done
358
379
 
359
- - Headless mount, engine adapter, UI shell, 11 tools, theming, save flow
380
+ - Headless mount, engine adapter, UI shell, the transform and filter tools,
381
+ theming, save flow
360
382
  - `FabricEngineAdapter` rewrite (~640 LOC) and the state-service switch
361
383
  - Canvas-space crop (bake-and-replace), Sharpen `textureSize` fix, blob-URL undo
362
384
  - Bidirectional sync (`imageTransformed` event), live-bound rotate slider,
@@ -364,10 +386,12 @@ fraction of that — most is Angular CD + paint.
364
386
  - Canvas frame overlay
365
387
  - Toast UI dependency removed (640 LOC adapter deleted)
366
388
  - Bundle, memory and functional verification
389
+ - Insert tools — Shapes, Text and Mask — with a Layers panel over the
390
+ object stack
367
391
 
368
392
  ### Planned
369
393
 
370
- - Shapes (Free Draw, Rectangle, Circle, Text, Icons, Mask)
394
+ - Free-draw brush and an icon library for the Shapes tool
371
395
  - Color picker / eyedropper
372
396
  - WebP / AVIF export options
373
397
  - Rich-text inline widget integration
@@ -385,7 +409,7 @@ fraction of that — most is Angular CD + paint.
385
409
  consumer-defined tools
386
410
  - **Video editor companion** sharing the engine-adapter pattern
387
411
 
388
- ## License
412
+ ## Licence
389
413
 
390
- MIT (CoolMS DXP). The runtime peer dependency `fabric` is also MIT.
414
+ MIT. The runtime peer dependency `fabric` is also MIT.
391
415
  See `ATTRIBUTION.md` for the full vendor acknowledgement chain.