mirror of
https://git.sr.ht/~cadence/cloudtube
synced 2026-03-02 10:41:36 +00:00
First working video page
This commit is contained in:
parent
23a7da45d3
commit
cbc3a2bf67
21 changed files with 3935 additions and 78 deletions
137
html/static/js/elemjs/elemjs.js
Normal file
137
html/static/js/elemjs/elemjs.js
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
* Shortcut for querySelector.
|
||||
* @template {HTMLElement} T
|
||||
* @returns {T}
|
||||
*/
|
||||
const q = s => document.querySelector(s);
|
||||
/**
|
||||
* Shortcut for querySelectorAll.
|
||||
* @template {HTMLElement} T
|
||||
* @returns {T[]}
|
||||
*/
|
||||
const qa = s => document.querySelectorAll(s);
|
||||
|
||||
/**
|
||||
* An easier, chainable, object-oriented way to create and update elements
|
||||
* and children according to related data. Subclass ElemJS to create useful,
|
||||
* advanced data managers, or just use it inline to quickly make a custom element.
|
||||
*/
|
||||
class ElemJS {
|
||||
constructor(type) {
|
||||
if (type instanceof HTMLElement) {
|
||||
// If passed an existing element, bind to it
|
||||
this.bind(type);
|
||||
} else if (typeof type === "string") {
|
||||
// Otherwise, create a new detached element to bind to
|
||||
this.bind(document.createElement(type));
|
||||
} else {
|
||||
throw new Error("Cannot create an element of type ${type}")
|
||||
}
|
||||
this.children = [];
|
||||
}
|
||||
|
||||
/** Bind this construct to an existing element on the page. */
|
||||
bind(element) {
|
||||
this.element = element;
|
||||
this.element.js = this;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Add a class. */
|
||||
class() {
|
||||
for (let name of arguments) if (name) this.element.classList.add(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Remove a class. */
|
||||
removeClass() {
|
||||
for (let name of arguments) if (name) this.element.classList.remove(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Set a JS property on the element. */
|
||||
direct(name, value) {
|
||||
if (name) this.element[name] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Set an attribute on the element. */
|
||||
attribute(name, value) {
|
||||
if (name) this.element.setAttribute(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Set a style on the element. */
|
||||
style(name, value) {
|
||||
if (name) this.element.style[name] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Set the element's ID. */
|
||||
id(name) {
|
||||
if (name) this.element.id = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Attach a callback function to an event on the element. */
|
||||
on(name, callback) {
|
||||
this.element.addEventListener(name, callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Set the element's text. */
|
||||
text(name) {
|
||||
this.element.innerText = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Create a text node and add it to the element. */
|
||||
addText(name) {
|
||||
const node = document.createTextNode(name);
|
||||
this.element.appendChild(node);
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Set the element's HTML content. */
|
||||
html(name) {
|
||||
this.element.innerHTML = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add children to the element.
|
||||
* Children can either be an instance of ElemJS, in
|
||||
* which case the element will be appended as a child,
|
||||
* or a string, in which case the string will be added as a text node.
|
||||
* Each child should be a parameter to this method.
|
||||
*/
|
||||
child(...children) {
|
||||
for (const toAdd of children) {
|
||||
if (typeof toAdd === "object" && toAdd !== null) {
|
||||
// Should be an instance of ElemJS, so append as child
|
||||
toAdd.parent = this;
|
||||
this.element.appendChild(toAdd.element);
|
||||
this.children.push(toAdd);
|
||||
} else if (typeof toAdd === "string") {
|
||||
// Is a string, so add as text node
|
||||
this.addText(toAdd);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all children from the element.
|
||||
*/
|
||||
clearChildren() {
|
||||
this.children.length = 0;
|
||||
while (this.element.lastChild) this.element.removeChild(this.element.lastChild);
|
||||
}
|
||||
}
|
||||
|
||||
/** Shortcut for `new ElemJS`. */
|
||||
function ejs(tag) {
|
||||
return new ElemJS(tag);
|
||||
}
|
||||
|
||||
export {q, qa, ElemJS, ejs};
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/** @returns {HTMLElement} */
|
||||
export function q(s) {
|
||||
return document.querySelector(s)
|
||||
}
|
||||
|
||||
export class ElemJS {
|
||||
constructor(type) {
|
||||
if (type instanceof HTMLElement) this.bind(type)
|
||||
else this.bind(document.createElement(type))
|
||||
this.children = [];
|
||||
}
|
||||
bind(element) {
|
||||
/** @type {HTMLElement} */
|
||||
this.element = element
|
||||
// @ts-ignore
|
||||
this.element.js = this
|
||||
return this
|
||||
}
|
||||
class() {
|
||||
for (let name of arguments) if (name) this.element.classList.add(name);
|
||||
return this;
|
||||
}
|
||||
removeClass() {
|
||||
for (let name of arguments) if (name) this.element.classList.remove(name);
|
||||
return this;
|
||||
}
|
||||
direct(name, value) {
|
||||
if (name) this.element[name] = value;
|
||||
return this;
|
||||
}
|
||||
attribute(name, value) {
|
||||
if (name) this.element.setAttribute(name, value);
|
||||
return this;
|
||||
}
|
||||
style(name, value) {
|
||||
if (name) this.element.style[name] = value;
|
||||
return this;
|
||||
}
|
||||
id(name) {
|
||||
if (name) this.element.id = name;
|
||||
return this;
|
||||
}
|
||||
text(name) {
|
||||
this.element.innerText = name;
|
||||
return this;
|
||||
}
|
||||
addText(name) {
|
||||
const node = document.createTextNode(name)
|
||||
this.element.appendChild(node)
|
||||
return this
|
||||
}
|
||||
html(name) {
|
||||
this.element.innerHTML = name;
|
||||
return this;
|
||||
}
|
||||
event(name, callback) {
|
||||
this.element.addEventListener(name, event => callback(event))
|
||||
}
|
||||
child(toAdd, position) {
|
||||
if (typeof(toAdd) == "object") {
|
||||
toAdd.parent = this;
|
||||
if (typeof(position) == "number" && position >= 0) {
|
||||
this.element.insertBefore(toAdd.element, this.element.children[position]);
|
||||
this.children.splice(position, 0, toAdd);
|
||||
} else {
|
||||
this.element.appendChild(toAdd.element);
|
||||
this.children.push(toAdd);
|
||||
}
|
||||
} else if (typeof toAdd === "string") {
|
||||
this.text(toAdd)
|
||||
}
|
||||
return this;
|
||||
}
|
||||
clearChildren() {
|
||||
this.children.length = 0;
|
||||
while (this.element.lastChild) this.element.removeChild(this.element.lastChild);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue