Skip to content

Commit fa41a27

Browse files
committed
AG-54728 Fix 'googletagservices-gpt' — add missed 'setConfig' and 'getConfig' methods to 'googletag'. #560
Squashed commit of the following: commit 3f5b433 Author: Adam Wróblewski <adam@adguard.com> Date: Thu May 28 17:40:21 2026 +0200 Add `setConfig` and `getConfig`pnpm methods to `googletagservices-gpt` redirect
1 parent 3ba7a33 commit fa41a27

3 files changed

Lines changed: 139 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic
1414

1515
### Added
1616

17+
- `setConfig` and `getConfig` methods to `googletagservices-gpt` redirect [#560].
1718
- Delay range matching for `prevent-setTimeout` and `prevent-setInterval` scriptlets.
1819
Supported formats: `min-max`, `min-`, `-max`, with `!` prefix for inversion [#467].
1920

@@ -30,6 +31,7 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic
3031
- Added the missing `google.ima.dai.api.StreamRequest.StreamFormat` object to the `google-ima3-dai` redirect.
3132

3233
[Unreleased]: https://github.com/AdguardTeam/Scriptlets/compare/v2.4.2...HEAD
34+
[#560]: https://github.com/AdguardTeam/Scriptlets/issues/560
3335
[#529]: https://github.com/AdguardTeam/Scriptlets/issues/529
3436
[#467]: https://github.com/AdguardTeam/Scriptlets/issues/467
3537

src/redirects/googletagservices-gpt.js

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ export function GoogleTagServicesGpt(source) {
188188
let clickUrl = '';
189189
let collapseEmptyDiv = null;
190190
const services = new Set();
191+
const config = {};
191192
const slot = {
192193
addService(e) {
193194
services.add(e);
@@ -211,6 +212,21 @@ export function GoogleTagServicesGpt(source) {
211212
getCategoryExclusions: () => Array.from(exclusions),
212213
getClickUrl: () => clickUrl,
213214
getCollapseEmptyDiv: () => collapseEmptyDiv,
215+
getConfig: (keys) => {
216+
const configKeys = Array.isArray(keys) ? keys : [keys];
217+
const googleTagServicesConfig = {};
218+
for (let i = 0; i < configKeys.length; i += 1) {
219+
const key = configKeys[i];
220+
if (key === 'clickUrl') {
221+
googleTagServicesConfig[key] = clickUrl;
222+
} else if (key === 'targeting') {
223+
googleTagServicesConfig[key] = targeting;
224+
} else {
225+
googleTagServicesConfig[key] = config[key];
226+
}
227+
}
228+
return Object.freeze(googleTagServicesConfig);
229+
},
214230
getContentUrl: () => '',
215231
getDivStartsCollapsed: () => null,
216232
getDomId: () => optDiv,
@@ -249,6 +265,25 @@ export function GoogleTagServicesGpt(source) {
249265
collapseEmptyDiv = !!v;
250266
return slot;
251267
},
268+
setConfig(obj) {
269+
try {
270+
const entries = Object.entries(obj);
271+
for (let i = 0; i < entries.length; i += 1) {
272+
const entry = entries[i];
273+
const key = entry[0];
274+
const value = entry[1];
275+
if (key === 'clickUrl') {
276+
clickUrl = value;
277+
} else if (key === 'targeting') {
278+
updateTargeting(targeting, value);
279+
} else {
280+
config[key] = value;
281+
}
282+
}
283+
} catch (ex) {
284+
// do nothing
285+
}
286+
},
252287
setSafeFrameConfig: noopThis,
253288
setTagForChildDirectedTreatment: noopThis,
254289
setTargeting(k, v) {
@@ -267,6 +302,8 @@ export function GoogleTagServicesGpt(source) {
267302
return slot;
268303
};
269304

305+
let initialLoadDisabled = false;
306+
270307
const pubAdsService = {
271308
addEventListener,
272309
removeEventListener,
@@ -283,7 +320,9 @@ export function GoogleTagServicesGpt(source) {
283320
collapseEmptyDivs: noopFunc,
284321
defineOutOfPagePassback() { return new PassbackSlot(); },
285322
definePassback() { return new PassbackSlot(); },
286-
disableInitialLoad: noopFunc,
323+
disableInitialLoad() {
324+
initialLoadDisabled = true;
325+
},
287326
display: noopFunc,
288327
enableAsyncRendering: noopFunc,
289328
enableLazyLoad: noopFunc,
@@ -295,7 +334,7 @@ export function GoogleTagServicesGpt(source) {
295334
getTargeting: noopArray,
296335
getTargetingKeys: noopArray,
297336
getSlots: noopArray,
298-
isInitialLoadDisabled: trueFunc,
337+
isInitialLoadDisabled: () => initialLoadDisabled,
299338
refresh: noopFunc,
300339
set: noopThis,
301340
setCategoryExclusion: noopThis,
@@ -313,6 +352,8 @@ export function GoogleTagServicesGpt(source) {
313352
updateCorrelator: noopFunc,
314353
};
315354

355+
const config = {};
356+
316357
const { googletag = {} } = window;
317358
const { cmd = [] } = googletag;
318359

@@ -346,10 +387,44 @@ export function GoogleTagServicesGpt(source) {
346387
displaySlot(slotsById.get(id));
347388
};
348389
googletag.enableServices = noopFunc;
390+
googletag.getConfig = function (keys) {
391+
const configKeys = Array.isArray(keys) ? keys : [keys];
392+
const googleTagServicesConfig = {};
393+
for (let i = 0; i < configKeys.length; i += 1) {
394+
const key = configKeys[i];
395+
if (key === 'disableInitialLoad') {
396+
googleTagServicesConfig[key] = initialLoadDisabled;
397+
} else if (key === 'targeting') {
398+
googleTagServicesConfig[key] = gTargeting;
399+
} else {
400+
googleTagServicesConfig[key] = config[key];
401+
}
402+
}
403+
return Object.freeze(googleTagServicesConfig);
404+
};
349405
googletag.getVersion = noopStr;
350406
googletag.pubads = () => pubAdsService;
351407
googletag.pubadsReady = true;
352408
googletag.setAdIframeTitle = noopFunc;
409+
googletag.setConfig = function (obj) {
410+
try {
411+
const entries = Object.entries(obj);
412+
for (let i = 0; i < entries.length; i += 1) {
413+
const entry = entries[i];
414+
const key = entry[0];
415+
const value = entry[1];
416+
if (key === 'disableInitialLoad') {
417+
initialLoadDisabled = !!value;
418+
} else if (key === 'targeting') {
419+
updateTargeting(gTargeting, value);
420+
} else {
421+
config[key] = value;
422+
}
423+
}
424+
} catch (ex) {
425+
// do nothing
426+
}
427+
};
353428
googletag.sizeMapping = () => new SizeMappingBuilder();
354429

355430
window.googletag = googletag;

tests/redirects/googletagservices-gpt.test.js

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ test('AdGuard Syntax', (assert) => {
4949
assert.strictEqual(typeof mockedPubads.getTargeting, 'function', 'pubads().getTargeting() is function');
5050
assert.ok(mockedPubads.getTargeting() instanceof Array, 'pubads().getTargeting() returns array');
5151
assert.strictEqual(mockedPubads.getTargeting().length, 0, 'pubads().getTargeting() is mocked');
52-
assert.true(mockedPubads.isInitialLoadDisabled(), 'pubads().isInitialLoadDisabled() returns true');
52+
assert.false(mockedPubads.isInitialLoadDisabled(), 'pubads().isInitialLoadDisabled() returns false');
5353
});
5454

5555
test('Test Slot', (assert) => {
@@ -140,3 +140,62 @@ test('Test setPrivacySettings', (assert) => {
140140
assert.ok(window.googletag, 'window.googletag have been created');
141141
assert.strictEqual(typeof setPrivacySettings, 'object', 'setPrivacySettings has been mocked');
142142
});
143+
144+
test('Test slot setConfig and getConfig', (assert) => {
145+
evalWrapper(redirects.getRedirect(name).content);
146+
147+
const slot = window.googletag.defineSlot('/1234567/sports', [160, 600], 'slot-config-div');
148+
slot.setConfig({
149+
clickUrl: 'https://example.com/click',
150+
customKey: 'custom-value',
151+
targeting: {
152+
category: 'sports',
153+
tags: ['a', ['b', 'c']],
154+
},
155+
});
156+
157+
const config = slot.getConfig(['clickUrl', 'customKey', 'targeting']);
158+
159+
assert.ok(Object.isFrozen(config), 'slot.getConfig() returns a frozen object');
160+
assert.strictEqual(config.clickUrl, 'https://example.com/click', 'clickUrl from setConfig is stored');
161+
assert.strictEqual(config.customKey, 'custom-value', 'custom key from setConfig is stored');
162+
assert.ok(config.targeting instanceof Map, 'targeting is stored as Map');
163+
assert.strictEqual(config.targeting.get('category')[0], 'sports', 'targeting string value is converted to array');
164+
assert.strictEqual(config.targeting.get('tags')[2], 'c', 'nested targeting arrays are flattened');
165+
});
166+
167+
test('Test googletag setConfig and getConfig', (assert) => {
168+
evalWrapper(redirects.getRedirect(name).content);
169+
170+
window.googletag.setConfig({
171+
customKey: 'global-value',
172+
disableInitialLoad: true,
173+
targeting: {
174+
placement: 'homepage',
175+
audiences: ['sports', 'news'],
176+
},
177+
});
178+
179+
const config = window.googletag.getConfig(['customKey', 'disableInitialLoad', 'targeting']);
180+
const slot = window.googletag.defineSlot('/1234567/sports', [160, 600], 'global-config-div');
181+
182+
assert.ok(Object.isFrozen(config), 'googletag.getConfig() returns a frozen object');
183+
assert.strictEqual(config.customKey, 'global-value', 'custom value is stored in googletag config');
184+
assert.true(config.disableInitialLoad, 'disableInitialLoad from setConfig is stored');
185+
assert.ok(config.targeting instanceof Map, 'global targeting is stored as Map');
186+
assert.strictEqual(slot.getTargeting('placement')[0], 'homepage', 'slot reads global targeting key');
187+
assert.strictEqual(slot.getTargeting('audiences')[1], 'news', 'slot reads global targeting array');
188+
});
189+
190+
test('Test pubads disableInitialLoad state', (assert) => {
191+
evalWrapper(redirects.getRedirect(name).content);
192+
193+
const pubads = window.googletag.pubads();
194+
195+
assert.false(pubads.isInitialLoadDisabled(), 'initial load is enabled by default');
196+
assert.strictEqual(pubads.disableInitialLoad(), undefined, 'disableInitialLoad() returns nothing');
197+
assert.true(pubads.isInitialLoadDisabled(), 'disableInitialLoad() sets initial-load state to disabled');
198+
199+
window.googletag.setConfig({ disableInitialLoad: 0 });
200+
assert.false(pubads.isInitialLoadDisabled(), 'disableInitialLoad state is boolean-coerced by setConfig()');
201+
});

0 commit comments

Comments
 (0)