Created
March 17, 2012 16:35
-
-
Save Sai/2061900 to your computer and use it in GitHub Desktop.
Web@2x
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| if (typeof (AC) === "undefined") { | |
| AC = {} | |
| } | |
| AC.ImageReplacer = Class.create({ | |
| _defaultOptions: { | |
| listenToSwapView: true, | |
| filenameRegex: /(.*)(\.[a-z]{3}($|#.*|\?.*))/i, | |
| filenameInsert: "_☃x", | |
| ignoreCheck: /(^http:\/\/movies\.apple\.com\/|\/105\/|\/global\/elements\/quicktime\/|_(([2-9]|[1-9][0-9]+)x|nohires)(\.[a-z]{3})($|#.*|\?.*))/i, | |
| attribute: "data-hires", | |
| recursive: true, | |
| preload: false, | |
| checkExists: true, | |
| queueSize: 8, | |
| debug: false | |
| }, | |
| _lowestPriority: 2, | |
| __replacedAttribute: "data-hires-status", | |
| initialize: function (c) { | |
| if (typeof c !== "object") { | |
| c = {} | |
| } | |
| this.options = Object.extend(Object.clone(this._defaultOptions), c); | |
| this.options.lowestPriority = this._lowestPriority; | |
| this.options.replacedAttribute = this.__replacedAttribute; | |
| if ((this.options.debug !== true) && ((typeof AC.Detector !== "undefined" && AC.Detector.isMobile()) || (AC.ImageReplacer.devicePixelRatio() <= 1))) { | |
| return | |
| } | |
| if (this.options.debug === true) { | |
| AC.ImageReplacer._devicePixelRatio = 2 | |
| } | |
| Object.synthesize(this); | |
| if (windowHasLoaded) { | |
| this.__setup() | |
| } else { | |
| var d = this.__setup.bind(this); | |
| Event.observe(window, "load", d) | |
| } | |
| }, | |
| log: function () { | |
| if (this.__canLog !== false && this.options.debug === true) { | |
| var d = $A(arguments); | |
| if (d.length < 2) { | |
| d = d[0] | |
| } | |
| try { | |
| console.log(d) | |
| } catch (c) { | |
| this.__canLog = false | |
| } | |
| } | |
| }, | |
| isReplaceable: function (f) { | |
| if ((f.getAttribute(this.options.attribute) === "false") || (f.up("[" + this.options.attribute + '="false"]') && this.options.recursive === true)) { | |
| return false | |
| } | |
| var e = (typeof f.responsiveImageObject === "undefined"); | |
| if (f.tagName.toLowerCase() === "img") { | |
| return e | |
| } else { | |
| if (f.hasClassName("imageLink") && f.tagName.toLowerCase() === "a") { | |
| return true | |
| } else { | |
| var d = AC.ImageReplacer.Image.removeCSSURLSyntax(f.getStyle("background-image")); | |
| return (((d.match(AC.ImageReplacer.normalImageTypeRegex) !== null) && e)) | |
| } | |
| } | |
| }, | |
| potentialElements: function (j, k) { | |
| if (typeof j === "undefined") { | |
| j = document.body | |
| } | |
| var h = $(j).getElementsBySelector("[" + this.options.attribute + "]"); | |
| var i; | |
| var n = function (a) { | |
| if (typeof k === "undefined") { | |
| return typeof j.up("[" + a + "]") !== "undefined" | |
| } else { | |
| return k.getAttribute(a) !== null || typeof k.up("[" + a + "]") !== "undefined" | |
| } | |
| }; | |
| if (this.options.recursive === true) { | |
| if (j !== document.body && n(this.options.attribute)) { | |
| h = h.concat(j) | |
| } | |
| i = []; | |
| var l = this.isReplaceable.bind(this); | |
| var m = function (a) { | |
| if (l(a)) { | |
| i.push(a) | |
| } | |
| i = i.concat(this.replaceableElementsWithinElement(a)) | |
| }.bind(this); | |
| $A(h).each(m) | |
| } else { | |
| i = h | |
| } | |
| return i | |
| }, | |
| prioritize: function (f) { | |
| var h = []; | |
| var g = function (a) { | |
| if (typeof a.responsiveImageObject !== "undefined") { | |
| return | |
| } | |
| var b = new AC.ImageReplacer.Image(a, this.options); | |
| if (b.hiResSrc() !== null && !b.isHiRes()) { | |
| if (typeof h[b.priority()] === "undefined") { | |
| h[b.priority()] = [] | |
| } | |
| h[b.priority()].push(b) | |
| } else { | |
| if (b.hiResSrc() && b.isHiRes()) { | |
| b.setStatus("already-hires") | |
| } else { | |
| b.setStatus("not-replaceable") | |
| } | |
| } | |
| }.bind(this); | |
| $A(f).each(g); | |
| var e; | |
| for (e = this._lowestPriority; | |
| e >= 0; e--) { | |
| if (typeof h[e] === "undefined") { | |
| h[e] = [] | |
| } | |
| } | |
| return h.flatten() | |
| }, | |
| replaceableElementsWithinElement: function (g) { | |
| g = $(g); | |
| var f = this; | |
| var e = g.descendants(); | |
| var h = this.isReplaceable.bind(this); | |
| return e.findAll(h) | |
| }, | |
| addToQueue: function (b) { | |
| if (typeof this.__queues === "undefined") { | |
| this.__queues = $A() | |
| } | |
| if (this.__queues.length === 0) { | |
| this.__queues.push($A()) | |
| } | |
| this.__queues[this.__queues.length - 1].push(b) | |
| }, | |
| replace: function () { | |
| if (typeof this.__queues === "undefined") { | |
| this.__queues = $A() | |
| } | |
| if (this.__queues.length > 0 && this.__queues[0].length > 0) { | |
| this.__queues.push($A()); | |
| var b = this.replace.bind(this); | |
| this.__replaceNextQueue(b) | |
| } else { | |
| this.log("There are no queues to replace") | |
| } | |
| }, | |
| __replaceNextQueue: function (g) { | |
| var f = this.__queues[0].reverse(); | |
| var e = this.log.bind(this); | |
| this.__queues.splice(0, 1); | |
| var h = function () { | |
| e("Found " + f.length + " elements to replace."); | |
| var a = function () { | |
| var b = f.pop(); | |
| if (!b) { | |
| e("No more images to start replacing."); | |
| if (typeof g === "function") { | |
| g() | |
| } | |
| g = Prototype.emptyFunction; | |
| return | |
| } | |
| b.replace(function (c) { | |
| e("Replaced image.", b.hiResSrc(), "status: " + b.status()); | |
| a() | |
| }) | |
| }; | |
| $R(0, this.options.queueSize - 1).each(a) | |
| }.bind(this); | |
| window.setTimeout(h, 10) | |
| }, | |
| __respondToSwapView: function (h) { | |
| var e = h.event_data.data.incomingView.content; | |
| var f = h.event_data.data.sender.view.view(); | |
| var g = this.addToQueue.bind(this); | |
| this.prioritize(this.potentialElements(e, f)).each(g); | |
| this.replace() | |
| }, | |
| __setup: function () { | |
| if (this.options.listenToSwapView === true && "Listener" in Event && typeof AC.ViewMaster !== "undefined") { | |
| this.respondToSwapView = this.__respondToSwapView.bindAsEventListener(this); | |
| Event.Listener.listenForEvent(AC.ViewMaster, "ViewMasterDidShowNotification", false, this.respondToSwapView) | |
| } | |
| var b = this.addToQueue.bind(this); | |
| this.prioritize(this.potentialElements()).each(b); | |
| this.replace() | |
| } | |
| }); | |
| AC.ImageReplacer.normalImageTypeRegex = /(\.jpg($|#.*|\?.*)|\.png($|#.*|\?.*)|\.gif($|#.*|\?.*))/; | |
| AC.ImageReplacer.devicePixelRatio = function () { | |
| if (typeof AC.ImageReplacer._devicePixelRatio !== "undefined") { | |
| return AC.ImageReplacer._devicePixelRatio | |
| } | |
| if ("devicePixelRatio" in window && window.devicePixelRatio > 1) { | |
| return AC.ImageReplacer._devicePixelRatio = 2 | |
| } else { | |
| return AC.ImageReplacer._devicePixelRatio = 1 | |
| } | |
| }; | |
| AC.ImageReplacer.Image = Class.create(Object.clone(AC.Synthesize), { | |
| initialize: function (c, d) { | |
| if (Object.isElement(c)) { | |
| this._el = c; | |
| this._tagName = this._el.tagName.toLowerCase(); | |
| this.options = Object.extend(Object.clone(d), AC.ImageReplacer.Image.convertParametersToOptions(this.src())); | |
| this.setStatus("considered"); | |
| this.synthesize() | |
| } | |
| }, | |
| __synthesizeSetter: Prototype.emptyFunction, | |
| preload: function (c) { | |
| if (this._isPreloaded) { | |
| return true | |
| } | |
| this.setStatus("loading"); | |
| var d = new Element("img"); | |
| d.observe("load", function () { | |
| this._isPreloaded = true; | |
| this.width = d.width; | |
| this.height = d.height; | |
| this.setStatus("replaced"); | |
| if (typeof c === "function") { | |
| c() | |
| } | |
| }.bind(this)); | |
| d.observe("error", function () { | |
| this.setStatus("404"); | |
| this._exists = false; | |
| if (typeof c === "function") { | |
| c() | |
| } | |
| }.bind(this)); | |
| d.src = this.hiResSrc() | |
| }, | |
| replace: function (c) { | |
| var d = this.replace.bind(this, c); | |
| if (this._exists === false) { | |
| this.setStatus("404"); | |
| if (typeof c === "function") { | |
| c(false) | |
| } | |
| return | |
| } | |
| if (this.options.checkExists === true && typeof this._exists === "undefined") { | |
| return this.requestHeaders(d) | |
| } | |
| if (this.isImageLink()) { | |
| this._el.setAttribute("href", this.hiResSrc()); | |
| this.setStatus("replaced"); | |
| if (typeof c === "function") { | |
| c(true) | |
| } | |
| } else { | |
| if ((this.options.preload === true || this._tagName !== "img") && this._isPreloaded !== true) { | |
| return this.preload(d) | |
| } | |
| if (this._tagName === "img") { | |
| this._el.setAttribute("src", this.hiResSrc()); | |
| if ((this.options.preload !== true)) { | |
| this.setStatus("loading"); | |
| this._el.observe("load", function (a) { | |
| this.setStatus("replaced"); | |
| if (typeof c === "function") { | |
| c(true) | |
| } | |
| }.bindAsEventListener(this)); | |
| this._el.observe("error", function (a) { | |
| this.setStatus("404"); | |
| this._el.setAttribute("src", this.src()); | |
| if (typeof c === "function") { | |
| c(false) | |
| } | |
| }.bindAsEventListener(this)) | |
| } | |
| } else { | |
| this._el.setStyle("background-image:url(" + this.hiResSrc() + ");"); | |
| this._el.setStyle("background-size:" + (this.width / AC.ImageReplacer.devicePixelRatio()) + "px " + (this.height / AC.ImageReplacer.devicePixelRatio()) + "px;"); | |
| if (typeof c === "function") { | |
| c(true) | |
| } | |
| } | |
| } | |
| this._el.responsiveImageObject = this; | |
| this.synthesize() | |
| }, | |
| requestHeaders: function (f) { | |
| var e = this; | |
| if (typeof e._headers === "undefined") { | |
| var d = new XMLHttpRequest(); | |
| var e = this; | |
| src = this.hiResSrc().replace(/^http:\/\/.*\.apple\.com\//, "/"); | |
| d.open("HEAD", src, true); | |
| d.onreadystatechange = function () { | |
| if (d.readyState == 4) { | |
| if (d.status === 200) { | |
| e._exists = true; | |
| var a = d.getAllResponseHeaders(); | |
| e._headers = { | |
| src: src | |
| }; | |
| var c, b; | |
| a = a.split("\r"); | |
| for (c = 0; | |
| c < a.length; c++) { | |
| b = a[c].split(": "); | |
| if (b.length > 1) { | |
| e._headers[b[0].replace("\n", "")] = b[1] | |
| } | |
| } | |
| } else { | |
| e._exists = false; | |
| e._headers = null | |
| } | |
| if (typeof f === "function") { | |
| f(e._headers, e) | |
| } | |
| } | |
| }; | |
| d.send(null) | |
| } else { | |
| f(e._headers, e) | |
| } | |
| }, | |
| requestFileSize: function (f) { | |
| var d = this; | |
| if (typeof d._fileSize === "undefined") { | |
| var e = function (a) { | |
| d._fileSize = parseFloat(a["Content-Length"]) / 1000; | |
| if (typeof f === "function") { | |
| f(d._fileSize, d) | |
| } | |
| }; | |
| this.requestHeaders(e) | |
| } else { | |
| f(d._fileSize, d) | |
| } | |
| }, | |
| src: function () { | |
| if (typeof this._src !== "undefined") { | |
| return this._src | |
| } | |
| if (this.isImageLink()) { | |
| this._src = this._el.getAttribute("href") | |
| } else { | |
| if (this._tagName === "img") { | |
| this._src = this._el.getAttribute("src") | |
| } else { | |
| this._src = AC.ImageReplacer.Image.removeCSSURLSyntax(this._el.getStyle("background-image")); | |
| if (this._src === "none") { | |
| return this._src = "" | |
| } | |
| } | |
| } | |
| return this._src | |
| }, | |
| hiResSrc: function () { | |
| if (typeof this._hiResSrc !== "undefined") { | |
| return this._hiResSrc | |
| } | |
| var b; | |
| if (typeof this.options.hiresFormat === "string") { | |
| b = this.src().match(/^(.*)((\.[a-z]{3})($|#.*|\?.*))/i); | |
| if (b !== null && b.length > 1) { | |
| return this._hiResSrc = b[1] + "." + this.options.hiresFormat + (b[4] || "") | |
| } | |
| } | |
| b = this.src().match(this.options.filenameRegex); | |
| if (b === null) { | |
| return this._hiResSrc = null | |
| } else { | |
| return this._hiResSrc = b[1] + this.options.filenameInsert.replace("☃", AC.ImageReplacer.devicePixelRatio()) + b[2] | |
| } | |
| }, | |
| isHiRes: function () { | |
| if (this._isHiRes === true) { | |
| return this._isHiRes | |
| } | |
| if (this.status() === "replaced") { | |
| return this._isHiRes = true | |
| } | |
| var b = this.src(); | |
| if (b.match(AC.ImageReplacer.normalImageTypeRegex) === null) { | |
| return this._isHiRes = true | |
| } | |
| if (b.match(this.options.ignoreCheck) !== null) { | |
| return this._isHiRes = true | |
| } | |
| this._isHiRes = false | |
| }, | |
| isImageLink: function () { | |
| if (typeof this._isImageLink !== "undefined") { | |
| return this._isImageLink | |
| } | |
| return this._isImageLink = (this._el.hasClassName("imageLink") && this._tagName === "a") | |
| }, | |
| priority: function () { | |
| if (typeof this._priority !== "undefined") { | |
| return this._priority | |
| } | |
| if (this.options.recursive && this._el.hasAttribute(this.options.attribute) === false) { | |
| var b = this._el.up("[" + this.options.attribute + "]"); | |
| if ( !! b) { | |
| this._priority = parseInt(b.getAttribute(this.options.attribute)) | |
| } else { | |
| this._priority = this.options.lowestPriority | |
| } | |
| } else { | |
| this._priority = parseInt(this._el.getAttribute(this.options.attribute)) | |
| } | |
| if (isNaN(this._priority) || this._priority > this.options.lowestPriority) { | |
| this._priority = this.options.lowestPriority | |
| } else { | |
| if (this._priority < 0) { | |
| this._priority = 0 | |
| } | |
| } | |
| return this._priority | |
| }, | |
| setStatus: function (b) { | |
| if (typeof b === "string") { | |
| this._status = b; | |
| this._el.setAttribute(this.options.replacedAttribute, b) | |
| } | |
| }, | |
| status: function () { | |
| return this._el.getAttribute(this.options.replacedAttribute) | |
| } | |
| }); | |
| AC.ImageReplacer.Image.removeCSSURLSyntax = function (b) { | |
| if (typeof b === "string" && typeof b.replace === "function") { | |
| return b.replace(/^url\(/, "").replace(/\)$/, "") | |
| } | |
| return "" | |
| }; | |
| AC.ImageReplacer.Image.convertParametersToOptions = function (d) { | |
| if (typeof d === "string" && typeof d.toQueryParams === "function") { | |
| var e = d.toQueryParams(), | |
| f; | |
| for (f in e) { | |
| if (e.hasOwnProperty(f)) { | |
| e[f.camelize()] = e[f] | |
| } | |
| } | |
| return e | |
| } | |
| return {} | |
| }; | |
| AC.ImageReplacer.autoInstance = new AC.ImageReplacer(); | |
| var windowHasLoaded = false; | |
| Event.observe(window, "load", function () { | |
| windowHasLoaded = true | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
So this is based on prototype.js?