muspe-cli
Version:
MusPE Advanced Framework v2.1.3 - Mobile User-friendly Simple Progressive Engine with Enhanced CLI Tools, Specialized E-Commerce Templates, Material Design 3, Progressive Enhancement, Mobile Optimizations, Performance Analysis, and Enterprise-Grade Develo
449 lines (370 loc) • 11.7 kB
JavaScript
// MusPE DOM Utilities - Fast and convenient DOM manipulation
class MusPEDOM {
// Core selection methods
static $(selector, context = document) {
return context.querySelector(selector);
}
static $$(selector, context = document) {
return Array.from(context.querySelectorAll(selector));
}
static id(id) {
return document.getElementById(id);
}
static tag(tagName, context = document) {
return Array.from(context.getElementsByTagName(tagName));
}
static class(className, context = document) {
return Array.from(context.getElementsByClassName(className));
}
// Element creation with enhanced features
static create(tag, options = {}) {
const element = document.createElement(tag);
// Set attributes
if (options.attrs) {
Object.entries(options.attrs).forEach(([key, value]) => {
element.setAttribute(key, value);
});
}
// Set properties
if (options.props) {
Object.entries(options.props).forEach(([key, value]) => {
element[key] = value;
});
}
// Set classes
if (options.class) {
if (Array.isArray(options.class)) {
element.classList.add(...options.class);
} else {
element.className = options.class;
}
}
// Set styles
if (options.style) {
if (typeof options.style === 'object') {
Object.assign(element.style, options.style);
} else {
element.style.cssText = options.style;
}
}
// Set content
if (options.text) {
element.textContent = options.text;
} else if (options.html) {
element.innerHTML = options.html;
}
// Add event listeners
if (options.events) {
Object.entries(options.events).forEach(([event, handler]) => {
element.addEventListener(event, handler);
});
}
// Add children
if (options.children) {
options.children.forEach(child => {
if (typeof child === 'string') {
element.appendChild(document.createTextNode(child));
} else if (child instanceof Node) {
element.appendChild(child);
}
});
}
return element;
}
// Enhanced element manipulation
static append(parent, ...children) {
const parentEl = typeof parent === 'string' ? this.$(parent) : parent;
if (!parentEl) return;
children.forEach(child => {
if (typeof child === 'string') {
parentEl.appendChild(document.createTextNode(child));
} else if (child instanceof Node) {
parentEl.appendChild(child);
}
});
return parentEl;
}
static prepend(parent, ...children) {
const parentEl = typeof parent === 'string' ? this.$(parent) : parent;
if (!parentEl) return;
children.reverse().forEach(child => {
if (typeof child === 'string') {
parentEl.insertBefore(document.createTextNode(child), parentEl.firstChild);
} else if (child instanceof Node) {
parentEl.insertBefore(child, parentEl.firstChild);
}
});
return parentEl;
}
static remove(element) {
const el = typeof element === 'string' ? this.$(element) : element;
if (el && el.parentNode) {
el.parentNode.removeChild(el);
}
return el;
}
static replace(oldElement, newElement) {
const oldEl = typeof oldElement === 'string' ? this.$(oldElement) : oldElement;
const newEl = typeof newElement === 'string' ? this.create('div', { html: newElement }) : newElement;
if (oldEl && oldEl.parentNode) {
oldEl.parentNode.replaceChild(newEl, oldEl);
}
return newEl;
}
// Class manipulation
static addClass(element, ...classes) {
const el = typeof element === 'string' ? this.$(element) : element;
if (el) el.classList.add(...classes);
return el;
}
static removeClass(element, ...classes) {
const el = typeof element === 'string' ? this.$(element) : element;
if (el) el.classList.remove(...classes);
return el;
}
static toggleClass(element, className, force) {
const el = typeof element === 'string' ? this.$(element) : element;
if (el) return el.classList.toggle(className, force);
return false;
}
static hasClass(element, className) {
const el = typeof element === 'string' ? this.$(element) : element;
return el ? el.classList.contains(className) : false;
}
// Style manipulation
static css(element, styles) {
const el = typeof element === 'string' ? this.$(element) : element;
if (!el) return;
if (typeof styles === 'string') {
return getComputedStyle(el).getPropertyValue(styles);
}
if (typeof styles === 'object') {
Object.entries(styles).forEach(([property, value]) => {
el.style[property] = value;
});
}
return el;
}
static show(element, display = 'block') {
const el = typeof element === 'string' ? this.$(element) : element;
if (el) el.style.display = display;
return el;
}
static hide(element) {
const el = typeof element === 'string' ? this.$(element) : element;
if (el) el.style.display = 'none';
return el;
}
static toggle(element, display = 'block') {
const el = typeof element === 'string' ? this.$(element) : element;
if (!el) return;
const currentDisplay = getComputedStyle(el).display;
el.style.display = currentDisplay === 'none' ? display : 'none';
return el;
}
// Attribute manipulation
static attr(element, name, value) {
const el = typeof element === 'string' ? this.$(element) : element;
if (!el) return;
if (value === undefined) {
return el.getAttribute(name);
}
if (value === null) {
el.removeAttribute(name);
} else {
el.setAttribute(name, value);
}
return el;
}
static data(element, name, value) {
const el = typeof element === 'string' ? this.$(element) : element;
if (!el) return;
const dataName = `data-${name}`;
if (value === undefined) {
return el.getAttribute(dataName);
}
if (value === null) {
el.removeAttribute(dataName);
} else {
el.setAttribute(dataName, value);
}
return el;
}
// Event handling with delegation support
static on(element, event, selector, handler) {
const el = typeof element === 'string' ? this.$(element) : element;
if (!el) return;
// If selector is actually the handler (no delegation)
if (typeof selector === 'function') {
handler = selector;
selector = null;
}
const eventHandler = selector ? (e) => {
const target = e.target.closest(selector);
if (target && el.contains(target)) {
handler.call(target, e);
}
} : handler;
el.addEventListener(event, eventHandler);
// Return cleanup function
return () => el.removeEventListener(event, eventHandler);
}
static off(element, event, handler) {
const el = typeof element === 'string' ? this.$(element) : element;
if (el) el.removeEventListener(event, handler);
return el;
}
static trigger(element, event, detail = {}) {
const el = typeof element === 'string' ? this.$(element) : element;
if (el) {
const customEvent = new CustomEvent(event, { detail, bubbles: true });
el.dispatchEvent(customEvent);
}
return el;
}
// Form utilities
static val(element, value) {
const el = typeof element === 'string' ? this.$(element) : element;
if (!el) return;
if (value === undefined) {
return el.value;
}
el.value = value;
return el;
}
static serialize(form) {
const formEl = typeof form === 'string' ? this.$(form) : form;
if (!formEl) return {};
const formData = new FormData(formEl);
const data = {};
for (const [key, value] of formData.entries()) {
if (data[key]) {
if (Array.isArray(data[key])) {
data[key].push(value);
} else {
data[key] = [data[key], value];
}
} else {
data[key] = value;
}
}
return data;
}
// Animation helpers
static fadeIn(element, duration = 300) {
const el = typeof element === 'string' ? this.$(element) : element;
if (!el) return Promise.resolve();
return new Promise(resolve => {
el.style.opacity = '0';
el.style.display = 'block';
el.style.transition = `opacity ${duration}ms ease`;
requestAnimationFrame(() => {
el.style.opacity = '1';
setTimeout(() => {
el.style.transition = '';
resolve(el);
}, duration);
});
});
}
static fadeOut(element, duration = 300) {
const el = typeof element === 'string' ? this.$(element) : element;
if (!el) return Promise.resolve();
return new Promise(resolve => {
el.style.transition = `opacity ${duration}ms ease`;
el.style.opacity = '0';
setTimeout(() => {
el.style.display = 'none';
el.style.transition = '';
resolve(el);
}, duration);
});
}
static slideDown(element, duration = 300) {
const el = typeof element === 'string' ? this.$(element) : element;
if (!el) return Promise.resolve();
return new Promise(resolve => {
const startHeight = el.scrollHeight;
el.style.height = '0px';
el.style.overflow = 'hidden';
el.style.display = 'block';
el.style.transition = `height ${duration}ms ease`;
requestAnimationFrame(() => {
el.style.height = startHeight + 'px';
setTimeout(() => {
el.style.height = '';
el.style.overflow = '';
el.style.transition = '';
resolve(el);
}, duration);
});
});
}
static slideUp(element, duration = 300) {
const el = typeof element === 'string' ? this.$(element) : element;
if (!el) return Promise.resolve();
return new Promise(resolve => {
el.style.height = el.scrollHeight + 'px';
el.style.overflow = 'hidden';
el.style.transition = `height ${duration}ms ease`;
requestAnimationFrame(() => {
el.style.height = '0px';
setTimeout(() => {
el.style.display = 'none';
el.style.height = '';
el.style.overflow = '';
el.style.transition = '';
resolve(el);
}, duration);
});
});
}
// Utility methods
static ready(callback) {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
} else {
callback();
}
}
static offset(element) {
const el = typeof element === 'string' ? this.$(element) : element;
if (!el) return { top: 0, left: 0 };
const rect = el.getBoundingClientRect();
return {
top: rect.top + window.pageYOffset,
left: rect.left + window.pageXOffset,
width: rect.width,
height: rect.height
};
}
static position(element) {
const el = typeof element === 'string' ? this.$(element) : element;
if (!el) return { top: 0, left: 0 };
return {
top: el.offsetTop,
left: el.offsetLeft,
width: el.offsetWidth,
height: el.offsetHeight
};
}
static scrollTo(element, options = {}) {
const el = typeof element === 'string' ? this.$(element) : element;
if (!el) return;
el.scrollIntoView({
behavior: options.behavior || 'smooth',
block: options.block || 'start',
inline: options.inline || 'nearest'
});
}
}
// Export for module usage
if (typeof module !== 'undefined' && module.exports) {
module.exports = MusPEDOM;
}
// Make available globally
if (typeof window !== 'undefined') {
window.MusPEDOM = MusPEDOM;
window.$ = MusPEDOM.$;
window.$$ = MusPEDOM.$$;
}