/** * @author Nerd Almighty * @copyright 2010 Bergwerk * @license Creative Commons - Attribution-Noncommercial-Share Alike 3.0 Unported */ var VideoBBCode = Class.create({ /** * Initialize the video bbcode functions (prepare the background, add eventlisteners, et cetera) */ initialize: function() { // get video containers var videos = $$('.videoBBCodeInnerContainer'); this.activeVideo = 0; this.activeVideoData = new Array(); // if there are no videos, we don't need to be able to view them ;> if (videos.size()) { // get language vars this.langVars = Object.extend({ zoomIn : '', copyright : '', defaultTitle : '' }, arguments[0] || { }); // since videos cant be zoomed in any IE at all, we don't need any of this if (!IS_IE) { // create a background div for fade in and fade out this.background = new Element('div').addClassName('videoBBCodeBackground'); if (IS_SAFARI_MOBILE) { this.background.setStyle('height: ' + $$('body')[0].getHeight() + 'px; width: ' + $$('body')[0].getWidth() + 'px;'); } this.background.hide(); $$('body')[0].insert(this.background); // create the caption and add it to the background this.caption = new Element('p').addClassName('videoBBCodeCaption').hide(); this.background.insert(this.caption); // create the copyright link this.copyright = new Element('div').addClassName('videoBBCodeCopyright').update(this.langVars.copyright); this.copyright.hide(); $$('body')[0].insert(this.copyright); // prepare each video for zooming in and out var videoID = 0; videos.each(function(videoContainer) { // increase videoID videoID++; // zoom icon element = videoContainer.select('.videoBBCodeZoom')[0]; element.id = 'videoBBCodeZoom-' + videoID; element.alt = 'zoom'; element.title = this.langVars.zoomIn; element.style.cursor = 'pointer'; element.observe('click', this.zoomIn.bindAsEventListener(this)); element.onmouseover = function() { this.src = this.src.replace(/videoM\.png/, 'videoZoomM.png'); } element.onmouseout = function() { this.src = this.src.replace(/videoZoomM\.png/, 'videoM.png'); } // title element = videoContainer.select('.containerContent h4 a')[0]; element.id = 'videoBBCodeTitle-' + videoID; // object container element = videoContainer.select('.videoBBCodeObjectContainer')[0]; element.id = 'videoBBCodeObjectContainer-' + videoID; // low res video object element = videoContainer.select('.videoBBCodeObject')[0]; element.id = 'videoBBCodeObject-' + videoID; // hi res video object /* element = videoContainer.select('.videoBBCodeZoomedObject')[0]; element.id = 'videoBBCodeZoomedObject-' + videoID; */ }.bind(this)); // cache eventlistener function this._resize = this.resize.bindAsEventListener(this); } // kill video objects before navigating away from the page Event.observe(window, 'beforeunload', this.suicide.bindAsEventListener(this)); } }, /** * Show a high res version of the requested video in the middle of the window, fade out the rest of the page and stop the playback of the low res version in the background. */ zoomIn: function(evt) { // only allow this if there isn't already a zoomed video if (this.activeVideo == 0) { // get videoID from event element id var videoID = evt.findElement().id.split('-')[1]; this.activeVideo = videoID; // find the video title and add it to the caption var titleElement = $('videoBBCodeTitle-' + this.activeVideo); var title = titleElement.innerHTML; if (titleElement.select('.highlight')[0]) { // prevent a bug with the search function's keyword highlighter title = titleElement.select('.highlight')[0].innerHTML; } this.caption.update(title); // add eventlistener to zoom out again this.background.onclick = function() { this.zoomOut(); }.bind(this); // hide low res video to stop playback in the background $('videoBBCodeObject-' + this.activeVideo).hide(); // switch out low res version with hi res version (+ autoplayback) // get current values var video = $('videoBBCodeObject-' + this.activeVideo); this.activeVideoData['data'] = video.readAttribute('data'); this.activeVideoData['movieParam'] = video.select('param[name="movie"]')[0].readAttribute('value'); this.activeVideoData['flashVars'] = ''; if (video.select('param[name="flashVars"]')[0]) { this.activeVideoData['flashVars'] = video.select('param[name="flashVars"]')[0].readAttribute('value'); video.select('param[name="flashVars"]')[0].remove(); } this.activeVideoData['width'] = video.readAttribute('width'); this.activeVideoData['height'] = video.readAttribute('height'); // get new values var data = video.select('param[name="dataCache"]')[0].readAttribute('value'); var movie = video.select('param[name="movieCache"]')[0].readAttribute('value'); var flashVars = (this.activeVideoData['flashVars'] != '' && this.activeVideoData['flashVars'] != 'autoPlay=false' ? this.activeVideoData['flashVars'] + '&' : '') + (movie.indexOf('http://www.metacafe.com') > -1 ? 'playerVars=autoPlay=yes' : 'autorun=yes&isAutoPlay=true&autoPlay=true&autorun=yes&autostart=true'); // switch video.writeAttribute('data', data); video.select('param[name="movie"]')[0].writeAttribute('value', movie); var flashVarsParam = new Element('param').writeAttribute('name', 'flashVars').writeAttribute('value', flashVars); video.insert(flashVarsParam); // fade out the rest of the page and show the video title and the copyright notice this.background.appear({ duration: 1, to: 0.9, afterFinish: function() { this.copyright.appear({duration: 0.5}); if (this.caption.innerHTML != this.langVars.defaultTitle) { this.caption.appear({duration: 0.5}); } // make main content invisible to save resources (especially important for firefox) $('headerContainer').setStyle('visibility: hidden;'); $('mainContainer').setStyle('visibility: hidden;'); $('footerContainer').setStyle('visibility: hidden;'); // show hi res video $('videoBBCodeObject-' + this.activeVideo).removeClassName('videoBBCodeObject').addClassName('videoBBCodeZoomedObject').show(); // position the video in the middle of the window and keep it there this.resize(); Event.observe(window, 'resize', this._resize); }.bind(this) }); } }, /** * Return to the normal page with the low res video and stop the playback of the high res version. */ zoomOut: function() { // hide the high res video to stop video playback $('videoBBCodeObject-' + this.activeVideo).hide(); // switch out hi res version with low res version (without autoplayback) var video = $('videoBBCodeObject-' + this.activeVideo); video.addClassName('videoBBCodeObject').removeClassName('videoBBCodeZoomedObject').setStyle('left: 0px; top: 0px;'); video.width = this.activeVideoData['width']; video.height = this.activeVideoData['height']; video.writeAttribute('data', this.activeVideoData['data']); video.select('param[name="movie"]')[0].writeAttribute('value', this.activeVideoData['movieParam']); video.select('param[name="flashVars"]')[0].replace(new Element('param').writeAttribute('name', 'flashVars').writeAttribute('value', this.activeVideoData['flashVars'])); // show main content $('headerContainer').setStyle('visibility: visible;'); $('mainContainer').setStyle('visibility: visible;'); $('footerContainer').setStyle('visibility: visible;'); // hide video background etc this.copyright.hide(); this.caption.hide(); this.background.fade({ duration: 1, afterFinish: function() { // load low res video $('videoBBCodeObject-' + this.activeVideo).setStyle('display: block;'); this.activeVideo = 0; }.bind(this) }); // remove event listeners this.background.onclick = ''; Event.stopObserving(window, 'resize', this._resize); }, /** * Keep the high res video in the middle of the window and recalculate the size of the video, whenever the window is resized. */ resize: function() { if (this.activeVideo) { // min and max values var width = 600; var height = 450; var maxWidth = document.viewport.getWidth() - document.viewport.getWidth() / 10; var maxHeight = document.viewport.getHeight() - document.viewport.getHeight() / 8; if (maxWidth > 1200) maxWidth = 1200; if (maxHeight > 900) maxHeight = 900; // get final size and position if (maxWidth > width) width = maxWidth; if (maxHeight > height) height = maxHeight; var left = document.viewport.getWidth()/2 - width/2; var top = document.viewport.getHeight()/2 - height/2 + (IS_SAFARI_MOBILE ? document.viewport.getScrollOffsets().top : 0); // keep video in the middle of the window var element = $('videoBBCodeObject-' + this.activeVideo); if (element) { element.setStyle('left: ' + left + 'px; top: ' + top + 'px;'); element.width = width element.height = height } } }, /** * Due to a bug in the flash player plugin for IE, we have to remove all objects before navigating away from the page. * Some few players will still give us the occasional script error, but at least it's not breaking the browser anymore. */ suicide: function() { $$('body')[0].select('.videoBBCodeObject, .videoBBCodeZoomedObject').invoke('remove'); } });