1// initialize and store reference in Cargo.Plugins 2var Cargo = Cargo || {}; 3 4Cargo.Plugins = Cargo.Plugins || {}; 5 6// use a closure so we have private and public methods. 7Cargo.Plugins.elementResizer = (function($) { 8 9 var self = { 10 11 vars: { 12 ticking: false, 13 initialized: false 14 }, 15 16 options: { 17 cargo_refreshEvents: ['show_index_complete', 'pagination_complete', 'project_load_complete', 'inspector_preview', 'project_collection_reset', 'direct_link_loaded'], 18 generic_refreshEvents: [], 19 updateEvents: ['resize', 'orientationchange'], 20 selectors: ['img', 'object', 'iframe', 'video', '.elementresizer', '[data-elementresizer-child]', '.slideshow', '.audio_component'], 21 targets: {}, 22 minimumHeight: 100, 23 minimumWidth: 100, 24 centerElements: true, 25 adjustElementsToWindowHeight: true, 26 forceMargin: false, 27 forceVerticalMargin: 40, 28 forceHorizontalMargin: 0, 29 allowInit: true 30 }, 31 32 init: function() { 33 34 if(Cargo.hasOwnProperty('Event')){ 35 Cargo.Event.trigger("element_resizer_init", publicVars); 36 } 37 38 // stupid IE8 fallback 39 function bindEvent(el, eventName, eventHandler) { 40 if (el.addEventListener){ 41 el.addEventListener(eventName, eventHandler, false); 42 } else if (el.attachEvent){ 43 el.attachEvent('on'+eventName, eventHandler); 44 } 45 } 46 47 if(!self.options.allowInit){ 48 return false; 49 } 50 51 var resizeTimeout; 52 53 $.each(self.options.updateEvents, function(key, event) { 54 bindEvent(window, event, function() { 55 self.requestTick(); 56 57 if(event === "resize"){ 58 clearTimeout(resizeTimeout); 59 resizeTimeout = setTimeout(function(){ 60 self.requestTick(); 61 }, 100); 62 } 63 64 }); 65 }); 66 67 // bind some event listeners to automagically refresh 68 $.each(self.options.generic_refreshEvents, function(key, event) { 69 bindEvent(window, event, function() { 70 self.refresh(); 71 self.update(); 72 }); 73 }); 74 75 $.each(self.options.cargo_refreshEvents, function(key, val) { 76 // these are Cargo specific events. Only do this when we are on Cargo. 77 if(Cargo.hasOwnProperty('Event')){ 78 Cargo.Event.on(val, function() { 79 self.refresh(); 80 self.update(); 81 }); 82 } 83 }); 84 85 if(Cargo.hasOwnProperty('Event')){ 86 Cargo.Event.on("inspector_open", function() { 87 CargoInspector.eventManager.subscribe('style_changed', function(source){ 88 self.update(); 89 }); 90 }); 91 } 92 93 self.vars.initialized = true; 94 95 self.refresh(); 96 self.update(); 97 98 }, 99 100 refresh: function() { 101 102 if(!self.vars.initialized){ 103 return false; 104 } 105 106 var containers = $('[data-elementresizer]'); 107 108 self.options.targets = {}; 109 110 containers.each(function(index, container) { 111 var children = $(container).find(self.options.selectors.join(',')), 112 resize_parent = $(container).closest('[data-resize-parent]'); 113 114 if (resize_parent.length == 0) { 115 resize_parent = $('body'); 116 } 117 118 var childrenArray = [], 119 queueArray = []; 120 121 // minimize DOM api calls 122 children.each(function(key, child) { 123 124 var columnizerParent = $(child).closest('[data-columnize]'), 125 nodeName = child.nodeName, 126 child = $(child); 127 128 if ((columnizerParent.length == 0 || columnizerParent.is('[data-allow-elementresizer]') !== false) && !(child.closest('[data-no-elementresizer]').length > 0 || child[0].hasAttribute('data-no-elementresizer'))) { 129 130 var childWidth = child.width(), 131 childHeight = child.height(), 132 133 actualWidth = parseInt(child.attr('width')), 134 actualHeight = parseInt(child.attr('height')), 135 136 originalWidth = (isNaN(actualWidth) ? childWidth : actualWidth), 137 originalHeight = (isNaN(actualHeight) ? childHeight : actualHeight), 138 139 minimumHeight = self.constrain(self.options.minimumHeight, 0, originalHeight), 140 minimumWidth = self.constrain(self.options.minimumWidth, 0, originalWidth), 141 142 isSlideshow = (child.hasClass('slideshow') ? Cargo.Core.Slideshow.SlideshowObjects[child.attr('data-id')] : false), 143 isVideoPlayer = child.closest('.video_component').length > 0 && child.is('video'), 144 145 noResize = isVideoPlayer ? 146 child.closest('.video_component').parent('[data-elementresizer-no-resize]').length > 0 || child.closest('.video_component')[0].hasAttribute('data-elementresizer-no-resize') : 147 child.parent('[data-elementresizer-no-resize]').length > 0 || child[0].hasAttribute('data-elementresizer-no-resize'), 148 149 noVerticalResize = isVideoPlayer ? 150 child.closest('.video_component').parent('[data-elementresizer-no-vertical-resize]').length > 0 || child.closest('.video_component')[0].hasAttribute('data-elementresizer-no-vertical-resize') : 151 child.parent('[data-elementresizer-no-vertical-resize]').length > 0 || child[0].hasAttribute('data-elementresizer-no-vertical-resize'), 152 153 noCentering = isVideoPlayer ? 154 child.closest('.video_component').parent('[data-elementresizer-no-centering]').length > 0 || child.closest('.video_component')[0].hasAttribute('data-elementresizer-no-centering') : 155 child.parent('[data-elementresizer-no-centering]').length > 0 || child[0].hasAttribute('data-elementresizer-no-centering'), 156 157 childObj = { 158 element: child, 159 originalWidth : originalWidth, 160 originalHeight : originalHeight, 161 actualWidth : actualWidth, 162 actualHeight : actualHeight, 163 minimumHeight : (minimumHeight > originalHeight ? originalHeight : minimumHeight), 164 minimumWidth : (minimumWidth > originalWidth ? originalWidth : minimumWidth), 165 ratio : (originalHeight / originalWidth), 166 nodeName : child[0].nodeName.toLowerCase(), 167 isVideoPlayer : isVideoPlayer,
168 isSlideshow : isSlideshow, 169 isAudioPlayer : child.hasClass('audio_component'), 170 noResize : noResize, 171 noCentering : noCentering, 172 noVerticalResize : noVerticalResize, 173 prevLeftMargin : 0, 174 isSoundCloudFrame: (child.attr('src') + '').indexOf('soundcloud') !== -1 && child[0].nodeName === "IFRAME" 175 }; 176 177 if(isSlideshow){ 178 queueArray.push(childObj); 179 } else { 180 childrenArray.push(childObj); 181 } 182 183 } 184 }); 185 186 childrenArray = childrenArray.concat(queueArray); 187 188 var padding = parseInt($(resize_parent).css('paddingLeft')) + parseInt($(resize_parent).css('paddingRight')); 189 190 191 if (isNaN(padding)) { 192 padding = 0; 193 } 194 195 self.options.targets[index] = { 196 container: $(container), 197 resize_parent: resize_parent, 198 children: childrenArray, 199 padding: padding 200 } 201 202 }); 203 204 self.update(); 205 206 }, 207 208 requestTick: function() { 209 210 if (!self.vars.ticking) { 211 212 requestAnimationFrame(function(){ 213 self.update(); 214 }); 215 216 self.vars.ticking = true; 217 } 218 219 }, 220 221 constrain: function(val, min, max){ 222 return val > max ? max : val < min ? min : val; 223 }, 224 225 update: function() { 226 227 // for in vars 228 var targetKey, 229 childKey, 230 childObj, 231 target; 232 233 for(targetKey in self.options.targets){ 234 235 target = self.options.targets[targetKey]; 236 237 var parentWidth = target.container.width(), 238 padding = target.padding, 239 maxWidth = target.resize_parent.width() - self.options.forceHorizontalMargin, 240 globalMaxHeight = (self.options.adjustElementsToWindowHeight ? document.documentElement.clientHeight - self.options.forceVerticalMargin : 9e9), 241 maxHeight = globalMaxHeight, 242 scalingRatio = 1; // set it to one. Just in case. 243 244 // handle rotation 245 if(self.options.adjustElementsToWindowHeight && window.orientation !== undefined){ 246 if(window.orientation != 0){ 247 maxHeight = document.documentElement.clientWidth - (self.options.forceMargin === false ? 40 : self.options.forceMargin); 248 } 249 } 250 251 for(childKey in target.children){ 252 253 childObj = target.children[childKey]; 254 255 if(!childObj.noResize){ 256 if(childObj.noVerticalResize){ 257 maxHeight = 9e9; 258 } else { 259 maxHeight = globalMaxHeight; 260 } 261 262 var childWidth = childObj.actualWidth, 263 childHeight = childObj.actualHeight; 264 265 // check if we need to scale the horizontal or vertical side 266 horizontalDelta = self.constrain(maxWidth - childWidth, 1, 9e9), 267 verticalDelta = self.constrain(maxHeight - childHeight, 1, 9e9); 268 269 // get the ratio based on the side that's being scaled 270 scalingRatio = [maxWidth / childObj.actualWidth, maxHeight / childObj.actualHeight]; 271 scalingRatio = Math.min(scalingRatio[0], scalingRatio[1]); 272 273 // calculate new size 274 childHeight = self.constrain(childHeight * scalingRatio, -9e9, childObj.originalHeight); 275 childWidth = self.constrain(childWidth * scalingRatio, -9e9, childObj.originalWidth); 276 277 // rescale if one of the dimensions is smaller than the minimum value 278 if(childHeight <= childObj.minimumHeight || childWidth <= childObj.minimumWidth){ 279 scalingRatio = [childObj.minimumWidth / childWidth, childObj.minimumHeight / childHeight]; 280 scalingRatio = Math.max(scalingRatio[0], scalingRatio[1]); 281 282 childHeight = childHeight * scalingRatio; 283 childWidth = childWidth * scalingRatio; 284 } 285 286 if(childObj.isAudioPlayer){ 287 if(Cargo.hasOwnProperty('Core')){ 288 Cargo.Core.Audio.InitPlayerSize(); 289 } 290 } 291 292 // check if anything changed. Otherwise no need to redraw. 293 if(childObj.actualWidth != childWidth || childObj.actualHeight != childHeight){ 294 295 if(!isNaN(childWidth) && !isNaN(childHeight)){ 296 297 childObj.actualWidth = childWidth; 298 childObj.actualHeight = childHeight; 299 300 childObj.element.add(childObj.nodeName === "object" ? childObj.element.find('embed') : '').css({ 301 'width': childObj.actualWidth + 'px', 302 'height': childObj.actualHeight + 'px' 303 }); 304 305 if ( childObj.isVideoPlayer){ 306 var mediaPlayer = childObj.element.closest('.mediaplayer') 307 mediaPlayer.css({ 308 'width': childObj.actualWidth + 'px', 309 'height': childObj.actualHeight + 'px' 310 }); 311 } 312 313 } 314 315 } 316 317 } 318 319 if(self.options.centerElements && !childObj.noCentering){ 320 self.setLeftMargin(childObj, parentWidth); 321 } 322
323 if(childObj.isSlideshow){ 324 if(childObj.isSlideshow !== undefined){ 325 childObj.actualWidth = childObj.isSlideshow.resizeContainer(); 326 } 327 } 328 329 }; 330 331 }; 332 333 self.vars.ticking = false; 334 335 if(Cargo.hasOwnProperty('Event')){ 336 Cargo.Event.trigger("elementresizer_update_complete", publicVars); 337 } 338 339 }, 340 341 setLeftMargin: function(childObj, parentWidth, force){ 342 343 var marginLeft; 344 345 if(childObj.isSoundCloudFrame){ 346 marginLeft = (parentWidth - childObj.element.width()) / 2; 347 } else { 348 marginLeft = (parentWidth - childObj.actualWidth) / 2; 349 } 350 351 352 if(!isNaN(marginLeft)){ 353 354 if (childObj.prevLeftMargin !== marginLeft) { 355 356 if ( childObj.isVideoPlayer ){ 357 childObj.element.closest('.mediaplayer').css('marginLeft', marginLeft); 358 } else { 359 childObj.element.css('marginLeft', marginLeft); 360 } 361 362 } 363 364 childObj.prevLeftMargin = marginLeft; 365 366 } 367 368 } 369 370 }; 371 372 var publicVars = { 373 options: self.options, 374 init: self.init, 375 refresh: self.refresh, 376 update: self.update, 377 setOptions: function(newOptions) { 378 379 $.extend(self.options, newOptions); 380 381 if(self.options.forceMargin !== false){ 382 self.options.forceHorizontalMargin = self.options.forceMargin; 383 self.options.forceVerticalMargin = self.options.forceMargin; 384 } 385 386 if(self.options.allowInit && self.vars.initialized){ 387 self.update(); 388 } 389 390 }, 391 targets: function() { 392 return self.options.targets; 393 } 394 }; 395 396 $(function(){ 397 self.init(); 398 }); 399 400 return publicVars 401 402 })(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.