mnfst 0.5.162 → 0.5.164
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.auth.js +107 -199
- package/lib/manifest.appwrite.data.js +1 -3
- package/lib/manifest.charts.js +88 -97
- package/lib/manifest.chat.js +515 -0
- package/lib/manifest.code.js +110 -340
- package/lib/manifest.colorpicker.js +252 -551
- package/lib/manifest.combobox.js +73 -91
- package/lib/manifest.components.js +34 -95
- package/lib/manifest.css +18 -144
- package/lib/manifest.data.js +189 -562
- package/lib/manifest.datepicker.js +43 -128
- package/lib/manifest.dropdowns.js +18 -39
- package/lib/manifest.export.js +29 -147
- package/lib/manifest.form.css +18 -12
- package/lib/manifest.icons.js +9 -24
- package/lib/manifest.integrity.json +23 -23
- package/lib/manifest.js +62 -126
- package/lib/manifest.localization.js +67 -200
- package/lib/manifest.markdown.js +65 -174
- package/lib/manifest.min.css +1 -1
- package/lib/manifest.payments.js +40 -139
- package/lib/manifest.router.js +24 -73
- package/lib/manifest.status.js +20 -56
- package/lib/manifest.svg.js +12 -30
- package/lib/manifest.tooltips.js +28 -65
- package/lib/manifest.utilities.js +40 -107
- package/lib/manifest.virtual.js +15 -53
- package/package.json +1 -1
- package/lib/manifest.appwrite.presence.js +0 -1650
|
@@ -728,8 +728,7 @@ class TailwindCompiler {
|
|
|
728
728
|
|
|
729
729
|
|
|
730
730
|
|
|
731
|
-
// Synchronous utility generation
|
|
732
|
-
// Methods for generating utilities synchronously before first paint
|
|
731
|
+
// Synchronous utility generation before first paint
|
|
733
732
|
|
|
734
733
|
TailwindCompiler.prototype.addCriticalBlockingStylesSync = function () {
|
|
735
734
|
if (!this.criticalStyleElement) return;
|
|
@@ -737,7 +736,6 @@ TailwindCompiler.prototype.addCriticalBlockingStylesSync = function () {
|
|
|
737
736
|
const syncStart = performance.now();
|
|
738
737
|
|
|
739
738
|
try {
|
|
740
|
-
// Extract CSS variables synchronously from already-loaded sources
|
|
741
739
|
const cssVariables = new Map();
|
|
742
740
|
|
|
743
741
|
// 1. From inline style elements (already in DOM)
|
|
@@ -778,7 +776,7 @@ TailwindCompiler.prototype.addCriticalBlockingStylesSync = function () {
|
|
|
778
776
|
const rules = Array.from(sheet.cssRules || []);
|
|
779
777
|
for (const rule of rules) {
|
|
780
778
|
if (rule.type === CSSRule.STYLE_RULE && rule.styleSheet) {
|
|
781
|
-
//
|
|
779
|
+
// @import rules with nested stylesheets
|
|
782
780
|
try {
|
|
783
781
|
const nestedRules = Array.from(rule.styleSheet.cssRules || []);
|
|
784
782
|
for (const nestedRule of nestedRules) {
|
|
@@ -809,18 +807,10 @@ TailwindCompiler.prototype.addCriticalBlockingStylesSync = function () {
|
|
|
809
807
|
} catch (e) {
|
|
810
808
|
}
|
|
811
809
|
|
|
812
|
-
// 4. From computed styles
|
|
813
|
-
//
|
|
814
|
-
//
|
|
815
|
-
//
|
|
816
|
-
// method 3 (CSSOM cssRules) throws on cross-origin sheets (e.g. the CDN
|
|
817
|
-
// build at cdn.jsdelivr.net). The classic <script> blocks on preceding
|
|
818
|
-
// stylesheets, so :root variables are already resolved here. Skipping
|
|
819
|
-
// this during 'loading' meant a CDN-hosted page captured zero variables
|
|
820
|
-
// synchronously, so the critical "all colors" fallback never ran and
|
|
821
|
-
// variable-derived utilities (bg-line, border-line, …) fell back to
|
|
822
|
-
// currentColor — pure white in dark mode / black in light — until the
|
|
823
|
-
// async compile finished.
|
|
810
|
+
// 4. From computed styles. Runs even during 'loading': getComputedStyle
|
|
811
|
+
// reads the resolved cascade across origins (CDN sheets), which the CSSOM
|
|
812
|
+
// path (method 3) can't — without it CDN pages capture no vars and
|
|
813
|
+
// utilities flash as currentColor.
|
|
824
814
|
try {
|
|
825
815
|
if (document.documentElement) {
|
|
826
816
|
const rootStyles = getComputedStyle(document.documentElement);
|
|
@@ -851,7 +841,6 @@ TailwindCompiler.prototype.addCriticalBlockingStylesSync = function () {
|
|
|
851
841
|
while ((classMatch = classRegex.exec(htmlSource)) !== null) {
|
|
852
842
|
const classes = classMatch[1].split(/\s+/).filter(Boolean);
|
|
853
843
|
for (const cls of classes) {
|
|
854
|
-
// Match utility patterns that might use CSS variables
|
|
855
844
|
if (/^(border|bg|text|ring|outline|decoration|caret|accent|fill|stroke)-[a-z0-9-]+(\/[0-9]+)?$/.test(cls)) {
|
|
856
845
|
classesToGenerate.add(cls);
|
|
857
846
|
}
|
|
@@ -895,7 +884,7 @@ TailwindCompiler.prototype.addCriticalBlockingStylesSync = function () {
|
|
|
895
884
|
variableSuffixes: []
|
|
896
885
|
};
|
|
897
886
|
} else {
|
|
898
|
-
//
|
|
887
|
+
// Fall back to the cache (only generate what was used before)
|
|
899
888
|
const cached = localStorage.getItem('tailwind-cache');
|
|
900
889
|
let cachedClasses = new Set();
|
|
901
890
|
|
|
@@ -904,17 +893,14 @@ TailwindCompiler.prototype.addCriticalBlockingStylesSync = function () {
|
|
|
904
893
|
const parsed = JSON.parse(cached);
|
|
905
894
|
const cacheEntries = Object.values(parsed);
|
|
906
895
|
|
|
907
|
-
// Extract classes from cache keys (format: "class1,class2-themeHash")
|
|
908
896
|
for (const entry of cacheEntries) {
|
|
909
|
-
// Find the cache entry with the most recent timestamp
|
|
910
897
|
const mostRecent = cacheEntries.sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0))[0];
|
|
911
898
|
if (mostRecent && mostRecent.css) {
|
|
912
|
-
// Extract class names from generated CSS
|
|
913
899
|
const classMatches = mostRecent.css.match(/\.([a-zA-Z0-9_-]+(?::[a-zA-Z0-9_-]+)*)\s*{/g);
|
|
914
900
|
if (classMatches) {
|
|
915
901
|
for (const match of classMatches) {
|
|
916
902
|
const className = match.replace(/^\./, '').replace(/\s*{.*$/, '');
|
|
917
|
-
//
|
|
903
|
+
// Utility classes only (not native like red-500)
|
|
918
904
|
if (/^(border|bg|text|ring|outline|decoration|caret|accent|fill|stroke)-[a-z0-9-]+(\/[0-9]+)?$/.test(className.split(':').pop())) {
|
|
919
905
|
cachedClasses.add(className);
|
|
920
906
|
}
|
|
@@ -962,14 +948,12 @@ TailwindCompiler.prototype.addCriticalBlockingStylesSync = function () {
|
|
|
962
948
|
}
|
|
963
949
|
}
|
|
964
950
|
|
|
965
|
-
//
|
|
951
|
+
// No classes found: generate every color-* utility to prevent flash.
|
|
966
952
|
if (!usedData || !usedData.classes || usedData.classes.length === 0) {
|
|
967
|
-
// Generate utilities for all color-* variables to prevent flash
|
|
968
953
|
const colorVars = Array.from(cssVariables.entries())
|
|
969
954
|
.filter(([name]) => name.startsWith('color-'));
|
|
970
955
|
|
|
971
956
|
if (colorVars.length > 0) {
|
|
972
|
-
// Create synthetic classes for all color utilities (text, bg, border)
|
|
973
957
|
const syntheticClasses = [];
|
|
974
958
|
for (const [varName] of colorVars) {
|
|
975
959
|
const suffix = varName.replace('color-', '');
|
|
@@ -1046,16 +1030,12 @@ TailwindCompiler.prototype.generateSynchronousUtilities = function () {
|
|
|
1046
1030
|
// Ignore parsing errors
|
|
1047
1031
|
}
|
|
1048
1032
|
|
|
1049
|
-
// Method 3:
|
|
1050
|
-
//
|
|
1051
|
-
//
|
|
1052
|
-
// methods above cannot read. See addCriticalBlockingStylesSync for the
|
|
1053
|
-
// full rationale: without this, CDN-hosted pages capture no variables
|
|
1054
|
-
// synchronously and variable-derived utilities flash as currentColor.
|
|
1033
|
+
// Method 3: Computed styles from :root. Runs even during 'loading' —
|
|
1034
|
+
// resolves cross-origin (CDN) vars the CSSOM methods can't; see
|
|
1035
|
+
// addCriticalBlockingStylesSync.
|
|
1055
1036
|
try {
|
|
1056
1037
|
if (document.documentElement) {
|
|
1057
1038
|
const rootStyles = getComputedStyle(document.documentElement);
|
|
1058
|
-
// Extract all CSS variables, not just color ones
|
|
1059
1039
|
const allProps = rootStyles.length;
|
|
1060
1040
|
for (let i = 0; i < allProps; i++) {
|
|
1061
1041
|
const prop = rootStyles[i];
|
|
@@ -1074,14 +1054,12 @@ TailwindCompiler.prototype.generateSynchronousUtilities = function () {
|
|
|
1074
1054
|
// Method 4: Scan HTML source directly for class attributes
|
|
1075
1055
|
try {
|
|
1076
1056
|
const htmlSource = document.documentElement.outerHTML;
|
|
1077
|
-
// Extract all class attributes from HTML source
|
|
1078
1057
|
const classRegex = /class=["']([^"']+)["']/gi;
|
|
1079
1058
|
let classMatch;
|
|
1080
1059
|
while ((classMatch = classRegex.exec(htmlSource)) !== null) {
|
|
1081
1060
|
const classString = classMatch[1];
|
|
1082
1061
|
const classes = classString.split(/\s+/).filter(Boolean);
|
|
1083
1062
|
for (const cls of classes) {
|
|
1084
|
-
// Match common color utility patterns (more comprehensive)
|
|
1085
1063
|
if (/^(border|bg|text|ring|outline|decoration|caret|accent|fill|stroke)-[a-z0-9-]+(\/[0-9]+)?$/.test(cls)) {
|
|
1086
1064
|
commonColorClasses.add(cls);
|
|
1087
1065
|
}
|
|
@@ -2430,8 +2408,7 @@ TailwindCompiler.prototype.parseClassName = function (className) {
|
|
|
2430
2408
|
|
|
2431
2409
|
|
|
2432
2410
|
|
|
2433
|
-
// Compilation
|
|
2434
|
-
// Main compilation logic and utility generation
|
|
2411
|
+
// Compilation logic and utility generation
|
|
2435
2412
|
|
|
2436
2413
|
// Generate utilities from CSS variables
|
|
2437
2414
|
TailwindCompiler.prototype.generateUtilitiesFromVars = function (cssText, usedData) {
|
|
@@ -2579,16 +2556,10 @@ TailwindCompiler.prototype.generateUtilitiesFromVars = function (cssText, usedDa
|
|
|
2579
2556
|
generateUtility(className, css);
|
|
2580
2557
|
}
|
|
2581
2558
|
|
|
2582
|
-
//
|
|
2583
|
-
//
|
|
2584
|
-
//
|
|
2585
|
-
//
|
|
2586
|
-
// trailing segment after the last `:`, so passing it the bare base
|
|
2587
|
-
// lets its variant loop emit the correct selector
|
|
2588
|
-
// (`.backdrop\:bg-black\/10::backdrop`). Passing the prefixed class
|
|
2589
|
-
// instead made generateUtility treat it as a plain base class and
|
|
2590
|
-
// emit a malformed `.backdrop\:bg-black\/10 { … }` rule with no
|
|
2591
|
-
// `::backdrop` pseudo-element.
|
|
2559
|
+
// Opacity variants: collect the bare base (e.g. `bg-black/10`),
|
|
2560
|
+
// not the prefixed class — generateUtility discovers variant
|
|
2561
|
+
// prefixes itself, so passing the bare base emits the correct
|
|
2562
|
+
// selector (`.backdrop\:bg-black\/10::backdrop`).
|
|
2592
2563
|
const opacityBaseClasses = new Set();
|
|
2593
2564
|
for (const cls of usedClasses) {
|
|
2594
2565
|
// Parse the class to extract the base utility name
|
|
@@ -2648,16 +2619,9 @@ TailwindCompiler.prototype.generateCustomUtilities = function (usedData) {
|
|
|
2648
2619
|
return className.replace(/[^a-zA-Z0-9-]/g, '\\$&');
|
|
2649
2620
|
};
|
|
2650
2621
|
|
|
2651
|
-
//
|
|
2652
|
-
//
|
|
2653
|
-
// The & should remain as-is so CSS nesting works correctly
|
|
2654
|
-
// This function should only be used for legacy/flattened CSS, not nested CSS
|
|
2622
|
+
// Replace & in selectors — legacy/flattened CSS only; nested CSS keeps &
|
|
2623
|
+
// as-is so native nesting works.
|
|
2655
2624
|
const replaceAmpersandInSelectors = (cssText, replacement) => {
|
|
2656
|
-
// For full blocks with nested rules, don't replace & at all - preserve CSS nesting
|
|
2657
|
-
// Check if this looks like nested CSS:
|
|
2658
|
-
// - Has & followed by :, ., [, or whitespace then { (nested selector)
|
|
2659
|
-
// - Has ] & (attribute selector followed by &, like [dir=rtl] &)
|
|
2660
|
-
// - Has & on its own line followed by :, ., or [ (common nested pattern)
|
|
2661
2625
|
const hasNestedSelectors =
|
|
2662
2626
|
/&\s*[:\.\[{]/.test(cssText) || // &:not(), &::before, &[attr], & {
|
|
2663
2627
|
/&\s*\n\s*[:\.\[{]/.test(cssText) || // & on new line followed by selector
|
|
@@ -3192,13 +3156,9 @@ TailwindCompiler.prototype.compile = async function () {
|
|
|
3192
3156
|
// Fetch CSS content once for initial compilation
|
|
3193
3157
|
const themeCss = await this.fetchThemeContent();
|
|
3194
3158
|
if (themeCss) {
|
|
3195
|
-
// Extract
|
|
3196
|
-
//
|
|
3197
|
-
//
|
|
3198
|
-
// variants (e.g. md:row, hover:brand). Base-form re-emission is
|
|
3199
|
-
// suppressed in generateCustomUtilities ("Skip generating base
|
|
3200
|
-
// utility - it already exists in the CSS"); duplicate captures
|
|
3201
|
-
// are collapsed at the end of extractCustomUtilities.
|
|
3159
|
+
// Extract custom utilities. Framework CSS is scanned too so the
|
|
3160
|
+
// generator can emit variants of semantic classes (md:row,
|
|
3161
|
+
// hover:brand); base forms are suppressed in generateCustomUtilities.
|
|
3202
3162
|
const discoveredCustomUtilities = this.extractCustomUtilities(themeCss);
|
|
3203
3163
|
for (const [name, value] of discoveredCustomUtilities.entries()) {
|
|
3204
3164
|
this.customUtilities.set(name, value);
|
|
@@ -3357,25 +3317,19 @@ TailwindCompiler.prototype.compile = async function () {
|
|
|
3357
3317
|
|
|
3358
3318
|
|
|
3359
3319
|
|
|
3360
|
-
// DOM observation and
|
|
3361
|
-
// Methods for watching DOM changes and triggering recompilation
|
|
3320
|
+
// DOM observation: watch for changes and trigger recompilation
|
|
3362
3321
|
|
|
3363
3322
|
// Setup component load listener and MutationObserver
|
|
3364
3323
|
TailwindCompiler.prototype.setupComponentLoadListener = function () {
|
|
3365
|
-
// Use a single debounced handler for all component-related events
|
|
3366
3324
|
const debouncedCompile = this.debounce(() => {
|
|
3367
3325
|
if (!this.isCompiling) {
|
|
3368
3326
|
this.compile();
|
|
3369
3327
|
}
|
|
3370
3328
|
}, this.options.debounceTime);
|
|
3371
3329
|
|
|
3372
|
-
//
|
|
3373
|
-
// Support both old (manifest) and new (manifest) event names for compatibility
|
|
3330
|
+
// Recompile when components load/process; re-scan so component HTML is covered.
|
|
3374
3331
|
const handleComponentEvent = () => {
|
|
3375
|
-
// If we haven't scanned static classes yet, trigger a full re-scan
|
|
3376
|
-
// This ensures component HTML files are scanned for utility classes
|
|
3377
3332
|
if (!this.hasScannedStatic) {
|
|
3378
|
-
// Reset the scan promise to allow re-scanning
|
|
3379
3333
|
this.staticScanPromise = null;
|
|
3380
3334
|
this.hasScannedStatic = false;
|
|
3381
3335
|
}
|
|
@@ -3389,12 +3343,9 @@ TailwindCompiler.prototype.setupComponentLoadListener = function () {
|
|
|
3389
3343
|
document.addEventListener('manifest:components-processed', handleComponentEvent);
|
|
3390
3344
|
document.addEventListener('manifest:components-ready', handleComponentEvent);
|
|
3391
3345
|
|
|
3392
|
-
//
|
|
3346
|
+
// On route change, recompile only if genuinely new dynamic classes appeared.
|
|
3393
3347
|
document.addEventListener('manifest:route-change', (event) => {
|
|
3394
|
-
// Only trigger compilation if we detect new dynamic classes
|
|
3395
|
-
// The existing MutationObserver will handle actual DOM changes
|
|
3396
3348
|
if (this.hasScannedStatic) {
|
|
3397
|
-
// Wait longer for route content to fully load before checking
|
|
3398
3349
|
setTimeout(() => {
|
|
3399
3350
|
const currentDynamicCount = this.dynamicClassCache.size;
|
|
3400
3351
|
const currentClassesHash = this.lastClassesHash;
|
|
@@ -3405,10 +3356,9 @@ TailwindCompiler.prototype.setupComponentLoadListener = function () {
|
|
|
3405
3356
|
const dynamicClasses = Array.from(this.dynamicClassCache);
|
|
3406
3357
|
const newClassesHash = dynamicClasses.sort().join(',');
|
|
3407
3358
|
|
|
3408
|
-
// Only compile if we found genuinely new classes, not just code processing artifacts
|
|
3409
3359
|
if (newDynamicCount > currentDynamicCount && newClassesHash !== currentClassesHash) {
|
|
3410
3360
|
const newClasses = dynamicClasses.filter(cls =>
|
|
3411
|
-
//
|
|
3361
|
+
// Ignore highlight/code-processing artifacts
|
|
3412
3362
|
!cls.includes('hljs') &&
|
|
3413
3363
|
!cls.startsWith('language-') &&
|
|
3414
3364
|
!cls.includes('copy') &&
|
|
@@ -3419,11 +3369,11 @@ TailwindCompiler.prototype.setupComponentLoadListener = function () {
|
|
|
3419
3369
|
debouncedCompile();
|
|
3420
3370
|
}
|
|
3421
3371
|
}
|
|
3422
|
-
}, 300); //
|
|
3372
|
+
}, 300); // let code processing finish
|
|
3423
3373
|
}
|
|
3424
3374
|
});
|
|
3425
3375
|
|
|
3426
|
-
//
|
|
3376
|
+
// Single MutationObserver for all DOM changes
|
|
3427
3377
|
const observer = new MutationObserver((mutations) => {
|
|
3428
3378
|
let shouldRecompile = false;
|
|
3429
3379
|
|
|
@@ -3510,15 +3460,10 @@ TailwindCompiler.prototype.setupComponentLoadListener = function () {
|
|
|
3510
3460
|
});
|
|
3511
3461
|
};
|
|
3512
3462
|
|
|
3513
|
-
//
|
|
3514
|
-
// setupComponentLoadListener (
|
|
3515
|
-
//
|
|
3516
|
-
//
|
|
3517
|
-
// own MutationObserver here that called getUsedClasses() on EVERY mutation
|
|
3518
|
-
// (a full document-wide O(N) DOM scan), so on a busy page with N≥3000 the
|
|
3519
|
-
// scan cost exceeded the inter-mutation interval and the main thread froze
|
|
3520
|
-
// (~100% CPU on docs site, 3042 elements). That observer was redundant with
|
|
3521
|
-
// the incremental one and has been removed.
|
|
3463
|
+
// Initial compilation only. DOM observation is owned by
|
|
3464
|
+
// setupComponentLoadListener (incremental, scales to thousands of elements);
|
|
3465
|
+
// don't add a per-mutation getUsedClasses() scan here — it froze the main
|
|
3466
|
+
// thread on busy pages.
|
|
3522
3467
|
TailwindCompiler.prototype.startProcessing = async function () {
|
|
3523
3468
|
if (this.usesStaticPrerenderUtilities) return;
|
|
3524
3469
|
try {
|
|
@@ -3531,15 +3476,11 @@ TailwindCompiler.prototype.startProcessing = async function () {
|
|
|
3531
3476
|
|
|
3532
3477
|
|
|
3533
3478
|
|
|
3534
|
-
// Utilities initialization
|
|
3535
|
-
// Initialize compiler and set up event listeners
|
|
3479
|
+
// Utilities initialization: create compiler, set up event listeners
|
|
3536
3480
|
|
|
3537
|
-
//
|
|
3538
|
-
// (
|
|
3539
|
-
//
|
|
3540
|
-
// minimum required. Runs synchronously at script load (documentElement exists
|
|
3541
|
-
// during head parsing) to set the marker before first paint. Honors a value
|
|
3542
|
-
// already present (e.g. written by the prerenderer or set manually).
|
|
3481
|
+
// Stamp <html data-os> so OS variants (mac:, ios:, …) resolve in pure CSS
|
|
3482
|
+
// (no CSS media feature for OS). Runs synchronously before first paint;
|
|
3483
|
+
// honors an existing value (prerenderer or manual).
|
|
3543
3484
|
function detectOS() {
|
|
3544
3485
|
try {
|
|
3545
3486
|
const html = document.documentElement;
|
|
@@ -3561,13 +3502,9 @@ function detectOS() {
|
|
|
3561
3502
|
}
|
|
3562
3503
|
detectOS();
|
|
3563
3504
|
|
|
3564
|
-
//
|
|
3565
|
-
//
|
|
3566
|
-
//
|
|
3567
|
-
// engine, which only knows its built-in variants. A `<style type="text/tailwindcss">`
|
|
3568
|
-
// carrying @custom-variant definitions teaches Tailwind the same variants, so
|
|
3569
|
-
// touch:px-4 / mac:flex / cursor:gap-2 resolve like sm:/hover:. Tailwind's
|
|
3570
|
-
// browser build reprocesses when this style is added, so load order is moot.
|
|
3505
|
+
// Teach Tailwind the same device/OS variants via @custom-variant so its own
|
|
3506
|
+
// utilities (px-4, flex) get touch:/mac:/cursor: like sm:/hover: — the Manifest
|
|
3507
|
+
// compiler only applies them to its own utilities.
|
|
3571
3508
|
function injectTailwindVariants() {
|
|
3572
3509
|
try {
|
|
3573
3510
|
if (document.getElementById('manifest-tailwind-variants')) return;
|
|
@@ -3598,16 +3535,12 @@ const compiler = new TailwindCompiler();
|
|
|
3598
3535
|
// Expose utilities compiler for optional integration
|
|
3599
3536
|
window.ManifestUtilities = compiler;
|
|
3600
3537
|
|
|
3601
|
-
// Log when DOM is ready
|
|
3602
3538
|
if (document.readyState === 'loading') {
|
|
3603
3539
|
document.addEventListener('DOMContentLoaded', () => {
|
|
3604
|
-
// DOM ready
|
|
3605
3540
|
});
|
|
3606
3541
|
} else {
|
|
3607
|
-
// DOM already ready
|
|
3608
3542
|
}
|
|
3609
3543
|
|
|
3610
|
-
// Log first paint if available
|
|
3611
3544
|
if ('PerformanceObserver' in window) {
|
|
3612
3545
|
try {
|
|
3613
3546
|
const paintObserver = new PerformanceObserver((list) => {
|
|
@@ -3620,7 +3553,7 @@ if ('PerformanceObserver' in window) {
|
|
|
3620
3553
|
}
|
|
3621
3554
|
}
|
|
3622
3555
|
|
|
3623
|
-
//
|
|
3556
|
+
// Recompile on DOMContentLoaded for late-added elements
|
|
3624
3557
|
document.addEventListener('DOMContentLoaded', () => {
|
|
3625
3558
|
if (!compiler.usesStaticPrerenderUtilities && !compiler.isCompiling) {
|
|
3626
3559
|
compiler.compile();
|
package/lib/manifest.virtual.js
CHANGED
|
@@ -1,44 +1,11 @@
|
|
|
1
|
-
/* Manifest Virtual — in-flow list/table/grid/gallery virtualization for Alpine.
|
|
1
|
+
/* Manifest Virtual — in-flow list/table/grid/gallery/masonry virtualization for Alpine.
|
|
2
2
|
*
|
|
3
|
-
* Renders only
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Usage — wrap an x-for template in the scrolling container:
|
|
10
|
-
*
|
|
11
|
-
* <div x-virtual style="height: 600px; overflow: auto">
|
|
12
|
-
* <template x-for="row in $x.customers" :key="row.id">
|
|
13
|
-
* <div class="grid-row"> … cells … </div>
|
|
14
|
-
* </template>
|
|
15
|
-
* </div>
|
|
16
|
-
*
|
|
17
|
-
* The template may be nested (e.g. inside <table><tbody>); the plugin finds it
|
|
18
|
-
* and hosts spacers/rows in its parent.
|
|
19
|
-
*
|
|
20
|
-
* Options (object expression on the directive):
|
|
21
|
-
*
|
|
22
|
-
* estimate Initial per-row height in px (default 50), or { width, height }
|
|
23
|
-
* for galleries. Used for unmeasured rows; closer = less drift.
|
|
24
|
-
* overscan Rows/lines to render above/below the window (default 3).
|
|
25
|
-
* mode 'rows' | 'gallery' | 'masonry'. Auto-detected if omitted
|
|
26
|
-
* (masonry must be set explicitly).
|
|
27
|
-
*
|
|
28
|
-
* Modes (how items fill lines — the spacer element is auto-detected separately):
|
|
29
|
-
* rows — one item per line: stacked lists, native <table>, and
|
|
30
|
-
* .grid-table. The spacer is a div, a <tr>, or a grid cell
|
|
31
|
-
* depending on the container.
|
|
32
|
-
* gallery — many items per line (flex-wrap); items pack N per line and
|
|
33
|
-
* whole lines render so flex sizing stays correct. Ragged
|
|
34
|
-
* width + height supported.
|
|
35
|
-
* masonry — independent-size items packed into the shortest column
|
|
36
|
-
* (absolute positioning); set explicitly with mode: 'masonry'.
|
|
37
|
-
*
|
|
38
|
-
* Notes:
|
|
39
|
-
* - Column widths should be content-independent (table-layout: fixed, fixed/%
|
|
40
|
-
* grid tracks) or columns shift as the window changes. Stripe by data index,
|
|
41
|
-
* not :nth-child. See the docs for these table caveats.
|
|
3
|
+
* Renders only rows in the viewport (plus overscan). Line modes keep rows in NORMAL
|
|
4
|
+
* FLOW between top/bottom spacers standing in for off-window rows, so the same markup
|
|
5
|
+
* works virtualized or not and shared columns/sticky/flex-wrap behave normally;
|
|
6
|
+
* masonry positions absolutely. Options: estimate (px or {width,height}), overscan,
|
|
7
|
+
* mode ('rows'|'gallery'|'masonry'; masonry must be explicit, others auto-detect).
|
|
8
|
+
* Column widths must be content-independent or columns shift as the window changes.
|
|
42
9
|
*/
|
|
43
10
|
|
|
44
11
|
function initializeVirtualPlugin() {
|
|
@@ -48,8 +15,7 @@ function initializeVirtualPlugin() {
|
|
|
48
15
|
// --- Find the template (may be nested, e.g. table > tbody > template) ---
|
|
49
16
|
const template = el.querySelector('template[x-for]') || el.querySelector(':scope template');
|
|
50
17
|
if (!template || !template.getAttribute('x-for')) {
|
|
51
|
-
//
|
|
52
|
-
// stripped on the first pass); only warn on genuine misuse.
|
|
18
|
+
// Quiet on re-init of an already-virtualized container (x-for stripped first pass).
|
|
53
19
|
if (!el.querySelector('[data-virtual-spacer]')) {
|
|
54
20
|
console.warn('[x-virtual] expects a descendant <template> with x-for, e.g. <template x-for="row in $x.items" :key="row.id">…');
|
|
55
21
|
}
|
|
@@ -65,8 +31,7 @@ function initializeVirtualPlugin() {
|
|
|
65
31
|
const sourceExpr = m[2].trim();
|
|
66
32
|
const keyExpr = template.getAttribute(':key') || template.getAttribute('x-bind:key') || `${itemName}.id`;
|
|
67
33
|
|
|
68
|
-
// Strip x-for/:key so Alpine
|
|
69
|
-
// template in the DOM as our clone source.
|
|
34
|
+
// Strip x-for/:key so Alpine won't render the full list; keep the template as clone source.
|
|
70
35
|
template.removeAttribute('x-for');
|
|
71
36
|
template.removeAttribute(':key');
|
|
72
37
|
template.removeAttribute('x-bind:key');
|
|
@@ -89,9 +54,8 @@ function initializeVirtualPlugin() {
|
|
|
89
54
|
const isGallery = mode === 'gallery';
|
|
90
55
|
const isMasonry = mode === 'masonry';
|
|
91
56
|
|
|
92
|
-
// Masonry
|
|
93
|
-
//
|
|
94
|
-
// settling; `gap` px (falls back to CSS gap).
|
|
57
|
+
// Masonry: fixed `columns` or target `columnWidth`; optional per-item `span`/
|
|
58
|
+
// `height` fns from data for ~zero settling; `gap` px (falls back to CSS gap).
|
|
95
59
|
const colsOpt = Number(options.columns) > 0 ? Math.floor(options.columns) : 0;
|
|
96
60
|
const colWidthOpt = Number(options.columnWidth) > 0 ? Number(options.columnWidth) : 0;
|
|
97
61
|
const spanFn = typeof options.span === 'function' ? options.span : null;
|
|
@@ -147,9 +111,8 @@ function initializeVirtualPlugin() {
|
|
|
147
111
|
else rebuildSingle();
|
|
148
112
|
}
|
|
149
113
|
|
|
150
|
-
// Skyline packer: place each item in the column band
|
|
151
|
-
//
|
|
152
|
-
// order — so the whole layout is computed here in JS, no rendering.
|
|
114
|
+
// Skyline packer: place each item in the `span`-wide column band with the lowest
|
|
115
|
+
// top. Positions depend only on order, so the whole layout is computed in JS.
|
|
153
116
|
function rebuildMasonry() {
|
|
154
117
|
const cw = contentWidth();
|
|
155
118
|
const g = masonryGap;
|
|
@@ -279,8 +242,8 @@ function initializeVirtualPlugin() {
|
|
|
279
242
|
scheduleMeasure(keys);
|
|
280
243
|
}
|
|
281
244
|
|
|
282
|
-
// Masonry: render items whose packed box intersects the viewport,
|
|
283
|
-
// absolutely
|
|
245
|
+
// Masonry: render items whose packed box intersects the viewport, positioned
|
|
246
|
+
// absolutely at their computed (x, y, w).
|
|
284
247
|
function renderMasonry() {
|
|
285
248
|
if (!data.length) { clearRows(); sizer.style.height = '0px'; return; }
|
|
286
249
|
const vh = scrollEl.clientHeight;
|
|
@@ -532,7 +495,6 @@ function buildKeyFn(itemName, keyExpr) {
|
|
|
532
495
|
}
|
|
533
496
|
}
|
|
534
497
|
|
|
535
|
-
// Track initialization to prevent duplicates
|
|
536
498
|
let virtualPluginInitialized = false;
|
|
537
499
|
|
|
538
500
|
function ensureVirtualPluginInitialized() {
|