@capacitor-community/admob 8.2.1 → 8.3.0-beta.pr495.shaaa5aedc59a51
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 +1 -1
- package/android/build.gradle +5 -1
- package/android/src/main/java/com/getcapacitor/community/admob/AdMob.java +15 -0
- package/android/src/main/java/com/getcapacitor/community/admob/nativeads/NativeAdExecutor.kt +257 -9
- package/dist/esm/native-ads/native-ad-definitions.interface.d.ts +6 -0
- package/dist/esm/native-ads/native-ad-feed.d.ts +3 -3
- package/dist/esm/native-ads/native-ad-feed.js +107 -32
- package/dist/esm/native-ads/native-ad-feed.js.map +1 -1
- package/dist/esm/native-ads/native-ad-geometry.js +2 -1
- package/dist/esm/native-ads/native-ad-geometry.js.map +1 -1
- package/dist/esm/native-ads/native-ad-options.interface.d.ts +6 -2
- package/dist/esm/native-ads/native-ad-placement.interface.d.ts +2 -0
- package/dist/plugin.cjs.js +165 -33
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +165 -33
- package/dist/plugin.js.map +1 -1
- package/docs/native-ads.md +32 -6
- package/ios/Sources/AdMobPlugin/AppOpen/AppOpenAdPluginEvents.swift +3 -0
- package/ios/Sources/AdMobPlugin/Banner/BannerAdPluginEvents.swift +3 -0
- package/ios/Sources/AdMobPlugin/Banner/BannerAdSizeEnum.swift +3 -0
- package/ios/Sources/AdMobPlugin/Banner/BannerExecutor.swift +4 -4
- package/ios/Sources/AdMobPlugin/Helper/AuthorizationStatusEnum.swift +3 -0
- package/ios/Sources/AdMobPlugin/Interstitial/InterstitialAdPluginEvents.swift +3 -0
- package/ios/Sources/AdMobPlugin/Rewarded/RewardAdPluginEvents.swift +3 -0
- package/ios/Sources/AdMobPlugin/RewardedInterstitial/RewardInterstitialAdPluginEvents.swift +3 -0
- package/package.json +5 -4
package/dist/plugin.js
CHANGED
|
@@ -1,6 +1,64 @@
|
|
|
1
1
|
var capacitorStripe = (function (exports, core) {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
function* projectionAncestors(element) {
|
|
5
|
+
let current = element;
|
|
6
|
+
while (current) {
|
|
7
|
+
const root = current.getRootNode();
|
|
8
|
+
current = current.assignedSlot ?? current.parentElement ?? (root instanceof ShadowRoot ? root.host : null);
|
|
9
|
+
if (current)
|
|
10
|
+
yield current;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Current CSS visibility without the Engine's projection hiding rules.
|
|
15
|
+
* Use when an existing renderer decides whether its DOM source is authored hidden.
|
|
16
|
+
* Projection attributes are restored synchronously before returning; this performs
|
|
17
|
+
* a style read and may notify MutationObservers, so it is not a cached measurement.
|
|
18
|
+
*/
|
|
19
|
+
const getUnprojectedVisibility = (element) => {
|
|
20
|
+
const win = element.ownerDocument.defaultView;
|
|
21
|
+
if (!win)
|
|
22
|
+
return 'hidden';
|
|
23
|
+
const markers = [];
|
|
24
|
+
for (const node of [element, ...projectionAncestors(element)]) {
|
|
25
|
+
for (const attribute of Array.from(node.attributes)) {
|
|
26
|
+
if (attribute.name === 'data-native-ui-snapshot-source' ||
|
|
27
|
+
attribute.name === 'data-native-ui-snapshot-prepared' ||
|
|
28
|
+
attribute.name === 'data-native-ui-snapshot-content' ||
|
|
29
|
+
attribute.name.startsWith('data-native-ui-session-'))
|
|
30
|
+
markers.push({ node, name: attribute.name, value: attribute.value });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
for (const { node, name } of markers)
|
|
35
|
+
node.removeAttribute(name);
|
|
36
|
+
return win.getComputedStyle(element).visibility;
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
for (const { node, name, value } of markers)
|
|
40
|
+
node.setAttribute(name, value);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// The injected runtime and a plugin's bundled helper share the binding.
|
|
45
|
+
const placementKey = Symbol.for('webview-native-ui-engine.projection-placement');
|
|
46
|
+
const bindProjectionPlacement = (element, measure, invalidate = () => { }) => {
|
|
47
|
+
const host = element;
|
|
48
|
+
const state = { projected: false, measure, invalidate };
|
|
49
|
+
host[placementKey] = state;
|
|
50
|
+
return {
|
|
51
|
+
get projected() {
|
|
52
|
+
return host[placementKey] === state && state.projected;
|
|
53
|
+
},
|
|
54
|
+
dispose() {
|
|
55
|
+
if (host[placementKey] === state)
|
|
56
|
+
delete host[placementKey];
|
|
57
|
+
state.projected = false;
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
|
|
4
62
|
const NATIVE_AD_ELEMENT_NAME = 'capacitor-admob-native';
|
|
5
63
|
const defineNativeAdElement = (findFeed) => {
|
|
6
64
|
const runtime = globalThis;
|
|
@@ -93,7 +151,7 @@ var capacitorStripe = (function (exports, core) {
|
|
|
93
151
|
const domRect = element.getBoundingClientRect();
|
|
94
152
|
if (!element.isConnected ||
|
|
95
153
|
style.display === 'none' ||
|
|
96
|
-
style.visibility === 'hidden' ||
|
|
154
|
+
(style.visibility === 'hidden' && getUnprojectedVisibility(element) === 'hidden') ||
|
|
97
155
|
Number.parseFloat(style.opacity || '1') === 0 ||
|
|
98
156
|
domRect.width <= 0 ||
|
|
99
157
|
domRect.height <= 0) {
|
|
@@ -188,12 +246,10 @@ var capacitorStripe = (function (exports, core) {
|
|
|
188
246
|
const feeds = new Map();
|
|
189
247
|
const createSessionId = () => { var _a, _b, _c; return (_c = (_b = (_a = globalThis.crypto) === null || _a === void 0 ? void 0 : _a.randomUUID) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : `${Date.now()}-${++sessionSequence}-${Math.random().toString(36).slice(2)}`; };
|
|
190
248
|
/**
|
|
191
|
-
*
|
|
249
|
+
* Manages native ad placement and lifecycle in a scrolling feed.
|
|
192
250
|
*
|
|
193
251
|
* A stable `slotKey`, rather than the element or array index, owns the native
|
|
194
252
|
* ad lifecycle. Virtual-scroller compatibility has not yet been validated.
|
|
195
|
-
*
|
|
196
|
-
* @experimental Native overlay gesture routing is still being validated on devices.
|
|
197
253
|
*/
|
|
198
254
|
class NativeAdFeed {
|
|
199
255
|
constructor(options) {
|
|
@@ -216,6 +272,15 @@ var capacitorStripe = (function (exports, core) {
|
|
|
216
272
|
if (this.destroyed) {
|
|
217
273
|
return;
|
|
218
274
|
}
|
|
275
|
+
if (event instanceof Event &&
|
|
276
|
+
event.type === 'load' &&
|
|
277
|
+
event.target instanceof HTMLImageElement &&
|
|
278
|
+
event.target.dataset['admobSnapshot'] !== undefined)
|
|
279
|
+
return;
|
|
280
|
+
if (!(event instanceof Event) || !['scroll', 'touchmove', 'wheel'].includes(event.type)) {
|
|
281
|
+
for (const state of this.slots.values())
|
|
282
|
+
state.lastPlacement = undefined;
|
|
283
|
+
}
|
|
219
284
|
if (!(this.nativeScrollElement &&
|
|
220
285
|
event instanceof Event &&
|
|
221
286
|
['scroll', 'touchmove', 'wheel'].includes(event.type))) {
|
|
@@ -244,6 +309,9 @@ var capacitorStripe = (function (exports, core) {
|
|
|
244
309
|
if (feeds.size >= MAX_ACTIVE_FEEDS) {
|
|
245
310
|
throw new Error(`At most ${MAX_ACTIVE_FEEDS} native ad feeds can be active`);
|
|
246
311
|
}
|
|
312
|
+
if (options.androidScrollSnapshot && core.Capacitor.getPlatform() !== 'android') {
|
|
313
|
+
throw new Error('androidScrollSnapshot requires Android');
|
|
314
|
+
}
|
|
247
315
|
this.options = Object.assign(Object.assign({}, options), { feedId: id });
|
|
248
316
|
this.nativeScrollElement = core.Capacitor.getPlatform() === 'ios' ? options.scrollElement : undefined;
|
|
249
317
|
if (typeof IntersectionObserver !== 'undefined') {
|
|
@@ -330,7 +398,7 @@ var capacitorStripe = (function (exports, core) {
|
|
|
330
398
|
return handle;
|
|
331
399
|
}
|
|
332
400
|
attach(slotKey, element) {
|
|
333
|
-
var _a, _b, _c;
|
|
401
|
+
var _a, _b, _c, _d, _e;
|
|
334
402
|
this.assertActive();
|
|
335
403
|
const normalizedKey = slotKey.trim();
|
|
336
404
|
if (!normalizedKey) {
|
|
@@ -357,30 +425,58 @@ var capacitorStripe = (function (exports, core) {
|
|
|
357
425
|
};
|
|
358
426
|
applySlotDefaults(element, (_a = this.options.template) !== null && _a !== void 0 ? _a : exports.NativeAdTemplate.Medium);
|
|
359
427
|
state.element = element;
|
|
428
|
+
if (this.options.androidScrollSnapshot) {
|
|
429
|
+
const owner = ((_b = state.projectionOwner) !== null && _b !== void 0 ? _b : (state.projectionOwner = `admob-${crypto.randomUUID()}`));
|
|
430
|
+
element.dataset['admobProjection'] = owner;
|
|
431
|
+
state.projectionSelector = `[data-admob-projection="${owner}"]`;
|
|
432
|
+
(_c = state.placementBinding) === null || _c === void 0 ? void 0 : _c.dispose();
|
|
433
|
+
state.placementBinding = bindProjectionPlacement(element, () => {
|
|
434
|
+
const placement = this.measurePlacement(state);
|
|
435
|
+
state.lastPlacement = placement;
|
|
436
|
+
// The reveal request applies this exact placement; keep batch deduplication in sync.
|
|
437
|
+
if (this.lastPlacements) {
|
|
438
|
+
const previous = JSON.parse(this.lastPlacements);
|
|
439
|
+
previous.placements = previous.placements.map((item) => item.slotKey === state.slotKey ? placement : item);
|
|
440
|
+
this.lastPlacements = JSON.stringify(previous);
|
|
441
|
+
}
|
|
442
|
+
return Object.assign(Object.assign({}, placement), { sessionId: this.sessionId, sequence: ++this.placementSequence });
|
|
443
|
+
}, () => {
|
|
444
|
+
if (state.element !== element || this.destroyed)
|
|
445
|
+
return;
|
|
446
|
+
state.lastPlacement = undefined;
|
|
447
|
+
this.lastPlacements = undefined;
|
|
448
|
+
this.schedulePlacementUpdate();
|
|
449
|
+
});
|
|
450
|
+
}
|
|
360
451
|
state.generation += 1;
|
|
361
452
|
state.lastUsed = Date.now();
|
|
362
453
|
this.slots.set(normalizedKey, state);
|
|
363
454
|
this.elementSlots.set(element, normalizedKey);
|
|
364
455
|
this.updateScrollRoots();
|
|
365
|
-
(
|
|
366
|
-
(
|
|
456
|
+
(_d = this.intersectionObserver) === null || _d === void 0 ? void 0 : _d.observe(element);
|
|
457
|
+
(_e = this.resizeObserver) === null || _e === void 0 ? void 0 : _e.observe(element);
|
|
367
458
|
this.scheduleEvaluation();
|
|
368
459
|
}
|
|
369
460
|
detach(element) {
|
|
370
|
-
var _a, _b;
|
|
461
|
+
var _a, _b, _c;
|
|
371
462
|
const slotKey = this.elementSlots.get(element);
|
|
372
463
|
if (!slotKey) {
|
|
373
464
|
return;
|
|
374
465
|
}
|
|
375
466
|
const state = this.slots.get(slotKey);
|
|
376
467
|
if ((state === null || state === void 0 ? void 0 : state.element) === element) {
|
|
468
|
+
(_a = state.placementBinding) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
469
|
+
state.placementBinding = undefined;
|
|
470
|
+
state.lastPlacement = undefined;
|
|
471
|
+
if (state.projectionOwner)
|
|
472
|
+
delete element.dataset['admobProjection'];
|
|
377
473
|
state.element = undefined;
|
|
378
474
|
state.intersecting = false;
|
|
379
475
|
state.generation += 1;
|
|
380
476
|
state.lastUsed = Date.now();
|
|
381
477
|
}
|
|
382
|
-
(
|
|
383
|
-
(
|
|
478
|
+
(_b = this.intersectionObserver) === null || _b === void 0 ? void 0 : _b.unobserve(element);
|
|
479
|
+
(_c = this.resizeObserver) === null || _c === void 0 ? void 0 : _c.unobserve(element);
|
|
384
480
|
this.elementSlots.delete(element);
|
|
385
481
|
this.updateScrollRoots();
|
|
386
482
|
void this.requestPlacementUpdate();
|
|
@@ -402,6 +498,7 @@ var capacitorStripe = (function (exports, core) {
|
|
|
402
498
|
throw new Error('Native ad capacity is currently in use by visible slots');
|
|
403
499
|
}
|
|
404
500
|
await this.loadState(state);
|
|
501
|
+
await this.requestPlacementUpdate();
|
|
405
502
|
});
|
|
406
503
|
}
|
|
407
504
|
/** Immediately hides this feed's overlays until {@link resume} is called. */
|
|
@@ -422,6 +519,8 @@ var capacitorStripe = (function (exports, core) {
|
|
|
422
519
|
/** Hides stale overlays and remeasures after an application-driven layout change. */
|
|
423
520
|
async invalidateLayout() {
|
|
424
521
|
this.assertActive();
|
|
522
|
+
for (const state of this.slots.values())
|
|
523
|
+
state.lastPlacement = undefined;
|
|
425
524
|
this.layoutInvalidated = true;
|
|
426
525
|
this.scheduleEvaluation();
|
|
427
526
|
if (!(await this.requestPlacementUpdate())) {
|
|
@@ -506,7 +605,9 @@ var capacitorStripe = (function (exports, core) {
|
|
|
506
605
|
}
|
|
507
606
|
this.settleTimer = setTimeout(() => {
|
|
508
607
|
this.layoutInvalidated = false;
|
|
509
|
-
void this.runOperation(() =>
|
|
608
|
+
void this.runOperation(async () => {
|
|
609
|
+
await this.evaluate();
|
|
610
|
+
});
|
|
510
611
|
}, SCROLL_SETTLE_MS);
|
|
511
612
|
}
|
|
512
613
|
async evaluate() {
|
|
@@ -523,7 +624,7 @@ var capacitorStripe = (function (exports, core) {
|
|
|
523
624
|
.filter((state) => state.status === 'idle')
|
|
524
625
|
.slice(0, Math.max(0, MAX_NATIVE_ADS - occupied));
|
|
525
626
|
await Promise.allSettled(loadable.map((state) => this.loadState(state)));
|
|
526
|
-
|
|
627
|
+
await this.requestPlacementUpdate();
|
|
527
628
|
}
|
|
528
629
|
async loadState(state) {
|
|
529
630
|
var _a;
|
|
@@ -533,16 +634,7 @@ var capacitorStripe = (function (exports, core) {
|
|
|
533
634
|
state.status = 'loading';
|
|
534
635
|
const loadVersion = ++state.loadVersion;
|
|
535
636
|
try {
|
|
536
|
-
await bridge.loadNativeAd({
|
|
537
|
-
feedId: this.options.feedId,
|
|
538
|
-
sessionId: this.sessionId,
|
|
539
|
-
slotKey: state.slotKey,
|
|
540
|
-
template: (_a = this.options.template) !== null && _a !== void 0 ? _a : exports.NativeAdTemplate.Medium,
|
|
541
|
-
style: this.options.style,
|
|
542
|
-
adId: this.options.adId,
|
|
543
|
-
isTesting: this.options.isTesting,
|
|
544
|
-
npa: this.options.npa,
|
|
545
|
-
});
|
|
637
|
+
await bridge.loadNativeAd(Object.assign({ feedId: this.options.feedId, sessionId: this.sessionId, slotKey: state.slotKey, template: (_a = this.options.template) !== null && _a !== void 0 ? _a : exports.NativeAdTemplate.Medium, style: this.options.style, adId: this.options.adId, isTesting: this.options.isTesting, npa: this.options.npa }, (state.projectionSelector ? { projectionSelector: state.projectionSelector } : {})));
|
|
546
638
|
if (state.loadVersion === loadVersion) {
|
|
547
639
|
state.status = 'loaded';
|
|
548
640
|
state.lastUsed = Date.now();
|
|
@@ -576,6 +668,9 @@ var capacitorStripe = (function (exports, core) {
|
|
|
576
668
|
}
|
|
577
669
|
getVisibleStates() {
|
|
578
670
|
return [...this.slots.values()].filter((state) => {
|
|
671
|
+
var _a;
|
|
672
|
+
if (this.reuseProjectedPlacement(state))
|
|
673
|
+
return state.intersecting && !!((_a = state.lastPlacement) === null || _a === void 0 ? void 0 : _a.visible);
|
|
579
674
|
const measured = state.element && state.intersecting ? measureNativeAdSlot(state.element) : undefined;
|
|
580
675
|
return Boolean(measured && this.isSupportedSize(measured));
|
|
581
676
|
});
|
|
@@ -624,6 +719,7 @@ var capacitorStripe = (function (exports, core) {
|
|
|
624
719
|
return result;
|
|
625
720
|
}
|
|
626
721
|
async destroyResources() {
|
|
722
|
+
var _a;
|
|
627
723
|
await Promise.all([
|
|
628
724
|
...[...this.listenerHandles].map((handle) => handle.remove()),
|
|
629
725
|
...(this.nativeStarted && bridge
|
|
@@ -632,9 +728,39 @@ var capacitorStripe = (function (exports, core) {
|
|
|
632
728
|
]);
|
|
633
729
|
this.nativeStarted = false;
|
|
634
730
|
this.listenerHandles.clear();
|
|
731
|
+
for (const state of this.slots.values())
|
|
732
|
+
(_a = state.placementBinding) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
635
733
|
this.slots.clear();
|
|
636
734
|
this.elementSlots.clear();
|
|
637
735
|
}
|
|
736
|
+
reuseProjectedPlacement(state) {
|
|
737
|
+
var _a, _b, _c;
|
|
738
|
+
return Boolean(((_a = state.placementBinding) === null || _a === void 0 ? void 0 : _a.projected) &&
|
|
739
|
+
((_b = state.lastPlacement) === null || _b === void 0 ? void 0 : _b.visible) &&
|
|
740
|
+
((_c = state.element) === null || _c === void 0 ? void 0 : _c.isConnected) &&
|
|
741
|
+
!this.paused &&
|
|
742
|
+
!this.destroyed &&
|
|
743
|
+
!document.hidden &&
|
|
744
|
+
state.status === 'loaded' &&
|
|
745
|
+
state.lastPlacement.generation === state.generation);
|
|
746
|
+
}
|
|
747
|
+
measurePlacement(state) {
|
|
748
|
+
const measured = state.element ? measureNativeAdSlot(state.element, this.nativeScrollElement) : undefined;
|
|
749
|
+
return {
|
|
750
|
+
feedId: this.options.feedId,
|
|
751
|
+
slotKey: state.slotKey,
|
|
752
|
+
generation: state.generation,
|
|
753
|
+
visible: Boolean(!this.paused &&
|
|
754
|
+
!this.destroyed &&
|
|
755
|
+
state.status === 'loaded' &&
|
|
756
|
+
(!this.layoutInvalidated || this.options.androidScrollSnapshot) &&
|
|
757
|
+
measured &&
|
|
758
|
+
this.isSupportedSize(measured) &&
|
|
759
|
+
!document.hidden),
|
|
760
|
+
rect: measured === null || measured === void 0 ? void 0 : measured.rect,
|
|
761
|
+
clipRect: measured === null || measured === void 0 ? void 0 : measured.clipRect,
|
|
762
|
+
};
|
|
763
|
+
}
|
|
638
764
|
requestPlacementUpdate(allowDirect = false) {
|
|
639
765
|
this.updateDirty = true;
|
|
640
766
|
this.placementAcknowledgementRequired || (this.placementAcknowledgementRequired = !allowDirect);
|
|
@@ -652,19 +778,15 @@ var capacitorStripe = (function (exports, core) {
|
|
|
652
778
|
this.updateDirty = false;
|
|
653
779
|
const allowDirect = !this.placementAcknowledgementRequired;
|
|
654
780
|
this.placementAcknowledgementRequired = false;
|
|
781
|
+
const retainedSlots = new Set();
|
|
655
782
|
const placements = [...this.slots.values()]
|
|
656
783
|
.filter((state) => state.status === 'loaded')
|
|
657
784
|
.map((state) => {
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
generation: state.generation,
|
|
664
|
-
visible,
|
|
665
|
-
rect: measured === null || measured === void 0 ? void 0 : measured.rect,
|
|
666
|
-
clipRect: measured === null || measured === void 0 ? void 0 : measured.clipRect,
|
|
667
|
-
};
|
|
785
|
+
if (this.reuseProjectedPlacement(state)) {
|
|
786
|
+
retainedSlots.add(state.slotKey);
|
|
787
|
+
return state.lastPlacement;
|
|
788
|
+
}
|
|
789
|
+
return (state.lastPlacement = this.measurePlacement(state));
|
|
668
790
|
});
|
|
669
791
|
const scrollContainer = this.nativeScrollElement
|
|
670
792
|
? measureNativeAdScrollContainer(this.nativeScrollElement)
|
|
@@ -674,7 +796,17 @@ var capacitorStripe = (function (exports, core) {
|
|
|
674
796
|
continue;
|
|
675
797
|
}
|
|
676
798
|
try {
|
|
677
|
-
const batch = Object.assign({ feedId: this.options.feedId, sessionId: this.sessionId, sequence: ++this.placementSequence, placements
|
|
799
|
+
const batch = Object.assign({ feedId: this.options.feedId, sessionId: this.sessionId, sequence: ++this.placementSequence, placements: placements.map((placement) => {
|
|
800
|
+
return retainedSlots.has(placement.slotKey)
|
|
801
|
+
? {
|
|
802
|
+
feedId: placement.feedId,
|
|
803
|
+
slotKey: placement.slotKey,
|
|
804
|
+
generation: placement.generation,
|
|
805
|
+
visible: true,
|
|
806
|
+
retain: true,
|
|
807
|
+
}
|
|
808
|
+
: placement;
|
|
809
|
+
}) }, (scrollContainer ? { scrollContainer } : {}));
|
|
678
810
|
const channel = core.Capacitor.getPlatform() === 'android'
|
|
679
811
|
? window
|
|
680
812
|
.capacitorAdMobPlacements
|