@@ -42,7 +42,96 @@ import type {
4242let ConfigPrototype = { } ;
4343
4444/**
45- * Default Editor's Configuration
45+ * Default Editor's Configuration.
46+ *
47+ * This class holds all default option values for the Jodit editor.
48+ * It uses a **private constructor** and a **lazy singleton** pattern — the single instance
49+ * is created on the first access to {@link Config.defaultOptions} (also available as `Jodit.defaultOptions`).
50+ *
51+ * ## How options are resolved
52+ *
53+ * When you create an editor with `Jodit.make('#editor', userOptions)`, the library
54+ * calls {@link ConfigProto}(userOptions, Config.defaultOptions). `ConfigProto` does
55+ * **not** deep-clone the defaults. Instead it creates a new object whose JavaScript
56+ * prototype is `Config.defaultOptions`:
57+ *
58+ * ```
59+ * userOptions ──[[Prototype]]──► Config.defaultOptions
60+ * ```
61+ *
62+ * Any key present in `userOptions` shadows the default;
63+ * any key **not** present falls through to `Config.defaultOptions` via the prototype chain.
64+ * Nested plain objects are recursively prototyped in the same way, so partial overrides
65+ * of nested options work automatically:
66+ *
67+ * ```js
68+ * // Only override `dialogWidth`; all other `image.*` defaults are still available
69+ * Jodit.make('#editor', {
70+ * image: { dialogWidth: 500 }
71+ * });
72+ * ```
73+ *
74+ * ## How plugins extend the config
75+ *
76+ * Each plugin adds its own defaults by assigning to `Config.prototype` and augmenting
77+ * the TypeScript type with `declare module`:
78+ *
79+ * ```ts
80+ * // 1. Type augmentation (compile-time)
81+ * declare module 'jodit/config' {
82+ * interface Config {
83+ * toolbarSticky: boolean;
84+ * }
85+ * }
86+ *
87+ * // 2. Runtime default
88+ * Config.prototype.toolbarSticky = true;
89+ * ```
90+ *
91+ * Because the constructor runs `Object.assign(this, ConfigPrototype)` (where
92+ * `ConfigPrototype` is captured as `Config.prototype` after the class definition),
93+ * all prototype-level values — including those added by plugins — are materialized
94+ * as own properties on the singleton. This means `Config.defaultOptions` always
95+ * contains every registered option as an own, enumerable property.
96+ *
97+ * ## Changing global defaults
98+ *
99+ * You can modify `Jodit.defaultOptions` **before** creating editors to change
100+ * defaults globally:
101+ *
102+ * ```js
103+ * Jodit.defaultOptions.language = 'de';
104+ * Jodit.defaultOptions.theme = 'dark';
105+ *
106+ * // Both editors inherit the new defaults
107+ * Jodit.make('#editor1');
108+ * Jodit.make('#editor2');
109+ * ```
110+ *
111+ * ## `Jodit.atom` — preventing deep merge
112+ *
113+ * By default, `ConfigProto` deep-merges nested plain objects and arrays.
114+ * Wrap a value with `Jodit.atom(value)` to make it **atomic** — it will completely
115+ * replace the default instead of being merged:
116+ *
117+ * ```js
118+ * Jodit.make('#editor', {
119+ * controls: {
120+ * fontsize: {
121+ * // Replace the entire list rather than merging with the default one
122+ * list: Jodit.atom([8, 9, 10])
123+ * }
124+ * }
125+ * });
126+ * ```
127+ *
128+ * `Jodit.atom` calls {@link markAsAtomic}, which sets a non-enumerable
129+ * `isAtom` flag on the object. `ConfigProto` checks this flag and skips
130+ * recursive merging when it is present. Note: top-level arrays (depth 0)
131+ * are always treated as atomic — they replace rather than merge.
132+ *
133+ * @see {@link ConfigProto } for the full merge algorithm
134+ * @see {@link markAsAtomic } / {@link isAtom } for the atom marker implementation
46135 */
47136class Config implements IViewOptions {
48137 private constructor ( ) {
0 commit comments