From 68c3227fe401e189d3486a7135168c30dba8ad7c Mon Sep 17 00:00:00 2001 From: Maxence Charriere Date: Tue, 19 Sep 2023 17:15:37 +0800 Subject: [PATCH 01/28] Condition Rework (#887) * rework condition to take functions instead of ui elements * update ci go version * improve condition test coverage * test only pkg * only test app pkg * Update build.yml * Update build.yml * Update build.yml --- .github/workflows/build.yml | 21 ++++-- pkg/app/component_test.go | 10 +-- pkg/app/condition.go | 93 +++++++++++++++++--------- pkg/app/condition_test.go | 129 +++++++++++++++++++----------------- 4 files changed, 151 insertions(+), 102 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 719b41224..0b043c5bf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,11 +10,16 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: "1.20" + go-version: "1.21" - name: Checkout Code uses: actions/checkout@v3 - name: Vet - run: go vet ./... + run: | + go vet ./pkg/app + go vet ./pkg/errors + go vet ./pkg/logs + go vet ./pkg/cache + go vet ./pkg/cli server: name: Unit Tests @@ -23,11 +28,15 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: "1.18" + go-version: "1.21" - name: Checkout Code uses: actions/checkout@v3 - name: Run Unit Tests - run: go test -race ./... + run: | + go test -race ./pkg/app + go test -race ./pkg/errors + go test -race ./pkg/logs + go test -race ./pkg/cache client: name: WebAssembly Unit Tests @@ -36,7 +45,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v3 with: - go-version: "1.18" + go-version: "1.21" - name: Checkout Code uses: actions/checkout@v3 - name: Install WASM Browser Test @@ -46,3 +55,5 @@ jobs: - name: Run Unit Tests run: | GOARCH=wasm GOOS=js go test ./pkg/app + GOARCH=wasm GOOS=js go test ./pkg/errors + GOARCH=wasm GOOS=js go test ./pkg/logs diff --git a/pkg/app/component_test.go b/pkg/app/component_test.go index e2c3c3cdf..752839060 100644 --- a/pkg/app/component_test.go +++ b/pkg/app/component_test.go @@ -487,11 +487,11 @@ type foo struct { } func (f *foo) Render() UI { - return If(f.Bar != "", - &bar{Value: f.Bar}, - ).Else( - Text("bar"), - ) + return If(f.Bar != "", func() UI { + return &bar{Value: f.Bar} + }).Else(func() UI { + return Text("bar") + }) } type bar struct { diff --git a/pkg/app/condition.go b/pkg/app/condition.go index 367e90dfb..3555b18ef 100644 --- a/pkg/app/condition.go +++ b/pkg/app/condition.go @@ -7,53 +7,84 @@ import ( "github.com/maxence-charriere/go-app/v9/pkg/errors" ) -// Condition represents a control structure that displays nodes depending on a -// given expression. +// Condition represents a control structure for conditionally displaying UI +// elements. It extends the UI interface to include methods for handling +// conditional logic. type Condition interface { UI - // ElseIf sets the condition with the given nodes if previous expressions - // were not met and given expression is true. - ElseIf(expr bool, elems ...UI) Condition - - // Else sets the condition with the given UI elements if previous - // expressions were not met. - Else(elems ...UI) Condition -} - -// If returns a condition that filters the given elements according to the given -// expression. -func If(expr bool, elems ...UI) Condition { + // ElseIf sets a UI element to be displayed when the given boolean + // expression is true and all previous conditions have been false. + // + // expr: Boolean expression to evaluate. + // elem: Function that returns the UI element to display. + ElseIf(expr bool, elem func() UI) Condition + + // ElseIfSlice sets multiple UI elements to be displayed when the given + // boolean expression is true and all previous conditions have been false. + // + // expr: Boolean expression to evaluate. + // elems: Function that returns a slice of UI elements to display. + ElseIfSlice(expr bool, elems func() []UI) Condition + + // Else sets a UI element to be displayed as a fallback when all previous + // conditions have been false. + // + // elem: Function that returns the UI element to display. + Else(elem func() UI) Condition + + // ElseSlice sets multiple UI elements to be displayed as a fallback when + // all previous conditions have been false. + // + // expr: Boolean expression to evaluate. + // elems: Function that returns a slice of UI elements to display. + ElseSlice(elems func() []UI) Condition +} + +// If returns a Condition that will display the given UI element based on the +// evaluation of the provided boolean expression. +func If(expr bool, elem func() UI) Condition { + return IfSlice(expr, func() []UI { + return []UI{elem()} + }) +} + +// IfSlice returns a Condition that will display the given slice of UI elements +// based on the evaluation of the provided boolean expression. +func IfSlice(expr bool, elems func() []UI) Condition { if !expr { - elems = nil - } - - return condition{ - body: FilterUIElems(elems...), - satisfied: expr, + return condition{} } + return condition{body: FilterUIElems(elems()...)} } type condition struct { - body []UI - satisfied bool + body []UI } -func (c condition) ElseIf(expr bool, elems ...UI) Condition { - if c.satisfied { - return c - } +func (c condition) ElseIf(expr bool, elem func() UI) Condition { + return c.ElseIfSlice(expr, func() []UI { + return []UI{elem()} + }) +} - if expr { - c.body = FilterUIElems(elems...) - c.satisfied = expr +func (c condition) ElseIfSlice(expr bool, elems func() []UI) Condition { + if len(c.body) != 0 || !expr { + return c } + c.body = FilterUIElems(elems()...) return c } -func (c condition) Else(elems ...UI) Condition { - return c.ElseIf(true, elems...) +func (c condition) Else(elem func() UI) Condition { + return c.ElseSlice(func() []UI { + return []UI{elem()} + }) +} + +func (c condition) ElseSlice(elems func() []UI) Condition { + return c.ElseIfSlice(true, elems) } func (c condition) Kind() Kind { diff --git a/pkg/app/condition_test.go b/pkg/app/condition_test.go index 1019842c7..9ef18d32d 100644 --- a/pkg/app/condition_test.go +++ b/pkg/app/condition_test.go @@ -7,21 +7,20 @@ func TestCondition(t *testing.T) { { scenario: "if is interpreted", a: Div().Body( - If(false, - H1(), - ), + If(false, func() UI { + return H1() + }), ), b: Div().Body( - If(true, - H1(), - ), + If(true, func() UI { + return H1() + }), ), matches: []TestUIDescriptor{ { Path: TestPath(), Expected: Div(), }, - { Path: TestPath(0), Expected: H1(), @@ -31,14 +30,14 @@ func TestCondition(t *testing.T) { { scenario: "if is not interpreted", a: Div().Body( - If(true, - H1(), - ), + If(true, func() UI { + return H1() + }), ), b: Div().Body( - If(false, - H1(), - ), + If(false, func() UI { + return H1() + }), ), matches: []TestUIDescriptor{ { @@ -54,18 +53,18 @@ func TestCondition(t *testing.T) { { scenario: "else if is interpreted", a: Div().Body( - If(true, - H1(), - ).ElseIf(false, - H2(), - ), + If(true, func() UI { + return H1() + }).ElseIf(false, func() UI { + return H2() + }), ), b: Div().Body( - If(false, - H1(), - ).ElseIf(true, - H2(), - ), + If(false, func() UI { + return H1() + }).ElseIf(true, func() UI { + return H2() + }), ), matches: []TestUIDescriptor{ { @@ -82,18 +81,18 @@ func TestCondition(t *testing.T) { { scenario: "else if is not interpreted", a: Div().Body( - If(false, - H1(), - ).ElseIf(true, - H2(), - ), + If(false, func() UI { + return H1() + }).ElseIf(true, func() UI { + return H2() + }), ), b: Div().Body( - If(false, - H1(), - ).ElseIf(false, - H2(), - ), + If(false, func() UI { + return H1() + }).ElseIf(false, func() UI { + return H2() + }), ), matches: []TestUIDescriptor{ { @@ -110,22 +109,22 @@ func TestCondition(t *testing.T) { { scenario: "else is interpreted", a: Div().Body( - If(false, - H1(), - ).ElseIf(true, - H2(), - ).Else( - H3(), - ), + If(false, func() UI { + return H1() + }).ElseIf(true, func() UI { + return H2() + }).Else(func() UI { + return H3() + }), ), b: Div().Body( - If(false, - H1(), - ).ElseIf(false, - H2(), - ).Else( - H3(), - ), + If(false, func() UI { + return H1() + }).ElseIf(false, func() UI { + return H2() + }).Else(func() UI { + return H3() + }), ), matches: []TestUIDescriptor{ { @@ -142,22 +141,22 @@ func TestCondition(t *testing.T) { { scenario: "else is not interpreted", a: Div().Body( - If(false, - H1(), - ).ElseIf(true, - H2(), - ).Else( - H3(), - ), + If(false, func() UI { + return H1() + }).ElseIf(true, func() UI { + return H2() + }).Else(func() UI { + return H3() + }), ), b: Div().Body( - If(true, - H1(), - ).ElseIf(false, - H2(), - ).Else( - H3(), - ), + If(true, func() UI { + return H1() + }).ElseIf(false, func() UI { + return H2() + }).Else(func() UI { + return H3() + }), ), matches: []TestUIDescriptor{ { @@ -173,3 +172,11 @@ func TestCondition(t *testing.T) { }, }) } + +func BenchmarkCondition(b *testing.B) { + for n := 0; n < b.N; n++ { + If(true, func() UI { + return Div() + }) + } +} From 48e43ab20da6f209cde2560637303556a3699d2b Mon Sep 17 00:00:00 2001 From: Maxence Charriere Date: Wed, 20 Sep 2023 19:07:13 +0800 Subject: [PATCH 02/28] Broader use of formatted string arg and generated documentation overhaul (#888) * replace remaining strings argument by format * use format with Style * Improve generated documentation. * improve generated doc C * Improve generated doc D - E * Update html.go * Update html.go * Update html.go * Update html.go * Update html.go * Update html.go * update event handlers doc * Update html.go * Update html.go * Update html.go * modify fixed method doc * Update html.go * Update html.go * Update html.go * Update html.go * Update html.go * Update html.go * Update html.go * Update html.go * Update html.go * Update html.go * Update html.go * Update html.go * update generated doc * update generated wording --- pkg/app/gen/html.go | 639 +- pkg/app/html_gen.go | 13524 ++++++++++++++++++------------------- pkg/app/html_gen_test.go | 230 +- 3 files changed, 7195 insertions(+), 7198 deletions(-) diff --git a/pkg/app/gen/html.go b/pkg/app/gen/html.go index eb5d92385..7714ed25f 100644 --- a/pkg/app/gen/html.go +++ b/pkg/app/gen/html.go @@ -28,10 +28,10 @@ const ( ) var tags = []tag{ + // A: { - // A: Name: "A", - Doc: "defines a hyperlink.", + Doc: "that creates a hyperlink, allowing navigation to other web pages or resources.", Attrs: withGlobalAttrs(attrsByNames( "download", "href", @@ -46,20 +46,20 @@ var tags = []tag{ }, { Name: "Abbr", - Doc: "defines an abbreviation or an acronym.", + Doc: "that represents an abbreviation or an acronym, providing a longer description or meaning of the content.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Address", - Doc: "defines contact information for the author/owner of a document.", + Doc: "that designates contact information for the author or owner of a document or web page.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Area", Type: selfClosing, - Doc: "defines an area inside an image-map.", + Doc: "that defines a clickable region within an image map, usually linking to another resource.", Attrs: withGlobalAttrs(attrsByNames( "alt", "coords", @@ -76,19 +76,19 @@ var tags = []tag{ }, { Name: "Article", - Doc: "defines an article.", + Doc: "that marks a self-contained composition in a document, like a blog post or news story.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Aside", - Doc: "defines content aside from the page content.", + Doc: "that represents content tangentially related to the main content, and can be considered separate.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Audio", - Doc: "defines sound content.", + Doc: "that embeds an audio player for playing sound or music content.", Attrs: withGlobalAttrs(attrsByNames( "autoplay", "controls", @@ -104,14 +104,14 @@ var tags = []tag{ // B: { Name: "B", - Doc: "defines bold text.", + Doc: "that applies bold styling to its content.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Base", Type: selfClosing, - Doc: "specifies the base URL/target for all relative URLs in a document.", + Doc: "that specifies the base URL and target for all relative URLs in the document.", Attrs: withGlobalAttrs(attrsByNames( "href", "target", @@ -120,19 +120,19 @@ var tags = []tag{ }, { Name: "Bdi", - Doc: "isolates a part of text that might be formatted in a different direction from other text outside it.", + Doc: "that isolates a section of text, allowing it to be formatted in a different direction than the surrounding content.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Bdo", - Doc: "overrides the current text direction.", + Doc: "that controls the text direction of its content, overriding other directional settings.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Blockquote", - Doc: "defines a section that is quoted from another source.", + Doc: "that represents a section of text quoted from another source.", Attrs: withGlobalAttrs(attrsByNames( "cite", )...), @@ -141,7 +141,7 @@ var tags = []tag{ { Name: "Body", Type: privateParent, - Doc: "defines the document's body.", + Doc: "that encloses the main content of the HTML document.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(eventHandlersByName( "onafterprint", @@ -164,13 +164,13 @@ var tags = []tag{ { Name: "Br", Type: selfClosing, - Doc: "defines a single line break.", + Doc: "that inserts a line break within inline content.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Button", - Doc: "defines a clickable button.", + Doc: "that creates a clickable button, typically used for form submission or triggering interactions.", Attrs: withGlobalAttrs(attrsByNames( "autofocus", "disabled", @@ -190,7 +190,7 @@ var tags = []tag{ // C: { Name: "Canvas", - Doc: "is used to draw graphics on the fly.", + Doc: "that provides a space where graphics can be rendered dynamically, such as 2D drawings or 3D visualizations.", Attrs: withGlobalAttrs(attrsByNames( "height", "width", @@ -199,26 +199,26 @@ var tags = []tag{ }, { Name: "Caption", - Doc: "defines a table caption.", + Doc: "that represents the title or description of a table, usually appearing above or below the table.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Cite", - Doc: "defines the title of a work.", + Doc: "that indicates the title or reference of a creative work, such as a book, film, or research paper.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Code", - Doc: "defines a piece of computer code.", + Doc: "that displays a single line of code or a code snippet, preserving its formatting.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Col", Type: selfClosing, - Doc: "specifies column properties for each column within a colgroup element.", + Doc: "that defines the properties for a single column or a group of columns within a table, when nested within a `` element.", Attrs: withGlobalAttrs(attrsByNames( "span", )...), @@ -226,7 +226,7 @@ var tags = []tag{ }, { Name: "ColGroup", - Doc: "specifies a group of one or more columns in a table for formatting.", + Doc: "that groups one or more `` elements, providing a way to apply styles and attributes to multiple columns simultaneously.", Attrs: withGlobalAttrs(attrsByNames( "span", )...), @@ -236,26 +236,26 @@ var tags = []tag{ // D: { Name: "Data", - Doc: "links the given content with a machine-readable translation.", + Doc: "that pairs content with its machine-readable translation or value.", Attrs: withGlobalAttrs(attrsByNames( "value", )...), }, { Name: "DataList", - Doc: "specifies a list of pre-defined options for input controls.", + Doc: "that offers a predefined set of options for input controls.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Dd", - Doc: "defines a description/value of a term in a description list.", + Doc: "that provides the description or value for a term in a description list.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Del", - Doc: "defines text that has been deleted from a document.", + Doc: "that denotes text segments that have been deleted or modified in the content.", Attrs: withGlobalAttrs(attrsByNames( "cite", "datetime", @@ -264,7 +264,7 @@ var tags = []tag{ }, { Name: "Details", - Doc: "defines additional details that the user can view or hide.", + Doc: "that encapsulates content users can toggle visibility for, such as additional information or context.", Attrs: withGlobalAttrs(attrsByNames( "open", )...), @@ -274,13 +274,13 @@ var tags = []tag{ }, { Name: "Dfn", - Doc: "represents the defining instance of a term.", + Doc: "that marks the defining occurrence or clarification of a term or phrase.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Dialog", - Doc: "defines a dialog box or window.", + Doc: "that represents a popup dialog box or an interactive window overlay.", Attrs: withGlobalAttrs(attrsByNames( "open", )...), @@ -288,19 +288,19 @@ var tags = []tag{ }, { Name: "Div", - Doc: "defines a section in a document.", + Doc: "that creates a generic container for flow content, usually combined with styles or scripts.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Dl", - Doc: "defines a description list.", + Doc: "that structures a list of terms alongside their associated descriptions.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Dt", - Doc: "defines a term/name in a description list.", + Doc: "that specifies a term or name within a description list.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, @@ -308,7 +308,7 @@ var tags = []tag{ // E: { Name: "Elem", - Doc: "represents an customizable HTML element.", + Doc: "that is customizable.", Attrs: withGlobalAttrs(attrsByNames( "xmlns", )...), @@ -317,7 +317,7 @@ var tags = []tag{ { Name: "ElemSelfClosing", Type: selfClosing, - Doc: "represents a self closing custom HTML element.", + Doc: "that is self-closing and customizable.", Attrs: withGlobalAttrs(attrsByNames( "xmlns", )...), @@ -325,14 +325,14 @@ var tags = []tag{ }, { Name: "Em", - Doc: "defines emphasized text.", + Doc: "that marks text for emphasis, typically rendered as italicized text.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Embed", Type: selfClosing, - Doc: "defines a container for an external (non-HTML) application.", + Doc: "that offers a container for integrating non-HTML content or applications.", Attrs: withGlobalAttrs(attrsByNames( "height", "src", @@ -345,7 +345,7 @@ var tags = []tag{ // F: { Name: "FieldSet", - Doc: "groups related elements in a form.", + Doc: "that clusters related input controls and labels within a form.", Attrs: withGlobalAttrs(attrsByNames( "disabled", "form", @@ -355,25 +355,25 @@ var tags = []tag{ }, { Name: "FigCaption", - Doc: "defines a caption for a figure element.", + Doc: "that supplies a caption or explanation for content within the
element.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Figure", - Doc: "specifies self-contained content.", + Doc: "that encapsulates media content or illustrations with an optional caption.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Footer", - Doc: "defines a footer for a document or section.", + Doc: "that denotes the footer of a section or the whole document, often containing metadata or author info.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Form", - Doc: "defines an HTML form for user input.", + Doc: "that constructs a user input form, allowing for various control elements and submission options.", Attrs: withGlobalAttrs(attrsByNames( "accept-charset", "action", @@ -390,75 +390,75 @@ var tags = []tag{ // H: { Name: "H1", - Doc: "defines HTML heading.", + Doc: "that defines a level 1 HTML heading, indicating the most important topic or section.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "H2", - Doc: "defines HTML heading.", + Doc: "that defines a level 2 HTML heading, indicating a main subsection under H1.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "H3", - Doc: "defines HTML heading.", + Doc: "that defines a level 3 HTML heading, indicating a subsection under H2.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "H4", - Doc: "defines HTML heading.", + Doc: "that defines a level 4 HTML heading, indicating topics that fall under the H3 section.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "H5", - Doc: "defines HTML heading.", + Doc: "that defines a level 5 HTML heading, typically used for finer details under an H4 section.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "H6", - Doc: "defines HTML heading.", + Doc: "that defines a level 6 HTML heading, used for the smallest granularity of topics or details.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Head", - Doc: "defines information about the document.", + Doc: "that defines information about the document.", Attrs: withGlobalAttrs(attrsByNames()...), }, { Name: "Header", - Doc: "defines a header for a document or section.", + Doc: "that defines a header for a document or section.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Hr", Type: selfClosing, - Doc: "defines a thematic change in the content.", + Doc: "that defines a thematic change in the content.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Html", Type: privateParent, - Doc: "defines the root of an HTML document.", + Doc: "that defines the root of an HTML document.", Attrs: withGlobalAttrs(), }, // I: { Name: "I", - Doc: "defines a part of text in an alternate voice or mood.", + Doc: "that defines a part of text in an alternate voice or mood.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "IFrame", - Doc: "defines an inline frame.", + Doc: "that defines an inline frame.", Attrs: withGlobalAttrs(attrsByNames( "allow", "allowfullscreen", @@ -480,7 +480,7 @@ var tags = []tag{ { Name: "Img", Type: selfClosing, - Doc: "defines an image.", + Doc: "that defines an image.", Attrs: withGlobalAttrs(attrsByNames( "alt", "crossorigin", @@ -502,7 +502,7 @@ var tags = []tag{ { Name: "Input", Type: selfClosing, - Doc: "defines an input control.", + Doc: "that defines an input control.", Attrs: withGlobalAttrs(attrsByNames( "accept", "alt", @@ -543,7 +543,7 @@ var tags = []tag{ }, { Name: "Ins", - Doc: "defines a text that has been inserted into a document.", + Doc: "that defines text that has been inserted into a document.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, @@ -551,7 +551,7 @@ var tags = []tag{ // K: { Name: "Kbd", - Doc: "defines keyboard input.", + Doc: "that represents keyboard input.", Attrs: withGlobalAttrs(attrsByNames()...), EventHandlers: withGlobalEventHandlers(), }, @@ -559,7 +559,7 @@ var tags = []tag{ // L: { Name: "Label", - Doc: "defines a label for an input element.", + Doc: "that represents a label for an input element.", Attrs: withGlobalAttrs(attrsByNames( "for", "form", @@ -568,13 +568,13 @@ var tags = []tag{ }, { Name: "Legend", - Doc: "defines a caption for a fieldset element.", + Doc: "that represents a caption for a fieldset element.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Li", - Doc: "defines a list item.", + Doc: "that represents a list item.", Attrs: withGlobalAttrs(attrsByNames( "value", )...), @@ -583,7 +583,7 @@ var tags = []tag{ { Name: "Link", Type: selfClosing, - Doc: "defines the relationship between a document and an external resource (most used to link to style sheets).", + Doc: "that describes the relationship between a document and an external resource (most commonly used to link to style sheets).", Attrs: withGlobalAttrs(attrsByNames( "as", "crossorigin", @@ -603,13 +603,13 @@ var tags = []tag{ // M: { Name: "Main", - Doc: "specifies the main content of a document.", + Doc: "that specifies the main content of a document.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Map", - Doc: "defines a client-side image-map.", + Doc: "that represents a client-side image-map.", Attrs: withGlobalAttrs(attrsByNames( "name", )...), @@ -617,14 +617,14 @@ var tags = []tag{ }, { Name: "Mark", - Doc: "defines marked/highlighted text.", + Doc: "that represents marked/highlighted text.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Meta", Type: selfClosing, - Doc: ".", + Doc: "that provides metadata about the HTML document.", Attrs: withGlobalAttrs(attrsByNames( "charset", "content", @@ -635,7 +635,7 @@ var tags = []tag{ }, { Name: "Meter", - Doc: "defines a scalar measurement within a known range (a gauge).", + Doc: "that represents a scalar measurement within a known range (like a gauge).", Attrs: withGlobalAttrs(attrsByNames( "form", "high", @@ -651,20 +651,20 @@ var tags = []tag{ // N: { Name: "Nav", - Doc: "defines navigation links.", + Doc: "that represents navigation links.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "NoScript", - Doc: "defines an alternate content for users that do not support client-side scripts.", + Doc: "that provides alternate content for users who do not support client-side scripts.", Attrs: withGlobalAttrs(attrsByNames()...), }, // O: { Name: "Object", - Doc: "defines an embedded object.", + Doc: "that embeds an object within the document.", Attrs: withGlobalAttrs(attrsByNames( "data", "form", @@ -678,7 +678,7 @@ var tags = []tag{ }, { Name: "Ol", - Doc: "defines an ordered list.", + Doc: "that represents an ordered list.", Attrs: withGlobalAttrs(attrsByNames( "reversed", "start", @@ -688,7 +688,7 @@ var tags = []tag{ }, { Name: "OptGroup", - Doc: "defines a group of related options in a drop-down list.", + Doc: "that groups related options in a drop-down list.", Attrs: withGlobalAttrs(attrsByNames( "disabled", "label", @@ -697,7 +697,7 @@ var tags = []tag{ }, { Name: "Option", - Doc: "defines an option in a drop-down list.", + Doc: "that represents an option in a drop-down list.", Attrs: withGlobalAttrs(attrsByNames( "disabled", "label", @@ -708,7 +708,7 @@ var tags = []tag{ }, { Name: "Output", - Doc: ".", + Doc: "that displays the result of a calculation or user action.", Attrs: withGlobalAttrs(attrsByNames( "for", "form", @@ -720,14 +720,14 @@ var tags = []tag{ // P: { Name: "P", - Doc: "defines a paragraph.", + Doc: "that represents a paragraph.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Param", Type: selfClosing, - Doc: "defines a parameter for an object.", + Doc: "that defines a parameter for an embedded object.", Attrs: withGlobalAttrs(attrsByNames( "name", "value", @@ -736,19 +736,19 @@ var tags = []tag{ }, { Name: "Picture", - Doc: "defines a container for multiple image resources.", + Doc: "that provides a container for multiple image sources.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Pre", - Doc: "defines preformatted text.", + Doc: "that displays preformatted text.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Progress", - Doc: "represents the progress of a task.", + Doc: "that visualizes the progress of a task.", Attrs: withGlobalAttrs(attrsByNames( "max", "value", @@ -759,7 +759,7 @@ var tags = []tag{ // Q: { Name: "Q", - Doc: "defines a short quotation.", + Doc: "that represents a short quotation.", Attrs: withGlobalAttrs(attrsByNames( "cite", )...), @@ -769,19 +769,19 @@ var tags = []tag{ // R: { Name: "Rp", - Doc: "defines what to show in browsers that do not support ruby annotations.", + Doc: "that indicates text for browsers not supporting ruby annotations.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Rt", - Doc: "defines an explanation/pronunciation of characters (for East Asian typography).", + Doc: "that provides explanation or pronunciation of characters (used in East Asian typography).", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Ruby", - Doc: "defines a ruby annotation (for East Asian typography).", + Doc: "that marks a ruby annotation (used for East Asian typography).", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, @@ -789,19 +789,19 @@ var tags = []tag{ // S: { Name: "S", - Doc: "Defines text that is no longer correct.", + Doc: "that represents text which is no longer correct or relevant.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Samp", - Doc: "defines sample output from a computer program.", + Doc: "that displays sample output from a computer program.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Script", - Doc: "defines a client-side script.", + Doc: "that embeds or references a client-side script.", Attrs: withGlobalAttrs(attrsByNames( "async", "charset", @@ -814,13 +814,13 @@ var tags = []tag{ }, { Name: "Section", - Doc: "defines a section in a document.", + Doc: "that represents a standalone section in a document.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Select", - Doc: "defines a drop-down list.", + Doc: "that creates a drop-down list or list box for form input.", Attrs: withGlobalAttrs(attrsByNames( "autofocus", "disabled", @@ -834,14 +834,14 @@ var tags = []tag{ }, { Name: "Small", - Doc: "defines smaller text.", + Doc: "that displays text in a smaller font, typically for side comments or legal disclaimers.", Attrs: withGlobalAttrs(), EventHandlers: withGlobalEventHandlers(), }, { Name: "Source", Type: selfClosing, - Doc: ".", + Doc: "that specifies multiple media resources for elements like ,