@xnocss/core
Version:
short class online parse
326 lines (325 loc) • 12.9 kB
JavaScript
var M = Object.defineProperty;
var I = (a, e, t) => e in a ? M(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t;
var d = (a, e, t) => (I(a, typeof e != "symbol" ? e + "" : e, t), t), O = (a, e, t) => {
if (!e.has(a))
throw TypeError("Cannot " + t);
};
var n = (a, e, t) => (O(a, e, "read from private field"), t ? t.call(a) : e.get(a)), w = (a, e, t) => {
if (e.has(a))
throw TypeError("Cannot add the same private member more than once");
e instanceof WeakSet ? e.add(a) : e.set(a, t);
}, D = (a, e, t, i) => (O(a, e, "write to private field"), i ? i.call(a, t) : e.set(a, t), t);
var A = (a, e, t) => (O(a, e, "access private method"), t);
var S, y, m, p, C, E, v, b, R, L;
const g = class {
constructor(e = {}) {
w(this, R);
d(this, "title", "XCLASS");
d(this, "version", "1.0.0");
d(this, "isClearCache", !0);
d(this, "cacheExpire", -1);
d(this, "pseudoClassDefine", {});
d(this, "responsiveDefine", {});
d(this, "shortDefine", {});
d(this, "rules", []);
d(this, "themes", {});
d(this, "initialRenderNum", 1e3);
d(this, "debug", !1);
w(this, S, /* @__PURE__ */ new Map());
w(this, y, /* @__PURE__ */ new Map());
w(this, m, /* @__PURE__ */ new Map());
w(this, p, null);
w(this, C, /* @__PURE__ */ new Map());
w(this, E, null);
w(this, v, {});
w(this, b, /* @__PURE__ */ new Map());
d(this, "intersectionCallback", (e) => {
e.forEach((t) => {
let i = t.target;
t.isIntersecting && (this.initNode(i), n(this, p).unobserve(i));
});
});
var t, i, h, u, r, s, l, c, f, o;
this.title = (t = e == null ? void 0 : e.title) != null ? t : "XCLASS", this.version = (i = e == null ? void 0 : e.version) != null ? i : "1.0.0", this.isClearCache = (h = e == null ? void 0 : e.isClearCache) != null ? h : !0, this.cacheExpire = (u = e == null ? void 0 : e.cacheExpire) != null ? u : -1, this.pseudoClassDefine = (r = e == null ? void 0 : e.pseudoClassDefine) != null ? r : {}, this.responsiveDefine = (s = e == null ? void 0 : e.responsiveDefine) != null ? s : {}, this.shortDefine = (l = e == null ? void 0 : e.shortDefine) != null ? l : {}, this.themes = (c = e == null ? void 0 : e.themes) != null ? c : {}, this.rules = (f = e == null ? void 0 : e.rules) != null ? f : [], this.initialRenderNum = (e == null ? void 0 : e.initialRenderNum) || 1e3, this.debug = (o = e == null ? void 0 : e.debug) != null ? o : !1, typeof window == "object" && this.init();
}
init() {
let e = this.title + "_" + this.version;
this.isClearCache ? g.removeStorages(new RegExp(`${this.title}_.*`)) : g.removeStorages(new RegExp(`${this.title}_.*`), [e]);
const t = function(r) {
const s = history[r], l = new Event(r);
return function() {
const c = s.apply(this, arguments);
return l.arguments = arguments, window.dispatchEvent(l), c;
};
};
history.pushState = t("pushState"), history.replaceState = t("replaceState"), window.addEventListener("hashchange", () => {
n(this, b).clear();
}), window.addEventListener("popstate", () => {
n(this, b).clear();
}), window.addEventListener("pushState", () => {
n(this, b).clear();
}), window.addEventListener("replaceState", () => {
n(this, b).clear();
});
let i = g.getStorage(e) || {};
if (D(this, v, new Proxy(i, {
get(r, s) {
return r[s];
},
set(r, s, l) {
return r[s] = l, g.setStorage(e, i, this.cacheExpire), !0;
}
})), document.querySelectorAll(`style[title=${this.title}]`).length == 0) {
let r = document.createElement("style");
r.type = "text/css", r.title = this.title, document.querySelector("head").appendChild(r);
}
let u = document.styleSheets;
for (let r = u.length - 1; r >= 0; r--) {
let s = u.item(r);
s.title == this.title && D(this, E, s);
}
D(this, p, new IntersectionObserver(this.intersectionCallback, {
rootMargin: "500px 0px"
}));
}
bind(e, t) {
var i;
if (n(this, b).set(e, t), e.getAttribute("guid")) {
this.initNode(e);
return;
}
n(this, b).size > this.initialRenderNum ? (i = t == null ? void 0 : t.modifiers) != null && i.real || g.isInViewPort(e) ? this.initNode(e) : n(this, p).observe(e) : this.initNode(e);
}
unbind(e) {
let t = e.getAttribute("uid");
n(this, m).get(t) && (n(this, m).get(t).disconnect(), n(this, m).delete(t));
}
initNode(e) {
let t = e.getAttribute("guid");
if (t && console.log("插件生成", t), !t) {
t = `${this.title}-${g.guid()}`;
let u = document.createAttribute("uid");
u.nodeValue = t, e.attributes.setNamedItem(u), this.handleDebug(n(this, b).get(e), t);
let r = new Date().getTime();
this.parseAndCreate(e), this.debug && console.log("生成时间", t, new Date().getTime() - r);
}
var i = {
childList: !1,
// 观察目标子节点的变化,是否有添加或者删除
attributes: !0,
// 观察属性变动
subtree: !1
// 观察后代节点,默认为 false
};
let h = new MutationObserver(() => {
let u = new Date().getTime();
this.parseAndCreate(e), this.debug && console.log("生成时间-", t, new Date().getTime() - u);
});
h.observe(e, i), n(this, m).set(t, h);
}
parseAndCreate(e) {
let t = this.parseStyle(e);
this.createStyles(t, e);
}
// 解析style结果
parseStyle(e) {
let t = e.attributes, i = [];
e.classList.forEach((s) => {
i.push(s);
});
for (let s = 0; s < t.length; s++)
i.push(t[s].nodeName);
let u = e.getAttribute("uid"), r = n(this, C).get(u);
return r && r.length == i.length && r.filter((s) => !i.includes(s)).length == 0 ? {} : (n(this, C).set(u, i.map((s) => s)), this.parseStyleNode(i, u));
}
//将结果挂载到stylesheet上
createStyles(e, t) {
this.createStylesNode(e, t.getAttribute("uid"), t.tagName.toLocaleLowerCase()).forEach((h) => {
h.forEach((u) => {
this.insertStyle(u.selector, u.styleText, u.newStyleText);
});
}), this.debugConsole(t);
}
//插入stylesheet的
insertStyle(e, t, i) {
let h = n(this, E);
if (h.title == this.title) {
let u = h.cssRules, r = !0;
for (let s = 0; s < u.length; s++) {
let l = u.item(s);
if (!i && l.type == 1) {
if (l.selectorText == e && l.cssText != t) {
g.deleteRule(h, s), g.insertRule(h, e, t, s), r = !1;
break;
}
} else if (i && l.type == 4) {
for (let c = 0; c < l.cssRules.length; c++) {
let f = l.cssRules.item(c);
if (f.selectorText == e && f.cssText != t) {
g.deleteRule(h, s), g.insertRule(h, e, i, s), r = !1;
break;
}
}
if (!r)
break;
}
}
r && g.insertRule(h, e, i || t, 0);
}
}
// 将得到的class或者attr解析成style
//先处理响应式的东西,然后交给#parseStyleResultNode来统一处理style结果
parseStyleNode(e, t) {
let i = [];
e.forEach((u, r) => {
if (Object.keys(this.shortDefine).includes(u)) {
e.splice(r, 1, "");
let s = this.shortDefine[u] || [];
typeof s == "string" && (s = s.split(" ")), i.push(...s);
}
}), e = e.filter((u) => u), e.push(...i);
let h = {};
return Object.keys(this.responsiveDefine).length > 0 ? (Object.keys(this.responsiveDefine).forEach((u) => {
h[this.responsiveDefine[u]] || (h[this.responsiveDefine[u]] = []), e = e.filter((r) => r), h[this.responsiveDefine[u]].push(A(this, R, L).call(this, e.filter((r, s) => {
let l = r.startsWith(u);
return l && e.splice(s, 1, ""), l;
}).map((r) => r.replace(u, "")), t));
}), e = e.filter((u) => u), h[""] = [A(this, R, L).call(this, e, t)]) : h[""] = [A(this, R, L).call(this, e, t)], h;
}
//生成单个css结果
createStyleNode(e, t, i, h = "") {
var s;
let u = `${i.toLocaleLowerCase()}[uid="${t}"]${h}`, r = ((s = e == null ? void 0 : e.length) != null ? s : 0) > 0 ? `
${u}{
${e.join("")}
}
` : "";
return r ? {
selector: u,
styleText: r
} : void 0;
}
//生成所有的css并返回生成对象
createStylesNode(e, t, i) {
return e ? Object.keys(e).map((h) => {
let r = e[h].reduce((s, l) => (Object.keys(l).forEach((c) => {
s[c] || (s[c] = []), s[c].push(...l[c]);
}), s), {});
return Object.keys(r).map((s) => {
try {
let l = this.createStyleNode(r[s], t, i, s || "");
if (l)
return h && (l.newStyleText = h + `{${l.styleText}}`), l;
} catch (l) {
console.error(l);
}
}).filter((s) => s);
}).filter((h) => h.length > 0) : [];
}
handleDebug(e, t) {
if (this.debug)
if (e.arg == "test") {
let i = e.value || [];
typeof i == "string" && (i = i.split(" ")), n(this, S).set(t, i || []);
} else
n(this, S).delete(t);
}
debugCollect(e, t) {
if (this.debug && n(this, S).get(e)) {
let i = n(this, S).get(e) || [];
if (t) {
let h = t(i);
n(this, y).get(e) || n(this, y).set(e, []), h && n(this, y).get(e).push(h);
}
}
}
debugConsole(e) {
if (this.debug) {
let t = e.getAttribute("uid");
n(this, S).get(t) && (console.log("测试结果", t, e), console.log(n(this, y).get(t)));
}
}
static insertRule(e, t, i, h) {
e.insertRule && i ? e.insertRule(i, h) : e.addRule && i && e.addRule(t, i, h);
}
static deleteRule(e, t) {
e.deleteRule ? e.deleteRule(t) : e.removeRule && e.removeRule(t);
}
};
let x = g;
S = new WeakMap(), y = new WeakMap(), m = new WeakMap(), p = new WeakMap(), C = new WeakMap(), E = new WeakMap(), v = new WeakMap(), b = new WeakMap(), R = new WeakSet(), L = function(e, t) {
let i = {}, h = e.map((r, s) => {
let l = n(this, v)[r];
return l && (this.debugCollect(t, function(c) {
if (c.length == 0)
return ["规则生成缓存", r, l];
if (c.includes(r))
return ["规则生成缓存", r, l];
}), e.splice(s, 1, "")), l;
}).filter((r) => r);
Object.keys(this.pseudoClassDefine).forEach((r) => {
i[this.pseudoClassDefine[r]] || (i[this.pseudoClassDefine[r]] = []), e = e.filter((l) => l);
let s = e.filter((l, c) => {
let f = l.startsWith(r);
return f && e.splice(c, 1, ""), f;
}).map((l) => {
let c = l.replace(r, ""), f = n(this, v)[c];
return f ? (this.debugCollect(t, function(o) {
if (o.length == 0)
return ["规则生成-缓存", l, f];
if (o.includes(l))
return ["规则生成-缓存", l, f];
}), [f]) : this.rules.filter((o) => o[0].test(c)).map((o) => (f = o[1](o[0].exec(c), c, this.themes), n(this, v)[c] = f, this.debugCollect(t, function(k) {
if (k.length == 0)
return ["规则生成", o[0], l, f];
if (k.includes(l))
return ["规则生成", o[0], l, f];
}), f));
}).flat(1 / 0);
i[this.pseudoClassDefine[r]].push(...s);
}), e = e.filter((r) => r);
let u = this.rules.map((r) => e.filter((l) => r[0].test(l)).map((l) => {
let c = r[1](r[0].exec(l), l, this.themes);
return n(this, v)[l] = c, this.debugCollect(t, function(f) {
if (f.length == 0)
return ["规则生成", r[0], l, c];
if (f.includes(l))
return ["规则生成", r[0], l, c];
}), c;
})).flat(1 / 0);
return i[""] = h.concat(u), i;
}, d(x, "guid", () => "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(e) {
var t = Math.random() * 16 | 0, i = e == "x" ? t : t & 3 | 8;
return i.toString(16);
})), d(x, "setStorage", (e, t, i = 72e5) => {
let h = {
value: t,
expire: i,
timestamp: Date.now(),
isForever: i == -1
};
window.localStorage.setItem(e, JSON.stringify(h));
}), d(x, "getStorage", (e) => {
let t = window.localStorage.getItem(e);
if (!t)
return null;
let i = JSON.parse(t);
return !i.isForever && Date.now() > i.expire + i.timestamp ? (window.localStorage.removeItem(e), null) : i.value;
}), d(x, "removeStorage", (e) => {
window.localStorage.removeItem(e);
}), d(x, "removeStorages", (e, t = []) => {
Object.keys(window.localStorage).filter((i) => e.test(i) && !t.includes(i)).forEach((i) => {
window.localStorage.removeItem(i);
});
}), d(x, "isInViewPort", (e) => {
const t = window.innerWidth || document.documentElement.clientWidth, i = window.innerHeight || document.documentElement.clientHeight, {
top: h,
right: u,
bottom: r,
left: s
} = e.getBoundingClientRect();
return h >= 0 && s >= 0 && u <= t && r <= i;
});
export {
x as default
};