-
-
Save saighost/2067091 to your computer and use it in GitHub Desktop.
Web@2x
This file contains 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