Documentation
¶
Overview ¶
Package js provides type-safe JavaScript string generation for HTML event attributes.
This package provides a builder API for generating JavaScript code strings suitable for use in HTML event handler attributes like onclick, onchange, etc. It integrates seamlessly with the github.com/jeffh/htmlgen/h package.
Quick Start ¶
The most common use case is adding event handlers to HTML elements:
import (
"github.com/jeffh/htmlgen/h"
"github.com/jeffh/htmlgen/js"
)
// Simple click handler
button := h.Button(
js.OnClick(js.ExprStmt(js.Alert(js.String("Hello!")))),
h.Text("Say Hello"),
)
// Output: <button onclick="alert("Hello!")">Say Hello</button>
Type System ¶
The package uses three core interfaces to ensure type safety:
- Expr - JavaScript expressions that produce values (e.g., "1 + 2", "x.foo")
- Stmt - JavaScript statements that perform actions (e.g., "let x = 1", "x++")
- Callable - Expressions that can have properties accessed or methods called
This type system prevents accidentally passing raw Go strings where JavaScript is expected. The only way to inject arbitrary JavaScript is through the explicit Raw escape hatch.
Creating Values ¶
Use these functions to create JavaScript literals safely:
js.String("hello") // "hello" (JSON-escaped, prevents XSS)
js.Int(42) // 42
js.Float(3.14) // 3.14
js.Bool(true) // true
js.Null() // null
js.Undefined() // undefined
For complex values, use JSON, Array, or Object:
js.JSON(map[string]int{"a": 1}) // {"a":1}
js.Array(js.Int(1), js.Int(2), js.Int(3)) // [1, 2, 3]
js.Object(
js.Pair("name", js.String("John")),
js.Pair("age", js.Int(30)),
) // {"name": "John", "age": 30}
To reference JavaScript variables, use Ident:
js.Ident("myVariable") // myVariable
js.Ident("window") // window
js.This() // this
Property and Method Access ¶
Access properties with Prop and call methods with Method:
js.Prop(js.Ident("document"), "body")
// document.body
js.Method(js.Ident("console"), "log", js.String("hello"))
// console.log("hello")
js.Prop(js.Prop(js.Ident("event"), "target"), "value")
// event.target.value
For array/computed property access, use Index:
js.Index(js.Ident("arr"), js.Int(0)) // arr[0]
js.Index(js.Ident("obj"), js.String("key")) // obj["key"]
Optional chaining is supported with OptionalProp and OptionalCall:
js.OptionalProp(js.Ident("user"), "name") // user?.name
js.OptionalCall(js.Ident("obj"), "method") // obj?.method()
Operators ¶
All standard JavaScript operators are available:
// Arithmetic
js.Add(js.Int(1), js.Int(2)) // (1 + 2)
js.Sub(js.Int(5), js.Int(3)) // (5 - 3)
js.Mul(js.Int(4), js.Int(2)) // (4 * 2)
js.Div(js.Int(10), js.Int(2)) // (10 / 2)
// Comparison (strict by default)
js.Eq(js.Ident("x"), js.Int(5)) // (x === 5)
js.NotEq(js.Ident("x"), js.Null()) // (x !== null)
js.Lt(js.Ident("x"), js.Int(10)) // (x < 10)
js.Gt(js.Ident("x"), js.Int(0)) // (x > 0)
// Logical
js.And(js.Ident("a"), js.Ident("b")) // (a && b)
js.Or(js.Ident("a"), js.Ident("b")) // (a || b)
js.Not(js.Ident("x")) // !x
// Ternary
js.Ternary(js.Ident("cond"), js.String("yes"), js.String("no"))
// (cond ? "yes" : "no")
// Nullish coalescing
js.NullishCoalesce(js.Ident("x"), js.String("default"))
// (x ?? "default")
Statements ¶
Create JavaScript statements for use in handlers:
// Variable declarations
js.Let("x", js.Int(5)) // let x = 5
js.Const("PI", js.Float(3.14)) // const PI = 3.14
// Assignment
js.Assign(js.Ident("x"), js.Int(10)) // x = 10
js.AddAssign(js.Ident("x"), js.Int(1)) // x += 1
// Increment/decrement
js.Incr(js.Ident("count")) // count++
js.Decr(js.Ident("count")) // count--
// Conditionals
js.If(js.Eq(js.Ident("x"), js.Int(0)),
js.Return(js.Null()),
)
// if (x === 0) { return null }
To use an expression as a statement, wrap it with ExprStmt:
js.ExprStmt(js.ConsoleLog(js.String("hello")))
// console.log("hello")
Event Handlers ¶
The Handler function combines statements into a handler string:
handler := js.Handler(
js.ExprStmt(js.PreventDefault()),
js.Let("value", js.EventValue()),
js.ExprStmt(js.ConsoleLog(js.Ident("value"))),
)
// "event.preventDefault(); let value = event.target.value; console.log(value)"
For convenience, use the On* functions to create h.Attribute values directly:
js.OnClick(...) // onclick="..." js.OnInput(...) // oninput="..." js.OnChange(...) // onchange="..." js.OnSubmit(...) // onsubmit="..." js.OnKeyDown(...) // onkeydown="..." js.OnLoad(...) // onload="..."
For custom events, use On:
js.On("touchstart", js.ExprStmt(js.ConsoleLog(js.String("touched"))))
// ontouchstart="console.log(\"touched\")"
Built-in Helpers ¶
The package provides helpers for common JavaScript patterns:
Console:
js.ConsoleLog(js.String("message")) // console.log("message")
js.ConsoleError(js.String("error")) // console.error("error")
js.ConsoleWarn(js.String("warning")) // console.warn("warning")
Document:
js.GetElementById(js.String("myId")) // document.getElementById("myId")
js.QuerySelector(js.String(".myClass")) // document.querySelector(".myClass")
Event handling:
js.PreventDefault() // event.preventDefault() js.StopPropagation() // event.stopPropagation() js.EventTarget() // event.target js.EventValue() // event.target.value js.EventChecked() // event.target.checked js.EventKey() // event.key
Navigation:
js.Navigate(js.String("/home")) // location.href = "/home"
js.Reload() // location.reload()
js.HistoryBack() // history.back()
DOM manipulation:
js.ClassListAdd(js.Ident("el"), js.String("active"))
// el.classList.add("active")
js.ClassListToggle(js.Ident("el"), js.String("hidden"))
// el.classList.toggle("hidden")
js.SetStyle(js.Ident("el"), "backgroundColor", js.String("red"))
// el.style.backgroundColor = "red"
Arrow Functions ¶
Create arrow functions for callbacks:
// Expression body
js.ArrowFunc([]string{"x"}, js.Mul(js.Ident("x"), js.Int(2)))
// x => (x * 2)
// Statement body
js.ArrowFuncStmts([]string{"x"},
js.Let("result", js.Mul(js.Ident("x"), js.Int(2))),
js.Return(js.Ident("result")),
)
// x => { let result = (x * 2); return result }
// Async arrow functions
js.AsyncArrowFunc([]string{}, js.Await(js.Fetch(js.String("/api"))))
// async () => await fetch("/api")
Template Literals ¶
Create template literals with Template:
js.Template("Hello, ", js.Ident("name"), "!")
// `Hello, ${name}!`
Promises and Async ¶
js.Await(js.Fetch(js.String("/api/data")))
// await fetch("/api/data")
js.PromiseThen(
js.Fetch(js.String("/api")),
js.ArrowFunc([]string{"r"}, js.Method(js.Ident("r"), "json")),
)
// fetch("/api").then(r => r.json())
Raw JavaScript Escape Hatch ¶
When you need to inject arbitrary JavaScript that isn't covered by the API, use Raw. This is the ONLY way to inject raw JavaScript and must be used explicitly:
js.Raw("myCustomFunction()")
js.Raw("window.gtag('event', 'click')")
Use Raw sparingly, as it bypasses type safety. The API covers most common use cases, so prefer using the type-safe builders when possible.
Complete Examples ¶
Form submission with validation:
h.Form(
js.OnSubmit(
js.ExprStmt(js.PreventDefault()),
js.Let("email", js.Prop(js.GetElementById(js.String("email")), "value")),
js.If(js.Eq(js.Ident("email"), js.String("")),
js.ExprStmt(js.Alert(js.String("Email is required"))),
js.ReturnVoid(),
),
js.ExprStmt(js.Method(js.This(), "submit")),
),
// ... form fields
)
Toggle visibility:
h.Button(
js.OnClick(
js.ExprStmt(js.ClassListToggle(
js.GetElementById(js.String("panel")),
js.String("hidden"),
)),
),
h.Text("Toggle Panel"),
)
Live character count:
h.Textarea(
h.Attrs("id", "message", "maxlength", "200"),
js.OnInput(
js.Assign(
js.Prop(js.GetElementById(js.String("charCount")), "textContent"),
js.Template(js.Prop(js.EventValue(), "length"), " / 200"),
),
),
)
Keyboard shortcuts:
h.Body(
js.OnKeyDown(
js.If(js.And(js.EventCtrlKey(), js.Eq(js.EventKey(), js.String("s"))),
js.ExprStmt(js.PreventDefault()),
js.ExprStmt(js.Raw("saveDocument()")),
),
),
)
Fetch with error handling:
h.Button(
js.OnClick(
js.ExprStmt(
js.PromiseCatch(
js.PromiseThen(
js.Fetch(js.String("/api/data")),
js.ArrowFunc([]string{"r"}, js.Method(js.Ident("r"), "json")),
),
js.ArrowFunc([]string{"err"}, js.ConsoleError(js.Ident("err"))),
),
),
),
h.Text("Load Data"),
)
Example (ArrayMethods) ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Chain array methods
expr := js.Method(
js.Method(js.Ident("items"), "filter", js.ArrowFunc([]string{"x"}, js.Prop(js.Ident("x"), "active"))),
"map",
js.ArrowFunc([]string{"x"}, js.Prop(js.Ident("x"), "name")),
)
fmt.Println(js.ExprHandler(expr))
}
Output: items.filter(x => x.active).map(x => x.name)
Example (ArrowFunction) ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Create an arrow function for setTimeout
expr := js.SetTimeout(
js.ArrowFunc(nil, js.ConsoleLog(js.String("Delayed!"))),
js.Int(1000),
)
fmt.Println(js.ExprHandler(expr))
}
Output: setTimeout(() => console.log("Delayed!"), 1000)
Example (BasicClickHandler) ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
handler := js.Handler(
js.ExprStmt(js.Alert(js.String("Hello, World!"))),
)
fmt.Println(handler)
}
Output: alert("Hello, World!")
Example (ConditionalLogic) ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Show alert if input is empty
handler := js.Handler(
js.If(js.Eq(js.EventValue(), js.String("")),
js.ExprStmt(js.Alert(js.String("Please enter a value"))),
js.ReturnVoid(),
),
)
fmt.Println(handler)
}
Output: if ((event.target.value === "")) { alert("Please enter a value"); return }
Example (EventValue) ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Transform input to uppercase as the user types
handler := js.Handler(
js.Assign(
js.Prop(js.EventTarget(), "value"),
js.Method(js.EventValue(), "toUpperCase"),
),
)
fmt.Println(handler)
}
Output: event.target.value = event.target.value.toUpperCase()
Example (KeyboardShortcut) ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Handle Ctrl+S keyboard shortcut
handler := js.Handler(
js.If(js.And(js.EventCtrlKey(), js.Eq(js.EventKey(), js.String("s"))),
js.ExprStmt(js.PreventDefault()),
js.ExprStmt(js.ConsoleLog(js.String("Save triggered"))),
),
)
fmt.Println(handler)
}
Output: if ((event.ctrlKey && (event.key === "s"))) { event.preventDefault(); console.log("Save triggered") }
Example (ObjectLiteral) ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Create a JavaScript object
obj := js.Object(
js.Pair("name", js.String("John")),
js.Pair("age", js.Int(30)),
js.Pair("active", js.Bool(true)),
)
fmt.Println(js.ExprHandler(obj))
}
Output: {"name": "John", "age": 30, "active": true}
Example (PreventDefault) ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
handler := js.Handler(
js.ExprStmt(js.PreventDefault()),
js.ExprStmt(js.ConsoleLog(js.String("Form submitted"))),
)
fmt.Println(handler)
}
Output: event.preventDefault(); console.log("Form submitted")
Example (PromiseChain) ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Fetch with promise chain
expr := js.PromiseCatch(
js.PromiseThen(
js.Fetch(js.String("/api/users")),
js.ArrowFunc([]string{"r"}, js.Method(js.Ident("r"), "json")),
),
js.ArrowFunc([]string{"e"}, js.ConsoleError(js.Ident("e"))),
)
fmt.Println(js.ExprHandler(expr))
}
Output: fetch("/api/users").then(r => r.json()).catch(e => console.error(e))
Example (RawEscapeHatch) ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Use Raw for custom JavaScript
handler := js.Handler(
js.ExprStmt(js.Raw("gtag('event', 'button_click')")),
)
fmt.Println(handler)
}
Output: gtag('event', 'button_click')
Example (TemplateLiteral) ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Create a template literal with interpolation
expr := js.Template("Hello, ", js.Ident("name"), "! You have ", js.Ident("count"), " messages.")
fmt.Println(js.ExprHandler(expr))
}
Output: `Hello, ${name}! You have ${count} messages.`
Example (TernaryOperator) ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Use ternary for conditional text
expr := js.Ternary(
js.Ident("isLoggedIn"),
js.String("Logout"),
js.String("Login"),
)
fmt.Println(js.ExprHandler(expr))
}
Output: (isLoggedIn ? "Logout" : "Login")
Example (ToggleClass) ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Toggle a CSS class on an element
handler := js.Handler(
js.ExprStmt(js.ClassListToggle(
js.GetElementById(js.String("menu")),
js.String("open"),
)),
)
fmt.Println(handler)
}
Output: document.getElementById("menu").classList.toggle("open")
Index ¶
- Variables
- func ExprHandler(expr Expr) string
- func Handler(stmts ...Stmt) string
- func On(event string, stmts ...Stmt) h.Attribute
- func OnAfterPrint(stmts ...Stmt) h.Attribute
- func OnAnimationEnd(stmts ...Stmt) h.Attribute
- func OnAnimationIteration(stmts ...Stmt) h.Attribute
- func OnAnimationStart(stmts ...Stmt) h.Attribute
- func OnBeforePrint(stmts ...Stmt) h.Attribute
- func OnBeforeUnload(stmts ...Stmt) h.Attribute
- func OnBlur(stmts ...Stmt) h.Attribute
- func OnCanPlay(stmts ...Stmt) h.Attribute
- func OnCanPlayThrough(stmts ...Stmt) h.Attribute
- func OnChange(stmts ...Stmt) h.Attribute
- func OnClick(stmts ...Stmt) h.Attribute
- func OnContextMenu(stmts ...Stmt) h.Attribute
- func OnCopy(stmts ...Stmt) h.Attribute
- func OnCut(stmts ...Stmt) h.Attribute
- func OnDblClick(stmts ...Stmt) h.Attribute
- func OnDrag(stmts ...Stmt) h.Attribute
- func OnDragEnd(stmts ...Stmt) h.Attribute
- func OnDragEnter(stmts ...Stmt) h.Attribute
- func OnDragLeave(stmts ...Stmt) h.Attribute
- func OnDragOver(stmts ...Stmt) h.Attribute
- func OnDragStart(stmts ...Stmt) h.Attribute
- func OnDrop(stmts ...Stmt) h.Attribute
- func OnEnded(stmts ...Stmt) h.Attribute
- func OnError(stmts ...Stmt) h.Attribute
- func OnFocus(stmts ...Stmt) h.Attribute
- func OnFocusIn(stmts ...Stmt) h.Attribute
- func OnFocusOut(stmts ...Stmt) h.Attribute
- func OnHashChange(stmts ...Stmt) h.Attribute
- func OnInput(stmts ...Stmt) h.Attribute
- func OnInvalid(stmts ...Stmt) h.Attribute
- func OnKeyDown(stmts ...Stmt) h.Attribute
- func OnKeyPress(stmts ...Stmt) h.Attribute
- func OnKeyUp(stmts ...Stmt) h.Attribute
- func OnLoad(stmts ...Stmt) h.Attribute
- func OnLoadedData(stmts ...Stmt) h.Attribute
- func OnLoadedMetadata(stmts ...Stmt) h.Attribute
- func OnMouseDown(stmts ...Stmt) h.Attribute
- func OnMouseEnter(stmts ...Stmt) h.Attribute
- func OnMouseLeave(stmts ...Stmt) h.Attribute
- func OnMouseMove(stmts ...Stmt) h.Attribute
- func OnMouseOut(stmts ...Stmt) h.Attribute
- func OnMouseOver(stmts ...Stmt) h.Attribute
- func OnMouseUp(stmts ...Stmt) h.Attribute
- func OnOffline(stmts ...Stmt) h.Attribute
- func OnOnline(stmts ...Stmt) h.Attribute
- func OnPaste(stmts ...Stmt) h.Attribute
- func OnPause(stmts ...Stmt) h.Attribute
- func OnPlay(stmts ...Stmt) h.Attribute
- func OnPointerCancel(stmts ...Stmt) h.Attribute
- func OnPointerDown(stmts ...Stmt) h.Attribute
- func OnPointerEnter(stmts ...Stmt) h.Attribute
- func OnPointerLeave(stmts ...Stmt) h.Attribute
- func OnPointerMove(stmts ...Stmt) h.Attribute
- func OnPointerOut(stmts ...Stmt) h.Attribute
- func OnPointerOver(stmts ...Stmt) h.Attribute
- func OnPointerUp(stmts ...Stmt) h.Attribute
- func OnPopState(stmts ...Stmt) h.Attribute
- func OnReset(stmts ...Stmt) h.Attribute
- func OnResize(stmts ...Stmt) h.Attribute
- func OnScroll(stmts ...Stmt) h.Attribute
- func OnSeeked(stmts ...Stmt) h.Attribute
- func OnSeeking(stmts ...Stmt) h.Attribute
- func OnSelect(stmts ...Stmt) h.Attribute
- func OnStorage(stmts ...Stmt) h.Attribute
- func OnSubmit(stmts ...Stmt) h.Attribute
- func OnTimeUpdate(stmts ...Stmt) h.Attribute
- func OnTouchCancel(stmts ...Stmt) h.Attribute
- func OnTouchEnd(stmts ...Stmt) h.Attribute
- func OnTouchMove(stmts ...Stmt) h.Attribute
- func OnTouchStart(stmts ...Stmt) h.Attribute
- func OnTransitionCancel(stmts ...Stmt) h.Attribute
- func OnTransitionEnd(stmts ...Stmt) h.Attribute
- func OnTransitionRun(stmts ...Stmt) h.Attribute
- func OnTransitionStart(stmts ...Stmt) h.Attribute
- func OnUnload(stmts ...Stmt) h.Attribute
- func OnVolumeChange(stmts ...Stmt) h.Attribute
- func OnWheel(stmts ...Stmt) h.Attribute
- func ToJS(expr Expr) string
- func ToJSStmt(stmt Stmt) string
- type Callable
- func Add(left, right Expr) Callable
- func Alert(message Expr) Callable
- func And(left, right Expr) Callable
- func AppendChild(parent, child Callable) Callable
- func Array(elements ...Expr) Callable
- func ArrowFunc(params []string, body Expr) Callable
- func ArrowFuncStmts(params []string, stmts ...Stmt) Callable
- func AsyncArrowFunc(params []string, body Expr) Callable
- func AsyncArrowFuncStmts(params []string, stmts ...Stmt) Callable
- func Await(expr Expr) Callable
- func BitwiseAnd(left, right Expr) Callable
- func BitwiseNot(expr Expr) Callable
- func BitwiseOr(left, right Expr) Callable
- func BitwiseXor(left, right Expr) Callable
- func Blur(element Callable) Callable
- func BlurThis() Callable
- func Bool(b bool) Callable
- func Call(fn Callable, args ...Expr) Callable
- func CancelAnimationFrame(id Expr) Callable
- func ClassList(element Callable) Callable
- func ClassListAdd(element Callable, classes ...Expr) Callable
- func ClassListContains(element Callable, className Expr) Callable
- func ClassListRemove(element Callable, classes ...Expr) Callable
- func ClassListReplace(element Callable, oldClass, newClass Expr) Callable
- func ClassListToggle(element Callable, className Expr, force ...Expr) Callable
- func ClearInterval(id Expr) Callable
- func ClearStorage(storage Callable) Callable
- func ClearTimeout(id Expr) Callable
- func Click(element Callable) Callable
- func CloneNode(element Callable, deep Expr) Callable
- func Comma(exprs ...Expr) Callable
- func Confirm(message Expr) Callable
- func ConsoleClear() Callable
- func ConsoleDebug(args ...Expr) Callable
- func ConsoleError(args ...Expr) Callable
- func ConsoleInfo(args ...Expr) Callable
- func ConsoleLog(args ...Expr) Callable
- func ConsoleTable(data Expr) Callable
- func ConsoleWarn(args ...Expr) Callable
- func CreateElement(tag Expr) Callable
- func CreateTextNode(text Expr) Callable
- func DecodeURI(uri Expr) Callable
- func DecodeURIComponent(component Expr) Callable
- func Delete(expr Expr) Callable
- func Div(left, right Expr) Callable
- func EncodeURI(uri Expr) Callable
- func EncodeURIComponent(component Expr) Callable
- func Eq(left, right Expr) Callable
- func EventAltKey() Callable
- func EventChecked() Callable
- func EventCode() Callable
- func EventCtrlKey() Callable
- func EventCurrentTarget() Callable
- func EventKey() Callable
- func EventKeyCode() Callable
- func EventMetaKey() Callable
- func EventShiftKey() Callable
- func EventTarget() Callable
- func EventValue() Callable
- func EventWhich() Callable
- func Fetch(url Expr, options ...Expr) Callable
- func Float(f float64) Callable
- func Focus(element Callable) Callable
- func FocusThis() Callable
- func Func(params []string, stmts ...Stmt) Callable
- func GetAttribute(element Callable, name Expr) Callable
- func GetElementById(id Expr) Callable
- func GetElementsByClassName(className Expr) Callable
- func GetElementsByTagName(tagName Expr) Callable
- func GetItem(storage Callable, key Expr) Callable
- func Group(expr Expr) Callable
- func Gt(left, right Expr) Callable
- func GtEq(left, right Expr) Callable
- func HasAttribute(element Callable, name Expr) Callable
- func HistoryBack() Callable
- func HistoryForward() Callable
- func HistoryGo(delta Expr) Callable
- func HistoryPushState(state, title, url Expr) Callable
- func HistoryReplaceState(state, title, url Expr) Callable
- func IIFE(stmts ...Stmt) Callable
- func Ident(name string) Callable
- func In(left, right Expr) Callable
- func Index(obj Callable, index Expr) Callable
- func InsertBefore(parent, newNode, referenceNode Callable) Callable
- func Instanceof(left, right Expr) Callable
- func Int(n int) Callable
- func Int64(n int64) Callable
- func IsFinite(value Expr) Callable
- func IsNaN(value Expr) Callable
- func JSON(value any) Callable
- func JSONParse(text Expr, reviver ...Expr) Callable
- func JSONStringify(value Expr, args ...Expr) Callable
- func LooseEq(left, right Expr) Callable
- func LooseNotEq(left, right Expr) Callable
- func Lt(left, right Expr) Callable
- func LtEq(left, right Expr) Callable
- func Method(obj Callable, method string, args ...Expr) Callable
- func Mod(left, right Expr) Callable
- func Mul(left, right Expr) Callable
- func Neg(expr Expr) Callable
- func New(constructor Callable, args ...Expr) Callable
- func Not(expr Expr) Callable
- func NotEq(left, right Expr) Callable
- func Null() Callable
- func NullishCoalesce(left, right Expr) Callable
- func Object(pairs ...KV) Callable
- func OptionalCall(obj Callable, method string, args ...Expr) Callable
- func OptionalProp(obj Callable, name string) Callable
- func Or(left, right Expr) Callable
- func ParseFloat(str Expr) Callable
- func ParseInt(str Expr, radix ...Expr) Callable
- func Pos(expr Expr) Callable
- func PostDecr(target Callable) Callable
- func PostIncr(target Callable) Callable
- func PreDecr(target Callable) Callable
- func PreIncr(target Callable) Callable
- func PreventDefault() Callable
- func PromiseAll(iterable Expr) Callable
- func PromiseCatch(promise Callable, onRejected Expr) Callable
- func PromiseFinally(promise Callable, onFinally Expr) Callable
- func PromiseRace(iterable Expr) Callable
- func PromiseReject(reason Expr) Callable
- func PromiseResolve(value Expr) Callable
- func PromiseThen(promise Callable, onFulfilled Expr) Callable
- func Prompt(message Expr, defaultValue ...Expr) Callable
- func Prop(obj Callable, name string) Callable
- func QuerySelector(selector Expr) Callable
- func QuerySelectorAll(selector Expr) Callable
- func Raw(code string) Callable
- func Reload() Callable
- func Remove(element Callable) Callable
- func RemoveAttribute(element Callable, name Expr) Callable
- func RemoveChild(parent, child Callable) Callable
- func RemoveItem(storage Callable, key Expr) Callable
- func ReplaceChild(parent, newChild, oldChild Callable) Callable
- func RequestAnimationFrame(callback Expr) Callable
- func Select(element Callable) Callable
- func SetAttribute(element, name, value Expr) Callable
- func SetInterval(callback, interval Expr) Callable
- func SetItem(storage Callable, key, value Expr) Callable
- func SetTimeout(callback, delay Expr) Callable
- func ShiftLeft(left, right Expr) Callable
- func ShiftRight(left, right Expr) Callable
- func Spread(expr Expr) Callable
- func StopImmediatePropagation() Callable
- func StopPropagation() Callable
- func String(s string) Callable
- func Style(element Callable) Callable
- func Sub(left, right Expr) Callable
- func Template(parts ...any) Callable
- func Ternary(cond, ifTrue, ifFalse Expr) Callable
- func This() Callable
- func Typeof(expr Expr) Callable
- func Undefined() Callable
- func UnsignedShiftRight(left, right Expr) Callable
- func Void(expr Expr) Callable
- type Expr
- type KV
- type Stmt
- func AddAssign(target Callable, value Expr) Stmt
- func AndAssign(target Callable, value Expr) Stmt
- func Assign(target Callable, value Expr) Stmt
- func Block(body ...Stmt) Stmt
- func Break() Stmt
- func BreakLabel(label string) Stmt
- func Const(name string, value Expr) Stmt
- func Continue() Stmt
- func ContinueLabel(label string) Stmt
- func Debugger() Stmt
- func Decr(target Callable) Stmt
- func DivAssign(target Callable, value Expr) Stmt
- func ExprStmt(expr Expr) Stmt
- func If(cond Expr, body ...Stmt) Stmt
- func IfElse(cond Expr, thenBody []Stmt, elseBody []Stmt) Stmt
- func Incr(target Callable) Stmt
- func Let(name string, value Expr) Stmt
- func LetDecl(name string) Stmt
- func ModAssign(target Callable, value Expr) Stmt
- func MulAssign(target Callable, value Expr) Stmt
- func Navigate(url Expr) Stmt
- func NullishAssign(target Callable, value Expr) Stmt
- func OrAssign(target Callable, value Expr) Stmt
- func Return(value Expr) Stmt
- func ReturnVoid() Stmt
- func SetStyle(element Callable, property string, value Expr) Stmt
- func Stmts(stmts ...Stmt) Stmt
- func SubAssign(target Callable, value Expr) Stmt
- func Throw(value Expr) Stmt
- func Var(name string, value Expr) Stmt
- func VarDecl(name string) Stmt
Examples ¶
- Package (ArrayMethods)
- Package (ArrowFunction)
- Package (BasicClickHandler)
- Package (ConditionalLogic)
- Package (EventValue)
- Package (KeyboardShortcut)
- Package (ObjectLiteral)
- Package (PreventDefault)
- Package (PromiseChain)
- Package (RawEscapeHatch)
- Package (TemplateLiteral)
- Package (TernaryOperator)
- Package (ToggleClass)
- ArrowFunc
- ArrowFuncStmts
- AsyncArrowFunc
- Await
- ExprStmt
- Handler
- If
- IfElse
- JSON
- Method
- OnClick
- OnInput
- OnSubmit
- Prop
- Raw
- String
- Template
- Ternary
Constants ¶
This section is empty.
Variables ¶
var ( // Console is the console object Console = Ident("console") // Document is the document object Document = Ident("document") // Window is the window object Window = Ident("window") // Event is the event object in handlers (the event parameter) Event = Ident("event") // EventThis is the 'this' value in event handlers (the element) EventThis = This() // Location is the window.location object Location = Ident("location") // History is the window.history object History = Ident("history") Navigator = Ident("navigator") // LocalStorage is the localStorage object LocalStorage = Ident("localStorage") // SessionStorage is the sessionStorage object SessionStorage = Ident("sessionStorage") // JSON_ is the JSON global object (underscore to avoid conflict with JSON() function) JSON_ = Ident("JSON") // Math is the Math global object Math = Ident("Math") // Date is the Date constructor Date = Ident("Date") // Promise is the Promise constructor Promise = Ident("Promise") // Object_ is the Object constructor Object_ = Ident("Object") // Array_ is the Array constructor Array_ = Ident("Array") )
Pre-defined global identifiers
Functions ¶
func ExprHandler ¶
ExprHandler builds an inline JavaScript handler from a single expression.
func Handler ¶
Handler builds an inline JavaScript handler string from statements. Statements are joined with semicolons.
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Combine multiple statements
handler := js.Handler(
js.Let("x", js.Int(1)),
js.Incr(js.Ident("x")),
js.ExprStmt(js.ConsoleLog(js.Ident("x"))),
)
fmt.Println(handler)
}
Output: let x = 1; x++; console.log(x)
func On ¶
On creates a custom event handler attribute. Example: On("touchstart", stmts...) creates ontouchstart="..."
func OnAfterPrint ¶
OnAfterPrint creates an onafterprint attribute with the given handler.
func OnAnimationEnd ¶
OnAnimationEnd creates an onanimationend attribute with the given handler.
func OnAnimationIteration ¶
OnAnimationIteration creates an onanimationiteration attribute with the given handler.
func OnAnimationStart ¶
OnAnimationStart creates an onanimationstart attribute with the given handler.
func OnBeforePrint ¶
OnBeforePrint creates an onbeforeprint attribute with the given handler.
func OnBeforeUnload ¶
OnBeforeUnload creates an onbeforeunload attribute with the given handler.
func OnCanPlayThrough ¶
OnCanPlayThrough creates an oncanplaythrough attribute with the given handler.
func OnClick ¶
OnClick creates an onclick attribute with the given handler.
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
attr := js.OnClick(js.ExprStmt(js.ConsoleLog(js.String("clicked"))))
fmt.Printf("%s=%q", attr.Name, attr.Value)
}
Output: onclick="console.log(\"clicked\")"
func OnContextMenu ¶
OnContextMenu creates an oncontextmenu attribute with the given handler.
func OnDblClick ¶
OnDblClick creates an ondblclick attribute with the given handler.
func OnDragEnter ¶
OnDragEnter creates an ondragenter attribute with the given handler.
func OnDragLeave ¶
OnDragLeave creates an ondragleave attribute with the given handler.
func OnDragOver ¶
OnDragOver creates an ondragover attribute with the given handler.
func OnDragStart ¶
OnDragStart creates an ondragstart attribute with the given handler.
func OnFocusOut ¶
OnFocusOut creates an onfocusout attribute with the given handler.
func OnHashChange ¶
OnHashChange creates an onhashchange attribute with the given handler.
func OnInput ¶
OnInput creates an oninput attribute with the given handler.
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
attr := js.OnInput(
js.Assign(js.Ident("value"), js.EventValue()),
)
fmt.Printf("%s=%q", attr.Name, attr.Value)
}
Output: oninput="value = event.target.value"
func OnKeyPress ¶
OnKeyPress creates an onkeypress attribute with the given handler. Deprecated: Use OnKeyDown or OnKeyUp instead.
func OnLoadedData ¶
OnLoadedData creates an onloadeddata attribute with the given handler.
func OnLoadedMetadata ¶
OnLoadedMetadata creates an onloadedmetadata attribute with the given handler.
func OnMouseDown ¶
OnMouseDown creates an onmousedown attribute with the given handler.
func OnMouseEnter ¶
OnMouseEnter creates an onmouseenter attribute with the given handler.
func OnMouseLeave ¶
OnMouseLeave creates an onmouseleave attribute with the given handler.
func OnMouseMove ¶
OnMouseMove creates an onmousemove attribute with the given handler.
func OnMouseOut ¶
OnMouseOut creates an onmouseout attribute with the given handler.
func OnMouseOver ¶
OnMouseOver creates an onmouseover attribute with the given handler.
func OnPointerCancel ¶
OnPointerCancel creates an onpointercancel attribute with the given handler.
func OnPointerDown ¶
OnPointerDown creates an onpointerdown attribute with the given handler.
func OnPointerEnter ¶
OnPointerEnter creates an onpointerenter attribute with the given handler.
func OnPointerLeave ¶
OnPointerLeave creates an onpointerleave attribute with the given handler.
func OnPointerMove ¶
OnPointerMove creates an onpointermove attribute with the given handler.
func OnPointerOut ¶
OnPointerOut creates an onpointerout attribute with the given handler.
func OnPointerOver ¶
OnPointerOver creates an onpointerover attribute with the given handler.
func OnPointerUp ¶
OnPointerUp creates an onpointerup attribute with the given handler.
func OnPopState ¶
OnPopState creates an onpopstate attribute with the given handler.
func OnSubmit ¶
OnSubmit creates an onsubmit attribute with the given handler.
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
attr := js.OnSubmit(
js.ExprStmt(js.PreventDefault()),
js.ExprStmt(js.Method(js.This(), "submit")),
)
fmt.Printf("%s=%q", attr.Name, attr.Value)
}
Output: onsubmit="event.preventDefault(); this.submit()"
func OnTimeUpdate ¶
OnTimeUpdate creates an ontimeupdate attribute with the given handler.
func OnTouchCancel ¶
OnTouchCancel creates an ontouchcancel attribute with the given handler.
func OnTouchEnd ¶
OnTouchEnd creates an ontouchend attribute with the given handler.
func OnTouchMove ¶
OnTouchMove creates an ontouchmove attribute with the given handler.
func OnTouchStart ¶
OnTouchStart creates an ontouchstart attribute with the given handler.
func OnTransitionCancel ¶
OnTransitionCancel creates an ontransitioncancel attribute with the given handler.
func OnTransitionEnd ¶
OnTransitionEnd creates an ontransitionend attribute with the given handler.
func OnTransitionRun ¶
OnTransitionRun creates an ontransitionrun attribute with the given handler.
func OnTransitionStart ¶
OnTransitionStart creates an ontransitionstart attribute with the given handler.
func OnVolumeChange ¶
OnVolumeChange creates an onvolumechange attribute with the given handler.
Types ¶
type Callable ¶
type Callable interface {
Expr
// contains filtered or unexported methods
}
Callable represents a JavaScript value that can have properties accessed and methods called on it (identifiers, objects, function results).
func AppendChild ¶
AppendChild creates parent.appendChild(child)
func ArrowFunc ¶
ArrowFunc creates an arrow function expression with a single expression body. Example: ArrowFunc([]string{"x", "y"}, Add(Ident("x"), Ident("y")))
=> (x, y) => (x + y)
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Single expression arrow function
fn := js.ArrowFunc([]string{"a", "b"}, js.Add(js.Ident("a"), js.Ident("b")))
fmt.Println(js.ExprHandler(fn))
}
Output: (a, b) => (a + b)
func ArrowFuncStmts ¶
ArrowFuncStmts creates an arrow function with a statement body. Example: ArrowFuncStmts([]string{"e"}, ExprStmt(ConsoleLog(Ident("e"))))
=> (e) => { console.log(e) }
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Multi-statement arrow function
fn := js.ArrowFuncStmts([]string{"x"},
js.Let("result", js.Mul(js.Ident("x"), js.Int(2))),
js.Return(js.Ident("result")),
)
fmt.Println(js.ExprHandler(fn))
}
Output: x => { let result = (x * 2); return result }
func AsyncArrowFunc ¶
AsyncArrowFunc creates an async arrow function with a single expression body. Example: AsyncArrowFunc([]string{}, Await(Fetch(String("/api"))))
=> async () => await fetch("/api")
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
fn := js.AsyncArrowFunc([]string{"url"},
js.Await(js.Fetch(js.Ident("url"))),
)
fmt.Println(js.ExprHandler(fn))
}
Output: async url => await fetch(url)
func AsyncArrowFuncStmts ¶
AsyncArrowFuncStmts creates an async arrow function with a statement body. Example: AsyncArrowFuncStmts([]string{}, Let("data", Await(Fetch(String("/api")))))
=> async () => { let data = await fetch("/api") }
func Await ¶
Await creates an await expression. Example: Await(Fetch(String("/api/data")))
=> await fetch("/api/data")
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
expr := js.Await(js.Method(js.Fetch(js.String("/api")), "json"))
fmt.Println(js.ExprHandler(expr))
}
Output: await fetch("/api").json()
func Call ¶
Call invokes a callable with arguments. Example: Call(Ident("alert"), String("hello")) => alert("hello")
func CancelAnimationFrame ¶
CancelAnimationFrame creates cancelAnimationFrame(id)
func ClassListAdd ¶
ClassListAdd creates element.classList.add(classes...)
func ClassListContains ¶
ClassListContains creates element.classList.contains(className)
func ClassListRemove ¶
ClassListRemove creates element.classList.remove(classes...)
func ClassListReplace ¶
ClassListReplace creates element.classList.replace(oldClass, newClass)
func ClassListToggle ¶
ClassListToggle creates element.classList.toggle(className, force?)
func ClearStorage ¶
ClearStorage creates storage.clear()
func Comma ¶
Comma creates a comma expression that evaluates all expressions and returns the value of the last one.
func ConsoleDebug ¶
ConsoleDebug creates console.debug(args...)
func ConsoleError ¶
ConsoleError creates console.error(args...)
func ConsoleInfo ¶
ConsoleInfo creates console.info(args...)
func ConsoleWarn ¶
ConsoleWarn creates console.warn(args...)
func CreateElement ¶
CreateElement creates document.createElement(tag)
func CreateTextNode ¶
CreateTextNode creates document.createTextNode(text)
func DecodeURIComponent ¶
DecodeURIComponent creates decodeURIComponent(component)
func EncodeURIComponent ¶
EncodeURIComponent creates encodeURIComponent(component)
func EventChecked ¶
func EventChecked() Callable
EventChecked creates event.target.checked (common for checkbox handlers)
func EventCurrentTarget ¶
func EventCurrentTarget() Callable
EventCurrentTarget creates event.currentTarget
func EventKeyCode ¶
func EventKeyCode() Callable
EventKeyCode creates event.keyCode (for keyboard events, deprecated but common)
func EventValue ¶
func EventValue() Callable
EventValue creates event.target.value (common for input handlers)
func EventWhich ¶
func EventWhich() Callable
EventWhich creates event.which (for keyboard events, deprecated but common)
func FocusThis ¶
func FocusThis() Callable
FocusThis creates this.focus() (for use in event handlers)
func Func ¶
Func creates an anonymous function expression. Example: Func([]string{"x", "y"}, Return(Add(Ident("x"), Ident("y"))))
=> function(x, y) { return (x + y) }
func GetAttribute ¶
GetAttribute creates element.getAttribute(name)
func GetElementById ¶
GetElementById creates document.getElementById(id)
func GetElementsByClassName ¶
GetElementsByClassName creates document.getElementsByClassName(className)
func GetElementsByTagName ¶
GetElementsByTagName creates document.getElementsByTagName(tagName)
func HasAttribute ¶
HasAttribute creates element.hasAttribute(name)
func HistoryPushState ¶
HistoryPushState creates history.pushState(state, title, url)
func HistoryReplaceState ¶
HistoryReplaceState creates history.replaceState(state, title, url)
func IIFE ¶
IIFE creates an immediately invoked function expression. Example: IIFE(ExprStmt(ConsoleLog(String("hello"))))
=> (function() { console.log("hello") })()
func Ident ¶
Ident creates a JavaScript identifier reference. This should be used for variable names, not for string literals.
func Index ¶
Index accesses an element by index or computed property. Example: Index(Ident("arr"), Int(0)) => arr[0] Example: Index(Ident("obj"), String("key")) => obj["key"]
func InsertBefore ¶
InsertBefore creates parent.insertBefore(newNode, referenceNode)
func Instanceof ¶
Instanceof returns left instanceof right
func JSON ¶
JSON creates a JavaScript value from a Go value using JSON encoding. Panics if the value cannot be marshaled to JSON.
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// JSON encodes any Go value
expr := js.JSON(map[string]any{
"users": []string{"alice", "bob"},
})
fmt.Println(js.ExprHandler(expr))
}
Output: {"users":["alice","bob"]}
func JSONStringify ¶
JSONStringify creates JSON.stringify(value, replacer?, space?)
func LooseNotEq ¶
LooseNotEq returns left != right (loose inequality)
func Method ¶
Method calls a method on an object with arguments. Example: Method(Ident("console"), "log", String("hello")) => console.log("hello")
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Call a method with arguments
expr := js.Method(js.Ident("arr"), "push", js.Int(1), js.Int(2))
fmt.Println(js.ExprHandler(expr))
}
Output: arr.push(1, 2)
func New ¶
New creates a new instance with the new keyword. Example: New(Ident("Date")) => new Date()
func NullishCoalesce ¶
NullishCoalesce returns left ?? right
func OptionalCall ¶
OptionalCall calls a method with optional chaining. Example: OptionalCall(Ident("obj"), "method", args...) => obj?.method(args...)
func OptionalProp ¶
OptionalProp accesses a property with optional chaining. Example: OptionalProp(Ident("obj"), "foo") => obj?.foo
func PromiseCatch ¶
PromiseCatch creates expr.catch(onRejected)
func PromiseFinally ¶
PromiseFinally creates expr.finally(onFinally)
func PromiseRace ¶
PromiseRace creates Promise.race(iterable)
func PromiseReject ¶
PromiseReject creates Promise.reject(reason)
func PromiseResolve ¶
PromiseResolve creates Promise.resolve(value)
func PromiseThen ¶
PromiseThen creates expr.then(onFulfilled)
func Prop ¶
Prop accesses a property on a callable expression. Example: Prop(Ident("document"), "body") => document.body
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Access nested properties
expr := js.Prop(js.Prop(js.Ident("window"), "location"), "href")
fmt.Println(js.ExprHandler(expr))
}
Output: window.location.href
func QuerySelector ¶
QuerySelector creates document.querySelector(selector)
func QuerySelectorAll ¶
QuerySelectorAll creates document.querySelectorAll(selector)
func Raw ¶
Raw injects raw JavaScript code. This is the ONLY way to inject arbitrary JS. Use with caution as this bypasses type safety.
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Raw is the escape hatch for arbitrary JavaScript
expr := js.Raw("customLibrary.doSomething()")
fmt.Println(js.ExprHandler(expr))
}
Output: customLibrary.doSomething()
func RemoveAttribute ¶
RemoveAttribute creates element.removeAttribute(name)
func RemoveChild ¶
RemoveChild creates parent.removeChild(child)
func RemoveItem ¶
RemoveItem creates storage.removeItem(key)
func ReplaceChild ¶
ReplaceChild creates parent.replaceChild(newChild, oldChild)
func RequestAnimationFrame ¶
RequestAnimationFrame creates requestAnimationFrame(callback)
func SetAttribute ¶
SetAttribute creates element.setAttribute(name, value)
func SetInterval ¶
SetInterval creates setInterval(callback, interval)
func SetTimeout ¶
SetTimeout creates setTimeout(callback, delay)
func StopImmediatePropagation ¶
func StopImmediatePropagation() Callable
StopImmediatePropagation creates event.stopImmediatePropagation()
func StopPropagation ¶
func StopPropagation() Callable
StopPropagation creates event.stopPropagation()
func String ¶
String creates a JavaScript string literal, properly escaped using JSON encoding.
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Strings are JSON-encoded for safety
expr := js.String(`He said "hello"`)
fmt.Println(js.ExprHandler(expr))
}
Output: "He said \"hello\""
func Template ¶
Template creates a template literal expression. Alternates between string parts and expression parts. Example: Template("Hello, ", Ident("name"), "!")
=> `Hello, ${name}!`
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
expr := js.Template("User: ", js.Ident("name"), " (", js.Ident("id"), ")")
fmt.Println(js.ExprHandler(expr))
}
Output: `User: ${name} (${id})`
func Ternary ¶
Ternary returns cond ? ifTrue : ifFalse
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
expr := js.Ternary(
js.Gt(js.Ident("age"), js.Int(18)),
js.String("adult"),
js.String("minor"),
)
fmt.Println(js.ExprHandler(expr))
}
Output: ((age > 18) ? "adult" : "minor")
func UnsignedShiftRight ¶
UnsignedShiftRight returns left >>> right
type Expr ¶
type Expr interface {
// contains filtered or unexported methods
}
Expr represents a JavaScript expression that produces a value. Expressions can be composed into larger expressions or used as statements.
type Stmt ¶
type Stmt interface {
// contains filtered or unexported methods
}
Stmt represents a JavaScript statement. Statements are complete units of execution.
func BreakLabel ¶
BreakLabel creates a break statement with a label: break label
func ContinueLabel ¶
ContinueLabel creates a continue statement with a label: continue label
func ExprStmt ¶
ExprStmt converts an expression to a statement.
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
// Convert an expression to a statement
stmt := js.ExprStmt(js.ConsoleLog(js.String("hello")))
fmt.Println(js.ToJSStmt(stmt))
}
Output: console.log("hello")
func If ¶
If creates an if statement: if (cond) { body... }
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
stmt := js.If(js.Gt(js.Ident("x"), js.Int(0)),
js.ExprStmt(js.ConsoleLog(js.String("positive"))),
)
fmt.Println(js.ToJSStmt(stmt))
}
Output: if ((x > 0)) { console.log("positive") }
func IfElse ¶
IfElse creates an if-else statement: if (cond) { thenBody... } else { elseBody... }
Example ¶
package main
import (
"fmt"
"github.com/jeffh/htmlgen/js"
)
func main() {
stmt := js.IfElse(
js.Gt(js.Ident("x"), js.Int(0)),
[]js.Stmt{js.Return(js.String("positive"))},
[]js.Stmt{js.Return(js.String("non-positive"))},
)
fmt.Println(js.ToJSStmt(stmt))
}
Output: if ((x > 0)) { return "positive" } else { return "non-positive" }
func NullishAssign ¶
NullishAssign creates: target ??= value