1// IE5.5+ PNG Alpha Fix v2.0 Alpha: Background Tiling Support 2// (c) 2008-2009 Angus Turnbull http://www.twinhelix.com 3 4// This is licensed under the GNU LGPL, version 2.1 or later. 5// For details, see: http://creativecommons.org/licenses/LGPL/2.1/ 6 7var IEPNGFix = window.IEPNGFix || {}; 8 9IEPNGFix.tileBG = function(elm, pngSrc, ready) { 10 // Params: A reference to a DOM element, the PNG src file pathname, and a 11 // hidden "ready-to-run" passed when called back after image preloading. 12 13 var data = this.data[elm.uniqueID], 14 elmW = Math.max(elm.clientWidth, elm.scrollWidth), 15 elmH = Math.max(elm.clientHeight, elm.scrollHeight), 16 bgX = elm.currentStyle.backgroundPositionX, 17 bgY = elm.currentStyle.backgroundPositionY, 18 bgR = elm.currentStyle.backgroundRepeat; 19 20 // Cache of DIVs created per element, and image preloader/data. 21 if (!data.tiles) { 22 data.tiles = { 23 elm: elm, 24 src: '', 25 cache: [], 26 img: new Image(), 27 old: {} 28 }; 29 } 30 var tiles = data.tiles, 31 pngW = tiles.img.width, 32 pngH = tiles.img.height; 33 34 if (pngSrc) { 35 if (!ready && pngSrc != tiles.src) { 36 // New image? Preload it with a callback to detect dimensions. 37 tiles.img.onload = function() { 38 this.onload = null; 39 IEPNGFix.tileBG(elm, pngSrc, 1); 40 }; 41 return tiles.img.src = pngSrc; 42 } 43 } else { 44 // No image? 45 if (tiles.src) ready = 1; 46 pngW = pngH = 0; 47 } 48 tiles.src = pngSrc; 49 50 if (!ready && elmW == tiles.old.w && elmH == tiles.old.h && 51 bgX == tiles.old.x && bgY == tiles.old.y && bgR == tiles.old.r) { 52 return; 53 } 54 55 // Convert English and percentage positions to pixels. 56 var pos = { 57 top: '0%', 58 left: '0%', 59 center: '50%', 60 bottom: '100%', 61 right: '100%' 62 }, 63 x, 64 y, 65 pc; 66 x = pos[bgX] || bgX; 67 y = pos[bgY] || bgY; 68 if (pc = x.match(/(\d+)%/)) { 69 x = Math.round((elmW - pngW) * (parseInt(pc[1]) / 100)); 70 } 71 if (pc = y.match(/(\d+)%/)) { 72 y = Math.round((elmH - pngH) * (parseInt(pc[1]) / 100)); 73 } 74 x = parseInt(x); 75 y = parseInt(y); 76 77 // Handle backgroundRepeat. 78 var repeatX = { 'repeat': 1, 'repeat-x': 1 }[bgR], 79 repeatY = { 'repeat': 1, 'repeat-y': 1 }[bgR]; 80 if (repeatX) { 81 x %= pngW; 82 if (x > 0) x -= pngW; 83 } 84 if (repeatY) { 85 y %= pngH; 86 if (y > 0) y -= pngH; 87 } 88 89 // Go! 90 this.hook.enabled = 0; 91 if (!({ relative: 1, absolute: 1 }[elm.currentStyle.position])) { 92 elm.style.position = 'relative'; 93 } 94 var count = 0, 95 xPos, 96 maxX = repeatX ? elmW : x + 0.1, 97 yPos, 98 maxY = repeatY ? elmH : y + 0.1, 99 d, 100 s, 101 isNew; 102 if (pngW && pngH) { 103 for (xPos = x; xPos < maxX; xPos += pngW) { 104 for (yPos = y; yPos < maxY; yPos += pngH) { 105 isNew = 0; 106 if (!tiles.cache[count]) { 107 tiles.cache[count] = document.createElement('div'); 108 isNew = 1; 109 } 110 var clipR = Math.max(0, xPos + pngW > elmW ? elmW - xPos : pngW), 111 clipB = Math.max(0, yPos + pngH > elmH ? elmH - yPos : pngH); 112 d = tiles.cache[count]; 113 s = d.style; 114 s.behavior = 'none'; 115 s.left = (xPos - parseInt(elm.currentStyle.paddingLeft)) + 'px'; 116 s.top = yPos + 'px'; 117 s.width = clipR + 'px'; 118 s.height = clipB + 'px'; 119 s.clip = 'rect(' + 120 (yPos < 0 ? 0 - yPos : 0) + 'px,' + 121 clipR + 'px,' + 122 clipB + 'px,' + 123 (xPos < 0 ? 0 - xPos : 0) + 'px)'; 124 s.display = 'block'; 125 if (isNew) { 126 s.position = 'absolute'; 127 s.zIndex = -999; 128 if (elm.firstChild) { 129 elm.insertBefore(d, elm.firstChild); 130 } else { 131 elm.appendChild(d); 132 } 133 } 134 this.fix(d, pngSrc, 0); 135 count++; 136 } 137 } 138 } 139 while (count < tiles.cache.length) { 140 this.fix(tiles.cache[count], '', 0); 141 tiles.cache[count++].style.display = 'none'; 142 } 143 144 this.hook.enabled = 1; 145 146 // Cache so updates are infrequent. 147 tiles.old = { 148 w: elmW, 149 h: elmH, 150 x: bgX, 151 y: bgY, 152 r: bgR 153 }; 154}; 155 156 157IEPNGFix.update = function() { 158 // Update all PNG backgrounds. 159 for (var i in IEPNGFix.data) { 160 var t = IEPNGFix.data[i].tiles; 161 if (t && t.elm && t.src) { 162 IEPNGFix.tileBG(t.elm, t.src); 163 } 164 } 165}; 166IEPNGFix.update.timer = 0; 167 168if (window.attachEvent && !window.opera) { 169 window.attachEvent('onresize', function() { 170 clearTimeout(IEPNGFix.update.timer); 171 IEPNGFix.update.timer = setTimeout(IEPNGFix.update, 100); 172 }); 173}
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.