Initial commit
This commit is contained in:
264
src/fluent-dom-esm.ts
Normal file
264
src/fluent-dom-esm.ts
Normal file
@@ -0,0 +1,264 @@
|
||||
/**
|
||||
* 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";
|
||||
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;
|
||||
})();
|
13
src/fluent-dom-esm.type-guards.ts
Normal file
13
src/fluent-dom-esm.type-guards.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { FluentDomObject } from "./fluent-dom-esm.types";
|
||||
|
||||
export const isFluentDomObject = (value: any): value is FluentDomObject =>
|
||||
!!value.fluentDom;
|
||||
|
||||
export const isHTMLElement = (value: any): value is HTMLElement =>
|
||||
!!value.nodeType;
|
||||
|
||||
export const isNumber = (value: any): value is number =>
|
||||
typeof value === "number";
|
||||
|
||||
export const isString = (value: any): value is string =>
|
||||
typeof value === "string";
|
46
src/fluent-dom-esm.types.ts
Normal file
46
src/fluent-dom-esm.types.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
export interface FluentDomObject {
|
||||
fluentDom: string;
|
||||
|
||||
a: (name: string, value?: string) => FluentDomObject | string | null;
|
||||
app: (obj: FluentDomObject | HTMLElement | string) => FluentDomObject;
|
||||
append: (obj: FluentDomObject | HTMLElement | string) => FluentDomObject;
|
||||
attr: (name: string, value?: string) => FluentDomObject | string | null;
|
||||
c: (tagName: string) => FluentDomObject;
|
||||
create: (tagName: string) => FluentDomObject;
|
||||
className: (className?: string) => FluentDomObject | string | null;
|
||||
clear: () => FluentDomObject;
|
||||
cls: (className?: string) => FluentDomObject | string | null;
|
||||
clr: () => FluentDomObject;
|
||||
h: (url?: string) => FluentDomObject | string | null;
|
||||
href: (url?: string) => FluentDomObject | string | null;
|
||||
html: (content?: string) => string | FluentDomObject;
|
||||
id: (id?: string) => FluentDomObject | string | null;
|
||||
l: (
|
||||
type: keyof HTMLElementEventMap,
|
||||
listener: () => {},
|
||||
optionsOrUseCapture?: boolean | object,
|
||||
) => FluentDomObject;
|
||||
listen: (
|
||||
type: keyof HTMLElementEventMap,
|
||||
listener: () => {},
|
||||
optionsOrUseCapture?: boolean | object,
|
||||
) => FluentDomObject;
|
||||
ohtml: (content?: string) => string | FluentDomObject;
|
||||
s: (
|
||||
prop?: CSSStyleDeclaration | string,
|
||||
value?: string,
|
||||
) => FluentDomObject | CSSStyleDeclaration | string | undefined;
|
||||
style: (
|
||||
prop?: CSSStyleDeclaration | string,
|
||||
value?: string,
|
||||
) => FluentDomObject | CSSStyleDeclaration | string | undefined;
|
||||
t: (text?: string) => FluentDomObject | string;
|
||||
text: (text?: string) => FluentDomObject | string;
|
||||
title: (title?: string) => FluentDomObject | string | null;
|
||||
toDom: () => HTMLElement | null;
|
||||
unlisten: (
|
||||
type: keyof HTMLElementEventMap,
|
||||
listener: () => {},
|
||||
optionsOrUseCapture?: boolean | object,
|
||||
) => FluentDomObject;
|
||||
}
|
1
src/license-begin.txt
Normal file
1
src/license-begin.txt
Normal file
@@ -0,0 +1 @@
|
||||
// @license magnet:?xt=urn:btih:723febf9f6185544f57f0660a41489c7d6b4931b&dn=wtfpl.txt
|
1
src/license-end.txt
Normal file
1
src/license-end.txt
Normal file
@@ -0,0 +1 @@
|
||||
// @license-end
|
Reference in New Issue
Block a user