Home | History | Annotate | Download | only in video_VimeoVideo
      1 
      2 // Init style shamelessly stolen from jQuery http://jquery.com
      3 var Froogaloop = (function(){
      4     // Define a local copy of Froogaloop
      5     function Froogaloop(iframe) {
      6         // The Froogaloop object is actually just the init constructor
      7         return new Froogaloop.fn.init(iframe);
      8     }
      9 
     10     var eventCallbacks = {},
     11         hasWindowEvent = false,
     12         isReady = false,
     13         slice = Array.prototype.slice,
     14         playerDomain = '';
     15 
     16     Froogaloop.fn = Froogaloop.prototype = {
     17         element: null,
     18 
     19         init: function(iframe) {
     20             if (typeof iframe === "string") {
     21                 iframe = document.getElementById(iframe);
     22             }
     23 
     24             this.element = iframe;
     25 
     26             // Register message event listeners
     27             playerDomain = getDomainFromUrl(this.element.getAttribute('src'));
     28 
     29             return this;
     30         },
     31 
     32         /*
     33          * Calls a function to act upon the player.
     34          *
     35          * @param {string} method The name of the Javascript API method to call. Eg: 'play'.
     36          * @param {Array|Function} valueOrCallback params Array of parameters to pass when calling an API method
     37          *                                or callback function when the method returns a value.
     38          */
     39         api: function(method, valueOrCallback) {
     40             if (!this.element || !method) {
     41                 return false;
     42             }
     43 
     44             var self = this,
     45                 element = self.element,
     46                 target_id = element.id !== '' ? element.id : null,
     47                 params = !isFunction(valueOrCallback) ? valueOrCallback : null,
     48                 callback = isFunction(valueOrCallback) ? valueOrCallback : null;
     49 
     50             // Store the callback for get functions
     51             if (callback) {
     52                 storeCallback(method, callback, target_id);
     53             }
     54 
     55             postMessage(method, params, element);
     56             return self;
     57         },
     58 
     59         /*
     60          * Registers an event listener and a callback function that gets called when the event fires.
     61          *
     62          * @param eventName (String): Name of the event to listen for.
     63          * @param callback (Function): Function that should be called when the event fires.
     64          */
     65         addEvent: function(eventName, callback) {
     66             if (!this.element) {
     67                 return false;
     68             }
     69 
     70             var self = this,
     71                 element = self.element,
     72                 target_id = element.id !== '' ? element.id : null;
     73 
     74 
     75             storeCallback(eventName, callback, target_id);
     76 
     77             // The ready event is not registered via postMessage. It fires regardless.
     78             if (eventName != 'ready') {
     79                 postMessage('addEventListener', eventName, element);
     80             }
     81             else if (eventName == 'ready' && isReady) {
     82                 callback.call(null, target_id);
     83             }
     84 
     85             return self;
     86         },
     87 
     88         /*
     89          * Unregisters an event listener that gets called when the event fires.
     90          *
     91          * @param eventName (String): Name of the event to stop listening for.
     92          */
     93         removeEvent: function(eventName) {
     94             if (!this.element) {
     95                 return false;
     96             }
     97 
     98             var self = this,
     99                 element = self.element,
    100                 target_id = element.id !== '' ? element.id : null,
    101                 removed = removeCallback(eventName, target_id);
    102 
    103             // The ready event is not registered
    104             if (eventName != 'ready' && removed) {
    105                 postMessage('removeEventListener', eventName, element);
    106             }
    107         }
    108     };
    109 
    110     /**
    111      * Handles posting a message to the parent window.
    112      *
    113      * @param method (String): name of the method to call inside the player. For api calls
    114      * this is the name of the api method (api_play or api_pause) while for events this method
    115      * is api_addEventListener.
    116      * @param params (Object or Array): List of parameters to submit to the method. Can be either
    117      * a single param or an array list of parameters.
    118      * @param target (HTMLElement): Target iframe to post the message to.
    119      */
    120     function postMessage(method, params, target) {
    121         if (!target.contentWindow.postMessage) {
    122             return false;
    123         }
    124 
    125         var url = target.getAttribute('src').split('?')[0],
    126             data = JSON.stringify({
    127                 method: method,
    128                 value: params
    129             });
    130 
    131         if (url.substr(0, 2) === '//') {
    132             url = window.location.protocol + url;
    133         }
    134 
    135         target.contentWindow.postMessage(data, url);
    136     }
    137 
    138     /**
    139      * Event that fires whenever the window receives a message from its parent
    140      * via window.postMessage.
    141      */
    142     function onMessageReceived(event) {
    143         var data, method;
    144 
    145         try {
    146             data = JSON.parse(event.data);
    147             method = data.event || data.method;
    148         }
    149         catch(e)  {
    150             //fail silently... like a ninja!
    151         }
    152 
    153         if (method == 'ready' && !isReady) {
    154             isReady = true;
    155         }
    156 
    157         // Handles messages from moogaloop only
    158         if (event.origin != playerDomain) {
    159             return false;
    160         }
    161 
    162         var value = data.value,
    163             eventData = data.data,
    164             target_id = target_id === '' ? null : data.player_id,
    165 
    166             callback = getCallback(method, target_id),
    167             params = [];
    168 
    169         if (!callback) {
    170             return false;
    171         }
    172 
    173         if (value !== undefined) {
    174             params.push(value);
    175         }
    176 
    177         if (eventData) {
    178             params.push(eventData);
    179         }
    180 
    181         if (target_id) {
    182             params.push(target_id);
    183         }
    184 
    185         return params.length > 0 ? callback.apply(null, params) : callback.call();
    186     }
    187 
    188 
    189     /**
    190      * Stores submitted callbacks for each iframe being tracked and each
    191      * event for that iframe.
    192      *
    193      * @param eventName (String): Name of the event. Eg. api_onPlay
    194      * @param callback (Function): Function that should get executed when the
    195      * event is fired.
    196      * @param target_id (String) [Optional]: If handling more than one iframe then
    197      * it stores the different callbacks for different iframes based on the iframe's
    198      * id.
    199      */
    200     function storeCallback(eventName, callback, target_id) {
    201         if (target_id) {
    202             if (!eventCallbacks[target_id]) {
    203                 eventCallbacks[target_id] = {};
    204             }
    205             eventCallbacks[target_id][eventName] = callback;
    206         }
    207         else {
    208             eventCallbacks[eventName] = callback;
    209         }
    210     }
    211 
    212     /**
    213      * Retrieves stored callbacks.
    214      */
    215     function getCallback(eventName, target_id) {
    216         if (target_id) {
    217             return eventCallbacks[target_id][eventName];
    218         }
    219         else {
    220             return eventCallbacks[eventName];
    221         }
    222     }
    223 
    224     function removeCallback(eventName, target_id) {
    225         if (target_id && eventCallbacks[target_id]) {
    226             if (!eventCallbacks[target_id][eventName]) {
    227                 return false;
    228             }
    229             eventCallbacks[target_id][eventName] = null;
    230         }
    231         else {
    232             if (!eventCallbacks[eventName]) {
    233                 return false;
    234             }
    235             eventCallbacks[eventName] = null;
    236         }
    237 
    238         return true;
    239     }
    240 
    241     /**
    242      * Returns a domain's root domain.
    243      * Eg. returns http://vimeo.com when http://vimeo.com/channels is sbumitted
    244      *
    245      * @param url (String): Url to test against.
    246      * @return url (String): Root domain of submitted url
    247      */
    248     function getDomainFromUrl(url) {
    249         if (url.substr(0, 2) === '//') {
    250             url = window.location.protocol + url;
    251         }
    252 
    253         var url_pieces = url.split('/'),
    254             domain_str = '';
    255 
    256         for(var i = 0, length = url_pieces.length; i < length; i++) {
    257             if(i<3) {domain_str += url_pieces[i];}
    258             else {break;}
    259             if(i<2) {domain_str += '/';}
    260         }
    261 
    262         return domain_str;
    263     }
    264 
    265     function isFunction(obj) {
    266         return !!(obj && obj.constructor && obj.call && obj.apply);
    267     }
    268 
    269     function isArray(obj) {
    270         return toString.call(obj) === '[object Array]';
    271     }
    272 
    273     // Give the init function the Froogaloop prototype for later instantiation
    274     Froogaloop.fn.init.prototype = Froogaloop.fn;
    275 
    276     // Listens for the message event.
    277     // W3C
    278     if (window.addEventListener) {
    279         window.addEventListener('message', onMessageReceived, false);
    280     }
    281     // IE
    282     else {
    283         window.attachEvent('onmessage', onMessageReceived);
    284     }
    285 
    286     // Expose froogaloop to the global object
    287     return (window.Froogaloop = window.$f = Froogaloop);
    288 
    289 })();
    290