@absmartly/sdk-plugins 1.1.1 → 1.2.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/README.md +34 -33
- package/dist/absmartly-cookie.min.js +1 -1
- package/dist/absmartly-dom-changes-core.min.js +1 -1
- package/dist/absmartly-dom-changes-lite.min.js +1 -1
- package/dist/absmartly-overrides-full.min.js +1 -1
- package/dist/absmartly-overrides-lite.min.js +1 -1
- package/dist/absmartly-sdk-plugins.min.js +1 -1
- package/dist/absmartly-vitals.min.js +1 -1
- package/es/cookies/CookiePlugin.js +10 -8
- package/es/cookies/CookiePlugin.js.map +1 -1
- package/es/core/DOMChangesPluginLite.js +226 -248
- package/es/core/DOMChangesPluginLite.js.map +1 -1
- package/es/core/DOMManipulatorLite.js +68 -10
- package/es/core/DOMManipulatorLite.js.map +1 -1
- package/es/core/ExposureTracker.js +136 -11
- package/es/core/ExposureTracker.js.map +1 -1
- package/es/entries/dom-with-overrides-lite.js +3 -0
- package/es/entries/dom-with-overrides-lite.js.map +1 -1
- package/es/index.js +9 -2
- package/es/index.js.map +1 -1
- package/es/overrides/OverridesPlugin.js +2 -2
- package/es/overrides/OverridesPlugin.js.map +1 -1
- package/es/overrides/OverridesPluginLite.js +29 -1
- package/es/overrides/OverridesPluginLite.js.map +1 -1
- package/es/overrides/overridesUtils.js +27 -18
- package/es/overrides/overridesUtils.js.map +1 -1
- package/es/parsers/VariantExtractor.js +80 -67
- package/es/parsers/VariantExtractor.js.map +1 -1
- package/es/url-redirect/URLRedirectExtractor.js +185 -0
- package/es/url-redirect/URLRedirectExtractor.js.map +1 -0
- package/es/url-redirect/URLRedirectMatcher.js +115 -0
- package/es/url-redirect/URLRedirectMatcher.js.map +1 -0
- package/es/url-redirect/URLRedirectPlugin.js +350 -0
- package/es/url-redirect/URLRedirectPlugin.js.map +1 -0
- package/es/url-redirect/index.js +5 -0
- package/es/url-redirect/index.js.map +1 -0
- package/es/url-redirect/types.js +2 -0
- package/es/url-redirect/types.js.map +1 -0
- package/es/utils/persistence.js +278 -0
- package/es/utils/persistence.js.map +1 -0
- package/es/utils/plugin-registry.js +47 -0
- package/es/utils/plugin-registry.js.map +1 -0
- package/es/vitals/WebVitalsPlugin.js +19 -4
- package/es/vitals/WebVitalsPlugin.js.map +1 -1
- package/lib/cookies/CookiePlugin.d.ts +2 -1
- package/lib/cookies/CookiePlugin.js +10 -8
- package/lib/cookies/CookiePlugin.js.map +1 -1
- package/lib/core/DOMChangesPluginLite.d.ts +13 -9
- package/lib/core/DOMChangesPluginLite.js +226 -248
- package/lib/core/DOMChangesPluginLite.js.map +1 -1
- package/lib/core/DOMManipulatorLite.js +68 -10
- package/lib/core/DOMManipulatorLite.js.map +1 -1
- package/lib/core/ExposureTracker.d.ts +6 -0
- package/lib/core/ExposureTracker.js +136 -11
- package/lib/core/ExposureTracker.js.map +1 -1
- package/lib/entries/dom-with-overrides-lite.d.ts +2 -0
- package/lib/entries/dom-with-overrides-lite.js +3 -1
- package/lib/entries/dom-with-overrides-lite.js.map +1 -1
- package/lib/index.d.ts +8 -2
- package/lib/index.js +17 -1
- package/lib/index.js.map +1 -1
- package/lib/overrides/OverridesPlugin.js +2 -2
- package/lib/overrides/OverridesPlugin.js.map +1 -1
- package/lib/overrides/OverridesPluginLite.d.ts +8 -0
- package/lib/overrides/OverridesPluginLite.js +29 -1
- package/lib/overrides/OverridesPluginLite.js.map +1 -1
- package/lib/overrides/overridesUtils.d.ts +10 -5
- package/lib/overrides/overridesUtils.js +28 -18
- package/lib/overrides/overridesUtils.js.map +1 -1
- package/lib/parsers/VariantExtractor.d.ts +4 -5
- package/lib/parsers/VariantExtractor.js +80 -67
- package/lib/parsers/VariantExtractor.js.map +1 -1
- package/lib/types/index.d.ts +5 -12
- package/lib/url-redirect/URLRedirectExtractor.d.ts +16 -0
- package/lib/url-redirect/URLRedirectExtractor.js +188 -0
- package/lib/url-redirect/URLRedirectExtractor.js.map +1 -0
- package/lib/url-redirect/URLRedirectMatcher.d.ts +8 -0
- package/lib/url-redirect/URLRedirectMatcher.js +118 -0
- package/lib/url-redirect/URLRedirectMatcher.js.map +1 -0
- package/lib/url-redirect/URLRedirectPlugin.d.ts +21 -0
- package/lib/url-redirect/URLRedirectPlugin.js +353 -0
- package/lib/url-redirect/URLRedirectPlugin.js.map +1 -0
- package/lib/url-redirect/index.d.ts +4 -0
- package/lib/url-redirect/index.js +25 -0
- package/lib/url-redirect/index.js.map +1 -0
- package/lib/url-redirect/types.d.ts +29 -0
- package/lib/url-redirect/types.js +3 -0
- package/lib/url-redirect/types.js.map +1 -0
- package/lib/utils/persistence.d.ts +23 -0
- package/lib/utils/persistence.js +281 -0
- package/lib/utils/persistence.js.map +1 -0
- package/lib/utils/plugin-registry.d.ts +40 -0
- package/lib/utils/plugin-registry.js +53 -0
- package/lib/utils/plugin-registry.js.map +1 -0
- package/lib/vitals/WebVitalsPlugin.d.ts +2 -0
- package/lib/vitals/WebVitalsPlugin.js +19 -4
- package/lib/vitals/WebVitalsPlugin.js.map +1 -1
- package/package.json +59 -3
- package/types/cookies/CookiePlugin.d.ts +2 -1
- package/types/core/DOMChangesPluginLite.d.ts +13 -9
- package/types/core/ExposureTracker.d.ts +6 -0
- package/types/entries/dom-with-overrides-lite.d.ts +2 -0
- package/types/index.d.ts +8 -2
- package/types/overrides/OverridesPluginLite.d.ts +8 -0
- package/types/overrides/overridesUtils.d.ts +10 -5
- package/types/parsers/VariantExtractor.d.ts +4 -5
- package/types/types/index.d.ts +5 -12
- package/types/url-redirect/URLRedirectExtractor.d.ts +16 -0
- package/types/url-redirect/URLRedirectMatcher.d.ts +8 -0
- package/types/url-redirect/URLRedirectPlugin.d.ts +21 -0
- package/types/url-redirect/index.d.ts +4 -0
- package/types/url-redirect/types.d.ts +29 -0
- package/types/utils/persistence.d.ts +23 -0
- package/types/utils/plugin-registry.d.ts +40 -0
- package/types/vitals/WebVitalsPlugin.d.ts +2 -0
|
@@ -82,19 +82,18 @@ var ExposureTracker_1 = require("./ExposureTracker");
|
|
|
82
82
|
var HTMLInjector_1 = require("./HTMLInjector");
|
|
83
83
|
var debug_1 = require("../utils/debug");
|
|
84
84
|
var URLMatcher_1 = require("../utils/URLMatcher");
|
|
85
|
+
var persistence_1 = require("../utils/persistence");
|
|
86
|
+
var plugin_registry_1 = require("../utils/plugin-registry");
|
|
85
87
|
var DOMChangesPluginLite = /** @class */ (function () {
|
|
86
88
|
function DOMChangesPluginLite(config) {
|
|
87
|
-
var
|
|
89
|
+
var _this = this;
|
|
90
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
88
91
|
this.mutationObserver = null;
|
|
89
92
|
this.exposedExperiments = new Set();
|
|
90
93
|
this.eventListeners = new Map();
|
|
91
94
|
this.styleManagers = new Map();
|
|
92
95
|
this.initialized = false;
|
|
93
|
-
this.
|
|
94
|
-
this.persistenceObserver = null;
|
|
95
|
-
this.reapplyingElements = new Set();
|
|
96
|
-
this.reapplyLogThrottle = new Map();
|
|
97
|
-
this.appliedChanges = new Map();
|
|
96
|
+
this.persistenceManager = null;
|
|
98
97
|
this.antiFlickerTimeout = null;
|
|
99
98
|
this.antiFlickerStyleId = 'absmartly-antiflicker';
|
|
100
99
|
this.config = {
|
|
@@ -102,28 +101,54 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
102
101
|
autoApply: (_a = config.autoApply) !== null && _a !== void 0 ? _a : true,
|
|
103
102
|
spa: (_b = config.spa) !== null && _b !== void 0 ? _b : true,
|
|
104
103
|
visibilityTracking: (_c = config.visibilityTracking) !== null && _c !== void 0 ? _c : true,
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
hideTimeout: (_h = config.hideTimeout) !== null && _h !== void 0 ? _h : 3000,
|
|
111
|
-
hideSelector: (_j = config.hideSelector) !== null && _j !== void 0 ? _j : '[data-absmartly-hide]',
|
|
112
|
-
hideTransition: (_k = config.hideTransition) !== null && _k !== void 0 ? _k : false,
|
|
104
|
+
variableName: (_d = config.variableName) !== null && _d !== void 0 ? _d : '__dom_changes',
|
|
105
|
+
debug: (_e = config.debug) !== null && _e !== void 0 ? _e : false,
|
|
106
|
+
hideUntilReady: (_f = config.hideUntilReady) !== null && _f !== void 0 ? _f : false,
|
|
107
|
+
hideTimeout: (_g = config.hideTimeout) !== null && _g !== void 0 ? _g : 3000,
|
|
108
|
+
hideTransition: (_h = config.hideTransition) !== null && _h !== void 0 ? _h : false,
|
|
113
109
|
};
|
|
114
110
|
if (!this.config.context) {
|
|
115
111
|
throw new Error('[ABsmartly] Context is required');
|
|
116
112
|
}
|
|
117
|
-
|
|
113
|
+
console.log("[ABsmartly] DOMChangesPluginLite v".concat(DOMChangesPluginLite.VERSION, " initialized"));
|
|
118
114
|
if (this.config.hideUntilReady) {
|
|
119
115
|
this.hideContent();
|
|
120
116
|
}
|
|
121
117
|
this.domManipulator = new DOMManipulatorLite_1.DOMManipulatorLite(this.config.debug, this);
|
|
122
|
-
this.variantExtractor = new VariantExtractor_1.VariantExtractor(this.config.context, this.config.
|
|
118
|
+
this.variantExtractor = new VariantExtractor_1.VariantExtractor(this.config.context, this.config.variableName, this.config.debug);
|
|
123
119
|
this.exposureTracker = new ExposureTracker_1.ExposureTracker(this.config.context, this.config.debug);
|
|
124
120
|
this.htmlInjector = new HTMLInjector_1.HTMLInjector(this.config.debug);
|
|
121
|
+
this.persistenceManager = new persistence_1.DOMPersistenceManager({
|
|
122
|
+
debug: this.config.debug,
|
|
123
|
+
onReapply: function (change, experimentName) {
|
|
124
|
+
(0, debug_1.logDebug)('[DOMChangesPluginLite] Re-applying change due to mutation', {
|
|
125
|
+
experimentName: experimentName,
|
|
126
|
+
selector: change.selector,
|
|
127
|
+
type: change.type,
|
|
128
|
+
});
|
|
129
|
+
_this.domManipulator.applyChange(change, experimentName);
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
// Auto-initialize when context is ready
|
|
133
|
+
this.readyPromise = this.config.context
|
|
134
|
+
.ready()
|
|
135
|
+
.then(function () {
|
|
136
|
+
(0, debug_1.logDebug)('[DOMChangesPluginLite] Context is ready, starting initialization');
|
|
137
|
+
return _this.initialize();
|
|
138
|
+
})
|
|
139
|
+
.catch(function (error) {
|
|
140
|
+
(0, debug_1.logDebug)('[DOMChangesPluginLite] ERROR during initialization:', error);
|
|
141
|
+
throw error;
|
|
142
|
+
});
|
|
125
143
|
}
|
|
126
144
|
DOMChangesPluginLite.prototype.ready = function () {
|
|
145
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
146
|
+
return __generator(this, function (_a) {
|
|
147
|
+
return [2 /*return*/, this.readyPromise];
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
DOMChangesPluginLite.prototype.initialize = function () {
|
|
127
152
|
return __awaiter(this, void 0, void 0, function () {
|
|
128
153
|
var startTime, duration, error_1;
|
|
129
154
|
return __generator(this, function (_a) {
|
|
@@ -140,7 +165,6 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
140
165
|
autoApply: this.config.autoApply,
|
|
141
166
|
spa: this.config.spa,
|
|
142
167
|
visibilityTracking: this.config.visibilityTracking,
|
|
143
|
-
dataSource: this.config.dataSource,
|
|
144
168
|
DEBUG: debug_1.DEBUG,
|
|
145
169
|
},
|
|
146
170
|
});
|
|
@@ -148,9 +172,14 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
148
172
|
case 1:
|
|
149
173
|
_a.trys.push([1, 4, , 5]);
|
|
150
174
|
if (this.config.spa) {
|
|
175
|
+
// SPA mode: observe body for React/Vue hydration recovery
|
|
176
|
+
// and listen for URL changes to re-apply changes on navigation
|
|
151
177
|
this.setupMutationObserver();
|
|
152
178
|
this.setupURLChangeListener();
|
|
153
179
|
}
|
|
180
|
+
else {
|
|
181
|
+
(0, debug_1.logDebug)('[DOMChangesPluginLite] SPA mode disabled - skipping body observer');
|
|
182
|
+
}
|
|
154
183
|
if (!this.config.autoApply) return [3 /*break*/, 3];
|
|
155
184
|
// Apply HTML injections and DOM changes in parallel to minimize flickering
|
|
156
185
|
return [4 /*yield*/, this.applyInjectionsAndChanges()];
|
|
@@ -161,6 +190,7 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
161
190
|
case 3:
|
|
162
191
|
this.initialized = true;
|
|
163
192
|
this.registerWithContext();
|
|
193
|
+
this.registerGlobally();
|
|
164
194
|
this.emit('initialized');
|
|
165
195
|
duration = performance.now() - startTime;
|
|
166
196
|
(0, debug_1.logPerformance)('Plugin initialization', duration);
|
|
@@ -178,13 +208,6 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
178
208
|
});
|
|
179
209
|
});
|
|
180
210
|
};
|
|
181
|
-
DOMChangesPluginLite.prototype.initialize = function () {
|
|
182
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
183
|
-
return __generator(this, function (_a) {
|
|
184
|
-
return [2 /*return*/, this.ready()];
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
};
|
|
188
211
|
DOMChangesPluginLite.prototype.setupMutationObserver = function () {
|
|
189
212
|
var _this = this;
|
|
190
213
|
var observer = new MutationObserver(function (mutations) {
|
|
@@ -193,10 +216,12 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
193
216
|
if (mutation.type === 'childList') {
|
|
194
217
|
// Check if any added nodes match our applied change selectors
|
|
195
218
|
mutation.addedNodes.forEach(function (node) {
|
|
219
|
+
var _a;
|
|
196
220
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
197
221
|
var element_1 = node;
|
|
198
222
|
// Check all experiments with applied changes (not just style changes)
|
|
199
|
-
_this.
|
|
223
|
+
var appliedChanges = ((_a = _this.persistenceManager) === null || _a === void 0 ? void 0 : _a.getAppliedChanges()) || new Map();
|
|
224
|
+
appliedChanges.forEach(function (changes, experimentName) {
|
|
200
225
|
changes.forEach(function (change) {
|
|
201
226
|
try {
|
|
202
227
|
// Check if this new element or any of its descendants match the selector
|
|
@@ -226,11 +251,30 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
226
251
|
}
|
|
227
252
|
});
|
|
228
253
|
});
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
254
|
+
// Wait for document.body to exist before observing
|
|
255
|
+
// This prevents "parameter 1 is not of type 'Node'" errors when SDK loads in <head>
|
|
256
|
+
var startObserving = function () {
|
|
257
|
+
observer.observe(document.body, {
|
|
258
|
+
childList: true,
|
|
259
|
+
subtree: true,
|
|
260
|
+
});
|
|
261
|
+
_this.mutationObserver = observer;
|
|
262
|
+
(0, debug_1.logDebug)('[DOMChangesPluginLite] MutationObserver started on document.body');
|
|
263
|
+
};
|
|
264
|
+
if (document.body) {
|
|
265
|
+
startObserving();
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
// Use MutationObserver on documentElement to detect when body is added
|
|
269
|
+
var bodyObserver = new MutationObserver(function (_mutations, obs) {
|
|
270
|
+
if (document.body) {
|
|
271
|
+
obs.disconnect();
|
|
272
|
+
startObserving();
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
bodyObserver.observe(document.documentElement, { childList: true });
|
|
276
|
+
(0, debug_1.logDebug)('[DOMChangesPluginLite] Waiting for document.body...');
|
|
277
|
+
}
|
|
234
278
|
};
|
|
235
279
|
/**
|
|
236
280
|
* Set up URL change listener for SPA mode
|
|
@@ -297,7 +341,9 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
297
341
|
// The stylesheets will be reused or cleared on next applyChanges
|
|
298
342
|
this.styleManagers.clear();
|
|
299
343
|
// Clear applied changes
|
|
300
|
-
this.
|
|
344
|
+
if (this.persistenceManager) {
|
|
345
|
+
this.persistenceManager.clearAll();
|
|
346
|
+
}
|
|
301
347
|
// Clear HTML injections
|
|
302
348
|
this.htmlInjector.destroy();
|
|
303
349
|
// Clear variant extractor cache to force re-extraction
|
|
@@ -414,22 +460,46 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
414
460
|
allExperiments = this.getAllExperimentsData();
|
|
415
461
|
totalApplied = 0;
|
|
416
462
|
experimentStats = new Map();
|
|
417
|
-
(0, debug_1.logDebug)('[
|
|
418
|
-
|
|
463
|
+
(0, debug_1.logDebug)('[APPLY-CHANGES] Experiments found with DOM changes:', {
|
|
464
|
+
experimentNames: Array.from(allExperiments.keys()),
|
|
465
|
+
totalCount: allExperiments.size,
|
|
466
|
+
currentURL: currentURL,
|
|
467
|
+
});
|
|
468
|
+
if (allExperiments.size === 0) {
|
|
469
|
+
(0, debug_1.logDebug)('[APPLY-CHANGES] ⚠️ No experiments found with DOM changes - nothing to process');
|
|
470
|
+
}
|
|
419
471
|
try {
|
|
420
472
|
for (allExperiments_1 = __values(allExperiments), allExperiments_1_1 = allExperiments_1.next(); !allExperiments_1_1.done; allExperiments_1_1 = allExperiments_1.next()) {
|
|
421
473
|
_a = __read(allExperiments_1_1.value, 2), expName = _a[0], experimentData = _a[1];
|
|
474
|
+
(0, debug_1.logDebug)("[APPLY-CHANGES] [".concat(expName, "] Starting to process experiment"), {
|
|
475
|
+
experimentName: expName,
|
|
476
|
+
currentURL: currentURL,
|
|
477
|
+
});
|
|
422
478
|
// Skip if filtering by specific experiment
|
|
423
479
|
if (experimentName && expName !== experimentName) {
|
|
480
|
+
(0, debug_1.logDebug)("[APPLY-CHANGES] [".concat(expName, "] \u23ED\uFE0F Skipping - filtering for different experiment"), {
|
|
481
|
+
filteringFor: experimentName,
|
|
482
|
+
});
|
|
424
483
|
continue;
|
|
425
484
|
}
|
|
426
485
|
currentVariant = this.config.context.peek(expName);
|
|
486
|
+
if (currentVariant === undefined || currentVariant === null) {
|
|
487
|
+
(0, debug_1.logDebug)("[APPLY-CHANGES] [".concat(expName, "] \u23ED\uFE0F Skipping - no variant assigned (peek returned ").concat(currentVariant, ")"), {
|
|
488
|
+
experimentName: expName,
|
|
489
|
+
});
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
492
|
+
(0, debug_1.logDebug)("[APPLY-CHANGES] [".concat(expName, "] User assigned to variant ").concat(currentVariant));
|
|
427
493
|
variantData = experimentData.variantData, urlFilter = experimentData.urlFilter, globalDefaults = experimentData.globalDefaults;
|
|
428
494
|
anyVariantMatchesURL = this.variantExtractor.anyVariantMatchesURL(expName, currentURL);
|
|
429
495
|
if (!anyVariantMatchesURL) {
|
|
430
|
-
(0, debug_1.logDebug)("[
|
|
496
|
+
(0, debug_1.logDebug)("[APPLY-CHANGES] [".concat(expName, "] \u23ED\uFE0F Skipping - no variant matches URL: ").concat(currentURL), {
|
|
497
|
+
experimentName: expName,
|
|
498
|
+
currentURL: currentURL,
|
|
499
|
+
});
|
|
431
500
|
continue;
|
|
432
501
|
}
|
|
502
|
+
(0, debug_1.logDebug)("[APPLY-CHANGES] [".concat(expName, "] \u2713 At least one variant matches current URL"));
|
|
433
503
|
shouldApplyVisualChanges = this.shouldApplyVisualChanges(variantData, urlFilter, currentURL);
|
|
434
504
|
changes = this.extractChangesFromData(variantData, globalDefaults);
|
|
435
505
|
allVariantChanges = this.extractAllVariantChanges(expName);
|
|
@@ -443,7 +513,9 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
443
513
|
}
|
|
444
514
|
stats = { total: (changes === null || changes === void 0 ? void 0 : changes.length) || 0, success: 0, pending: 0 };
|
|
445
515
|
if (this.config.debug) {
|
|
446
|
-
(0, debug_1.logDebug)("[ABsmartly] Processing experiment '".concat(expName, "'
|
|
516
|
+
(0, debug_1.logDebug)("[ABsmartly] Processing experiment '".concat(expName, "' - User is in variant ").concat(currentVariant, ":"), {
|
|
517
|
+
experimentName: expName,
|
|
518
|
+
userVariant: currentVariant,
|
|
447
519
|
urlMatches: shouldApplyVisualChanges,
|
|
448
520
|
changeCount: (changes === null || changes === void 0 ? void 0 : changes.length) || 0,
|
|
449
521
|
userVariantHasChanges: ((changes === null || changes === void 0 ? void 0 : changes.length) || 0) > 0,
|
|
@@ -454,11 +526,28 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
454
526
|
}); })) || [],
|
|
455
527
|
});
|
|
456
528
|
}
|
|
529
|
+
// Log if user is in control variant (no changes)
|
|
530
|
+
if (!changes || changes.length === 0) {
|
|
531
|
+
if (this.config.debug) {
|
|
532
|
+
(0, debug_1.logDebug)("[ABsmartly] User is in control variant ".concat(currentVariant, " with no changes, but will still track for SRM prevention"), {
|
|
533
|
+
experimentName: expName,
|
|
534
|
+
currentVariant: currentVariant,
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
}
|
|
457
538
|
// Apply visual changes only if URL matches for user's variant AND user has changes
|
|
458
539
|
if (shouldApplyVisualChanges && changes && changes.length > 0) {
|
|
459
540
|
try {
|
|
460
541
|
for (changes_1 = (e_2 = void 0, __values(changes)), changes_1_1 = changes_1.next(); !changes_1_1.done; changes_1_1 = changes_1.next()) {
|
|
461
542
|
change = changes_1_1.value;
|
|
543
|
+
// Skip delete changes with viewport triggers - they must be applied AFTER exposure
|
|
544
|
+
// Otherwise the element is removed before it can be observed
|
|
545
|
+
if (change.type === 'delete' && change.trigger_on_view) {
|
|
546
|
+
if (this.config.debug) {
|
|
547
|
+
(0, debug_1.logDebug)("[ABsmartly] Deferring delete change until after viewport trigger for '".concat(expName, "'"), { selector: change.selector });
|
|
548
|
+
}
|
|
549
|
+
continue;
|
|
550
|
+
}
|
|
462
551
|
success = this.domManipulator.applyChange(change, expName);
|
|
463
552
|
if (success) {
|
|
464
553
|
totalApplied++;
|
|
@@ -576,14 +665,41 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
576
665
|
finally { if (e_3) throw e_3.error; }
|
|
577
666
|
}
|
|
578
667
|
if (this.config.debug) {
|
|
579
|
-
(0, debug_1.logDebug)("[
|
|
668
|
+
(0, debug_1.logDebug)("[TRIGGER-DETECTION] [".concat(expName, "] Final trigger decision for '").concat(expName, "':"), {
|
|
669
|
+
experimentName: expName,
|
|
670
|
+
userVariant: currentVariant,
|
|
671
|
+
hasImmediateTrigger: hasAnyImmediateTriggerInAnyVariant,
|
|
672
|
+
hasViewportTrigger: hasAnyViewportTriggerInAnyVariant,
|
|
673
|
+
willRegisterExperiment: hasAnyViewportTriggerInAnyVariant || hasAnyImmediateTriggerInAnyVariant,
|
|
674
|
+
userChangesCount: (changes === null || changes === void 0 ? void 0 : changes.length) || 0,
|
|
675
|
+
allVariantsChangesCount: allVariantChanges.map(function (vc) { return vc.length; }),
|
|
676
|
+
});
|
|
580
677
|
}
|
|
581
678
|
// CRITICAL: Always register experiment for tracking if ANY variant has ANY trigger type
|
|
582
679
|
// This prevents SRM even when user's variant doesn't match URL filter
|
|
583
680
|
// Pass the URL-filtered trigger flags to ExposureTracker
|
|
584
681
|
if (hasAnyViewportTriggerInAnyVariant || hasAnyImmediateTriggerInAnyVariant) {
|
|
682
|
+
(0, debug_1.logDebug)("[TRIGGER-DETECTION] [".concat(expName, "] \u2713 REGISTERING EXPERIMENT - Calling exposureTracker.registerExperiment()"), {
|
|
683
|
+
experimentName: expName,
|
|
684
|
+
userVariant: currentVariant,
|
|
685
|
+
hasImmediateTrigger: hasAnyImmediateTriggerInAnyVariant,
|
|
686
|
+
hasViewportTrigger: hasAnyViewportTriggerInAnyVariant,
|
|
687
|
+
changesForUser: (changes === null || changes === void 0 ? void 0 : changes.length) || 0,
|
|
688
|
+
allVariantCounts: allVariantChanges.map(function (vc, idx) { return ({
|
|
689
|
+
variant: idx,
|
|
690
|
+
count: vc.length,
|
|
691
|
+
}); }),
|
|
692
|
+
});
|
|
585
693
|
this.exposureTracker.registerExperiment(expName, currentVariant || 0, changes || [], allVariantChanges, hasAnyImmediateTriggerInAnyVariant, hasAnyViewportTriggerInAnyVariant);
|
|
586
694
|
}
|
|
695
|
+
else {
|
|
696
|
+
(0, debug_1.logDebug)("[TRIGGER-DETECTION] [".concat(expName, "] \u26A0\uFE0F No triggers detected - experiment will NOT be registered!"), {
|
|
697
|
+
experimentName: expName,
|
|
698
|
+
userVariant: currentVariant,
|
|
699
|
+
hasAnyChangesInAnyVariant: hasAnyChangesInAnyVariant,
|
|
700
|
+
allVariantsChangesCount: allVariantChanges.map(function (vc) { return vc.length; }),
|
|
701
|
+
});
|
|
702
|
+
}
|
|
587
703
|
// Note: We do NOT call treatment() here anymore to avoid duplicate calls.
|
|
588
704
|
// The ExposureTracker.registerExperiment() will call triggerExposure() internally
|
|
589
705
|
// when hasImmediateTrigger is true (see ExposureTracker line 169-174).
|
|
@@ -639,18 +755,43 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
639
755
|
var e_5, _a;
|
|
640
756
|
var experiments = new Map();
|
|
641
757
|
var allVariants = this.variantExtractor.extractAllChanges();
|
|
758
|
+
(0, debug_1.logDebug)('[GET-EXPERIMENTS] Extracting experiment data from context', {
|
|
759
|
+
experimentsWithChanges: Array.from(allVariants.keys()),
|
|
760
|
+
totalCount: allVariants.size,
|
|
761
|
+
});
|
|
642
762
|
try {
|
|
643
763
|
for (var allVariants_1 = __values(allVariants), allVariants_1_1 = allVariants_1.next(); !allVariants_1_1.done; allVariants_1_1 = allVariants_1.next()) {
|
|
644
764
|
var _b = __read(allVariants_1_1.value, 1), expName = _b[0];
|
|
645
765
|
var currentVariant = this.config.context.peek(expName);
|
|
766
|
+
(0, debug_1.logDebug)("[GET-EXPERIMENTS] [".concat(expName, "] Checking experiment"), {
|
|
767
|
+
experimentName: expName,
|
|
768
|
+
currentVariant: currentVariant,
|
|
769
|
+
variantIsValid: currentVariant !== undefined && currentVariant !== null,
|
|
770
|
+
});
|
|
646
771
|
if (currentVariant === undefined || currentVariant === null) {
|
|
772
|
+
(0, debug_1.logDebug)("[GET-EXPERIMENTS] [".concat(expName, "] \u23ED\uFE0F Skipping - context.peek() returned ").concat(currentVariant));
|
|
647
773
|
continue;
|
|
648
774
|
}
|
|
649
775
|
var variantsData = this.variantExtractor.getAllVariantsData(expName);
|
|
650
776
|
var variantData = variantsData.get(currentVariant);
|
|
777
|
+
if (this.config.debug) {
|
|
778
|
+
(0, debug_1.logDebug)("[GET-EXPERIMENTS] [".concat(expName, "] Variant data lookup:"), {
|
|
779
|
+
experimentName: expName,
|
|
780
|
+
userVariant: currentVariant,
|
|
781
|
+
variantDataExists: !!variantData,
|
|
782
|
+
allVariantsInMap: Array.from(variantsData.keys()),
|
|
783
|
+
userVariantInMap: variantsData.has(currentVariant),
|
|
784
|
+
});
|
|
785
|
+
}
|
|
651
786
|
if (!variantData) {
|
|
652
|
-
|
|
787
|
+
(0, debug_1.logDebug)("[GET-EXPERIMENTS] [".concat(expName, "] \u26A0\uFE0F User's variant ").concat(currentVariant, " has no DOM changes (control variant)"), {
|
|
788
|
+
availableVariants: Array.from(variantsData.keys()),
|
|
789
|
+
note: 'Will still track for SRM prevention',
|
|
790
|
+
});
|
|
791
|
+
// Don't skip! Include experiments even if user's variant has no changes
|
|
792
|
+
// This is critical for SRM prevention - we need to track ALL experiments
|
|
653
793
|
}
|
|
794
|
+
(0, debug_1.logDebug)("[GET-EXPERIMENTS] [".concat(expName, "] \u2713 Including experiment (variant ").concat(currentVariant, ")"));
|
|
654
795
|
// Extract URL filter and global defaults if using wrapped format
|
|
655
796
|
var urlFilter = null;
|
|
656
797
|
var globalDefaults = {};
|
|
@@ -683,12 +824,15 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
683
824
|
* Extract changes from DOMChangesData and apply global defaults
|
|
684
825
|
*/
|
|
685
826
|
DOMChangesPluginLite.prototype.extractChangesFromData = function (data, globalDefaults) {
|
|
827
|
+
if (!data) {
|
|
828
|
+
return null;
|
|
829
|
+
}
|
|
686
830
|
var changes = null;
|
|
687
831
|
// Extract changes array
|
|
688
832
|
if (Array.isArray(data)) {
|
|
689
833
|
changes = data;
|
|
690
834
|
}
|
|
691
|
-
else if (
|
|
835
|
+
else if (typeof data === 'object' && 'changes' in data) {
|
|
692
836
|
changes = data.changes;
|
|
693
837
|
}
|
|
694
838
|
if (!changes || changes.length === 0) {
|
|
@@ -745,6 +889,10 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
745
889
|
* Determine if visual changes should be applied based on URL filter
|
|
746
890
|
*/
|
|
747
891
|
DOMChangesPluginLite.prototype.shouldApplyVisualChanges = function (variantData, urlFilter, url) {
|
|
892
|
+
// No data for this variant - no changes to apply
|
|
893
|
+
if (!variantData) {
|
|
894
|
+
return false;
|
|
895
|
+
}
|
|
748
896
|
// Legacy array format has no URL filter - always apply
|
|
749
897
|
if (Array.isArray(variantData)) {
|
|
750
898
|
return true;
|
|
@@ -878,9 +1026,9 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
878
1026
|
this.mutationObserver.disconnect();
|
|
879
1027
|
this.mutationObserver = null;
|
|
880
1028
|
}
|
|
881
|
-
if (this.
|
|
882
|
-
this.
|
|
883
|
-
this.
|
|
1029
|
+
if (this.persistenceManager) {
|
|
1030
|
+
this.persistenceManager.destroy();
|
|
1031
|
+
this.persistenceManager = null;
|
|
884
1032
|
}
|
|
885
1033
|
// Clean up anti-flicker timeout and style
|
|
886
1034
|
if (this.antiFlickerTimeout !== null) {
|
|
@@ -893,11 +1041,8 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
893
1041
|
}
|
|
894
1042
|
this.eventListeners.clear();
|
|
895
1043
|
this.exposedExperiments.clear();
|
|
896
|
-
this.watchedElements = new WeakMap();
|
|
897
|
-
this.appliedChanges.clear();
|
|
898
|
-
this.reapplyingElements.clear();
|
|
899
|
-
this.reapplyLogThrottle.clear();
|
|
900
1044
|
this.unregisterFromContext();
|
|
1045
|
+
this.unregisterGlobally();
|
|
901
1046
|
this.initialized = false;
|
|
902
1047
|
if (this.config.debug) {
|
|
903
1048
|
(0, debug_1.logDebug)('[ABsmartly] DOM Changes Plugin Lite destroyed');
|
|
@@ -936,13 +1081,38 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
936
1081
|
}
|
|
937
1082
|
}
|
|
938
1083
|
};
|
|
1084
|
+
/**
|
|
1085
|
+
* Register plugin in global registry for detection
|
|
1086
|
+
*/
|
|
1087
|
+
DOMChangesPluginLite.prototype.registerGlobally = function () {
|
|
1088
|
+
(0, plugin_registry_1.registerPlugin)('dom', {
|
|
1089
|
+
name: 'DOMChangesPluginLite',
|
|
1090
|
+
version: DOMChangesPluginLite.VERSION,
|
|
1091
|
+
initialized: true,
|
|
1092
|
+
timestamp: Date.now(),
|
|
1093
|
+
capabilities: ['spa', 'visibility', 'auto-apply'],
|
|
1094
|
+
instance: this,
|
|
1095
|
+
});
|
|
1096
|
+
if (this.config.debug) {
|
|
1097
|
+
(0, debug_1.logDebug)('[ABsmartly] DOMChangesPluginLite registered in global window.__ABSMARTLY_PLUGINS__');
|
|
1098
|
+
}
|
|
1099
|
+
};
|
|
1100
|
+
/**
|
|
1101
|
+
* Unregister plugin from global registry
|
|
1102
|
+
*/
|
|
1103
|
+
DOMChangesPluginLite.prototype.unregisterGlobally = function () {
|
|
1104
|
+
(0, plugin_registry_1.unregisterPlugin)('dom');
|
|
1105
|
+
if (this.config.debug) {
|
|
1106
|
+
(0, debug_1.logDebug)('[ABsmartly] DOMChangesPluginLite unregistered from global registry');
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
939
1109
|
/**
|
|
940
1110
|
* Hide content to prevent flicker before experiments are applied
|
|
941
1111
|
*/
|
|
942
1112
|
DOMChangesPluginLite.prototype.hideContent = function () {
|
|
943
1113
|
var _this = this;
|
|
944
|
-
var
|
|
945
|
-
if (!
|
|
1114
|
+
var selector = this.config.hideUntilReady;
|
|
1115
|
+
if (!selector)
|
|
946
1116
|
return;
|
|
947
1117
|
// Check if style already exists (prevent duplicate injection)
|
|
948
1118
|
if (document.getElementById(this.antiFlickerStyleId)) {
|
|
@@ -951,7 +1121,6 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
951
1121
|
var style = document.createElement('style');
|
|
952
1122
|
style.id = this.antiFlickerStyleId;
|
|
953
1123
|
var hasTransition = this.config.hideTransition !== false;
|
|
954
|
-
var selector = mode === 'body' ? 'body' : this.config.hideSelector || '[data-absmartly-hide]';
|
|
955
1124
|
if (hasTransition) {
|
|
956
1125
|
// Use both visibility:hidden and opacity:0 for smooth transition
|
|
957
1126
|
style.textContent = "\n ".concat(selector, " {\n visibility: hidden !important;\n opacity: 0 !important;\n }\n ");
|
|
@@ -961,7 +1130,7 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
961
1130
|
style.textContent = "\n ".concat(selector, " {\n visibility: hidden !important;\n }\n ");
|
|
962
1131
|
}
|
|
963
1132
|
document.head.appendChild(style);
|
|
964
|
-
// Set timeout to show content even if experiments fail to load
|
|
1133
|
+
// Set timeout to show content even if experiments fail to load or timeout expires
|
|
965
1134
|
this.antiFlickerTimeout = window.setTimeout(function () {
|
|
966
1135
|
if (_this.config.debug) {
|
|
967
1136
|
(0, debug_1.logDebug)("[ABsmartly] Anti-flicker timeout reached (".concat(_this.config.hideTimeout, "ms), showing content"));
|
|
@@ -969,11 +1138,11 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
969
1138
|
_this.showContent();
|
|
970
1139
|
}, this.config.hideTimeout);
|
|
971
1140
|
if (this.config.debug) {
|
|
972
|
-
(0, debug_1.logDebug)("[ABsmartly] Anti-flicker enabled (
|
|
1141
|
+
(0, debug_1.logDebug)("[ABsmartly] Anti-flicker enabled (selector: '".concat(selector, "', transition: ").concat(hasTransition ? this.config.hideTransition : 'none', ", timeout: ").concat(this.config.hideTimeout, "ms)"));
|
|
973
1142
|
}
|
|
974
1143
|
};
|
|
975
1144
|
/**
|
|
976
|
-
* Show hidden content after experiments are applied
|
|
1145
|
+
* Show hidden content after experiments are applied or timeout expires
|
|
977
1146
|
*/
|
|
978
1147
|
DOMChangesPluginLite.prototype.showContent = function () {
|
|
979
1148
|
var _this = this;
|
|
@@ -988,8 +1157,7 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
988
1157
|
var hasTransition = this.config.hideTransition !== false;
|
|
989
1158
|
if (hasTransition) {
|
|
990
1159
|
// Smooth fade-in: remove visibility, add transition, then animate opacity
|
|
991
|
-
var
|
|
992
|
-
var selector = mode === 'body' ? 'body' : this.config.hideSelector || '[data-absmartly-hide]';
|
|
1160
|
+
var selector = this.config.hideUntilReady;
|
|
993
1161
|
// Step 1: Remove visibility:hidden, keep opacity:0, add transition
|
|
994
1162
|
style.textContent = "\n ".concat(selector, " {\n opacity: 0 !important;\n transition: opacity ").concat(this.config.hideTransition, " !important;\n }\n ");
|
|
995
1163
|
// Step 2: Force reflow to ensure transition applies
|
|
@@ -1017,206 +1185,16 @@ var DOMChangesPluginLite = /** @class */ (function () {
|
|
|
1017
1185
|
}
|
|
1018
1186
|
};
|
|
1019
1187
|
DOMChangesPluginLite.prototype.watchElement = function (element, experimentName, change) {
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
experiments = new Set();
|
|
1023
|
-
this.watchedElements.set(element, experiments);
|
|
1024
|
-
}
|
|
1025
|
-
experiments.add(experimentName);
|
|
1026
|
-
// Store the applied change for this experiment (ALL types: style, class, attribute, html, text, etc.)
|
|
1027
|
-
if (!this.appliedChanges.has(experimentName)) {
|
|
1028
|
-
this.appliedChanges.set(experimentName, []);
|
|
1029
|
-
}
|
|
1030
|
-
var changes = this.appliedChanges.get(experimentName);
|
|
1031
|
-
var isNewWatch = !changes.includes(change);
|
|
1032
|
-
if (isNewWatch) {
|
|
1033
|
-
changes.push(change);
|
|
1034
|
-
// Only log when actually adding a new watch, not on every reapply
|
|
1035
|
-
if (this.config.debug) {
|
|
1036
|
-
var currentStyles_1 = {};
|
|
1037
|
-
if (change.value && typeof change.value === 'object') {
|
|
1038
|
-
Object.keys(change.value).forEach(function (prop) {
|
|
1039
|
-
var cssProp = prop.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
1040
|
-
currentStyles_1[cssProp] = element.style.getPropertyValue(cssProp);
|
|
1041
|
-
});
|
|
1042
|
-
}
|
|
1043
|
-
(0, debug_1.logDebug)('[WATCH-ELEMENT] Started watching element for persistence/hydration recovery', {
|
|
1044
|
-
experimentName: experimentName,
|
|
1045
|
-
selector: change.selector,
|
|
1046
|
-
element: element.tagName,
|
|
1047
|
-
changeType: change.type,
|
|
1048
|
-
value: change.value,
|
|
1049
|
-
currentStyles: change.type === 'style' ? currentStyles_1 : undefined,
|
|
1050
|
-
timestamp: Date.now(),
|
|
1051
|
-
});
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
|
-
if (!this.persistenceObserver) {
|
|
1055
|
-
this.setupPersistenceObserver();
|
|
1188
|
+
if (this.persistenceManager) {
|
|
1189
|
+
this.persistenceManager.watchElement(element, experimentName, change);
|
|
1056
1190
|
}
|
|
1057
1191
|
};
|
|
1058
1192
|
DOMChangesPluginLite.prototype.unwatchElement = function (element, experimentName) {
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
experiments.delete(experimentName);
|
|
1062
|
-
if (experiments.size === 0) {
|
|
1063
|
-
this.watchedElements.delete(element);
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
};
|
|
1067
|
-
DOMChangesPluginLite.prototype.setupPersistenceObserver = function () {
|
|
1068
|
-
var _this = this;
|
|
1069
|
-
if (this.persistenceObserver)
|
|
1070
|
-
return;
|
|
1071
|
-
if (this.config.debug) {
|
|
1072
|
-
(0, debug_1.logDebug)('[PERSISTENCE-OBSERVER] Setting up persistence observer', {
|
|
1073
|
-
timestamp: Date.now(),
|
|
1074
|
-
watchedElementsCount: this.watchedElements ? 'has WeakMap' : 'no WeakMap',
|
|
1075
|
-
});
|
|
1076
|
-
}
|
|
1077
|
-
this.persistenceObserver = new MutationObserver(function (mutations) {
|
|
1078
|
-
if (_this.config.debug) {
|
|
1079
|
-
(0, debug_1.logDebug)('[MUTATION-DETECTED] Persistence observer detected mutations', {
|
|
1080
|
-
mutationCount: mutations.length,
|
|
1081
|
-
timestamp: Date.now(),
|
|
1082
|
-
mutations: mutations.map(function (m) {
|
|
1083
|
-
var _a;
|
|
1084
|
-
return ({
|
|
1085
|
-
target: m.target.tagName,
|
|
1086
|
-
oldValue: (_a = m.oldValue) === null || _a === void 0 ? void 0 : _a.substring(0, 100),
|
|
1087
|
-
});
|
|
1088
|
-
}),
|
|
1089
|
-
});
|
|
1090
|
-
}
|
|
1091
|
-
mutations.forEach(function (mutation) {
|
|
1092
|
-
var element = mutation.target;
|
|
1093
|
-
if (_this.reapplyingElements.has(element)) {
|
|
1094
|
-
if (_this.config.debug) {
|
|
1095
|
-
(0, debug_1.logDebug)('[MUTATION-SKIP] Skipping mutation - currently reapplying', {
|
|
1096
|
-
element: element.tagName,
|
|
1097
|
-
});
|
|
1098
|
-
}
|
|
1099
|
-
return;
|
|
1100
|
-
}
|
|
1101
|
-
var experiments = _this.watchedElements.get(element);
|
|
1102
|
-
if (experiments) {
|
|
1103
|
-
// Throttle mutation detection logs to once per 5 seconds per element
|
|
1104
|
-
if (_this.config.debug) {
|
|
1105
|
-
var elementKey = "mutation:".concat(element.tagName, ":").concat(element.getAttribute('name') || element.className);
|
|
1106
|
-
var now = Date.now();
|
|
1107
|
-
var lastLogged = _this.reapplyLogThrottle.get(elementKey) || 0;
|
|
1108
|
-
if (now - lastLogged > 5000) {
|
|
1109
|
-
(0, debug_1.logDebug)('[MUTATION-ON-WATCHED] Style mutation detected on watched element', {
|
|
1110
|
-
element: element.tagName,
|
|
1111
|
-
selector: element.getAttribute('name') || element.className,
|
|
1112
|
-
oldValue: mutation.oldValue,
|
|
1113
|
-
newValue: element.getAttribute('style'),
|
|
1114
|
-
experiments: Array.from(experiments),
|
|
1115
|
-
});
|
|
1116
|
-
_this.reapplyLogThrottle.set(elementKey, now);
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
experiments.forEach(function (experimentName) {
|
|
1120
|
-
var appliedChanges = _this.appliedChanges.get(experimentName);
|
|
1121
|
-
if (appliedChanges) {
|
|
1122
|
-
appliedChanges.forEach(function (change) {
|
|
1123
|
-
var e_7, _a;
|
|
1124
|
-
// Skip the .matches() check - we already know this element should have this change
|
|
1125
|
-
// because we added it to watchedElements when we applied it successfully.
|
|
1126
|
-
// The .matches() check fails for complex selectors with parent relationships (e.g., "div > p")
|
|
1127
|
-
if (change.type === 'style') {
|
|
1128
|
-
var needsReapply = _this.checkStyleOverwritten(element, change.value);
|
|
1129
|
-
if (needsReapply) {
|
|
1130
|
-
_this.reapplyingElements.add(element);
|
|
1131
|
-
var logKey = "".concat(experimentName, "-").concat(change.selector);
|
|
1132
|
-
var now = Date.now();
|
|
1133
|
-
var lastLogged = _this.reapplyLogThrottle.get(logKey) || 0;
|
|
1134
|
-
if (_this.config.debug && now - lastLogged > 5000) {
|
|
1135
|
-
(0, debug_1.logDebug)('[REAPPLY-TRIGGERED] Reapplying style after mutation (React/framework conflict detected)', {
|
|
1136
|
-
experimentName: experimentName,
|
|
1137
|
-
selector: change.selector,
|
|
1138
|
-
element: element.tagName,
|
|
1139
|
-
timestamp: now,
|
|
1140
|
-
note: 'This happens when the page framework (React/Vue/etc) fights with DOM changes',
|
|
1141
|
-
});
|
|
1142
|
-
_this.reapplyLogThrottle.set(logKey, now);
|
|
1143
|
-
// Cleanup old throttle entries to prevent memory leak
|
|
1144
|
-
if (_this.reapplyLogThrottle.size > 100) {
|
|
1145
|
-
var oldestAllowed = now - 60000; // 1 minute
|
|
1146
|
-
try {
|
|
1147
|
-
for (var _b = __values(_this.reapplyLogThrottle.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
1148
|
-
var _d = __read(_c.value, 2), key = _d[0], time = _d[1];
|
|
1149
|
-
if (time < oldestAllowed) {
|
|
1150
|
-
_this.reapplyLogThrottle.delete(key);
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
1155
|
-
finally {
|
|
1156
|
-
try {
|
|
1157
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
1158
|
-
}
|
|
1159
|
-
finally { if (e_7) throw e_7.error; }
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1163
|
-
_this.domManipulator.applyChange(change, experimentName);
|
|
1164
|
-
setTimeout(function () {
|
|
1165
|
-
_this.reapplyingElements.delete(element);
|
|
1166
|
-
}, 0);
|
|
1167
|
-
}
|
|
1168
|
-
else if (_this.config.debug) {
|
|
1169
|
-
(0, debug_1.logDebug)('[MUTATION-NO-REAPPLY] Style mutation detected but no reapply needed', {
|
|
1170
|
-
experimentName: experimentName,
|
|
1171
|
-
selector: change.selector,
|
|
1172
|
-
});
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
});
|
|
1176
|
-
}
|
|
1177
|
-
});
|
|
1178
|
-
}
|
|
1179
|
-
});
|
|
1180
|
-
});
|
|
1181
|
-
this.persistenceObserver.observe(document.body, {
|
|
1182
|
-
attributes: true,
|
|
1183
|
-
attributeFilter: ['style'],
|
|
1184
|
-
subtree: true,
|
|
1185
|
-
attributeOldValue: true,
|
|
1186
|
-
});
|
|
1187
|
-
if (this.config.debug) {
|
|
1188
|
-
(0, debug_1.logDebug)('[PERSISTENCE-OBSERVER] Setup complete - now observing style mutations', {
|
|
1189
|
-
target: 'document.body',
|
|
1190
|
-
attributeFilter: ['style'],
|
|
1191
|
-
subtree: true,
|
|
1192
|
-
attributeOldValue: true,
|
|
1193
|
-
timestamp: Date.now(),
|
|
1194
|
-
});
|
|
1195
|
-
}
|
|
1196
|
-
};
|
|
1197
|
-
DOMChangesPluginLite.prototype.checkStyleOverwritten = function (element, expectedStyles) {
|
|
1198
|
-
var e_8, _a;
|
|
1199
|
-
try {
|
|
1200
|
-
for (var _b = __values(Object.entries(expectedStyles)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
1201
|
-
var _d = __read(_c.value, 2), prop = _d[0], value = _d[1];
|
|
1202
|
-
var cssProp = prop.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
1203
|
-
var currentValue = element.style.getPropertyValue(cssProp);
|
|
1204
|
-
var currentPriority = element.style.getPropertyPriority(cssProp);
|
|
1205
|
-
if (currentValue !== value || (value.includes('!important') && !currentPriority)) {
|
|
1206
|
-
return true;
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1210
|
-
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
1211
|
-
finally {
|
|
1212
|
-
try {
|
|
1213
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
1214
|
-
}
|
|
1215
|
-
finally { if (e_8) throw e_8.error; }
|
|
1193
|
+
if (this.persistenceManager) {
|
|
1194
|
+
this.persistenceManager.unwatchElement(element, experimentName);
|
|
1216
1195
|
}
|
|
1217
|
-
return false;
|
|
1218
1196
|
};
|
|
1219
|
-
DOMChangesPluginLite.VERSION = '1.
|
|
1197
|
+
DOMChangesPluginLite.VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : '1.1.2';
|
|
1220
1198
|
return DOMChangesPluginLite;
|
|
1221
1199
|
}());
|
|
1222
1200
|
exports.DOMChangesPluginLite = DOMChangesPluginLite;
|