Scenario generator for vore roleplay and story ideas.
https://scenario-generator.deliciousreya.net/responses
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
4.0 KiB
142 lines
4.0 KiB
import {
|
|
type ButtonFeatures,
|
|
ButtonType,
|
|
type CheckboxFeatures,
|
|
type ElementFeatures,
|
|
type FormFeatures,
|
|
HyperlinkDestination,
|
|
type HyperlinkFeatures,
|
|
type LabelFeatures,
|
|
type TemplateBuilder
|
|
} from '../common/template';
|
|
|
|
function tag<T extends keyof HTMLElementTagNameMap>(tagName: T, features: ElementFeatures, contents: Node[]): HTMLElementTagNameMap[T] {
|
|
const element = document.createElement(tagName)
|
|
if (typeof features.id !== "undefined") {
|
|
element.id = features.id
|
|
}
|
|
if (typeof features.classes !== "undefined") {
|
|
if (typeof features.classes === "string") {
|
|
element.classList.add(features.classes)
|
|
} else {
|
|
for (const className of features.classes) {
|
|
element.classList.add(className)
|
|
}
|
|
}
|
|
}
|
|
if (typeof features.data !== "undefined") {
|
|
for (const [key, value] of features.data) {
|
|
element.dataset[key] = value
|
|
}
|
|
}
|
|
for (const node of contents) {
|
|
element.appendChild(node)
|
|
}
|
|
return element
|
|
}
|
|
|
|
class DOMTemplateBuilderImpl implements TemplateBuilder<Node> {
|
|
makeButton(features: ButtonFeatures, ...contents: Node[]): HTMLButtonElement {
|
|
const element = tag('button', features, contents)
|
|
element.classList.add("button")
|
|
element.type = features.type ?? ButtonType.Button
|
|
if (typeof features.name === "string") {
|
|
element.name = features.name
|
|
}
|
|
if (typeof features.value === "string") {
|
|
element.value = features.value
|
|
}
|
|
return element
|
|
}
|
|
|
|
makeCheckbox(features: CheckboxFeatures, ...contents: Node[]): HTMLInputElement {
|
|
const element = tag('input', features, contents)
|
|
element.type = "checkbox"
|
|
element.name = features.name
|
|
if (features.checked) {
|
|
element.checked = true
|
|
}
|
|
if (typeof features.value === "string") {
|
|
element.value = features.value
|
|
}
|
|
return element
|
|
}
|
|
|
|
makeDiv(features: ElementFeatures, ...contents: Node[]): HTMLDivElement {
|
|
return tag('div', features, contents);
|
|
}
|
|
|
|
makeFooter(features: ElementFeatures, ...contents: Node[]): HTMLElement {
|
|
return tag('footer', features, contents);
|
|
}
|
|
|
|
makeForm(features: FormFeatures, ...contents: Node[]): HTMLFormElement {
|
|
const element = tag('form', features, contents)
|
|
element.action = features.action
|
|
element.method = features.method
|
|
return element;
|
|
}
|
|
|
|
makeHeader(features: ElementFeatures, ...contents: Node[]): HTMLElement {
|
|
return tag('header', features, contents)
|
|
}
|
|
|
|
makeHeading1(features: ElementFeatures, ...contents: Node[]): HTMLHeadingElement {
|
|
return tag('h1', features, contents);
|
|
}
|
|
|
|
makeHeading2(features: ElementFeatures, ...contents: Node[]): HTMLHeadingElement {
|
|
return tag('h2', features, contents);
|
|
}
|
|
|
|
makeHyperlink(features: HyperlinkFeatures, ...contents: Node[]): HTMLAnchorElement {
|
|
const element = tag('a', features, contents)
|
|
element.href = features.url
|
|
if (features.destination === HyperlinkDestination.External) {
|
|
element.rel = "external nofollow noreferrer"
|
|
}
|
|
if (features.asButton) {
|
|
element.classList.add("button")
|
|
element.draggable = false
|
|
}
|
|
return element;
|
|
}
|
|
|
|
makeLabel(features: LabelFeatures, ...contents: Node[]): HTMLLabelElement {
|
|
const element = tag('label', features, contents)
|
|
if (typeof features.forId === "string") {
|
|
element.htmlFor = features.forId
|
|
}
|
|
return element;
|
|
}
|
|
|
|
makeListItem(features: ElementFeatures, ...contents: Node[]): HTMLLIElement {
|
|
return tag('li', features, contents)
|
|
}
|
|
|
|
makeNav(features: ElementFeatures, ...contents: Node[]): HTMLElement {
|
|
return tag('nav', features, contents)
|
|
}
|
|
|
|
makeNoscript(features: ElementFeatures, ...contents: Node[]): HTMLElement {
|
|
return tag('noscript', features, contents);
|
|
}
|
|
|
|
makeParagraph(features: ElementFeatures, ...contents: Node[]): HTMLParagraphElement {
|
|
return tag('p', features, contents);
|
|
}
|
|
|
|
makeSpan(features: ElementFeatures, ...contents: Node[]): HTMLSpanElement {
|
|
return tag('span', features, contents);
|
|
}
|
|
|
|
makeText(text: string): Text {
|
|
return document.createTextNode(text);
|
|
}
|
|
|
|
makeUnorderedList(features: ElementFeatures, ...contents: Node[]): HTMLUListElement {
|
|
return tag('ul', features, contents);
|
|
}
|
|
}
|
|
|
|
export const DOMTemplateBuilder = new DOMTemplateBuilderImpl()
|
|
|