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.
 
 

131 lines
4.3 KiB

import {
type ButtonFeatures,
ButtonType,
type CheckboxFeatures,
type ElementFeatures, extendClasses,
type FormFeatures,
HyperlinkDestination,
type HyperlinkFeatures,
type LabelFeatures,
type TemplateBuilder
} from '../../common/template';
import escapeHTML from 'escape-html';
import { kebabCase } from 'change-case';
function tag(tagName: string, features: ElementFeatures, attributes: string[], contents: string[]): string {
if (typeof features.id !== "undefined") {
attributes.push(`id="${escapeHTML(features.id)}"`)
}
if (typeof features.classes !== "undefined") {
attributes.push(`class="${typeof features.classes === "string"
? escapeHTML(features.classes)
: Array.from(features.classes).map(escapeHTML).join(" ")}"`)
}
if (typeof features.data !== "undefined") {
for (const [key, value] of features.data) {
attributes.push(`data-${escapeHTML(kebabCase(key))}="${escapeHTML(value)}"`)
}
}
return `<${tagName}${attributes.length === 0 ? "" : " " + attributes.join(" ")}>${contents.join("")}</${tagName}>`
}
class StringTemplateBuilderImpl implements TemplateBuilder<string> {
makeButton(features: ButtonFeatures, ...contents: string[]): string {
const attributes = [
`type="${escapeHTML(features.type ?? ButtonType.Button)}"`,
]
if (typeof features.name === "string") {
attributes.push(`name="${escapeHTML(features.name)}"`)
}
if (typeof features.value === "string") {
attributes.push(`value="${escapeHTML(features.value)}"`)
}
return tag('button', {...features, classes: extendClasses(features.classes, "button")}, attributes, contents)
}
makeCheckbox(features: CheckboxFeatures, ...contents: string[]): string {
const attributes = [`type="checkbox"`, `name="${escapeHTML(features.name)}"`]
if (features.checked) {
attributes.push("checked")
}
if (typeof features.value === "string") {
attributes.push(`value="${escapeHTML(features.value)}"`)
}
return tag('input', features, attributes, contents);
}
makeDiv(features: ElementFeatures, ...contents: string[]): string {
return tag('div', features, [], contents);
}
makeFooter(features: ElementFeatures, ...contents: string[]): string {
return tag('footer', features, [], contents);
}
makeForm(features: FormFeatures, ...contents: string[]): string {
const attributes = [`action="${escapeHTML(features.action)}"`, `method="${escapeHTML(features.method)}"`]
return tag('form', features, attributes, contents);
}
makeHeader(features: ElementFeatures, ...contents: string[]): string {
return tag('header', features, [], contents)
}
makeHeading1(features: ElementFeatures, ...contents: string[]): string {
return tag('h1', features, [], contents);
}
makeHeading2(features: ElementFeatures, ...contents: string[]): string {
return tag('h2', features, [], contents);
}
makeHyperlink(features: HyperlinkFeatures, ...contents: string[]): string {
const attributes = [`href="${escapeHTML(features.url)}"`]
if (features.destination === HyperlinkDestination.External) {
attributes.push(`rel="external nofollow noreferrer"`)
}
if (features.asButton) {
attributes.push(`draggable="false"`)
}
return tag('a', {...features, classes: extendClasses(features.classes, features.asButton ? ["button"] : [])}, attributes, contents);
}
makeLabel(features: LabelFeatures, ...contents: string[]): string {
const attributes = []
if (typeof features.forId === "string") {
attributes.push(`for="${escapeHTML(features.forId)}"`)
}
return tag('label', features, attributes, contents);
}
makeListItem(features: ElementFeatures, ...contents: string[]): string {
return tag('li', features, [], contents)
}
makeNav(features: ElementFeatures, ...contents: string[]): string {
return tag('nav', features, [], contents)
}
makeNoscript(features: ElementFeatures, ...contents: string[]): string {
return tag('noscript', features, [], contents);
}
makeParagraph(features: ElementFeatures, ...contents: string[]): string {
return tag('p', features, [], contents);
}
makeSpan(features: ElementFeatures, ...contents: string[]): string {
return tag('span', features, [], contents);
}
makeText(text: string): string {
return escapeHTML(text);
}
makeUnorderedList(features: ElementFeatures, ...contents: string[]): string {
return tag('ul', features, [], contents);
}
}
export const StringTemplateBuilder = new StringTemplateBuilderImpl()