@folklore/ads 0.0.2

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.
Files changed (3) hide show
  1. package/dist/cjs.js +662 -0
  2. package/dist/es.js +645 -0
  3. package/package.json +61 -0
package/dist/cjs.js ADDED
@@ -0,0 +1,662 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var debounce = require('lodash/debounce');
6
+ var PropTypes = require('prop-types');
7
+ var React = require('react');
8
+ var EventEmitter = require('wolfy87-eventemitter');
9
+ var isObject = require('lodash/isObject');
10
+ var createDebug = require('debug');
11
+ var isArray = require('lodash/isArray');
12
+ var jsxRuntime = require('react/jsx-runtime');
13
+
14
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
15
+
16
+ var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce);
17
+ var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
18
+ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
19
+ var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
20
+ var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
21
+ var createDebug__default = /*#__PURE__*/_interopDefaultLegacy(createDebug);
22
+ var isArray__default = /*#__PURE__*/_interopDefaultLegacy(isArray);
23
+
24
+ class AdSlot extends EventEmitter__default["default"] {
25
+ constructor(id, path, size) {
26
+ let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
27
+ super();
28
+ this.options = {
29
+ sizeMapping: null,
30
+ targeting: {},
31
+ categoryExclusions: [],
32
+ visible: true,
33
+ ...opts
34
+ };
35
+ const {
36
+ visible
37
+ } = this.options;
38
+ this.elementId = id;
39
+ this.adPath = path;
40
+ this.adSize = size;
41
+ this.adSlot = null;
42
+ this.visible = visible;
43
+ this.wasVisible = visible;
44
+ this.rendered = false;
45
+ this.displayed = false;
46
+ this.viewable = false;
47
+ this.destroyed = false;
48
+ this.renderEvent = null;
49
+ this.refreshDisabled = false;
50
+ }
51
+ updateAdSlot() {
52
+ const {
53
+ adSlot
54
+ } = this;
55
+ const {
56
+ targeting = {},
57
+ categoryExclusions = [],
58
+ sizeMapping = null
59
+ } = this.options;
60
+
61
+ // Size mapping
62
+ if (sizeMapping !== null) {
63
+ adSlot.defineSizeMapping(sizeMapping);
64
+ }
65
+
66
+ // Targeting
67
+ const targetingKeys = targeting !== null ? Object.keys(targeting) : null;
68
+ if (targetingKeys !== null && targetingKeys.length > 0) {
69
+ targetingKeys.forEach(key => {
70
+ adSlot.setTargeting(key, targeting[key]);
71
+ });
72
+ } else {
73
+ adSlot.clearTargeting();
74
+ }
75
+
76
+ // Category exclusions
77
+ if (categoryExclusions !== null && categoryExclusions.length > 0) {
78
+ categoryExclusions.forEach(exclusion => {
79
+ adSlot.setCategoryExclusion(exclusion);
80
+ });
81
+ } else {
82
+ adSlot.clearCategoryExclusions();
83
+ }
84
+ }
85
+ setAdSlot(slot) {
86
+ this.adSlot = slot;
87
+ if (slot !== null) {
88
+ this.updateAdSlot();
89
+ }
90
+ return this;
91
+ }
92
+ setRenderEvent(event) {
93
+ this.renderEvent = event;
94
+ this.rendered = true;
95
+ this.emit('render', event, this);
96
+ return this;
97
+ }
98
+ setViewable(viewable) {
99
+ this.viewable = viewable;
100
+ }
101
+ setDisplayed(displayed) {
102
+ this.displayed = displayed;
103
+ return this;
104
+ }
105
+
106
+ // eslint-disable-next-line
107
+ setVisible(visible) {
108
+ this.visible = visible;
109
+ if (!this.wasVisible && visible) {
110
+ this.wasVisible = visible;
111
+ }
112
+ this.emit('visible', visible, this);
113
+ return this;
114
+ }
115
+ setRefreshDisabled() {
116
+ this.refreshDisabled = true;
117
+ }
118
+ destroy() {
119
+ if (this.destroyed) {
120
+ return;
121
+ }
122
+ this.removeAllListeners();
123
+ this.adSlot = null;
124
+ this.rendered = false;
125
+ this.displayed = false;
126
+ this.renderEvent = null;
127
+ this.destroyed = true;
128
+ }
129
+ getElementId() {
130
+ return this.elementId;
131
+ }
132
+ getAdSlot() {
133
+ return this.adSlot;
134
+ }
135
+ getAdPath() {
136
+ return this.adPath;
137
+ }
138
+ getAdSize() {
139
+ return this.adSize;
140
+ }
141
+ getTargeting() {
142
+ const {
143
+ targeting
144
+ } = this.options;
145
+ return targeting;
146
+ }
147
+ isVisible() {
148
+ return this.visible;
149
+ }
150
+ isDefined() {
151
+ return this.adSlot !== null;
152
+ }
153
+ isDisplayed() {
154
+ return this.displayed;
155
+ }
156
+ isViewable() {
157
+ return this.viewable;
158
+ }
159
+ isRendered() {
160
+ return this.rendered;
161
+ }
162
+ isRefreshDisabled() {
163
+ return this.refreshDisabled;
164
+ }
165
+ isDestroyed() {
166
+ return this.destroyed;
167
+ }
168
+ isEmpty() {
169
+ if (this.renderEvent === null) {
170
+ return false;
171
+ }
172
+ return this.renderEvent.isEmpty;
173
+ }
174
+ canBeDisplayed() {
175
+ return this.isDefined() && !this.isDisplayed();
176
+ }
177
+ getRenderedSize() {
178
+ if (this.renderEvent === null) {
179
+ return null;
180
+ }
181
+ const {
182
+ size = null
183
+ } = this.renderEvent;
184
+ return size !== null ? {
185
+ width: size[0],
186
+ height: size[1]
187
+ } : null;
188
+ }
189
+ }
190
+
191
+ /* globals refreshDisabledLineItems: [] */
192
+ const debug = createDebug__default["default"]('site:ads');
193
+ class AdsManager extends EventEmitter__default["default"] {
194
+ static index = 0;
195
+ static createAdId() {
196
+ const newId = `div-gpt-ad-${new Date().getTime()}-${Math.round(Math.random() * (Math.random() * 1000))}-${AdsManager.index}`;
197
+ AdsManager.index += 1;
198
+ return newId;
199
+ }
200
+ static getArticleTargeting(article) {
201
+ if (article === null) {
202
+ return null;
203
+ }
204
+ const {
205
+ id,
206
+ title,
207
+ slug,
208
+ metadata: {
209
+ categories = [],
210
+ authors = [],
211
+ sponsors = [],
212
+ safeForDistribution = true
213
+ }
214
+ } = article;
215
+ return {
216
+ title,
217
+ slug,
218
+ postID: id,
219
+ categories: categories.map(it => it.slug),
220
+ authors: authors.map(it => it.slug),
221
+ sponsors: sponsors.map(it => it.name),
222
+ GoogleSafeTargeting: safeForDistribution
223
+ };
224
+ }
225
+ static getSectionTargeting(section) {
226
+ return section !== null ? {
227
+ section: section.slug
228
+ } : null;
229
+ }
230
+ static getIndexTargeting(index) {
231
+ return index !== null ? {
232
+ index: index.slug
233
+ } : null;
234
+ }
235
+ static getIndexItemTargeting(index, item) {
236
+ return index !== null && item !== null ? {
237
+ [index.id]: [item.slug]
238
+ } : null;
239
+ }
240
+ constructor() {
241
+ let opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
242
+ super();
243
+ this.options = {
244
+ disabled: false,
245
+ disablePersonnalizedAds: false,
246
+ enableSingleRequest: false,
247
+ autoInit: false,
248
+ ...opts
249
+ };
250
+ this.onGPTReady = this.onGPTReady.bind(this);
251
+ this.onSlotRenderEnded = this.onSlotRenderEnded.bind(this);
252
+ this.onSlotImpressionViewable = this.onSlotImpressionViewable.bind(this);
253
+ this.onSlotVisibleChange = this.onSlotVisibleChange.bind(this);
254
+ this.disabled = this.options.disabled;
255
+ this.personnalizedAdsDisabled = this.options.disablePersonnalizedAds;
256
+ this.ready = false;
257
+ this.enabled = false;
258
+ this.googletag = window.googletag;
259
+ this.slots = [];
260
+ if (this.options.autoInit) {
261
+ this.init();
262
+ }
263
+ }
264
+ onGPTReady() {
265
+ const {
266
+ googletag
267
+ } = this;
268
+ this.ready = true;
269
+ googletag.cmd.push(() => {
270
+ const {
271
+ disabled,
272
+ personnalizedAdsDisabled
273
+ } = this;
274
+ const {
275
+ enableSingleRequest
276
+ } = this.options;
277
+ if (disabled) {
278
+ debug('Disable initial load');
279
+ googletag.pubads().disableInitialLoad();
280
+ }
281
+ if (enableSingleRequest) {
282
+ debug('Enable single request');
283
+ googletag.pubads().enableSingleRequest();
284
+ }
285
+ if (personnalizedAdsDisabled) {
286
+ debug('Disable personalized ads');
287
+ googletag.pubads().setRequestNonPersonalizedAds(1);
288
+ }
289
+ googletag.pubads().enableLazyLoad({
290
+ // Fetch slots within 5 viewports.
291
+ fetchMarginPercent: 300,
292
+ // Render slots within 2 viewports.
293
+ renderMarginPercent: 100,
294
+ // Double the above values on mobile, where viewports are smaller
295
+ // and users tend to scroll faster.
296
+ mobileScaling: 1.0
297
+ });
298
+ googletag.pubads().enableVideoAds();
299
+ googletag.pubads().addEventListener('slotRenderEnded', this.onSlotRenderEnded);
300
+ googletag.pubads().addEventListener('impressionViewable', this.onSlotImpressionViewable);
301
+ googletag.enableServices();
302
+ this.enabled = true;
303
+ debug('GPT is ready');
304
+ if (!disabled) {
305
+ this.emit('ready');
306
+ }
307
+ });
308
+ }
309
+ onSlotRenderEnded(event) {
310
+ const {
311
+ slot: eventSlot,
312
+ lineItemId = null,
313
+ size = []
314
+ } = event;
315
+ const renderSlot = this.slots.find(slot => eventSlot === slot.getAdSlot()) || null;
316
+ if (renderSlot !== null) {
317
+ renderSlot.setRenderEvent(event);
318
+ }
319
+ const lineItems = window.refreshDisabledLineItems || [];
320
+ if (isArray__default["default"](lineItems) && lineItems.indexOf(lineItemId) > -1) {
321
+ renderSlot.setRefreshDisabled();
322
+ }
323
+ if (event.isEmpty) {
324
+ debug('Render ended for slot #%s(%s). Slot is empty.', eventSlot.getSlotElementId(), eventSlot.getAdUnitPath());
325
+ } else {
326
+ debug('Render ended for slot #%s(%s) with size %s.', eventSlot.getSlotElementId(), eventSlot.getAdUnitPath(), size !== null ? size.join('x') : '-');
327
+ }
328
+ }
329
+ onSlotImpressionViewable(event) {
330
+ const {
331
+ slot: eventSlot
332
+ } = event;
333
+ const impressionSlot = this.slots.find(slot => eventSlot === slot.getAdSlot()) || null;
334
+ if (impressionSlot !== null) {
335
+ impressionSlot.setViewable(true);
336
+ }
337
+ debug('Impression viewable for slot #%s(%s).', eventSlot.getSlotElementId(), eventSlot.getAdUnitPath());
338
+ }
339
+
340
+ // eslint-disable-next-line class-methods-use-this
341
+ onSlotVisibleChange(visible, slot) {
342
+ debug('Slot #%s(%s) visibility change to %s', slot.getElementId(), slot.getAdPath(), visible ? 'visible' : 'not visible');
343
+ }
344
+ init() {
345
+ const {
346
+ googletag
347
+ } = this;
348
+ debug('Initializing ads manager...');
349
+ googletag.cmd.push(() => {
350
+ this.onGPTReady();
351
+ });
352
+ }
353
+ isReady() {
354
+ return this.ready && this.enabled && !this.disabled;
355
+ }
356
+ isDisabled() {
357
+ return this.disabled;
358
+ }
359
+ setDisabled(disabled) {
360
+ const shouldRefresh = this.disabled && !disabled;
361
+ this.disabled = disabled;
362
+ if (shouldRefresh) {
363
+ this.refreshAllSlots();
364
+ }
365
+ if (this.enabled && !disabled) {
366
+ this.emit('ready');
367
+ }
368
+ }
369
+ disablePersonnalizedAds(disablePersonnalizedAds) {
370
+ const {
371
+ googletag
372
+ } = this;
373
+ this.personnalizedAdsDisabled = disablePersonnalizedAds;
374
+ googletag.cmd.push(() => {
375
+ googletag.pubads().setRequestNonPersonalizedAds(disablePersonnalizedAds ? 1 : 0);
376
+ });
377
+ }
378
+ createSlot(path, size) {
379
+ let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
380
+ const {
381
+ id: providedId = null
382
+ } = opts;
383
+ const id = providedId || AdsManager.createAdId();
384
+ debug('Creating slot #%s(%s)...', id, path);
385
+ const slot = new AdSlot(id, path, size, {
386
+ ...opts
387
+ });
388
+ slot.on('visible', this.onSlotVisibleChange);
389
+ this.slots.push(slot);
390
+ return slot;
391
+ }
392
+ defineSlot(slot) {
393
+ const {
394
+ googletag
395
+ } = this;
396
+ googletag.cmd.push(() => {
397
+ if (slot.isDestroyed() || slot.isDefined()) {
398
+ return;
399
+ }
400
+ const id = slot.getElementId();
401
+ const path = slot.getAdPath();
402
+ const size = slot.getAdSize();
403
+ debug('Defining slot #%s(%s)...', id, path);
404
+ const adSlot = googletag.defineSlot(path, size, id).addService(googletag.pubads());
405
+ slot.setAdSlot(adSlot);
406
+ });
407
+ }
408
+ displaySlots() {
409
+ const slotsToDisplay = this.slots.filter(slot => slot.canBeDisplayed());
410
+ const slotsCount = slotsToDisplay.length;
411
+ if (slotsCount > 0) {
412
+ debug('Displaying %i slot(s)...', slotsCount);
413
+ slotsToDisplay.forEach(slot => this.callDisplaySlot(slot));
414
+ }
415
+ return true;
416
+ }
417
+ displaySlot(slot) {
418
+ if (!slot.canBeDisplayed()) {
419
+ return;
420
+ }
421
+ this.callDisplaySlot(slot);
422
+ }
423
+
424
+ /* eslint-disable */
425
+ callDisplaySlot(slot) {
426
+ const {
427
+ googletag
428
+ } = this;
429
+ googletag.cmd.push(() => {
430
+ const id = slot.getElementId();
431
+ const path = slot.getAdPath();
432
+ debug('Displaying slot #%s(%s)...', id, path);
433
+ googletag.display(slot.getAdSlot());
434
+ if (googletag.pubads().isInitialLoadDisabled()) {
435
+ googletag.pubads().refresh([slot.getAdSlot()]);
436
+ }
437
+ slot.setDisplayed(true);
438
+ });
439
+ }
440
+ /* eslint-enable */
441
+
442
+ destroySlot(id) {
443
+ const {
444
+ googletag
445
+ } = this;
446
+ const slot = isObject__default["default"](id) ? id : this.slots.find(it => it.getElementId() === id) || null;
447
+ if (slot === null || slot.isDestroyed()) {
448
+ return;
449
+ }
450
+ const adSlot = slot.getAdSlot();
451
+ slot.destroy();
452
+ this.slots = this.slots.filter(it => it !== slot);
453
+ if (adSlot !== null) {
454
+ debug('Destroying slot #%s(%s)...', adSlot.getAdUnitPath(), adSlot.getSlotElementId());
455
+ googletag.cmd.push(() => {
456
+ googletag.destroySlots([adSlot]);
457
+ });
458
+ }
459
+ }
460
+ refreshSlot(id) {
461
+ const {
462
+ googletag
463
+ } = this;
464
+ const slot = isObject__default["default"](id) ? id : this.slots.find(it => it.getElementId() === id) || null;
465
+ if (slot === null || slot.isDestroyed() || slot.isRefreshDisabled()) {
466
+ return;
467
+ }
468
+ const adSlot = slot.getAdSlot();
469
+ if (adSlot !== null) {
470
+ debug('Refreshing slot #%s(%s)...', adSlot.getAdUnitPath(), slot.getElementId());
471
+ googletag.cmd.push(() => {
472
+ googletag.pubads().refresh([adSlot], {
473
+ changeCorrelator: false
474
+ });
475
+ });
476
+ }
477
+ }
478
+ refreshSlots(ids) {
479
+ const {
480
+ googletag
481
+ } = this;
482
+ const slots = ids.map(id => isObject__default["default"](id) ? id : this.slots.find(it => !it.isDestroyed() && it.getElementId() === id) || null).filter(it => it !== null).map(it => it.getAdSlot());
483
+ if (slots.length === 0) {
484
+ return;
485
+ }
486
+ debug('Refreshing slots %o...', slots.map(slot => `#${slot.getElementId()}(${slot.getAdUnitPath()})`));
487
+ googletag.cmd.push(() => {
488
+ googletag.pubads().refresh(slots);
489
+ });
490
+ }
491
+ refreshAllSlots() {
492
+ const {
493
+ googletag
494
+ } = this;
495
+ debug('Refreshing all slots...');
496
+ googletag.cmd.push(() => {
497
+ googletag.pubads().refresh();
498
+ });
499
+ }
500
+ }
501
+
502
+ const viewports = {
503
+ default: [0, 0],
504
+ tablet: [728, 0],
505
+ desktop: [1024, 0],
506
+ laptop: [1400, 700]
507
+ };
508
+ const positions = {
509
+ top: {
510
+ size: [[320, 50], [1382, 600], [320, 100], [970, 90], [1024, 300], [970, 250], [300, 150], [1382, 300], [300, 100], [250, 250], [300, 250]],
511
+ sizeMapping: {
512
+ default: [[320, 50], [320, 100], [300, 150], [300, 100], [250, 250], [300, 250]],
513
+ tablet: [[320, 100], [300, 150], [300, 100]],
514
+ desktop: [[320, 100], [970, 90], [1024, 300], [970, 250], [300, 150], [300, 100]],
515
+ laptop: [[320, 100], [1382, 600], [320, 100], [970, 90], [1024, 300], [970, 250], [300, 150], [1382, 300], [300, 100]]
516
+ }
517
+ },
518
+ grid: {
519
+ size: [[250, 250], [300, 250], 'fluid']
520
+ },
521
+ sidebar: {
522
+ size: [[300, 600], [300, 250], [160, 600]],
523
+ sizeMapping: {
524
+ default: [[300, 250]],
525
+ laptop: [[300, 250], [300, 600], [160, 600]]
526
+ }
527
+ },
528
+ fullwidth: {
529
+ size: [[300, 250], [728, 90], [970, 250]],
530
+ sizeMapping: {
531
+ default: [[300, 250]],
532
+ tablet: [[300, 250], [728, 90]],
533
+ desktop: [[300, 250], [728, 90], [970, 250]],
534
+ laptop: [[300, 250], [728, 90], [970, 250]]
535
+ }
536
+ },
537
+ content: {
538
+ size: [[300, 600], [300, 100], [728, 90], [300, 250], [320, 100], [320, 50], [336, 280]],
539
+ sizeMapping: {
540
+ default: [[300, 600], [300, 100], [300, 250], [320, 100], [320, 50]],
541
+ tablet: [[300, 100], [728, 90], [300, 250], [320, 100], [320, 50], [336, 280]],
542
+ desktop: [[300, 100], [728, 90], [300, 250], [320, 100], [336, 280]],
543
+ laptop: [[300, 100], [728, 90], [300, 250], [320, 100], [336, 280]]
544
+ }
545
+ }
546
+ };
547
+
548
+ PropTypes__default["default"].string;
549
+ const adSize = PropTypes__default["default"].oneOfType([PropTypes__default["default"].arrayOf(PropTypes__default["default"].number), PropTypes__default["default"].arrayOf(PropTypes__default["default"].string), PropTypes__default["default"].string, PropTypes__default["default"].arrayOf(PropTypes__default["default"].oneOfType([PropTypes__default["default"].arrayOf(PropTypes__default["default"].number), PropTypes__default["default"].arrayOf(PropTypes__default["default"].string), PropTypes__default["default"].string]))]);
550
+ PropTypes__default["default"].arrayOf(PropTypes__default["default"].arrayOf(PropTypes__default["default"].oneOfType([PropTypes__default["default"].arrayOf(PropTypes__default["default"].number), adSize])));
551
+ const adPosition = PropTypes__default["default"].shape({
552
+ size: adSize,
553
+ sizeMapping: PropTypes__default["default"].objectOf(adSize)
554
+ });
555
+ PropTypes__default["default"].objectOf(adPosition);
556
+ const adViewports = PropTypes__default["default"].objectOf(PropTypes__default["default"].arrayOf(PropTypes__default["default"].number));
557
+ PropTypes__default["default"].shape({
558
+ domain: PropTypes__default["default"].string
559
+ });
560
+
561
+ /* eslint-disable react/jsx-props-no-spreading */
562
+ const AdsContext = /*#__PURE__*/React__default["default"].createContext(null);
563
+ const useAdsContext = () => React.useContext(AdsContext);
564
+ const propTypes = {
565
+ children: PropTypes__default["default"].node.isRequired,
566
+ defaultSlotPath: PropTypes__default["default"].string,
567
+ slotsPath: PropTypes__default["default"].objectOf(PropTypes__default["default"].string),
568
+ enableSingleRequest: PropTypes__default["default"].bool,
569
+ autoInit: PropTypes__default["default"].bool,
570
+ resizeDebounceDelay: PropTypes__default["default"].number,
571
+ refreshOnResize: PropTypes__default["default"].bool,
572
+ positions: adViewports,
573
+ viewports: adViewports
574
+ };
575
+ const defaultProps = {
576
+ defaultSlotPath: null,
577
+ slotsPath: null,
578
+ enableSingleRequest: true,
579
+ autoInit: true,
580
+ resizeDebounceDelay: 500,
581
+ refreshOnResize: false,
582
+ positions: positions,
583
+ viewports: viewports
584
+ };
585
+ function AdsProvider(_ref) {
586
+ let {
587
+ children,
588
+ defaultSlotPath,
589
+ slotsPath,
590
+ enableSingleRequest,
591
+ autoInit,
592
+ resizeDebounceDelay,
593
+ refreshOnResize,
594
+ viewports,
595
+ positions
596
+ } = _ref;
597
+ const [ready, setReady] = React.useState(false);
598
+ const adsRef = React.useRef(null);
599
+ const ads = React.useMemo(() => {
600
+ if (adsRef.current === null) {
601
+ adsRef.current = new AdsManager({
602
+ enableSingleRequest,
603
+ autoInit
604
+ });
605
+ }
606
+ return adsRef.current;
607
+ }, [enableSingleRequest, autoInit]);
608
+ React.useEffect(() => {
609
+ let onReady = null;
610
+ if (!ads.isReady()) {
611
+ onReady = () => setReady(true);
612
+ ads.on('ready', onReady);
613
+ } else {
614
+ setReady(true);
615
+ }
616
+ return () => {
617
+ if (onReady != null) {
618
+ ads.off('ready', onReady);
619
+ }
620
+ };
621
+ }, [ads, setReady]);
622
+ React.useEffect(() => {
623
+ if (!autoInit) {
624
+ ads.init();
625
+ }
626
+ }, [ads, autoInit]);
627
+ React.useEffect(() => {
628
+ const onResize = debounce__default["default"](() => ads.refreshAllSlots(), resizeDebounceDelay);
629
+ if (refreshOnResize) {
630
+ window.addEventListener('resize', onResize);
631
+ }
632
+ return () => {
633
+ if (refreshOnResize) {
634
+ window.removeEventListener('resize', onResize);
635
+ }
636
+ onResize.cancel();
637
+ };
638
+ }, [ads, resizeDebounceDelay, refreshOnResize]);
639
+ const value = React.useMemo(() => ({
640
+ ready,
641
+ ads,
642
+ viewports,
643
+ positions,
644
+ slotsPath: defaultSlotPath !== null ? {
645
+ default: defaultSlotPath,
646
+ ...slotsPath
647
+ } : {
648
+ ...slotsPath
649
+ }
650
+ }), [ready, ads, viewports, positions, slotsPath, defaultSlotPath]);
651
+ return /*#__PURE__*/jsxRuntime.jsx(AdsContext.Provider, {
652
+ value: value,
653
+ children: children
654
+ });
655
+ }
656
+ AdsProvider.propTypes = propTypes;
657
+ AdsProvider.defaultProps = defaultProps;
658
+
659
+ exports.AdSlot = AdSlot;
660
+ exports.AdsManager = AdsManager;
661
+ exports.AdsProvider = AdsProvider;
662
+ exports.useAdsContext = useAdsContext;
package/dist/es.js ADDED
@@ -0,0 +1,645 @@
1
+ import debounce from 'lodash/debounce';
2
+ import PropTypes from 'prop-types';
3
+ import React, { useContext, useState, useRef, useMemo, useEffect } from 'react';
4
+ import EventEmitter from 'wolfy87-eventemitter';
5
+ import isObject from 'lodash/isObject';
6
+ import createDebug from 'debug';
7
+ import isArray from 'lodash/isArray';
8
+ import { jsx } from 'react/jsx-runtime';
9
+
10
+ class AdSlot extends EventEmitter {
11
+ constructor(id, path, size) {
12
+ let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
13
+ super();
14
+ this.options = {
15
+ sizeMapping: null,
16
+ targeting: {},
17
+ categoryExclusions: [],
18
+ visible: true,
19
+ ...opts
20
+ };
21
+ const {
22
+ visible
23
+ } = this.options;
24
+ this.elementId = id;
25
+ this.adPath = path;
26
+ this.adSize = size;
27
+ this.adSlot = null;
28
+ this.visible = visible;
29
+ this.wasVisible = visible;
30
+ this.rendered = false;
31
+ this.displayed = false;
32
+ this.viewable = false;
33
+ this.destroyed = false;
34
+ this.renderEvent = null;
35
+ this.refreshDisabled = false;
36
+ }
37
+ updateAdSlot() {
38
+ const {
39
+ adSlot
40
+ } = this;
41
+ const {
42
+ targeting = {},
43
+ categoryExclusions = [],
44
+ sizeMapping = null
45
+ } = this.options;
46
+
47
+ // Size mapping
48
+ if (sizeMapping !== null) {
49
+ adSlot.defineSizeMapping(sizeMapping);
50
+ }
51
+
52
+ // Targeting
53
+ const targetingKeys = targeting !== null ? Object.keys(targeting) : null;
54
+ if (targetingKeys !== null && targetingKeys.length > 0) {
55
+ targetingKeys.forEach(key => {
56
+ adSlot.setTargeting(key, targeting[key]);
57
+ });
58
+ } else {
59
+ adSlot.clearTargeting();
60
+ }
61
+
62
+ // Category exclusions
63
+ if (categoryExclusions !== null && categoryExclusions.length > 0) {
64
+ categoryExclusions.forEach(exclusion => {
65
+ adSlot.setCategoryExclusion(exclusion);
66
+ });
67
+ } else {
68
+ adSlot.clearCategoryExclusions();
69
+ }
70
+ }
71
+ setAdSlot(slot) {
72
+ this.adSlot = slot;
73
+ if (slot !== null) {
74
+ this.updateAdSlot();
75
+ }
76
+ return this;
77
+ }
78
+ setRenderEvent(event) {
79
+ this.renderEvent = event;
80
+ this.rendered = true;
81
+ this.emit('render', event, this);
82
+ return this;
83
+ }
84
+ setViewable(viewable) {
85
+ this.viewable = viewable;
86
+ }
87
+ setDisplayed(displayed) {
88
+ this.displayed = displayed;
89
+ return this;
90
+ }
91
+
92
+ // eslint-disable-next-line
93
+ setVisible(visible) {
94
+ this.visible = visible;
95
+ if (!this.wasVisible && visible) {
96
+ this.wasVisible = visible;
97
+ }
98
+ this.emit('visible', visible, this);
99
+ return this;
100
+ }
101
+ setRefreshDisabled() {
102
+ this.refreshDisabled = true;
103
+ }
104
+ destroy() {
105
+ if (this.destroyed) {
106
+ return;
107
+ }
108
+ this.removeAllListeners();
109
+ this.adSlot = null;
110
+ this.rendered = false;
111
+ this.displayed = false;
112
+ this.renderEvent = null;
113
+ this.destroyed = true;
114
+ }
115
+ getElementId() {
116
+ return this.elementId;
117
+ }
118
+ getAdSlot() {
119
+ return this.adSlot;
120
+ }
121
+ getAdPath() {
122
+ return this.adPath;
123
+ }
124
+ getAdSize() {
125
+ return this.adSize;
126
+ }
127
+ getTargeting() {
128
+ const {
129
+ targeting
130
+ } = this.options;
131
+ return targeting;
132
+ }
133
+ isVisible() {
134
+ return this.visible;
135
+ }
136
+ isDefined() {
137
+ return this.adSlot !== null;
138
+ }
139
+ isDisplayed() {
140
+ return this.displayed;
141
+ }
142
+ isViewable() {
143
+ return this.viewable;
144
+ }
145
+ isRendered() {
146
+ return this.rendered;
147
+ }
148
+ isRefreshDisabled() {
149
+ return this.refreshDisabled;
150
+ }
151
+ isDestroyed() {
152
+ return this.destroyed;
153
+ }
154
+ isEmpty() {
155
+ if (this.renderEvent === null) {
156
+ return false;
157
+ }
158
+ return this.renderEvent.isEmpty;
159
+ }
160
+ canBeDisplayed() {
161
+ return this.isDefined() && !this.isDisplayed();
162
+ }
163
+ getRenderedSize() {
164
+ if (this.renderEvent === null) {
165
+ return null;
166
+ }
167
+ const {
168
+ size = null
169
+ } = this.renderEvent;
170
+ return size !== null ? {
171
+ width: size[0],
172
+ height: size[1]
173
+ } : null;
174
+ }
175
+ }
176
+
177
+ /* globals refreshDisabledLineItems: [] */
178
+ const debug = createDebug('site:ads');
179
+ class AdsManager extends EventEmitter {
180
+ static index = 0;
181
+ static createAdId() {
182
+ const newId = `div-gpt-ad-${new Date().getTime()}-${Math.round(Math.random() * (Math.random() * 1000))}-${AdsManager.index}`;
183
+ AdsManager.index += 1;
184
+ return newId;
185
+ }
186
+ static getArticleTargeting(article) {
187
+ if (article === null) {
188
+ return null;
189
+ }
190
+ const {
191
+ id,
192
+ title,
193
+ slug,
194
+ metadata: {
195
+ categories = [],
196
+ authors = [],
197
+ sponsors = [],
198
+ safeForDistribution = true
199
+ }
200
+ } = article;
201
+ return {
202
+ title,
203
+ slug,
204
+ postID: id,
205
+ categories: categories.map(it => it.slug),
206
+ authors: authors.map(it => it.slug),
207
+ sponsors: sponsors.map(it => it.name),
208
+ GoogleSafeTargeting: safeForDistribution
209
+ };
210
+ }
211
+ static getSectionTargeting(section) {
212
+ return section !== null ? {
213
+ section: section.slug
214
+ } : null;
215
+ }
216
+ static getIndexTargeting(index) {
217
+ return index !== null ? {
218
+ index: index.slug
219
+ } : null;
220
+ }
221
+ static getIndexItemTargeting(index, item) {
222
+ return index !== null && item !== null ? {
223
+ [index.id]: [item.slug]
224
+ } : null;
225
+ }
226
+ constructor() {
227
+ let opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
228
+ super();
229
+ this.options = {
230
+ disabled: false,
231
+ disablePersonnalizedAds: false,
232
+ enableSingleRequest: false,
233
+ autoInit: false,
234
+ ...opts
235
+ };
236
+ this.onGPTReady = this.onGPTReady.bind(this);
237
+ this.onSlotRenderEnded = this.onSlotRenderEnded.bind(this);
238
+ this.onSlotImpressionViewable = this.onSlotImpressionViewable.bind(this);
239
+ this.onSlotVisibleChange = this.onSlotVisibleChange.bind(this);
240
+ this.disabled = this.options.disabled;
241
+ this.personnalizedAdsDisabled = this.options.disablePersonnalizedAds;
242
+ this.ready = false;
243
+ this.enabled = false;
244
+ this.googletag = window.googletag;
245
+ this.slots = [];
246
+ if (this.options.autoInit) {
247
+ this.init();
248
+ }
249
+ }
250
+ onGPTReady() {
251
+ const {
252
+ googletag
253
+ } = this;
254
+ this.ready = true;
255
+ googletag.cmd.push(() => {
256
+ const {
257
+ disabled,
258
+ personnalizedAdsDisabled
259
+ } = this;
260
+ const {
261
+ enableSingleRequest
262
+ } = this.options;
263
+ if (disabled) {
264
+ debug('Disable initial load');
265
+ googletag.pubads().disableInitialLoad();
266
+ }
267
+ if (enableSingleRequest) {
268
+ debug('Enable single request');
269
+ googletag.pubads().enableSingleRequest();
270
+ }
271
+ if (personnalizedAdsDisabled) {
272
+ debug('Disable personalized ads');
273
+ googletag.pubads().setRequestNonPersonalizedAds(1);
274
+ }
275
+ googletag.pubads().enableLazyLoad({
276
+ // Fetch slots within 5 viewports.
277
+ fetchMarginPercent: 300,
278
+ // Render slots within 2 viewports.
279
+ renderMarginPercent: 100,
280
+ // Double the above values on mobile, where viewports are smaller
281
+ // and users tend to scroll faster.
282
+ mobileScaling: 1.0
283
+ });
284
+ googletag.pubads().enableVideoAds();
285
+ googletag.pubads().addEventListener('slotRenderEnded', this.onSlotRenderEnded);
286
+ googletag.pubads().addEventListener('impressionViewable', this.onSlotImpressionViewable);
287
+ googletag.enableServices();
288
+ this.enabled = true;
289
+ debug('GPT is ready');
290
+ if (!disabled) {
291
+ this.emit('ready');
292
+ }
293
+ });
294
+ }
295
+ onSlotRenderEnded(event) {
296
+ const {
297
+ slot: eventSlot,
298
+ lineItemId = null,
299
+ size = []
300
+ } = event;
301
+ const renderSlot = this.slots.find(slot => eventSlot === slot.getAdSlot()) || null;
302
+ if (renderSlot !== null) {
303
+ renderSlot.setRenderEvent(event);
304
+ }
305
+ const lineItems = window.refreshDisabledLineItems || [];
306
+ if (isArray(lineItems) && lineItems.indexOf(lineItemId) > -1) {
307
+ renderSlot.setRefreshDisabled();
308
+ }
309
+ if (event.isEmpty) {
310
+ debug('Render ended for slot #%s(%s). Slot is empty.', eventSlot.getSlotElementId(), eventSlot.getAdUnitPath());
311
+ } else {
312
+ debug('Render ended for slot #%s(%s) with size %s.', eventSlot.getSlotElementId(), eventSlot.getAdUnitPath(), size !== null ? size.join('x') : '-');
313
+ }
314
+ }
315
+ onSlotImpressionViewable(event) {
316
+ const {
317
+ slot: eventSlot
318
+ } = event;
319
+ const impressionSlot = this.slots.find(slot => eventSlot === slot.getAdSlot()) || null;
320
+ if (impressionSlot !== null) {
321
+ impressionSlot.setViewable(true);
322
+ }
323
+ debug('Impression viewable for slot #%s(%s).', eventSlot.getSlotElementId(), eventSlot.getAdUnitPath());
324
+ }
325
+
326
+ // eslint-disable-next-line class-methods-use-this
327
+ onSlotVisibleChange(visible, slot) {
328
+ debug('Slot #%s(%s) visibility change to %s', slot.getElementId(), slot.getAdPath(), visible ? 'visible' : 'not visible');
329
+ }
330
+ init() {
331
+ const {
332
+ googletag
333
+ } = this;
334
+ debug('Initializing ads manager...');
335
+ googletag.cmd.push(() => {
336
+ this.onGPTReady();
337
+ });
338
+ }
339
+ isReady() {
340
+ return this.ready && this.enabled && !this.disabled;
341
+ }
342
+ isDisabled() {
343
+ return this.disabled;
344
+ }
345
+ setDisabled(disabled) {
346
+ const shouldRefresh = this.disabled && !disabled;
347
+ this.disabled = disabled;
348
+ if (shouldRefresh) {
349
+ this.refreshAllSlots();
350
+ }
351
+ if (this.enabled && !disabled) {
352
+ this.emit('ready');
353
+ }
354
+ }
355
+ disablePersonnalizedAds(disablePersonnalizedAds) {
356
+ const {
357
+ googletag
358
+ } = this;
359
+ this.personnalizedAdsDisabled = disablePersonnalizedAds;
360
+ googletag.cmd.push(() => {
361
+ googletag.pubads().setRequestNonPersonalizedAds(disablePersonnalizedAds ? 1 : 0);
362
+ });
363
+ }
364
+ createSlot(path, size) {
365
+ let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
366
+ const {
367
+ id: providedId = null
368
+ } = opts;
369
+ const id = providedId || AdsManager.createAdId();
370
+ debug('Creating slot #%s(%s)...', id, path);
371
+ const slot = new AdSlot(id, path, size, {
372
+ ...opts
373
+ });
374
+ slot.on('visible', this.onSlotVisibleChange);
375
+ this.slots.push(slot);
376
+ return slot;
377
+ }
378
+ defineSlot(slot) {
379
+ const {
380
+ googletag
381
+ } = this;
382
+ googletag.cmd.push(() => {
383
+ if (slot.isDestroyed() || slot.isDefined()) {
384
+ return;
385
+ }
386
+ const id = slot.getElementId();
387
+ const path = slot.getAdPath();
388
+ const size = slot.getAdSize();
389
+ debug('Defining slot #%s(%s)...', id, path);
390
+ const adSlot = googletag.defineSlot(path, size, id).addService(googletag.pubads());
391
+ slot.setAdSlot(adSlot);
392
+ });
393
+ }
394
+ displaySlots() {
395
+ const slotsToDisplay = this.slots.filter(slot => slot.canBeDisplayed());
396
+ const slotsCount = slotsToDisplay.length;
397
+ if (slotsCount > 0) {
398
+ debug('Displaying %i slot(s)...', slotsCount);
399
+ slotsToDisplay.forEach(slot => this.callDisplaySlot(slot));
400
+ }
401
+ return true;
402
+ }
403
+ displaySlot(slot) {
404
+ if (!slot.canBeDisplayed()) {
405
+ return;
406
+ }
407
+ this.callDisplaySlot(slot);
408
+ }
409
+
410
+ /* eslint-disable */
411
+ callDisplaySlot(slot) {
412
+ const {
413
+ googletag
414
+ } = this;
415
+ googletag.cmd.push(() => {
416
+ const id = slot.getElementId();
417
+ const path = slot.getAdPath();
418
+ debug('Displaying slot #%s(%s)...', id, path);
419
+ googletag.display(slot.getAdSlot());
420
+ if (googletag.pubads().isInitialLoadDisabled()) {
421
+ googletag.pubads().refresh([slot.getAdSlot()]);
422
+ }
423
+ slot.setDisplayed(true);
424
+ });
425
+ }
426
+ /* eslint-enable */
427
+
428
+ destroySlot(id) {
429
+ const {
430
+ googletag
431
+ } = this;
432
+ const slot = isObject(id) ? id : this.slots.find(it => it.getElementId() === id) || null;
433
+ if (slot === null || slot.isDestroyed()) {
434
+ return;
435
+ }
436
+ const adSlot = slot.getAdSlot();
437
+ slot.destroy();
438
+ this.slots = this.slots.filter(it => it !== slot);
439
+ if (adSlot !== null) {
440
+ debug('Destroying slot #%s(%s)...', adSlot.getAdUnitPath(), adSlot.getSlotElementId());
441
+ googletag.cmd.push(() => {
442
+ googletag.destroySlots([adSlot]);
443
+ });
444
+ }
445
+ }
446
+ refreshSlot(id) {
447
+ const {
448
+ googletag
449
+ } = this;
450
+ const slot = isObject(id) ? id : this.slots.find(it => it.getElementId() === id) || null;
451
+ if (slot === null || slot.isDestroyed() || slot.isRefreshDisabled()) {
452
+ return;
453
+ }
454
+ const adSlot = slot.getAdSlot();
455
+ if (adSlot !== null) {
456
+ debug('Refreshing slot #%s(%s)...', adSlot.getAdUnitPath(), slot.getElementId());
457
+ googletag.cmd.push(() => {
458
+ googletag.pubads().refresh([adSlot], {
459
+ changeCorrelator: false
460
+ });
461
+ });
462
+ }
463
+ }
464
+ refreshSlots(ids) {
465
+ const {
466
+ googletag
467
+ } = this;
468
+ const slots = ids.map(id => isObject(id) ? id : this.slots.find(it => !it.isDestroyed() && it.getElementId() === id) || null).filter(it => it !== null).map(it => it.getAdSlot());
469
+ if (slots.length === 0) {
470
+ return;
471
+ }
472
+ debug('Refreshing slots %o...', slots.map(slot => `#${slot.getElementId()}(${slot.getAdUnitPath()})`));
473
+ googletag.cmd.push(() => {
474
+ googletag.pubads().refresh(slots);
475
+ });
476
+ }
477
+ refreshAllSlots() {
478
+ const {
479
+ googletag
480
+ } = this;
481
+ debug('Refreshing all slots...');
482
+ googletag.cmd.push(() => {
483
+ googletag.pubads().refresh();
484
+ });
485
+ }
486
+ }
487
+
488
+ const viewports = {
489
+ default: [0, 0],
490
+ tablet: [728, 0],
491
+ desktop: [1024, 0],
492
+ laptop: [1400, 700]
493
+ };
494
+ const positions = {
495
+ top: {
496
+ size: [[320, 50], [1382, 600], [320, 100], [970, 90], [1024, 300], [970, 250], [300, 150], [1382, 300], [300, 100], [250, 250], [300, 250]],
497
+ sizeMapping: {
498
+ default: [[320, 50], [320, 100], [300, 150], [300, 100], [250, 250], [300, 250]],
499
+ tablet: [[320, 100], [300, 150], [300, 100]],
500
+ desktop: [[320, 100], [970, 90], [1024, 300], [970, 250], [300, 150], [300, 100]],
501
+ laptop: [[320, 100], [1382, 600], [320, 100], [970, 90], [1024, 300], [970, 250], [300, 150], [1382, 300], [300, 100]]
502
+ }
503
+ },
504
+ grid: {
505
+ size: [[250, 250], [300, 250], 'fluid']
506
+ },
507
+ sidebar: {
508
+ size: [[300, 600], [300, 250], [160, 600]],
509
+ sizeMapping: {
510
+ default: [[300, 250]],
511
+ laptop: [[300, 250], [300, 600], [160, 600]]
512
+ }
513
+ },
514
+ fullwidth: {
515
+ size: [[300, 250], [728, 90], [970, 250]],
516
+ sizeMapping: {
517
+ default: [[300, 250]],
518
+ tablet: [[300, 250], [728, 90]],
519
+ desktop: [[300, 250], [728, 90], [970, 250]],
520
+ laptop: [[300, 250], [728, 90], [970, 250]]
521
+ }
522
+ },
523
+ content: {
524
+ size: [[300, 600], [300, 100], [728, 90], [300, 250], [320, 100], [320, 50], [336, 280]],
525
+ sizeMapping: {
526
+ default: [[300, 600], [300, 100], [300, 250], [320, 100], [320, 50]],
527
+ tablet: [[300, 100], [728, 90], [300, 250], [320, 100], [320, 50], [336, 280]],
528
+ desktop: [[300, 100], [728, 90], [300, 250], [320, 100], [336, 280]],
529
+ laptop: [[300, 100], [728, 90], [300, 250], [320, 100], [336, 280]]
530
+ }
531
+ }
532
+ };
533
+
534
+ PropTypes.string;
535
+ const adSize = PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.arrayOf(PropTypes.string), PropTypes.string, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.arrayOf(PropTypes.string), PropTypes.string]))]);
536
+ PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), adSize])));
537
+ const adPosition = PropTypes.shape({
538
+ size: adSize,
539
+ sizeMapping: PropTypes.objectOf(adSize)
540
+ });
541
+ PropTypes.objectOf(adPosition);
542
+ const adViewports = PropTypes.objectOf(PropTypes.arrayOf(PropTypes.number));
543
+ PropTypes.shape({
544
+ domain: PropTypes.string
545
+ });
546
+
547
+ /* eslint-disable react/jsx-props-no-spreading */
548
+ const AdsContext = /*#__PURE__*/React.createContext(null);
549
+ const useAdsContext = () => useContext(AdsContext);
550
+ const propTypes = {
551
+ children: PropTypes.node.isRequired,
552
+ defaultSlotPath: PropTypes.string,
553
+ slotsPath: PropTypes.objectOf(PropTypes.string),
554
+ enableSingleRequest: PropTypes.bool,
555
+ autoInit: PropTypes.bool,
556
+ resizeDebounceDelay: PropTypes.number,
557
+ refreshOnResize: PropTypes.bool,
558
+ positions: adViewports,
559
+ viewports: adViewports
560
+ };
561
+ const defaultProps = {
562
+ defaultSlotPath: null,
563
+ slotsPath: null,
564
+ enableSingleRequest: true,
565
+ autoInit: true,
566
+ resizeDebounceDelay: 500,
567
+ refreshOnResize: false,
568
+ positions: positions,
569
+ viewports: viewports
570
+ };
571
+ function AdsProvider(_ref) {
572
+ let {
573
+ children,
574
+ defaultSlotPath,
575
+ slotsPath,
576
+ enableSingleRequest,
577
+ autoInit,
578
+ resizeDebounceDelay,
579
+ refreshOnResize,
580
+ viewports,
581
+ positions
582
+ } = _ref;
583
+ const [ready, setReady] = useState(false);
584
+ const adsRef = useRef(null);
585
+ const ads = useMemo(() => {
586
+ if (adsRef.current === null) {
587
+ adsRef.current = new AdsManager({
588
+ enableSingleRequest,
589
+ autoInit
590
+ });
591
+ }
592
+ return adsRef.current;
593
+ }, [enableSingleRequest, autoInit]);
594
+ useEffect(() => {
595
+ let onReady = null;
596
+ if (!ads.isReady()) {
597
+ onReady = () => setReady(true);
598
+ ads.on('ready', onReady);
599
+ } else {
600
+ setReady(true);
601
+ }
602
+ return () => {
603
+ if (onReady != null) {
604
+ ads.off('ready', onReady);
605
+ }
606
+ };
607
+ }, [ads, setReady]);
608
+ useEffect(() => {
609
+ if (!autoInit) {
610
+ ads.init();
611
+ }
612
+ }, [ads, autoInit]);
613
+ useEffect(() => {
614
+ const onResize = debounce(() => ads.refreshAllSlots(), resizeDebounceDelay);
615
+ if (refreshOnResize) {
616
+ window.addEventListener('resize', onResize);
617
+ }
618
+ return () => {
619
+ if (refreshOnResize) {
620
+ window.removeEventListener('resize', onResize);
621
+ }
622
+ onResize.cancel();
623
+ };
624
+ }, [ads, resizeDebounceDelay, refreshOnResize]);
625
+ const value = useMemo(() => ({
626
+ ready,
627
+ ads,
628
+ viewports,
629
+ positions,
630
+ slotsPath: defaultSlotPath !== null ? {
631
+ default: defaultSlotPath,
632
+ ...slotsPath
633
+ } : {
634
+ ...slotsPath
635
+ }
636
+ }), [ready, ads, viewports, positions, slotsPath, defaultSlotPath]);
637
+ return /*#__PURE__*/jsx(AdsContext.Provider, {
638
+ value: value,
639
+ children: children
640
+ });
641
+ }
642
+ AdsProvider.propTypes = propTypes;
643
+ AdsProvider.defaultProps = defaultProps;
644
+
645
+ export { AdSlot, AdsManager, AdsProvider, useAdsContext };
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@folklore/ads",
3
+ "version": "0.0.2",
4
+ "description": "Ads library",
5
+ "keywords": [
6
+ "javascript",
7
+ "size",
8
+ "ui",
9
+ "utils"
10
+ ],
11
+ "homepage": "https://github.com/folkloreinc/folklore-js",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/folkloreinc/folklore-js.git"
15
+ },
16
+ "author": {
17
+ "name": "Folklore",
18
+ "email": "info@folklore.email"
19
+ },
20
+ "contributors": [
21
+ {
22
+ "name": "David Mongeau-Petitpas",
23
+ "email": "dmp@folklore.email"
24
+ },
25
+ {
26
+ "name": "Nicolas Roy-Bourdages",
27
+ "email": "nrb@folklore.email"
28
+ }
29
+ ],
30
+ "main": "dist/cjs.js",
31
+ "module": "dist/es.js",
32
+ "files": [
33
+ "dist"
34
+ ],
35
+ "scripts": {
36
+ "clean": "rm -rf dist",
37
+ "build": "rollup --config ../../rollup.config.js",
38
+ "prepare": "npm run clean && npm run build"
39
+ },
40
+ "devDependencies": {
41
+ "prop-types": "^15.7.2",
42
+ "react": "^17.0.0 || ^18.0.0",
43
+ "react-dom": "^17.0.0 || ^18.0.0"
44
+ },
45
+ "peerDependencies": {
46
+ "prop-types": "^15.7.2",
47
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
48
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
52
+ },
53
+ "gitHead": "a13caffa03c30420cb515e32448911740ce67c30",
54
+ "dependencies": {
55
+ "@folklore/hooks": "^0.0.41",
56
+ "@folklore/tracking": "^0.0.16",
57
+ "debug": "^4.3.4",
58
+ "lodash": "^4.17.21",
59
+ "wolfy87-eventemitter": "^5.2.9"
60
+ }
61
+ }