Created
January 19, 2017 17:46
-
-
Save blasten/efb299fc69ccdfa97c7cf398a955c6e1 to your computer and use it in GitHub Desktop.
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
! function(t, i) { | |
"object" == typeof exports && "undefined" != typeof module ? module.exports = i() : "function" == typeof define && define.amd ? define(i) : t.Layout = i() | |
}(this, function() { | |
"use strict"; | |
function t(t) { | |
return new Promise(function(i, n) { | |
function s(h, o) { | |
try { | |
var r = t[o ? "throw" : "next"](h) | |
} catch (t) { | |
return void n(t) | |
} | |
r.done ? i(r.value) : Promise.resolve(r.value).then(s, e) | |
} | |
function e(t) { | |
s(t, 1) | |
} | |
s() | |
}) | |
} | |
function i() { | |
return new Promise(function(t) { | |
window.requestAnimationFrame(t) | |
}) | |
} | |
function n(t, i, n) { | |
return Math.max(i, Math.min(n, t)) | |
} | |
function s(t, i, n) { | |
return ~~(t + (n - i) * (t / i)) | |
} | |
function e(t, i, n, s, e, h) { | |
return e == x ? t <= n - h : i >= n + s + h | |
} | |
function h(t, i, n, s, e) { | |
if (n == x && i + 1 < s.length) { | |
let n = e.get(s[i + 1]); | |
return n.y - t.h | |
} | |
if (n == E && i > 0) { | |
let t = e.get(s[i - 1]); | |
return t.y + t.h | |
} | |
return t.y | |
} | |
function o(t, i) { | |
if (i.hasOwnProperty("props")) { | |
let n = i.props; | |
delete i.props, i.props = t, i.props = n | |
} else i.props = t | |
} | |
function r(t) { | |
const i = document; | |
return t !== i.body && t !== i.documentElement && t instanceof HTMLElement ? t : window | |
} | |
function u(t) { | |
return t === window ? window.pageYOffset : t.scrollTop | |
} | |
function c(t, i) { | |
t === window ? window.scrollTo(0, i) : t.scrollTop = i | |
} | |
function f(t) { | |
return t.getBoundingClientRect().height | |
} | |
function l(t, i) { | |
if (0 == t) return []; | |
let n = Array(t); | |
n[0] = [0, i(0)]; | |
for (let s = 1; s < t; s++) { | |
let t = n[s - 1][1] + 1, | |
e = t + i(s); | |
n[s] = [t, e] | |
} | |
return n | |
} | |
function d(t, i) { | |
let n = 0, | |
s = i.length - 1; | |
for (; n <= s;) { | |
let e = n + s >> 1; | |
if (t < i[e][0]) s = e - 1; | |
else { | |
if (!(t > i[e][1])) return e; | |
n = e + 1 | |
} | |
} | |
return null | |
} | |
function a(t, i, n) { | |
return Object.keys(t).reduce((s, e) => { | |
let h = t[e]; | |
return h[i] <= n && (!s || n - h[i] < n - s[i]) ? h : s | |
}, null) | |
} | |
function p(t, i, n) { | |
t[i] || (t[i] = []), t[i].push(n) | |
} | |
function g(t, i) { | |
return t[i] ? t[i].pop() : null | |
} | |
function y() { | |
return document.createElement("div") | |
} | |
const m = t => {}, | |
b = {}, | |
w = -1, | |
x = 1, | |
E = 2, | |
F = 0; | |
class v { | |
constructor(t, i, n, s) { | |
this.a = t, this.b = n, this.c = s, this.d = i, this.e = 0, this.f = 0, this.g = [], this.i = {} | |
} | |
recycle(i) { | |
return t(function*() { | |
if (i) { | |
let t = Array(i.length); | |
i.forEach((i, n) => { | |
let s = i.dataset.id; | |
t[n] = this.i[s] ? null : s, this.j(i) | |
}), i === this.g && (this.g = []), yield this.k(E, Math.max(1, t.length), ++this.e), t.forEach(t => this.release(t)) | |
} else yield this.k(x, 1, ++this.e), yield this.k(E, 1, ++this.e) | |
}.call(this)) | |
} | |
k(i, n, s) { | |
return t(function*() { | |
if (this.e == s) | |
for (; !this.l(this.startMeta, this.endMeta, i);) { | |
let t = performance.now(); | |
if (0 === (n = this.m(i, n))) break; | |
this.n = (performance.now() - t) / n, n = 1 | |
} | |
}.call(this)) | |
} | |
p(t) { | |
let i = t.dataset; | |
i.poolId || (i.poolId = F), this.i[i.id] || (this.q(t), p(this.d, i.poolId, t)) | |
} | |
m(t, i) { | |
let n, s, e = 0, | |
h = this.g, | |
o = this.c, | |
r = this.r, | |
u = this.s, | |
c = this.t; | |
for (; t == E && (n = h[0]) && (s = this.c.get(n)) && r(n, s);) this.p(n), h.shift(); | |
for (; t == x && (n = h[h.length - 1]) && (s = this.c.get(n)) && r(n, s);) this.p(n), h.pop(); | |
for (; e < i && (n = this.u(t));) t == x ? h.unshift(n) : h.push(n), this.v(n), e++; | |
for (let f = e - 1; t == x && f >= 0; f--) u(h[f], o.get(h[f]), h, o, f, t); | |
for (let f = h.length - e; t == E && f < h.length; f++) u(h[f], o.get(h[f]), h, o, f, t); | |
for (let f = e - 1; t == x && f >= 0; f--) c(h[f], o.get(h[f])); | |
for (let f = h.length - e; t == E && f < h.length; f++) c(h[f], o.get(h[f])); | |
return e | |
} | |
v(t) { | |
let i = this.a; | |
void 0 !== t.parentNode && t.parentNode !== i && i.appendChild(t) | |
} | |
u(t) { | |
let i, n = this.w(); | |
if (0 == n) return null; | |
if (0 == this.g.length) i = w; | |
else if (i = t == x ? this.startMeta.idx - 1 : this.endMeta.idx + 1, i < 0 || i >= n) return; | |
return this.x(i) | |
} | |
x(t) { | |
let i, n, s; | |
this.w(); | |
return i = this.z(this.b[t] || { | |
idx: t, | |
id: t | |
}), s = this.A(i.idx, i), n = this.i[i.id] || g(this.d, s) || this.B(), this.b[i.idx] = i, this.c.set(n, i), n.dataset.id = i.id, n.dataset.poolId = s, n.style.pointerEvents = "", this.C(n, i.idx, i), n | |
} | |
has(t) { | |
return t >= this.startMeta.idx && t <= this.endMeta.idx | |
} | |
j(t) { | |
this.i[t.dataset.id] = t | |
} | |
keep(t) { | |
let i, n = this.b[t]; | |
return n && (i = this.i[n.id]) ? (this.t(i, n), n.id) : (i = this.has(t) ? this.g[t - this.startMeta.idx] : this.x(t), this.j(i, !1), this.v(i, E), this.t(i, this.c.get(i)), i.dataset.id) | |
} | |
release(t) { | |
let i = this.i[t]; | |
if (i) { | |
let n = this.c.get(i); | |
delete this.i[t], this.g[n.idx - this.startMeta.idx] === i ? this.t(i, n) : this.p(i) | |
} | |
} | |
q(t) { | |
let i = t.style; | |
i.position = "absolute", i.pointerEvents = "none", i.top = "-100000000px", i.bottom = "" | |
} | |
get startMeta() { | |
return this.c.get(this.g[0]) || b | |
} | |
get endMeta() { | |
return this.c.get(this.g[this.g.length - 1]) || b | |
} | |
get nodes() { | |
return this.g | |
} | |
B() { | |
return null | |
} | |
r(t, i) { | |
return !0 | |
} | |
l(t, i, n) { | |
return !0 | |
} | |
o(t, i, n) { | |
return !0 | |
} | |
w() { | |
return 0 | |
} | |
t(t, i) {} | |
s(t, i, n, s, e, h) {} | |
C(t, i, n) {} | |
A(t, i) { | |
return F | |
} | |
z(t) { | |
return b | |
} | |
} | |
class M extends HTMLElement { | |
constructor() { | |
super(), this.style.cssText = ` | |
display: block; | |
position: absolute; | |
top: 0; | |
left: 0; | |
right: 0; | |
bottom: 0; | |
`, this.D = 0, this.F = 0, this.G = 0, this.H = !1, this.I = null, this.J = null, this.b = {}, this.d = {}, this.c = new WeakMap, this.K = this.K.bind(this), this.L = this.L.bind(this), this.M = this.M.bind(this); | |
const t = new v(this, this.d, this.b, this.c); | |
t.z = this.N.bind(this), t.r = this.O.bind(this), t.l = this.P.bind(this), t.o = this.Q.bind(this), t.A = this.R.bind(this), t.t = this.S.bind(this), t.s = this.T.bind(this), t.C = this.U.bind(this), t.w = (t => this.f), t.B = y, this.V = t, o({ | |
numberOfSections: 0, | |
numberOfRowsInSection: t => 0, | |
poolIdForHeader: t => "header", | |
poolIdForRow: t => "row", | |
domForHeader: m, | |
domForRow: m, | |
heightForHeader: f, | |
heightForRow: f, | |
scrollingElement: document.scrollingElement, | |
bottom: !1, | |
idForRow: t => 0, | |
idForHeader: t => 0 | |
}, this) | |
} | |
connectedCallback() { | |
return t(function*() { | |
window.addEventListener("resize", this.L), this.addEventListener("focus", this.M, !0) | |
}.call(this)) | |
} | |
disconnectedCallback() { | |
window.removeEventListener("resize", this.L), this.removeEventListener("focus", this.M) | |
} | |
get props() { | |
return this.W | |
} | |
set props(t) { | |
let i = this.W, | |
n = Object.assign({}, i, t); | |
i && i.scrollingElement === n.scrollingElement || (i && r(i.scrollingElement).removeEventListener("scroll", this.K), r(n.scrollingElement).addEventListener("scroll", this.K)), this.W = n, this.X() | |
} | |
get f() { | |
const t = this.J; | |
return t && t.length > 0 ? t[t.length - 1][1] + 1 : 0 | |
} | |
get Y() { | |
const t = this.f, | |
i = this.b[t - 1]; | |
return i && this.D == i.D ? i.y + i.h : s(this.F, this.G, t) | |
} | |
get Z() { | |
return ~~(this.F / this.G) | |
} | |
k(i, n, s) { | |
return t(function*() { | |
if (this.H) { | |
let t = this.V; | |
this.$ = i, this._ = n, yield t.recycle(s), this.style.height = 0 == this.f ? "" : `${this.Y}px`; | |
let e = t.startMeta, | |
h = e.idx, | |
o = e.y; | |
if (e != b) { | |
(h > 0 && o < 0 || 0 == h && 0 != o) && (e.y = this.Z * h, c(this.props.scrollingElement, e.y + this.$ - o), yield t.recycle(t.nodes)); | |
let i = this.J[e.aa], | |
n = this.props.bottom ? this.f - i[1] - 1 : i[0], | |
s = t.keep(n); | |
s != this.ba && (t.release(this.ba), this.ba = s) | |
} | |
} | |
}.call(this)) | |
} | |
X() { | |
return t(function*() { | |
let t = this.props; | |
if (yield i(), this.props === t) { | |
let i = u(t.scrollingElement), | |
n = t.scrollingElement.clientHeight, | |
s = this.V; | |
this.J = l(t.numberOfSections, t.numberOfRowsInSection), this.D++, this.G = 0, this.F = 0, (this.H || 0 != this.f) && (!this.H && this.f > 0 ? (this.H = !0, yield this.k(i, n, Array.from(this.children))) : yield this.k(i, n, s.nodes)) | |
} | |
}.call(this)) | |
} | |
P(t, i, n) { | |
return e(t.y, i.y + i.h, this.$, this._, n, 0) | |
} | |
Q(t, i, n) { | |
return !0 | |
} | |
O(t, i) { | |
return i.y + i.h < this.$ - this._ / 2 || i.y > this.$ + 1.5 * this._ | |
} | |
ca(t) { | |
let i = this.J, | |
n = this.props.bottom, | |
s = n ? this.f - t.idx - 1 : t.idx, | |
e = d(s, i), | |
h = n ? s - i[e][0] : s - i[e][0] - 1, | |
o = s == i[e][n ? 1 : 0], | |
r = o ? this.props.idForHeader(e) : this.props.idForRow(e, h); | |
return { | |
idx: t.idx, | |
h: t.h || 0, | |
y: t.y || 0, | |
id: r, | |
D: t.D || -1, | |
da: o, | |
aa: e, | |
ea: h | |
} | |
} | |
N(t) { | |
if (t.idx != w) return this.ca(t); | |
let i = a(this.b, "y", this.$); | |
return this.ca(i && i.idx < this.f && !this.O(null, i) ? i : { | |
idx: n(~~(this.$ / this.Z), 0, this.f - 1), | |
h: 0, | |
y: this.$ | |
}) | |
} | |
S(t, i) { | |
if (t.style.position = "absolute", t.style.top = `${i.y}px`, t.style.left = "0px", t.style.right = "0px", i.da) { | |
let n = this.J, | |
s = this.V, | |
e = n[i.aa + 1], | |
h = t.firstElementChild; | |
if (e && s.has(e[0])) { | |
let n = this.b[e[0]]; | |
t.style.height = `${n.y-i.y}px`, t.style.bottom = "auto" | |
} else t.style.height = "", t.style.bottom = "0px"; | |
h.style.position = "sticky", h.style.top = "0px" | |
} | |
} | |
T(t, i, n, s, e, o) { | |
i.D != this.D && (i.h = i.da ? this.props.heightForHeader(t.firstElementChild, i.aa) : this.props.heightForRow(t, i.aa, i.ea)), i.y = h(i, e, o, n, s), i.D = this.D, this.F = this.F + i.h, this.G = this.G + 1 | |
} | |
R(t, i) { | |
return i.da ? this.props.poolIdForHeader(i.aa) : this.props.poolIdForRow(i.aa, i.ea) | |
} | |
U(t, i, n) { | |
return n.da ? (t.firstElementChild || t.appendChild(y()), this.props.domForHeader(t.firstElementChild, n.aa)) : this.props.domForRow(t, n.aa, n.ea) | |
} | |
K() { | |
let t = this.props.scrollingElement; | |
this.k(u(t), t.clientHeight) | |
} | |
L() { | |
this.X() | |
} | |
M(t) { | |
let i = t.target; | |
for (; i && i != this && !this.c.has(i);) i = i.parentNode; | |
let n = this.c.get(i); | |
n && (this.fa && this.V.release(this.fa), this.fa = this.V.keep(n.idx)) | |
} | |
} | |
return customElements.define("layout-vertical", M), { | |
LayoutVertical: M | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment