PageSourceSearch

https://www.journeywest.com/js/blueimp-gallery-youtube.js

js journeywest.com collected 2026-10-09 22:42:16 UTC 6,213 bytes, 224 lines download raw bytes

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

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.