1/** 2 * Video Resizer 3 * 4 * Makes legacy fixed-size embeds (pasted iframes carrying pixel width/height 5 * attributes, e.g. width="640" height="360") fit the content column. 6 * 7 * Iframes WITHOUT pixel size attributes are sized by the page's CSS (e.g. the 8 * video call-to-action panels, whose iframes fill an aspect-ratio wrapper via 9 * width/height:100%) and are deliberately left alone: writing inline pixel 10 * sizes onto them would override their stylesheet sizing and pin them to the 11 * #content column width inside full-bleed sections. Add data-vr-skip to an 12 * element or any ancestor to opt anything else out explicitly. 13 * 14 * iframes injected AFTER page load (e.g. by yt-facade.js) are picked up 15 * via refresh() calls on resize; if you inject videos dynamically you can also 16 * call window.VideoResizer.refresh() directly. 17 */ 18(function ($) { 19 'use strict'; 20 21 var DEFAULT_RATIO = 9 / 16; // height / width 22 var SELECTOR = [ 23 'iframe[src*="player.vimeo.com"]', 24 'iframe[src*="youtube.com/embed"]', 25 'iframe[src*="youtube-nocookie.com/embed"]', 26 'object', 27 'embed' 28 ].join(', '); 29 30 function getParent() { 31 return $('#homeContent').length ? $('#homeContent') : $('#content'); 32 } 33 34 // Returns the attribute as a pixel count, or 0 when it's absent or not a 35 // plain number (percentage attributes like width="100%" are CSS-style 36 // sizing, not a pixel measurement - parseInt would misread them as 100px). 37 function pixelAttr($v, name) { 38 var val = $v.attr(name); 39 return (typeof val === 'string' && /^\s*\d+\s*$/.test(val)) ? parseInt(val, 10) : 0; 40 } 41 42 // Only legacy fixed-size embeds are managed; CSS-sized iframes (no pixel 43 // width/height attributes) manage themselves. <object>/<embed> predate CSS 44 // sizing and stay managed. data-vr-skip is an explicit opt-out for both. 45 function isManaged($v) { 46 if ($v.closest('[data-vr-skip]').length) return false; 47 if (!$v.is('iframe')) return true; 48 return pixelAttr($v, 'width') > 0 || pixelAttr($v, 'height') > 0; 49 } 50 51 function measure($v) { 52 // Prefer explicit pixel attributes, fall back to rendered size 53 var w = pixelAttr($v, 'width') || $v.width() || 0; 54 var h = pixelAttr($v, 'height') || $v.height() || 0; 55 56 var ratio = (w > 0 && h > 0) ? h / w : DEFAULT_RATIO; 57 // Guard against degenerate values from hidden/collapsed elements 58 if (!isFinite(ratio) || ratio <= 0) ratio = DEFAULT_RATIO; 59 60 $v.data('vrRatio', ratio); 61 // Natural width caps upscaling; 0 = unknown, no cap 62 $v.data('vrNaturalWidth', w > 0 ? w : 0); 63 $v.data('vrMeasured', true); 64 } 65 66 function resizeAll() { 67 var parentWidth = getParent().width(); 68 if (!parentWidth || parentWidth <= 0) return; 69 70 $(SELECTOR).each(function () { 71 var $v = $(this); 72 if (!isManaged($v)) return; // CSS-sized embeds (e.g. panels) manage themselves 73 if (!$v.data('vrMeasured')) measure($v); // late-added videos 74 75 var natural = $v.data('vrNaturalWidth'); 76 var ratio = $v.data('vrRatio'); 77 78 // Fit container, but don't upscale past the natural width 79 var targetWidth = (natural > 0) ? Math.min(parentWidth, natural) : parentWidth; 80 81 $v 82 .removeAttr('height') 83 .removeAttr('width') 84 .width(targetWidth) 85 .height(Math.round(targetWidth * ratio)); 86 }); 87 } 88 89 var resizeTimer; 90 function onResize() { 91 clearTimeout(resizeTimer); 92 resizeTimer = setTimeout(resizeAll, 100); 93 } 94 95 function init() { 96 $(SELECTOR).each(function () { 97 var $v = $(this); 98 if (isManaged($v)) measure($v); 99 }); 100 $(window).on('resize', onResize); 101 resizeAll(); 102 } 103 104 $(document).ready(init); 105 106 // Public hook for dynamically injected videos 107 window.VideoResizer = { refresh: resizeAll }; 108})(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.