@sc4rfurryx/proteusjs 1.0.0
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/API.md +438 -0
- package/FEATURES.md +286 -0
- package/LICENSE +21 -0
- package/README.md +645 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/proteus.cjs.js +16014 -0
- package/dist/proteus.cjs.js.map +1 -0
- package/dist/proteus.d.ts +3018 -0
- package/dist/proteus.esm.js +16005 -0
- package/dist/proteus.esm.js.map +1 -0
- package/dist/proteus.esm.min.js +8 -0
- package/dist/proteus.esm.min.js.map +1 -0
- package/dist/proteus.js +16020 -0
- package/dist/proteus.js.map +1 -0
- package/dist/proteus.min.js +8 -0
- package/dist/proteus.min.js.map +1 -0
- package/package.json +98 -0
- package/src/__tests__/mvp-integration.test.ts +518 -0
- package/src/accessibility/AccessibilityEngine.ts +2106 -0
- package/src/accessibility/ScreenReaderSupport.ts +444 -0
- package/src/accessibility/__tests__/ScreenReaderSupport.test.ts +435 -0
- package/src/animations/FLIPAnimationSystem.ts +491 -0
- package/src/compatibility/BrowserCompatibility.ts +1076 -0
- package/src/containers/BreakpointSystem.ts +347 -0
- package/src/containers/ContainerBreakpoints.ts +726 -0
- package/src/containers/ContainerManager.ts +370 -0
- package/src/containers/ContainerUnits.ts +336 -0
- package/src/containers/ContextIsolation.ts +394 -0
- package/src/containers/ElementQueries.ts +411 -0
- package/src/containers/SmartContainer.ts +536 -0
- package/src/containers/SmartContainers.ts +376 -0
- package/src/containers/__tests__/ContainerBreakpoints.test.ts +411 -0
- package/src/containers/__tests__/SmartContainers.test.ts +281 -0
- package/src/content/ResponsiveImages.ts +570 -0
- package/src/core/EventSystem.ts +147 -0
- package/src/core/MemoryManager.ts +321 -0
- package/src/core/PerformanceMonitor.ts +238 -0
- package/src/core/PluginSystem.ts +275 -0
- package/src/core/ProteusJS.test.ts +164 -0
- package/src/core/ProteusJS.ts +962 -0
- package/src/developer/PerformanceProfiler.ts +567 -0
- package/src/developer/VisualDebuggingTools.ts +656 -0
- package/src/developer/ZeroConfigSystem.ts +593 -0
- package/src/index.ts +35 -0
- package/src/integration.test.ts +227 -0
- package/src/layout/AdaptiveGrid.ts +429 -0
- package/src/layout/ContentReordering.ts +532 -0
- package/src/layout/FlexboxEnhancer.ts +406 -0
- package/src/layout/FlowLayout.ts +545 -0
- package/src/layout/SpacingSystem.ts +512 -0
- package/src/observers/IntersectionObserverPolyfill.ts +289 -0
- package/src/observers/ObserverManager.ts +299 -0
- package/src/observers/ResizeObserverPolyfill.ts +179 -0
- package/src/performance/BatchDOMOperations.ts +519 -0
- package/src/performance/CSSOptimizationEngine.ts +646 -0
- package/src/performance/CacheOptimizationSystem.ts +601 -0
- package/src/performance/EfficientEventHandler.ts +740 -0
- package/src/performance/LazyEvaluationSystem.ts +532 -0
- package/src/performance/MemoryManagementSystem.ts +497 -0
- package/src/performance/PerformanceMonitor.ts +931 -0
- package/src/performance/__tests__/BatchDOMOperations.test.ts +309 -0
- package/src/performance/__tests__/EfficientEventHandler.test.ts +268 -0
- package/src/performance/__tests__/PerformanceMonitor.test.ts +422 -0
- package/src/polyfills/BrowserPolyfills.ts +586 -0
- package/src/polyfills/__tests__/BrowserPolyfills.test.ts +328 -0
- package/src/test/setup.ts +115 -0
- package/src/theming/SmartThemeSystem.ts +591 -0
- package/src/types/index.ts +134 -0
- package/src/typography/ClampScaling.ts +356 -0
- package/src/typography/FluidTypography.ts +759 -0
- package/src/typography/LineHeightOptimization.ts +430 -0
- package/src/typography/LineHeightOptimizer.ts +326 -0
- package/src/typography/TextFitting.ts +355 -0
- package/src/typography/TypographicScale.ts +428 -0
- package/src/typography/VerticalRhythm.ts +369 -0
- package/src/typography/__tests__/FluidTypography.test.ts +432 -0
- package/src/typography/__tests__/LineHeightOptimization.test.ts +436 -0
- package/src/utils/Logger.ts +173 -0
- package/src/utils/debounce.ts +259 -0
- package/src/utils/performance.ts +371 -0
- package/src/utils/support.ts +106 -0
- package/src/utils/version.ts +24 -0
@@ -0,0 +1,962 @@
|
|
1
|
+
/**
|
2
|
+
* ProteusJS - Main library class
|
3
|
+
* Shape-shifting responsive design that adapts like the sea god himself
|
4
|
+
*/
|
5
|
+
|
6
|
+
import type { ProteusConfig, TypographyConfig, LayoutConfig, AccessibilityConfig } from '../types';
|
7
|
+
import type { ContainerOptions } from '../containers/SmartContainer';
|
8
|
+
import type { SmartContainer } from '../containers/SmartContainer';
|
9
|
+
import type { ScalingConfig } from '../typography/ClampScaling';
|
10
|
+
import type { ScaleConfig, TypeScale } from '../typography/TypographicScale';
|
11
|
+
import type { GridConfig } from '../layout/AdaptiveGrid';
|
12
|
+
import { logger } from '../utils/Logger';
|
13
|
+
import { EventSystem } from './EventSystem';
|
14
|
+
import { PluginSystem } from './PluginSystem';
|
15
|
+
|
16
|
+
import { MemoryManager } from './MemoryManager';
|
17
|
+
import { ObserverManager } from '../observers/ObserverManager';
|
18
|
+
import { ContainerManager } from '../containers/ContainerManager';
|
19
|
+
import { ClampScaling } from '../typography/ClampScaling';
|
20
|
+
import { TypographicScale } from '../typography/TypographicScale';
|
21
|
+
import { TextFitting } from '../typography/TextFitting';
|
22
|
+
import { LineHeightOptimizer } from '../typography/LineHeightOptimizer';
|
23
|
+
import { VerticalRhythm } from '../typography/VerticalRhythm';
|
24
|
+
import { AdaptiveGrid } from '../layout/AdaptiveGrid';
|
25
|
+
import { FlexboxEnhancer } from '../layout/FlexboxEnhancer';
|
26
|
+
import { FlowLayout } from '../layout/FlowLayout';
|
27
|
+
import { SpacingSystem } from '../layout/SpacingSystem';
|
28
|
+
import { ContentReordering } from '../layout/ContentReordering';
|
29
|
+
import { ResponsiveImages } from '../content/ResponsiveImages';
|
30
|
+
import { AccessibilityEngine } from '../accessibility/AccessibilityEngine';
|
31
|
+
import { EfficientEventHandler } from '../performance/EfficientEventHandler';
|
32
|
+
import { FluidTypography } from '../typography/FluidTypography';
|
33
|
+
import { ContainerBreakpoints } from '../containers/ContainerBreakpoints';
|
34
|
+
import { BrowserCompatibility } from '../compatibility/BrowserCompatibility';
|
35
|
+
import { PerformanceMonitor } from '../performance/PerformanceMonitor';
|
36
|
+
import { BatchDOMOperations } from '../performance/BatchDOMOperations';
|
37
|
+
import { LazyEvaluationSystem } from '../performance/LazyEvaluationSystem';
|
38
|
+
import { CSSOptimizationEngine } from '../performance/CSSOptimizationEngine';
|
39
|
+
import { MemoryManagementSystem } from '../performance/MemoryManagementSystem';
|
40
|
+
import { CacheOptimizationSystem } from '../performance/CacheOptimizationSystem';
|
41
|
+
import { SmartThemeSystem } from '../theming/SmartThemeSystem';
|
42
|
+
import { FLIPAnimationSystem, MicroInteractions, ScrollAnimations } from '../animations/FLIPAnimationSystem';
|
43
|
+
import { ZeroConfigSystem } from '../developer/ZeroConfigSystem';
|
44
|
+
import { BrowserPolyfills } from '../polyfills/BrowserPolyfills';
|
45
|
+
import { getSupportInfo, isSupported } from '../utils/support';
|
46
|
+
import { version } from '../utils/version';
|
47
|
+
|
48
|
+
export class ProteusJS {
|
49
|
+
private static instance: ProteusJS | null = null;
|
50
|
+
private config!: Required<ProteusConfig>;
|
51
|
+
private eventSystem!: EventSystem;
|
52
|
+
private pluginSystem!: PluginSystem;
|
53
|
+
private performanceMonitor!: PerformanceMonitor;
|
54
|
+
private memoryManager!: MemoryManager;
|
55
|
+
private observerManager!: ObserverManager;
|
56
|
+
private containerManager!: ContainerManager;
|
57
|
+
private clampScaling!: ClampScaling;
|
58
|
+
private typographicScale!: TypographicScale;
|
59
|
+
private textFitting!: TextFitting;
|
60
|
+
private lineHeightOptimizer!: LineHeightOptimizer;
|
61
|
+
private verticalRhythm!: VerticalRhythm;
|
62
|
+
private eventHandler!: EfficientEventHandler;
|
63
|
+
private batchDOM!: BatchDOMOperations;
|
64
|
+
private lazyEvaluation!: LazyEvaluationSystem;
|
65
|
+
private cssOptimizer!: CSSOptimizationEngine;
|
66
|
+
private themeSystem!: SmartThemeSystem;
|
67
|
+
private flipAnimations!: FLIPAnimationSystem;
|
68
|
+
private scrollAnimations!: ScrollAnimations;
|
69
|
+
private memoryManagement!: MemoryManagementSystem;
|
70
|
+
private cacheOptimization!: CacheOptimizationSystem;
|
71
|
+
private zeroConfig!: ZeroConfigSystem;
|
72
|
+
private browserPolyfills!: BrowserPolyfills;
|
73
|
+
private fluidTypography!: FluidTypography;
|
74
|
+
private containerBreakpoints!: ContainerBreakpoints;
|
75
|
+
private accessibilityEngine!: AccessibilityEngine;
|
76
|
+
private browserCompatibility!: BrowserCompatibility;
|
77
|
+
private initialized: boolean = false;
|
78
|
+
|
79
|
+
constructor(config: ProteusConfig = {}) {
|
80
|
+
// Singleton pattern to ensure only one instance
|
81
|
+
if (ProteusJS.instance) {
|
82
|
+
return ProteusJS.instance;
|
83
|
+
}
|
84
|
+
|
85
|
+
this.config = this.mergeConfig(config);
|
86
|
+
this.eventSystem = new EventSystem();
|
87
|
+
this.pluginSystem = new PluginSystem(this);
|
88
|
+
|
89
|
+
this.memoryManager = new MemoryManager();
|
90
|
+
this.observerManager = new ObserverManager();
|
91
|
+
this.containerManager = new ContainerManager(
|
92
|
+
this.config.containers,
|
93
|
+
this.observerManager,
|
94
|
+
this.memoryManager,
|
95
|
+
this.eventSystem
|
96
|
+
);
|
97
|
+
this.clampScaling = new ClampScaling();
|
98
|
+
this.typographicScale = new TypographicScale();
|
99
|
+
this.textFitting = new TextFitting();
|
100
|
+
this.lineHeightOptimizer = new LineHeightOptimizer();
|
101
|
+
this.verticalRhythm = new VerticalRhythm({
|
102
|
+
baseFontSize: 16,
|
103
|
+
baseLineHeight: 1.5,
|
104
|
+
baselineUnit: 24,
|
105
|
+
scale: 'minor-third',
|
106
|
+
precision: 0.001,
|
107
|
+
responsive: true,
|
108
|
+
containerAware: true
|
109
|
+
});
|
110
|
+
this.eventHandler = new EfficientEventHandler({
|
111
|
+
debounceDelay: 16,
|
112
|
+
useRAF: true,
|
113
|
+
batchOperations: true,
|
114
|
+
performanceTarget: 16.67
|
115
|
+
});
|
116
|
+
this.batchDOM = new BatchDOMOperations({
|
117
|
+
maxBatchSize: 50,
|
118
|
+
separateReadWrite: true,
|
119
|
+
autoFlush: true
|
120
|
+
});
|
121
|
+
this.lazyEvaluation = new LazyEvaluationSystem({
|
122
|
+
useIdleCallback: true,
|
123
|
+
progressiveEnhancement: true,
|
124
|
+
cacheResults: true
|
125
|
+
});
|
126
|
+
this.cssOptimizer = new CSSOptimizationEngine({
|
127
|
+
deduplication: true,
|
128
|
+
criticalCSS: true,
|
129
|
+
unusedStyleRemoval: true
|
130
|
+
});
|
131
|
+
this.themeSystem = new SmartThemeSystem({
|
132
|
+
autoDetect: true,
|
133
|
+
respectSystemPreference: true,
|
134
|
+
adaptiveContrast: true
|
135
|
+
});
|
136
|
+
this.flipAnimations = new FLIPAnimationSystem({
|
137
|
+
respectMotionPreference: true,
|
138
|
+
batchAnimations: true
|
139
|
+
});
|
140
|
+
this.scrollAnimations = new ScrollAnimations();
|
141
|
+
this.memoryManagement = new MemoryManagementSystem({
|
142
|
+
autoCleanup: true,
|
143
|
+
leakDetection: true
|
144
|
+
});
|
145
|
+
this.cacheOptimization = new CacheOptimizationSystem({
|
146
|
+
maxSize: 100,
|
147
|
+
evictionStrategy: 'adaptive'
|
148
|
+
});
|
149
|
+
this.zeroConfig = new ZeroConfigSystem({
|
150
|
+
autoDetectContainers: true,
|
151
|
+
intelligentBreakpoints: true,
|
152
|
+
performanceOptimization: true
|
153
|
+
});
|
154
|
+
this.browserPolyfills = BrowserPolyfills.getInstance();
|
155
|
+
this.performanceMonitor = new PerformanceMonitor();
|
156
|
+
this.fluidTypography = new FluidTypography();
|
157
|
+
this.containerBreakpoints = new ContainerBreakpoints();
|
158
|
+
this.accessibilityEngine = new AccessibilityEngine(document.body);
|
159
|
+
this.browserCompatibility = new BrowserCompatibility();
|
160
|
+
|
161
|
+
// Connect performance monitoring
|
162
|
+
this.fluidTypography.setPerformanceMonitor(this.performanceMonitor);
|
163
|
+
this.containerBreakpoints.setPerformanceMonitor(this.performanceMonitor);
|
164
|
+
|
165
|
+
ProteusJS.instance = this;
|
166
|
+
|
167
|
+
// Auto-initialize if configured
|
168
|
+
if (this.config.autoInit) {
|
169
|
+
this.init();
|
170
|
+
}
|
171
|
+
}
|
172
|
+
|
173
|
+
/**
|
174
|
+
* Public getters for subsystems
|
175
|
+
*/
|
176
|
+
public get typography(): FluidTypography {
|
177
|
+
return this.fluidTypography;
|
178
|
+
}
|
179
|
+
|
180
|
+
public get containers(): ContainerBreakpoints {
|
181
|
+
return this.containerBreakpoints;
|
182
|
+
}
|
183
|
+
|
184
|
+
public get performance(): PerformanceMonitor {
|
185
|
+
return this.performanceMonitor;
|
186
|
+
}
|
187
|
+
|
188
|
+
public get accessibility(): AccessibilityEngine {
|
189
|
+
return this.accessibilityEngine;
|
190
|
+
}
|
191
|
+
|
192
|
+
public get compatibility(): BrowserCompatibility {
|
193
|
+
return this.browserCompatibility;
|
194
|
+
}
|
195
|
+
|
196
|
+
/**
|
197
|
+
* Get current configuration
|
198
|
+
*/
|
199
|
+
public getConfiguration(): Required<ProteusConfig> {
|
200
|
+
return this.config;
|
201
|
+
}
|
202
|
+
|
203
|
+
/**
|
204
|
+
* Initialize ProteusJS (async version)
|
205
|
+
*/
|
206
|
+
public async initialize(): Promise<this> {
|
207
|
+
return this.init();
|
208
|
+
}
|
209
|
+
|
210
|
+
/**
|
211
|
+
* Initialize ProteusJS
|
212
|
+
*/
|
213
|
+
public init(): this {
|
214
|
+
if (this.initialized) {
|
215
|
+
if (this.config.debug) {
|
216
|
+
logger.warn('Already initialized');
|
217
|
+
}
|
218
|
+
return this;
|
219
|
+
}
|
220
|
+
|
221
|
+
// Check browser support
|
222
|
+
if (!isSupported()) {
|
223
|
+
logger.error('Browser not supported. Missing required APIs.');
|
224
|
+
return this;
|
225
|
+
}
|
226
|
+
|
227
|
+
if (this.config.debug) {
|
228
|
+
logger.info('Initializing...', {
|
229
|
+
version,
|
230
|
+
config: this.config,
|
231
|
+
support: getSupportInfo()
|
232
|
+
});
|
233
|
+
}
|
234
|
+
|
235
|
+
// Start performance monitoring
|
236
|
+
this.performanceMonitor.start();
|
237
|
+
|
238
|
+
// Initialize core systems
|
239
|
+
this.eventSystem.init();
|
240
|
+
this.pluginSystem.init();
|
241
|
+
this.eventHandler.initialize();
|
242
|
+
|
243
|
+
// Initialize zero-config system for automatic optimization
|
244
|
+
this.zeroConfig.initialize().catch(error => {
|
245
|
+
logger.warn('Zero-config initialization failed', error);
|
246
|
+
});
|
247
|
+
|
248
|
+
// Mark as initialized
|
249
|
+
this.initialized = true;
|
250
|
+
|
251
|
+
// Emit initialization event
|
252
|
+
this.eventSystem.emit('init', { config: this.config });
|
253
|
+
|
254
|
+
if (this.config.debug) {
|
255
|
+
logger.info('Initialized successfully');
|
256
|
+
}
|
257
|
+
|
258
|
+
return this;
|
259
|
+
}
|
260
|
+
|
261
|
+
/**
|
262
|
+
* Get browser capabilities
|
263
|
+
*/
|
264
|
+
public getBrowserCapabilities(): any {
|
265
|
+
const support = this.browserPolyfills?.checkBrowserSupport() || { supported: [], missing: [] };
|
266
|
+
|
267
|
+
// Convert to expected format
|
268
|
+
return {
|
269
|
+
resizeObserver: support.supported.includes('ResizeObserver'),
|
270
|
+
intersectionObserver: support.supported.includes('IntersectionObserver'),
|
271
|
+
containerQueries: support.supported.includes('CSS Container Queries'),
|
272
|
+
cssClamp: support.supported.includes('CSS clamp()'),
|
273
|
+
customProperties: support.supported.includes('CSS Custom Properties'),
|
274
|
+
matchMedia: support.supported.includes('matchMedia'),
|
275
|
+
mutationObserver: support.supported.includes('MutationObserver')
|
276
|
+
};
|
277
|
+
}
|
278
|
+
|
279
|
+
/**
|
280
|
+
* Get performance metrics
|
281
|
+
*/
|
282
|
+
public getMetrics(): any {
|
283
|
+
return this.performanceMonitor?.getMetrics() || {};
|
284
|
+
}
|
285
|
+
|
286
|
+
/**
|
287
|
+
* Detect browser features
|
288
|
+
*/
|
289
|
+
public detectFeatures(): any {
|
290
|
+
const capabilities = this.getBrowserCapabilities();
|
291
|
+
const support = this.browserPolyfills?.checkBrowserSupport() || { supported: [], missing: [] };
|
292
|
+
|
293
|
+
return {
|
294
|
+
// Include individual capability flags
|
295
|
+
resizeObserver: capabilities.resizeObserver,
|
296
|
+
intersectionObserver: capabilities.intersectionObserver,
|
297
|
+
containerQueries: capabilities.containerQueries,
|
298
|
+
cssClamp: capabilities.cssClamp,
|
299
|
+
customProperties: capabilities.customProperties,
|
300
|
+
flexbox: capabilities.flexbox,
|
301
|
+
grid: capabilities.grid,
|
302
|
+
// Include arrays for detailed info
|
303
|
+
supported: support.supported,
|
304
|
+
missing: support.missing,
|
305
|
+
polyfillsActive: support.missing.length > 0
|
306
|
+
};
|
307
|
+
}
|
308
|
+
|
309
|
+
/**
|
310
|
+
* Update live region for screen readers
|
311
|
+
*/
|
312
|
+
public updateLiveRegion(element: Element, message: string): void {
|
313
|
+
if (element instanceof HTMLElement) {
|
314
|
+
element.textContent = message;
|
315
|
+
element.setAttribute('aria-live', 'polite');
|
316
|
+
}
|
317
|
+
}
|
318
|
+
|
319
|
+
|
320
|
+
|
321
|
+
/**
|
322
|
+
* Destroy ProteusJS instance and clean up resources
|
323
|
+
*/
|
324
|
+
public destroy(): void {
|
325
|
+
if (!this.initialized) return;
|
326
|
+
|
327
|
+
if (this.config.debug) {
|
328
|
+
console.log('ProteusJS: Destroying...');
|
329
|
+
}
|
330
|
+
|
331
|
+
// Clean up systems
|
332
|
+
this.containerManager.destroy();
|
333
|
+
this.observerManager.destroy();
|
334
|
+
this.memoryManager.destroy();
|
335
|
+
this.performanceMonitor.stop();
|
336
|
+
this.eventHandler.destroy();
|
337
|
+
this.batchDOM.destroy();
|
338
|
+
this.lazyEvaluation.destroy();
|
339
|
+
this.cssOptimizer.destroy();
|
340
|
+
this.themeSystem.destroy();
|
341
|
+
this.flipAnimations.destroy();
|
342
|
+
this.scrollAnimations.destroy();
|
343
|
+
this.memoryManagement.destroy();
|
344
|
+
this.cacheOptimization.destroy();
|
345
|
+
this.zeroConfig.destroy();
|
346
|
+
this.pluginSystem.destroy();
|
347
|
+
this.eventSystem.destroy();
|
348
|
+
|
349
|
+
// Reset state
|
350
|
+
this.initialized = false;
|
351
|
+
ProteusJS.instance = null;
|
352
|
+
|
353
|
+
if (this.config.debug) {
|
354
|
+
console.log('ProteusJS: Destroyed');
|
355
|
+
}
|
356
|
+
}
|
357
|
+
|
358
|
+
/**
|
359
|
+
* Get current configuration
|
360
|
+
*/
|
361
|
+
public getConfig(): Required<ProteusConfig> {
|
362
|
+
return { ...this.config };
|
363
|
+
}
|
364
|
+
|
365
|
+
/**
|
366
|
+
* Update configuration
|
367
|
+
*/
|
368
|
+
public updateConfig(newConfig: Partial<ProteusConfig>): this {
|
369
|
+
this.config = this.mergeConfig(newConfig, this.config);
|
370
|
+
this.eventSystem.emit('configUpdate', { config: this.config });
|
371
|
+
return this;
|
372
|
+
}
|
373
|
+
|
374
|
+
/**
|
375
|
+
* Get event system instance
|
376
|
+
*/
|
377
|
+
public getEventSystem(): EventSystem {
|
378
|
+
return this.eventSystem;
|
379
|
+
}
|
380
|
+
|
381
|
+
/**
|
382
|
+
* Get plugin system instance
|
383
|
+
*/
|
384
|
+
public getPluginSystem(): PluginSystem {
|
385
|
+
return this.pluginSystem;
|
386
|
+
}
|
387
|
+
|
388
|
+
/**
|
389
|
+
* Get performance monitor instance
|
390
|
+
*/
|
391
|
+
public getPerformanceMonitor(): PerformanceMonitor {
|
392
|
+
return this.performanceMonitor;
|
393
|
+
}
|
394
|
+
|
395
|
+
/**
|
396
|
+
* Get memory manager instance
|
397
|
+
*/
|
398
|
+
public getMemoryManager(): MemoryManager {
|
399
|
+
return this.memoryManager;
|
400
|
+
}
|
401
|
+
|
402
|
+
/**
|
403
|
+
* Get observer manager instance
|
404
|
+
*/
|
405
|
+
public getObserverManager(): ObserverManager {
|
406
|
+
return this.observerManager;
|
407
|
+
}
|
408
|
+
|
409
|
+
/**
|
410
|
+
* Get container manager instance
|
411
|
+
*/
|
412
|
+
public getContainerManager(): ContainerManager {
|
413
|
+
return this.containerManager;
|
414
|
+
}
|
415
|
+
|
416
|
+
/**
|
417
|
+
* Create a container with responsive behavior
|
418
|
+
*/
|
419
|
+
public container(selector: string | Element | Element[], options?: ContainerOptions): SmartContainer | SmartContainer[] {
|
420
|
+
return this.containerManager.container(selector, options);
|
421
|
+
}
|
422
|
+
|
423
|
+
/**
|
424
|
+
* Create fluid typography scaling
|
425
|
+
*/
|
426
|
+
public fluidType(selector: string | Element | Element[], config?: ScalingConfig): void {
|
427
|
+
const elements = this.normalizeSelector(selector);
|
428
|
+
elements.forEach(element => {
|
429
|
+
// Apply fluid typography using clamp scaling
|
430
|
+
const defaultConfig: ScalingConfig = {
|
431
|
+
minSize: 16,
|
432
|
+
maxSize: 24,
|
433
|
+
minContainer: 320,
|
434
|
+
maxContainer: 1200,
|
435
|
+
unit: 'px',
|
436
|
+
containerUnit: 'px',
|
437
|
+
curve: 'linear'
|
438
|
+
};
|
439
|
+
const scaling = this.clampScaling.createScaling(config || defaultConfig);
|
440
|
+
(element as HTMLElement).style.fontSize = scaling.clampValue;
|
441
|
+
|
442
|
+
// Apply default line height for accessibility
|
443
|
+
const computedStyle = getComputedStyle(element);
|
444
|
+
const fontSize = parseFloat(computedStyle.fontSize);
|
445
|
+
(element as HTMLElement).style.lineHeight = `${fontSize * 1.5}px`;
|
446
|
+
});
|
447
|
+
}
|
448
|
+
|
449
|
+
/**
|
450
|
+
* Generate typographic scale
|
451
|
+
*/
|
452
|
+
public createTypeScale(config?: ScaleConfig): TypeScale | number[] {
|
453
|
+
const defaultConfig: ScaleConfig = {
|
454
|
+
ratio: 1.25,
|
455
|
+
baseSize: 16,
|
456
|
+
baseUnit: 'px',
|
457
|
+
levels: 6,
|
458
|
+
direction: 'both'
|
459
|
+
};
|
460
|
+
return this.typographicScale.generateScale(config || defaultConfig);
|
461
|
+
}
|
462
|
+
|
463
|
+
/**
|
464
|
+
* Create adaptive grid layout
|
465
|
+
*/
|
466
|
+
public createGrid(selector: string | Element, config?: Partial<GridConfig>): AdaptiveGrid | null {
|
467
|
+
const element = typeof selector === 'string'
|
468
|
+
? document.querySelector(selector)
|
469
|
+
: selector;
|
470
|
+
|
471
|
+
if (!element) {
|
472
|
+
console.warn('ProteusJS: Grid element not found');
|
473
|
+
return null;
|
474
|
+
}
|
475
|
+
|
476
|
+
const grid = new AdaptiveGrid(element, config);
|
477
|
+
grid.activate();
|
478
|
+
return grid;
|
479
|
+
}
|
480
|
+
|
481
|
+
/**
|
482
|
+
* Apply text fitting to elements
|
483
|
+
*/
|
484
|
+
public fitText(selector: string | Element | Element[], config?: any) {
|
485
|
+
const elements = this.normalizeSelector(selector);
|
486
|
+
elements.forEach(element => {
|
487
|
+
const rect = element.getBoundingClientRect();
|
488
|
+
const text = element.textContent || '';
|
489
|
+
const result = this.textFitting.fitText(element, text, rect.width, rect.height, config);
|
490
|
+
this.textFitting.applyFitting(element, result, config);
|
491
|
+
});
|
492
|
+
}
|
493
|
+
|
494
|
+
/**
|
495
|
+
* Apply vertical rhythm to elements
|
496
|
+
*/
|
497
|
+
public applyRhythm(selector: string | Element | Element[], _config?: unknown): void {
|
498
|
+
const elements = this.normalizeSelector(selector);
|
499
|
+
elements.forEach(element => {
|
500
|
+
const rhythm = this.verticalRhythm.generateRhythm();
|
501
|
+
this.verticalRhythm.applyRhythm(element, rhythm);
|
502
|
+
});
|
503
|
+
}
|
504
|
+
|
505
|
+
/**
|
506
|
+
* Create enhanced flexbox layout
|
507
|
+
*/
|
508
|
+
public createFlexbox(selector: string | Element, config?: any) {
|
509
|
+
const element = typeof selector === 'string'
|
510
|
+
? document.querySelector(selector)
|
511
|
+
: selector;
|
512
|
+
|
513
|
+
if (!element) {
|
514
|
+
console.warn('ProteusJS: Flexbox element not found');
|
515
|
+
return null;
|
516
|
+
}
|
517
|
+
|
518
|
+
const flexbox = new FlexboxEnhancer(element, config);
|
519
|
+
flexbox.activate();
|
520
|
+
return flexbox;
|
521
|
+
}
|
522
|
+
|
523
|
+
/**
|
524
|
+
* Apply flow layout
|
525
|
+
*/
|
526
|
+
public applyFlow(selector: string | Element, config?: any) {
|
527
|
+
const element = typeof selector === 'string'
|
528
|
+
? document.querySelector(selector)
|
529
|
+
: selector;
|
530
|
+
|
531
|
+
if (!element) {
|
532
|
+
console.warn('ProteusJS: Flow element not found');
|
533
|
+
return null;
|
534
|
+
}
|
535
|
+
|
536
|
+
const flow = new FlowLayout(element, config);
|
537
|
+
flow.activate();
|
538
|
+
return flow;
|
539
|
+
}
|
540
|
+
|
541
|
+
/**
|
542
|
+
* Apply spacing system
|
543
|
+
*/
|
544
|
+
public applySpacing(selector: string | Element, config?: any) {
|
545
|
+
const element = typeof selector === 'string'
|
546
|
+
? document.querySelector(selector)
|
547
|
+
: selector;
|
548
|
+
|
549
|
+
if (!element) {
|
550
|
+
console.warn('ProteusJS: Spacing element not found');
|
551
|
+
return null;
|
552
|
+
}
|
553
|
+
|
554
|
+
const spacing = new SpacingSystem(element, config);
|
555
|
+
spacing.activate();
|
556
|
+
return spacing;
|
557
|
+
}
|
558
|
+
|
559
|
+
/**
|
560
|
+
* Enable content reordering
|
561
|
+
*/
|
562
|
+
public enableReordering(selector: string | Element, config?: any) {
|
563
|
+
const element = typeof selector === 'string'
|
564
|
+
? document.querySelector(selector)
|
565
|
+
: selector;
|
566
|
+
|
567
|
+
if (!element) {
|
568
|
+
console.warn('ProteusJS: Reordering element not found');
|
569
|
+
return null;
|
570
|
+
}
|
571
|
+
|
572
|
+
const reordering = new ContentReordering(element, config);
|
573
|
+
reordering.activate();
|
574
|
+
return reordering;
|
575
|
+
}
|
576
|
+
|
577
|
+
/**
|
578
|
+
* Enable responsive images
|
579
|
+
*/
|
580
|
+
public responsiveImages(selector: string | Element | Element[], config?: any) {
|
581
|
+
const elements = this.normalizeSelector(selector);
|
582
|
+
const instances: ResponsiveImages[] = [];
|
583
|
+
|
584
|
+
elements.forEach(element => {
|
585
|
+
const responsiveImage = new ResponsiveImages(element, config);
|
586
|
+
responsiveImage.activate();
|
587
|
+
instances.push(responsiveImage);
|
588
|
+
});
|
589
|
+
|
590
|
+
return instances.length === 1 ? instances[0] : instances;
|
591
|
+
}
|
592
|
+
|
593
|
+
/**
|
594
|
+
* Enable accessibility features
|
595
|
+
*/
|
596
|
+
public enableAccessibility(selector: string | Element, config?: any) {
|
597
|
+
const element = typeof selector === 'string'
|
598
|
+
? document.querySelector(selector)
|
599
|
+
: selector;
|
600
|
+
|
601
|
+
if (!element) {
|
602
|
+
console.warn('ProteusJS: Accessibility element not found');
|
603
|
+
return null;
|
604
|
+
}
|
605
|
+
|
606
|
+
const accessibility = new AccessibilityEngine(element, config);
|
607
|
+
accessibility.activate();
|
608
|
+
return accessibility;
|
609
|
+
}
|
610
|
+
|
611
|
+
/**
|
612
|
+
* Comprehensive setup for complete ProteusJS experience
|
613
|
+
*/
|
614
|
+
public setupComplete(config?: any) {
|
615
|
+
// Apply to document body by default
|
616
|
+
const container = config?.container || document.body;
|
617
|
+
|
618
|
+
// Enable all core features
|
619
|
+
this.container(container, config?.container);
|
620
|
+
this.fluidType(container.querySelectorAll('h1, h2, h3, h4, h5, h6, p'), config?.typography);
|
621
|
+
this.createGrid(container.querySelectorAll('.grid, .gallery'), config?.grid);
|
622
|
+
this.applySpacing(container, config?.spacing);
|
623
|
+
this.enableAccessibility(container, config?.accessibility);
|
624
|
+
|
625
|
+
// Enable responsive images for all images
|
626
|
+
this.responsiveImages(container.querySelectorAll('img'), config?.images);
|
627
|
+
|
628
|
+
return this;
|
629
|
+
}
|
630
|
+
|
631
|
+
/**
|
632
|
+
* Check if ProteusJS is initialized
|
633
|
+
*/
|
634
|
+
public isInitialized(): boolean {
|
635
|
+
return this.initialized;
|
636
|
+
}
|
637
|
+
|
638
|
+
/**
|
639
|
+
* Get library version
|
640
|
+
*/
|
641
|
+
public static getVersion(): string {
|
642
|
+
return version;
|
643
|
+
}
|
644
|
+
|
645
|
+
/**
|
646
|
+
* Get browser support information
|
647
|
+
*/
|
648
|
+
public static getSupportInfo() {
|
649
|
+
return getSupportInfo();
|
650
|
+
}
|
651
|
+
|
652
|
+
/**
|
653
|
+
* Check if browser is supported
|
654
|
+
*/
|
655
|
+
public static isSupported(): boolean {
|
656
|
+
return isSupported();
|
657
|
+
}
|
658
|
+
|
659
|
+
/**
|
660
|
+
* Get or create global instance
|
661
|
+
*/
|
662
|
+
public static getInstance(config?: ProteusConfig): ProteusJS {
|
663
|
+
if (!ProteusJS.instance) {
|
664
|
+
ProteusJS.instance = new ProteusJS(config);
|
665
|
+
}
|
666
|
+
return ProteusJS.instance;
|
667
|
+
}
|
668
|
+
|
669
|
+
/**
|
670
|
+
* Merge configuration with defaults
|
671
|
+
*/
|
672
|
+
private mergeConfig(
|
673
|
+
config: Partial<ProteusConfig>,
|
674
|
+
existing?: Required<ProteusConfig>
|
675
|
+
): Required<ProteusConfig> {
|
676
|
+
const defaults: Required<ProteusConfig> = {
|
677
|
+
debug: false,
|
678
|
+
performance: 'high',
|
679
|
+
accessibility: true,
|
680
|
+
autoInit: true,
|
681
|
+
containers: {
|
682
|
+
autoDetect: true,
|
683
|
+
breakpoints: {},
|
684
|
+
units: true,
|
685
|
+
isolation: true,
|
686
|
+
polyfill: true
|
687
|
+
},
|
688
|
+
typography: {
|
689
|
+
fluidScaling: true,
|
690
|
+
autoOptimize: true,
|
691
|
+
accessibility: true,
|
692
|
+
scale: {
|
693
|
+
ratio: 1.33,
|
694
|
+
base: '1rem',
|
695
|
+
levels: 6
|
696
|
+
},
|
697
|
+
lineHeight: {
|
698
|
+
auto: true,
|
699
|
+
density: 'comfortable'
|
700
|
+
}
|
701
|
+
},
|
702
|
+
layout: {
|
703
|
+
grid: {
|
704
|
+
auto: true,
|
705
|
+
masonry: false,
|
706
|
+
gap: 'fluid'
|
707
|
+
},
|
708
|
+
flexbox: {
|
709
|
+
enhanced: true,
|
710
|
+
autoWrap: true
|
711
|
+
},
|
712
|
+
spacing: {
|
713
|
+
scale: 'minor-third',
|
714
|
+
density: 'comfortable'
|
715
|
+
}
|
716
|
+
},
|
717
|
+
animations: {
|
718
|
+
enabled: true,
|
719
|
+
respectMotionPreferences: true,
|
720
|
+
duration: 300,
|
721
|
+
easing: 'ease-out',
|
722
|
+
flip: true,
|
723
|
+
microInteractions: true
|
724
|
+
},
|
725
|
+
theming: {
|
726
|
+
darkMode: {
|
727
|
+
auto: true,
|
728
|
+
schedule: '18:00-06:00',
|
729
|
+
transition: 'smooth'
|
730
|
+
},
|
731
|
+
contrast: {
|
732
|
+
adaptive: true,
|
733
|
+
level: 'AA'
|
734
|
+
}
|
735
|
+
}
|
736
|
+
};
|
737
|
+
|
738
|
+
return {
|
739
|
+
...defaults,
|
740
|
+
...existing,
|
741
|
+
...config,
|
742
|
+
containers: { ...defaults.containers, ...existing?.containers, ...config.containers },
|
743
|
+
typography: {
|
744
|
+
...defaults.typography,
|
745
|
+
...existing?.typography,
|
746
|
+
...config.typography,
|
747
|
+
scale: { ...defaults.typography.scale, ...existing?.typography?.scale, ...config.typography?.scale },
|
748
|
+
lineHeight: { ...defaults.typography.lineHeight, ...existing?.typography?.lineHeight, ...config.typography?.lineHeight }
|
749
|
+
},
|
750
|
+
layout: {
|
751
|
+
...defaults.layout,
|
752
|
+
...existing?.layout,
|
753
|
+
...config.layout,
|
754
|
+
grid: { ...defaults.layout.grid, ...existing?.layout?.grid, ...config.layout?.grid },
|
755
|
+
flexbox: { ...defaults.layout.flexbox, ...existing?.layout?.flexbox, ...config.layout?.flexbox },
|
756
|
+
spacing: { ...defaults.layout.spacing, ...existing?.layout?.spacing, ...config.layout?.spacing }
|
757
|
+
},
|
758
|
+
animations: { ...defaults.animations, ...existing?.animations, ...config.animations },
|
759
|
+
theming: {
|
760
|
+
...defaults.theming,
|
761
|
+
...existing?.theming,
|
762
|
+
...config.theming,
|
763
|
+
darkMode: { ...defaults.theming.darkMode, ...existing?.theming?.darkMode, ...config.theming?.darkMode },
|
764
|
+
contrast: { ...defaults.theming.contrast, ...existing?.theming?.contrast, ...config.theming?.contrast }
|
765
|
+
}
|
766
|
+
};
|
767
|
+
}
|
768
|
+
|
769
|
+
/**
|
770
|
+
* Normalize selector to array of elements
|
771
|
+
*/
|
772
|
+
private normalizeSelector(selector: string | Element | Element[]): Element[] {
|
773
|
+
if (typeof selector === 'string') {
|
774
|
+
return Array.from(document.querySelectorAll(selector));
|
775
|
+
} else if (selector instanceof Element) {
|
776
|
+
return [selector];
|
777
|
+
} else if (Array.isArray(selector)) {
|
778
|
+
return selector;
|
779
|
+
}
|
780
|
+
return [];
|
781
|
+
}
|
782
|
+
|
783
|
+
/**
|
784
|
+
* Get performance metrics from event handler
|
785
|
+
*/
|
786
|
+
public getPerformanceMetrics() {
|
787
|
+
return {
|
788
|
+
eventHandler: this.eventHandler.getMetrics(),
|
789
|
+
batchDOM: this.batchDOM.getMetrics(),
|
790
|
+
performanceMonitor: this.performanceMonitor.getMetrics()
|
791
|
+
};
|
792
|
+
}
|
793
|
+
|
794
|
+
/**
|
795
|
+
* Efficiently observe element resize with batching
|
796
|
+
*/
|
797
|
+
public observeResize(
|
798
|
+
selector: string | Element,
|
799
|
+
callback: (entry: ResizeObserverEntry) => void,
|
800
|
+
priority: 'high' | 'normal' | 'low' = 'normal'
|
801
|
+
) {
|
802
|
+
const element = typeof selector === 'string'
|
803
|
+
? document.querySelector(selector)
|
804
|
+
: selector;
|
805
|
+
|
806
|
+
if (!element) {
|
807
|
+
console.warn('ProteusJS: Element not found for resize observation');
|
808
|
+
return null;
|
809
|
+
}
|
810
|
+
|
811
|
+
return this.eventHandler.observeResize(element, callback, priority);
|
812
|
+
}
|
813
|
+
|
814
|
+
/**
|
815
|
+
* Batch DOM style changes for performance
|
816
|
+
*/
|
817
|
+
public batchStyles(
|
818
|
+
selector: string | Element,
|
819
|
+
styles: Record<string, string>,
|
820
|
+
priority: 'high' | 'normal' | 'low' = 'normal'
|
821
|
+
) {
|
822
|
+
const element = typeof selector === 'string'
|
823
|
+
? document.querySelector(selector)
|
824
|
+
: selector;
|
825
|
+
|
826
|
+
if (!element) {
|
827
|
+
console.warn('ProteusJS: Element not found for style batching');
|
828
|
+
return Promise.reject(new Error('Element not found'));
|
829
|
+
}
|
830
|
+
|
831
|
+
return this.batchDOM.batchStyles(element, styles, priority);
|
832
|
+
}
|
833
|
+
|
834
|
+
/**
|
835
|
+
* Batch DOM measurements for performance
|
836
|
+
*/
|
837
|
+
public measureElement(
|
838
|
+
selector: string | Element,
|
839
|
+
measurements: ('width' | 'height' | 'top' | 'left' | 'right' | 'bottom')[] = ['width', 'height'],
|
840
|
+
priority: 'high' | 'normal' | 'low' = 'normal'
|
841
|
+
) {
|
842
|
+
const element = typeof selector === 'string'
|
843
|
+
? document.querySelector(selector)
|
844
|
+
: selector;
|
845
|
+
|
846
|
+
if (!element) {
|
847
|
+
console.warn('ProteusJS: Element not found for measurement');
|
848
|
+
return Promise.reject(new Error('Element not found'));
|
849
|
+
}
|
850
|
+
|
851
|
+
return this.batchDOM.measureElement(element, measurements, priority);
|
852
|
+
}
|
853
|
+
|
854
|
+
/**
|
855
|
+
* Set theme scheme
|
856
|
+
*/
|
857
|
+
public setTheme(scheme: string) {
|
858
|
+
this.themeSystem.setScheme(scheme);
|
859
|
+
return this;
|
860
|
+
}
|
861
|
+
|
862
|
+
/**
|
863
|
+
* Toggle theme between light and dark
|
864
|
+
*/
|
865
|
+
public toggleTheme() {
|
866
|
+
this.themeSystem.toggle();
|
867
|
+
return this;
|
868
|
+
}
|
869
|
+
|
870
|
+
/**
|
871
|
+
* Animate element with FLIP technique
|
872
|
+
*/
|
873
|
+
public async animateElement(
|
874
|
+
selector: string | Element,
|
875
|
+
newPosition: () => void,
|
876
|
+
options?: any
|
877
|
+
) {
|
878
|
+
const element = typeof selector === 'string'
|
879
|
+
? document.querySelector(selector)
|
880
|
+
: selector;
|
881
|
+
|
882
|
+
if (!element) {
|
883
|
+
console.warn('ProteusJS: Element not found for animation');
|
884
|
+
return;
|
885
|
+
}
|
886
|
+
|
887
|
+
return this.flipAnimations.animate(element, newPosition, options);
|
888
|
+
}
|
889
|
+
|
890
|
+
/**
|
891
|
+
* Add micro-interactions to elements
|
892
|
+
*/
|
893
|
+
public addMicroInteractions(selector: string | Element, type: 'hover' | 'press' | 'focus' | 'ripple' = 'hover') {
|
894
|
+
const element = typeof selector === 'string'
|
895
|
+
? document.querySelector(selector)
|
896
|
+
: selector;
|
897
|
+
|
898
|
+
if (!element) {
|
899
|
+
console.warn('ProteusJS: Element not found for micro-interactions');
|
900
|
+
return this;
|
901
|
+
}
|
902
|
+
|
903
|
+
switch (type) {
|
904
|
+
case 'hover':
|
905
|
+
MicroInteractions.addHover(element);
|
906
|
+
break;
|
907
|
+
case 'press':
|
908
|
+
MicroInteractions.addPress(element);
|
909
|
+
break;
|
910
|
+
case 'focus':
|
911
|
+
MicroInteractions.addFocus(element);
|
912
|
+
break;
|
913
|
+
case 'ripple':
|
914
|
+
MicroInteractions.addRipple(element);
|
915
|
+
break;
|
916
|
+
}
|
917
|
+
|
918
|
+
return this;
|
919
|
+
}
|
920
|
+
|
921
|
+
/**
|
922
|
+
* Register lazy-loaded component
|
923
|
+
*/
|
924
|
+
public lazyLoad(
|
925
|
+
selector: string | Element,
|
926
|
+
activator: () => Promise<void>,
|
927
|
+
options?: any
|
928
|
+
) {
|
929
|
+
const element = typeof selector === 'string'
|
930
|
+
? document.querySelector(selector)
|
931
|
+
: selector;
|
932
|
+
|
933
|
+
if (!element) {
|
934
|
+
console.warn('ProteusJS: Element not found for lazy loading');
|
935
|
+
return null;
|
936
|
+
}
|
937
|
+
|
938
|
+
return this.lazyEvaluation.register(element, activator, options);
|
939
|
+
}
|
940
|
+
|
941
|
+
/**
|
942
|
+
* Optimize CSS performance
|
943
|
+
*/
|
944
|
+
public async optimizeCSS() {
|
945
|
+
return this.cssOptimizer.optimizeAll();
|
946
|
+
}
|
947
|
+
|
948
|
+
/**
|
949
|
+
* Get comprehensive performance metrics
|
950
|
+
*/
|
951
|
+
public getAdvancedMetrics() {
|
952
|
+
return {
|
953
|
+
eventHandler: this.eventHandler.getMetrics(),
|
954
|
+
batchDOM: this.batchDOM.getMetrics(),
|
955
|
+
lazyEvaluation: this.lazyEvaluation.getMetrics(),
|
956
|
+
cssOptimizer: this.cssOptimizer.getMetrics(),
|
957
|
+
themeSystem: this.themeSystem.getState(),
|
958
|
+
flipAnimations: this.flipAnimations.getActiveCount(),
|
959
|
+
performanceMonitor: this.performanceMonitor.getMetrics()
|
960
|
+
};
|
961
|
+
}
|
962
|
+
}
|