PageSourceSearch

http://coehdi.org/js/ads.js

js coehdi.org collected 2026-10-09 00:30:50 UTC 7,463 bytes, 279 lines download raw bytes

1/* global googletag, DFPSlots, DFPSlotsLoaded, DFPSlotsTargeting, DFPSlotsRefresh */
2
3const gptadslots = [];
4
5/**
6 * Defines DFP slot.
7 *
8 * @param {string} slot
9 *   Ad slot name.
10 * @param {string} id
11 *   Ad slot id.
12 * @param {array<number, number>} sizes
13 *   Ad slot sizes.
14 * @param {array<string>} pos
15 *   Ad slot pos value.
16 * @param {array<string, array<number, number>>} map
17 *   Size mapping.
18 */
19function DFPDefineSlot(slot, id, sizes, pos, map) {
20  const DFPSlot = sizes.length
21    ? googletag.defineSlot(slot, sizes, id)
22    : googletag.defineOutOfPageSlot(slot, id);
23  if (pos) {
24    DFPSlot.setTargeting('pos', [pos]);
25  }
26
27  // https://support.google.com/dfp_premium/answer/3423562?hl=en
28  if (map.length) {
29    let mapping = googletag.sizeMapping();
30    for (const item of map) {
31      mapping = mapping.addSize(item[0], item[1]);
32    }
33 const builtMapping = mapping.build();
34DFPSlot.defineSizeMapping(builtMapping);
35  }
36
37  if (DFPSlot && typeof DFPSlot.addService === 'function') {
38    gptadslots.push(DFPSlot.addService(googletag.pubads()));
39  }
40}
41
42/**
43 * Returns the width of the window.
44 *
45 * @see http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
46 *
47 * @return {number}
48 *   Window width.
49 */
50function windowWidth() {
51  // Non-IE.
52  if (typeof window.innerWidth === 'number') {
53    return window.innerWidth;
54  }
55
56  // IE 6+ in 'standards compliant mode'
57  if (document.documentElement && document.documentElement.clientWidth) {
58    return document.documentElement.clientWidth;
59  }
60
61  // IE 4 compatible.
62  if (document.body && document.body.clientWidth) {
63    return document.body.clientWidth;
64  }
65
66  // Sorry, your browser is weird.
67  return 0;
68}
69
70/**
71 * Checks if screen size matches mobile breakpoint.
72 * @return {number|boolean}
73 *   Flag indicating that mobile ads should be used.
74 */
75function onsiteAdsIsMobile() {
76  const width = windowWidth();
77  return width && width < 768;
78}
79
80/**
81 * Check if slot should be displayed.
82 *
83 * @param {object} dataset
84 *   Ad slot element dataset.
85 * @return {boolean|boolean}
86 *   Flag indicating that ad element matches breakpoint.
87 */
88function onsiteAdsIsDisplayed(dataset) {
89  if (typeof dataset.mobile !== 'undefined') {
90    return onsiteAdsIsMobile() === !!dataset.mobile;
91  }
92
93  const slot = dataset.slot;
94  const DFPSlot = DFPSlots[slot] || {};
95  const isMobileSlot = slot.indexOf('_mobile') !== -1;
96  const map = DFPSlot.map || [];
97  const isOop = (DFPSlot.map_code || '').toLowerCase() === 'oop' || !dataset.pos;
98  return isOop || onsiteAdsIsMobile() === isMobileSlot || map.length > 0;
99}
100
101/**
102 * Gets parent by selector.
103 *
104 * @param {HTMLElement} element
105 *   Element to find the parent for.
106 * @param {string} selector
107 *   Selector.
108 * @return {null|*}
109 *   Parent found or null if none.
110 */
111function getParentBySelector(element, selector) {
112  for (; element && element !== document; element = element.parentNode) {
113    if (element.matches(selector)) {
114      return element;
115    }
116  }
117  return null;
118}
119
120/**
121 * Autodetect ad placeholders on the page.
122 */
123(function () {
124  Object.keys(DFPSlots).forEach(function (key) {
125    DFPSlotsLoaded[key] = {};
126  });
127
128  for (const element of document.getElementsByClassName('onsite-ads')) {
129    if (
130      element.dataset &&
131      typeof DFPSlotsLoaded[element.dataset.slot] !== 'undefined'
132    ) {
133      if (onsiteAdsIsDisplayed(element.dataset)) {
134        DFPSlotsLoaded[element.dataset.slot][element.dataset.pos] = element.id;
135        continue;
136      }
137    }
138
139    const parent = getParentBySelector(element, '.block-onsite-ads');
140    if (!parent) {
141      parent = element;
142    }
143    parent.parentNode.removeChild(parent);
144  }
145})();
146
147/**
148 * GoogleTag: define slots.
149 */
150googletag.cmd.push(function () {
151  for (const DFPSlot in DFPSlots) {
152    if (DFPSlots.hasOwnProperty(DFPSlot) && typeof DFPSlotsLoaded[DFPSlot] !== 'undefined') {
153      Object.keys(DFPSlotsLoaded[DFPSlot]).forEach(function (pos) {
154        const id = DFPSlotsLoaded[DFPSlot][pos];
155        const slot = DFPSlots[DFPSlot].slot;
156        const map = DFPSlots[DFPSlot].map || [];
157        const sizes = DFPSlots[DFPSlot].sizes;
158        DFPDefineSlot(slot, id, sizes, pos, map);
159      });
160    }
161  }
162
163  googletag.pubads().collapseEmptyDivs();
164/**
165 * Targeting
166 */
167 
168if (typeof DFPSlotsTargeting !== 'undefined') {
169  Object.entries(DFPSlotsTargeting).forEach(([key, value]) => {
170    googletag.pubads().setTargeting(key, value);
171  });
172}
173
174// Enable lazyloading.
175  googletag.pubads().enableLazyLoad({
176    fetchMarginPercent: 25,
177    renderMarginPercent: 0,
178    mobileScaling: 2.0
179  });
180
181
182googletag.enableServices();
183});
184
185// Display ads.
186googletag.cmd.push(function () {
187  const nodes = document.getElementsByClassName('onsite-ads');
188  if (nodes.length) {
189    for (const node of nodes) {
190      if (node.id && onsiteAdsIsDisplayed(node.dataset)) {
191        googletag.display(node.id);
192      }
193    }
194  }
195});
196
197
198/**
199 * Quick check that ad slot element is fully visible on screen.
200 *
201 * @param {HTMLElement} element
202 *   Element to find the parent for.
203 * @returns {boolean}
204 *   Flag if visible.
205 */
206function onsiteAdsIsElementFullyVisible(element) {
207  const rect = element.getBoundingClientRect();
208  return rect.top > 0 && rect.bottom < windowHeight();
209}
210
211/**
212 * Quick check that ad slot is visible partially on screen.
213 *
214 * @param gptadslot
215 *   DFP ad slot.
216 * @returns {boolean}
217 *   Flag if visible.
218 */
219function onsiteAdsIsSlotFullyVisible(gptadslot) {
220  const id = gptadslot.getSlotElementId();
221  const element = document.getElementById(id);
222  return element ? onsiteAdsIsElementFullyVisible(element) : false;
223}
224
225/**
226 * Get slot name.
227 *
228 * @param gptadslot
229 * @returns {string|boolean}
230 */
231function onsiteAdsGetSlotPos(gptadslot) {
232  const id = gptadslot.getSlotElementId();
233  const element = document.getElementById(id);
234  return element && element.dataset && element.dataset.pos || false;
235}
236
237// Refresh ads.
238if (DFPSlotsRefresh && DFPSlotsRefresh.interval) {
239  let refreshLimit = parseInt(DFPSlotsRefresh.limit || -1);
240  if (refreshLimit) {
241    const refreshVisible = !!DFPSlotsRefresh.visible;
242    const refreshSlots = DFPSlotsRefresh.slots || [];
243
244    window.gptRefreshCounter = 0;
245    googletag.cmd.push(function () {
246      window.gptRefreshInterval = setInterval(function () {
247        console.log('gpt:refresh', 'tick', window.gptRefreshCounter % DFPSlotsRefresh.interval);
248        if (++window.gptRefreshCounter % DFPSlotsRefresh.interval === 0) {
249          if (!refreshVisible) {
250            googletag.pubads().refresh(gptadslots);
251            refreshLimit--;
252          } else {
253            let refreshed = false;
254            gptadslots.forEach(function (gptadslot) {
255              const pos = onsiteAdsGetSlotPos(gptadslot);
256              if (refreshSlots.length && refreshSlots.indexOf(pos) === -1) {
257                return;
258              }
259              if (onsiteAdsIsSlotFullyVisible(gptadslot)) {
260                googletag.pubads().refresh([gptadslot]);
261                console.log('gpt:refresh', 'refreshed', pos);
262                refreshed = true;
263              } else {
264                console.log('gpt:refresh', 'not in view', pos);
265              }
266            });
267            if (refreshed) {
268              refreshLimit--;
269            }
270          }
271          console.log('gpt:refresh', 'limit', refreshLimit);
272          if (refreshLimit === 0) {
273            clearInterval(window.gptRefreshInterval);
274          }
275        }
276      }, 1000);
277    });
278  }
279}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.