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