1/* 2 * blueimp Gallery YouTube Video Factory JS 3 * https://github.com/blueimp/Gallery 4 * 5 * Copyright 2013, Sebastian Tschan 6 * https://blueimp.net 7 * 8 * Licensed under the MIT license: 9 * https://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 || 49 Gallery.prototype.imageFactory 50 var YouTubePlayer = function (videoId, playerVars, clickToPlay) { 51 this.videoId = videoId 52 this.playerVars = playerVars 53 this.clickToPlay = clickToPlay 54 this.element = document.createElement('div') 55 this.listeners = {} 56 } 57 58 $.extend(YouTubePlayer.prototype, { 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 var onYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady 71 var apiUrl = '//www.youtube.com/iframe_api' 72 var scriptTags = document.getElementsByTagName('script') 73 var i = scriptTags.length 74 var 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 YouTubePlayer: YouTubePlayer, 200 201 textFactory: function (obj, callback) { 202 var options = this.options 203 var videoId = this.getItemProperty(obj, options.youTubeVideoIdProperty) 204 if (videoId) { 205 if (this.getItemProperty(obj, options.urlProperty) === undefined) { 206 obj[options.urlProperty] = '//www.youtube.com/watch?v=' + videoId 207 } 208 if (this.getItemProperty(obj, options.videoPosterProperty) === undefined) { 209 obj[options.videoPosterProperty] = '//img.youtube.com/vi/' + videoId + 210 '/maxresdefault.jpg' 211 } 212 return this.videoFactory( 213 obj, 214 callback, 215 new YouTubePlayer( 216 videoId, 217 options.youTubePlayerVars, 218 options.youTubeClickToPlay 219 ) 220 ) 221 } 222 return textFactory.call(this, obj, callback) 223 } 224 225 }) 226 227 return Gallery 228}))
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.