@betarena/ad-engine 0.3.0 → 0.3.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@betarena/ad-engine",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "private": false,
5
5
  "description": "Betarena ad-engine widget",
6
6
  "keywords": [
@@ -88,7 +88,7 @@
88
88
  "vite": "5.1.6"
89
89
  },
90
90
  "dependencies": {
91
- "@betarena/scores-lib": "4.1.0",
91
+ "@betarena/scores-lib": "4.14.11",
92
92
  "@fontsource/roboto": "5.0.12",
93
93
  "chalk": "5.3.0",
94
94
  "colorthief": "2.6.0",
@@ -106,9 +106,20 @@
106
106
  * @description
107
107
  * 📝 Condition for testing
108
108
  */
109
- isStandalone = true
109
+ isStandalone = true,
110
+ /**
111
+ * @description
112
+ * 📝 Signal from the host that the current page is an article page.
113
+ * Zone 1 body-mounted ads (slider/popup) must only inject when this is `true`.
114
+ * Defaults to `false` so the widget fails closed on non-article pages.
115
+ */
116
+ isArticlePage: boolean = false
110
117
  ;
111
118
 
119
+ // Retained as a supported public prop for API compatibility.
120
+ // Device detection is UA-based; this value is not consumed internally.
121
+ $: void deviceWidthList;
122
+
112
123
  /**
113
124
  * @description
114
125
  * 📝 Component Local Interface
@@ -583,7 +594,7 @@
583
594
  // │ |: (not from DOM-filtered targetZoneIds) so global placements inject correctly
584
595
  // │ |: even when no zone-1 element exists in the DOM.
585
596
  // ╰─────
586
- if (includesGlobalZone && (authorId || authorArticleTagIds.length > 0))
597
+ if (includesGlobalZone && isArticlePage && (authorId || authorArticleTagIds.length > 0))
587
598
  {
588
599
  // ╭─────
589
600
  // │ NOTE:
@@ -760,7 +771,7 @@
760
771
  // │ |: Inject STANDARD SLIDER adverts in 'document.body'
761
772
  // │ |: Guard with `includesGlobalZone` to avoid body injections on scoped refreshes.
762
773
  // ╰─────
763
- else if (includesGlobalZone)
774
+ else if (includesGlobalZone && isArticlePage)
764
775
  {
765
776
  // [🐞]
766
777
  logger
@@ -773,11 +784,25 @@
773
784
 
774
785
  // ╭─────
775
786
  // │ NOTE:
776
- // │ |: Loop over creative data and inject adverts
787
+ // │ |: Loop over creative data and inject adverts.
788
+ // │ |: Build a Set of creative IDs that belong to zone 1 so we only
789
+ // │ |: inject zone-1-specific creatives rather than all slider-type creatives.
777
790
  // ╰─────
778
- for (const [, adData] of mapCreative)
791
+ const
792
+ zone1CampaignIds
793
+ = mapZoneIdToCampaignId.get(1) ?? [],
794
+ zone1CreativeIds
795
+ = new Set
796
+ (
797
+ zone1CampaignIds
798
+ .flatMap(campaignId => mapCampaignIdToCreativeId.get(campaignId) ?? [])
799
+ )
800
+ ;
801
+
802
+ for (const [creativeId, adData] of mapCreative)
779
803
  {
780
804
  if (adData.type != 1) continue;
805
+ if (!zone1CreativeIds.has(creativeId)) continue;
781
806
 
782
807
  listAdWidgetElements.push
783
808
  (
@@ -903,7 +928,7 @@
903
928
  {
904
929
  deviceType,
905
930
  isoCountryCode: geoLocation?.country_code ?? 'EN',
906
- authorId,
931
+ authorId: authorId ?? undefined,
907
932
  tagIds: authorArticleTagIds,
908
933
  zoneIds: targetZoneIds
909
934
  },
@@ -1062,7 +1087,7 @@
1062
1087
 
1063
1088
  {#if isStandalone}
1064
1089
  <link rel="preconnect" href="https://fonts.googleapis.com">
1065
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
1090
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous">
1066
1091
  <link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
1067
1092
  {/if}
1068
1093
 
@@ -106,6 +106,7 @@
106
106
  width=250
107
107
  height=250
108
108
  src={adData.data.media}
109
+ title="Betarena advert"
109
110
  />
110
111
  <!--
111
112
  <video
@@ -262,10 +262,12 @@
262
262
  >
263
263
  <a
264
264
  target='_blank'
265
+ rel='noopener noreferrer'
265
266
  on:click=
266
267
  {
267
268
  () =>
268
269
  {
270
+ if (objectAdvertData.id === undefined) return;
269
271
  new ServiceAdEngine
270
272
  (
271
273
  betarenaEndpoint
@@ -114,11 +114,13 @@
114
114
 
115
115
  <a
116
116
  target='_blank'
117
+ rel='noopener noreferrer'
117
118
  href={objectAdvertData.data?.cta_link}
118
119
  on:click=
119
120
  {
120
121
  () =>
121
122
  {
123
+ if (objectAdvertData.id === undefined) return;
122
124
  new ServiceAdEngine
123
125
  (
124
126
  betarenaEndpoint
@@ -247,16 +247,11 @@
247
247
  ╰─────
248
248
  -->
249
249
  {#if isAdvertCloseBtnShown}
250
- <img
251
- id='close'
252
- src={iconClose}
253
- alt='icon-close'
254
- title='icon-close'
255
- loading='lazy'
256
- class=
257
- "
258
- cursor-pointer
259
- "
250
+ <button
251
+ type="button"
252
+ aria-label="Close advert"
253
+ class="cursor-pointer"
254
+ style="background:none;border:none;padding:0;"
260
255
  on:click=
261
256
  {
262
257
  () =>
@@ -274,7 +269,14 @@
274
269
  return;
275
270
  }
276
271
  }
277
- />
272
+ >
273
+ <img
274
+ class='close-btn'
275
+ src={iconClose}
276
+ alt=''
277
+ loading='lazy'
278
+ />
279
+ </button>
278
280
  {/if}
279
281
 
280
282
  <!--
@@ -295,6 +297,7 @@
295
297
  {
296
298
  () =>
297
299
  {
300
+ if (adData.id === undefined) return;
298
301
  new ServiceAdEngine
299
302
  (
300
303
  betarenaEndpoint
@@ -428,6 +431,7 @@
428
431
  {
429
432
  () =>
430
433
  {
434
+ if (adData.id === undefined) return;
431
435
  new ServiceAdEngine
432
436
  (
433
437
  betarenaEndpoint
@@ -520,7 +524,7 @@
520
524
 
521
525
  img
522
526
  {
523
- &#close
527
+ &.close-btn
524
528
  {
525
529
  /* 📌 position */
526
530
  position: absolute;