myetv-player 1.6.0 → 1.6.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/README.md +1 -0
- package/css/myetv-player.css +29 -1
- package/css/myetv-player.min.css +1 -1
- package/dist/myetv-player.js +163 -49
- package/dist/myetv-player.min.js +134 -29
- package/package.json +3 -1
- package/plugins/iframe-ads/myetv-iframe-banner-ads.js +1037 -0
- package/plugins/iframe-ads/readme.md +191 -0
- package/plugins/vast-vpaid-ads/README.md +146 -0
|
@@ -0,0 +1,1037 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MyeTV Iframe Banner Ads Plugin
|
|
3
|
+
* Display iframe banner ads with countdown timer and auto-close functionality
|
|
4
|
+
* Supports both direct iframe URL and external ad script injection
|
|
5
|
+
*
|
|
6
|
+
* Created by https://www.myetv.tv - https://oskarcosimo.com
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // Method 1: Direct iframe URL
|
|
10
|
+
* const player = new MYETVvideoplayer('video', {
|
|
11
|
+
* plugins: {
|
|
12
|
+
* 'iframe-banner-ads': {
|
|
13
|
+
* url: 'https://your-ads-server.com/banner.html',
|
|
14
|
+
* duration: 7,
|
|
15
|
+
* opacity: 0.8,
|
|
16
|
+
* minTimeBetweenAds: 60, // seconds - minimum time before showing next ad
|
|
17
|
+
* repeatInterval: 90 // seconds - show ad every 90 seconds during playback
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // Method 2: External ad script
|
|
23
|
+
* const player = new MYETVvideoplayer('video', {
|
|
24
|
+
* plugins: {
|
|
25
|
+
* 'iframe-banner-ads': {
|
|
26
|
+
* adScript: 'https://store.myetv.tv/ads/CDN/publishers/adcode.js',
|
|
27
|
+
* adParams: {
|
|
28
|
+
* 'data-size': '728x90',
|
|
29
|
+
* 'data-language': '',
|
|
30
|
+
* 'data-country': 'all',
|
|
31
|
+
* 'data-category': 'all',
|
|
32
|
+
* 'data-uidcode': '7b71af83c540d5919a8c47baf3ef2b76d6c0aa4554c716ddce0a26d9cb88fd57'
|
|
33
|
+
* },
|
|
34
|
+
* duration: 7,
|
|
35
|
+
* opacity: 0.8,
|
|
36
|
+
* minTimeBetweenAds: 60,
|
|
37
|
+
* repeatInterval: 90
|
|
38
|
+
* }
|
|
39
|
+
* }
|
|
40
|
+
* });
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
(function () {
|
|
44
|
+
'use strict';
|
|
45
|
+
|
|
46
|
+
class IframeBannerAds {
|
|
47
|
+
constructor(player, options) {
|
|
48
|
+
this.player = player;
|
|
49
|
+
this.options = {
|
|
50
|
+
url: options.url || '',
|
|
51
|
+
adScript: options.adScript || '',
|
|
52
|
+
adParams: options.adParams || {},
|
|
53
|
+
duration: options.duration || 5, // seconds
|
|
54
|
+
opacity: options.opacity !== undefined ? options.opacity : 0.85,
|
|
55
|
+
showOnPlay: options.showOnPlay !== undefined ? options.showOnPlay : true,
|
|
56
|
+
showOnPause: options.showOnPause !== undefined ? options.showOnPause : false,
|
|
57
|
+
closeable: options.closeable !== undefined ? options.closeable : true,
|
|
58
|
+
minTimeBetweenAds: options.minTimeBetweenAds || 0, // seconds - 0 = disabled
|
|
59
|
+
repeatInterval: options.repeatInterval || 0, // seconds - 0 = disabled
|
|
60
|
+
cookieName: options.cookieName || 'myetv_last_ad_timestamp',
|
|
61
|
+
debug: options.debug || false
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Plugin state
|
|
65
|
+
this.banner = null;
|
|
66
|
+
this.contentContainer = null;
|
|
67
|
+
this.adContainer = null;
|
|
68
|
+
this.timerElement = null;
|
|
69
|
+
this.closeButton = null;
|
|
70
|
+
this.countdown = this.options.duration;
|
|
71
|
+
this.countdownInterval = null;
|
|
72
|
+
this.autoCloseTimeout = null;
|
|
73
|
+
this.repeatIntervalTimeout = null;
|
|
74
|
+
this.isVisible = false;
|
|
75
|
+
this.mode = null; // 'iframe' or 'script'
|
|
76
|
+
this.adShownCount = 0; // Track how many times ad was shown in this session
|
|
77
|
+
|
|
78
|
+
// Determine mode based on options
|
|
79
|
+
if (this.options.adScript) {
|
|
80
|
+
this.mode = 'script';
|
|
81
|
+
} else if (this.options.url) {
|
|
82
|
+
this.mode = 'iframe';
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (this.options.debug) {
|
|
86
|
+
console.log('[IframeBannerAds] Initialized with options:', this.options);
|
|
87
|
+
console.log('[IframeBannerAds] Mode:', this.mode);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Setup plugin - called by player after initialization
|
|
93
|
+
*/
|
|
94
|
+
setup() {
|
|
95
|
+
if (!this.mode) {
|
|
96
|
+
console.error('[IframeBannerAds] No URL or adScript provided');
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this.createBanner();
|
|
101
|
+
this.bindEvents();
|
|
102
|
+
this.injectStyles();
|
|
103
|
+
|
|
104
|
+
if (this.options.debug) {
|
|
105
|
+
console.log('[IframeBannerAds] Setup completed');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Cookie management - Set cookie
|
|
111
|
+
*/
|
|
112
|
+
setCookie(name, value, seconds) {
|
|
113
|
+
const date = new Date();
|
|
114
|
+
date.setTime(date.getTime() + (seconds * 1000));
|
|
115
|
+
const expires = "expires=" + date.toUTCString();
|
|
116
|
+
document.cookie = name + "=" + value + ";" + expires + ";path=/;SameSite=Lax";
|
|
117
|
+
|
|
118
|
+
if (this.options.debug) {
|
|
119
|
+
console.log('[IframeBannerAds] Cookie set:', name, '=', value, 'for', seconds, 'seconds');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Cookie management - Get cookie
|
|
125
|
+
*/
|
|
126
|
+
getCookie(name) {
|
|
127
|
+
const nameEQ = name + "=";
|
|
128
|
+
const ca = document.cookie.split(';');
|
|
129
|
+
for (let i = 0; i < ca.length; i++) {
|
|
130
|
+
let c = ca[i];
|
|
131
|
+
while (c.charAt(0) === ' ') c = c.substring(1, c.length);
|
|
132
|
+
if (c.indexOf(nameEQ) === 0) {
|
|
133
|
+
return c.substring(nameEQ.length, c.length);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Check if enough time has passed since last ad
|
|
141
|
+
*/
|
|
142
|
+
canShowAd() {
|
|
143
|
+
if (this.options.minTimeBetweenAds <= 0) {
|
|
144
|
+
// Feature disabled
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const lastAdTimestamp = this.getCookie(this.options.cookieName);
|
|
149
|
+
|
|
150
|
+
if (!lastAdTimestamp) {
|
|
151
|
+
// No previous ad shown
|
|
152
|
+
if (this.options.debug) {
|
|
153
|
+
console.log('[IframeBannerAds] No previous ad found - can show');
|
|
154
|
+
}
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const now = Math.floor(Date.now() / 1000); // Current timestamp in seconds
|
|
159
|
+
const lastAd = parseInt(lastAdTimestamp, 10);
|
|
160
|
+
const timePassed = now - lastAd;
|
|
161
|
+
|
|
162
|
+
if (this.options.debug) {
|
|
163
|
+
console.log('[IframeBannerAds] Time since last ad:', timePassed, 'seconds / Required:', this.options.minTimeBetweenAds);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return timePassed >= this.options.minTimeBetweenAds;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Update last ad timestamp
|
|
171
|
+
*/
|
|
172
|
+
updateLastAdTimestamp() {
|
|
173
|
+
const now = Math.floor(Date.now() / 1000);
|
|
174
|
+
// Set cookie for double the minTimeBetweenAds to ensure it persists
|
|
175
|
+
const cookieDuration = this.options.minTimeBetweenAds > 0 ? this.options.minTimeBetweenAds * 2 : 86400; // 24 hours default
|
|
176
|
+
this.setCookie(this.options.cookieName, now.toString(), cookieDuration);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Start repeat interval timer
|
|
181
|
+
*/
|
|
182
|
+
startRepeatInterval() {
|
|
183
|
+
// Clear any existing repeat timer
|
|
184
|
+
this.stopRepeatInterval();
|
|
185
|
+
|
|
186
|
+
if (this.options.repeatInterval <= 0) {
|
|
187
|
+
// Feature disabled
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (this.options.debug) {
|
|
192
|
+
console.log('[IframeBannerAds] Starting repeat interval:', this.options.repeatInterval, 'seconds');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
this.repeatIntervalTimeout = setTimeout(() => {
|
|
196
|
+
if (this.options.debug) {
|
|
197
|
+
console.log('[IframeBannerAds] Repeat interval triggered - showing ad again');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Show ad again if allowed
|
|
201
|
+
if (this.canShowAd()) {
|
|
202
|
+
this.show();
|
|
203
|
+
} else {
|
|
204
|
+
if (this.options.debug) {
|
|
205
|
+
console.log('[IframeBannerAds] Repeat blocked by minTimeBetweenAds');
|
|
206
|
+
}
|
|
207
|
+
// Try again after the remaining time
|
|
208
|
+
const lastAdTimestamp = this.getCookie(this.options.cookieName);
|
|
209
|
+
if (lastAdTimestamp) {
|
|
210
|
+
const now = Math.floor(Date.now() / 1000);
|
|
211
|
+
const timePassed = now - parseInt(lastAdTimestamp, 10);
|
|
212
|
+
const timeRemaining = this.options.minTimeBetweenAds - timePassed;
|
|
213
|
+
|
|
214
|
+
if (timeRemaining > 0) {
|
|
215
|
+
setTimeout(() => this.startRepeatInterval(), timeRemaining * 1000);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}, this.options.repeatInterval * 1000);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Stop repeat interval timer
|
|
224
|
+
*/
|
|
225
|
+
stopRepeatInterval() {
|
|
226
|
+
if (this.repeatIntervalTimeout) {
|
|
227
|
+
clearTimeout(this.repeatIntervalTimeout);
|
|
228
|
+
this.repeatIntervalTimeout = null;
|
|
229
|
+
|
|
230
|
+
if (this.options.debug) {
|
|
231
|
+
console.log('[IframeBannerAds] Repeat interval stopped');
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
injectStyles() {
|
|
237
|
+
const styleId = 'myetv-iframe-banner-ads-styles';
|
|
238
|
+
|
|
239
|
+
// Check if styles already exist
|
|
240
|
+
if (document.getElementById(styleId)) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const style = document.createElement('style');
|
|
245
|
+
style.id = styleId;
|
|
246
|
+
style.textContent = `
|
|
247
|
+
/* Iframe Banner Ads Plugin Styles */
|
|
248
|
+
.myetv-iframe-banner {
|
|
249
|
+
position: absolute;
|
|
250
|
+
bottom: var(--player-controls-height, 60px);
|
|
251
|
+
left: 50%;
|
|
252
|
+
transform: translateX(-50%);
|
|
253
|
+
width: clamp(300px, 90vw, 728px);
|
|
254
|
+
height: auto;
|
|
255
|
+
background: rgba(0, 0, 0, ${this.options.opacity});
|
|
256
|
+
border-radius: 8px;
|
|
257
|
+
z-index: 998;
|
|
258
|
+
display: none;
|
|
259
|
+
flex-direction: column;
|
|
260
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
|
261
|
+
overflow: visible;
|
|
262
|
+
transition: bottom 0.3s ease, all 0.3s ease;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.myetv-iframe-banner.visible {
|
|
266
|
+
display: flex;
|
|
267
|
+
animation: slideUp 0.4s ease-out;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
@keyframes slideUp {
|
|
271
|
+
from {
|
|
272
|
+
opacity: 0;
|
|
273
|
+
transform: translateX(-50%) translateY(20px);
|
|
274
|
+
}
|
|
275
|
+
to {
|
|
276
|
+
opacity: 1;
|
|
277
|
+
transform: translateX(-50%) translateY(0);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.myetv-iframe-banner.hidden {
|
|
282
|
+
animation: fadeOutSlideDown 0.5s ease-out forwards;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@keyframes fadeOutSlideDown {
|
|
286
|
+
0% {
|
|
287
|
+
opacity: 1;
|
|
288
|
+
transform: translateX(-50%) translateY(0);
|
|
289
|
+
}
|
|
290
|
+
100% {
|
|
291
|
+
opacity: 0;
|
|
292
|
+
transform: translateX(-50%) translateY(15px);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.myetv-iframe-banner-content {
|
|
297
|
+
flex: 0 0 90px;
|
|
298
|
+
position: relative;
|
|
299
|
+
overflow: hidden;
|
|
300
|
+
display: flex;
|
|
301
|
+
align-items: center;
|
|
302
|
+
justify-content: center;
|
|
303
|
+
border-radius: 8px 8px 0 0;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.myetv-iframe-banner-ad-container {
|
|
307
|
+
width: 100%;
|
|
308
|
+
height: 100%;
|
|
309
|
+
display: flex;
|
|
310
|
+
align-items: center;
|
|
311
|
+
justify-content: center;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.myetv-iframe-banner iframe {
|
|
315
|
+
width: 100%;
|
|
316
|
+
height: 100%;
|
|
317
|
+
border: none;
|
|
318
|
+
display: block;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.myetv-iframe-banner-close {
|
|
322
|
+
position: absolute;
|
|
323
|
+
top: 8px;
|
|
324
|
+
right: 8px;
|
|
325
|
+
width: 28px;
|
|
326
|
+
height: 28px;
|
|
327
|
+
background: rgba(0, 0, 0, 0.7);
|
|
328
|
+
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
329
|
+
border-radius: 50%;
|
|
330
|
+
color: #fff;
|
|
331
|
+
font-size: 18px;
|
|
332
|
+
line-height: 26px;
|
|
333
|
+
text-align: center;
|
|
334
|
+
cursor: pointer;
|
|
335
|
+
z-index: 999;
|
|
336
|
+
transition: background 0.2s ease, transform 0.2s ease;
|
|
337
|
+
font-weight: bold;
|
|
338
|
+
user-select: none;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.myetv-iframe-banner-close:hover {
|
|
342
|
+
background: rgba(255, 0, 0, 0.8);
|
|
343
|
+
transform: scale(1.1);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.myetv-iframe-banner-timer {
|
|
347
|
+
position: absolute;
|
|
348
|
+
bottom: -20px;
|
|
349
|
+
left: 50%;
|
|
350
|
+
transform: translateX(-50%);
|
|
351
|
+
background: rgba(0, 0, 0, 0.85);
|
|
352
|
+
color: #fff;
|
|
353
|
+
font-size: 12px;
|
|
354
|
+
padding: 6px 12px;
|
|
355
|
+
text-align: center;
|
|
356
|
+
font-family: Arial, sans-serif;
|
|
357
|
+
border-radius: 4px;
|
|
358
|
+
white-space: nowrap;
|
|
359
|
+
z-index: 999;
|
|
360
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/* Compact button mode when space is limited */
|
|
364
|
+
@media (max-width: 640px) and (max-height: 500px) {
|
|
365
|
+
.myetv-iframe-banner {
|
|
366
|
+
width: 75%; /* 3/4 of player width */
|
|
367
|
+
min-width: 300px;
|
|
368
|
+
max-width: 600px;
|
|
369
|
+
left: 50%; /* Center */
|
|
370
|
+
transform: translateX(-50%);
|
|
371
|
+
border-radius: 6px;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.myetv-iframe-banner.visible {
|
|
375
|
+
animation: slideUpLeft 0.4s ease-out;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
@keyframes slideUpLeft {
|
|
379
|
+
from {
|
|
380
|
+
opacity: 0;
|
|
381
|
+
transform: translateX(-20px) translateY(20px);
|
|
382
|
+
}
|
|
383
|
+
to {
|
|
384
|
+
opacity: 1;
|
|
385
|
+
transform: translateX(0) translateY(0);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.myetv-iframe-banner-content {
|
|
390
|
+
flex: 0 0 50px; /* Smaller height */
|
|
391
|
+
border-radius: 6px 6px 0 0;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
.myetv-iframe-banner-close {
|
|
395
|
+
width: 20px;
|
|
396
|
+
height: 20px;
|
|
397
|
+
font-size: 14px;
|
|
398
|
+
line-height: 18px;
|
|
399
|
+
top: 4px;
|
|
400
|
+
right: 4px;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
.myetv-iframe-banner-timer {
|
|
404
|
+
font-size: 10px;
|
|
405
|
+
padding: 4px 6px;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/* Extra compact mode for very small screens */
|
|
410
|
+
@media (max-width: 480px) and (max-height: 400px) {
|
|
411
|
+
.myetv-iframe-banner {
|
|
412
|
+
width: 75%; /* 3/4 of player width */
|
|
413
|
+
min-width: 250px;
|
|
414
|
+
max-width: 500px;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.myetv-iframe-banner-content {
|
|
418
|
+
flex: 0 0 40px;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.myetv-iframe-banner-timer {
|
|
422
|
+
font-size: 9px;
|
|
423
|
+
padding: 3px 4px;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/* Tablet adjustments - keep normal size */
|
|
428
|
+
@media (min-width: 641px) and (max-width: 768px) {
|
|
429
|
+
.myetv-iframe-banner-content {
|
|
430
|
+
flex: 0 0 75px;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/* Mobile portrait - keep full width but smaller */
|
|
435
|
+
@media (max-width: 480px) and (min-height: 501px) {
|
|
436
|
+
.myetv-iframe-banner-content {
|
|
437
|
+
flex: 0 0 60px;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
.myetv-iframe-banner-close {
|
|
441
|
+
width: 24px;
|
|
442
|
+
height: 24px;
|
|
443
|
+
font-size: 16px;
|
|
444
|
+
line-height: 22px;
|
|
445
|
+
top: 6px;
|
|
446
|
+
right: 6px;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
.myetv-iframe-banner-timer {
|
|
450
|
+
font-size: 11px;
|
|
451
|
+
padding: 6px 8px;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
`;
|
|
455
|
+
|
|
456
|
+
document.head.appendChild(style);
|
|
457
|
+
|
|
458
|
+
if (this.options.debug) {
|
|
459
|
+
console.log('[IframeBannerAds] Styles injected');
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Create banner DOM structure
|
|
465
|
+
*/
|
|
466
|
+
createBanner() {
|
|
467
|
+
// Create main banner container
|
|
468
|
+
this.banner = document.createElement('div');
|
|
469
|
+
this.banner.className = 'myetv-iframe-banner';
|
|
470
|
+
this.banner.setAttribute('role', 'complementary');
|
|
471
|
+
this.banner.setAttribute('aria-label', 'Advertisement');
|
|
472
|
+
|
|
473
|
+
// Create content container
|
|
474
|
+
this.contentContainer = document.createElement('div');
|
|
475
|
+
this.contentContainer.className = 'myetv-iframe-banner-content';
|
|
476
|
+
|
|
477
|
+
// Create ad container
|
|
478
|
+
this.adContainer = document.createElement('div');
|
|
479
|
+
this.adContainer.className = 'myetv-iframe-banner-ad-container';
|
|
480
|
+
|
|
481
|
+
// Load ad based on mode
|
|
482
|
+
if (this.mode === 'iframe') {
|
|
483
|
+
this.loadDirectIframe();
|
|
484
|
+
} else if (this.mode === 'script') {
|
|
485
|
+
this.loadAdScript();
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
this.contentContainer.appendChild(this.adContainer);
|
|
489
|
+
|
|
490
|
+
// Create close button (only if closeable option is true)
|
|
491
|
+
if (this.options.closeable) {
|
|
492
|
+
this.closeButton = document.createElement('div');
|
|
493
|
+
this.closeButton.className = 'myetv-iframe-banner-close';
|
|
494
|
+
this.closeButton.innerHTML = '×';
|
|
495
|
+
this.closeButton.setAttribute('role', 'button');
|
|
496
|
+
this.closeButton.setAttribute('aria-label', 'Close advertisement');
|
|
497
|
+
this.closeButton.addEventListener('click', (e) => {
|
|
498
|
+
e.stopPropagation();
|
|
499
|
+
this.hideBanner();
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
this.contentContainer.appendChild(this.closeButton);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Create timer element
|
|
506
|
+
this.timerElement = document.createElement('div');
|
|
507
|
+
this.timerElement.className = 'myetv-iframe-banner-timer';
|
|
508
|
+
this.updateTimerText();
|
|
509
|
+
|
|
510
|
+
// Assemble banner
|
|
511
|
+
this.banner.appendChild(this.contentContainer);
|
|
512
|
+
this.banner.appendChild(this.timerElement);
|
|
513
|
+
|
|
514
|
+
// Append to player container
|
|
515
|
+
if (this.player.container) {
|
|
516
|
+
this.player.container.appendChild(this.banner);
|
|
517
|
+
} else {
|
|
518
|
+
console.error('[IframeBannerAds] Player container not found');
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
if (this.options.debug) {
|
|
522
|
+
console.log('[IframeBannerAds] Banner created');
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Load direct iframe
|
|
528
|
+
*/
|
|
529
|
+
loadDirectIframe() {
|
|
530
|
+
const iframe = document.createElement('iframe');
|
|
531
|
+
iframe.src = this.options.url;
|
|
532
|
+
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms');
|
|
533
|
+
iframe.setAttribute('loading', 'lazy');
|
|
534
|
+
iframe.setAttribute('title', 'Advertisement');
|
|
535
|
+
|
|
536
|
+
this.adContainer.appendChild(iframe);
|
|
537
|
+
|
|
538
|
+
if (this.options.debug) {
|
|
539
|
+
console.log('[IframeBannerAds] Direct iframe loaded:', this.options.url);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Load external ad script with parameters
|
|
545
|
+
*/
|
|
546
|
+
loadAdScript() {
|
|
547
|
+
// Create script element
|
|
548
|
+
const script = document.createElement('script');
|
|
549
|
+
script.src = this.options.adScript;
|
|
550
|
+
|
|
551
|
+
// Apply data-* attributes from adParams
|
|
552
|
+
if (this.options.adParams && typeof this.options.adParams === 'object') {
|
|
553
|
+
for (const [key, value] of Object.entries(this.options.adParams)) {
|
|
554
|
+
script.setAttribute(key, value);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// Append script to ad container
|
|
559
|
+
this.adContainer.appendChild(script);
|
|
560
|
+
|
|
561
|
+
if (this.options.debug) {
|
|
562
|
+
console.log('[IframeBannerAds] Ad script loaded:', this.options.adScript);
|
|
563
|
+
console.log('[IframeBannerAds] Ad params:', this.options.adParams);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Bind player events
|
|
569
|
+
*/
|
|
570
|
+
bindEvents() {
|
|
571
|
+
if (this.options.showOnPlay) {
|
|
572
|
+
this.player.addEventListener('played', () => {
|
|
573
|
+
if (this.options.debug) {
|
|
574
|
+
console.log('[IframeBannerAds] Video played - checking if can show banner');
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
if (this.canShowAd()) {
|
|
578
|
+
this.show();
|
|
579
|
+
} else {
|
|
580
|
+
if (this.options.debug) {
|
|
581
|
+
console.log('[IframeBannerAds] Ad blocked by minTimeBetweenAds');
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
if (this.options.showOnPause) {
|
|
588
|
+
this.player.addEventListener('paused', () => {
|
|
589
|
+
if (this.options.debug) {
|
|
590
|
+
console.log('[IframeBannerAds] Video paused - checking if can show banner');
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
if (this.canShowAd()) {
|
|
594
|
+
this.show();
|
|
595
|
+
} else {
|
|
596
|
+
if (this.options.debug) {
|
|
597
|
+
console.log('[IframeBannerAds] Ad blocked by minTimeBetweenAds');
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// Hide banner when video ends and stop repeat interval
|
|
604
|
+
this.player.addEventListener('ended', () => {
|
|
605
|
+
if (this.options.debug) {
|
|
606
|
+
console.log('[IframeBannerAds] Video ended - hiding banner and stopping repeat');
|
|
607
|
+
}
|
|
608
|
+
this.hide();
|
|
609
|
+
this.stopRepeatInterval();
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
if (this.options.debug) {
|
|
613
|
+
console.log('[IframeBannerAds] Events bound');
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// Setup controlbar tracking
|
|
617
|
+
this.setupControlbarTracking();
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Setup controlbar tracking to move banner with controlbar
|
|
623
|
+
*/
|
|
624
|
+
setupControlbarTracking() {
|
|
625
|
+
if (!this.player || !this.player.container) {
|
|
626
|
+
if (this.options.debug) {
|
|
627
|
+
console.log('[IframeBannerAds] Cannot setup controlbar tracking');
|
|
628
|
+
}
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
const updatePosition = () => {
|
|
633
|
+
requestAnimationFrame(() => this.updateBannerPosition());
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
this.controlbarObserver = new MutationObserver(() => updatePosition());
|
|
637
|
+
this.controlbarObserver.observe(this.player.container, {
|
|
638
|
+
attributes: true,
|
|
639
|
+
attributeFilter: ['class', 'style'],
|
|
640
|
+
subtree: true,
|
|
641
|
+
childList: false
|
|
642
|
+
});
|
|
643
|
+
|
|
644
|
+
let mouseTimer;
|
|
645
|
+
this.player.container.addEventListener('mousemove', () => {
|
|
646
|
+
clearTimeout(mouseTimer);
|
|
647
|
+
mouseTimer = setTimeout(() => updatePosition(), 50);
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
this.player.container.addEventListener('mouseleave', () => {
|
|
651
|
+
clearTimeout(mouseTimer);
|
|
652
|
+
mouseTimer = setTimeout(() => updatePosition(), 300);
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
if (this.player.addEventListener) {
|
|
656
|
+
this.player.addEventListener('controlsshown', () => updatePosition());
|
|
657
|
+
this.player.addEventListener('controlshidden', () => updatePosition());
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
setTimeout(() => updatePosition(), 100);
|
|
661
|
+
|
|
662
|
+
if (this.options.debug) {
|
|
663
|
+
console.log('[IframeBannerAds] Controlbar tracking setup completed');
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Update banner position based on controlbar visibility
|
|
669
|
+
*/
|
|
670
|
+
updateBannerPosition() {
|
|
671
|
+
if (!this.banner || !this.player || !this.player.container || !this.isVisible) {
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
const controlbar = this.player.container.querySelector('.myetv-controls-container') ||
|
|
676
|
+
this.player.container.querySelector('.myetv-controls') ||
|
|
677
|
+
this.player.container.querySelector('[class*="controls"]');
|
|
678
|
+
|
|
679
|
+
if (!controlbar) {
|
|
680
|
+
if (this.options.debug) {
|
|
681
|
+
console.log('[IframeBannerAds] Controlbar not found');
|
|
682
|
+
}
|
|
683
|
+
this.banner.style.bottom = '10px';
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
const computedStyle = window.getComputedStyle(controlbar);
|
|
688
|
+
const rect = controlbar.getBoundingClientRect();
|
|
689
|
+
|
|
690
|
+
const isHidden =
|
|
691
|
+
controlbar.classList.contains('hidden') ||
|
|
692
|
+
controlbar.classList.contains('myetv-controls-hidden') ||
|
|
693
|
+
computedStyle.opacity === '0' ||
|
|
694
|
+
computedStyle.visibility === 'hidden' ||
|
|
695
|
+
computedStyle.display === 'none' ||
|
|
696
|
+
rect.height === 0;
|
|
697
|
+
|
|
698
|
+
let newBottom;
|
|
699
|
+
if (isHidden) {
|
|
700
|
+
newBottom = '10px';
|
|
701
|
+
} else {
|
|
702
|
+
const controlbarHeight = controlbar.offsetHeight || rect.height || 60;
|
|
703
|
+
newBottom = `${controlbarHeight + 5}px`;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
if (this.banner.style.bottom !== newBottom) {
|
|
707
|
+
this.banner.style.bottom = newBottom;
|
|
708
|
+
|
|
709
|
+
if (this.options.debug) {
|
|
710
|
+
console.log(`[IframeBannerAds] Banner repositioned to: ${newBottom} (controlbar ${isHidden ? 'hidden' : 'visible'})`);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* Update timer text display
|
|
716
|
+
*/
|
|
717
|
+
updateTimerText() {
|
|
718
|
+
if (this.timerElement) {
|
|
719
|
+
if (this.countdown > 0) {
|
|
720
|
+
this.timerElement.textContent = `This ad will close in ${this.countdown} second${this.countdown !== 1 ? 's' : ''}`;
|
|
721
|
+
} else {
|
|
722
|
+
this.timerElement.textContent = 'Closing...';
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Start countdown timer
|
|
729
|
+
*/
|
|
730
|
+
startCountdown() {
|
|
731
|
+
// Clear any existing timers
|
|
732
|
+
this.stopCountdown();
|
|
733
|
+
|
|
734
|
+
this.countdown = this.options.duration;
|
|
735
|
+
this.updateTimerText();
|
|
736
|
+
|
|
737
|
+
// Countdown interval (updates every second)
|
|
738
|
+
this.countdownInterval = setInterval(() => {
|
|
739
|
+
this.countdown--;
|
|
740
|
+
this.updateTimerText();
|
|
741
|
+
|
|
742
|
+
if (this.countdown <= 0) {
|
|
743
|
+
clearInterval(this.countdownInterval);
|
|
744
|
+
this.countdownInterval = null;
|
|
745
|
+
}
|
|
746
|
+
}, 1000);
|
|
747
|
+
|
|
748
|
+
// Auto-close timeout
|
|
749
|
+
this.autoCloseTimeout = setTimeout(() => {
|
|
750
|
+
if (this.options.debug) {
|
|
751
|
+
console.log('[IframeBannerAds] Auto-closing banner');
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// Clear interval first
|
|
755
|
+
if (this.countdownInterval) {
|
|
756
|
+
clearInterval(this.countdownInterval);
|
|
757
|
+
this.countdownInterval = null;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
// Then hide
|
|
761
|
+
this.hideBanner();
|
|
762
|
+
|
|
763
|
+
}, this.options.duration * 1000);
|
|
764
|
+
|
|
765
|
+
if (this.options.debug) {
|
|
766
|
+
console.log('[IframeBannerAds] Countdown started:', this.options.duration, 'seconds');
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* Stop countdown timer
|
|
772
|
+
*/
|
|
773
|
+
stopCountdown() {
|
|
774
|
+
if (this.countdownInterval) {
|
|
775
|
+
clearInterval(this.countdownInterval);
|
|
776
|
+
this.countdownInterval = null;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
if (this.autoCloseTimeout) {
|
|
780
|
+
clearTimeout(this.autoCloseTimeout);
|
|
781
|
+
this.autoCloseTimeout = null;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
if (this.options.debug) {
|
|
785
|
+
console.log('[IframeBannerAds] Countdown stopped');
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* Show banner
|
|
791
|
+
*/
|
|
792
|
+
show() {
|
|
793
|
+
if (this.isVisible || !this.banner) {
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// Check again if we can show the ad
|
|
798
|
+
if (!this.canShowAd()) {
|
|
799
|
+
if (this.options.debug) {
|
|
800
|
+
console.log('[IframeBannerAds] Cannot show ad - time restriction');
|
|
801
|
+
}
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
this.banner.style.display = 'flex';
|
|
806
|
+
this.banner.style.opacity = '1';
|
|
807
|
+
this.banner.classList.remove('hidden');
|
|
808
|
+
this.banner.classList.add('visible');
|
|
809
|
+
this.isVisible = true;
|
|
810
|
+
this.adShownCount++;
|
|
811
|
+
|
|
812
|
+
// Update banner position
|
|
813
|
+
setTimeout(() => this.updateBannerPosition(), 150);
|
|
814
|
+
|
|
815
|
+
// Update last ad timestamp
|
|
816
|
+
this.updateLastAdTimestamp();
|
|
817
|
+
|
|
818
|
+
// Start countdown
|
|
819
|
+
this.startCountdown();
|
|
820
|
+
|
|
821
|
+
// Start repeat interval if configured
|
|
822
|
+
if (this.options.repeatInterval > 0) {
|
|
823
|
+
this.startRepeatInterval();
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
if (this.options.debug) {
|
|
827
|
+
console.log('[IframeBannerAds] Banner shown (count:', this.adShownCount + ')');
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
/**
|
|
832
|
+
* Hide banner - SINGLE METHOD used by both X button and auto-close
|
|
833
|
+
*/
|
|
834
|
+
hideBanner() {
|
|
835
|
+
if (!this.banner) {
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
// Stop all timers
|
|
840
|
+
if (this.countdownInterval) {
|
|
841
|
+
clearInterval(this.countdownInterval);
|
|
842
|
+
this.countdownInterval = null;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
if (this.autoCloseTimeout) {
|
|
846
|
+
clearTimeout(this.autoCloseTimeout);
|
|
847
|
+
this.autoCloseTimeout = null;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
// Set flag immediately
|
|
851
|
+
this.isVisible = false;
|
|
852
|
+
|
|
853
|
+
// Fadeout animation via JavaScript
|
|
854
|
+
let opacity = 1;
|
|
855
|
+
const fadeInterval = setInterval(() => {
|
|
856
|
+
opacity -= 0.05;
|
|
857
|
+
|
|
858
|
+
if (opacity <= 0) {
|
|
859
|
+
clearInterval(fadeInterval);
|
|
860
|
+
|
|
861
|
+
// Hide completely after fadeout
|
|
862
|
+
if (this.banner) {
|
|
863
|
+
this.banner.style.display = 'none';
|
|
864
|
+
this.banner.style.opacity = '1';
|
|
865
|
+
this.banner.classList.remove('visible');
|
|
866
|
+
this.banner.classList.remove('hidden');
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
if (this.options.debug) {
|
|
870
|
+
console.log('[IframeBannerAds] Banner hidden');
|
|
871
|
+
}
|
|
872
|
+
} else {
|
|
873
|
+
if (this.banner) {
|
|
874
|
+
this.banner.style.opacity = opacity;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
}, 25);
|
|
878
|
+
|
|
879
|
+
// Add hidden class for other animations
|
|
880
|
+
this.banner.classList.add('hidden');
|
|
881
|
+
this.banner.classList.remove('visible');
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* Hide banner
|
|
886
|
+
*/
|
|
887
|
+
hide() {
|
|
888
|
+
this.hideBanner();
|
|
889
|
+
// Don't stop repeat interval here - it continues until video ends
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* Toggle banner visibility
|
|
894
|
+
*/
|
|
895
|
+
toggle() {
|
|
896
|
+
if (this.isVisible) {
|
|
897
|
+
this.hide();
|
|
898
|
+
} else {
|
|
899
|
+
this.show();
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* Update iframe URL (only for direct iframe mode)
|
|
905
|
+
*/
|
|
906
|
+
setUrl(newUrl) {
|
|
907
|
+
if (this.mode !== 'iframe') {
|
|
908
|
+
console.warn('[IframeBannerAds] setUrl() only works in iframe mode');
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
if (newUrl) {
|
|
913
|
+
this.options.url = newUrl;
|
|
914
|
+
|
|
915
|
+
// Clear and reload
|
|
916
|
+
this.adContainer.innerHTML = '';
|
|
917
|
+
this.loadDirectIframe();
|
|
918
|
+
|
|
919
|
+
if (this.options.debug) {
|
|
920
|
+
console.log('[IframeBannerAds] URL updated:', newUrl);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* Update ad script parameters (only for script mode)
|
|
927
|
+
*/
|
|
928
|
+
setAdParams(newParams) {
|
|
929
|
+
if (this.mode !== 'script') {
|
|
930
|
+
console.warn('[IframeBannerAds] setAdParams() only works in script mode');
|
|
931
|
+
return;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
if (newParams && typeof newParams === 'object') {
|
|
935
|
+
this.options.adParams = { ...this.options.adParams, ...newParams };
|
|
936
|
+
|
|
937
|
+
// Clear and reload
|
|
938
|
+
this.adContainer.innerHTML = '';
|
|
939
|
+
this.loadAdScript();
|
|
940
|
+
|
|
941
|
+
if (this.options.debug) {
|
|
942
|
+
console.log('[IframeBannerAds] Ad params updated:', this.options.adParams);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Update banner duration
|
|
949
|
+
*/
|
|
950
|
+
setDuration(seconds) {
|
|
951
|
+
if (typeof seconds === 'number' && seconds > 0) {
|
|
952
|
+
this.options.duration = seconds;
|
|
953
|
+
|
|
954
|
+
if (this.options.debug) {
|
|
955
|
+
console.log('[IframeBannerAds] Duration updated:', seconds);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
/**
|
|
961
|
+
* Update banner opacity
|
|
962
|
+
*/
|
|
963
|
+
setOpacity(opacity) {
|
|
964
|
+
if (typeof opacity === 'number' && opacity >= 0 && opacity <= 1) {
|
|
965
|
+
this.options.opacity = opacity;
|
|
966
|
+
|
|
967
|
+
if (this.banner) {
|
|
968
|
+
this.banner.style.background = `rgba(0, 0, 0, ${opacity})`;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
if (this.options.debug) {
|
|
972
|
+
console.log('[IframeBannerAds] Opacity updated:', opacity);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* Get plugin state
|
|
979
|
+
*/
|
|
980
|
+
getState() {
|
|
981
|
+
return {
|
|
982
|
+
mode: this.mode,
|
|
983
|
+
isVisible: this.isVisible,
|
|
984
|
+
countdown: this.countdown,
|
|
985
|
+
url: this.options.url,
|
|
986
|
+
adScript: this.options.adScript,
|
|
987
|
+
adParams: this.options.adParams,
|
|
988
|
+
duration: this.options.duration,
|
|
989
|
+
opacity: this.options.opacity,
|
|
990
|
+
minTimeBetweenAds: this.options.minTimeBetweenAds,
|
|
991
|
+
repeatInterval: this.options.repeatInterval,
|
|
992
|
+
adShownCount: this.adShownCount,
|
|
993
|
+
lastAdTimestamp: this.getCookie(this.options.cookieName)
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
/**
|
|
998
|
+
* Dispose plugin - cleanup
|
|
999
|
+
*/
|
|
1000
|
+
dispose() {
|
|
1001
|
+
if (this.options.debug) {
|
|
1002
|
+
console.log('[IframeBannerAds] Disposing plugin');
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
// Stop timers
|
|
1006
|
+
this.stopCountdown();
|
|
1007
|
+
this.stopRepeatInterval();
|
|
1008
|
+
|
|
1009
|
+
// Cleanup controlbar tracking
|
|
1010
|
+
if (this.controlbarObserver) {
|
|
1011
|
+
this.controlbarObserver.disconnect();
|
|
1012
|
+
this.controlbarObserver = null;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// Remove DOM elements
|
|
1016
|
+
if (this.banner && this.banner.parentNode) {
|
|
1017
|
+
this.banner.parentNode.removeChild(this.banner);
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
// Clear references
|
|
1021
|
+
this.banner = null;
|
|
1022
|
+
this.contentContainer = null;
|
|
1023
|
+
this.adContainer = null;
|
|
1024
|
+
this.timerElement = null;
|
|
1025
|
+
this.closeButton = null;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
// Register plugin globally
|
|
1030
|
+
if (typeof window !== 'undefined' && typeof window.registerMYETVPlugin === 'function') {
|
|
1031
|
+
window.registerMYETVPlugin('iframe-banner-ads', IframeBannerAds);
|
|
1032
|
+
console.log('[MyeTV] Iframe Banner Ads plugin registered');
|
|
1033
|
+
} else {
|
|
1034
|
+
console.error('[IframeBannerAds] Plugin registration failed - registerMYETVPlugin not available');
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
})();
|