mnfst 0.5.218 → 0.5.219
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/manifest.appwrite.data.js +1 -1
- package/lib/manifest.code.js +120 -46
- package/lib/manifest.css +83 -222
- package/lib/manifest.d.ts +2 -0
- package/lib/manifest.data.js +26 -3
- package/lib/manifest.defer.js +145 -34
- package/lib/manifest.edit.css +63 -27
- package/lib/manifest.edit.js +213 -28
- package/lib/manifest.integrity.json +11 -11
- package/lib/manifest.js +43 -2
- package/lib/manifest.markdown.js +11 -7
- package/lib/manifest.min.css +1 -1
- package/lib/manifest.router.js +58 -69
- package/lib/manifest.sw.js +1 -1
- package/lib/manifest.text.edit.css +20 -0
- package/lib/manifest.text.edit.js +151 -25
- package/lib/manifest.utilities.js +246 -100
- package/lib/manifest.utilities.node.mjs +195 -35
- package/package.json +1 -1
|
@@ -617,6 +617,7 @@ class TailwindCompiler {
|
|
|
617
617
|
this.lastClassesHash = ''; // Track changes in used classes
|
|
618
618
|
this.staticClassCache = new Set(); // Cache classes found in static HTML/components
|
|
619
619
|
this.dynamicClassCache = new Set(); // Cache classes that appear dynamically
|
|
620
|
+
this.quietClasses = new Set(); // Seen only inside ignored elements, not yet compiled
|
|
620
621
|
this.hasScannedStatic = false; // Track if we've done initial static scan
|
|
621
622
|
this.staticScanPromise = null; // Promise for initial static scan
|
|
622
623
|
this.ignoredClassPatterns = [ // Patterns for classes to ignore
|
|
@@ -772,6 +773,7 @@ class TailwindCompiler {
|
|
|
772
773
|
TailwindCompiler.prototype.ensureUtilityStylesLast = function () {
|
|
773
774
|
if (this.styleElement && this.styleElement.parentNode && document.head.lastElementChild !== this.styleElement) {
|
|
774
775
|
document.head.appendChild(this.styleElement);
|
|
776
|
+
if (this.resyncUtilitiesText) this.resyncUtilitiesText();
|
|
775
777
|
}
|
|
776
778
|
};
|
|
777
779
|
|
|
@@ -1148,6 +1150,8 @@ TailwindCompiler.prototype.fetchThemeContent = async function () {
|
|
|
1148
1150
|
// Wait for all fetches to complete
|
|
1149
1151
|
await Promise.all(fetchPromises);
|
|
1150
1152
|
|
|
1153
|
+
// Order-free identity (fetches land in any order) for "theme unchanged" checks
|
|
1154
|
+
this.lastThemeKey = Array.from(themeContents).sort().join('\n');
|
|
1151
1155
|
return Array.from(themeContents).join('\n');
|
|
1152
1156
|
};
|
|
1153
1157
|
|
|
@@ -1884,6 +1888,10 @@ TailwindCompiler.prototype.generateUtilitiesFromVars = function (cssText, usedDa
|
|
|
1884
1888
|
const generatedRules = new Set(); // Track generated rules to prevent duplicates
|
|
1885
1889
|
const variables = this.extractThemeVariables(cssText);
|
|
1886
1890
|
const { classes: usedClasses, variableSuffixes } = usedData;
|
|
1891
|
+
// Optional: raw rules + their full-regen order keys (incremental apply places deltas by them)
|
|
1892
|
+
const rulesOut = usedData.rulesOut, keysOut = usedData.keysOut;
|
|
1893
|
+
let slot = null;
|
|
1894
|
+
const emit = (rule, sub) => { utilities.push(rule); if (rulesOut) { rulesOut.push(rule); keysOut.push(slot.concat(slot[3] ? 2 : sub)); } }; // opacity rules order by discovery
|
|
1887
1895
|
|
|
1888
1896
|
if (variables.size === 0) {
|
|
1889
1897
|
return '';
|
|
@@ -1908,7 +1916,7 @@ TailwindCompiler.prototype.generateUtilitiesFromVars = function (cssText, usedDa
|
|
|
1908
1916
|
if (usedClasses.includes(baseClass)) {
|
|
1909
1917
|
const rule = `.${escapeClassName(baseClass)} { ${css} }`;
|
|
1910
1918
|
if (!generatedRules.has(rule)) {
|
|
1911
|
-
|
|
1919
|
+
emit(rule, 0);
|
|
1912
1920
|
generatedRules.add(rule);
|
|
1913
1921
|
}
|
|
1914
1922
|
}
|
|
@@ -1919,7 +1927,7 @@ TailwindCompiler.prototype.generateUtilitiesFromVars = function (cssText, usedDa
|
|
|
1919
1927
|
css + ' !important';
|
|
1920
1928
|
const rule = `.${escapeClassName('!' + baseClass)} { ${importantCss} }`;
|
|
1921
1929
|
if (!generatedRules.has(rule)) {
|
|
1922
|
-
|
|
1930
|
+
emit(rule, 1);
|
|
1923
1931
|
generatedRules.add(rule);
|
|
1924
1932
|
}
|
|
1925
1933
|
}
|
|
@@ -1988,26 +1996,33 @@ TailwindCompiler.prototype.generateUtilitiesFromVars = function (cssText, usedDa
|
|
|
1988
1996
|
rule;
|
|
1989
1997
|
|
|
1990
1998
|
if (!generatedRules.has(finalRule)) {
|
|
1991
|
-
|
|
1999
|
+
emit(finalRule, 2);
|
|
1992
2000
|
generatedRules.add(finalRule);
|
|
1993
2001
|
}
|
|
1994
2002
|
}
|
|
1995
2003
|
};
|
|
1996
2004
|
|
|
2005
|
+
// Every generated class ends in its variable's suffix: skip variables no used class mentions
|
|
2006
|
+
const usedBases = usedClasses.map(cls => this.parseClassName(cls).baseClass);
|
|
2007
|
+
|
|
1997
2008
|
// Generate utilities based on variable prefix
|
|
2009
|
+
let vi = -1;
|
|
1998
2010
|
for (const [varName, varValue] of variables.entries()) {
|
|
2011
|
+
vi++;
|
|
1999
2012
|
if (!varName.match(this.regexPatterns.tailwindPrefix)) {
|
|
2000
2013
|
continue;
|
|
2001
2014
|
}
|
|
2002
2015
|
|
|
2003
2016
|
const suffix = varName.split('-').slice(1).join('-');
|
|
2017
|
+
if (!usedBases.some(base => base.includes(suffix))) continue;
|
|
2004
2018
|
const value = `var(--${varName})`;
|
|
2005
2019
|
const prefix = varName.split('-')[0] + '-';
|
|
2006
2020
|
const generator = this.utilityGenerators[prefix];
|
|
2007
2021
|
|
|
2008
2022
|
if (generator) {
|
|
2009
2023
|
const utilityPairs = generator(suffix, value);
|
|
2010
|
-
for (
|
|
2024
|
+
for (let pi = 0; pi < utilityPairs.length; pi++) {
|
|
2025
|
+
const [className, css] = utilityPairs[pi];
|
|
2011
2026
|
// Check if this specific utility class is actually used (including variants and important)
|
|
2012
2027
|
const isUsed = usedClasses.some(cls => {
|
|
2013
2028
|
// Parse the class to extract the base utility name
|
|
@@ -2020,6 +2035,7 @@ TailwindCompiler.prototype.generateUtilitiesFromVars = function (cssText, usedDa
|
|
|
2020
2035
|
(baseClass.startsWith('!') && baseClass.slice(1) === className);
|
|
2021
2036
|
});
|
|
2022
2037
|
if (isUsed) {
|
|
2038
|
+
slot = [0, vi, pi, 0];
|
|
2023
2039
|
generateUtility(className, css);
|
|
2024
2040
|
}
|
|
2025
2041
|
|
|
@@ -2051,6 +2067,7 @@ TailwindCompiler.prototype.generateUtilitiesFromVars = function (cssText, usedDa
|
|
|
2051
2067
|
const opacity = opacityBaseClass.split('/')[1];
|
|
2052
2068
|
const opacityValue = `color-mix(in oklch, ${value} ${opacity}%, transparent)`;
|
|
2053
2069
|
const opacityCss = css.replace(value, opacityValue);
|
|
2070
|
+
slot = [0, vi, pi, 1];
|
|
2054
2071
|
generateUtility(opacityBaseClass, opacityCss);
|
|
2055
2072
|
}
|
|
2056
2073
|
}
|
|
@@ -2070,6 +2087,9 @@ TailwindCompiler.prototype.generateCustomUtilities = function (usedData) {
|
|
|
2070
2087
|
const utilities = [];
|
|
2071
2088
|
const generatedRules = new Set();
|
|
2072
2089
|
const { classes: usedClasses } = usedData;
|
|
2090
|
+
const rulesOut = usedData.rulesOut, keysOut = usedData.keysOut;
|
|
2091
|
+
let slot = null;
|
|
2092
|
+
const emit = (rule, sub) => { utilities.push(rule); if (rulesOut) { rulesOut.push(rule); keysOut.push(slot.concat(sub)); } };
|
|
2073
2093
|
|
|
2074
2094
|
// Helper to clean up [object Object] from CSS strings
|
|
2075
2095
|
const cleanCssString = (css) => {
|
|
@@ -2225,7 +2245,7 @@ TailwindCompiler.prototype.generateCustomUtilities = function (usedData) {
|
|
|
2225
2245
|
rule = `.${escapeClassName('!' + baseClass)} { ${importantCss} }`;
|
|
2226
2246
|
}
|
|
2227
2247
|
if (!generatedRules.has(rule)) {
|
|
2228
|
-
|
|
2248
|
+
emit(rule, 1);
|
|
2229
2249
|
generatedRules.add(rule);
|
|
2230
2250
|
}
|
|
2231
2251
|
}
|
|
@@ -2399,14 +2419,16 @@ TailwindCompiler.prototype.generateCustomUtilities = function (usedData) {
|
|
|
2399
2419
|
}
|
|
2400
2420
|
|
|
2401
2421
|
if (!generatedRules.has(finalRule)) {
|
|
2402
|
-
|
|
2422
|
+
emit(finalRule, 2);
|
|
2403
2423
|
generatedRules.add(finalRule);
|
|
2404
2424
|
}
|
|
2405
2425
|
}
|
|
2406
2426
|
};
|
|
2407
2427
|
|
|
2408
2428
|
// Generate utilities for each custom class that's actually used
|
|
2429
|
+
let ci = -1;
|
|
2409
2430
|
for (const [className, cssOrSelector] of this.customUtilities.entries()) {
|
|
2431
|
+
ci++;
|
|
2410
2432
|
// Normalize class name: if it starts with !, extract the base name
|
|
2411
2433
|
const hasImportantPrefix = className.startsWith('!');
|
|
2412
2434
|
const baseClassName = hasImportantPrefix ? className.slice(1) : className;
|
|
@@ -2446,9 +2468,12 @@ TailwindCompiler.prototype.generateCustomUtilities = function (usedData) {
|
|
|
2446
2468
|
// Generate utility with base class name (without !)
|
|
2447
2469
|
// The CSS already has !important if className started with !
|
|
2448
2470
|
if (typeof cssOrSelector === 'string') {
|
|
2471
|
+
slot = [1, ci, 0, 0];
|
|
2449
2472
|
generateUtility(baseClassName, normalizedCss, null);
|
|
2450
2473
|
} else if (Array.isArray(cssOrSelector)) {
|
|
2451
|
-
for (
|
|
2474
|
+
for (let ai = 0; ai < cssOrSelector.length; ai++) {
|
|
2475
|
+
const entry = cssOrSelector[ai];
|
|
2476
|
+
slot = [1, ci, ai, 0];
|
|
2452
2477
|
if (entry && entry.css && entry.selector) {
|
|
2453
2478
|
// Ensure entry.css is a string (not an object)
|
|
2454
2479
|
const extracted = typeof entry.css === 'string' ? entry.css :
|
|
@@ -2469,6 +2494,7 @@ TailwindCompiler.prototype.generateCustomUtilities = function (usedData) {
|
|
|
2469
2494
|
String(cssOrSelector.css));
|
|
2470
2495
|
const selectorCss = cleanCssString(extracted);
|
|
2471
2496
|
|
|
2497
|
+
slot = [1, ci, 0, 0];
|
|
2472
2498
|
generateUtility(baseClassName, selectorCss, {
|
|
2473
2499
|
selector: cssOrSelector.selector,
|
|
2474
2500
|
fullBlock: cssOrSelector.fullBlock || false
|
|
@@ -2484,49 +2510,169 @@ TailwindCompiler.prototype.generateCustomUtilities = function (usedData) {
|
|
|
2484
2510
|
}
|
|
2485
2511
|
};
|
|
2486
2512
|
|
|
2487
|
-
//
|
|
2488
|
-
TailwindCompiler.prototype.
|
|
2489
|
-
if (!utilitiesText) return '';
|
|
2490
|
-
|
|
2491
|
-
// Split into individual rules (each rule starts with . or @media)
|
|
2513
|
+
// Split generated CSS into top-level rules (each starts with . or an at-rule)
|
|
2514
|
+
TailwindCompiler.prototype.splitUtilityRules = function (utilitiesText) {
|
|
2492
2515
|
const rules = [];
|
|
2493
2516
|
let currentRule = '';
|
|
2494
|
-
const
|
|
2495
|
-
|
|
2496
|
-
for (const line of lines) {
|
|
2497
|
-
// Check if this line starts a new rule
|
|
2517
|
+
for (const line of utilitiesText.split('\n')) {
|
|
2498
2518
|
if (line.trim().match(/^(\.|@media|@layer|@supports)/)) {
|
|
2499
|
-
|
|
2500
|
-
if (currentRule.trim()) {
|
|
2501
|
-
rules.push(currentRule.trim());
|
|
2502
|
-
}
|
|
2519
|
+
if (currentRule.trim()) rules.push(currentRule.trim());
|
|
2503
2520
|
currentRule = line;
|
|
2504
2521
|
} else {
|
|
2505
|
-
// Continue current rule
|
|
2506
2522
|
currentRule += '\n' + line;
|
|
2507
2523
|
}
|
|
2508
2524
|
}
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2525
|
+
if (currentRule.trim()) rules.push(currentRule.trim());
|
|
2526
|
+
return rules;
|
|
2527
|
+
};
|
|
2528
|
+
|
|
2529
|
+
// Sort utilities so base classes come before variants (@media)
|
|
2530
|
+
TailwindCompiler.prototype.sortUtilities = function (utilitiesText) {
|
|
2531
|
+
if (!utilitiesText) return '';
|
|
2532
|
+
const rules = this.splitUtilityRules(utilitiesText);
|
|
2515
2533
|
rules.sort((a, b) => {
|
|
2516
2534
|
const aHasMedia = a.startsWith('@media');
|
|
2517
2535
|
const bHasMedia = b.startsWith('@media');
|
|
2518
|
-
|
|
2519
|
-
// Base utilities come before variants
|
|
2520
2536
|
if (!aHasMedia && bHasMedia) return -1;
|
|
2521
2537
|
if (aHasMedia && !bHasMedia) return 1;
|
|
2522
|
-
|
|
2523
|
-
// Same type, maintain order
|
|
2524
2538
|
return 0;
|
|
2525
2539
|
});
|
|
2526
|
-
|
|
2527
2540
|
return rules.join('\n\n');
|
|
2528
2541
|
};
|
|
2529
2542
|
|
|
2543
|
+
// ---- Incremental apply: new rules go in through CSSOM, never a whole-sheet rewrite ----
|
|
2544
|
+
// Entries mirror the layer's cssRules 1:1, each keyed by where a full regen would emit it
|
|
2545
|
+
// ([media, section, var/entry, pair/array, region, sub]); deltas are inserted at that index.
|
|
2546
|
+
|
|
2547
|
+
const utilitiesCssFrom = (applied) => `@layer utilities {\n${applied.entries.map(e => e.rule).join('\n\n')}\n}`;
|
|
2548
|
+
const isMediaRule = (rule) => rule.trim().startsWith('@media');
|
|
2549
|
+
|
|
2550
|
+
function compareKeys(a, b) {
|
|
2551
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return a[i] - b[i];
|
|
2552
|
+
return 0;
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2555
|
+
// Raw rules + order keys for a class set, as a full regen would emit them (base before @media, stable)
|
|
2556
|
+
TailwindCompiler.prototype.generateKeyedUtilities = function (themeCss, classes) {
|
|
2557
|
+
const usedData = { classes, variableSuffixes: [], rulesOut: [], keysOut: [] };
|
|
2558
|
+
this.generateUtilitiesFromVars(themeCss, usedData);
|
|
2559
|
+
this.generateCustomUtilities(usedData);
|
|
2560
|
+
const out = usedData.rulesOut.map((rule, i) => {
|
|
2561
|
+
const media = isMediaRule(rule) ? 1 : 0;
|
|
2562
|
+
return { rule, key: [media].concat(usedData.keysOut[i]) };
|
|
2563
|
+
});
|
|
2564
|
+
return out.filter(e => !e.key[0]).concat(out.filter(e => e.key[0]));
|
|
2565
|
+
};
|
|
2566
|
+
|
|
2567
|
+
TailwindCompiler.prototype.utilitiesLayerRule = function () {
|
|
2568
|
+
const sheet = this.styleElement && this.styleElement.sheet;
|
|
2569
|
+
if (!sheet || typeof CSSLayerBlockRule === 'undefined') return null;
|
|
2570
|
+
try {
|
|
2571
|
+
for (const rule of sheet.cssRules) {
|
|
2572
|
+
if (rule instanceof CSSLayerBlockRule && rule.name === 'utilities') return rule;
|
|
2573
|
+
}
|
|
2574
|
+
} catch (e) { }
|
|
2575
|
+
return null;
|
|
2576
|
+
};
|
|
2577
|
+
|
|
2578
|
+
// Entries must match the parsed sheet rule-for-rule, or deltas could land at the wrong index
|
|
2579
|
+
TailwindCompiler.prototype.entriesMatchSheet = function (entries) {
|
|
2580
|
+
const layer = this.utilitiesLayerRule();
|
|
2581
|
+
if (!layer || layer.cssRules.length !== entries.length) return false;
|
|
2582
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2583
|
+
if ((layer.cssRules[i] instanceof CSSMediaRule) !== !!entries[i].key[0]) return false;
|
|
2584
|
+
}
|
|
2585
|
+
return true;
|
|
2586
|
+
};
|
|
2587
|
+
|
|
2588
|
+
// After a full write: remember its rules so later compiles can insert beside them
|
|
2589
|
+
TailwindCompiler.prototype.recordAppliedUtilities = function (entries, themeCss) {
|
|
2590
|
+
this._applied = null;
|
|
2591
|
+
if (window.__manifestRender === true || !this.entriesMatchSheet(entries)) return;
|
|
2592
|
+
this._applied = {
|
|
2593
|
+
themeKey: this.lastThemeKey,
|
|
2594
|
+
themeCss, // keys index this exact variable order
|
|
2595
|
+
entries,
|
|
2596
|
+
rules: new Set(entries.map(e => e.rule)),
|
|
2597
|
+
classes: new Set(this.dynamicClassCache),
|
|
2598
|
+
dirty: false // inserted rules not yet in textContent
|
|
2599
|
+
};
|
|
2600
|
+
};
|
|
2601
|
+
|
|
2602
|
+
// Moving <style> rebuilds its sheet from textContent: write inserted rules back first
|
|
2603
|
+
TailwindCompiler.prototype.resyncUtilitiesText = function () {
|
|
2604
|
+
const applied = this._applied;
|
|
2605
|
+
if (!applied || !applied.dirty) return;
|
|
2606
|
+
applied.dirty = false;
|
|
2607
|
+
this.styleElement.textContent = utilitiesCssFrom(applied);
|
|
2608
|
+
if (!this.entriesMatchSheet(applied.entries)) this._applied = null;
|
|
2609
|
+
};
|
|
2610
|
+
|
|
2611
|
+
// Prerender snapshots read #manifest-styles text, so render passes always rewrite it
|
|
2612
|
+
TailwindCompiler.prototype.canCompileDelta = function () {
|
|
2613
|
+
return !!this._applied && window.__manifestRender !== true && !!this.utilitiesLayerRule();
|
|
2614
|
+
};
|
|
2615
|
+
|
|
2616
|
+
// Generate only never-compiled classes and insert each rule where a full regen would put it.
|
|
2617
|
+
// Returns false when a rule's place depends on class discovery order: caller does a full compile.
|
|
2618
|
+
TailwindCompiler.prototype.compileDelta = function (themeCss) {
|
|
2619
|
+
const applied = this._applied;
|
|
2620
|
+
const candidates = [];
|
|
2621
|
+
for (const cls of this.dynamicClassCache) if (!applied.classes.has(cls)) candidates.push(cls);
|
|
2622
|
+
const classes = this.filterStaticallyCoveredClasses(candidates);
|
|
2623
|
+
const fresh = classes.length ? this.generateKeyedUtilities(themeCss, classes).filter(e => !applied.rules.has(e.rule)) : [];
|
|
2624
|
+
const entries = applied.entries;
|
|
2625
|
+
|
|
2626
|
+
// Place every rule first; bail before touching the sheet if any is ambiguous
|
|
2627
|
+
const plan = [];
|
|
2628
|
+
for (const e of fresh) {
|
|
2629
|
+
let lo = 0, hi = entries.length;
|
|
2630
|
+
while (lo < hi) { const mid = (lo + hi) >> 1; if (compareKeys(entries[mid].key, e.key) <= 0) lo = mid + 1; else hi = mid; }
|
|
2631
|
+
// Same utility, same group, both variants: full regen orders them by discovery
|
|
2632
|
+
if (e.key[5] === 2) {
|
|
2633
|
+
const sameSlot = (x) => x && compareKeys(x.key.slice(0, 5), e.key.slice(0, 5)) === 0 && x.key[5] === 2;
|
|
2634
|
+
if (sameSlot(entries[lo - 1]) || sameSlot(entries[lo]) || plan.some(q => sameSlot(q.e))) return false;
|
|
2635
|
+
}
|
|
2636
|
+
plan.push({ e, at: lo });
|
|
2637
|
+
}
|
|
2638
|
+
for (const cls of candidates) applied.classes.add(cls);
|
|
2639
|
+
if (!plan.length) return true;
|
|
2640
|
+
|
|
2641
|
+
const layer = this.utilitiesLayerRule();
|
|
2642
|
+
try {
|
|
2643
|
+
// Insert in key order; each insert shifts later indices by one
|
|
2644
|
+
plan.sort((x, y) => compareKeys(x.e.key, y.e.key));
|
|
2645
|
+
plan.forEach((q, n) => {
|
|
2646
|
+
layer.insertRule(q.e.rule, q.at + n);
|
|
2647
|
+
entries.splice(q.at + n, 0, q.e);
|
|
2648
|
+
applied.rules.add(q.e.rule);
|
|
2649
|
+
});
|
|
2650
|
+
} catch (err) {
|
|
2651
|
+
// A rule the parser splits or drops: the planned indices no longer hold
|
|
2652
|
+
this._applied = null;
|
|
2653
|
+
return false;
|
|
2654
|
+
}
|
|
2655
|
+
applied.dirty = true;
|
|
2656
|
+
this.schedulePersistentSave(themeCss);
|
|
2657
|
+
return true;
|
|
2658
|
+
};
|
|
2659
|
+
|
|
2660
|
+
// Coalesce cache writes: localStorage serialisation is too slow to run per compile
|
|
2661
|
+
TailwindCompiler.prototype.schedulePersistentSave = function (themeCss) {
|
|
2662
|
+
clearTimeout(this._persistTimer);
|
|
2663
|
+
this._persistTimer = setTimeout(() => {
|
|
2664
|
+
if (!this._applied) return;
|
|
2665
|
+
const classesHash = Array.from(this.dynamicClassCache).sort().join(',');
|
|
2666
|
+
const themeHash = this.generateThemeHash(themeCss);
|
|
2667
|
+
this.cache.set(`${classesHash}-${themeHash}`, {
|
|
2668
|
+
css: utilitiesCssFrom(this._applied),
|
|
2669
|
+
timestamp: Date.now(),
|
|
2670
|
+
themeHash
|
|
2671
|
+
});
|
|
2672
|
+
this.savePersistentCache();
|
|
2673
|
+
}, 1000);
|
|
2674
|
+
};
|
|
2675
|
+
|
|
2530
2676
|
// Helper function to filter critical utilities that are already in layer utilities
|
|
2531
2677
|
TailwindCompiler.prototype.filterCriticalUtilities = function(criticalText, layerUtilities) {
|
|
2532
2678
|
if (!criticalText || !layerUtilities) return '';
|
|
@@ -2630,6 +2776,7 @@ TailwindCompiler.prototype.compile = async function () {
|
|
|
2630
2776
|
}
|
|
2631
2777
|
this.lastCompileTime = now;
|
|
2632
2778
|
this.isCompiling = true;
|
|
2779
|
+
this.quietClasses.clear(); // this compile covers them
|
|
2633
2780
|
window.__manifestUtilitiesPending = (window.__manifestUtilitiesPending || 0) + 1;
|
|
2634
2781
|
this._compileCounted = true;
|
|
2635
2782
|
|
|
@@ -2720,6 +2867,13 @@ TailwindCompiler.prototype.compile = async function () {
|
|
|
2720
2867
|
return;
|
|
2721
2868
|
}
|
|
2722
2869
|
|
|
2870
|
+
// Theme unchanged since the last full write: insert only the new classes
|
|
2871
|
+
let prefetchedTheme = null;
|
|
2872
|
+
if (this.canCompileDelta()) {
|
|
2873
|
+
prefetchedTheme = await this.fetchThemeContent();
|
|
2874
|
+
if (prefetchedTheme && this.lastThemeKey === this._applied.themeKey && this.compileDelta(this._applied.themeCss)) return;
|
|
2875
|
+
}
|
|
2876
|
+
|
|
2723
2877
|
// For subsequent compilations, check for new dynamic classes
|
|
2724
2878
|
const usedData = this.getUsedClasses();
|
|
2725
2879
|
const dynamicClasses = Array.from(this.dynamicClassCache);
|
|
@@ -2730,7 +2884,7 @@ TailwindCompiler.prototype.compile = async function () {
|
|
|
2730
2884
|
// Check if dynamic classes have actually changed
|
|
2731
2885
|
if (dynamicClassesHash !== this.lastClassesHash || !this.hasInitialized) {
|
|
2732
2886
|
// Fetch CSS content for dynamic compilation
|
|
2733
|
-
const themeCss = await this.fetchThemeContent();
|
|
2887
|
+
const themeCss = prefetchedTheme || await this.fetchThemeContent();
|
|
2734
2888
|
if (!themeCss) {
|
|
2735
2889
|
this.isCompiling = false;
|
|
2736
2890
|
return;
|
|
@@ -2757,8 +2911,10 @@ TailwindCompiler.prototype.compile = async function () {
|
|
|
2757
2911
|
if (hasVariableChanges || dynamicClassesHash !== this.lastClassesHash) {
|
|
2758
2912
|
|
|
2759
2913
|
// Generate both variable-based and custom utilities
|
|
2760
|
-
const
|
|
2761
|
-
const
|
|
2914
|
+
const rulesOut = [], keysOut = [];
|
|
2915
|
+
const keyedData = Object.assign({}, usedData, { rulesOut, keysOut });
|
|
2916
|
+
const varUtilities = this.generateUtilitiesFromVars(themeCss, keyedData);
|
|
2917
|
+
const customUtilitiesGenerated = this.generateCustomUtilities(keyedData);
|
|
2762
2918
|
|
|
2763
2919
|
let allUtilities = [varUtilities, customUtilitiesGenerated].filter(Boolean).join('\n\n');
|
|
2764
2920
|
// Sort utilities so base classes come before variants
|
|
@@ -2784,6 +2940,8 @@ TailwindCompiler.prototype.compile = async function () {
|
|
|
2784
2940
|
});
|
|
2785
2941
|
});
|
|
2786
2942
|
this.lastClassesHash = dynamicClassesHash;
|
|
2943
|
+
const entries = rulesOut.map((rule, i) => ({ rule, key: [isMediaRule(rule) ? 1 : 0].concat(keysOut[i]) }));
|
|
2944
|
+
this.recordAppliedUtilities(entries.filter(e => !e.key[0]).concat(entries.filter(e => e.key[0])), themeCss);
|
|
2787
2945
|
|
|
2788
2946
|
// Save to cache for next page load
|
|
2789
2947
|
const themeHash = this.generateThemeHash(themeCss);
|
|
@@ -2795,6 +2953,8 @@ TailwindCompiler.prototype.compile = async function () {
|
|
|
2795
2953
|
});
|
|
2796
2954
|
this.savePersistentCache();
|
|
2797
2955
|
}
|
|
2956
|
+
} else {
|
|
2957
|
+
this._applied = null; // theme text moved: order keys are stale until the next full write
|
|
2798
2958
|
}
|
|
2799
2959
|
}
|
|
2800
2960
|
|