/** * @file * Provides Media module integration. */ (function ($, Drupal, _doc) { 'use strict'; var _context = _doc; var _md = 'media'; var _id = 'blazy-' + _md; var _idOnce = 'b-' + _md; var _player = _md + '--player'; var _element = '.' + _player; var _icon = _md + '__icon'; var _elIconPlay = '.' + _icon + '--play'; var _elIconClose = '.' + _icon + '--close'; var _iFrame = 'iframe'; var _isPlaying = 'is-playing'; var _dataIFrameTitle = 'data-' + _iFrame + '-title'; var _dataUrl = 'data-url'; /** * Blazy media utility functions. * * @param {HTMLElement} el * The media player HTML element. */ function process(el) { var $el = $(el); var iframe = $el.find(_iFrame); var btn = $el.find(_elIconPlay); // Media player toggler is disabled, just display iframe. if (!$.isElm(btn)) { return; } var url = $.attr(btn, _dataUrl); var title = $.attr(btn, _dataIFrameTitle); var newIframe; /** * Play the media. * * @param {Event} e * The event triggered by a `click` event. * * @return {bool|mixed} * Return false if url is not available. */ function play(e) { e.preventDefault(); // oEmbed/ Soundcloud needs internet, fails on disconnected local. if (url === '') { return false; } var target = this; var player = target.parentNode; var playing = $.find(_doc, '.' + _isPlaying); var iframe = $.find(player, _iFrame); var video = $.find(_doc, 'video'); url = $.attr(target, _dataUrl); title = $.attr(target, _dataIFrameTitle); // First, reset any (local) video to avoid multiple videos from playing. if ($.isElm(video) && !video.paused) { video.pause(); } // Remove other playing video. if ($.isElm(playing)) { var played = $.find(_doc, '.' + _isPlaying + ' ' + _iFrame); // Remove the previous iframe. $.remove(played); playing.className = playing.className.replace(/(\S+)playing/, ''); } // Appends the iframe. $.addClass(player, _isPlaying); // Remove the existing iframe on the current clicked iframe. $.remove(iframe); // Cache iframe for the potential repeating clicks. if (!newIframe) { newIframe = $.create(_iFrame, _md + '__iframe ' + _md + '__element'); $.attr(newIframe, { src: url, allowfullscreen: true, title: title }); } player.appendChild(newIframe); } /** * Close the media. * * @param {Event} e * The event triggered by a `click` event. */ function stop(e) { e.preventDefault(); var target = this; var player = target.parentNode; var iframe = $.find(player, _iFrame); if (player.className.match(_isPlaying)) { player.className = player.className.replace(/(\S+)playing/, ''); } $.remove(iframe); } // Remove iframe to avoid browser requesting them till clicked. // The iframe is there as Blazy supports non-lazyloaded/ non-JS iframes. $.remove(iframe); // Plays the media player. $el.on('click.' + _id, _elIconPlay, play); // Closes the video. $el.on('click.' + _id, _elIconClose, stop); } /** * Theme function for a dynamic inline video. * * @param {Object} settings * An object containing the link element which triggers the lightbox. * This link must have [data-media] attribute containing video metadata. * * @return {HTMLElement} * Returns a HTMLElement object. */ Drupal.theme.blazyMedia = function (settings) { // PhotoSwipe5 has element, PhotoSwipe4 el, etc. var el = settings.el || settings.element; var $el = $(el); var img = $el.find('img'); var data = $.parse($el.attr('data-' + _md)); var alt = $.isElm(img) ? Drupal.checkPlain($.attr(img, 'alt', 'Video preview', true)) : ''; var width = data.width ? parseInt(data.width, 10) : 640; var height = data.height ? parseInt(data.height, 10) : 360; var pad = data ? ((height / width) * 100).toFixed(2) : 100; var imgUrl = $el.attr('data-box-url'); var href = $el.attr('href'); var oembedUrl = $el.attr('data-oembed-url', href, true); var defClass = _md + '__image ' + _md + '__element'; var imgClass = settings.imgClass ? defClass + ' ' + settings.imgClass : defClass; var idClass = data.id ? ' ' + _md + '--' + data.id : ''; var player = data.type === 'video' ? ' ' + _player : ''; var html = ''; if (imgUrl) { html += '$alt'; } if (player) { html += ''; html += ''; } html = '
' + html + '
'; if (!settings.unwrap) { html = '
' + html + '
'; } return $.template(html, { md: _md, icon: _icon, idClass: idClass, player: player, pad: pad, imgUrl: imgUrl, imgClass: imgClass, alt: alt, oembed: oembedUrl, width: width, wrapper: _md + '-wrapper' }); }; /** * Attaches Blazy media behavior to HTML element. * * @type {Drupal~behavior} */ Drupal.behaviors.blazyMedia = { attach: function (context) { _context = $.context(context); $.once(process, _idOnce, _element, _context); }, detach: function (context, setting, trigger) { if (trigger === 'unload') { $.once.removeSafely(_idOnce, _element, _context); } } }; })(dBlazy, Drupal, this.document);