claude-mpm 4.2.44__py3-none-any.whl → 4.2.51__py3-none-any.whl
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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_PM.md +43 -1
- claude_mpm/agents/INSTRUCTIONS.md +75 -1
- claude_mpm/agents/WORKFLOW.md +46 -1
- claude_mpm/agents/frontmatter_validator.py +20 -12
- claude_mpm/agents/templates/nextjs_engineer.json +277 -0
- claude_mpm/agents/templates/python_engineer.json +289 -0
- claude_mpm/agents/templates/react_engineer.json +11 -3
- claude_mpm/agents/templates/security.json +50 -9
- claude_mpm/cli/commands/agents.py +2 -2
- claude_mpm/cli/commands/uninstall.py +1 -2
- claude_mpm/cli/interactive/agent_wizard.py +3 -3
- claude_mpm/cli/parsers/agent_manager_parser.py +3 -3
- claude_mpm/cli/parsers/agents_parser.py +1 -1
- claude_mpm/constants.py +1 -1
- claude_mpm/core/error_handler.py +2 -4
- claude_mpm/core/file_utils.py +4 -12
- claude_mpm/core/log_manager.py +8 -5
- claude_mpm/core/logger.py +1 -1
- claude_mpm/core/logging_utils.py +6 -6
- claude_mpm/core/unified_agent_registry.py +18 -4
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +188 -0
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +156 -0
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +38 -0
- claude_mpm/dashboard/react/components/shared/FilterBar.module.css +92 -0
- claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +248 -0
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +61 -0
- claude_mpm/dashboard/static/archive/test_activity_connection.html +179 -0
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +68 -0
- claude_mpm/dashboard/static/archive/test_dashboard.html +409 -0
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +519 -0
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +181 -0
- claude_mpm/dashboard/static/archive/test_file_data.html +315 -0
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +243 -0
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +234 -0
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +117 -0
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +115 -0
- claude_mpm/dashboard/static/archive/test_file_viewer.html +224 -0
- claude_mpm/dashboard/static/archive/test_final_activity.html +220 -0
- claude_mpm/dashboard/static/archive/test_tab_fix.html +139 -0
- claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +1 -0
- claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +777 -0
- claude_mpm/dashboard/static/built/components/agent-inference.js +1 -1
- claude_mpm/dashboard/static/built/components/build-tracker.js +333 -0
- claude_mpm/dashboard/static/built/components/code-simple.js +857 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +353 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +235 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +409 -0
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +435 -0
- claude_mpm/dashboard/static/built/components/code-viewer.js +2 -1076
- claude_mpm/dashboard/static/built/components/connection-debug.js +654 -0
- claude_mpm/dashboard/static/built/components/diff-viewer.js +891 -0
- claude_mpm/dashboard/static/built/components/event-processor.js +1 -1
- claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
- claude_mpm/dashboard/static/built/components/export-manager.js +1 -1
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +443 -0
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +690 -0
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +1 -1
- claude_mpm/dashboard/static/built/components/module-viewer.js +1 -1
- claude_mpm/dashboard/static/built/components/nav-bar.js +145 -0
- claude_mpm/dashboard/static/built/components/page-structure.js +429 -0
- claude_mpm/dashboard/static/built/components/session-manager.js +1 -1
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -465
- claude_mpm/dashboard/static/built/components/working-directory.js +1 -1
- claude_mpm/dashboard/static/built/connection-manager.js +536 -0
- claude_mpm/dashboard/static/built/dashboard.js +1 -1
- claude_mpm/dashboard/static/built/extension-error-handler.js +164 -0
- claude_mpm/dashboard/static/built/react/events.js +30 -0
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +396 -0
- claude_mpm/dashboard/static/built/shared/event-bus.js +330 -0
- claude_mpm/dashboard/static/built/shared/event-filter-service.js +540 -0
- claude_mpm/dashboard/static/built/shared/logger.js +385 -0
- claude_mpm/dashboard/static/built/shared/page-structure.js +251 -0
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +253 -0
- claude_mpm/dashboard/static/built/socket-client.js +1 -1
- claude_mpm/dashboard/static/built/tab-isolation-fix.js +185 -0
- claude_mpm/dashboard/static/css/dashboard.css +28 -5
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +1 -0
- claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
- claude_mpm/dashboard/static/dist/components/agent-inference.js +1 -1
- claude_mpm/dashboard/static/dist/components/code-viewer.js +2 -0
- claude_mpm/dashboard/static/dist/components/event-processor.js +1 -1
- claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
- claude_mpm/dashboard/static/dist/components/export-manager.js +1 -1
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +1 -1
- claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
- claude_mpm/dashboard/static/dist/components/session-manager.js +1 -1
- claude_mpm/dashboard/static/dist/components/working-directory.js +1 -1
- claude_mpm/dashboard/static/dist/dashboard.js +1 -1
- claude_mpm/dashboard/static/dist/react/events.js +30 -0
- claude_mpm/dashboard/static/dist/socket-client.js +1 -1
- claude_mpm/dashboard/static/events.html +607 -0
- claude_mpm/dashboard/static/index.html +713 -0
- claude_mpm/dashboard/static/js/components/activity-tree.js +3 -17
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +4 -1
- claude_mpm/dashboard/static/js/components/agent-inference.js +3 -0
- claude_mpm/dashboard/static/js/components/build-tracker.js +8 -0
- claude_mpm/dashboard/static/js/components/code-viewer.js +306 -66
- claude_mpm/dashboard/static/js/components/event-processor.js +3 -0
- claude_mpm/dashboard/static/js/components/event-viewer.js +39 -2
- claude_mpm/dashboard/static/js/components/export-manager.js +3 -0
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +30 -10
- claude_mpm/dashboard/static/js/components/socket-manager.js +4 -0
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +285 -85
- claude_mpm/dashboard/static/js/components/working-directory.js +3 -0
- claude_mpm/dashboard/static/js/dashboard.js +61 -33
- claude_mpm/dashboard/static/js/socket-client.js +12 -8
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +562 -0
- claude_mpm/dashboard/static/js/tab-isolation-fix.js +185 -0
- claude_mpm/dashboard/static/legacy/activity.html +736 -0
- claude_mpm/dashboard/static/legacy/agents.html +786 -0
- claude_mpm/dashboard/static/legacy/files.html +747 -0
- claude_mpm/dashboard/static/legacy/tools.html +831 -0
- claude_mpm/dashboard/static/monitors-index.html +218 -0
- claude_mpm/dashboard/static/monitors.html +431 -0
- claude_mpm/dashboard/static/production/events.html +659 -0
- claude_mpm/dashboard/static/production/main.html +715 -0
- claude_mpm/dashboard/static/production/monitors.html +483 -0
- claude_mpm/dashboard/static/socket.io.min.js +7 -0
- claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +7 -0
- claude_mpm/dashboard/static/test-archive/dashboard.html +635 -0
- claude_mpm/dashboard/static/test-archive/debug-events.html +147 -0
- claude_mpm/dashboard/static/test-archive/test-navigation.html +256 -0
- claude_mpm/dashboard/static/test-archive/test-react-exports.html +180 -0
- claude_mpm/dashboard/templates/index.html +79 -9
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +1 -1
- claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +25 -8
- claude_mpm/services/agents/deployment/agent_validator.py +3 -0
- claude_mpm/services/agents/deployment/validation/template_validator.py +13 -4
- claude_mpm/services/agents/local_template_manager.py +2 -6
- claude_mpm/services/monitor/daemon.py +1 -2
- claude_mpm/services/monitor/daemon_manager.py +2 -5
- claude_mpm/services/monitor/event_emitter.py +2 -2
- claude_mpm/services/monitor/handlers/code_analysis.py +4 -6
- claude_mpm/services/monitor/handlers/hooks.py +2 -4
- claude_mpm/services/monitor/server.py +27 -4
- claude_mpm/tools/code_tree_analyzer.py +2 -2
- {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/METADATA +1 -1
- {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/RECORD +146 -81
- claude_mpm/dashboard/static/test-browser-monitor.html +0 -470
- claude_mpm/dashboard/static/test-simple.html +0 -97
- /claude_mpm/dashboard/static/{test_debug.html → test-archive/test_debug.html} +0 -0
- {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/WHEEL +0 -0
- {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.2.44.dist-info → claude_mpm-4.2.51.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,396 @@
|
|
1
|
+
/**
|
2
|
+
* DOM Helper Utilities
|
3
|
+
*
|
4
|
+
* Common DOM manipulation utilities for dashboard components.
|
5
|
+
* Provides safe, consistent methods for element creation and manipulation.
|
6
|
+
*
|
7
|
+
* @module dom-helpers
|
8
|
+
*/
|
9
|
+
|
10
|
+
const domHelpers = {
|
11
|
+
/**
|
12
|
+
* Create an element with attributes and content
|
13
|
+
* @param {string} tag - Element tag name
|
14
|
+
* @param {Object} attrs - Attributes to set
|
15
|
+
* @param {string|Element|Array} content - Element content
|
16
|
+
* @returns {HTMLElement} Created element
|
17
|
+
*/
|
18
|
+
createElement(tag, attrs = {}, content = null) {
|
19
|
+
const element = document.createElement(tag);
|
20
|
+
|
21
|
+
// Set attributes
|
22
|
+
for (const [key, value] of Object.entries(attrs)) {
|
23
|
+
if (key === 'className') {
|
24
|
+
element.className = value;
|
25
|
+
} else if (key === 'style' && typeof value === 'object') {
|
26
|
+
Object.assign(element.style, value);
|
27
|
+
} else if (key === 'dataset' && typeof value === 'object') {
|
28
|
+
for (const [dataKey, dataValue] of Object.entries(value)) {
|
29
|
+
element.dataset[dataKey] = dataValue;
|
30
|
+
}
|
31
|
+
} else if (key.startsWith('on') && typeof value === 'function') {
|
32
|
+
const eventName = key.slice(2).toLowerCase();
|
33
|
+
element.addEventListener(eventName, value);
|
34
|
+
} else {
|
35
|
+
element.setAttribute(key, value);
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
// Add content
|
40
|
+
if (content !== null) {
|
41
|
+
this.setContent(element, content);
|
42
|
+
}
|
43
|
+
|
44
|
+
return element;
|
45
|
+
},
|
46
|
+
|
47
|
+
/**
|
48
|
+
* Set element content (supports text, HTML, elements, and arrays)
|
49
|
+
* @param {HTMLElement} element - Target element
|
50
|
+
* @param {string|Element|Array} content - Content to set
|
51
|
+
*/
|
52
|
+
setContent(element, content) {
|
53
|
+
if (typeof content === 'string') {
|
54
|
+
element.textContent = content;
|
55
|
+
} else if (content instanceof HTMLElement) {
|
56
|
+
element.appendChild(content);
|
57
|
+
} else if (Array.isArray(content)) {
|
58
|
+
content.forEach(item => {
|
59
|
+
if (typeof item === 'string') {
|
60
|
+
element.appendChild(document.createTextNode(item));
|
61
|
+
} else if (item instanceof HTMLElement) {
|
62
|
+
element.appendChild(item);
|
63
|
+
}
|
64
|
+
});
|
65
|
+
}
|
66
|
+
},
|
67
|
+
|
68
|
+
/**
|
69
|
+
* Safely query selector with null check
|
70
|
+
* @param {string} selector - CSS selector
|
71
|
+
* @param {Element} context - Context element (default: document)
|
72
|
+
* @returns {Element|null} Found element or null
|
73
|
+
*/
|
74
|
+
query(selector, context = document) {
|
75
|
+
try {
|
76
|
+
return context.querySelector(selector);
|
77
|
+
} catch (e) {
|
78
|
+
console.error(`Invalid selector: ${selector}`, e);
|
79
|
+
return null;
|
80
|
+
}
|
81
|
+
},
|
82
|
+
|
83
|
+
/**
|
84
|
+
* Safely query all matching elements
|
85
|
+
* @param {string} selector - CSS selector
|
86
|
+
* @param {Element} context - Context element (default: document)
|
87
|
+
* @returns {Array} Array of elements
|
88
|
+
*/
|
89
|
+
queryAll(selector, context = document) {
|
90
|
+
try {
|
91
|
+
return Array.from(context.querySelectorAll(selector));
|
92
|
+
} catch (e) {
|
93
|
+
console.error(`Invalid selector: ${selector}`, e);
|
94
|
+
return [];
|
95
|
+
}
|
96
|
+
},
|
97
|
+
|
98
|
+
/**
|
99
|
+
* Add classes to element
|
100
|
+
* @param {HTMLElement} element - Target element
|
101
|
+
* @param {...string} classes - Classes to add
|
102
|
+
*/
|
103
|
+
addClass(element, ...classes) {
|
104
|
+
if (element && element.classList) {
|
105
|
+
element.classList.add(...classes.filter(c => c));
|
106
|
+
}
|
107
|
+
},
|
108
|
+
|
109
|
+
/**
|
110
|
+
* Remove classes from element
|
111
|
+
* @param {HTMLElement} element - Target element
|
112
|
+
* @param {...string} classes - Classes to remove
|
113
|
+
*/
|
114
|
+
removeClass(element, ...classes) {
|
115
|
+
if (element && element.classList) {
|
116
|
+
element.classList.remove(...classes);
|
117
|
+
}
|
118
|
+
},
|
119
|
+
|
120
|
+
/**
|
121
|
+
* Toggle classes on element
|
122
|
+
* @param {HTMLElement} element - Target element
|
123
|
+
* @param {string} className - Class to toggle
|
124
|
+
* @param {boolean} force - Force add (true) or remove (false)
|
125
|
+
* @returns {boolean} Whether class is now present
|
126
|
+
*/
|
127
|
+
toggleClass(element, className, force) {
|
128
|
+
if (element && element.classList) {
|
129
|
+
return element.classList.toggle(className, force);
|
130
|
+
}
|
131
|
+
return false;
|
132
|
+
},
|
133
|
+
|
134
|
+
/**
|
135
|
+
* Check if element has class
|
136
|
+
* @param {HTMLElement} element - Target element
|
137
|
+
* @param {string} className - Class to check
|
138
|
+
* @returns {boolean} Whether element has class
|
139
|
+
*/
|
140
|
+
hasClass(element, className) {
|
141
|
+
return element && element.classList && element.classList.contains(className);
|
142
|
+
},
|
143
|
+
|
144
|
+
/**
|
145
|
+
* Set multiple styles on element
|
146
|
+
* @param {HTMLElement} element - Target element
|
147
|
+
* @param {Object} styles - Style properties and values
|
148
|
+
*/
|
149
|
+
setStyles(element, styles) {
|
150
|
+
if (element && element.style && styles) {
|
151
|
+
Object.assign(element.style, styles);
|
152
|
+
}
|
153
|
+
},
|
154
|
+
|
155
|
+
/**
|
156
|
+
* Get computed style value
|
157
|
+
* @param {HTMLElement} element - Target element
|
158
|
+
* @param {string} property - CSS property name
|
159
|
+
* @returns {string} Computed style value
|
160
|
+
*/
|
161
|
+
getStyle(element, property) {
|
162
|
+
if (element) {
|
163
|
+
return window.getComputedStyle(element).getPropertyValue(property);
|
164
|
+
}
|
165
|
+
return '';
|
166
|
+
},
|
167
|
+
|
168
|
+
/**
|
169
|
+
* Show element (removes display: none)
|
170
|
+
* @param {HTMLElement} element - Element to show
|
171
|
+
* @param {string} displayValue - Display value to use (default: '')
|
172
|
+
*/
|
173
|
+
show(element, displayValue = '') {
|
174
|
+
if (element && element.style) {
|
175
|
+
element.style.display = displayValue;
|
176
|
+
}
|
177
|
+
},
|
178
|
+
|
179
|
+
/**
|
180
|
+
* Hide element (sets display: none)
|
181
|
+
* @param {HTMLElement} element - Element to hide
|
182
|
+
*/
|
183
|
+
hide(element) {
|
184
|
+
if (element && element.style) {
|
185
|
+
element.style.display = 'none';
|
186
|
+
}
|
187
|
+
},
|
188
|
+
|
189
|
+
/**
|
190
|
+
* Toggle element visibility
|
191
|
+
* @param {HTMLElement} element - Element to toggle
|
192
|
+
* @param {boolean} show - Force show (true) or hide (false)
|
193
|
+
*/
|
194
|
+
toggle(element, show) {
|
195
|
+
if (element) {
|
196
|
+
if (show === undefined) {
|
197
|
+
show = element.style.display === 'none';
|
198
|
+
}
|
199
|
+
if (show) {
|
200
|
+
this.show(element);
|
201
|
+
} else {
|
202
|
+
this.hide(element);
|
203
|
+
}
|
204
|
+
}
|
205
|
+
},
|
206
|
+
|
207
|
+
/**
|
208
|
+
* Remove element from DOM
|
209
|
+
* @param {HTMLElement} element - Element to remove
|
210
|
+
*/
|
211
|
+
remove(element) {
|
212
|
+
if (element && element.parentNode) {
|
213
|
+
element.parentNode.removeChild(element);
|
214
|
+
}
|
215
|
+
},
|
216
|
+
|
217
|
+
/**
|
218
|
+
* Empty element content
|
219
|
+
* @param {HTMLElement} element - Element to empty
|
220
|
+
*/
|
221
|
+
empty(element) {
|
222
|
+
if (element) {
|
223
|
+
while (element.firstChild) {
|
224
|
+
element.removeChild(element.firstChild);
|
225
|
+
}
|
226
|
+
}
|
227
|
+
},
|
228
|
+
|
229
|
+
/**
|
230
|
+
* Insert element after reference element
|
231
|
+
* @param {HTMLElement} newElement - Element to insert
|
232
|
+
* @param {HTMLElement} referenceElement - Reference element
|
233
|
+
*/
|
234
|
+
insertAfter(newElement, referenceElement) {
|
235
|
+
if (referenceElement && referenceElement.parentNode) {
|
236
|
+
referenceElement.parentNode.insertBefore(newElement, referenceElement.nextSibling);
|
237
|
+
}
|
238
|
+
},
|
239
|
+
|
240
|
+
/**
|
241
|
+
* Wrap element with wrapper element
|
242
|
+
* @param {HTMLElement} element - Element to wrap
|
243
|
+
* @param {HTMLElement} wrapper - Wrapper element
|
244
|
+
*/
|
245
|
+
wrap(element, wrapper) {
|
246
|
+
if (element && element.parentNode) {
|
247
|
+
element.parentNode.insertBefore(wrapper, element);
|
248
|
+
wrapper.appendChild(element);
|
249
|
+
}
|
250
|
+
},
|
251
|
+
|
252
|
+
/**
|
253
|
+
* Get element dimensions
|
254
|
+
* @param {HTMLElement} element - Target element
|
255
|
+
* @returns {Object} Width and height
|
256
|
+
*/
|
257
|
+
getDimensions(element) {
|
258
|
+
if (element) {
|
259
|
+
return {
|
260
|
+
width: element.offsetWidth,
|
261
|
+
height: element.offsetHeight,
|
262
|
+
innerWidth: element.clientWidth,
|
263
|
+
innerHeight: element.clientHeight
|
264
|
+
};
|
265
|
+
}
|
266
|
+
return { width: 0, height: 0, innerWidth: 0, innerHeight: 0 };
|
267
|
+
},
|
268
|
+
|
269
|
+
/**
|
270
|
+
* Get element position relative to viewport
|
271
|
+
* @param {HTMLElement} element - Target element
|
272
|
+
* @returns {Object} Position coordinates
|
273
|
+
*/
|
274
|
+
getPosition(element) {
|
275
|
+
if (element) {
|
276
|
+
const rect = element.getBoundingClientRect();
|
277
|
+
return {
|
278
|
+
top: rect.top,
|
279
|
+
right: rect.right,
|
280
|
+
bottom: rect.bottom,
|
281
|
+
left: rect.left,
|
282
|
+
x: rect.x,
|
283
|
+
y: rect.y,
|
284
|
+
width: rect.width,
|
285
|
+
height: rect.height
|
286
|
+
};
|
287
|
+
}
|
288
|
+
return { top: 0, right: 0, bottom: 0, left: 0, x: 0, y: 0, width: 0, height: 0 };
|
289
|
+
},
|
290
|
+
|
291
|
+
/**
|
292
|
+
* Check if element is visible in viewport
|
293
|
+
* @param {HTMLElement} element - Element to check
|
294
|
+
* @param {boolean} partial - Allow partial visibility
|
295
|
+
* @returns {boolean} Whether element is visible
|
296
|
+
*/
|
297
|
+
isInViewport(element, partial = false) {
|
298
|
+
if (!element) return false;
|
299
|
+
|
300
|
+
const rect = element.getBoundingClientRect();
|
301
|
+
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
|
302
|
+
const windowWidth = window.innerWidth || document.documentElement.clientWidth;
|
303
|
+
|
304
|
+
const vertInView = partial
|
305
|
+
? rect.top < windowHeight && rect.bottom > 0
|
306
|
+
: rect.top >= 0 && rect.bottom <= windowHeight;
|
307
|
+
|
308
|
+
const horInView = partial
|
309
|
+
? rect.left < windowWidth && rect.right > 0
|
310
|
+
: rect.left >= 0 && rect.right <= windowWidth;
|
311
|
+
|
312
|
+
return vertInView && horInView;
|
313
|
+
},
|
314
|
+
|
315
|
+
/**
|
316
|
+
* Smoothly scroll element into view
|
317
|
+
* @param {HTMLElement} element - Element to scroll to
|
318
|
+
* @param {Object} options - Scroll options
|
319
|
+
*/
|
320
|
+
scrollIntoView(element, options = {}) {
|
321
|
+
if (element && element.scrollIntoView) {
|
322
|
+
const defaultOptions = {
|
323
|
+
behavior: 'smooth',
|
324
|
+
block: 'nearest',
|
325
|
+
inline: 'nearest'
|
326
|
+
};
|
327
|
+
element.scrollIntoView({ ...defaultOptions, ...options });
|
328
|
+
}
|
329
|
+
},
|
330
|
+
|
331
|
+
/**
|
332
|
+
* Create DocumentFragment from HTML string
|
333
|
+
* @param {string} html - HTML string
|
334
|
+
* @returns {DocumentFragment} Document fragment
|
335
|
+
*/
|
336
|
+
createFragment(html) {
|
337
|
+
const template = document.createElement('template');
|
338
|
+
template.innerHTML = html.trim();
|
339
|
+
return template.content;
|
340
|
+
},
|
341
|
+
|
342
|
+
/**
|
343
|
+
* Escape HTML special characters
|
344
|
+
* @param {string} text - Text to escape
|
345
|
+
* @returns {string} Escaped text
|
346
|
+
*/
|
347
|
+
escapeHtml(text) {
|
348
|
+
const div = document.createElement('div');
|
349
|
+
div.textContent = text;
|
350
|
+
return div.innerHTML;
|
351
|
+
},
|
352
|
+
|
353
|
+
/**
|
354
|
+
* Debounce function calls
|
355
|
+
* @param {Function} func - Function to debounce
|
356
|
+
* @param {number} wait - Wait time in ms
|
357
|
+
* @returns {Function} Debounced function
|
358
|
+
*/
|
359
|
+
debounce(func, wait) {
|
360
|
+
let timeout;
|
361
|
+
return function executedFunction(...args) {
|
362
|
+
const later = () => {
|
363
|
+
clearTimeout(timeout);
|
364
|
+
func(...args);
|
365
|
+
};
|
366
|
+
clearTimeout(timeout);
|
367
|
+
timeout = setTimeout(later, wait);
|
368
|
+
};
|
369
|
+
},
|
370
|
+
|
371
|
+
/**
|
372
|
+
* Throttle function calls
|
373
|
+
* @param {Function} func - Function to throttle
|
374
|
+
* @param {number} limit - Time limit in ms
|
375
|
+
* @returns {Function} Throttled function
|
376
|
+
*/
|
377
|
+
throttle(func, limit) {
|
378
|
+
let inThrottle;
|
379
|
+
return function(...args) {
|
380
|
+
if (!inThrottle) {
|
381
|
+
func.apply(this, args);
|
382
|
+
inThrottle = true;
|
383
|
+
setTimeout(() => inThrottle = false, limit);
|
384
|
+
}
|
385
|
+
};
|
386
|
+
}
|
387
|
+
};
|
388
|
+
|
389
|
+
// Support both module and global usage
|
390
|
+
if (typeof module !== 'undefined' && module.exports) {
|
391
|
+
module.exports = domHelpers;
|
392
|
+
} else if (typeof define === 'function' && define.amd) {
|
393
|
+
define([], () => domHelpers);
|
394
|
+
} else {
|
395
|
+
window.domHelpers = domHelpers;
|
396
|
+
}
|