1/* 2 * blueimp Gallery YouTube Video Factory JS 1.2.0 3 * https://github.com/blueimp/Gallery 4 * 5 * Copyright 2013, Sebastian Tschan 6 * https://blueimp.net 7 * 8 * Licensed under the MIT license: 9 * http://www.opensource.org/licenses/MIT 10 */ 11 12/* global define, window, document, YT */ 13 14(function (factory) { 15 'use strict'; 16 if (typeof define === 'function' && define.amd) { 17 // Register as an anonymous AMD module: 18 define([ 19 './blueimp-helper', 20 './blueimp-gallery-video' 21 ], factory); 22 } else { 23 // Browser globals: 24 factory( 25 window.blueimp.helper || window.jQuery, 26 window.blueimp.Gallery 27 ); 28 } 29}(function ($, Gallery) { 30 'use strict'; 31 32 if (!window.postMessage) { 33 return Gallery; 34 } 35 36 $.extend(Gallery.prototype.options, { 37 // The list object property (or data attribute) with the YouTube video id: 38 youTubeVideoIdProperty: 'youtube', 39 // Optional object with parameters passed to the YouTube video player: 40 // https://developers.google.com/youtube/player_parameters 41 youTubePlayerVars: { 42 wmode: 'transparent' 43 }, 44 // Require a click on the native YouTube player for the initial playback: 45 youTubeClickToPlay: true 46 }); 47 48 var textFactory = Gallery.prototype.textFactory || Gallery.prototype.imageFactory, 49 YouTubePlayer = function (videoId, playerVars, clickToPlay) { 50 this.videoId = videoId; 51 this.playerVars = playerVars; 52 this.clickToPlay = clickToPlay; 53 this.element = document.createElement('div'); 54 this.listeners = {}; 55 }; 56 57 $.extend(YouTubePlayer.prototype, { 58 59 canPlayType: function () { 60 return true; 61 }, 62 63 on: function (type, func) { 64 this.listeners[type] = func; 65 return this; 66 }, 67 68 loadAPI: function () { 69 var that = this, 70 onYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady, 71 apiUrl = '//www.youtube.com/iframe_api', 72 scriptTags = document.getElementsByTagName('script'), 73 i = scriptTags.length, 74 scriptTag; 75 window.onYouTubeIframeAPIReady = function () { 76 if (onYouTubeIframeAPIReady) { 77 onYouTubeIframeAPIReady.apply(this); 78 } 79 if (that.playOnReady) { 80 that.play(); 81 } 82 }; 83 while (i) { 84 i -= 1; 85 if (scriptTags[i].src === apiUrl) { 86 return; 87 } 88 } 89 scriptTag = document.createElement('script'); 90 scriptTag.src = apiUrl; 91 scriptTags[0].parentNode.insertBefore(scriptTag, scriptTags[0]); 92 }, 93 94 onReady: function () { 95 this.ready = true; 96 if (this.playOnReady) { 97 this.play(); 98 } 99 }, 100 101 onPlaying: function () { 102 if (this.playStatus < 2) { 103 this.listeners.playing(); 104 this.playStatus = 2; 105 } 106 }, 107 108 onPause: function () { 109 Gallery.prototype.setTimeout.call( 110 this, 111 this.checkSeek, 112 null, 113 2000 114 ); 115 }, 116 117 checkSeek: function () { 118 if (this.stateChange === YT.PlayerState.PAUSED || 119 this.stateChange === YT.PlayerState.ENDED) { 120 // check if current state change is actually paused 121 this.listeners.pause(); 122 delete this.playStatus; 123 } 124 }, 125 126 onStateChange: function (event) { 127 switch (event.data) { 128 case YT.PlayerState.PLAYING: 129 this.hasPlayed = true; 130 this.onPlaying(); 131 break; 132 case YT.PlayerState.PAUSED: 133 case YT.PlayerState.ENDED: 134 this.onPause(); 135 break; 136 } 137 // Save most recent state change to this.stateChange 138 this.stateChange = event.data; 139 }, 140 141 onError: function (event) { 142 this.listeners.error(event); 143 }, 144 145 play: function () { 146 var that = this; 147 if (!this.playStatus) { 148 this.listeners.play(); 149 this.playStatus = 1; 150 } 151 if (this.ready) { 152 if (!this.hasPlayed && (this.clickToPlay || (window.navigator && 153 /iP(hone|od|ad)/.test(window.navigator.platform)))) { 154 // Manually trigger the playing callback if clickToPlay 155 // is enabled and to workaround a limitation in iOS, 156 // which requires synchronous user interaction to start 157 // the video playback: 158 this.onPlaying(); 159 } else { 160 this.player.playVideo(); 161 } 162 } else { 163 this.playOnReady = true; 164 if (!(window.YT && YT.Player)) { 165 this.loadAPI(); 166 } else if (!this.player) { 167 this.player = new YT.Player(this.element, { 168 videoId: this.videoId, 169 playerVars: this.playerVars, 170 events: { 171 onReady: function () { 172 that.onReady(); 173 }, 174 onStateChange: function (event) { 175 that.onStateChange(event); 176 }, 177 onError: function (event) { 178 that.onError(event); 179 } 180 } 181 }); 182 } 183 } 184 }, 185 186 pause: function () { 187 if (this.ready) { 188 this.player.pauseVideo(); 189 } else if (this.playStatus) { 190 delete this.playOnReady; 191 this.listeners.pause(); 192 delete this.playStatus; 193 } 194 } 195 196 }); 197 198 $.extend(Gallery.prototype, { 199 200 YouTubePlayer: YouTubePlayer, 201 202 textFactory: function (obj, callback) { 203 var options = this.options, 204 videoId = this.getItemProperty(obj, options.youTubeVideoIdProperty); 205 if (videoId) { 206 if (this.getItemProperty(obj, options.urlProperty) === undefined) { 207 obj[options.urlProperty] = '//www.youtube.com/watch?v=' + videoId; 208 } 209 if (this.getItemProperty(obj, options.videoPosterProperty) === undefined) { 210 obj[options.videoPosterProperty] = '//img.youtube.com/vi/' + videoId + 211 '/maxresdefault.jpg'; 212 } 213 return this.videoFactory( 214 obj, 215 callback, 216 new YouTubePlayer( 217 videoId, 218 options.youTubePlayerVars, 219 options.youTubeClickToPlay 220 ) 221 ); 222 } 223 return textFactory.call(this, obj, callback); 224 } 225 226 }); 227 228 return Gallery; 229}));
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.