1/* global Jetpack */ 2/** 3 * Resizeable Iframes. 4 * 5 * Start listening to resize postMessage events for selected iframes: 6 * $( selector ).Jetpack( 'resizeable' ); 7 * - OR - 8 * Jetpack.resizeable( 'on', context ); 9 * 10 * Resize selected iframes: 11 * $( selector ).Jetpack( 'resizeable', 'resize', { width: 100, height: 200 } ); 12 * - OR - 13 * Jetpack.resizeable( 'resize', { width: 100, height: 200 }, context ); 14 * 15 * Stop listening to resize postMessage events for selected iframes: 16 * $( selector ).Jetpack( 'resizeable', 'off' ); 17 * - OR - 18 * Jetpack.resizeable( 'off', context ); 19 * 20 * Stop listening to all resize postMessage events: 21 * Jetpack.resizeable( 'off' ); 22 */ 23(function($) { 24 var listening = false, // Are we listening for resize postMessage events 25 sourceOrigins = [], // What origins are allowed to send resize postMessage events 26 $sources = false, // What iframe elements are we tracking resize postMessage events from 27 28 URLtoOrigin, // Utility to convert URLs into origins 29 setupListener, // Binds global resize postMessage event handler 30 destroyListener, // Unbinds global resize postMessage event handler 31 32 methods; // Jetpack.resizeable methods 33 34 // Setup the Jetpack global 35 if ( 'undefined' === typeof window.Jetpack ) { 36 window.Jetpack = { 37 /** 38 * Handles the two different calling methods: 39 * $( selector ).Jetpack( 'namespace', 'method', context ) // here, context is optional and is used to filter the collection 40 * - vs. - 41 * Jetpack.namespace( 'method', context ) // here context defines the collection 42 * 43 * @internal 44 * 45 * Call as: Jetpack.getTarget.call( this, context ) 46 * 47 * @param string context: jQuery selector 48 * @return jQuery|undefined object on which to perform operations or undefined when context cannot be determined 49 */ 50 getTarget: function( context ) { 51 if ( this instanceof jQuery ) { 52 return context ? this.filter( context ) : this; 53 } 54 55 return context ? $( context ) : context; 56 } 57 }; 58 } 59 60 // Setup the Jetpack jQuery method 61 if ( 'undefined' === typeof $.fn.Jetpack ) { 62 /** 63 * Dispatches calls to the correct namespace 64 * 65 * @param string namespace 66 * @param ... 67 * @return mixed|jQuery (chainable) 68 */ 69 $.fn.Jetpack = function( namespace ) { 70 if ( 'function' === typeof Jetpack[namespace] ) { 71 // Send the call to the correct Jetpack.namespace 72 return Jetpack[namespace].apply( this, Array.prototype.slice.call( arguments, 1 ) ); 73 } else { 74 $.error( 'Namespace "' + namespace + '" does not exist on jQuery.Jetpack' ); 75 } 76 }; 77 } 78 79 // Define Jetpack.resizeable() namespace to just always bail if no postMessage 80 if ( 'function' !== typeof window.postMessage ) { 81 $.extend( window.Jetpack, { 82 /** 83 * Defines the Jetpack.resizeable() namespace. 84 * See below for non-trivial definition for browsers with postMessage. 85 */ 86 resizeable: function() { 87 $.error( 'Browser does not support window.postMessage' ); 88 } 89 } ); 90 91 return; 92 } 93 94 /** 95 * Utility to convert URLs into origins 96 * 97 * http://example.com:port/path?query#fragment -> http://example.com:port 98 * 99 * @param string URL 100 * @return string origin 101 */ 102 URLtoOrigin = function( URL ) { 103 if ( ! URL.match( /^https?:\/\// ) ) { 104 URL = document.location.href; 105 } 106 return URL.split( '/' ).slice( 0, 3 ).join( '/' ); 107 }; 108 109 /** 110 * Binds global resize postMessage event handler 111 */ 112 setupListener = function() { 113 listening = true; 114 115 $( window ).on( 'message.JetpackResizeableIframe', function( e ) { 116 var event = e.originalEvent, 117 data; 118 119 // Ensure origin is allowed 120 if ( -1 === $.inArray( event.origin, sourceOrigins ) ) { 121 return; 122 } 123 124 // Some browsers send structured data, some send JSON strings 125 if ( 'object' === typeof event.data ) { 126 data = event.data.data; 127 } else { 128 try { 129 data = JSON.parse( event.data ); 130 } catch ( err ) { 131 data = false; 132 } 133 } 134 135 if ( !data.data ) { 136 return; 137 } 138 139 // Un-nest 140 data = data.data; 141 142 // Is it a resize event? 143 if ( 'undefined' === typeof data.action || 'resize' !== data.action ) { 144 return; 145 } 146 147 // Find the correct iframe and resize it 148 $sources.filter( function() { 149 if ( 'undefined' !== typeof data.name ) { 150 return this.name === data.name; 151 } else { 152 return event.source === this.contentWindow; 153 } 154 } ).first().Jetpack( 'resizeable', 'resize', data ); 155 } ); 156 }; 157 158 /** 159 * Unbinds global resize postMessage event handler 160 */ 161 destroyListener = function() { 162 listening = false;
163 $( window ).off( 'message.JetpackResizeableIframe' ); 164 165 sourceOrigins = []; 166 $( '.jetpack-resizeable' ).removeClass( 'jetpack-resizeable' ); 167 $sources = false; 168 }; 169 170 // Methods for Jetpack.resizeable() namespace 171 methods = { 172 /** 173 * Start listening for resize postMessage events on the given iframes 174 * 175 * Call statically as: Jetpack.resizeable( 'on', context ) 176 * Call as: $( selector ).Jetpack( 'resizeable', 'on', context ) // context optional: used to filter the collectino 177 * 178 * @param string context jQuery selector. 179 * @return jQuery (chainable) 180 */ 181 on: function( context ) { 182 var target = Jetpack.getTarget.call( this, context ); 183 184 if ( ! listening ) { 185 setupListener(); 186 } 187 188 target.each( function() { 189 sourceOrigins.push( URLtoOrigin( $( this ).attr( 'src' ) ) ); 190 } ).addClass( 'jetpack-resizeable' ); 191 192 $sources = $( '.jetpack-resizeable' ); 193 194 return target; 195 }, 196 197 /** 198 * Stop listening for resize postMessage events on the given iframes 199 * 200 * Call statically as: Jetpack.resizeable( 'off', context ) 201 * Call as: $( selector ).Jetpack( 'resizeable', 'off', context ) // context optional: used to filter the collectino 202 * 203 * @param string context jQuery selector 204 * @return jQuery (chainable) 205 */ 206 off: function( context ) { 207 var target = Jetpack.getTarget.call( this, context ); 208 209 if ( 'undefined' === typeof target ) { 210 destroyListener(); 211 212 return target; 213 } 214 215 target.each( function() { 216 var origin = URLtoOrigin( $( this ).attr( 'src' ) ), 217 pos = $.inArray( origin, sourceOrigins ); 218 219 if ( -1 !== pos ) { 220 sourceOrigins.splice( pos, 1 ); 221 } 222 } ).removeClass( 'jetpack-resizeable' ); 223 224 $sources = $( '.jetpack-resizeable' ); 225 226 return target; 227 }, 228 229 /** 230 * Resize the given iframes 231 * 232 * Call statically as: Jetpack.resizeable( 'resize', dimensions, context ) 233 * Call as: $( selector ).Jetpack( 'resizeable', 'resize', dimensions, context ) // context optional: used to filter the collectino 234 * 235 * @param object dimensions in pixels: { width: (int), height: (int) } 236 * @param string context jQuery selector 237 * @return jQuery (chainable) 238 */ 239 resize: function( dimensions, context ) { 240 var target = Jetpack.getTarget.call( this, context ); 241 242 $.each( [ 'width', 'height' ], function( i, variable ) { 243 var value = 0, 244 container; 245 if ( 'undefined' !== typeof dimensions[variable] ) { 246 value = parseInt( dimensions[variable], 10 ); 247 } 248 249 if ( 0 !== value ) { 250 target[variable]( value ); 251 container = target.parent(); 252 if ( container.hasClass( 'slim-likes-widget' ) ) { 253 container[variable]( value ); 254 } 255 } 256 } ); 257 258 return target; 259 } 260 }; 261 262 // Define Jetpack.resizeable() namespace 263 $.extend( window.Jetpack, { 264 /** 265 * Defines the Jetpack.resizeable() namespace. 266 * See above for trivial definition for browsers with no postMessage. 267 * 268 * @param string method 269 * @param ... 270 * @return mixed|jQuery (chainable) 271 */ 272 resizeable: function( method ) { 273 if ( methods[method] ) { 274 // Send the call to the correct Jetpack.resizeable() method 275 return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ) ); 276 } else if ( ! method ) { 277 // By default, send to Jetpack.resizeable( 'on' ), which isn't useful in that form but is when called as 278 // jQuery( selector ).Jetpack( 'resizeable' ) 279 return methods.on.apply( this ); 280 } else { 281 $.error( 'Method ' + method + ' does not exist on Jetpack.resizeable' ); 282 } 283 } 284 } ); 285})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.