ngx-xtroedge-cms 1.3.17 → 1.4.0

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/LICENSE ADDED
@@ -0,0 +1,46 @@
1
+ XtroEdge CMS - Proprietary Software License
2
+
3
+ Copyright (c) 2024-2026 XtroEdge. All rights reserved.
4
+
5
+ IMPORTANT: READ THIS LICENSE AGREEMENT CAREFULLY BEFORE USING THIS SOFTWARE.
6
+
7
+ 1. GRANT OF LICENSE
8
+ This software is licensed, not sold. XtroEdge grants you a non-exclusive,
9
+ non-transferable, revocable license to use this software subject to a valid
10
+ subscription or active free trial period.
11
+
12
+ 2. FREE TRIAL
13
+ New users are granted a 30-day free trial starting from the date of
14
+ registration. During the trial period, all features are available. After
15
+ the trial period expires, a paid subscription ($10/month) is required.
16
+
17
+ 3. RESTRICTIONS
18
+ You may NOT:
19
+ - Copy, modify, merge, or create derivative works of this software
20
+ - Distribute, sublicense, sell, or transfer this software to any third party
21
+ - Reverse engineer, decompile, or disassemble this software
22
+ - Remove or alter any proprietary notices, labels, or marks
23
+ - Use this software after your license or trial has expired
24
+ - Share your license key with unauthorized parties
25
+
26
+ 4. SUBSCRIPTION
27
+ After the free trial, continued use requires an active subscription at the
28
+ current rate ($10/month). Failure to maintain an active subscription will
29
+ result in suspension of the software functionality.
30
+
31
+ 5. TERMINATION
32
+ This license is effective until terminated. XtroEdge may terminate this
33
+ license at any time if you fail to comply with any term of this agreement.
34
+ Upon termination, you must destroy all copies of the software.
35
+
36
+ 6. DISCLAIMER OF WARRANTIES
37
+ THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS
38
+ OR IMPLIED. XTROEDGE DOES NOT WARRANT THAT THE SOFTWARE WILL BE
39
+ UNINTERRUPTED OR ERROR-FREE.
40
+
41
+ 7. LIMITATION OF LIABILITY
42
+ IN NO EVENT SHALL XTROEDGE BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
43
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE.
44
+
45
+ For licensing inquiries: support@xtroedge.com
46
+ Website: https://xtroedge.com
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # xtro-edge-page-editor
package/dist/index.d.mts CHANGED
@@ -1,8 +1,12 @@
1
1
  /** Configuration for the CMS */
