@solidev/data 1.1.0 → 1.1.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidev/data",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "license": "AGPL-3.0-only",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^22",
@@ -1,7 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { OnInit } from '@angular/core';
3
- import { FormControl } from '@angular/forms';
4
- import { DataModel, BaseFieldManager } from '@solidev/data';
2
+ import { DataModel, FieldEditorBase } from '@solidev/data';
5
3
  import { StateCommand, EditorState, Compartment, Extension } from '@codemirror/state';
6
4
  import { HighlightStyle } from '@codemirror/language';
7
5
 
@@ -97,53 +95,11 @@ type MdToolbarEntry = ({
97
95
  kind: 'heading';
98
96
  label: string;
99
97
  };
100
- declare class MdeditComponent<FT, T extends DataModel> implements OnInit {
101
- /** Id tying the label to the editor. */
102
- readonly inputId: string;
103
- /** Id of the label element, wired to the editor through `aria-labelledby`. */
104
- readonly labelId: string;
105
- /** Model instance holding the field. */
106
- model: _angular_core.InputSignal<T | undefined>;
107
- /** Name of the markdown field to edit. */
108
- field: _angular_core.InputSignal<string | undefined>;
109
- /** Whether {@link toggleEdit} is allowed to enable editing. */
110
- editable: _angular_core.InputSignal<boolean>;
111
- /** Whether the editor is currently enabled. Defaults to true. */
112
- edit: _angular_core.ModelSignal<boolean>;
113
- /**
114
- * Layout, and whether {@link save} persists.
115
- *
116
- * `dd` renders a `<dt>`/`<dd>` block and is the only mode that saves to the
117
- * API; `inline` and `form` render a label plus the editor and leave saving to
118
- * the caller.
119
- */
120
- mode: _angular_core.InputSignal<"dd" | "inline" | "form">;
121
- /** Hide label (for inline forms). */
122
- hideLabel: _angular_core.InputSignal<boolean>;
123
- /**
124
- * Hide the built-in save button, for callers driving persistence themselves
125
- * from the {@link changed} output.
126
- */
127
- hideButton: _angular_core.InputSignal<boolean>;
128
- /**
129
- * Form control backing the editor.
130
- *
131
- * When supplied, the component uses it as-is and skips its own setup — no
132
- * field manager lookup, no seeding from the model, and no {@link changed}
133
- * emissions. When absent, one is created and wired up from `[model]` and
134
- * `[field]`.
135
- */
136
- fc: _angular_core.InputSignal<FormControl<string | null> | undefined>;
98
+ declare class MdeditComponent<FT, T extends DataModel> extends FieldEditorBase<FT, T> {
137
99
  /** Toolbar preset name from {@link MdEditToolbars}, or an explicit toolbar. */
138
- toolbar: _angular_core.InputSignal<"none" | MdToolbar | "default" | "light">;
100
+ toolbar: _angular_core.InputSignal<MdToolbar | "none" | "default" | "light">;
139
101
  /** Text shown while the document is empty. */
140
102
  placeholder: _angular_core.InputSignal<string>;
141
- /** Emits the markdown source on every change. Only wired for an internal `fc`. */
142
- changed: _angular_core.OutputEmitterRef<string | null>;
143
- /** Field manager for {@link field}; only resolved when `fc` is created here. */
144
- manager?: BaseFieldManager<FT>;
145
- /** Whether the manager declares the field required. */
146
- readonly required: _angular_core.WritableSignal<boolean>;
147
103
  /** Markdown constructs under the cursor, driving `aria-pressed`. */
148
104
  readonly active: _angular_core.WritableSignal<MarkdownActiveState>;
149
105
  /** Heading levels offered by the dropdown. */
@@ -151,8 +107,6 @@ declare class MdeditComponent<FT, T extends DataModel> implements OnInit {
151
107
  level: number;
152
108
  label: string;
153
109
  }[];
154
- /** The control actually in use: the supplied `[fc]`, or the internal one. */
155
- control: FormControl<string | null>;
156
110
  /** Toolbar resolved from {@link toolbar}, as entries the template can render. */
157
111
  readonly groups: _angular_core.Signal<MdToolbarEntry[][]>;
158
112
  private readonly host;
@@ -162,16 +116,12 @@ declare class MdeditComponent<FT, T extends DataModel> implements OnInit {
162
116
  private view?;
163
117
  constructor();
164
118
  /**
165
- * Resolve the control unless a `[fc]` was given, build one seeded from the
166
- * model field, enabled per `[edit]`, and relaying changes to {@link changed} —
167
- * then keep the editor and the control in step.
119
+ * Wire the resolved control to the editor, in both directions.
120
+ *
121
+ * The base picks the control (`[fc]`, `[form]`, or its own) and seeds it;
122
+ * this adds the CodeMirror half.
168
123
  */
169
124
  ngOnInit(): void;
170
- /**
171
- * Switch between read-only and editing by enabling or disabling the control.
172
- * Forces read-only when `[editable]` is false.
173
- */
174
- toggleEdit(): void;
175
125
  /**
176
126
  * Run a toolbar command against the editor and hand focus back, so a click
177
127
  * on the toolbar does not take the caret out of the document.
@@ -180,14 +130,13 @@ declare class MdeditComponent<FT, T extends DataModel> implements OnInit {
180
130
  /** Apply the heading level picked in the dropdown to the current line(s). */
181
131
  setHeadingLevel(value: string): void;
182
132
  /**
183
- * Write the editor content back to the model field, and persist it in `dd`
184
- * mode only.
133
+ * Build or tear down the CodeMirror view, following the host element.
185
134
  *
186
- * In `inline` / `form` modes the model is updated in memory but no request is
187
- * sent, leaving the save to the surrounding form. Does nothing without both a
188
- * `[model]` and a `[field]`.
135
+ * Toggling back to the read-only view removes the host, which would leave a
136
+ * detached view behind and make the next mount a no-op. The control keeps the
137
+ * value across the round trip, so a fresh view is seeded correctly.
189
138
  */
190
- save(): Promise<void>;
139
+ private syncView;
191
140
  /** Build the CodeMirror view inside the host element. */
192
141
  private mount;
193
142
  /**
@@ -203,7 +152,7 @@ declare class MdeditComponent<FT, T extends DataModel> implements OnInit {
203
152
  /** Mirror the control's enabled/disabled status onto the editor. */
204
153
  private applyEditable;
205
154
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<MdeditComponent<any, any>, never>;
206
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<MdeditComponent<any, any>, "data-mdedit", never, { "model": { "alias": "model"; "required": false; "isSignal": true; }; "field": { "alias": "field"; "required": false; "isSignal": true; }; "editable": { "alias": "editable"; "required": false; "isSignal": true; }; "edit": { "alias": "edit"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "hideLabel": { "alias": "hideLabel"; "required": false; "isSignal": true; }; "hideButton": { "alias": "hideButton"; "required": false; "isSignal": true; }; "fc": { "alias": "fc"; "required": false; "isSignal": true; }; "toolbar": { "alias": "toolbar"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; }, { "edit": "editChange"; "changed": "changed"; }, never, ["*"], true, never>;
155
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MdeditComponent<any, any>, "data-mdedit", never, { "toolbar": { "alias": "toolbar"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
207
156
  }
208
157
 
209
158
  /** Options accepted by {@link markdownSetup}. */
@@ -1,9 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { OnInit, OnDestroy, EventEmitter } from '@angular/core';
3
- import { FormControl } from '@angular/forms';
2
+ import { OnInit } from '@angular/core';
3
+ import { DataModel, FieldEditorBase } from '@solidev/data';
4
4
  import { EditorState, Command } from 'prosemirror-state';
5
5
  import { EditorView } from 'prosemirror-view';
6
- import { DataModel, BaseFieldManager } from '@solidev/data';
7
6
  import * as prosemirror_model from 'prosemirror-model';
8
7
  import { Schema, Node, MarkType, NodeType, Attrs } from 'prosemirror-model';
9
8
 
@@ -126,79 +125,23 @@ type Toolbar = ToolbarItem[][];
126
125
  * fits.
127
126
  */
128
127
  declare const RichEditToolbars: Record<string, Toolbar>;
129
- declare class RicheditComponent<FT, T extends DataModel> implements OnInit, OnDestroy {
130
- /** Model instance holding the field. */
131
- /** Id tying the label to the editor. */
132
- readonly inputId: string;
133
- model?: T;
134
- /** Name of the rich text field to edit. */
135
- field?: string;
136
- /** Whether {@link toggleEdit} is allowed to enable editing. */
137
- editable: boolean;
138
- /** Whether the editor is currently enabled. Defaults to true. */
139
- edit: boolean;
140
- /**
141
- * Layout, and whether {@link save} persists.
142
- *
143
- * `dd` renders a `<dt>`/`<dd>` block and is the only mode that saves to the
144
- * API; `inline` and `form` render a label plus the editor and leave saving to
145
- * the caller.
146
- */
147
- mode: 'dd' | 'inline' | 'form';
148
- /** Hide label (for inline forms) */
149
- hideLabel: boolean;
150
- /**
151
- * Hide the built-in save button, for callers driving persistence themselves
152
- * from the {@link changed} output.
153
- */
154
- hideButton: boolean;
155
- /**
156
- * Form control backing the editor.
157
- *
158
- * When supplied, the component uses it as-is and skips its own setup — no
159
- * field manager lookup, no seeding from the model, and no {@link changed}
160
- * emissions. When absent, one is created and wired up from `[model]` and
161
- * `[field]`.
162
- */
163
- fc: FormControl<string | null>;
128
+ declare class RicheditComponent<FT, T extends DataModel> extends FieldEditorBase<FT, T> implements OnInit {
164
129
  /** Toolbar preset name from {@link RichEditToolbars}, or an explicit toolbar. */
165
- toolbar: 'none' | 'default' | 'light' | Toolbar;
166
- /** Emits the editor's HTML on every change. Only wired for an internal `fc`. */
167
- changed: EventEmitter<string | null>;
168
- /** Field manager for {@link field}; only resolved when `fc` is created here. */
169
- manager?: BaseFieldManager<FT>;
170
- /** Whether the manager declares the field required. */
171
- required: boolean;
130
+ toolbar: i0.InputSignal<Toolbar | "none" | "default" | "light">;
172
131
  /** Underlying editor instance; destroyed with the component. */
173
132
  editor: Editor;
174
133
  /** Unused; kept for backwards compatibility. */
175
134
  html: string;
176
135
  /** Toolbar actually rendered, resolved from {@link toolbar}. */
177
136
  realToolbar: Toolbar;
137
+ private readonly destroyRef;
178
138
  /**
179
- * Create the editor, resolve the toolbar, and unless a `[fc]` was given —
180
- * build a control seeded from the model field, enabled per `[edit]`, and
181
- * relaying changes to {@link changed}.
139
+ * Build the engine and resolve the toolbar, then let the base resolve the
140
+ * control and relay its changes.
182
141
  */
183
142
  ngOnInit(): void;
184
- /** Destroy the editor instance to release its resources. */
185
- ngOnDestroy(): void;
186
- /**
187
- * Switch between read-only and editing by enabling or disabling the control.
188
- * Forces read-only when `[editable]` is false.
189
- */
190
- toggleEdit(): void;
191
- /**
192
- * Write the editor content back to the model field, and persist it in `dd`
193
- * mode only.
194
- *
195
- * In `inline` / `form` modes the model is updated in memory but no request is
196
- * sent, leaving the save to the surrounding form. Does nothing without both a
197
- * `[model]` and a `[field]`.
198
- */
199
- save(): Promise<void>;
200
143
  static ɵfac: i0.ɵɵFactoryDeclaration<RicheditComponent<any, any>, never>;
201
- static ɵcmp: i0.ɵɵComponentDeclaration<RicheditComponent<any, any>, "data-richedit", never, { "model": { "alias": "model"; "required": false; }; "field": { "alias": "field"; "required": false; }; "editable": { "alias": "editable"; "required": false; }; "edit": { "alias": "edit"; "required": false; }; "mode": { "alias": "mode"; "required": false; }; "hideLabel": { "alias": "hideLabel"; "required": false; }; "hideButton": { "alias": "hideButton"; "required": false; }; "fc": { "alias": "fc"; "required": false; }; "toolbar": { "alias": "toolbar"; "required": false; }; }, { "changed": "changed"; }, never, ["*"], true, never>;
144
+ static ɵcmp: i0.ɵɵComponentDeclaration<RicheditComponent<any, any>, "data-richedit", never, { "toolbar": { "alias": "toolbar"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
202
145
  }
203
146
 
204
147
  /** The schema itself — one instance, shared by every editor. */
@@ -8,6 +8,7 @@ import { CdkDragDrop } from '@angular/cdk/drag-drop';
8
8
  import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap';
9
9
  import * as _angular_common_http from '@angular/common/http';
10
10
  import { HttpClient, HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';
11
+ import { SafeHtml } from '@angular/platform-browser';
11
12
 
12
13
  /**
13
14
  * Base URL of the REST API every {@link Collection} builds its endpoints on.
@@ -945,12 +946,11 @@ interface IDispEditChoice {
945
946
  * - `textarea`: multi-line `<textarea>`.
946
947
  * - `select`: `<select>` built from the resolved choices. Automatically used
947
948
  * whenever choices are available, whatever the manager advertises.
948
- * - `quill`: rich text editor (rendered by the caller's own integration).
949
949
  * - `fkselect`: `<data-fkselect>` typeahead, set by `ForeignKeyFieldManager`.
950
950
  * - `m2mselect`: `<data-m2mselect>` multi-value typeahead, set by
951
951
  * `ManyToManyFieldManager`.
952
952
  */
953
- type DISPEDIT_EDITOR_TYPES = 'input.text' | 'input.email' | 'input.number' | 'input.decimal' | 'input.datetime' | 'input.date' | 'input.checkbox' | 'input.password' | 'textarea' | 'select' | 'quill' | 'fkselect' | 'm2mselect';
953
+ type DISPEDIT_EDITOR_TYPES = 'input.text' | 'input.email' | 'input.number' | 'input.decimal' | 'input.datetime' | 'input.date' | 'input.checkbox' | 'input.password' | 'textarea' | 'select' | 'fkselect' | 'm2mselect';
954
954
  /**
955
955
  * Every read-only renderer {@link DispeditComponent} knows how to produce.
956
956
  *
@@ -968,9 +968,12 @@ type DISPEDIT_EDITOR_TYPES = 'input.text' | 'input.email' | 'input.number' | 'in
968
968
  * - `m2mdetails`: one line per item, each rendered via its `_display`.
969
969
  * - `datetime` / `date`: value passed through Angular's `date` pipe (`short`
970
970
  * and `shortDate` respectively).
971
- * - `quill`: rich text, rendered as HTML by the caller's integration.
971
+ * - `html`: the value injected as trusted HTML. For rich text and markdown
972
+ * fields, whose rendered form is stored alongside the source — point the
973
+ * dispedit at that `…_html` field and set `[viewer]="'html'"`. **The value is
974
+ * not sanitized**; the value goes through `SafeHtmlPipe`.
972
975
  */
973
- type DISPEDIT_DISPLAY_TYPES = 'text' | 'choice' | 'boolean' | 'decimal' | 'fkdetails' | 'm2mdetails' | 'datetime' | 'date' | 'quill';
976
+ type DISPEDIT_DISPLAY_TYPES = 'text' | 'choice' | 'boolean' | 'decimal' | 'fkdetails' | 'm2mdetails' | 'datetime' | 'date' | 'html';
974
977
 
975
978
  /**
976
979
  * Options common to every field decorator. All are optional; each concrete
@@ -3738,8 +3741,8 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
3738
3741
  /**
3739
3742
  * Forces a display renderer, bypassing the field manager's `displayType`.
3740
3743
  *
3741
- * Writable because setting `[editor]="'quill'"` without a viewer makes the
3742
- * component select the `quill` viewer for you.
3744
+ * Writable so that cross-input consistency rules can settle on a renderer;
3745
+ * see {@link _checks}.
3743
3746
  */
3744
3747
  viewer: _angular_core.ModelSignal<DISPEDIT_DISPLAY_TYPES | undefined>;
3745
3748
  /**
@@ -3906,7 +3909,13 @@ declare class DispeditComponent<FT, T extends DataModel, R extends DataModel> {
3906
3909
  * @param v current list of selected instances.
3907
3910
  */
3908
3911
  onM2MValuesChanges(v: DataModel[]): void;
3909
- /** Apply cross-input consistency rules (a quill editor implies a quill viewer). */
3912
+ /**
3913
+ * Apply cross-input consistency rules.
3914
+ *
3915
+ * Nothing to reconcile at the moment: the one rule that lived here paired the
3916
+ * `quill` editor with the `quill` viewer, and neither exists any more. Kept
3917
+ * as the place such rules belong, since `_init` already calls it.
3918
+ */
3910
3919
  private _checks;
3911
3920
  /**
3912
3921
  * Save value to database, only if model have an id.
@@ -6002,6 +6011,169 @@ declare function uniqueId(prefix: string): string;
6002
6011
  */
6003
6012
  declare function installEditorDomShims(): void;
6004
6013
 
6014
+ /**
6015
+ * The behaviour `<data-richedit>` and `<data-mdedit>` share with
6016
+ * `<data-dispedit>`: show the value, click to edit, save explicitly.
6017
+ *
6018
+ * It lives in the primary entry point so both editors can extend it — they
6019
+ * import `@solidev/data`, and the reverse would be a circular dependency
6020
+ * between entry points. Everything here is engine-agnostic: resolving which
6021
+ * field to read, which control to bind, when to show the editor, and how to
6022
+ * persist. The subclass owns its template and its editor widget.
6023
+ *
6024
+ * ## The source / rendered pair
6025
+ *
6026
+ * Long text is rarely one column. A markdown field is stored as its source
6027
+ * plus the HTML the server rendered from it, and this base follows that shape
6028
+ * by convention: given `field="description"` it edits `description_src` and
6029
+ * displays `description_html` **when the model declares them**, and falls back
6030
+ * to `description` for both when it does not. `[htmlField]` overrides the
6031
+ * display half outright. A `field` that already ends in `_src` is understood,
6032
+ * so `field="description_src"` resolves the same pair.
6033
+ */
6034
+ declare abstract class FieldEditorBase<FT, T extends DataModel> implements OnInit {
6035
+ /** Id tying the label to the editor. */
6036
+ readonly inputId: string;
6037
+ /** Id of the label element, wired to the editor through `aria-labelledby`. */
6038
+ readonly labelId: string;
6039
+ /** Model instance holding the field. */
6040
+ model: _angular_core.InputSignal<T | undefined>;
6041
+ /**
6042
+ * Field to edit, or the base name of a source / rendered pair.
6043
+ *
6044
+ * See the class description for how `<field>_src` and `<field>_html` are
6045
+ * resolved.
6046
+ */
6047
+ field: _angular_core.InputSignal<string | undefined>;
6048
+ /** Overrides the field read for the read-only display. */
6049
+ htmlField: _angular_core.InputSignal<string | undefined>;
6050
+ /** Whether {@link toggleEdit} is allowed to reveal the editor. */
6051
+ editable: _angular_core.InputSignal<boolean>;
6052
+ /**
6053
+ * Whether the editor is showing, in `dd` mode.
6054
+ *
6055
+ * Defaults to false: the value renders and a click reveals the editor, the
6056
+ * way `<data-dispedit>` behaves. `inline` and `form` modes ignore this and
6057
+ * follow {@link showEditor}.
6058
+ */
6059
+ edit: _angular_core.ModelSignal<boolean>;
6060
+ /**
6061
+ * Layout, and whether {@link save} persists.
6062
+ *
6063
+ * `dd` renders a `<dt>`/`<dd>` block and is the only mode that saves to the
6064
+ * API; `inline` and `form` render a label plus the editor and leave saving to
6065
+ * the caller.
6066
+ */
6067
+ mode: _angular_core.InputSignal<"inline" | "dd" | "form">;
6068
+ /** Hide label (for inline forms). */
6069
+ hideLabel: _angular_core.InputSignal<boolean>;
6070
+ /**
6071
+ * Hide the built-in save button, for callers driving persistence themselves
6072
+ * from the {@link changed} output.
6073
+ */
6074
+ hideButton: _angular_core.InputSignal<boolean>;
6075
+ /**
6076
+ * Form control backing the editor.
6077
+ *
6078
+ * When supplied, the component uses it as-is and skips its own setup — no
6079
+ * field manager lookup, no seeding from the model, and no {@link changed}
6080
+ * emissions. Takes precedence over `[form]`.
6081
+ */
6082
+ fc: _angular_core.InputSignal<FormControl<string | null> | undefined>;
6083
+ /**
6084
+ * External form group to register into, the way `<data-dispedit>` does.
6085
+ *
6086
+ * A control named after the resolved source field is added to it, seeded
6087
+ * from the model. Ignored when `[fc]` is supplied.
6088
+ */
6089
+ form: _angular_core.InputSignal<UntypedFormGroup | undefined>;
6090
+ /** Emits the value on every change. Not wired for a caller-supplied `[fc]`. */
6091
+ changed: _angular_core.OutputEmitterRef<string | null>;
6092
+ /** Field manager for the source field; only resolved when `fc` is created here. */
6093
+ manager?: BaseFieldManager<FT>;
6094
+ /** Whether the manager declares the field required. */
6095
+ readonly required: _angular_core.WritableSignal<boolean>;
6096
+ /** The control actually in use. */
6097
+ control: FormControl<string | null>;
6098
+ /** The base name of the pair, with any trailing `_src` removed. */
6099
+ private readonly baseField;
6100
+ /** The field actually edited. */
6101
+ readonly sourceField: _angular_core.Signal<string>;
6102
+ /** The field actually displayed in read-only mode. */
6103
+ readonly displayField: _angular_core.Signal<string>;
6104
+ /**
6105
+ * Whether the editor is showing rather than the rendered value.
6106
+ *
6107
+ * The rule is `<data-dispedit>`'s: `dd` follows `[edit]`, `inline` shows the
6108
+ * editor unless the field is not editable, and `form` always shows it — a
6109
+ * form control that renders as static text would be a surprise.
6110
+ */
6111
+ readonly showEditor: _angular_core.Signal<boolean>;
6112
+ /**
6113
+ * Resolve the control: the supplied `[fc]`, one registered into `[form]`, or
6114
+ * one of our own seeded from the model.
6115
+ */
6116
+ ngOnInit(): void;
6117
+ /**
6118
+ * Switch between the rendered value and the editor.
6119
+ * Does nothing when `[editable]` is false.
6120
+ */
6121
+ toggleEdit(): void;
6122
+ /**
6123
+ * The rendered value, as stored on the display field.
6124
+ *
6125
+ * Templates pass it through {@link SafeHtmlPipe} to inject it — **trusted,
6126
+ * not sanitized**, because Angular's sanitizer allow-list has no `style` and
6127
+ * would drop the alignment and colours the rich text editor writes. Point
6128
+ * these components at fields your own editor produced and your own API
6129
+ * stored.
6130
+ */
6131
+ displayValue(): string;
6132
+ /**
6133
+ * Write the editor content back to the model's source field, and persist it
6134
+ * in `dd` mode only.
6135
+ *
6136
+ * In `inline` / `form` modes the model is updated in memory but no request is
6137
+ * sent, leaving the save to the surrounding form. Does nothing without both a
6138
+ * `[model]` and a `[field]`.
6139
+ */
6140
+ save(): Promise<void>;
6141
+ /** Whether the model declares a property under that name. */
6142
+ private modelHas;
6143
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<FieldEditorBase<any, any>, never>;
6144
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<FieldEditorBase<any, any>, never, never, { "model": { "alias": "model"; "required": false; "isSignal": true; }; "field": { "alias": "field"; "required": false; "isSignal": true; }; "htmlField": { "alias": "htmlField"; "required": false; "isSignal": true; }; "editable": { "alias": "editable"; "required": false; "isSignal": true; }; "edit": { "alias": "edit"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "hideLabel": { "alias": "hideLabel"; "required": false; "isSignal": true; }; "hideButton": { "alias": "hideButton"; "required": false; "isSignal": true; }; "fc": { "alias": "fc"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; }, { "edit": "editChange"; "changed": "changed"; }, never, never, true, never>;
6145
+ }
6146
+
6147
+ /**
6148
+ * Marks HTML as trusted, so `[innerHTML]` renders it as-is.
6149
+ *
6150
+ * Meant for the rendered half of a rich text field — the `<field>_html` column
6151
+ * the server produces from the markdown or HTML source. Angular's sanitizer
6152
+ * builds its allow-list from `URI_ATTRS + HTML_ATTRS + ARIA_ATTRS`, and `style`
6153
+ * is in none of them, so a plain `[innerHTML]` silently drops every
6154
+ * `text-align` and every colour `<data-richedit>` writes: read-only mode ends
6155
+ * up looking nothing like the editor.
6156
+ *
6157
+ * **Only use it on HTML the server produced.** The value is inserted without
6158
+ * any filtering, and trusted HTML executes scripts — pointing this at a string
6159
+ * a user of another system can influence is an XSS vector.
6160
+ *
6161
+ * @example
6162
+ * ```html
6163
+ * <div [innerHTML]="product.description_html | safeHtml"></div>
6164
+ * ```
6165
+ */
6166
+ declare class SafeHtmlPipe implements PipeTransform {
6167
+ private _sanitizer;
6168
+ /**
6169
+ * @param value HTML to trust; null for a nullish or empty input, which
6170
+ * `[innerHTML]` renders as nothing.
6171
+ */
6172
+ transform(value: string | null | undefined): SafeHtml | null;
6173
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SafeHtmlPipe, never>;
6174
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<SafeHtmlPipe, "safeHtml", true>;
6175
+ }
6176
+
6005
6177
  /**
6006
6178
  * Compiles (and optionally renders) an Underscore-style string template, using ERB
6007
6179
  * delimiters: `<%= expr %>` interpolates, `<% code %>` evaluates, and a `print()` helper
@@ -6075,5 +6247,5 @@ declare class UpdateComponent {
6075
6247
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<UpdateComponent, "data-update", never, {}, {}, never, never, true, never>;
6076
6248
  }
6077
6249
 
6078
- export { AuthInterceptor, AuthServiceBase, BanAdapter, BaseFieldManager, BootstrapDataDisplayConfig, BreadcrumbComponent, ChoicePipe, Collection, CollectionMock, DATA_API_URL, DATA_AUTH_PARAMS, DATA_AUTH_SERVICE, DATA_AUTH_URLS, DATA_AUTH_USER_SERVICE, DATA_DISPLAY_CONFIG, DATA_MAX_TRANSFERSTATE_TIME, DATA_MESSAGE_SOUNDS, DEFAULT_TIMEOUTS, DataBackend, DataMessageService, DataModel, DataUploaderService, DispeditComponent, FactorPipe, FactorcPipe, FkselectComponent, FlagsComponent, Jwt, Link, M2mselectComponent, Message, MessageZoneComponent, ModelList, ModelListAutocompleteFilter, ModelListAutocompleteMultiFilter, ModelListDateFilter, ModelListDatetimeFilter, ModelListDatetimerangeFilter, ModelListFieldHeaderComponent, ModelListFieldsSelectorComponent, ModelListFilter, ModelListFilterGroup, ModelListFilters, ModelListFiltersComponent, ModelListFiltersSelectComponent, ModelListFlagsFilter, ModelListGeodistanceFilter, ModelListNumberFilter, ModelListNumberOperations, ModelListPaginatorComponent, ModelListSelectFilter, ModelListSelectMultiFilter, ModelListService, ModelListSorterComponent, ModelListTextFilter, ModelListTreeFilter, NavDriver, NgFileDropDirective, NgFileSelectDirective, NgxUploaderModule, PChoicePipe, PFactorPipe, PFactorcPipe, Queryset, RData, STATUS, SafeDeleteComponent, TYPE, TabMemoryService, UpdateComponent, UpdateService, UploadStatus, asText, booleanField, charField, computedField, dateField, datetimeField, decimalField, detailsField, emailField, fieldValues, floatField, foreignKeyField, humanizeBytes, installEditorDomShims, integerField, isValue, manyToManyField, passwordField, primaryField, reverseForeignKeyField, slugify, strToNumber, textField, tmpl, uniqueId };
6250
+ export { AuthInterceptor, AuthServiceBase, BanAdapter, BaseFieldManager, BootstrapDataDisplayConfig, BreadcrumbComponent, ChoicePipe, Collection, CollectionMock, DATA_API_URL, DATA_AUTH_PARAMS, DATA_AUTH_SERVICE, DATA_AUTH_URLS, DATA_AUTH_USER_SERVICE, DATA_DISPLAY_CONFIG, DATA_MAX_TRANSFERSTATE_TIME, DATA_MESSAGE_SOUNDS, DEFAULT_TIMEOUTS, DataBackend, DataMessageService, DataModel, DataUploaderService, DispeditComponent, FactorPipe, FactorcPipe, FieldEditorBase, FkselectComponent, FlagsComponent, Jwt, Link, M2mselectComponent, Message, MessageZoneComponent, ModelList, ModelListAutocompleteFilter, ModelListAutocompleteMultiFilter, ModelListDateFilter, ModelListDatetimeFilter, ModelListDatetimerangeFilter, ModelListFieldHeaderComponent, ModelListFieldsSelectorComponent, ModelListFilter, ModelListFilterGroup, ModelListFilters, ModelListFiltersComponent, ModelListFiltersSelectComponent, ModelListFlagsFilter, ModelListGeodistanceFilter, ModelListNumberFilter, ModelListNumberOperations, ModelListPaginatorComponent, ModelListSelectFilter, ModelListSelectMultiFilter, ModelListService, ModelListSorterComponent, ModelListTextFilter, ModelListTreeFilter, NavDriver, NgFileDropDirective, NgFileSelectDirective, NgxUploaderModule, PChoicePipe, PFactorPipe, PFactorcPipe, Queryset, RData, STATUS, SafeDeleteComponent, SafeHtmlPipe, TYPE, TabMemoryService, UpdateComponent, UpdateService, UploadStatus, asText, booleanField, charField, computedField, dateField, datetimeField, decimalField, detailsField, emailField, fieldValues, floatField, foreignKeyField, humanizeBytes, installEditorDomShims, integerField, isValue, manyToManyField, passwordField, primaryField, reverseForeignKeyField, slugify, strToNumber, textField, tmpl, uniqueId };
6079
6251
  export type { AuthParams, BanResults, BaseRouteParams, BlobFile, CompiledTemplate, CustomField, DataDisplayConfig, DataModelFields, DataModelType, FakeDeleteResult, FieldsParams, FilterData, FilterDefaults, FilterValue, FiltersParams, GeoSearchResult, GetFlagsResult, IActionParams, ICollectionCacheParams, IFlagItem, IHttpMethod, IJwtBaseData, IJwtRefreshResponseJson, IJwtResponseJson, IModelListMessage, IPathTreeItem, IQueryFullResponse, IQueryMeta, IQueryMetaNav, IQueryMetaNavParams, IQueryNav, IQuerysetOptions, ISoundTypes, ModelListAutocompleteMultiParams, ModelListAutocompleteParams, ModelListFilterParams, ModelListFlagsFilterParams, ModelListGeodistanceFilterParams, ModelListMultiSelectFilterParams, ModelListNumberFilterParams, ModelListParams, ModelListSelectFilterParams, ModelListTreeParams, OutFilterData, PaginationParams, RouteConfigItem, RouteFn, RoutesConfig, RoutesDefinition, SortData, SorterDefaults, StrictRoutes, TplFn, TplFun, UploadFile, UploadInput, UploadOutput, UploadProgress, UploaderOptions };