PageSourceSearch

https://www.patrimonionacional.es/themes/custom/patrimonio/js/jquery.youtube-background.js?tltgvy

js patrimonionacional.es collected 2026-09-24 08:54:30 UTC 17,045 bytes, 609 lines download raw bytes

1/* jquery.youtube-background v1.0.7 | Nikola Stamatovic <@stamat> | MIT */
2
3var tag = document.createElement('script');
4tag.src = "https://www.youtube.com/player_api";
5var firstScriptTag = document.getElementsByTagName('script')[0];
6firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
7
8
9//native addClass, removeClass, hasClass and toggleClass
10if (!window.hasOwnProperty('d0')) {
11	window.d0 = {};
12
13	d0.hasClass = function(element, className) {
14		if (element.classList) {
15			return element.classList.contains(className);
16		}
17	    return new RegExp('\\b'+ className+'\\b').test(element.className);
18	};
19
20	d0.addClass = function(element, className) {
21	    if (element.classList) {
22			element.classList.add(className);
23			return;
24		}
25
26		if (!d0.hasClass(element, className)) {
27			element.className += ' ' + className;
28		}
29	};
30
31	d0.removeClass = function(element, className) {
32	    if (element.classList) {
33			element.classList.remove(className);
34			return;
35		}
36
37		element.className = element.className.replace(new RegExp('\\b'+ className+'\\b', 'g'), '');
38	};
39
40	d0.toogleClass = function(element, className) {
41	    if (d0.hasClass(element, className)) {
42			d0.removeClass(element, className);
43		} else {
44			d0.addClass(element, className);
45		}
46	};
47}
48
49function YoutubeBackground(elem, params, id, uid) {
50	this.is_mobile = this.isMobile();
51
52	this.element = elem;
53	this.ytid = id;
54	this.uid = uid;
55	this.player = null;
56	this.buttons = {};
57
58	this.state = {};
59	this.state.play = false;
60	this.state.mute = false;
61
62	this.params = {};
63
64	this.defaults = {
65		'pause': false, //deprecated
66		'play-button': false,
67		'mute-button': false,
68		'autoplay': true,
69		'muted': true,
70		'loop': true,
71		'mobile': false,
72		'load-background': true,
73		'resolution': '16:9',
74		'offset': 200
75	};
76
77	this.__init__ = function () {
78		if (!this.ytid) {
79			return;
80		}
81
82		this.parseProperties(params);
83		this.params.resolution_mod = this.parseResolutionString(this.params.resolution);
84		this.state.playing = this.params.autoplay;
85		this.state.muted = this.params.muted;
86
87		this.buildHTML();
88		this.injectIFrame();
89
90
91		if (this.params['play-button']) {
92			this.generateActionButton({
93				name: 'play',
94				className: 'play-toggle',
95				innerHtml: '<i class="fa"></i>',
96				initialState: false,
97				stateClassName: 'paused',
98				condition_parameter: 'autoplay',
99				stateChildClassNames: ['fa-pause-circle', 'fa-play-circle'],
100				actions: ['play', 'pause']
101			});
102		}
103
104		if (this.params['mute-button']) {
105			this.generateActionButton({
106				name: 'mute',
107				className: 'mute-toggle',
108				innerHtml: '<i class="fa"></i>',
109				initialState: true,
110				stateClassName: 'muted',
111				condition_parameter: 'muted',
112				stateChildClassNames: ['fa-volume-up', 'fa-volume-mute'],
113				actions: ['unmute', 'mute']
114			});
115		}
116	}
117
118	this.__init__();
119}
120
121YoutubeBackground.prototype.initYTPlayer = function () {
122	var self = this;
123
124	if (window.hasOwnProperty('YT')) {
125		this.player = new YT.Player(this.uid, {
126			events: {
127				'onReady': function(event) {
128					self.onVideoPlayerReady(event);
129				},
130				'onStateChange': function(event) {
131					self.onVideoStateChange(event);
132				},
133				'onError' : function(event) {
134					//console.error('player_api', event);
135				}
136			}
137		});
138	}
139};
140
141YoutubeBackground.prototype.onVideoPlayerReady = function (event) {
142	if (this.params.autoplay) {
143		event.target.playVideo();
144	}
145};
146
147YoutubeBackground.prototype.onVideoStateChange = function (event) {
148	if (event.data === 0 && this.params.loop) {
149		event.target.playVideo();
150	}
151
152	if (event.data === -1 && this.params.autoplay) {
153		event.target.playVideo();
154	}
155
156	if (event.data === 1) {
157		this.iframe.style.opacity = 1;
158	}
159};
160
161YoutubeBackground.prototype.parseProperties = function (params) {
162	if (!params) {
163		this.params = this.defaults;
164	} else {
165		//load in defaults
166		for (var k in this.defaults) {
167			if (!this.params.hasOwnProperty(k)) {
168				this.params[k] = this.defaults[k];
169			}
170		}
171	}
172
173	// load params from data attributes
174	for (var k in this.params) {
175		var data = this.element.getAttribute('data-ytbg-'+k);
176
177		if (data !== undefined && data !== null) {
178			switch (data) {
179				case data === 'false':
180					data = false;
181					break;
182				case data === 'true':
183					data = true;
184					break;
185			}
186
187			this.params[k] = data;
188		}
189	}
190
191	//pause deprecated
192	if (this.params.pause) {
193		this.params['play-button'] = this.params.pause;
194	}
195};
196
197YoutubeBackground.prototype.injectIFrame = function () {
198	this.iframe = document.createElement('iframe');
199	this.iframe.setAttribute('frameborder', 0);
200	this.iframe.setAttribute('allow', ['autoplay; mute']);
201	var src = 'https://www.youtube.com/embed/'+this.ytid+'?enablejsapi=1&disablekb=1&controls=0&rel=0&iv_load_policy=3&cc_load_policy=0&playsinline=1&showinfo=0&modestbranding=1&fs=0&origin='+window.location.origin;
202
203	if (this.params.muted) {
204		src += '&mute=1';
205	}
206
207	if (this.params.autoplay) {
208		src += '&autoplay=1';
209	}
210
211	if (this.params.loop) {
212		src += '&loop=1';
213	}
214
215	this.iframe.src = src;
216
217	if (this.uid) {
218		this.iframe.id = this.uid;
219	}
220
221	this.iframe.style.top = '50%';
222	this.iframe.style.left = '50%';
223	this.iframe.style.transform = 'translateX(-50%) translateY(-50%)';
224	this.iframe.style.position = 'absolute';
225	this.iframe.style.opacity = 0;
226
227	this.element.parentNode.appendChild(this.iframe);
228	this.iframe.parentNode.removeChild(this.element);
229
230	var self = this;
231
232	function onResize() {
233		var h = self.iframe.parentNode.offsetHeight + self.params.offset; // since showinfo is deprecated and ignored after September 25, 2018. we add +200 to hide it in the overflow
234		var w = self.iframe.parentNode.offsetWidth + self.params.offset;
235		var res = self.params.resolution_mod;
236
237		if (res > w/h) {
238			self.iframe.style.width = h*res + 'px';
239			self.iframe.style.height = h + 'px';
240		} else {
241			self.iframe.style.width = w + 'px';
242			self.iframe.style.height = w/res + 'px';
243		}
244	}
245
246	window.addEventListener('resize', onResize);
247	onResize();
248};
249
250YoutubeBackground.prototype.buildHTML = function () {
251	var parent = this.element.parentNode;
252	// wrap
253	var wrapper = document.createElement('div');
254	wrapper.className = 'youtube-background';
255	parent.insertBefore(wrapper, this.element);
256	wrapper.appendChild(this.element);
257	var id = this.element.id;
258	this.element.id = '';
259	wrapper.id = id;
260
261	//set css rules
262	var wrapper_styles = {
263		"height" : "100%",
264		"width" : "100%",
265		"z-index": "0",
266		"position": "absolute",
267		"overflow": "hidden",
268		"top": 0, // added by @insad
269		"left": 0,
270		"bottom": 0,
271		"right": 0
272	};
273
274	if (!this.params['mute-button']) {
275		wrapper_styles["pointer-events"] = "none" // avoid right mouse click popup menu
276	}
277
278	if (this.params['load-background']) {
279		wrapper_styles['background-image'] = 'url(https://img.youtube.com/vi/'+this.ytid+'/maxresdefault.jpg)';
280		wrapper_styles['background-size'] = 'cover';
281		wrapper_styles['background-repeat'] = 'no-repeat';
282		wrapper_styles['background-position'] = 'center';
283	}
284
285	for (var property in wrapper_styles) {
286		wrapper.style[property] = wrapper_styles[property];
287	}
288
289	wrapper.parentNode.style.position = 'relative';
290
291	if (this.is_mobile && !this.params.mobile) {
292		return wrapper;
293	}
294
295	// set play/mute controls wrap
296	if (this.params['play-button'] || this.params['mute-button']) {
297		var controls = document.createElement('div');
298		controls.className = 'video-background-controls';
299
300		controls.style.position = 'absolute';
301		controls.style.top = '10px';
302		controls.style.right = '10px';
303		controls.style['z-index'] = 2;
304
305		this.controls_element = controls;
306		wrapper.parentNode.appendChild(controls);
307	}
308
309	return wrapper;
310};
311
312YoutubeBackground.prototype.play = function () {
313	if (this.buttons.hasOwnProperty('play')) {
314		var btn_obj = this.buttons.play;
315		d0.removeClass(btn_obj.element, btn_obj.button_properties.stateClassName);
316		d0.addClass(btn_obj.element.firstChild, btn_obj.button_properties.stateChildClassNames[0])
317		d0.removeClass(btn_obj.element.firstChild, btn_obj.button_properties.stateChildClassNames[1]);
318	}
319
320	if (this.player) {
321		this.player.playVideo();
322	}
323}
324
325YoutubeBackground.prototype.pause = function () {
326	if (this.buttons.hasOwnProperty('play')) {
327		var btn_obj = this.buttons.play;
328		d0.addClass(btn_obj.element, btn_obj.button_properties.stateClassName);
329		d0.removeClass(btn_obj.element.firstChild, btn_obj.button_properties.stateChildClassNames[0])
330		d0.addClass(btn_obj.element.firstChild, btn_obj.button_properties.stateChildClassNames[1]);
331	}
332
333	if (this.player) {
334		this.player.pauseVideo();
335	}
336}
337
338YoutubeBackground.prototype.unmute = function () {
339	if (this.buttons.hasOwnProperty('mute')) {
340		var btn_obj = this.buttons.mute;
341		d0.removeClass(btn_obj.element, btn_obj.button_properties.stateClassName);
342		d0.addClass(btn_obj.element.firstChild, btn_obj.button_properties.stateChildClassNames[0])
343		d0.removeClass(btn_obj.element.firstChild, btn_obj.button_properties.stateChildClassNames[1]);
344	}
345
346	if (this.player) {
347		this.player.unMute();
348	}
349}
350
351YoutubeBackground.prototype.mute = function () {
352	if (this.buttons.hasOwnProperty('mute')) {
353		var btn_obj = this.buttons.mute;
354		d0.addClass(btn_obj.element, btn_obj.button_properties.stateClassName);
355		d0.removeClass(btn_obj.element.firstChild, btn_obj.button_properties.stateChildClassNames[0])
356		d0.addClass(btn_obj.element.firstChild, btn_obj.button_properties.stateChildClassNames[1]);
357	}
358
359	if (this.player) {
360		this.player.mute();
361	}
362}
363
364//TODO: refactor states to be equal for all buttons
365YoutubeBackground.prototype.generateActionButton = function (obj) {
366	var btn = document.createElement('button');
367	btn.className = obj.className;
368	btn.innerHTML = obj.innerHtml;
369	d0.addClass(btn.firstChild, obj.stateChildClassNames[0]);
370
371	if (this.params[obj.condition_parameter] == obj.initialState) {
372		d0.addClass(btn, obj.stateClassName);
373		d0.removeClass(btn.firstChild, obj.stateChildClassNames[0]);
374		d0.addClass(btn.firstChild, obj.stateChildClassNames[1]);
375	}
376
377	var self = this;
378	btn.addEventListener('click', function(e) {
379		if (d0.hasClass(this, obj.stateClassName)) {
380			self.state[obj.name] = false;
381			self[obj.actions[0]]();
382		} else {
383			self.state[obj.name] = true;
384			self[obj.actions[1]]();
385		}
386	});
387
388	this.buttons[obj.name] = {
389		element: btn,
390		button_properties: obj
391	};
392
393	this.controls_element.appendChild(btn);
394};
395
396
397YoutubeBackground.prototype.parseResolutionString = function (res) {
398	var pts = res.split(/\s?:\s?/i);
399	if (pts.length < 2) {
400		return 16/9;
401	}
402
403	var w = parseInt(pts[0], 10);
404	var h = parseInt(pts[1], 10);
405
406	if (isNaN(w) || isNaN(h)) {
407		return 16/9;
408	}
409
410	return w/h;
411};
412
413YoutubeBackground.prototype.isMobile = function (event) {
414	var is_mobile = false;
415	(function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) is_mobile = true;})(navigator.userAgent||navigator.vendor||window.opera);
416
417	return is_mobile;
418};
419
420YoutubeBackground.prototype.error = function (message, value) {
421	if (window.hasOwnProperty('console')
422		&& window.console.hasOwnProperty('error')) {
423		console.error(message, value);
424	}
425};
426
427function ActivityMonitor(on_activity, on_inactivity, activity_timeout, inactivity_timeout, events) {
428	this.timer = null;
429	this.timeout = inactivity_timeout || 10000;
430	this.activity_timer = null; //for event throttling
431	this.activity_timeout = activity_timeout || 1000;
432	this.last_activity = null;
433
434	this.resetTimer = function() {
435		if (this.timer) {
436			clearTimeout(this.timer);
437			this.timer = null;
438		}
439
440		var self = this;
441		this.timer = setTimeout(function() {
442			if (self.last_activity + self.timeout + self.activity_timeout
443				>= new Date().getTime()) {
444					if (on_inactivity) {
445						on_inactivity();
446					}
447			}
448		}, this.timeout);
449	};
450
451	this.logActivity = function() {
452		this.last_activity = new Date().getTime();
453
454		if (on_activity) {
455			on_activity();
456		}
457	};
458
459	this.onActivity = function() {
460		if (!this.activity_timer) {
461			var self = this;
462			this.activity_timer = setTimeout(function(){
463				self.logActivity();
464				self.resetTimer();
465
466				clearTimeout(self.activity_timer);
467				self.activity_timer = null;
468			}, this.activity_timeout);
469		}
470	};
471
472	this.__init__ = function() {
473		var self = this;
474
475		if (!events) {
476			events = ['click', 'mousemove', 'scroll'];
477		} else {
478			if (typeof events === 'string') {
479				events = [events];
480			}
481		}
482
483		for (var i = 0; i < events.length; i++) {
484			document.addEventListener(events[i], function() {
485				self.onActivity();
486			});
487		}
488	};
489
490	this.__init__();
491}
492
493function VideoBackgrounds(selector, params) {
494	this.elements = selector;
495
496	if (typeof selector === 'string') {
497		this.elements = document.querySelectorAll(selector);
498	}
499
500	this.index = {};
501	this.re = {};
502	this.re.YOUTUBE = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i;
503
504	this.__init__ = function () {
505		for (var i = 0; i < this.elements.length; i++) {
506			var element = this.elements[i];
507
508			var link = element.getAttribute('data-youtube');
509			var ytid = this.getYTID(link);
510			var uid = this.generateUID(ytid);
511
512			var yb = new YoutubeBackground(element, params, ytid, uid);
513
514			if (!uid) {
515				continue;
516			}
517
518			this.index[uid] = yb;
519		}
520
521		var self = this;
522
523		this.initYTPlayers(function() {
524			//TODO: FIX!
525			if (params &&
526				(params.hasOwnProperty('activity_timeout')
527				|| params.hasOwnProperty('inactivity_timeout'))) {
528					this.activity_monitor = new ActivityMonitor(function () {
529						self.playVideos();
530					}, function() {
531						self.pauseVideos();
532					},
533					params ? params.activity_timeout : null,
534					params ? params.inactivity_timeout : null,
535					['mousemove', 'scroll']
536				);
537			}
538		});
539	};
540
541	this.__init__();
542}
543
544VideoBackgrounds.prototype.getYTID = function (link) {
545	if (link !== undefined && link !== null) {
546		var pts = link.match(this.re.YOUTUBE);
547		if (pts && pts.length) {
548			this.re.YOUTUBE.lastIndex = 0; //regex needs a reset in for loops, I always forget this
549			return pts[1];
550		}
551	}
552	return null;
553};
554
555VideoBackgrounds.prototype.generateUID = function (pref) {
556	//index the instance
557	function getRandomIntInclusive(min, max) {
558		min = Math.ceil(min);
559		max = Math.floor(max);
560		return Math.floor(Math.random() * (max - min + 1)) + min; //The maximum is inclusive and the minimum is inclusive
561	}
562
563	var uid = pref +'-'+ getRandomIntInclusive(0, 9999);
564	while (this.index.hasOwnProperty(uid)) {
565		uid = pref +'-'+ getRandomIntInclusive(0, 9999);
566	}
567
568	return uid;
569};
570
571VideoBackgrounds.prototype.pauseVideos = function () {
572	for (var k in this.index) {
573		this.index[k].pause();
574	}
575};
576
577VideoBackgrounds.prototype.playVideos = function () {
578	for (var k in this.index) {
579		this.index[k].play();
580	}
581};
582
583VideoBackgrounds.prototype.initYTPlayers = function (callback) {
584	var self = this;
585
586	window.onYouTubeIframeAPIReady = function () {
587		for (var k in self.index) {
588			self.index[k].initYTPlayer();
589		}
590
591		if (callback) {
592			setTimeout(callback, 100);
593		}
594	};
595
596	if (window.hasOwnProperty('YT') && window.YT.loaded) {
597		window.onYouTubeIframeAPIReady();
598	}
599};
600
601if (window.hasOwnProperty('jQuery')) {
602	(function ($) {
603	    $.fn.youtube_background = function(params) {
604	        var $this = $(this);
605			new VideoBackgrounds(this, params);
606	 		return $this;
607	 	};
608	})(jQuery);
609}

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