1/*! jQuery.ImgLoader - v0.1.0 - 3/29/2012 2 * https://github.com/Takazudo/jQuery.ImgLoader 3 * Copyright (c) 2012 "Takazudo" Takeshi Takatsudo; Licensed MIT */ 4 5(function() { 6 var __slice = Array.prototype.slice, 7 __hasProp = Object.prototype.hasOwnProperty, 8 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; 9 10 (function($, win, doc) { 11 var ns, wait; 12 ns = $.ImgLoaderNs = {}; 13 ns.createCachedFunction = function(requestedFunction) { 14 var cache; 15 cache = {}; 16 return function(key) { 17 if (!cache[key]) { 18 cache[key] = $.Deferred(function(defer) { 19 return requestedFunction(defer, key); 20 }).promise(); 21 } 22 return cache[key]; 23 }; 24 }; 25 ns.fetchImg = ns.createCachedFunction(function(defer, src) { 26 var $img, cleanUp, img; 27 img = new Image; 28 cleanUp = function() { 29 return img.onload = img.onerror = null; 30 }; 31 defer.always(cleanUp); 32 $img = $(img); 33 img.onload = function() { 34 return defer.resolve($img); 35 }; 36 img.onerror = function() { 37 return defer.reject($img); 38 }; 39 return img.src = src; 40 }); 41 (function() { 42 var cache; 43 cache = {}; 44 return ns.loadImg = function(src) { 45 return $.Deferred(function(defer) { 46 return (ns.fetchImg(src)).then(function($img) { 47 var $cachedImg, $cloned; 48 if (!cache[src]) cache[src] = $img; 49 $cachedImg = cache[src]; 50 $cloned = $cachedImg.clone(); 51 cache[src] = $cloned; 52 return defer.resolve($cachedImg); 53 }, function($img) { 54 return defer.reject($img); 55 }); 56 }).promise(); 57 }; 58 })(); 59 wait = function(time) { 60 return $.Deferred(function(defer) { 61 return setTimeout(function() { 62 return defer.resolve(); 63 }, time); 64 }); 65 }; 66 ns.Event = (function() { 67 68 function Event() { 69 this._callbacks = {}; 70 } 71 72 Event.prototype.bind = function(ev, callback) { 73 var evs, name, _base, _i, _len; 74 evs = ev.split(' '); 75 for (_i = 0, _len = evs.length; _i < _len; _i++) { 76 name = evs[_i]; 77 (_base = this._callbacks)[name] || (_base[name] = []); 78 this._callbacks[name].push(callback); 79 } 80 return this; 81 }; 82 83 Event.prototype.one = function(ev, callback) { 84 return this.bind(ev, function() { 85 this.unbind(ev, arguments.callee); 86 return callback.apply(this, arguments); 87 }); 88 }; 89 90 Event.prototype.trigger = function() { 91 var args, callback, ev, list, _i, _len, _ref; 92 args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; 93 ev = args.shift(); 94 list = (_ref = this._callbacks) != null ? _ref[ev] : void 0; 95 if (!list) return; 96 for (_i = 0, _len = list.length; _i < _len; _i++) { 97 callback = list[_i]; 98 if (callback.apply(this, args) === false) break; 99 } 100 return this; 101 }; 102 103 Event.prototype.unbind = function(ev, callback) { 104 var cb, i, list, _len, _ref; 105 if (!ev) { 106 this._callbacks = {}; 107 return this; 108 } 109 list = (_ref = this._callbacks) != null ? _ref[ev] : void 0; 110 if (!list) return this; 111 if (!callback) { 112 delete this._callbacks[ev]; 113 return this; 114 } 115 for (i = 0, _len = list.length; i < _len; i++) { 116 cb = list[i]; 117 if (!(cb === callback)) continue; 118 list = list.slice(); 119 list.splice(i, 1); 120 this._callbacks[ev] = list; 121 break; 122 } 123 return this; 124 }; 125 126 return Event; 127 128 })(); 129 ns.LoaderItem = (function(_super) { 130 131 __extends(LoaderItem, _super); 132 133 function LoaderItem(src) { 134 this.src = src; 135 LoaderItem.__super__.constructor.apply(this, arguments); 136 } 137 138 LoaderItem.prototype.load = function() { 139 var _this = this; 140 return $.Deferred(function(defer) {
141 return (ns.loadImg(_this.src)).pipe(function($img) { 142 _this.$img = $img; 143 _this.trigger('success', _this.$img); 144 _this.trigger('complete', _this.$img); 145 return defer.resolve(_this.$img); 146 }, function($img) { 147 _this.$img = $img; 148 _this.trigger('error', _this.$img); 149 _this.trigger('complete', _this.$img); 150 return defer.reject(_this.$img); 151 }); 152 }).promise(); 153 }; 154 155 return LoaderItem; 156 157 })(ns.Event); 158 ns.BasicLoader = (function(_super) { 159 160 __extends(BasicLoader, _super); 161 162 function BasicLoader() { 163 BasicLoader.__super__.constructor.apply(this, arguments); 164 this.items = []; 165 } 166 167 BasicLoader.prototype.add = function(loaderItem) { 168 var src; 169 if (($.type(loaderItem)) === 'string') { 170 src = loaderItem; 171 loaderItem = new ns.LoaderItem(src); 172 } 173 this.items.push(loaderItem); 174 return loaderItem; 175 }; 176 177 BasicLoader.prototype.load = function() { 178 var count, laodDeferreds, 179 _this = this; 180 count = 0; 181 laodDeferreds = $.map(this.items, function(item) { 182 return item.bind('complete', function($img) { 183 _this.trigger('itemload', $img, count); 184 return count++; 185 }).load(); 186 }); 187 return $.Deferred(function(defer) { 188 return ($.when.apply(_this, laodDeferreds)).always(function() { 189 var $imgs, imgs; 190 imgs = 1 <= arguments.length ? __slice.call(arguments, 0) : []; 191 $imgs = $(imgs); 192 _this.trigger('allload', $imgs); 193 return defer.resolve($imgs); 194 }); 195 }); 196 }; 197 198 BasicLoader.prototype.kill = function() { 199 $.each(this.items, function(i, item) { 200 return item.unbind(); 201 }); 202 this.trigger('kill'); 203 this.unbind(); 204 return this; 205 }; 206 207 return BasicLoader; 208 209 })(ns.Event); 210 ns.ChainLoader = (function(_super) { 211 212 __extends(ChainLoader, _super); 213 214 function ChainLoader(_pipesize, _delay) { 215 this._pipesize = _pipesize; 216 this._delay = _delay != null ? _delay : 0; 217 ChainLoader.__super__.constructor.apply(this, arguments); 218 this._presets = []; 219 this._doneCount = 0; 220 this._inLoadCount = 0; 221 this._allDoneDefer = $.Deferred(); 222 } 223 224 ChainLoader.prototype._finished = function() { 225 return this._doneCount === this._presets.length; 226 }; 227 228 ChainLoader.prototype._nextLoadAllowed = function() { 229 return this._inLoadCount < this._pipesize; 230 }; 231 232 ChainLoader.prototype._getImgs = function() { 233 return $($.map(this._presets, function(preset) { 234 return preset.item.$img; 235 })); 236 }; 237 238 ChainLoader.prototype._handleNext = function() { 239 var $imgs, 240 _this = this; 241 if (this._finished()) { 242 if (this._allloadFired) return this; 243 this._allloadFired = true; 244 $imgs = this._getImgs(); 245 this.trigger('allload', $imgs); 246 this._allDoneDefer.resolve($imgs); 247 return this; 248 } 249 $.each(this._presets, function(i, preset) { 250 if (preset.started) return true; 251 if (!_this._nextLoadAllowed()) return false; 252 _this._inLoadCount++; 253 preset.started = true; 254 preset.item.one('complete', function($img) { 255 preset.done = true; 256 return setTimeout(function() { 257 var done; 258 done = function() { 259 _this.trigger('itemload', $img, _this._doneCount); 260 _this._inLoadCount--; 261 _this._doneCount++; 262 preset.defer.resolve($img); 263 return _this._handleNext(); 264 }; 265 if (i === 0) { 266 return done(); 267 } else { 268 return _this._presets[i - 1].defer.always(function() { 269 return done(); 270 }); 271 } 272 }, _this._delay); 273 }); 274 return preset.item.load(); 275 }); 276 return this; 277 }; 278 279 ChainLoader.prototype.add = function(loaderItem) { 280 var preset, src; 281 if (($.type(loaderItem)) === 'string') { 282 src = loaderItem; 283 loaderItem = new ns.LoaderItem(src); 284 } 285 preset = { 286 item: loaderItem, 287 done: false, 288 started: false, 289 defer: $.Deferred() 290 }; 291 this._presets.push(preset); 292 return preset.defer; 293 }; 294 295 ChainLoader.prototype.load = function() { 296 this._handleNext(); 297 return this._allDoneDefer; 298 }; 299 300 ChainLoader.prototype.kill = function() { 301 $.each(this._presets, function(i, preset) { 302 return preset.item.unbind(); 303 }); 304 this.trigger('kill'); 305 this.unbind(); 306 return this; 307 }; 308 309 return ChainLoader; 310 311 })(ns.Event); 312 ns.LoaderFacade = (function() { 313 var methods, 314 _this = this; 315 316 methods = ['bind', 'trigger', 'load', 'one', 'unbind', 'add', 'kill']; 317 318 $.each(methods, function(i, method) { 319 return LoaderFacade.prototype[method] = function() { 320 var args; 321 args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; 322 return this.loader[method].apply(this.loader, args); 323 }; 324 }); 325 326 function LoaderFacade(options) { 327 var o, 328 _this = this; 329 if (!(this instanceof arguments.callee)) { 330 return new ns.LoaderFacade(options); 331 } 332 this.options = o = $.extend({ 333 srcs: [], 334 pipesize: 0, 335 delay: 100 336 }, options); 337 if (o.pipesize) { 338 this.loader = new ns.ChainLoader(o.pipesize, o.delay); 339 } else { 340 this.loader = new ns.BasicLoader; 341 } 342 $.each(o.srcs, function(i, src) { 343 return _this.loader.add(new ns.LoaderItem(src)); 344 }); 345 } 346 347 return LoaderFacade; 348 349 }).call(this); 350 (function() { 351 var $holder, $holderSetup, cache, naturalWHDetectable, tryCalc; 352 cache = {}; 353 $holder = null; 354 $holderSetup = function() { 355 return $.Deferred(function(defer) { 356 return $(function() {
357 $holder = $('<div id="calcNaturalWH-tempholder"></div>').css({ 358 position: 'absolute', 359 left: '-9999px', 360 top: '-9999px' 361 }); 362 $('body').append($holder); 363 return defer.resolve(); 364 }); 365 }).promise(); 366 }; 367 naturalWHDetectable = function(img) { 368 if ((img.naturalWidth === void 0) || (img.naturalWidth === 0) || (img.naturalHeight === void 0) || (img.naturalHeight === 0)) { 369 return false; 370 } else { 371 return true; 372 } 373 }; 374 tryCalc = function($img, src) { 375 var img; 376 $img = $img.clone(); 377 img = $img[0]; 378 return $.Deferred(function(defer) { 379 var $div, count, oneTry, res; 380 res = {}; 381 $img.css({ 382 width: 'auto', 383 height: 'auto' 384 }); 385 $div = $('<div></div>').append($img); 386 $holder.append($div); 387 count = 0; 388 oneTry = function() { 389 res.width = img.naturalWidth || $img.width(); 390 res.height = img.naturalHeight || $img.height(); 391 if (count > 10) { 392 $div.remove(); 393 return defer.reject(); 394 } else { 395 if (!res.width || !res.height) { 396 count++; 397 return (wait(100)).done(function() { 398 return oneTry(); 399 }); 400 } else { 401 cache[src]; 402 $div.remove(); 403 return defer.resolve(res); 404 } 405 } 406 }; 407 return oneTry(); 408 }).promise(); 409 }; 410 return ns.calcNaturalWH = ns.createCachedFunction(function(defer, src) { 411 return (ns.loadImg(src)).then(function($img) { 412 var img, wh; 413 img = $img[0]; 414 if (!(naturalWHDetectable(img))) { 415 return $holderSetup().done(function() { 416 return (tryCalc($img, src)).then(function(wh) { 417 return defer.resolve(wh, $img); 418 }, function() { 419 return defer.reject(); 420 }); 421 }); 422 } else { 423 wh = { 424 width: img.naturalWidth, 425 height: img.naturalHeight 426 }; 427 cache[src] = wh; 428 return defer.resolve(wh, $img); 429 } 430 }, function() { 431 return defer.reject(); 432 }); 433 }); 434 })(); 435 $.loadImg = ns.loadImg; 436 $.ImgLoader = ns.LoaderFacade; 437 return $.calcNaturalWH = ns.calcNaturalWH; 438 })(jQuery, this, this.document); 439 440}).call(this);
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.