pageflow-embedded-video 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +22 -0
- data/.jshintignore +1 -0
- data/.jshintrc +22 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +10 -0
- data/README.md +63 -0
- data/Rakefile +17 -0
- data/app/assets/images/pageflow/embedded_video_pictogram.png +0 -0
- data/app/assets/images/pageflow/embedded_video_pictogram_small.png +0 -0
- data/app/assets/images/pageflow/embedded_video_sprite.png +0 -0
- data/app/assets/images/pageflow/mobile_overlay.png +0 -0
- data/app/assets/images/pageflow/ov-embedded_video.png +0 -0
- data/app/assets/javascript/pageflow/URI.js +52 -0
- data/app/assets/javascript/pageflow/embedded_video/editor/collections/embedded_videos_collection.js +23 -0
- data/app/assets/javascript/pageflow/embedded_video/editor/initializers/setup_collections.js +1 -0
- data/app/assets/javascript/pageflow/embedded_video/editor/models/embedded_video.js +55 -0
- data/app/assets/javascript/pageflow/embedded_video/editor/templates/embedded_video_status.jst.ejs +2 -0
- data/app/assets/javascript/pageflow/embedded_video/editor/templates/url_input.jst.ejs +7 -0
- data/app/assets/javascript/pageflow/embedded_video/editor/views/configuration_editor.js +29 -0
- data/app/assets/javascript/pageflow/embedded_video/editor/views/inputs/video_url_input_view.js +34 -0
- data/app/assets/javascript/pageflow/embedded_video/editor.js +9 -0
- data/app/assets/javascript/pageflow/embedded_video/page_type.js +370 -0
- data/app/assets/javascript/pageflow/embedded_video.js +6 -0
- data/app/assets/javascript/pageflow/froogaloop.js +288 -0
- data/app/assets/stylesheets/pageflow/embedded_video/custom.css.scss +0 -0
- data/app/assets/stylesheets/pageflow/embedded_video/editor.css.scss +17 -0
- data/app/assets/stylesheets/pageflow/embedded_video.css.scss +269 -0
- data/app/views/pageflow/embedded_video/page.html.erb +35 -0
- data/app/views/pageflow/embedded_video/page_type.json.jbuilder +2 -0
- data/bin/rails +8 -0
- data/config/locales/de.yml +45 -0
- data/config/locales/en.yml +34 -0
- data/lib/pageflow/embedded_video/configuration.rb +15 -0
- data/lib/pageflow/embedded_video/engine.rb +9 -0
- data/lib/pageflow/embedded_video/page_type.rb +12 -0
- data/lib/pageflow-embedded-video.rb +17 -0
- data/pageflow-embedded-video.gemspec +23 -0
- metadata +152 -0
@@ -0,0 +1,370 @@
|
|
1
|
+
/*global YT, URI, $f */
|
2
|
+
|
3
|
+
pageflow.pageType.register('embedded_video', _.extend({
|
4
|
+
prepareNextPageTimeout: 0,
|
5
|
+
|
6
|
+
enhance: function(pageElement, configuration) {
|
7
|
+
var that = this;
|
8
|
+
|
9
|
+
if (pageflow.features.has('mobile platform')) {
|
10
|
+
pageElement.find('.close_button, .iframe_container').click(function(event) {
|
11
|
+
event.stopPropagation();
|
12
|
+
that._pauseVideo();
|
13
|
+
pageElement.find('.iframe_container').removeClass('show');
|
14
|
+
pageflow.hideText.deactivate();
|
15
|
+
});
|
16
|
+
|
17
|
+
this._initPlaceholderImage(pageElement, configuration);
|
18
|
+
}
|
19
|
+
|
20
|
+
this.fullscreen = false;
|
21
|
+
$(document).on('fullscreenchange mozfullscreenchange webkitfullscreenchange msfullscreenchange', function() {
|
22
|
+
that.fullscreen = !that.fullscreen;
|
23
|
+
});
|
24
|
+
},
|
25
|
+
|
26
|
+
resize: function(pageElement, configuration) {
|
27
|
+
var iframeWrapper = pageElement.find('.iframe_wrapper'),
|
28
|
+
pageHeader = pageElement.find('.page_header'),
|
29
|
+
scroller = pageElement.find('.scroller'),
|
30
|
+
container = pageElement.find('.iframe_container'),
|
31
|
+
iframeOverlay = pageElement.find('.iframe_overlay'),
|
32
|
+
videoCaption = pageElement.find('.video_caption'),
|
33
|
+
widescreened = pageElement.width() > 1430,
|
34
|
+
fullWidth = configuration.full_width,
|
35
|
+
mobile = pageflow.features.has('mobile platform');
|
36
|
+
|
37
|
+
if (fullWidth && !this.fullscreen) {
|
38
|
+
widescreened = false;
|
39
|
+
}
|
40
|
+
|
41
|
+
iframeWrapper.add(scroller).toggleClass('widescreened', widescreened);
|
42
|
+
|
43
|
+
if (!this.fullscreen) {
|
44
|
+
if (widescreened || mobile) {
|
45
|
+
if (!container.find('iframe').length) {
|
46
|
+
container.append(iframeWrapper);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
else {
|
50
|
+
if (!scroller.find('iframe').length) {
|
51
|
+
iframeWrapper.insertAfter(pageHeader);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
if (widescreened) {
|
57
|
+
iframeWrapper.append(videoCaption);
|
58
|
+
}
|
59
|
+
else if (mobile) {
|
60
|
+
iframeOverlay.after(videoCaption);
|
61
|
+
}
|
62
|
+
else {
|
63
|
+
iframeWrapper.after(videoCaption);
|
64
|
+
}
|
65
|
+
|
66
|
+
scroller.scroller('refresh');
|
67
|
+
},
|
68
|
+
|
69
|
+
prepare: function(pageElement, configuration) {},
|
70
|
+
|
71
|
+
preload: function(pageElement, configuration) {
|
72
|
+
return pageflow.preload.backgroundImage(pageElement.find('.background_image'));
|
73
|
+
},
|
74
|
+
|
75
|
+
activating: function(pageElement, configuration) {
|
76
|
+
var that = this;
|
77
|
+
|
78
|
+
this.listenTo(pageflow.settings, "change:volume", function(model, value) {
|
79
|
+
that._setPlayerVolume(value);
|
80
|
+
});
|
81
|
+
|
82
|
+
this._createPlayer(pageElement, configuration);
|
83
|
+
|
84
|
+
this.resize(pageElement, configuration);
|
85
|
+
this.active = true;
|
86
|
+
},
|
87
|
+
|
88
|
+
activated: function(pageElement, configuration) {},
|
89
|
+
|
90
|
+
deactivating: function(pageElement, configuration) {
|
91
|
+
this.active = false;
|
92
|
+
this.stopListening(pageflow.settings);
|
93
|
+
this._removePlayer(pageElement);
|
94
|
+
},
|
95
|
+
|
96
|
+
deactivated: function(pageElement, configuration) {
|
97
|
+
},
|
98
|
+
|
99
|
+
update: function(pageElement, configuration) {
|
100
|
+
pageElement.find('h2 .tagline').text(configuration.get('tagline') || '');
|
101
|
+
pageElement.find('h2 .title').text(configuration.get('title') || '');
|
102
|
+
pageElement.find('h2 .subtitle').text(configuration.get('subtitle') || '');
|
103
|
+
pageElement.find('p').html(configuration.get('text') || '');
|
104
|
+
|
105
|
+
var that = this,
|
106
|
+
iframeWrapper = pageElement.find('.iframe_wrapper'),
|
107
|
+
captionElement = pageElement.find('.video_caption'),
|
108
|
+
caption = configuration.get('video_caption');
|
109
|
+
|
110
|
+
if ((caption || '').trim() !== '') {
|
111
|
+
if (!captionElement.length) {
|
112
|
+
captionElement = $('<div class="video_caption"></div>');
|
113
|
+
|
114
|
+
if (pageElement.find('.scroller iframe').length) {
|
115
|
+
captionElement.insertAfter(iframeWrapper);
|
116
|
+
} else {
|
117
|
+
captionElement.appendTo(iframeWrapper);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
captionElement.text(caption || '');
|
121
|
+
} else {
|
122
|
+
captionElement.remove();
|
123
|
+
}
|
124
|
+
|
125
|
+
if (this.active) {
|
126
|
+
var currentUrl = this._getCurrentUrl(pageElement),
|
127
|
+
newUrl = configuration.get('display_embedded_video_url');
|
128
|
+
|
129
|
+
if (this._urlOrigin(currentUrl) === this._urlOrigin(newUrl)) {
|
130
|
+
this._updatePlayerSrc(pageElement, configuration);
|
131
|
+
}
|
132
|
+
else {
|
133
|
+
this._removePlayer(pageElement, function() {
|
134
|
+
that._createPlayer(pageElement, configuration.attributes);
|
135
|
+
});
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
139
|
+
pageElement.find('.shadow').css({
|
140
|
+
opacity: configuration.get('gradient_opacity') / 100
|
141
|
+
});
|
142
|
+
|
143
|
+
this.updateCommonPageCssClasses(pageElement, configuration);
|
144
|
+
this.resize(pageElement, configuration.attributes);
|
145
|
+
},
|
146
|
+
|
147
|
+
embeddedEditorViews: function() {
|
148
|
+
return {
|
149
|
+
'.background_image': {
|
150
|
+
view: pageflow.BackgroundImageEmbeddedView,
|
151
|
+
options: {propertyName: 'background_image_id'}
|
152
|
+
}
|
153
|
+
};
|
154
|
+
},
|
155
|
+
|
156
|
+
_createPlayer: function(pageElement, configuration) {
|
157
|
+
var that = this,
|
158
|
+
url = configuration.display_embedded_video_url,
|
159
|
+
origin = this._urlOrigin(url);
|
160
|
+
|
161
|
+
if (origin === 'youtube') {
|
162
|
+
this.ytApiInitialize().done(function () {
|
163
|
+
that._createYouTubePlayer(pageElement, url);
|
164
|
+
});
|
165
|
+
}
|
166
|
+
else if (origin == 'vimeo') {
|
167
|
+
that._createVimeoPlayer(pageElement, url);
|
168
|
+
}
|
169
|
+
},
|
170
|
+
|
171
|
+
ytApiInitialize: function() {
|
172
|
+
if (!window.youtubeInitialized) {
|
173
|
+
var ytApi = new $.Deferred();
|
174
|
+
window.youtubeInitialized = ytApi.promise();
|
175
|
+
|
176
|
+
window.onYouTubeIframeAPIReady = function() {
|
177
|
+
ytApi.resolve();
|
178
|
+
};
|
179
|
+
|
180
|
+
var tag = document.createElement('script');
|
181
|
+
tag.src = "https://www.youtube.com/iframe_api";
|
182
|
+
var firstScriptTag = document.getElementsByTagName('script')[0];
|
183
|
+
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
184
|
+
}
|
185
|
+
return window.youtubeInitialized;
|
186
|
+
},
|
187
|
+
|
188
|
+
_createYouTubePlayer: function(pageElement, url) {
|
189
|
+
var that = this,
|
190
|
+
div = document.createElement('div');
|
191
|
+
|
192
|
+
this.playerId = 'youtube-player-' + this._getRandom(url);
|
193
|
+
|
194
|
+
div.setAttribute('id', this.playerId);
|
195
|
+
pageElement.find('.iframe_wrapper').prepend(div);
|
196
|
+
|
197
|
+
this.ytApiInitialize().done(function() {
|
198
|
+
new YT.Player(div, {
|
199
|
+
height: '100%',
|
200
|
+
width: '100%',
|
201
|
+
videoId: that._getVideoId(url),
|
202
|
+
playerVars: {
|
203
|
+
rel: false
|
204
|
+
},
|
205
|
+
events: {
|
206
|
+
'onReady': function(event) {
|
207
|
+
that.player = event.target;
|
208
|
+
that._setPlayerVolume(pageflow.settings.get('volume'));
|
209
|
+
}
|
210
|
+
}
|
211
|
+
});
|
212
|
+
});
|
213
|
+
},
|
214
|
+
|
215
|
+
_createVimeoPlayer: function(pageElement, url) {
|
216
|
+
var that = this,
|
217
|
+
iframe = document.createElement('iframe'),
|
218
|
+
uri = new URI('//player.vimeo.com/video/');
|
219
|
+
|
220
|
+
this.playerId = 'vimeo-player-' + this._getRandom(url);
|
221
|
+
|
222
|
+
uri.filename(that._getVideoId(url));
|
223
|
+
uri.search({api: '1', player_id: this.playerId});
|
224
|
+
|
225
|
+
$(iframe).attr({
|
226
|
+
id: this.playerId,
|
227
|
+
width: '100%',
|
228
|
+
height: '100%',
|
229
|
+
frameborder: '0',
|
230
|
+
webkitallowfullscreen: true,
|
231
|
+
mozallowfullscreen: true,
|
232
|
+
allowfullscreen: true,
|
233
|
+
src: uri.toString()
|
234
|
+
});
|
235
|
+
|
236
|
+
pageElement.find('.iframe_wrapper').prepend(iframe);
|
237
|
+
|
238
|
+
this.player = $f(iframe);
|
239
|
+
|
240
|
+
this.player.addEvent('ready', function() {
|
241
|
+
that._setPlayerVolume(pageflow.settings.get('volume'));
|
242
|
+
});
|
243
|
+
},
|
244
|
+
|
245
|
+
_updatePlayerSrc: function(pageElement, configuration) {
|
246
|
+
var that = this,
|
247
|
+
newUrl = configuration.get('display_embedded_video_url'),
|
248
|
+
p = pageElement.find('iframe'),
|
249
|
+
url = new URI(p.attr('src'));
|
250
|
+
|
251
|
+
p.attr('src', url.filename(that._getVideoId(newUrl)));
|
252
|
+
},
|
253
|
+
|
254
|
+
_setPlayerVolume: function(value) {
|
255
|
+
if (this.player) {
|
256
|
+
if (typeof this.player.setVolume === 'function') {
|
257
|
+
this.player.setVolume(value * 100);
|
258
|
+
} else if (typeof this.player.api === 'function') {
|
259
|
+
this.player.api('setVolume', value);
|
260
|
+
}
|
261
|
+
}
|
262
|
+
},
|
263
|
+
|
264
|
+
_pauseVideo: function() {
|
265
|
+
if (this.player) {
|
266
|
+
if (typeof this.player.pauseVideo === 'function') {
|
267
|
+
this.player.pauseVideo();
|
268
|
+
} else if (typeof this.player.api === 'function') {
|
269
|
+
this.player.api('pause');
|
270
|
+
}
|
271
|
+
}
|
272
|
+
},
|
273
|
+
|
274
|
+
_removePlayer: function (pageElement, callback) {
|
275
|
+
if (this.player && typeof this.player.destroy === 'function') {
|
276
|
+
this.player.destroy();
|
277
|
+
}
|
278
|
+
this.player = null;
|
279
|
+
$('#' + this.playerId, pageElement).remove();
|
280
|
+
|
281
|
+
if (typeof callback === 'function') {
|
282
|
+
callback();
|
283
|
+
}
|
284
|
+
},
|
285
|
+
|
286
|
+
_initPlaceholderImage: function(pageElement, configuration) {
|
287
|
+
var $div = $(document.createElement('div')),
|
288
|
+
pageHeader = pageElement.find('.page_header'),
|
289
|
+
container = pageElement.find('.iframe_container'),
|
290
|
+
url = configuration.display_embedded_video_url;
|
291
|
+
|
292
|
+
$div.addClass('iframe_overlay ' + this._urlOrigin(url));
|
293
|
+
|
294
|
+
this._setBackgroundImage(url, $div);
|
295
|
+
pageHeader.after($div);
|
296
|
+
|
297
|
+
$div.click(function(event) {
|
298
|
+
event.preventDefault();
|
299
|
+
container.addClass('show');
|
300
|
+
pageflow.hideText.activate();
|
301
|
+
});
|
302
|
+
},
|
303
|
+
|
304
|
+
_setBackgroundImage: function(url, element) {
|
305
|
+
var origin = this._urlOrigin(url),
|
306
|
+
videoId = this._getVideoId(url),
|
307
|
+
imageUrl = '';
|
308
|
+
|
309
|
+
if (origin === 'youtube') {
|
310
|
+
imageUrl = 'http://img.youtube.com/vi/' + videoId + '/hqdefault.jpg';
|
311
|
+
element.css('background-image', 'url("' + imageUrl + '")');
|
312
|
+
}
|
313
|
+
else if (origin === 'vimeo') {
|
314
|
+
var src = "http://vimeo.com/api/v2/video/" + videoId + ".json";
|
315
|
+
|
316
|
+
$.getJSON(src, function(data) {
|
317
|
+
element.css('background-image', 'url("' + data[0].thumbnail_large + '")');
|
318
|
+
});
|
319
|
+
}
|
320
|
+
},
|
321
|
+
|
322
|
+
_getCurrentUrl: function(pageElement) {
|
323
|
+
return pageElement.find('iframe').attr('src');
|
324
|
+
},
|
325
|
+
|
326
|
+
_urlOrigin: function(url) {
|
327
|
+
var uri = new URI(url),
|
328
|
+
domain = uri.domain(true);
|
329
|
+
|
330
|
+
if (['youtu.be', 'youtube.com'].indexOf(domain) >= 0) {
|
331
|
+
return 'youtube';
|
332
|
+
}
|
333
|
+
else if (domain === 'vimeo.com') {
|
334
|
+
return 'vimeo';
|
335
|
+
}
|
336
|
+
|
337
|
+
return '';
|
338
|
+
},
|
339
|
+
|
340
|
+
_getVideoId: function(url) {
|
341
|
+
var uri = new URI(url),
|
342
|
+
domain = uri.domain(true);
|
343
|
+
|
344
|
+
if (['youtu.be', 'vimeo.com'].indexOf(domain) >= 0) {
|
345
|
+
return uri.filename();
|
346
|
+
}
|
347
|
+
else if (domain === 'youtube.com') {
|
348
|
+
if (uri.directory() === '/embed') {
|
349
|
+
return uri.filename();
|
350
|
+
}
|
351
|
+
else {
|
352
|
+
return uri.search(true).v;
|
353
|
+
}
|
354
|
+
}
|
355
|
+
|
356
|
+
return '';
|
357
|
+
},
|
358
|
+
|
359
|
+
_getRandom: function(string) {
|
360
|
+
string = string + new Date().getTime();
|
361
|
+
var hash = 0, i, chr, len;
|
362
|
+
if (string === 0) return hash;
|
363
|
+
for (i = 0, len = string.length; i < len; i++) {
|
364
|
+
chr = string.charCodeAt(i);
|
365
|
+
hash = ((hash << 5) - hash) + chr;
|
366
|
+
hash |= 0; // Convert to 32bit integer
|
367
|
+
}
|
368
|
+
return hash;
|
369
|
+
}
|
370
|
+
}, pageflow.commonPageCssClasses));
|
@@ -0,0 +1,288 @@
|
|
1
|
+
// Init style shamelessly stolen from jQuery http://jquery.com
|
2
|
+
var Froogaloop = (function(){
|
3
|
+
// Define a local copy of Froogaloop
|
4
|
+
function Froogaloop(iframe) {
|
5
|
+
// The Froogaloop object is actually just the init constructor
|
6
|
+
return new Froogaloop.fn.init(iframe);
|
7
|
+
}
|
8
|
+
|
9
|
+
var eventCallbacks = {},
|
10
|
+
hasWindowEvent = false,
|
11
|
+
slice = Array.prototype.slice,
|
12
|
+
playerDomain = '';
|
13
|
+
|
14
|
+
Froogaloop.fn = Froogaloop.prototype = {
|
15
|
+
element: null,
|
16
|
+
isReady: false,
|
17
|
+
|
18
|
+
init: function(iframe) {
|
19
|
+
if (typeof iframe === "string") {
|
20
|
+
iframe = document.getElementById(iframe);
|
21
|
+
}
|
22
|
+
|
23
|
+
this.element = iframe;
|
24
|
+
|
25
|
+
// Register message event listeners
|
26
|
+
playerDomain = getDomainFromUrl(this.element.getAttribute('src'));
|
27
|
+
|
28
|
+
return this;
|
29
|
+
},
|
30
|
+
|
31
|
+
/*
|
32
|
+
* Calls a function to act upon the player.
|
33
|
+
*
|
34
|
+
* @param {string} method The name of the Javascript API method to call. Eg: 'play'.
|
35
|
+
* @param {Array|Function} valueOrCallback params Array of parameters to pass when calling an API method
|
36
|
+
* or callback function when the method returns a value.
|
37
|
+
*/
|
38
|
+
api: function(method, valueOrCallback) {
|
39
|
+
if (!this.element || !method) {
|
40
|
+
return false;
|
41
|
+
}
|
42
|
+
|
43
|
+
var self = this,
|
44
|
+
element = self.element,
|
45
|
+
target_id = element.id !== '' ? element.id : null,
|
46
|
+
params = !isFunction(valueOrCallback) ? valueOrCallback : null,
|
47
|
+
callback = isFunction(valueOrCallback) ? valueOrCallback : null;
|
48
|
+
|
49
|
+
// Store the callback for get functions
|
50
|
+
if (callback) {
|
51
|
+
storeCallback(method, callback, target_id);
|
52
|
+
}
|
53
|
+
|
54
|
+
postMessage(method, params, element);
|
55
|
+
return self;
|
56
|
+
},
|
57
|
+
|
58
|
+
/*
|
59
|
+
* Registers an event listener and a callback function that gets called when the event fires.
|
60
|
+
*
|
61
|
+
* @param eventName (String): Name of the event to listen for.
|
62
|
+
* @param callback (Function): Function that should be called when the event fires.
|
63
|
+
*/
|
64
|
+
addEvent: function(eventName, callback) {
|
65
|
+
if (!this.element) {
|
66
|
+
return false;
|
67
|
+
}
|
68
|
+
|
69
|
+
var self = this,
|
70
|
+
element = self.element,
|
71
|
+
target_id = element.id !== '' ? element.id : null;
|
72
|
+
|
73
|
+
|
74
|
+
storeCallback(eventName, callback, target_id);
|
75
|
+
|
76
|
+
// The ready event is not registered via postMessage. It fires regardless.
|
77
|
+
if (eventName != 'ready') {
|
78
|
+
postMessage('addEventListener', eventName, element);
|
79
|
+
}
|
80
|
+
else if (eventName == 'ready' && this.isReady) {
|
81
|
+
callback.call(null, target_id);
|
82
|
+
}
|
83
|
+
|
84
|
+
return self;
|
85
|
+
},
|
86
|
+
|
87
|
+
/*
|
88
|
+
* Unregisters an event listener that gets called when the event fires.
|
89
|
+
*
|
90
|
+
* @param eventName (String): Name of the event to stop listening for.
|
91
|
+
*/
|
92
|
+
removeEvent: function(eventName) {
|
93
|
+
if (!this.element) {
|
94
|
+
return false;
|
95
|
+
}
|
96
|
+
|
97
|
+
var self = this,
|
98
|
+
element = self.element,
|
99
|
+
target_id = element.id !== '' ? element.id : null,
|
100
|
+
removed = removeCallback(eventName, target_id);
|
101
|
+
|
102
|
+
// The ready event is not registered
|
103
|
+
if (eventName != 'ready' && removed) {
|
104
|
+
postMessage('removeEventListener', eventName, element);
|
105
|
+
}
|
106
|
+
}
|
107
|
+
};
|
108
|
+
|
109
|
+
/**
|
110
|
+
* Handles posting a message to the parent window.
|
111
|
+
*
|
112
|
+
* @param method (String): name of the method to call inside the player. For api calls
|
113
|
+
* this is the name of the api method (api_play or api_pause) while for events this method
|
114
|
+
* is api_addEventListener.
|
115
|
+
* @param params (Object or Array): List of parameters to submit to the method. Can be either
|
116
|
+
* a single param or an array list of parameters.
|
117
|
+
* @param target (HTMLElement): Target iframe to post the message to.
|
118
|
+
*/
|
119
|
+
function postMessage(method, params, target) {
|
120
|
+
if (!target.contentWindow.postMessage) {
|
121
|
+
return false;
|
122
|
+
}
|
123
|
+
|
124
|
+
var url = target.getAttribute('src').split('?')[0],
|
125
|
+
data = JSON.stringify({
|
126
|
+
method: method,
|
127
|
+
value: params
|
128
|
+
});
|
129
|
+
|
130
|
+
if (url.substr(0, 2) === '//') {
|
131
|
+
url = window.location.protocol + url;
|
132
|
+
}
|
133
|
+
|
134
|
+
target.contentWindow.postMessage(data, url);
|
135
|
+
}
|
136
|
+
|
137
|
+
/**
|
138
|
+
* Event that fires whenever the window receives a message from its parent
|
139
|
+
* via window.postMessage.
|
140
|
+
*/
|
141
|
+
function onMessageReceived(event) {
|
142
|
+
var data, method;
|
143
|
+
|
144
|
+
try {
|
145
|
+
data = JSON.parse(event.data);
|
146
|
+
method = data.event || data.method;
|
147
|
+
}
|
148
|
+
catch(e) {
|
149
|
+
//fail silently... like a ninja!
|
150
|
+
}
|
151
|
+
|
152
|
+
if (method == 'ready' && !this.isReady) {
|
153
|
+
this.isReady = true;
|
154
|
+
}
|
155
|
+
|
156
|
+
// Handles messages from moogaloop only
|
157
|
+
if (event.origin != playerDomain) {
|
158
|
+
return false;
|
159
|
+
}
|
160
|
+
|
161
|
+
var value = data.value,
|
162
|
+
eventData = data.data,
|
163
|
+
target_id = target_id === '' ? null : data.player_id,
|
164
|
+
|
165
|
+
callback = getCallback(method, target_id),
|
166
|
+
params = [];
|
167
|
+
|
168
|
+
if (!callback) {
|
169
|
+
return false;
|
170
|
+
}
|
171
|
+
|
172
|
+
if (value !== undefined) {
|
173
|
+
params.push(value);
|
174
|
+
}
|
175
|
+
|
176
|
+
if (eventData) {
|
177
|
+
params.push(eventData);
|
178
|
+
}
|
179
|
+
|
180
|
+
if (target_id) {
|
181
|
+
params.push(target_id);
|
182
|
+
}
|
183
|
+
|
184
|
+
return params.length > 0 ? callback.apply(null, params) : callback.call();
|
185
|
+
}
|
186
|
+
|
187
|
+
|
188
|
+
/**
|
189
|
+
* Stores submitted callbacks for each iframe being tracked and each
|
190
|
+
* event for that iframe.
|
191
|
+
*
|
192
|
+
* @param eventName (String): Name of the event. Eg. api_onPlay
|
193
|
+
* @param callback (Function): Function that should get executed when the
|
194
|
+
* event is fired.
|
195
|
+
* @param target_id (String) [Optional]: If handling more than one iframe then
|
196
|
+
* it stores the different callbacks for different iframes based on the iframe's
|
197
|
+
* id.
|
198
|
+
*/
|
199
|
+
function storeCallback(eventName, callback, target_id) {
|
200
|
+
if (target_id) {
|
201
|
+
if (!eventCallbacks[target_id]) {
|
202
|
+
eventCallbacks[target_id] = {};
|
203
|
+
}
|
204
|
+
eventCallbacks[target_id][eventName] = callback;
|
205
|
+
}
|
206
|
+
else {
|
207
|
+
eventCallbacks[eventName] = callback;
|
208
|
+
}
|
209
|
+
}
|
210
|
+
|
211
|
+
/**
|
212
|
+
* Retrieves stored callbacks.
|
213
|
+
*/
|
214
|
+
function getCallback(eventName, target_id) {
|
215
|
+
if (target_id) {
|
216
|
+
return eventCallbacks[target_id][eventName];
|
217
|
+
}
|
218
|
+
else {
|
219
|
+
return eventCallbacks[eventName];
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
223
|
+
function removeCallback(eventName, target_id) {
|
224
|
+
if (target_id && eventCallbacks[target_id]) {
|
225
|
+
if (!eventCallbacks[target_id][eventName]) {
|
226
|
+
return false;
|
227
|
+
}
|
228
|
+
eventCallbacks[target_id][eventName] = null;
|
229
|
+
}
|
230
|
+
else {
|
231
|
+
if (!eventCallbacks[eventName]) {
|
232
|
+
return false;
|
233
|
+
}
|
234
|
+
eventCallbacks[eventName] = null;
|
235
|
+
}
|
236
|
+
|
237
|
+
return true;
|
238
|
+
}
|
239
|
+
|
240
|
+
/**
|
241
|
+
* Returns a domain's root domain.
|
242
|
+
* Eg. returns http://vimeo.com when http://vimeo.com/channels is sbumitted
|
243
|
+
*
|
244
|
+
* @param url (String): Url to test against.
|
245
|
+
* @return url (String): Root domain of submitted url
|
246
|
+
*/
|
247
|
+
function getDomainFromUrl(url) {
|
248
|
+
if (url.substr(0, 2) === '//') {
|
249
|
+
url = window.location.protocol + url;
|
250
|
+
}
|
251
|
+
|
252
|
+
var url_pieces = url.split('/'),
|
253
|
+
domain_str = '';
|
254
|
+
|
255
|
+
for(var i = 0, length = url_pieces.length; i < length; i++) {
|
256
|
+
if(i<3) {domain_str += url_pieces[i];}
|
257
|
+
else {break;}
|
258
|
+
if(i<2) {domain_str += '/';}
|
259
|
+
}
|
260
|
+
|
261
|
+
return domain_str;
|
262
|
+
}
|
263
|
+
|
264
|
+
function isFunction(obj) {
|
265
|
+
return !!(obj && obj.constructor && obj.call && obj.apply);
|
266
|
+
}
|
267
|
+
|
268
|
+
function isArray(obj) {
|
269
|
+
return toString.call(obj) === '[object Array]';
|
270
|
+
}
|
271
|
+
|
272
|
+
// Give the init function the Froogaloop prototype for later instantiation
|
273
|
+
Froogaloop.fn.init.prototype = Froogaloop.fn;
|
274
|
+
|
275
|
+
// Listens for the message event.
|
276
|
+
// W3C
|
277
|
+
if (window.addEventListener) {
|
278
|
+
window.addEventListener('message', onMessageReceived, false);
|
279
|
+
}
|
280
|
+
// IE
|
281
|
+
else {
|
282
|
+
window.attachEvent('onmessage', onMessageReceived);
|
283
|
+
}
|
284
|
+
|
285
|
+
// Expose froogaloop to the global object
|
286
|
+
return (window.Froogaloop = window.$f = Froogaloop);
|
287
|
+
|
288
|
+
})();
|
File without changes
|