2
2
  interface XtroedgeCmsConfig {
3
- /** API base URL for save/publish/load endpoints (optional - only needed when backend is ready) */
3
+ /** Our XtroEdge server URL login, license, save, publish (required) */
4
4
  apiBase?: string;
5
- /** Base URL prepended to uploaded image paths (defaults to apiBase origin) */
5
+ /** Client's API server URL GET pages, image upload (falls back to apiBase if not set) */
6
+ clientApi?: string;
7
+ /** Headers to send with client API GET requests (e.g. {"x-data-source": "dev"}) */
8
+ clientHeaders?: Record<string, string>;
9
+ /** Base URL prepended to uploaded image paths (defaults to clientApi or apiBase origin) */
6
10
  imageBaseUrl?: string;
7
11
  /** CSS selector for the content container to scan (default: 'body') */
8
12
  containerSelector?: string;
@@ -20,6 +24,12 @@ interface XtroedgeCmsConfig {
20
24
  highlightColor?: string;
21
25
  /** Login API URL — if builder_token not found in localStorage, show login modal (default: apiBase + '/auth/login') */
22
26
  loginUrl?: string;
27
+ /** License key for subscription validation */
28
+ licenseKey?: string;
29
+ /** License validation API URL (default: apiBase + '/license/validate') */
30
+ licenseValidateUrl?: string;
31
+ /** Enable rich text toolbar for inline editing (default: true) */
32
+ richText?: boolean;
23
33
  onSaved?: () => void;
24
34
  onPublished?: () => void;
25
35
  onError?: (action: string, error: any) => void;
@@ -60,8 +70,25 @@ interface EditHistoryEntry {
60
70
  lang: string;
61
71
  snapshot: string;
62
72
  }
73
+ /** License validation response */
74
+ interface LicenseStatus {
75
+ valid: boolean;
76
+ plan: 'trial' | 'paid' | 'expired' | 'invalid';
77
+ daysLeft?: number;
78
+ message?: string;
79
+ }
63
80
 
64
81
  declare class XtroedgeCMS {
82
+ private static readonly _SK;
83
+ private static readonly _VAULT_KEY;
84
+ private static _enc;
85
+ private static _dec;
86
+ private static _readVault;
87
+ private static _writeVault;
88
+ private static secureSet;
89
+ private static secureGet;
90
+ private static secureRemove;
91
+ private static secureClear;
65
92
  private config;
66
93
  private containerSelector;
67
94
  private editableTags;
@@ -98,6 +125,7 @@ declare class XtroedgeCMS {
98
125
  private dirtyKeys;
99
126
  private dirtyImageKeys;
100
127
  private registeredKeys;
128
+ private domOriginals;
101
129
  private managedElements;
102
130
  private managedImages;
103
131
  private autoDetectedElements;
@@ -105,6 +133,10 @@ declare class XtroedgeCMS {
105
133
  private scanTimeout;
106
134
  private activeImageEl;
107
135
  private imageCtxMenu;
136
+ private richToolbarEl;
137
+ private activeEditableEl;
138
+ private toolbarHideTimeout;
139
+ private selectionChangeHandler;
108
140
  private currentSlug;
109
141
  private currentTitle;
110
142
  private initialized;
@@ -132,6 +164,8 @@ declare class XtroedgeCMS {
132
164
  private editModeContent;
133
165
  private fileInput;
134
166
  private imgOverlay;
167
+ private editScrollHandler;
168
+ private editScrollRAF;
135
169
  private posX;
136
170
  private posY;
137
171
  private isDragging;
@@ -141,6 +175,10 @@ declare class XtroedgeCMS {
141
175
  private startPosY;
142
176
  private hasMoved;
143
177
  private toastTimer;
178
+ private licenseValid;
179
+ private licenseStatus;
180
+ private licenseOverlayEl;
181
+ private trialBannerDismissed;
144
182
  private db;
145
183
  private boundMouseMove;
146
184
  private boundMouseUp;
@@ -150,8 +188,17 @@ declare class XtroedgeCMS {
150
188
  private boundHashChange;
151
189
  private translationCache;
152
190
  constructor(config?: XtroedgeCmsConfig);
153
- init(): void;
191
+ init(): Promise<void>;
154
192
  destroy(): void;
193
+ private static readonly LICENSE_CACHE_KEY;
194
+ private static readonly LICENSE_CACHE_TTL;
195
+ private validateLicense;
196
+ private getLicenseCache;
197
+ private setLicenseCache;
198
+ /** Shows toast when user tries to edit with expired/invalid license */
199
+ private showLicenseExpiredToast;
200
+ /** Returns trial/expired banner HTML if applicable, or empty string */
201
+ private getTrialBannerHTML;
155
202
  private injectStyles;
156
203
  private interceptNavigation;
157
204
  private handleNavigation;
@@ -166,12 +213,37 @@ declare class XtroedgeCMS {
166
213
  private scanImages;
167
214
  private getDirectTextContent;
168
215
  private hasEditableChildren;
216
+ private getElementContent;
217
+ private setElementContent;
169
218
  private setDirectTextContent;
170
219
  private attachElement;
171
220
  private detachElement;
221
+ /** Stop propagation so parent carousels (Swiper, Owl, etc.) don't hijack the event */
222
+ private static stopProp;
172
223
  private enableElementEdit;
173
224
  private disableElementEdit;
174
225
  private applyEditMode;
226
+ /** Set of positioned ancestors we added pointer-events:none to (for cleanup) */
227
+ private modifiedAncestors;
228
+ /**
229
+ * For each managed element, find the nearest position:absolute/fixed ancestor.
230
+ * If that ancestor is invisible (opacity ≈ 0), set pointer-events:none on it
231
+ * so clicks pass through to the visible element behind it.
232
+ */
233
+ private syncEditablePointerEvents;
234
+ /** Walk up from el to find the nearest position:absolute or position:fixed ancestor */
235
+ private findPositionedAncestor;
236
+ private killAnimations;
237
+ /** Remove GSAP ScrollTrigger pin-spacer wrapper divs and restore original elements */
238
+ private removePinSpacers;
239
+ /** Clear only animation-related inline styles (set by GSAP/ScrollTrigger) without breaking layout */
240
+ private clearAnimationInlineStyles;
241
+ /** Capture each element's current DOM text before CMS applies saved edits */
242
+ private captureDomOriginals;
243
+ /** Ensure every entry in pageTexts has _orig for current language (from domOriginals) */
244
+ private ensureOriginals;
245
+ /** Find a managed element whose current text matches the given original text */
246
+ private findElementByOriginal;
175
247
  private updateElementTexts;
176
248
  private cleanupManagedElements;
177
249
  private attachImage;
@@ -190,6 +262,18 @@ declare class XtroedgeCMS {
190
262
  private onImageChanged;
191
263
  private createSnapshot;
192
264
  private applySnapshot;
265
+ private get richTextEnabled();
266
+ private static readonly SINGLE_LINE_TAGS;
267
+ private static readonly ALLOWED_TAGS;
268
+ private static readonly ALLOWED_ATTRS;
269
+ private sanitizeHTML;
270
+ private createRichToolbar;
271
+ private destroyRichToolbar;
272
+ private execToolbarCommand;
273
+ private showRichToolbar;
274
+ private positionToolbar;
275
+ private hideRichToolbar;
276
+ private updateToolbarState;
193
277
  private onUndo;
194
278
  private onRedo;
195
279
  private recalcDirtyKeys;
@@ -200,6 +284,10 @@ declare class XtroedgeCMS {
200
284
  private loadTranslationsAndInit;
201
285
  private flattenTranslations;
202
286
  private getPageSection;
287
+ /** Resolve a stored URL against our server (apiBase) */
288
+ private resolveServerUrl;
289
+ /** Resolve a stored URL against client's server (clientApi, falls back to apiBase) */
290
+ private resolveClientUrl;
203
291
  private apiFetch;
204
292
  private fetchSection;
205
293
  private hasSection;
@@ -239,9 +327,9 @@ declare class XtroedgeCMS {
239
327
  private getDarkerColor;
240
328
  private applyThemeColor;
241
329
  /** Quick init - create and start CMS in one call */
242
- static create(config?: XtroedgeCmsConfig): XtroedgeCMS;
330
+ static create(config?: XtroedgeCmsConfig): Promise<XtroedgeCMS>;
243
331
  /** Auto-init: called automatically when package is loaded. No user code needed. */
244
- static autoInit(): void;
332
+ static autoInit(): Promise<void>;
245
333
  }
246
334
 
247
- export { type EditHistoryEntry, type PageTextEntry, type WebPageContent, XtroedgeCMS, type XtroedgeCmsConfig };
335
+ export { type EditHistoryEntry, type LicenseStatus, type PageTextEntry, type WebPageContent, XtroedgeCMS, type XtroedgeCmsConfig };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,12 @@
1
1
  /** Configuration for the CMS */
2
2
  interface XtroedgeCmsConfig {
3
- /** API base URL for save/publish/load endpoints (optional - only needed when backend is ready) */
3
+ /** Our XtroEdge server URL login, license, save, publish (required) */
4
4
  apiBase?: string;
5
- /** Base URL prepended to uploaded image paths (defaults to apiBase origin) */
5
+ /** Client's API server URL GET pages, image upload (falls back to apiBase if not set) */
6
+ clientApi?: string;
7
+ /** Headers to send with client API GET requests (e.g. {"x-data-source": "dev"}) */
8
+ clientHeaders?: Record<string, string>;
9
+ /** Base URL prepended to uploaded image paths (defaults to clientApi or apiBase origin) */
6
10
  imageBaseUrl?: string;
7
11
  /** CSS selector for the content container to scan (default: 'body') */
8
12
  containerSelector?: string;
@@ -20,6 +24,12 @@ interface XtroedgeCmsConfig {
20
24
  highlightColor?: string;
21
25
  /** Login API URL — if builder_token not found in localStorage, show login modal (default: apiBase + '/auth/login') */
22
26
  loginUrl?: string;
27
+ /** License key for subscription validation */
28
+ licenseKey?: string;
29
+ /** License validation API URL (default: apiBase + '/license/validate') */
30
+ licenseValidateUrl?: string;
31
+ /** Enable rich text toolbar for inline editing (default: true) */
32
+ richText?: boolean;
23
33
  onSaved?: () => void;
24
34
  onPublished?: () => void;
25
35
  onError?: (action: string, error: any) => void;
@@ -60,8 +70,25 @@ interface EditHistoryEntry {
60
70
  lang: string;
61
71
  snapshot: string;
62
72
  }
73
+ /** License validation response */
74
+ interface LicenseStatus {
75
+ valid: boolean;
76
+ plan: 'trial' | 'paid' | 'expired' | 'invalid';
77
+ daysLeft?: number;
78
+ message?: string;
79
+ }
63
80
 
64
81
  declare class XtroedgeCMS {
82
+ private static readonly _SK;
83
+ private static readonly _VAULT_KEY;
84
+ private static _enc;
85
+ private static _dec;
86
+ private static _readVault;
87
+ private static _writeVault;
88
+ private static secureSet;
89
+ private static secureGet;
90
+ private static secureRemove;
91
+ private static secureClear;
65
92
  private config;
66
93
  private containerSelector;
67
94
  private editableTags;
@@ -98,6 +125,7 @@ declare class XtroedgeCMS {
98
125
  private dirtyKeys;
99
126
  private dirtyImageKeys;
100
127
  private registeredKeys;
128
+ private domOriginals;
101
129
  private managedElements;
102
130
  private managedImages;
103
131
  private autoDetectedElements;
@@ -105,6 +133,10 @@ declare class XtroedgeCMS {
105
133
  private scanTimeout;
106
134
  private activeImageEl;
107
135
  private imageCtxMenu;
136
+ private richToolbarEl;
137
+ private activeEditableEl;
138
+ private toolbarHideTimeout;
139
+ private selectionChangeHandler;
108
140
  private currentSlug;
109
141
  private currentTitle;
110
142
  private initialized;
@@ -132,6 +164,8 @@ declare class XtroedgeCMS {
132
164
  private editModeContent;
133
165
  private fileInput;
134
166
  private imgOverlay;
167
+ private editScrollHandler;
168
+ private editScrollRAF;
135
169
  private posX;
136
170
  private posY;
137
171
  private isDragging;
@@ -141,6 +175,10 @@ declare class XtroedgeCMS {
141
175
  private startPosY;
142
176
  private hasMoved;
143
177
  private toastTimer;
178
+ private licenseValid;
179
+ private licenseStatus;
180
+ private licenseOverlayEl;
181
+ private trialBannerDismissed;
144
182
  private db;
145
183
  private boundMouseMove;
146
184
  private boundMouseUp;
@@ -150,8 +188,17 @@ declare class XtroedgeCMS {
150
188
  private boundHashChange;
151
189
  private translationCache;
152
190
  constructor(config?: XtroedgeCmsConfig);
153
- init(): void;
191
+ init(): Promise<void>;
154
192
  destroy(): void;
193
+ private static readonly LICENSE_CACHE_KEY;
194
+ private static readonly LICENSE_CACHE_TTL;
195
+ private validateLicense;
196
+ private getLicenseCache;
197
+ private setLicenseCache;
198
+ /** Shows toast when user tries to edit with expired/invalid license */
199
+ private showLicenseExpiredToast;
200
+ /** Returns trial/expired banner HTML if applicable, or empty string */
201
+ private getTrialBannerHTML;
155
202
  private injectStyles;
156
203
  private interceptNavigation;
157
204
  private handleNavigation;
@@ -166,12 +213,37 @@ declare class XtroedgeCMS {
166
213
  private scanImages;
167
214
  private getDirectTextContent;
168
215
  private hasEditableChildren;
216
+ private getElementContent;
217
+ private setElementContent;
169
218
  private setDirectTextContent;
170
219
  private attachElement;
171
220
  private detachElement;
221
+ /** Stop propagation so parent carousels (Swiper, Owl, etc.) don't hijack the event */
222
+ private static stopProp;
172
223
  private enableElementEdit;
173
224
  private disableElementEdit;
174
225
  private applyEditMode;
226
+ /** Set of positioned ancestors we added pointer-events:none to (for cleanup) */
227
+ private modifiedAncestors;
228
+ /**
229
+ * For each managed element, find the nearest position:absolute/fixed ancestor.
230
+ * If that ancestor is invisible (opacity ≈ 0), set pointer-events:none on it
231
+ * so clicks pass through to the visible element behind it.
232
+ */
233
+ private syncEditablePointerEvents;
234
+ /** Walk up from el to find the nearest position:absolute or position:fixed ancestor */
235
+ private findPositionedAncestor;
236
+ private killAnimations;
237
+ /** Remove GSAP ScrollTrigger pin-spacer wrapper divs and restore original elements */
238
+ private removePinSpacers;
239
+ /** Clear only animation-related inline styles (set by GSAP/ScrollTrigger) without breaking layout */
240
+ private clearAnimationInlineStyles;
241
+ /** Capture each element's current DOM text before CMS applies saved edits */
242
+ private captureDomOriginals;
243
+ /** Ensure every entry in pageTexts has _orig for current language (from domOriginals) */
244
+ private ensureOriginals;
245
+ /** Find a managed element whose current text matches the given original text */
246
+ private findElementByOriginal;
175
247
  private updateElementTexts;
176
248
  private cleanupManagedElements;
177
249
  private attachImage;
@@ -190,6 +262,18 @@ declare class XtroedgeCMS {
190
262
  private onImageChanged;
191
263
  private createSnapshot;
192
264
  private applySnapshot;
265
+ private get richTextEnabled();
266
+ private static readonly SINGLE_LINE_TAGS;
267
+ private static readonly ALLOWED_TAGS;
268
+ private static readonly ALLOWED_ATTRS;
269
+ private sanitizeHTML;
270
+ private createRichToolbar;
271
+ private destroyRichToolbar;
272
+ private execToolbarCommand;
273
+ private showRichToolbar;
274
+ private positionToolbar;
275
+ private hideRichToolbar;
276
+ private updateToolbarState;
193
277
  private onUndo;
194
278
  private onRedo;
195
279
  private recalcDirtyKeys;
@@ -200,6 +284,10 @@ declare class XtroedgeCMS {
200
284
  private loadTranslationsAndInit;
201
285
  private flattenTranslations;
202
286
  private getPageSection;
287
+ /** Resolve a stored URL against our server (apiBase) */
288
+ private resolveServerUrl;
289
+ /** Resolve a stored URL against client's server (clientApi, falls back to apiBase) */
290
+ private resolveClientUrl;
203
291
  private apiFetch;
204
292
  private fetchSection;
205
293
  private hasSection;
@@ -239,9 +327,9 @@ declare class XtroedgeCMS {
239
327
  private getDarkerColor;
240
328
  private applyThemeColor;
241
329
  /** Quick init - create and start CMS in one call */
242
- static create(config?: XtroedgeCmsConfig): XtroedgeCMS;
330
+ static create(config?: XtroedgeCmsConfig): Promise<XtroedgeCMS>;
243
331
  /** Auto-init: called automatically when package is loaded. No user code needed. */
244
- static autoInit(): void;
332
+ static autoInit(): Promise<void>;
245
333
  }
246
334
 
247
- export { type EditHistoryEntry, type PageTextEntry, type WebPageContent, XtroedgeCMS, type XtroedgeCmsConfig };
335
+ export { type EditHistoryEntry, type LicenseStatus, type PageTextEntry, type WebPageContent, XtroedgeCMS, type XtroedgeCmsConfig };