WordPress.org

Make WordPress Core

Ticket #29267: 29267.2.diff

File 29267.2.diff, 12.2 KB (added by wonderboymusic, 7 years ago)
  • src/wp-includes/js/mediaelement/froogaloop.min.js

     
     1// Init style shamelessly stolen from jQuery http://jquery.com
     2var 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        isReady = false,
     12        slice = Array.prototype.slice,
     13        playerDomain = '';
     14
     15    Froogaloop.fn = Froogaloop.prototype = {
     16        element: null,
     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' && 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' && !isReady) {
     153            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        window.Froogaloop = window.$f = Froogaloop
     287})();
     288 No newline at end of file
  • src/wp-includes/media-template.php

     
    5252?>
    5353<#  var w_rule = h_rule = '',
    5454                w, h, settings = wp.media.view.settings,
    55                 isYouTube = ! _.isEmpty( data.model.src ) && data.model.src.match(/youtube|youtu\.be/);
     55                isYouTube = ! _.isEmpty( data.model.src ) && data.model.src.match(/youtube|youtu\.be/),
     56                isVimeo = ! _.isEmpty( data.model.src ) && -1 !== data.model.src.indexOf('vimeo');
    5657
    5758        if ( settings.contentWidth && data.model.width >= settings.contentWidth ) {
    5859                w = settings.contentWidth;
     
    100101        <# if ( ! _.isEmpty( data.model.src ) ) {
    101102                if ( isYouTube ) { #>
    102103                <source src="{{ data.model.src }}" type="video/youtube" />
     104                <# } else if ( isVimeo ) { #>
     105                <source src="{{ data.model.src }}" type="video/vimeo" />
    103106                <# } else { #>
    104107                <source src="{{ data.model.src }}" type="{{ settings.embedMimes[ data.model.src.split('.').pop() ] }}" />
    105108                <# }
  • src/wp-includes/media.php

     
    17531753        }
    17541754
    17551755        $yt_pattern = '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#';
     1756        $vimeo_pattern = '#https?://(.+\.)?vimeo\.com/.*#';
    17561757
    17571758        $primary = false;
    17581759        if ( ! empty( $atts['src'] ) ) {
    1759                 if ( ! preg_match( $yt_pattern, $atts['src'] ) ) {
     1760                $is_vimeo = ( preg_match( $vimeo_pattern, $atts['src'] ) );
     1761                if ( ! preg_match( $yt_pattern, $atts['src'] ) && ! $is_vimeo ) {
    17601762                        $type = wp_check_filetype( $atts['src'], wp_get_mime_types() );
    17611763                        if ( ! in_array( strtolower( $type['ext'] ), $default_types ) ) {
    17621764                                return sprintf( '<a class="wp-embedded-video" href="%s">%s</a>', esc_url( $atts['src'] ), esc_html( $atts['src'] ) );
    17631765                        }
    17641766                }
     1767
     1768                if ( $is_vimeo ) {
     1769                        if ( in_the_loop() ) {
     1770                                wp_print_scripts( array( 'froogaloop' ) );
     1771                        } else {
     1772                                wp_enqueue_script( 'froogaloop' );
     1773                        }
     1774                }
     1775
    17651776                $primary = true;
    17661777                array_unshift( $default_types, 'src' );
    17671778        } else {
     
    18481859                        }
    18491860                        if ( 'src' === $fallback && preg_match( $yt_pattern, $atts['src'] ) ) {
    18501861                                $type = array( 'type' => 'video/youtube' );
     1862                        } elseif ( 'src' === $fallback && preg_match( $vimeo_pattern, $atts['src'] ) ) {
     1863                                $type = array( 'type' => 'video/vimeo' );
    18511864                        } else {
    18521865                                $type = wp_check_filetype( $atts[ $fallback ], wp_get_mime_types() );
    18531866                        }
  • src/wp-includes/script-loader.php

     
    327327                'pluginPath' => includes_url( 'js/mediaelement/', 'relative' ),
    328328        ) );
    329329
     330        $scripts->add( 'froogaloop', "/wp-includes/js/mediaelement/froogaloop.min.js" );
    330331        $scripts->add( 'wp-playlist', "/wp-includes/js/mediaelement/wp-playlist.js", array( 'wp-util', 'backbone', 'mediaelement' ), false, 1 );
    331332
    332333        $scripts->add( 'zxcvbn-async', "/wp-includes/js/zxcvbn-async$suffix.js", array(), '1.0' );