Created
April 4, 2011 14:43
-
-
Save roryokane/901751 to your computer and use it in GitHub Desktop.
http://slbkbs.org/jsgif/ bookmarklet automatically beautified by http://jsbeautifier.org/
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
javascript: (function () { | |
var n = null, | |
C = false; | |
function h(m) { | |
d(m, "jsgif_overlaid"); | |
m.removeEventListener("click", i, C) | |
} | |
function i(m) { | |
var o = this; | |
c.forEach(h); | |
setTimeout(function () { | |
j(o) | |
}, 0); | |
m.preventDefault() | |
} | |
function d(m, p) { | |
var o = m.className.split(/\s/).filter(function (r) { | |
return r !== p | |
}); | |
m.className = g(o, " ") | |
} | |
function g(m, o) { | |
if (o === undefined) { | |
o = "" | |
} | |
return m.reduce(function (p, r) { | |
return p + o + r | |
}, "") | |
} | |
function j(ai) { | |
function ag(p, m) { | |
return function (q) { | |
p(q); | |
T(m) | |
} | |
} | |
function ac() {} | |
function T(m) { | |
ab("Decoding (frame " + (M.length + 1) + ")...", Z.i, Z.data.length, m) | |
} | |
function I() { | |
G = C; | |
o.insertBefore(ai, L); | |
o.removeChild(L) | |
} | |
function F() { | |
N && M.push({ | |
data: N.getImageData(0, 0, ae.width, ae.height), | |
f: Y | |
}) | |
} | |
function V(m) { | |
af = m; | |
ae = { | |
width: ai.width, | |
height: ai.height | |
}; | |
M = []; | |
O.fillStyle = "black"; | |
O.fillRect(0, 0, ae.width, ae.height); | |
O.strokeStyle = "red"; | |
O.lineWidth = 3; | |
O.moveTo(0, 0); | |
O.lineTo(ae.width, ae.height); | |
O.moveTo(0, ae.height); | |
O.lineTo(ae.width, 0); | |
O.stroke(); | |
setTimeout(x, 0) | |
} | |
function ah(m) { | |
m.lengthComputable && ab("Loading...", m.loaded, m.total, true) | |
} | |
function ab(u, p, r, t) { | |
K.style.visibility = p === r ? "" : "visible"; | |
if (t) { | |
t = Math.min(J.height >> 3, J.height); | |
var q = J.height - t >> 1, | |
m = p / r * J.width; | |
O.fillStyle = "rgba(255,160,122,0.5)"; | |
O.fillRect(m, q, J.width - m, t); | |
O.fillStyle = "rgba(0,128,128,0.5)"; | |
O.fillRect(0, q, p / r * J.width, t) | |
} | |
K.innerHTML = u + " " + Math.floor(p / r * 100) + "%" | |
} | |
function ad() { | |
try { | |
b(Z, aj) | |
} catch (m) { | |
V("parse") | |
} | |
} | |
var Z, ae, af = n, | |
U = n, | |
Y = n, | |
w = n, | |
s = n, | |
N = n, | |
G = true, | |
P = true, | |
M = [], | |
x = function () { | |
function y() { | |
function S() { | |
G = !G; | |
aa(); | |
W.focus(); | |
u() | |
} | |
function aa() { | |
if (G) { | |
W.innerHTML = "❙❙"; | |
W.title = "Pause"; | |
R.style.visibility = "hidden"; | |
Q.style.visibility = "hidden" | |
} else { | |
W.innerHTML = P ? "▶" : "◀"; | |
W.title = "Play"; | |
R.style.visibility = ""; | |
Q.style.visibility = "" | |
} | |
K.style.visibility = r ? "visible" : ""; | |
z.style.display = m ? "" : "none"; | |
E.innerHTML = "i"; | |
E.title = "Show info/more tools"; | |
D.innerHTML = P ? "←" : "→"; | |
D.title = P ? "Reverse" : "Un-reverse"; | |
R.innerHTML = "◀❙"; | |
R.title = "Previous frame"; | |
Q.innerHTML = "❙▶"; | |
Q.title = "Next frame"; | |
B.innerHTML = r ? "○" : "⊙"; | |
B.title = r ? "Unpin" : "Pin"; | |
A.innerHTML = "✖"; | |
A.title = "Close jsgif and go back to original image"; | |
v.disabled = G; | |
q.disabled = G; | |
K.innerHTML = ""; | |
H.innerHTML = ""; | |
z.innerHTML = ""; | |
if (M.length < 2) { | |
if (af == "xhr") { | |
K.appendChild(document.createTextNode("Load failed; cross-domain? ")); | |
var al = ak("button", "popup"); | |
al.addEventListener("click", function () { | |
window.open(ai.src) | |
}); | |
al.innerHTML = "↗"; | |
al.title = "Click to open GIF in new window; try running jsgif there instead"; | |
K.appendChild(al) | |
} else { | |
af == "parse" && K.appendChild(document.createTextNode("Parse failed ")) | |
} | |
K.appendChild(A) | |
} else { | |
al = function (an, ao) { | |
an.innerHTML = ""; | |
ao.forEach(function (ap) { | |
an.appendChild(ap) | |
}) | |
}; | |
var am = P ? [E, D, R, W, Q, B, A] : [E, D, Q, W, R, B, A]; | |
al(K, [H, z]); | |
al(H, am); | |
al(z, [document.createTextNode(" frame: "), v, document.createTextNode(" / "), document.createTextNode(M.length), document.createTextNode(" (delay: "), q, document.createTextNode(")")]) | |
} | |
} | |
function ak(am, an, al) { | |
am = document.createElement(am); | |
if (an) { | |
am.className = "jsgif_" + an | |
} | |
for (var ao in al) { | |
am[ao] = al[ao] | |
} | |
return am | |
} | |
var H = ak("div", "simple_tools"), | |
D = ak("button", "rev"), | |
E = ak("button", "show_info"), | |
R = ak("button", "prev"), | |
W = ak("button", "play_pause"), | |
Q = ak("button", "next"), | |
B = ak("button", "pin"), | |
A = ak("button", "close"), | |
z = ak("div", "info_tools"); | |
v = ak("input", "cur_frame", { | |
type: "text" | |
}); | |
q = ak("input", "delay_info", { | |
type: "text" | |
}); | |
E.addEventListener("click", function () { | |
m = !m; | |
aa(); | |
E.focus() | |
}, C); | |
D.addEventListener("click", function () { | |
P = !P; | |
aa(); | |
D.focus() | |
}, C); | |
v.addEventListener("change", function () { | |
var al = +v.value; | |
if (isNaN(al) || al < 1 || al > M.length) { | |
v.value = t + 1 | |
} else { | |
t = al - 1; | |
O.putImageData(M[t].data, 0, 0) | |
} | |
}, C); | |
R.addEventListener("click", function () { | |
p(-1) | |
}, C); | |
W.addEventListener("click", S, C); | |
Q.addEventListener("click", function () { | |
p(1) | |
}, C); | |
B.addEventListener("click", function () { | |
r = !r; | |
aa(); | |
B.focus() | |
}, C); | |
A.addEventListener("click", I, C); | |
q.addEventListener("change", function () { | |
var al = +q.value; | |
if (!isNaN(al)) { | |
M[t].f = al | |
} | |
}, C); | |
J.addEventListener("click", S, C); | |
L.addEventListener("click", function (al) { | |
al.preventDefault() | |
}, C); | |
aa() | |
} | |
function p(z) { | |
t = (t + z + M.length) % M.length; | |
v.value = t + 1; | |
q.value = M[t].f; | |
O.putImageData(M[t].data, 0, 0) | |
} | |
var t = -1, | |
v, q, m = C, | |
r = C, | |
u = function () { | |
function z() { | |
if (A = G) { | |
p(P ? 1 : -1); | |
var B = M[t].f * 10; | |
B || (B = 100); | |
setTimeout(z, B) | |
} | |
} | |
var A = C; | |
return function () { | |
A || setTimeout(z, 0) | |
} | |
}(); | |
return function () { | |
setTimeout(y, 0); | |
if (!af) { | |
J.width = ae.width; | |
J.height = ae.height; | |
u() | |
} | |
} | |
}(), | |
aj = { | |
p: ag(function (m) { | |
ae = m; | |
J.width = ae.width; | |
J.height = ae.height; | |
L.style.width = ae.width + "px"; | |
K.style.minWidth = ae.width + "px"; | |
X.width = ae.width; | |
X.height = ae.height | |
}), | |
o: ag(function (m) { | |
F(); | |
Y = U = n; | |
s = w; | |
N = w = n; | |
U = m.L ? m.M : n; | |
Y = m.u; | |
w = m.v | |
}), | |
m: ag(ac), | |
c: { | |
l: ag(ac) | |
}, | |
q: ag(function (q) { | |
N || (N = X.getContext("2d")); | |
var m = q.r ? q.C : ae.w, | |
p = N.getImageData(q.g, q.k, q.width, q.height); | |
q.h.forEach(function (t, r) { | |
if (U !== t) { | |
p.data[r * 4 + 0] = m[t][0]; | |
p.data[r * 4 + 1] = m[t][1]; | |
p.data[r * 4 + 2] = m[t][2]; | |
p.data[r * 4 + 3] = 255 | |
} else { | |
if (s === 2 || s === 3) { | |
p.data[r * 4 + 3] = 0 | |
} | |
} | |
}); | |
N.putImageData(p, q.g, q.k); | |
O.putImageData(p, q.g, q.k) | |
}, true), | |
n: function () { | |
F(); | |
T(C); | |
K.innerHTML = "Playing..."; | |
x() | |
} | |
}, | |
o = ai.parentNode, | |
L = document.createElement("div"), | |
J = document.createElement("canvas"), | |
O = J.getContext("2d"), | |
K = document.createElement("div"), | |
X = document.createElement("canvas"); | |
J.width = ai.width; | |
J.height = ai.height; | |
K.style.minWidth = ai.width + "px"; | |
L.className = "jsgif"; | |
K.className = "jsgif_toolbar"; | |
L.appendChild(J); | |
L.appendChild(K); | |
o.insertBefore(L, ai); | |
o.removeChild(ai); | |
K.innerHTML = "Loading..."; | |
(function () { | |
var m = new XMLHttpRequest; | |
m.overrideMimeType("text/plain; charset=x-user-defined"); | |
m.onload = function () { | |
Z = new f(m.responseText); | |
setTimeout(ad, 0) | |
}; | |
m.onprogress = ah; | |
m.onerror = function () { | |
V("xhr") | |
}; | |
m.open("GET", ai.src, true); | |
m.send() | |
})() | |
} | |
function b(o, u) { | |
function r() { | |
var q = {}; | |
q.s = o.a(); | |
switch (String.fromCharCode(q.s)) { | |
case "!": | |
q.type = "ext"; | |
p(q); | |
break; | |
case ",": | |
q.type = "img"; | |
s(q); | |
break; | |
case ";": | |
q.type = "eof"; | |
u.n && u.n(q); | |
break; | |
default: | |
throw Error("Unknown block: 0x" + q.s.toString(16)) | |
} | |
q.type !== "eof" && setTimeout(r, 0) | |
} | |
function s(q) { | |
function v(F, I) { | |
function J(y, B) { | |
var D = F.slice(B * I, (B + 1) * I); | |
A.splice.apply(A, [y * I, I].concat(D)) | |
} | |
for (var A = Array(F.length), E = F.length / I, H = [0, 4, 2, 1], G = [8, 8, 4, 2], x = 0, K = 0; K < 4; K++) { | |
for (var z = H[K]; z < E; z += G[K]) { | |
J(z, x); | |
x++ | |
} | |
} | |
return A | |
} | |
q.g = o.b(); | |
q.k = o.b(); | |
q.width = o.b(); | |
q.height = o.b(); | |
var w = l(o.a()); | |
q.r = w.shift(); | |
q.B = w.shift(); | |
q.J = w.shift(); | |
q.H = w.splice(0, 2); | |
q.D = e(w.splice(0, 3)); | |
if (q.r) { | |
q.C = m(1 << q.D + 1) | |
} | |
q.F = o.a(); | |
w = t(); | |
q.h = a(q.F, w); | |
if (q.B) { | |
q.h = v(q.h, q.width) | |
} | |
u.q && u.q(q) | |
} | |
function p(q) { | |
function w(A) { | |
function z(B) { | |
o.a(); | |
B.t = o.a(); | |
B.R = o.b(); | |
B.K = o.a(); | |
u.c && u.c.l && u.c.l(B) | |
} | |
o.a(); | |
A.identifier = o.d(8); | |
A.O = o.d(3); | |
switch (A.identifier) { | |
case "NETSCAPE": | |
z(A); | |
break; | |
default: | |
(function (B) { | |
B.N = t(); | |
u.c && u.c[B.identifier] && u.c[B.identifier](B) | |
})(A) | |
} | |
} | |
function x(z) { | |
o.a(); | |
z.V = o.j(12); | |
z.U = t(); | |
u.G && u.G(z) | |
} | |
function v(z) { | |
z.Q = t(); | |
u.m && u.m(z) | |
} | |
function y(A) { | |
o.a(); | |
var z = l(o.a()); | |
A.H = z.splice(0, 3); | |
A.v = e(z.splice(0, 3)); | |
A.W = z.shift(); | |
A.L = z.shift(); | |
A.u = o.b(); | |
A.M = o.a(); | |
A.K = o.a(); | |
u.o && u.o(A) | |
} | |
q.label = o.a(); | |
switch (q.label) { | |
case 249: | |
q.e = "gce"; | |
y(q); | |
break; | |
case 254: | |
q.e = "com"; | |
v(q); | |
break; | |
case 1: | |
q.e = "pte"; | |
x(q); | |
break; | |
case 255: | |
q.e = "app"; | |
w(q); | |
break; | |
default: | |
q.e = "unknown"; | |
(function (z) { | |
z.data = t(); | |
u.t && u.t(z) | |
})(q) | |
} | |
} | |
function t() { | |
var q, v; | |
v = ""; | |
do { | |
q = o.a(); | |
v += o.d(q) | |
} while (q !== 0); | |
return v | |
} | |
function m(q) { | |
for (var v = [], w = 0; w < q; w++) { | |
v.push(o.j(3)) | |
} | |
return v | |
} | |
u || (u = {}); | |
(function () { | |
var q = {}; | |
q.I = o.d(3); | |
q.X = o.d(3); | |
if (q.I !== "GIF") { | |
throw Error("Not a GIF file.") | |
} | |
q.width = o.b(); | |
q.height = o.b(); | |
var v = l(o.a()); | |
q.z = v.shift(); | |
q.P = e(v.splice(0, 3)); | |
q.J = v.shift(); | |
q.A = e(v.splice(0, 3)); | |
q.bgColor = o.a(); | |
q.T = o.a(); | |
if (q.z) { | |
q.w = m(1 << q.A + 1) | |
} | |
u.p && u.p(q) | |
})(); | |
setTimeout(r, 0) | |
} | |
function a(y, w) { | |
function s() { | |
t = []; | |
r = y + 1; | |
for (var q = 0; q < o; q++) { | |
t[q] = [q] | |
} | |
t[o] = []; | |
t[x] = n | |
} | |
function m(A) { | |
for (var z = 0, q = 0; q < A; q++) { | |
if (w.charCodeAt(B >> 3) & 1 << (B & 7)) { | |
z |= 1 << q | |
} | |
B++ | |
} | |
return z | |
} | |
for (var B = 0, v = [], o = 1 << y, x = o + 1, r = y + 1, t = [], p, u;;) { | |
u = p; | |
p = m(r); | |
if (p === o) { | |
s() | |
} else { | |
if (p === x) { | |
break | |
} | |
if (p < t.length) { | |
u !== o && t.push(t[u].concat(t[p][0])) | |
} else { | |
if (p !== t.length) { | |
throw Error("Invalid LZW code.") | |
} | |
t.push(t[u].concat(t[u][0])) | |
} | |
v.push.apply(v, t[p]); | |
t.length === 1 << r && r < 12 && r++ | |
} | |
} | |
return v | |
} | |
function f(m) { | |
this.data = m; | |
this.S = this.data.length; | |
this.i = 0; | |
this.a = function () { | |
if (this.i >= this.data.length) { | |
throw Error("Attempted to read past end of stream.") | |
} | |
return m.charCodeAt(this.i++) & 255 | |
}; | |
this.j = function (r) { | |
for (var o = [], p = 0; p < r; p++) { | |
o.push(this.a()) | |
} | |
return o | |
}; | |
this.d = function (r) { | |
for (var o = "", p = 0; p < r; p++) { | |
o += String.fromCharCode(this.a()) | |
} | |
return o | |
}; | |
this.b = function () { | |
var o = this.j(2); | |
return (o[1] << 8) + o[0] | |
} | |
} | |
function l(m) { | |
for (var p = [], o = 7; o >= 0; o--) { | |
p.push( !! (m & 1 << o)) | |
} | |
return p | |
} | |
function e(m) { | |
return m.reduce(function (p, o) { | |
return p * 2 + o | |
}, 0) | |
} | |
var k = function (m) { | |
for (var p = [], o = 0; o < m.length; o++) { | |
p.push(m[o]) | |
} | |
return p | |
}(document.getElementsByTagName("img")), | |
c = k.filter(function (m) { | |
return m.src.slice(-4).toLowerCase() === ".gif" | |
}); | |
if (c.length === 0) { | |
c = k | |
}(function (m) { | |
var o = document.createElement("style"); | |
o.type = "text/css"; | |
o.textContent = m; | |
document.body.appendChild(o) | |
})(".jsgif{display:inline;position:relative;padding-bottom:3px;}.jsgif_toolbar{visibility:hidden;font-family:sans-serif;background-color:#555;border-radius:8px;-moz-border-radius:8px;-webkit-border-radius:8px;overflow:visible;white-space:nowrap;padding:3px;position:absolute;left:0;text-align:center;z-index:50;}.jsgif_toolbar button{width:3em;color:black;text-align:center;border-radius:8px;-moz-border-radius:8px;-webkit-border-radius:8px;margin:1px;cursor:pointer;background-color:#ddd;}.jsgif_cur_frame{width:2em;color:black;}.jsgif_delay_info{width:2em;color:black;}.jsgif_toolbar button:hover{color:red;}.jsgif:hover .jsgif_toolbar{visibility:visible;}.jsgif{text-decoration:none;color:black;}.jsgif_overlaid{border:5px solid red;}.jsgif_overlaid:hover{border:5px solid blue;}"); | |
c.forEach(function (m) { | |
if (m.className.split(/\s/).indexOf("jsgif_overlaid") === -1) { | |
m.className += " jsgif_overlaid"; | |
m.addEventListener("click", i, C) | |
} | |
}) | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment