265 lines
7.6 KiB
TypeScript
265 lines
7.6 KiB
TypeScript
/**
|
|
* fluent-dom-esm v1.1.0
|
|
*
|
|
* Fluent DOM Manipulation, adapted to ESM and cranked up to v1.1(.0).
|
|
*
|
|
* https://git.itsericwoodward.com/eric/fluent-dom-esm
|
|
*
|
|
* v1.1.0 Copyright (c) 2025 Eric Woodward
|
|
* Original copyright (c) 2009 Tommy Montgomery (https://glacius.tmont.com/articles/fluent-dom-manipulation-in-javascript)
|
|
*
|
|
* Released under the WTFPL (Do What the Fuck You Want to Public License)
|
|
*
|
|
* @author Eric Woodward (v1.1.0 update)
|
|
* @author Tommy Montgomery (original)
|
|
* @license http://sam.zoy.org/wtfpl/
|
|
*/
|
|
|
|
import type { FluentDomObject } from "./fluent-dom-esm.types";
|
|
|
|
import { version } from "../package.json" with { type: "json" };
|
|
import {
|
|
isFluentDomObject,
|
|
isHTMLElement,
|
|
isNumber,
|
|
isString,
|
|
} from "./fluent-dom-esm.type-guards";
|
|
|
|
/**
|
|
* IIFE that creates the FluentDomObject as default export
|
|
*/
|
|
export default (function () {
|
|
/**
|
|
* Wraps provided element in a FluentDomObject which is then returned
|
|
*/
|
|
const FluentDom = function (node: HTMLElement) {
|
|
return new (FluentDomInternal as any)(node);
|
|
};
|
|
|
|
/**
|
|
* Creates a new HTML element which is wrapped in a FluentDomObject and returned
|
|
*/
|
|
FluentDom.create = FluentDom.c = function (tagName: string) {
|
|
const f = new (FluentDomInternal as any)();
|
|
f.create(tagName);
|
|
return f;
|
|
};
|
|
|
|
/**
|
|
* The internal representation of the FluentDomObject
|
|
*/
|
|
const FluentDomInternal = function (
|
|
this: FluentDomObject,
|
|
node?: HTMLElement,
|
|
) {
|
|
let root = node || null;
|
|
|
|
// adds several new features
|
|
this.fluentDom = version;
|
|
|
|
/**
|
|
* Gets or sets the named attribute on the wrapped HTMLElement
|
|
*/
|
|
this.a = this.attr = function (name, value) {
|
|
if (!root || (value && !root.setAttribute)) {
|
|
throw new Error("Cannot set an attribute on a non-element");
|
|
}
|
|
|
|
if (!value) return root.getAttribute(name);
|
|
|
|
root.setAttribute(name, value);
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Appends value to wrapped HTMLElement
|
|
*/
|
|
this.app = this.append = function (value) {
|
|
if (!root || !root?.appendChild) {
|
|
throw new Error("Cannot append to a non-element");
|
|
}
|
|
|
|
const type = typeof value;
|
|
if (type === "object") {
|
|
if (isFluentDomObject(value)) {
|
|
const domVal = value.toDom();
|
|
if (domVal !== null) root.appendChild(domVal);
|
|
} else if (isHTMLElement(value)) {
|
|
root.appendChild(value);
|
|
} else {
|
|
throw new Error(
|
|
"Invalid argument: not an HTMLElement or FluentDom object",
|
|
);
|
|
}
|
|
} else if (isNumber(value) || isString(value)) {
|
|
root.appendChild(document.createTextNode(`${value}`));
|
|
} else {
|
|
throw new Error(
|
|
`Invalid argument: not a valid type (${typeof value})`,
|
|
);
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Creates a new wrapped HTMLElement of the indicated tag
|
|
*/
|
|
this.c = this.create = function (tagName) {
|
|
root = document.createElement(tagName);
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Gets or sets the "class" attribute on the wrapped HTMLElement
|
|
*/
|
|
this.className = this.cls = function (value) {
|
|
return this.attr("class", value);
|
|
};
|
|
|
|
/**
|
|
* Sets the wrapped HTMLElement to null
|
|
*/
|
|
this.clear = function () {
|
|
root = null;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Gets or sets the "href" attribute on the wrapped HTMLElement
|
|
*/
|
|
this.h = this.href = function (link) {
|
|
return this.attr("href", link);
|
|
};
|
|
|
|
/**
|
|
* Gets or sets the wrapped HTMLElement's "innerHTML" property
|
|
*/
|
|
this.html = function (content) {
|
|
if (!root) {
|
|
throw new Error(
|
|
"Cannot get or set innerHTML for a non-element",
|
|
);
|
|
}
|
|
|
|
if (!content) return root.innerHTML;
|
|
|
|
root.innerHTML = content;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Gets or sets the "id" attribute on the wrapped HTMLElement
|
|
*/
|
|
this.id = function (value) {
|
|
return this.attr("id", value);
|
|
};
|
|
|
|
/**
|
|
* Passes props to the "addEventListener" function on the wrapped HTMLElement
|
|
*/
|
|
this.l = this.listen = function (...props) {
|
|
if (!root || !root.addEventListener) {
|
|
throw new Error("Cannot addEventListener to a non-element");
|
|
}
|
|
|
|
root.addEventListener(...props);
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Gets or sets the wrapped HTMLElement's "outerHTML" property
|
|
*/
|
|
this.ohtml = function (content) {
|
|
if (!root) {
|
|
throw new Error(
|
|
"Cannot get or set outerHTML for a non-element",
|
|
);
|
|
}
|
|
|
|
if (!content) return root.outerHTML;
|
|
|
|
root.outerHTML = content;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Gets or sets a one or more style attributes on the wrapped HTMLElement
|
|
*/
|
|
this.s = this.style = function (prop, value) {
|
|
if (!root) {
|
|
throw new Error("Cannot get or set style for a non-element");
|
|
}
|
|
|
|
if (typeof prop === "undefined") return root.style;
|
|
|
|
if (typeof value !== "undefined") {
|
|
root.style[prop as any] = value;
|
|
return this;
|
|
}
|
|
|
|
if (typeof prop === "string") return root.style[prop as any];
|
|
|
|
if (typeof prop !== "object") {
|
|
throw new Error(
|
|
`Invalid argument: "prop" must be string or object (found ${typeof prop})`,
|
|
);
|
|
}
|
|
|
|
Object.keys(prop).forEach((key) => {
|
|
(root as HTMLElement).style[key as any] = prop[key as any];
|
|
});
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Gets or sets the wrapped HTMLElement's "innerText" property
|
|
*/
|
|
this.t = this.text = function (text) {
|
|
if (!root) {
|
|
throw new Error(
|
|
"Cannot get or set innerText for a non-element",
|
|
);
|
|
}
|
|
|
|
if (typeof text === "undefined") return root.innerText;
|
|
|
|
return this.append(text);
|
|
};
|
|
|
|
/**
|
|
* Gets or sets the "title" attribute on the wrapped HTMLElement
|
|
*/
|
|
this.title = function (value) {
|
|
if (!root) {
|
|
throw new Error(
|
|
"Cannot get or set outerHTML for a non-element",
|
|
);
|
|
}
|
|
|
|
return this.attr("title", value);
|
|
};
|
|
|
|
/**
|
|
* Gets the wrapped HTMLElement itself
|
|
*/
|
|
this.toDom = function () {
|
|
return root;
|
|
};
|
|
|
|
/**
|
|
* Passes props to the "removeEventListener" function on the wrapped HTMLElement
|
|
*/
|
|
this.unlisten = function (...props) {
|
|
if (!root || !root.removeEventListener) {
|
|
throw new Error("Cannot removeEventListener on a non-element");
|
|
}
|
|
|
|
root.removeEventListener(...props);
|
|
return this;
|
|
};
|
|
};
|
|
|
|
return FluentDom;
|
|
})() as unknown as FluentDomObject;
|