| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- /* global Jetpack, JSON */
- /**
- * Resizeable Iframes.
- *
- * Start listening to resize postMessage events for selected iframes:
- * $( selector ).Jetpack( 'resizeable' );
- * - OR -
- * Jetpack.resizeable( 'on', context );
- *
- * Resize selected iframes:
- * $( selector ).Jetpack( 'resizeable', 'resize', { width: 100, height: 200 } );
- * - OR -
- * Jetpack.resizeable( 'resize', { width: 100, height: 200 }, context );
- *
- * Stop listening to resize postMessage events for selected iframes:
- * $( selector ).Jetpack( 'resizeable', 'off' );
- * - OR -
- * Jetpack.resizeable( 'off', context );
- *
- * Stop listening to all resize postMessage events:
- * Jetpack.resizeable( 'off' );
- */
- (function($) {
- var listening = false, // Are we listening for resize postMessage events
- sourceOrigins = [], // What origins are allowed to send resize postMessage events
- $sources = false, // What iframe elements are we tracking resize postMessage events from
- URLtoOrigin, // Utility to convert URLs into origins
- setupListener, // Binds global resize postMessage event handler
- destroyListener, // Unbinds global resize postMessage event handler
- methods; // Jetpack.resizeable methods
- // Setup the Jetpack global
- if ( 'undefined' === typeof window.Jetpack ) {
- window.Jetpack = {
- /**
- * Handles the two different calling methods:
- * $( selector ).Jetpack( 'namespace', 'method', context ) // here, context is optional and is used to filter the collection
- * - vs. -
- * Jetpack.namespace( 'method', context ) // here context defines the collection
- *
- * @internal
- *
- * Call as: Jetpack.getTarget.call( this, context )
- *
- * @param string context: jQuery selector
- * @return jQuery|undefined object on which to perform operations or undefined when context cannot be determined
- */
- getTarget: function( context ) {
- if ( this instanceof jQuery ) {
- return context ? this.filter( context ) : this;
- }
- return context ? $( context ) : context;
- }
- };
- }
- // Setup the Jetpack jQuery method
- if ( 'undefined' === typeof $.fn.Jetpack ) {
- /**
- * Dispatches calls to the correct namespace
- *
- * @param string namespace
- * @param ...
- * @return mixed|jQuery (chainable)
- */
- $.fn.Jetpack = function( namespace ) {
- if ( 'function' === typeof Jetpack[namespace] ) {
- // Send the call to the correct Jetpack.namespace
- return Jetpack[namespace].apply( this, Array.prototype.slice.call( arguments, 1 ) );
- } else {
- $.error( 'Namespace "' + namespace + '" does not exist on jQuery.Jetpack' );
- }
- };
- }
- // Define Jetpack.resizeable() namespace to just always bail if no postMessage
- if ( 'function' !== typeof window.postMessage ) {
- $.extend( window.Jetpack, {
- /**
- * Defines the Jetpack.resizeable() namespace.
- * See below for non-trivial definition for browsers with postMessage.
- */
- resizeable: function() {
- $.error( 'Browser does not support window.postMessage' );
- }
- } );
- return;
- }
- /**
- * Utility to convert URLs into origins
- *
- * http://example.com:port/path?query#fragment -> http://example.com:port
- *
- * @param string URL
- * @return string origin
- */
- URLtoOrigin = function( URL ) {
- if ( ! URL.match( /^https?:\/\// ) ) {
- URL = document.location.href;
- }
- return URL.split( '/' ).slice( 0, 3 ).join( '/' );
- };
- /**
- * Binds global resize postMessage event handler
- */
- setupListener = function() {
- listening = true;
- $( window ).on( 'message.JetpackResizeableIframe', function( e ) {
- var event = e.originalEvent,
- data;
- // Ensure origin is allowed
- if ( -1 === $.inArray( event.origin, sourceOrigins ) ) {
- return;
- }
- // Some browsers send structured data, some send JSON strings
- if ( 'object' === typeof event.data ) {
- data = event.data.data;
- } else {
- try {
- data = JSON.parse( event.data );
- } catch ( err ) {
- data = false;
- }
- }
- if ( !data.data ) {
- return;
- }
- // Un-nest
- data = data.data;
- // Is it a resize event?
- if ( 'undefined' === typeof data.action || 'resize' !== data.action ) {
- return;
- }
- // Find the correct iframe and resize it
- $sources.filter( function() {
- if ( 'undefined' !== typeof data.name ) {
- return this.name === data.name;
- } else {
- return event.source === this.contentWindow;
- }
- } ).first().Jetpack( 'resizeable', 'resize', data );
- } );
- };
- /**
- * Unbinds global resize postMessage event handler
- */
- destroyListener = function() {
- listening = false;
- $( window ).off( 'message.JetpackResizeableIframe' );
- sourceOrigins = [];
- $( '.jetpack-resizeable' ).removeClass( 'jetpack-resizeable' );
- $sources = false;
- };
- // Methods for Jetpack.resizeable() namespace
- methods = {
- /**
- * Start listening for resize postMessage events on the given iframes
- *
- * Call statically as: Jetpack.resizeable( 'on', context )
- * Call as: $( selector ).Jetpack( 'resizeable', 'on', context ) // context optional: used to filter the collectino
- *
- * @param string context jQuery selector.
- * @return jQuery (chainable)
- */
- on: function( context ) {
- var target = Jetpack.getTarget.call( this, context );
- if ( ! listening ) {
- setupListener();
- }
- target.each( function() {
- sourceOrigins.push( URLtoOrigin( $( this ).attr( 'src' ) ) );
- } ).addClass( 'jetpack-resizeable' );
- $sources = $( '.jetpack-resizeable' );
- return target;
- },
- /**
- * Stop listening for resize postMessage events on the given iframes
- *
- * Call statically as: Jetpack.resizeable( 'off', context )
- * Call as: $( selector ).Jetpack( 'resizeable', 'off', context ) // context optional: used to filter the collectino
- *
- * @param string context jQuery selector
- * @return jQuery (chainable)
- */
- off: function( context ) {
- var target = Jetpack.getTarget.call( this, context );
- if ( 'undefined' === typeof target ) {
- destroyListener();
- return target;
- }
- target.each( function() {
- var origin = URLtoOrigin( $( this ).attr( 'src' ) ),
- pos = $.inArray( origin, sourceOrigins );
- if ( -1 !== pos ) {
- sourceOrigins.splice( pos, 1 );
- }
- } ).removeClass( 'jetpack-resizeable' );
- $sources = $( '.jetpack-resizeable' );
- return target;
- },
- /**
- * Resize the given iframes
- *
- * Call statically as: Jetpack.resizeable( 'resize', dimensions, context )
- * Call as: $( selector ).Jetpack( 'resizeable', 'resize', dimensions, context ) // context optional: used to filter the collectino
- *
- * @param object dimensions in pixels: { width: (int), height: (int) }
- * @param string context jQuery selector
- * @return jQuery (chainable)
- */
- resize: function( dimensions, context ) {
- var target = Jetpack.getTarget.call( this, context );
- $.each( [ 'width', 'height' ], function( i, variable ) {
- var value = 0,
- container;
- if ( 'undefined' !== typeof dimensions[variable] ) {
- value = parseInt( dimensions[variable], 10 );
- }
- if ( 0 !== value ) {
- target[variable]( value );
- container = target.parent();
- if ( container.hasClass( 'slim-likes-widget' ) ) {
- container[variable]( value );
- }
- }
- } );
- return target;
- }
- };
- // Define Jetpack.resizeable() namespace
- $.extend( window.Jetpack, {
- /**
- * Defines the Jetpack.resizeable() namespace.
- * See above for trivial definition for browsers with no postMessage.
- *
- * @param string method
- * @param ...
- * @return mixed|jQuery (chainable)
- */
- resizeable: function( method ) {
- if ( methods[method] ) {
- // Send the call to the correct Jetpack.resizeable() method
- return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ) );
- } else if ( ! method ) {
- // By default, send to Jetpack.resizeable( 'on' ), which isn't useful in that form but is when called as
- // jQuery( selector ).Jetpack( 'resizeable' )
- return methods.on.apply( this );
- } else {
- $.error( 'Method ' + method + ' does not exist on Jetpack.resizeable' );
- }
- }
- } );
- })(jQuery);
|