From 7c69a9664e410fb59c1716b35283dedee3ba6c98 Mon Sep 17 00:00:00 2001 From: cotinhalol Date: Sat, 20 Apr 2024 21:30:51 +0100 Subject: [PATCH 01/11] Addding extension properties and functions generator, tests, pom.xmlfile changes --- pom.xml | 44 +- .../htmlflow/HtmlFlowExtensionProperties.kt | 803 ++++++++++++++++++ .../kotlin/htmlflow/HtmlFlowExtensions.kt | 30 +- .../HtmlFlowExtensionPropertiesGenerator.kt | 67 ++ .../propertiesGenerator/Reflection.kt | 59 ++ .../htmlflow/test/TestKotlinExtensions.kt | 511 ++++++++++- 6 files changed, 1483 insertions(+), 31 deletions(-) create mode 100644 src/main/kotlin/htmlflow/HtmlFlowExtensionProperties.kt create mode 100644 src/main/kotlin/htmlflow/propertiesGenerator/HtmlFlowExtensionPropertiesGenerator.kt create mode 100644 src/main/kotlin/htmlflow/propertiesGenerator/Reflection.kt diff --git a/pom.xml b/pom.xml index 19dd89d..37e8845 100644 --- a/pom.xml +++ b/pom.xml @@ -43,16 +43,16 @@ - org.slf4j - slf4j-api - 2.0.3 - test + org.slf4j + slf4j-api + 2.0.3 + test - org.slf4j - slf4j-simple - 2.0.3 - test + org.slf4j + slf4j-simple + 2.0.3 + test com.github.xmlet @@ -118,6 +118,16 @@ guava 33.0.0-jre + + com.squareup + kotlinpoet-jvm + 1.16.0 + + + org.jetbrains.kotlin + kotlin-reflect + ${kotlin.version} + UTF-8 @@ -130,6 +140,24 @@ + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + htmlflow.propertiesGenerator.ReflectionKt + true + + + + teste + process-classes + + java + + + + org.apache.maven.plugins maven-surefire-plugin diff --git a/src/main/kotlin/htmlflow/HtmlFlowExtensionProperties.kt b/src/main/kotlin/htmlflow/HtmlFlowExtensionProperties.kt new file mode 100644 index 0000000..8f1230c --- /dev/null +++ b/src/main/kotlin/htmlflow/HtmlFlowExtensionProperties.kt @@ -0,0 +1,803 @@ +package htmlflow + +import org.xmlet.htmlapifaster.A +import org.xmlet.htmlapifaster.Abbr +import org.xmlet.htmlapifaster.Address +import org.xmlet.htmlapifaster.Area +import org.xmlet.htmlapifaster.Article +import org.xmlet.htmlapifaster.Aside +import org.xmlet.htmlapifaster.Audio +import org.xmlet.htmlapifaster.B +import org.xmlet.htmlapifaster.Base +import org.xmlet.htmlapifaster.Bdi +import org.xmlet.htmlapifaster.Bdo +import org.xmlet.htmlapifaster.Blockquote +import org.xmlet.htmlapifaster.Body +import org.xmlet.htmlapifaster.Br +import org.xmlet.htmlapifaster.Button +import org.xmlet.htmlapifaster.Canvas +import org.xmlet.htmlapifaster.Caption +import org.xmlet.htmlapifaster.Cite +import org.xmlet.htmlapifaster.Code +import org.xmlet.htmlapifaster.Col +import org.xmlet.htmlapifaster.Colgroup +import org.xmlet.htmlapifaster.Data +import org.xmlet.htmlapifaster.Datalist +import org.xmlet.htmlapifaster.Dd +import org.xmlet.htmlapifaster.Del +import org.xmlet.htmlapifaster.Details +import org.xmlet.htmlapifaster.DetailsComplete +import org.xmlet.htmlapifaster.DetailsSummary +import org.xmlet.htmlapifaster.Dfn +import org.xmlet.htmlapifaster.Dialog +import org.xmlet.htmlapifaster.Div +import org.xmlet.htmlapifaster.Dl +import org.xmlet.htmlapifaster.Dt +import org.xmlet.htmlapifaster.Element +import org.xmlet.htmlapifaster.Em +import org.xmlet.htmlapifaster.Embed +import org.xmlet.htmlapifaster.Fieldset +import org.xmlet.htmlapifaster.Figcaption +import org.xmlet.htmlapifaster.Figure +import org.xmlet.htmlapifaster.Footer +import org.xmlet.htmlapifaster.Form +import org.xmlet.htmlapifaster.H1 +import org.xmlet.htmlapifaster.H2 +import org.xmlet.htmlapifaster.H3 +import org.xmlet.htmlapifaster.H4 +import org.xmlet.htmlapifaster.H5 +import org.xmlet.htmlapifaster.H6 +import org.xmlet.htmlapifaster.Head +import org.xmlet.htmlapifaster.Header +import org.xmlet.htmlapifaster.Hr +import org.xmlet.htmlapifaster.I +import org.xmlet.htmlapifaster.Iframe +import org.xmlet.htmlapifaster.Img +import org.xmlet.htmlapifaster.Input +import org.xmlet.htmlapifaster.Ins +import org.xmlet.htmlapifaster.Kbd +import org.xmlet.htmlapifaster.Label +import org.xmlet.htmlapifaster.Legend +import org.xmlet.htmlapifaster.Li +import org.xmlet.htmlapifaster.Link +import org.xmlet.htmlapifaster.Main +import org.xmlet.htmlapifaster.Map +import org.xmlet.htmlapifaster.Mark +import org.xmlet.htmlapifaster.Math +import org.xmlet.htmlapifaster.Meta +import org.xmlet.htmlapifaster.Meter +import org.xmlet.htmlapifaster.Nav +import org.xmlet.htmlapifaster.Noscript +import org.xmlet.htmlapifaster.Object +import org.xmlet.htmlapifaster.Ol +import org.xmlet.htmlapifaster.Optgroup +import org.xmlet.htmlapifaster.Option +import org.xmlet.htmlapifaster.Output +import org.xmlet.htmlapifaster.P +import org.xmlet.htmlapifaster.Param +import org.xmlet.htmlapifaster.Picture +import org.xmlet.htmlapifaster.Pre +import org.xmlet.htmlapifaster.Progress +import org.xmlet.htmlapifaster.Q +import org.xmlet.htmlapifaster.Rb +import org.xmlet.htmlapifaster.Root +import org.xmlet.htmlapifaster.Rp +import org.xmlet.htmlapifaster.Rt +import org.xmlet.htmlapifaster.Rtc +import org.xmlet.htmlapifaster.Ruby +import org.xmlet.htmlapifaster.S +import org.xmlet.htmlapifaster.Samp +import org.xmlet.htmlapifaster.Script +import org.xmlet.htmlapifaster.Section +import org.xmlet.htmlapifaster.Select +import org.xmlet.htmlapifaster.Small +import org.xmlet.htmlapifaster.Source +import org.xmlet.htmlapifaster.Span +import org.xmlet.htmlapifaster.Strong +import org.xmlet.htmlapifaster.Style +import org.xmlet.htmlapifaster.Sub +import org.xmlet.htmlapifaster.Summary +import org.xmlet.htmlapifaster.Sup +import org.xmlet.htmlapifaster.Svg +import org.xmlet.htmlapifaster.Table +import org.xmlet.htmlapifaster.Tbody +import org.xmlet.htmlapifaster.Td +import org.xmlet.htmlapifaster.Template +import org.xmlet.htmlapifaster.Textarea +import org.xmlet.htmlapifaster.Tfoot +import org.xmlet.htmlapifaster.Th +import org.xmlet.htmlapifaster.Thead +import org.xmlet.htmlapifaster.Time +import org.xmlet.htmlapifaster.Title +import org.xmlet.htmlapifaster.Tr +import org.xmlet.htmlapifaster.Track +import org.xmlet.htmlapifaster.U +import org.xmlet.htmlapifaster.Ul +import org.xmlet.htmlapifaster.Var +import org.xmlet.htmlapifaster.Video +import org.xmlet.htmlapifaster.Wbr + +public inline val , Z : Element<*,*>> T.h2: H2 + get() = H2(this.self()) + +public fun , Z : Element<*,*>> T.h2(block: H2.() -> H2): T = + H2(this).block().l + +public inline val , Z : Element<*,*>> T.mark: Mark + get() = Mark(this.self()) + +public fun , Z : Element<*,*>> T.mark(block: Mark.() -> Mark): T = + Mark(this).block().l + +public inline val , Z : Element<*,*>> T.i: I + get() = I(this.self()) + +public fun , Z : Element<*,*>> T.i(block: I.() -> I): T = I(this).block().l + +public inline val , Z : Element<*,*>> T.th: Th + get() = Th(this.self()) + +public fun , Z : Element<*,*>> T.th(block: Th.() -> Th): T = + Th(this).block().l + +public inline val , Z : Element<*,*>> T.strong: Strong + get() = Strong(this.self()) + +public fun , Z : Element<*,*>> T.strong(block: Strong.() -> Strong): T = + Strong(this).block().l + +public inline val , Z : Element<*,*>> T.col: Col + get() = Col(this.self()) + +public fun , Z : Element<*,*>> T.col(block: Col.() -> Col): T = + Col(this).block().l + +public inline val , Z : Element<*,*>> T.math: Math + get() = Math(this.self()) + +public fun , Z : Element<*,*>> T.math(block: Math.() -> Math): T = + Math(this).block().l + +public inline val , Z : Element<*,*>> T.tbody: Tbody + get() = Tbody(this.self()) + +public fun , Z : Element<*,*>> T.tbody(block: Tbody.() -> Tbody): T = + Tbody(this).block().l + +public inline val , Z : Element<*,*>> T.textarea: Textarea + get() = Textarea(this.self()) + +public fun , Z : Element<*,*>> T.textarea(block: Textarea.() -> Textarea): T + = Textarea(this).block().l + +public inline val , Z : Element<*,*>> T.source: Source + get() = Source(this.self()) + +public fun , Z : Element<*,*>> T.source(block: Source.() -> Source): T = + Source(this).block().l + +public inline val , Z : Element<*,*>> T.rp: Rp + get() = Rp(this.self()) + +public fun , Z : Element<*,*>> T.rp(block: Rp.() -> Rp): T = + Rp(this).block().l + +public inline val , Z : Element<*,*>> T.picture: Picture + get() = Picture(this.self()) + +public fun , Z : Element<*,*>> T.picture(block: Picture.() -> Picture): T = + Picture(this).block().l + +public inline val , Z : Element<*,*>> T.p: P + get() = P(this.self()) + +public fun , Z : Element<*,*>> T.p(block: P.() -> P): T = P(this).block().l + +public inline val , Z : Element<*,*>> T.dt: Dt + get() = Dt(this.self()) + +public fun , Z : Element<*,*>> T.dt(block: Dt.() -> Dt): T = + Dt(this).block().l + +public inline val , Z : Element<*,*>> T.label: Label + get() = Label(this.self()) + +public fun , Z : Element<*,*>> T.label(block: Label.() -> Label): T = + Label(this).block().l + +public inline val , Z : Element<*,*>> T.embed: Embed + get() = Embed(this.self()) + +public fun , Z : Element<*,*>> T.embed(block: Embed.() -> Embed): T = + Embed(this).block().l + +public inline val , Z : Element<*,*>> T.rt: Rt + get() = Rt(this.self()) + +public fun , Z : Element<*,*>> T.rt(block: Rt.() -> Rt): T = + Rt(this).block().l + +public inline val , Z : Element<*,*>> T.address: Address + get() = Address(this.self()) + +public fun , Z : Element<*,*>> T.address(block: Address.() -> Address): T = + Address(this).block().l + +public inline val , Z : Element<*,*>> T.h4: H4 + get() = H4(this.self()) + +public fun , Z : Element<*,*>> T.h4(block: H4.() -> H4): T = + H4(this).block().l + +public inline val , Z : Element<*,*>> T.`data`: Data + get() = Data(this.self()) + +public fun , Z : Element<*,*>> T.`data`(block: Data.() -> Data): T = + Data(this).block().l + +public inline val , Z : Element<*,*>> T.legend: Legend + get() = Legend(this.self()) + +public fun , Z : Element<*,*>> T.legend(block: Legend.() -> Legend): T = + Legend(this).block().l + +public inline val , Z : Element<*,*>> T.option: Option + get() = Option(this.self()) + +public fun , Z : Element<*,*>> T.option(block: Option.() -> Option): T = + Option(this).block().l + +public inline val , Z : Element<*,*>> T.detailssummary: DetailsSummary + get() = DetailsSummary(this.self()) + +public fun , Z : Element<*,*>> + T.detailssummary(block: DetailsSummary.() -> DetailsSummary): T = + DetailsSummary(this).block().l + +public inline val , Z : Element<*,*>> T.track: Track + get() = Track(this.self()) + +public fun , Z : Element<*,*>> T.track(block: Track.() -> Track): T = + Track(this).block().l + +public inline val , Z : Element<*,*>> T.figcaption: Figcaption + get() = Figcaption(this.self()) + +public fun , Z : Element<*,*>> + T.figcaption(block: Figcaption.() -> Figcaption): T = Figcaption(this).block().l + +public inline val , Z : Element<*,*>> T.sub: Sub + get() = Sub(this.self()) + +public fun , Z : Element<*,*>> T.sub(block: Sub.() -> Sub): T = + Sub(this).block().l + +public inline val , Z : Element<*,*>> T.details: Details + get() = Details(this.self()) + +public fun , Z : Element<*,*>> T.details(block: Details.() -> Details): T = + Details(this).block().l + +public inline val , Z : Element<*,*>> T.aside: Aside + get() = Aside(this.self()) + +public fun , Z : Element<*,*>> T.aside(block: Aside.() -> Aside): T = + Aside(this).block().l + +public inline val , Z : Element<*,*>> T.footer: Footer + get() = Footer(this.self()) + +public fun , Z : Element<*,*>> T.footer(block: Footer.() -> Footer): T = + Footer(this).block().l + +public inline val , Z : Element<*,*>> T.h6: H6 + get() = H6(this.self()) + +public fun , Z : Element<*,*>> T.h6(block: H6.() -> H6): T = + H6(this).block().l + +public inline val , Z : Element<*,*>> T.hr: Hr + get() = Hr(this.self()) + +public fun , Z : Element<*,*>> T.hr(block: Hr.() -> Hr): T = + Hr(this).block().l + +public inline val , Z : Element<*,*>> T.link: Link + get() = Link(this.self()) + +public fun , Z : Element<*,*>> T.link(block: Link.() -> Link): T = + Link(this).block().l + +public inline val , Z : Element<*,*>> T.meta: Meta + get() = Meta(this.self()) + +public fun , Z : Element<*,*>> T.meta(block: Meta.() -> Meta): T = + Meta(this).block().l + +public inline val , Z : Element<*,*>> T.`var`: Var + get() = Var(this.self()) + +public fun , Z : Element<*,*>> T.`var`(block: Var.() -> Var): T = + Var(this).block().l + +public inline val , Z : Element<*,*>> T.h1: H1 + get() = H1(this.self()) + +public fun , Z : Element<*,*>> T.h1(block: H1.() -> H1): T = + H1(this).block().l + +public inline val , Z : Element<*,*>> T.q: Q + get() = Q(this.self()) + +public fun , Z : Element<*,*>> T.q(block: Q.() -> Q): T = Q(this).block().l + +public inline val , Z : Element<*,*>> T.output: Output + get() = Output(this.self()) + +public fun , Z : Element<*,*>> T.output(block: Output.() -> Output): T = + Output(this).block().l + +public inline val , Z : Element<*,*>> T.li: Li + get() = Li(this.self()) + +public fun , Z : Element<*,*>> T.li(block: Li.() -> Li): T = + Li(this).block().l + +public inline val , Z : Element<*,*>> T.span: Span + get() = Span(this.self()) + +public fun , Z : Element<*,*>> T.span(block: Span.() -> Span): T = + Span(this).block().l + +public inline val , Z : Element<*,*>> T.time: Time + get() = Time(this.self()) + +public fun , Z : Element<*,*>> T.time(block: Time.() -> Time): T = + Time(this).block().l + +public inline val , Z : Element<*,*>> T.caption: Caption + get() = Caption(this.self()) + +public fun , Z : Element<*,*>> T.caption(block: Caption.() -> Caption): T = + Caption(this).block().l + +public inline val , Z : Element<*,*>> T.progress: Progress + get() = Progress(this.self()) + +public fun , Z : Element<*,*>> T.progress(block: Progress.() -> Progress): T + = Progress(this).block().l + +public inline val , Z : Element<*,*>> T.dl: Dl + get() = Dl(this.self()) + +public fun , Z : Element<*,*>> T.dl(block: Dl.() -> Dl): T = + Dl(this).block().l + +public inline val , Z : Element<*,*>> T.s: S + get() = S(this.self()) + +public fun , Z : Element<*,*>> T.s(block: S.() -> S): T = S(this).block().l + +public inline val , Z : Element<*,*>> T.h3: H3 + get() = H3(this.self()) + +public fun , Z : Element<*,*>> T.h3(block: H3.() -> H3): T = + H3(this).block().l + +public inline val , Z : Element<*,*>> T.cite: Cite + get() = Cite(this.self()) + +public fun , Z : Element<*,*>> T.cite(block: Cite.() -> Cite): T = + Cite(this).block().l + +public inline val , Z : Element<*,*>> T.abbr: Abbr + get() = Abbr(this.self()) + +public fun , Z : Element<*,*>> T.abbr(block: Abbr.() -> Abbr): T = + Abbr(this).block().l + +public inline val , Z : Element<*,*>> T.tr: Tr + get() = Tr(this.self()) + +public fun , Z : Element<*,*>> T.tr(block: Tr.() -> Tr): T = + Tr(this).block().l + +public inline val , Z : Element<*,*>> T.`param`: Param + get() = Param(this.self()) + +public fun , Z : Element<*,*>> T.`param`(block: Param.() -> Param): T = + Param(this).block().l + +public inline val , Z : Element<*,*>> T.colgroup: Colgroup + get() = Colgroup(this.self()) + +public fun , Z : Element<*,*>> T.colgroup(block: Colgroup.() -> Colgroup): T + = Colgroup(this).block().l + +public inline val , Z : Element<*,*>> T.dfn: Dfn + get() = Dfn(this.self()) + +public fun , Z : Element<*,*>> T.dfn(block: Dfn.() -> Dfn): T = + Dfn(this).block().l + +public inline val , Z : Element<*,*>> T.br: Br + get() = Br(this.self()) + +public fun , Z : Element<*,*>> T.br(block: Br.() -> Br): T = + Br(this).block().l + +public inline val , Z : Element<*,*>> T.head: Head + get() = Head(this.self()) + +public fun , Z : Element<*,*>> T.head(block: Head.() -> Head): T = + Head(this).block().l + +public inline val , Z : Element<*,*>> T.table: Table + get() = Table(this.self()) + +public fun , Z : Element<*,*>> T.table(block: Table.() -> Table): T = + Table(this).block().l + +public inline val , Z : Element<*,*>> T.template: Template + get() = Template(this.self()) + +public fun , Z : Element<*,*>> T.template(block: Template.() -> Template): T + = Template(this).block().l + +public inline val , Z : Element<*,*>> T.kbd: Kbd + get() = Kbd(this.self()) + +public fun , Z : Element<*,*>> T.kbd(block: Kbd.() -> Kbd): T = + Kbd(this).block().l + +public inline val , Z : Element<*,*>> T.h5: H5 + get() = H5(this.self()) + +public fun , Z : Element<*,*>> T.h5(block: H5.() -> H5): T = + H5(this).block().l + +public inline val , Z : Element<*,*>> T.u: U + get() = U(this.self()) + +public fun , Z : Element<*,*>> T.u(block: U.() -> U): T = U(this).block().l + +public inline val , Z : Element<*,*>> T.noscript: Noscript + get() = Noscript(this.self()) + +public fun , Z : Element<*,*>> T.noscript(block: Noscript.() -> Noscript): T + = Noscript(this).block().l + +public inline val , Z : Element<*,*>> T.root: Root + get() = Root(this.self()) + +public fun , Z : Element<*,*>> T.root(block: Root.() -> Root): T = + Root(this).block().l + +public inline val , Z : Element<*,*>> T.div: Div + get() = Div(this.self()) + +public fun , Z : Element<*,*>> T.div(block: Div.() -> Div): T = + Div(this).block().l + +public inline val , Z : Element<*,*>> T.select: Select + get() = Select(this.self()) + +public fun , Z : Element<*,*>> T.select(block: Select.() -> Select): T = + Select(this).block().l + +public inline val , Z : Element<*,*>> T.`header`: Header + get() = Header(this.self()) + +public fun , Z : Element<*,*>> T.`header`(block: Header.() -> Header): T = + Header(this).block().l + +public inline val , Z : Element<*,*>> T.datalist: Datalist + get() = Datalist(this.self()) + +public fun , Z : Element<*,*>> T.datalist(block: Datalist.() -> Datalist): T + = Datalist(this).block().l + +public inline val , Z : Element<*,*>> T.bdi: Bdi + get() = Bdi(this.self()) + +public fun , Z : Element<*,*>> T.bdi(block: Bdi.() -> Bdi): T = + Bdi(this).block().l + +public inline val , Z : Element<*,*>> T.rb: Rb + get() = Rb(this.self()) + +public fun , Z : Element<*,*>> T.rb(block: Rb.() -> Rb): T = + Rb(this).block().l + +public inline val , Z : Element<*,*>> T.input: Input + get() = Input(this.self()) + +public fun , Z : Element<*,*>> T.input(block: Input.() -> Input): T = + Input(this).block().l + +public inline val , Z : Element<*,*>> T.canvas: Canvas + get() = Canvas(this.self()) + +public fun , Z : Element<*,*>> T.canvas(block: Canvas.() -> Canvas): T = + Canvas(this).block().l + +public inline val , Z : Element<*,*>> T.b: B + get() = B(this.self()) + +public fun , Z : Element<*,*>> T.b(block: B.() -> B): T = B(this).block().l + +public inline val , Z : Element<*,*>> T.ol: Ol + get() = Ol(this.self()) + +public fun , Z : Element<*,*>> T.ol(block: Ol.() -> Ol): T = + Ol(this).block().l + +public inline val , Z : Element<*,*>> T.code: Code + get() = Code(this.self()) + +public fun , Z : Element<*,*>> T.code(block: Code.() -> Code): T = + Code(this).block().l + +public inline val , Z : Element<*,*>> T.dd: Dd + get() = Dd(this.self()) + +public fun , Z : Element<*,*>> T.dd(block: Dd.() -> Dd): T = + Dd(this).block().l + +public inline val , Z : Element<*,*>> T.title: Title + get() = Title(this.self()) + +public fun , Z : Element<*,*>> T.title(block: Title.() -> Title): T = + Title(this).block().l + +public inline val , Z : Element<*,*>> T.thead: Thead + get() = Thead(this.self()) + +public fun , Z : Element<*,*>> T.thead(block: Thead.() -> Thead): T = + Thead(this).block().l + +public inline val , Z : Element<*,*>> T.em: Em + get() = Em(this.self()) + +public fun , Z : Element<*,*>> T.em(block: Em.() -> Em): T = + Em(this).block().l + +public inline val , Z : Element<*,*>> T.fieldset: Fieldset + get() = Fieldset(this.self()) + +public fun , Z : Element<*,*>> T.fieldset(block: Fieldset.() -> Fieldset): T + = Fieldset(this).block().l + +public inline val , Z : Element<*,*>> T.area: Area + get() = Area(this.self()) + +public fun , Z : Element<*,*>> T.area(block: Area.() -> Area): T = + Area(this).block().l + +public inline val , Z : Element<*,*>> T.sup: Sup + get() = Sup(this.self()) + +public fun , Z : Element<*,*>> T.sup(block: Sup.() -> Sup): T = + Sup(this).block().l + +public inline val , Z : Element<*,*>> T.style: Style + get() = Style(this.self()) + +public fun , Z : Element<*,*>> T.style(block: Style.() -> Style): T = + Style(this).block().l + +public inline val , Z : Element<*,*>> T.nav: Nav + get() = Nav(this.self()) + +public fun , Z : Element<*,*>> T.nav(block: Nav.() -> Nav): T = + Nav(this).block().l + +public inline val , Z : Element<*,*>> T.ul: Ul + get() = Ul(this.self()) + +public fun , Z : Element<*,*>> T.ul(block: Ul.() -> Ul): T = + Ul(this).block().l + +public inline val , Z : Element<*,*>> T.tfoot: Tfoot + get() = Tfoot(this.self()) + +public fun , Z : Element<*,*>> T.tfoot(block: Tfoot.() -> Tfoot): T = + Tfoot(this).block().l + +public inline val , Z : Element<*,*>> T.bdo: Bdo + get() = Bdo(this.self()) + +public fun , Z : Element<*,*>> T.bdo(block: Bdo.() -> Bdo): T = + Bdo(this).block().l + +public inline val , Z : Element<*,*>> T.script: Script + get() = Script(this.self()) + +public fun , Z : Element<*,*>> T.script(block: Script.() -> Script): T = + Script(this).block().l + +public inline val , Z : Element<*,*>> T.section: Section + get() = Section(this.self()) + +public fun , Z : Element<*,*>> T.section(block: Section.() -> Section): T = + Section(this).block().l + +public inline val , Z : Element<*,*>> T.meter: Meter + get() = Meter(this.self()) + +public fun , Z : Element<*,*>> T.meter(block: Meter.() -> Meter): T = + Meter(this).block().l + +public inline val , Z : Element<*,*>> T.small: Small + get() = Small(this.self()) + +public fun , Z : Element<*,*>> T.small(block: Small.() -> Small): T = + Small(this).block().l + +public inline val , Z : Element<*,*>> T.form: Form + get() = Form(this.self()) + +public fun , Z : Element<*,*>> T.form(block: Form.() -> Form): T = + Form(this).block().l + +public inline val , Z : Element<*,*>> T.base: Base + get() = Base(this.self()) + +public fun , Z : Element<*,*>> T.base(block: Base.() -> Base): T = + Base(this).block().l + +public inline val , Z : Element<*,*>> T.blockquote: Blockquote + get() = Blockquote(this.self()) + +public fun , Z : Element<*,*>> + T.blockquote(block: Blockquote.() -> Blockquote): T = Blockquote(this).block().l + +public inline val , Z : Element<*,*>> T.audio: Audio + get() = Audio(this.self()) + +public fun , Z : Element<*,*>> T.audio(block: Audio.() -> Audio): T = + Audio(this).block().l + +public inline val , Z : Element<*,*>> T.a: A + get() = A(this.self()) + +public fun , Z : Element<*,*>> T.a(block: A.() -> A): T = A(this).block().l + +public inline val , Z : Element<*,*>> T.article: Article + get() = Article(this.self()) + +public fun , Z : Element<*,*>> T.article(block: Article.() -> Article): T = + Article(this).block().l + +public inline val , Z : Element<*,*>> T.detailscomplete: DetailsComplete + get() = DetailsComplete(this.self()) + +public fun , Z : Element<*,*>> + T.detailscomplete(block: DetailsComplete.() -> DetailsComplete): T = + DetailsComplete(this).block().l + +public inline val , Z : Element<*,*>> T.rtc: Rtc + get() = Rtc(this.self()) + +public fun , Z : Element<*,*>> T.rtc(block: Rtc.() -> Rtc): T = + Rtc(this).block().l + +public inline val , Z : Element<*,*>> T.`object`: Object + get() = Object(this.self()) + +public fun , Z : Element<*,*>> T.`object`(block: Object.() -> Object): T = + Object(this).block().l + +public inline val , Z : Element<*,*>> T.main: Main + get() = Main(this.self()) + +public fun , Z : Element<*,*>> T.main(block: Main.() -> Main): T = + Main(this).block().l + +public inline val , Z : Element<*,*>> T.video: Video + get() = Video(this.self()) + +public fun , Z : Element<*,*>> T.video(block: Video.() -> Video): T = + Video(this).block().l + +public inline val , Z : Element<*,*>> T.iframe: Iframe + get() = Iframe(this.self()) + +public fun , Z : Element<*,*>> T.iframe(block: Iframe.() -> Iframe): T = + Iframe(this).block().l + +public inline val , Z : Element<*,*>> T.del: Del + get() = Del(this.self()) + +public fun , Z : Element<*,*>> T.del(block: Del.() -> Del): T = + Del(this).block().l + +public inline val , Z : Element<*,*>> T.pre: Pre + get() = Pre(this.self()) + +public fun , Z : Element<*,*>> T.pre(block: Pre.() -> Pre): T = + Pre(this).block().l + +public inline val , Z : Element<*,*>> T.wbr: Wbr + get() = Wbr(this.self()) + +public fun , Z : Element<*,*>> T.wbr(block: Wbr.() -> Wbr): T = + Wbr(this).block().l + +public inline val , Z : Element<*,*>> T.map: Map + get() = Map(this.self()) + +public fun , Z : Element<*,*>> T.map(block: Map.() -> Map): T = + Map(this).block().l + +public inline val , Z : Element<*,*>> T.figure: Figure + get() = Figure(this.self()) + +public fun , Z : Element<*,*>> T.figure(block: Figure.() -> Figure): T = + Figure(this).block().l + +public inline val , Z : Element<*,*>> T.summary: Summary + get() = Summary(this.self()) + +public fun , Z : Element<*,*>> T.summary(block: Summary.() -> Summary): T = + Summary(this).block().l + +public inline val , Z : Element<*,*>> T.body: Body + get() = Body(this.self()) + +public fun , Z : Element<*,*>> T.body(block: Body.() -> Body): T = + Body(this).block().l + +public inline val , Z : Element<*,*>> T.img: Img + get() = Img(this.self()) + +public fun , Z : Element<*,*>> T.img(block: Img.() -> Img): T = + Img(this).block().l + +public inline val , Z : Element<*,*>> T.optgroup: Optgroup + get() = Optgroup(this.self()) + +public fun , Z : Element<*,*>> T.optgroup(block: Optgroup.() -> Optgroup): T + = Optgroup(this).block().l + +public inline val , Z : Element<*,*>> T.ins: Ins + get() = Ins(this.self()) + +public fun , Z : Element<*,*>> T.ins(block: Ins.() -> Ins): T = + Ins(this).block().l + +public inline val , Z : Element<*,*>> T.svg: Svg + get() = Svg(this.self()) + +public fun , Z : Element<*,*>> T.svg(block: Svg.() -> Svg): T = + Svg(this).block().l + +public inline val , Z : Element<*,*>> T.samp: Samp + get() = Samp(this.self()) + +public fun , Z : Element<*,*>> T.samp(block: Samp.() -> Samp): T = + Samp(this).block().l + +public inline val , Z : Element<*,*>> T.td: Td + get() = Td(this.self()) + +public fun , Z : Element<*,*>> T.td(block: Td.() -> Td): T = + Td(this).block().l + +public inline val , Z : Element<*,*>> T.dialog: Dialog + get() = Dialog(this.self()) + +public fun , Z : Element<*,*>> T.dialog(block: Dialog.() -> Dialog): T = + Dialog(this).block().l + +public inline val , Z : Element<*,*>> T.ruby: Ruby + get() = Ruby(this.self()) + +public fun , Z : Element<*,*>> T.ruby(block: Ruby.() -> Ruby): T = + Ruby(this).block().l + +public inline val , Z : Element<*,*>> T.button: Button + get() = Button(this.self()) + +public fun , Z : Element<*,*>> T.button(block: Button.() -> Button): T = + Button(this).block().l diff --git a/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt b/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt index ca9c2f5..7acfcc8 100644 --- a/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt +++ b/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt @@ -1,8 +1,11 @@ package htmlflow import htmlflow.continuations.HtmlContinuationSuspendableTerminationNode +import htmlflow.visitor.HtmlVisitor import htmlflow.visitor.PreprocessingVisitor -import org.xmlet.htmlapifaster.Element +//import jdk.internal.org.jline.utils.ShutdownHooks +import org.xmlet.htmlapifaster.* +import java.util.concurrent.CompletableFuture inline val , Z : Element<*,*>> T.l: Z get() = this.`__`() @@ -13,6 +16,31 @@ inline fun , Z : Element<*,*>> T.add(block: T.() -> Unit): T { } +public inline val HtmlPage.html: Html + get() { + (this.visitor as HtmlVisitor).write(HtmlPage.HEADER) + return Html(self()) + } + +inline fun , Z : Element<*,*>> HtmlPage.html(block : Html.() -> Html) : T{ + (this.visitor as HtmlVisitor).write(HtmlPage.HEADER) + return Html(self()).block().l +} + +inline var , Z : Element<*,*>> T.text : T + get() = self() + set(value) { + visitor.visitText( + Text( + self(), + visitor, + value, + ) + ) + } + + + /** * @param T type of the Element receiver * @param Z type of the parent Element of the receiver diff --git a/src/main/kotlin/htmlflow/propertiesGenerator/HtmlFlowExtensionPropertiesGenerator.kt b/src/main/kotlin/htmlflow/propertiesGenerator/HtmlFlowExtensionPropertiesGenerator.kt new file mode 100644 index 0000000..bd08697 --- /dev/null +++ b/src/main/kotlin/htmlflow/propertiesGenerator/HtmlFlowExtensionPropertiesGenerator.kt @@ -0,0 +1,67 @@ +package htmlflow.propertiesGenerator + +import com.squareup.kotlinpoet.* +import java.io.File +import kotlin.reflect.KClass + +class HtmlFlowExtensionPropertiesGenerator { + + val t = TypeVariableName("T") + val type = TypeVariableName("T : Element, Z : Element<*,*>") + + fun createHtmlFlowExtensionProperties( + list: List>, + name : String = "HtmlFlowExtensionProperties", + destinationPackage : String = "src/main/kotlin", + element : KClass<*> + ) { + val file = FileSpec.builder("htmlflow", name) + file.addImport(element,"") + list.forEach {kClass -> + addProperty(file, kClass) + addFun(file, kClass) + } + file.build().writeTo(File(destinationPackage)) + } + + private fun addProperty( + file: FileSpec.Builder, + clazz: KClass<*> + ){ + clazz.simpleName?.let { className -> + file.addProperty( + PropertySpec.builder(className.lowercase(),TypeVariableName("${clazz.simpleName}")) + .receiver(t) + .addTypeVariable(type) + .getter( + FunSpec.getterBuilder() + .addModifiers(KModifier.INLINE) + .addStatement("return %T(%L.self())", clazz, "this") + .build() + ) + .build() + ) + } + } + + private fun addFun( + file: FileSpec.Builder, + clazz: KClass<*>, + ) { + clazz.simpleName?.let { className -> + val typeVariable = TypeVariableName("${className}") + file.addFunction( + FunSpec.builder(className.lowercase()) + .returns(t) + .receiver(t) + .addTypeVariable(type) + .addParameter("block", LambdaTypeName.get( + receiver = typeVariable, + returnType = typeVariable, + )) + .addStatement("return %T(%L).block().l", clazz, "this") + .build() + ) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/htmlflow/propertiesGenerator/Reflection.kt b/src/main/kotlin/htmlflow/propertiesGenerator/Reflection.kt new file mode 100644 index 0000000..6f47536 --- /dev/null +++ b/src/main/kotlin/htmlflow/propertiesGenerator/Reflection.kt @@ -0,0 +1,59 @@ +package htmlflow.propertiesGenerator + +import org.xmlet.htmlapifaster.Element +import java.net.URL +import java.util.zip.ZipEntry +import java.util.zip.ZipInputStream +import kotlin.reflect.KClass +import kotlin.reflect.full.isSubclassOf + +fun main() { + doStuff() +} + +fun doStuff() { + val url = Element::class.java.protectionDomain.codeSource.location + val list = listKClasses(url) + val element = Element::class + val generator = HtmlFlowExtensionPropertiesGenerator() + + val filteredList = list + .filter { it.isSubclassOf(element) } + .filter { + it.simpleName != "Text" + && it.simpleName != "CustomElement" + && it.simpleName != "Html" + } + + generator.createHtmlFlowExtensionProperties( + list = filteredList, + element = element, + ) +} + +fun listKClasses(url: URL): List> { + val loader = Element::class.java.protectionDomain.classLoader + ZipInputStream(url.openStream()).use { zip -> + val res = mutableListOf>() + var entry = zip.nextEntry + while (entry != null) { + println(entry.name) + if (!entry.isDirectory + && entry.name.indexOf(".class") >= 0 + //&& !entry.name.lowercase().contains("enum") + ) { + val clazz = loader.loadClass(qualifiedName(entry)).kotlin + if (!clazz.java.isInterface && !clazz.java.isEnum) + res.add(clazz) + } + entry = zip.nextEntry + } + return res; + } +} + + +fun qualifiedName(entry: ZipEntry) = entry + .name + .replace('/', '.') // including ".class" + .let { name -> name.substring(0, name.length - ".class".length) } \ No newline at end of file diff --git a/src/test/kotlin/htmlflow/test/TestKotlinExtensions.kt b/src/test/kotlin/htmlflow/test/TestKotlinExtensions.kt index c1e7645..228bd91 100644 --- a/src/test/kotlin/htmlflow/test/TestKotlinExtensions.kt +++ b/src/test/kotlin/htmlflow/test/TestKotlinExtensions.kt @@ -1,9 +1,13 @@ package htmlflow.test -import htmlflow.* +import htmlflow.HtmlFlow.view import org.junit.Test import org.xmlet.htmlapifaster.EnumBorderType import kotlin.test.assertEquals +import htmlflow.HtmlFlow.doc +import org.xmlet.htmlapifaster.EnumRelType +import htmlflow.* + data class Weather(val country: String, val locations: Iterable) data class Location(val city: String, val desc: String, val celsius: Int) @@ -14,8 +18,439 @@ class TestKotlinExtensions { val html = weatherView.render(portugal) assertEquals(expectedPortugalWeather, html) } -} + @Test + fun testExtensionSimple() { + val html = weatherView1.render(portugal) + assertEquals(expectedPortugalWeather, html) + } + + @Test + fun `test div extension property`() { + + val expectedHtml = """ + + +
+ Hello, HtmlFlow! +
+ +""" + val builder = StringBuilder() + + doc(builder) + .html() + .body() + .div() + .text("Hello, HtmlFlow!") + .`__`() //close div + .`__`() // close body + .`__`() // close html + + assertEquals(expectedHtml, builder.toString()) + builder.clear() + doc(builder) + .html + .body + .div + .text("Hello, HtmlFlow!") + .l // close div + .l // close body + .l // close html + + assertEquals(expectedHtml, builder.toString()) + builder.clear() + doc(builder) + .html { + body { + div { + text("Hello, HtmlFlow!") + } + } + } + + assertEquals(expectedHtml, builder.toString()) + + builder.clear() + doc(builder). + html { + body { + div.text("Hello, HtmlFlow!").l + } + } + + assertEquals(expectedHtml, builder.toString()) + + + } + + @Test + fun `test complex HTML page`() { + + val expectedHtml = """ + + + + My Complex Page + + + + + + + + + +
+

+ Welcome to My Complex Page +

+ +
+
+
+

+ Section 1 +

+

+ This is the first section. +

+ Image 1 +
+
+

+ Section 2 +

+

+ This is the second section. +

+ Image 2 +
+
+

+ Section 3 +

+

+ This is the third section. +

+ Image 3 +
+
+
+

+ Copyright © 2024 +

+
+ + + """.trimIndent() + + val builder = StringBuilder() + + doc(builder) + .html() + .head() + .title() + .raw("My Complex Page") + .`__`() //title + .meta().attrCharset("UTF-8") + .`__`() //meta + .meta().attrName("description").attrContent("This is a complex HTML page.") + .`__`() //meta + .meta().attrName("keywords").attrContent("HTML,CSS,JavaScript") + .`__`() //meta + .meta().attrName("author").attrContent("John Doe") + .`__`() //meta + .link().attrRel(EnumRelType.STYLESHEET).attrHref("styles.css") + .`__`() //link + .script().attrSrc("script.js") + .`__`() //script + .`__`() //head + .body() + .header() + .h1() + .raw("Welcome to My Complex Page") + .`__`() //h1 + .nav() + .ul() + .li() + .a().attrHref("#section1") + .raw("Section 1") + .`__`() //a + .`__`() //li + .li() + .a().attrHref("#section2") + .raw("Section 2") + .`__`() //a + .`__`() //li + .li() + .a().attrHref("#section3") + .raw("Section 3") + .`__`() //a + .`__`() //li + .`__`() //ul + .`__`() //nav + .`__`() //header + .main() + .section().attrId("section1") + .h2() + .raw("Section 1") + .`__`() //h2 + .p() + .raw("This is the first section.") + .`__`() //p + .img().attrSrc("image1.jpg").attrAlt("Image 1") + .`__`() //img + .`__`() //section + .section().attrId("section2") + .h2() + .raw("Section 2") + .`__`() //h2 + .p() + .raw("This is the second section.") + .`__`() //p + .img().attrSrc("image2.jpg").attrAlt("Image 2") + .`__`() //img + .`__`() //section + .section().attrId("section3") + .h2() + .raw("Section 3") + .`__`() //h2 + .p() + .raw("This is the third section.") + .`__`() //p + .img().attrSrc("image3.jpg").attrAlt("Image 3") + .`__`() //img + .`__`() //section + .`__`() //main + .footer() + .p() + .raw("Copyright © 2024") + .`__`() //p + .`__`() //footer + .`__`() //body + .`__`() //html + + assertEquals(expectedHtml, builder.toString()) + builder.clear() + + doc(builder) + .html + .head + .title + .raw("My Complex Page") + .l //title + .meta.attrCharset("UTF-8") + .l //meta + .meta.attrName("description").attrContent("This is a complex HTML page.") + .l //meta + .meta.attrName("keywords").attrContent("HTML,CSS,JavaScript") + .l //meta + .meta.attrName("author").attrContent("John Doe") + .l //meta + .link.attrRel(EnumRelType.STYLESHEET).attrHref("styles.css") + .l //link + .script.attrSrc("script.js") + .l //script + .l //head + .body + .header + .h1 + .raw("Welcome to My Complex Page") + .l //h1 + .nav + .ul + .li + .a.attrHref("#section1") + .raw("Section 1") + .l //a + .l //li + .li + .a.attrHref("#section2") + .raw("Section 2") + .l //a + .l //li + .li + .a.attrHref("#section3") + .raw("Section 3") + .l //a + .l //li + .l //ul + .l //nav + .l //header + .main + .section.attrId("section1") + .h2 + .raw("Section 1") + .l //h2 + .p + .raw("This is the first section.") + .l //p + .img.attrSrc("image1.jpg").attrAlt("Image 1") + .l //img + .l //section + .section.attrId("section2") + .h2 + .raw("Section 2") + .l //h2 + .p + .raw("This is the second section.") + .l //p + .img.attrSrc("image2.jpg").attrAlt("Image 2") + .l //img + .l //section + .section.attrId("section3") + .h2 + .raw("Section 3") + .l //h2 + .p + .raw("This is the third section.") + .l //p + .img.attrSrc("image3.jpg").attrAlt("Image 3") + .l //img + .l //section + .l //main + .footer + .p + .raw("Copyright © 2024") + .l //p + .l //footer + .l //body + .l //html + + assertEquals(expectedHtml, builder.toString()) + builder.clear() + + doc(builder) + .html { + head { + title { + text("My Complex Page") + } + meta { + attrCharset("UTF-8") + } + meta { + attrName("description") + attrContent("This is a complex HTML page.") + } + meta { + attrName("keywords") + attrContent("HTML,CSS,JavaScript") + } + meta { + attrName("author") + attrContent("John Doe") + } + link { + attrRel(EnumRelType.STYLESHEET) + attrHref("styles.css") + } + script { + attrSrc("script.js") + } + } + body { + header { + h1 { + text("Welcome to My Complex Page") + } + nav { + ul { + li { + a { + attrHref("#section1") + text("Section 1") + } + } + li { + a { + attrHref("#section2") + text("Section 2") + } + } + li { + a { + attrHref("#section3") + text("Section 3") + } + } + } + } + } + main { + section { + attrId("section1") + h2 { + text("Section 1") + } + p { + text("This is the first section.") + } + img { + attrSrc("image1.jpg") + attrAlt("Image 1") + } + } + section { + attrId("section2") + h2 { + text("Section 2") + } + p { + text("This is the second section.") + } + img { + attrSrc("image2.jpg") + attrAlt("Image 2") + } + } + section { + attrId("section3") + h2 { + text("Section 3") + } + p { + text("This is the third section.") + } + img { + attrSrc("image3.jpg") + attrAlt("Image 3") + } + } + } + footer { + p { + text("Copyright © 2024") + } + } + } + } + + assertEquals(expectedHtml, builder.toString()) + builder.clear() + } + +} private val portugal = Weather("Portugal", listOf( Location("Porto", "Light rain", 14), Location("Lisbon", "Sunny day", 14), @@ -27,34 +462,66 @@ private val portugal = Weather("Portugal", listOf( )) private val weatherView = view { - html() - .head() - .title().dyn { weather: Weather -> + it.html + .head + .title.dyn { weather: Weather -> +weather.country } .l // title .l // head - .body() - .table().attrBorder(EnumBorderType._1) - .tr() - .th().add { +"City" }.l - .th().text("Temperature").l - .l // tr - .dyn { weather: Weather -> - weather.locations.forEach{ loc -> - tr().add { - td().text(loc.city).l - td().text(loc.celsius).l + .body { + table.attrBorder(EnumBorderType._1) + .tr { + th { + text("City") + } + th { + text("Temperature") + } + } // tr + .dyn { weather: Weather -> + weather.locations.forEach { loc -> + tr.add { + td.text(loc.city).l + td.text(loc.celsius).l + } + .l // tr + } } - .l // tr - } + .l // table + } // body + .l // html +} + +private val weatherView1 = view { + it.html + .head + .title.dyn { weather: Weather -> + +weather.country } - .l // table - .l // body + .l // title + .l // head + .body { + table.attrBorder(EnumBorderType._1) + .tr + .th.add { +"City" }.l + .th.text("Temperature").l + .l // tr + .dyn { weather: Weather -> + weather.locations.forEach { loc -> + tr.add { + td.text(loc.city).l + td.text(loc.celsius).l + } + .l // tr + } + } + .l // table + } // body .l // html } -private const val expectedPortugalWeather = """ +private val expectedPortugalWeather = """ @@ -97,4 +564,4 @@ private const val expectedPortugalWeather = """<!DOCTYPE html> </tr> </table> </body> -</html>""" \ No newline at end of file +</html>""" From 210aa81d03f908e420d7ace8bc886ebfe4b6c9c9 Mon Sep 17 00:00:00 2001 From: Miguel Gamboa <miguelgamboa@outlook.com> Date: Mon, 22 Apr 2024 11:54:23 +0100 Subject: [PATCH 02/11] Upgrade Jacoco --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 37e8845..61de633 100644 --- a/pom.xml +++ b/pom.xml @@ -234,7 +234,7 @@ <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> - <version>0.8.7</version> + <version>0.8.12</version> <executions> <execution> <id>default-prepare-agent</id> From 4b0a961b6483b0e42e2dd578575dc99c64149203 Mon Sep 17 00:00:00 2001 From: Miguel Gamboa <miguelgamboa@outlook.com> Date: Mon, 22 Apr 2024 11:54:50 +0100 Subject: [PATCH 03/11] Tests mixing idioms: method chain with nested function in same view. --- .../kotlin/htmlflow/HtmlFlowExtensions.kt | 5 ++ .../htmlflow/test/TestKotlinExtensions.kt | 68 ++++--------------- 2 files changed, 20 insertions(+), 53 deletions(-) diff --git a/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt b/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt index 7acfcc8..7dcc023 100644 --- a/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt +++ b/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt @@ -10,6 +10,11 @@ import java.util.concurrent.CompletableFuture inline val <T : Element<*, Z>, Z : Element<*,*>> T.l: Z get() = this.`__`() + +/** + * Experimental extension to check the behavior of HTML builders for lambdas with an Element receiver. + * After the AutoDsl2kt automatically generate Kotlin extensions maybe this funcion is useless. + */ inline fun <T : Element<*, Z>, Z : Element<*,*>> T.add(block: T.() -> Unit): T { block() return this diff --git a/src/test/kotlin/htmlflow/test/TestKotlinExtensions.kt b/src/test/kotlin/htmlflow/test/TestKotlinExtensions.kt index 228bd91..4f02051 100644 --- a/src/test/kotlin/htmlflow/test/TestKotlinExtensions.kt +++ b/src/test/kotlin/htmlflow/test/TestKotlinExtensions.kt @@ -376,66 +376,30 @@ class TestKotlinExtensions { } nav { ul { - li { - a { - attrHref("#section1") - text("Section 1") - } - } - li { - a { - attrHref("#section2") - text("Section 2") - } - } - li { - a { - attrHref("#section3") - text("Section 3") - } - } + li.a.attrHref("#section1").text("Section 1").l.l + li.a.attrHref("#section2").text("Section 2").l.l + li.a.attrHref("#section3").text("Section 3").l.l } } } main { section { attrId("section1") - h2 { - text("Section 1") - } - p { - text("This is the first section.") - } - img { - attrSrc("image1.jpg") - attrAlt("Image 1") - } + h2.text("Section 1").l + p.text("This is the first section.").l + img.attrSrc("image1.jpg").attrAlt("Image 1").l } section { attrId("section2") - h2 { - text("Section 2") - } - p { - text("This is the second section.") - } - img { - attrSrc("image2.jpg") - attrAlt("Image 2") - } + h2.text("Section 2").l + p.text("This is the second section.").l + img.attrSrc("image2.jpg").attrAlt("Image 2").l } section { attrId("section3") - h2 { - text("Section 3") - } - p { - text("This is the third section.") - } - img { - attrSrc("image3.jpg") - attrAlt("Image 3") - } + h2.text("Section 3").l + p.text("This is the third section.").l + img.attrSrc("image3.jpg").attrAlt("Image 3").l } } footer { @@ -481,11 +445,10 @@ private val weatherView = view<Weather> { } // tr .dyn { weather: Weather -> weather.locations.forEach { loc -> - tr.add { + tr { td.text(loc.city).l td.text(loc.celsius).l } - .l // tr } } .l // table @@ -504,16 +467,15 @@ private val weatherView1 = view<Weather> { .body { table.attrBorder(EnumBorderType._1) .tr - .th.add { +"City" }.l + .th.text("City").l .th.text("Temperature").l .l // tr .dyn { weather: Weather -> weather.locations.forEach { loc -> - tr.add { + tr { td.text(loc.city).l td.text(loc.celsius).l } - .l // tr } } .l // table From 41ac222b93d55858d8ffaec030bd64046eef47ed Mon Sep 17 00:00:00 2001 From: Miguel Gamboa <miguelgamboa@outlook.com> Date: Tue, 23 Apr 2024 10:00:43 +0100 Subject: [PATCH 04/11] Make KotlinPoet and Kotlin Reflect non-transitive dependencies with provided scope. Make exec-maven-plugin classpathScope compile. --- pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pom.xml b/pom.xml index 61de633..cd631c5 100644 --- a/pom.xml +++ b/pom.xml @@ -122,11 +122,13 @@ <groupId>com.squareup</groupId> <artifactId>kotlinpoet-jvm</artifactId> <version>1.16.0</version> + <scope>provided</scope> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-reflect</artifactId> <version>${kotlin.version}</version> + <scope>provided</scope> </dependency> </dependencies> <properties> @@ -147,6 +149,7 @@ <configuration> <mainClass>htmlflow.propertiesGenerator.ReflectionKt</mainClass> <includeProjectDependencies>true</includeProjectDependencies> + <classpathScope>compile</classpathScope> </configuration> <executions> <execution> From ec825d1fd5a8ff5642d4751dd7ddf088a75ee702 Mon Sep 17 00:00:00 2001 From: Miguel Gamboa <miguelgamboa@outlook.com> Date: Thu, 9 May 2024 18:01:24 +0100 Subject: [PATCH 05/11] Change Generator to define lambda parameter block as returning Unit instead of the receiver Element. --- src/main/kotlin/htmlflow/HtmlFlowExtensions.kt | 4 ++-- .../HtmlFlowExtensionPropertiesGenerator.kt | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt b/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt index 7dcc023..9fb0202 100644 --- a/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt +++ b/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt @@ -27,9 +27,9 @@ public inline val HtmlPage.html: Html<HtmlPage> return Html(self()) } -inline fun <T : Element<*, Z>, Z : Element<*,*>> HtmlPage.html(block : Html<HtmlPage>.() -> Html<T>) : T{ +inline fun HtmlPage.html(block : Html<HtmlPage>.() -> Unit) : HtmlPage { (this.visitor as HtmlVisitor).write(HtmlPage.HEADER) - return Html(self()).block().l + return Html(self()).also { it.block() }.l } inline var <T : Element<T,Z>, Z : Element<*,*>> T.text : T diff --git a/src/main/kotlin/htmlflow/propertiesGenerator/HtmlFlowExtensionPropertiesGenerator.kt b/src/main/kotlin/htmlflow/propertiesGenerator/HtmlFlowExtensionPropertiesGenerator.kt index bd08697..74fc13d 100644 --- a/src/main/kotlin/htmlflow/propertiesGenerator/HtmlFlowExtensionPropertiesGenerator.kt +++ b/src/main/kotlin/htmlflow/propertiesGenerator/HtmlFlowExtensionPropertiesGenerator.kt @@ -57,9 +57,11 @@ class HtmlFlowExtensionPropertiesGenerator { .addTypeVariable(type) .addParameter("block", LambdaTypeName.get( receiver = typeVariable, - returnType = typeVariable, + returnType = ClassName("kotlin", "Unit"), )) - .addStatement("return %T(%L).block().l", clazz, "this") + .addStatement("val elem = %T(%L)", clazz, "this") + .addStatement("elem.block()") + .addStatement("return elem.l", clazz, "this") .build() ) } From a8ba42a421dde57d84c70549d0051ed9058b6e9e Mon Sep 17 00:00:00 2001 From: Miguel Gamboa <miguelgamboa@outlook.com> Date: Thu, 9 May 2024 18:02:42 +0100 Subject: [PATCH 06/11] New tests with the examples of the website htmlflow.org/features with if/else, loop, async, suspending and partials, fragments and layouts. --- .../htmlflow/test/views/HtmlPartials.java | 25 +- .../test/TestKotlinExtensionsOnPartials.kt | 262 ++++++++++++++++++ 2 files changed, 269 insertions(+), 18 deletions(-) create mode 100644 src/test/kotlin/htmlflow/test/TestKotlinExtensionsOnPartials.kt diff --git a/src/test/java/htmlflow/test/views/HtmlPartials.java b/src/test/java/htmlflow/test/views/HtmlPartials.java index 46d4ef9..04678ef 100644 --- a/src/test/java/htmlflow/test/views/HtmlPartials.java +++ b/src/test/java/htmlflow/test/views/HtmlPartials.java @@ -71,19 +71,13 @@ public void testPartials() { /** * Sample showcase of data binding with HtmlDoc */ - public void trackDoc(Appendable out, Track track) { + private void trackDoc(Appendable out, Track track) { HtmlFlow.doc(out) .html() .body() .ul() - .li() - .of((li) -> li - .text(format("Artist: %s", track.getArtist()))) - .__() // li - .li() - .of((li) -> li - .text(format("Track: %s", track.getName()))) - .__() // li + .li().text(format("Artist: %s", track.getArtist())).__() + .li().text(format("Track: %s", track.getName())).__() // li .of(ul -> { if(track.getDiedDate() != null) ul.li().text(format("Died in %d", track.getDiedDate().getYear())).__(); @@ -102,15 +96,10 @@ public void trackView() { .html() .body() .ul() - .li() - .<Track>dynamic((li, track) -> li - .text(format("Artist: %s", track.getArtist()))) - .__() // li - .li() - .<Track>dynamic((li, track) -> li - .text(format("Track: %s", track.getName()))) - .__() // li .<Track>dynamic((ul, track) -> { + ul + .li().text(format("Artist: %s", track.getArtist())).__() + .li().text(format("Track: %s", track.getName())).__(); if(track.getDiedDate() != null) ul.li().text(format("Died in %d", track.getDiedDate().getYear())).__(); }) @@ -125,7 +114,7 @@ public void trackView() { // trackView.setOut(System.out).write(spaceOddity); } - public void playlistDoc(Appendable out, List<Track> tracks) { + private void playlistDoc(Appendable out, List<Track> tracks) { HtmlFlow.doc(out) .html() .body() diff --git a/src/test/kotlin/htmlflow/test/TestKotlinExtensionsOnPartials.kt b/src/test/kotlin/htmlflow/test/TestKotlinExtensionsOnPartials.kt new file mode 100644 index 0000000..36965cc --- /dev/null +++ b/src/test/kotlin/htmlflow/test/TestKotlinExtensionsOnPartials.kt @@ -0,0 +1,262 @@ +package htmlflow.test + +import htmlflow.* +import htmlflow.test.model.Track +import kotlinx.coroutines.reactive.asFlow +import kotlinx.coroutines.runBlocking +import org.junit.Assert.assertEquals +import org.junit.Test +import org.xmlet.htmlapifaster.* +import reactor.core.publisher.Flux +import java.lang.String.format +import java.time.Duration +import java.time.LocalDate +import java.util.* + + +/** + * These tests do not contain any assertion because they are only a sample for README.md + * and HtmlFlow site examples. + */ +class TestKotlinExtensionsOnPartials { + /** + * Sample showcase of data binding with HtmlDoc + */ + private fun trackDoc(out: Appendable, track: Track) { + HtmlFlow + .doc(out) + .html { + body { + ul { + li { text(format("Artist: %s", track.artist)) } + li { text(format("Track: %s", track.name)) } + if (track.diedDate != null) { + li { text(format("Died in %d", track.diedDate.year)) } + } + } + } + } + } + + /** + * Sample showcase of data binding with HtmlView + */ + @Test + fun trackView() { + val trackView = view<Track> { + html { + body { + ul { + dyn { track: Track -> + li { text(format("Artist: %s", track.artist)) } + li { text(format("Track: %s", track.name)) } + if (track.diedDate != null) { + li { text(format("Died in %d", track.diedDate.year)) } + } + } + } + } + } + } + val spaceOddity = Track("David Bowie", "Space Oddity", LocalDate.of(2016, 1, 10)) + val actual = StringBuilder() + trackDoc(actual, spaceOddity) + assertEquals(actual.toString(), trackView.render(spaceOddity)) +// trackView.setOut(System.out).write(spaceOddity); + } + + /** + * Sample showcase of loop with HtmlDoc + */ + private fun playlistDoc(out: Appendable, tracks: List<Track>) { + HtmlFlow + .doc(out) + .html { + body { + table { + tr { + th { text("Artist") } + th { text("Track") } + } + tracks.forEach { track -> + tr { td { text(track.artist) } } + tr { td { text(track.name) } } + } + } // table + } // body + } // html + } + + /** + * Sample showcase of loop with HtmlView + */ + @Test + fun playlistView() { + val playlistView = view<List<Track>> { + html { + body { + table { + tr { + th { text("Artist") } + th { text("Track") } + } + dyn { tracks: List<Track> -> tracks + .forEach { track -> + tr { td { text(track.artist) } } + tr { td { text(track.name) } } + } + } + } // table + } // body + } // html + } + val tracks = listOf( + Track("David Bowie", "Space Oddity", LocalDate.of(2016, 1, 10)), + Track("U2", "Bad"), + Track("Queen", "Under Pressure") + ) + val actual = StringBuilder() + playlistDoc(actual, tracks) + assertEquals(actual.toString(), playlistView.render(tracks)) +// playlistView.setOut(System.out).write(tracks); + } + /** + * Sample showcase of loop with HtmlViewAsync + */ + @Test + fun playlistViewAsync() { + val playlistView = viewAsync<Flux<Track>> { + html { + body { + table { + tr { + th { text("Artist") } + th { text("Track") } + } + await { tracks: Flux<Track>, resume -> tracks + .doOnComplete(resume) + .doOnNext{ track -> + tr { td { text(track.artist) } } + tr { td { text(track.name) } } + } + } + } // table + } // body + } // html + } + val tracks = Arrays.asList( + Track("David Bowie", "Space Oddity", LocalDate.of(2016, 1, 10)), + Track("U2", "Bad"), + Track("Queen", "Under Pressure") + ) + val tracksFlux = Flux + .fromIterable(tracks) + .delayElements(Duration.ofMillis(10)) + val expected = StringBuilder() + playlistDoc(expected, tracks) + playlistView.renderAsync(tracksFlux).thenAccept { actual: String? -> + assertEquals( + expected.toString(), + actual + ) + } + } + /** + * Sample showcase of loop with HtmlViewSuspend + */ + @Test + fun playlistViewSuspend() { + val playlistView = viewSuspend<Flux<Track>> { + html { + body { + table { + tr { + th { text("Artist") } + th { text("Track") } + } + suspending { tracks: Flux<Track> -> tracks + .asFlow() + .collect { track -> + tr { td { text(track.artist) } } + tr { td { text(track.name) } } + } + } + } // table + } // body + } // html + } + val tracks = Arrays.asList( + Track("David Bowie", "Space Oddity", LocalDate.of(2016, 1, 10)), + Track("U2", "Bad"), + Track("Queen", "Under Pressure") + ) + val tracksFlux = Flux + .fromIterable(tracks) + .delayElements(Duration.ofMillis(10)) + val expected = StringBuilder() + playlistDoc(expected, tracks) + runBlocking { + val actual = playlistView.render(tracksFlux) + assertEquals( + expected.toString(), + actual + ) + } + } + private fun partialInputField(container: Div<*>, label: String, id: String, value: Any) { + container + .div { + attrClass("form-group") + label { text(label) } + input { + attrClass("form-control") + attrType(EnumTypeInputType.TEXT) + attrId(id) + attrName(id) + attrValue(value.toString()) + } + } + } + private fun ownerTemplate(container: Div<*>) { + container + .h2 { text("Owner") } + .form { + attrMethod(EnumMethodType.POST) + div { + attrClass("form-group has-feedback") + dyn { owner: Owner -> + partialInputField(this, "Name", "name", owner.name) + partialInputField(this, "Address", "address", owner.address) + } + } + } + } + private fun navbarFragment(nav: Nav<*>) { + + } + + private fun ownerView(navbar: (Nav<*>) -> Unit, content: (Div<*>) -> Unit): HtmlView<Owner> { + return view<Owner> { + html { + head { + title { text("PetClinic :: a Spring Framework demonstration") } + link { attrRel(EnumRelType.STYLESHEET).attrHref("/resources/css/petclinic.css") } + } + body { + nav { navbar(this) } + div { + attrClass("container xd-container") + content(this) + } // div + } // body + } // html + } + } + + @Test fun testOwnerView() { + val view = ownerView(::navbarFragment, ::ownerTemplate) + // view.setOut(System.out).write(Owner("Ze Manel", "Rua da Alfandega")) + } + + class Owner(val name: String, val address: String) +} \ No newline at end of file From 579e66269bb42ac2a1677498ab65069290239dc5 Mon Sep 17 00:00:00 2001 From: cotinhalol <cotinhalol@github.com> Date: Tue, 14 May 2024 16:29:34 +0100 Subject: [PATCH 07/11] update html flow extension properties with lambda block returning Unit --- .../htmlflow/HtmlFlowExtensionProperties.kt | 799 +++++++++++++----- 1 file changed, 576 insertions(+), 223 deletions(-) diff --git a/src/main/kotlin/htmlflow/HtmlFlowExtensionProperties.kt b/src/main/kotlin/htmlflow/HtmlFlowExtensionProperties.kt index 8f1230c..a1fdaf5 100644 --- a/src/main/kotlin/htmlflow/HtmlFlowExtensionProperties.kt +++ b/src/main/kotlin/htmlflow/HtmlFlowExtensionProperties.kt @@ -1,5 +1,6 @@ package htmlflow +import kotlin.Unit import org.xmlet.htmlapifaster.A import org.xmlet.htmlapifaster.Abbr import org.xmlet.htmlapifaster.Address @@ -120,684 +121,1036 @@ import org.xmlet.htmlapifaster.Wbr public inline val <T : Element<T,Z>, Z : Element<*,*>> T.h2: H2<T> get() = H2(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.h2(block: H2<T>.() -> H2<T>): T = - H2(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.h2(block: H2<T>.() -> Unit): T { + val elem = H2(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.mark: Mark<T> get() = Mark(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.mark(block: Mark<T>.() -> Mark<T>): T = - Mark(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.mark(block: Mark<T>.() -> Unit): T { + val elem = Mark(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.i: I<T> get() = I(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.i(block: I<T>.() -> I<T>): T = I(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.i(block: I<T>.() -> Unit): T { + val elem = I(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.th: Th<T> get() = Th(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.th(block: Th<T>.() -> Th<T>): T = - Th(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.th(block: Th<T>.() -> Unit): T { + val elem = Th(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.strong: Strong<T> get() = Strong(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.strong(block: Strong<T>.() -> Strong<T>): T = - Strong(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.strong(block: Strong<T>.() -> Unit): T { + val elem = Strong(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.col: Col<T> get() = Col(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.col(block: Col<T>.() -> Col<T>): T = - Col(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.col(block: Col<T>.() -> Unit): T { + val elem = Col(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.math: Math<T> get() = Math(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.math(block: Math<T>.() -> Math<T>): T = - Math(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.math(block: Math<T>.() -> Unit): T { + val elem = Math(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.tbody: Tbody<T> get() = Tbody(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.tbody(block: Tbody<T>.() -> Tbody<T>): T = - Tbody(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.tbody(block: Tbody<T>.() -> Unit): T { + val elem = Tbody(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.textarea: Textarea<T> get() = Textarea(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.textarea(block: Textarea<T>.() -> Textarea<T>): T - = Textarea(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.textarea(block: Textarea<T>.() -> Unit): T { + val elem = Textarea(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.source: Source<T> get() = Source(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.source(block: Source<T>.() -> Source<T>): T = - Source(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.source(block: Source<T>.() -> Unit): T { + val elem = Source(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.rp: Rp<T> get() = Rp(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.rp(block: Rp<T>.() -> Rp<T>): T = - Rp(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.rp(block: Rp<T>.() -> Unit): T { + val elem = Rp(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.picture: Picture<T> get() = Picture(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.picture(block: Picture<T>.() -> Picture<T>): T = - Picture(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.picture(block: Picture<T>.() -> Unit): T { + val elem = Picture(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.p: P<T> get() = P(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.p(block: P<T>.() -> P<T>): T = P(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.p(block: P<T>.() -> Unit): T { + val elem = P(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.dt: Dt<T> get() = Dt(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.dt(block: Dt<T>.() -> Dt<T>): T = - Dt(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.dt(block: Dt<T>.() -> Unit): T { + val elem = Dt(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.label: Label<T> get() = Label(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.label(block: Label<T>.() -> Label<T>): T = - Label(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.label(block: Label<T>.() -> Unit): T { + val elem = Label(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.embed: Embed<T> get() = Embed(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.embed(block: Embed<T>.() -> Embed<T>): T = - Embed(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.embed(block: Embed<T>.() -> Unit): T { + val elem = Embed(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.rt: Rt<T> get() = Rt(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.rt(block: Rt<T>.() -> Rt<T>): T = - Rt(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.rt(block: Rt<T>.() -> Unit): T { + val elem = Rt(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.address: Address<T> get() = Address(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.address(block: Address<T>.() -> Address<T>): T = - Address(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.address(block: Address<T>.() -> Unit): T { + val elem = Address(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.h4: H4<T> get() = H4(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.h4(block: H4<T>.() -> H4<T>): T = - H4(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.h4(block: H4<T>.() -> Unit): T { + val elem = H4(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.`data`: Data<T> get() = Data(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.`data`(block: Data<T>.() -> Data<T>): T = - Data(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.`data`(block: Data<T>.() -> Unit): T { + val elem = Data(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.legend: Legend<T> get() = Legend(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.legend(block: Legend<T>.() -> Legend<T>): T = - Legend(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.legend(block: Legend<T>.() -> Unit): T { + val elem = Legend(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.option: Option<T> get() = Option(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.option(block: Option<T>.() -> Option<T>): T = - Option(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.option(block: Option<T>.() -> Unit): T { + val elem = Option(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.detailssummary: DetailsSummary<T> get() = DetailsSummary(this.self()) public fun <T : Element<T,Z>, Z : Element<*,*>> - T.detailssummary(block: DetailsSummary<T>.() -> DetailsSummary<T>): T = - DetailsSummary(this).block().l + T.detailssummary(block: DetailsSummary<T>.() -> Unit): T { + val elem = DetailsSummary(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.track: Track<T> get() = Track(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.track(block: Track<T>.() -> Track<T>): T = - Track(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.track(block: Track<T>.() -> Unit): T { + val elem = Track(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.figcaption: Figcaption<T> get() = Figcaption(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> - T.figcaption(block: Figcaption<T>.() -> Figcaption<T>): T = Figcaption(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.figcaption(block: Figcaption<T>.() -> Unit): T { + val elem = Figcaption(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.sub: Sub<T> get() = Sub(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.sub(block: Sub<T>.() -> Sub<T>): T = - Sub(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.sub(block: Sub<T>.() -> Unit): T { + val elem = Sub(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.details: Details<T> get() = Details(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.details(block: Details<T>.() -> Details<T>): T = - Details(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.details(block: Details<T>.() -> Unit): T { + val elem = Details(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.aside: Aside<T> get() = Aside(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.aside(block: Aside<T>.() -> Aside<T>): T = - Aside(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.aside(block: Aside<T>.() -> Unit): T { + val elem = Aside(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.footer: Footer<T> get() = Footer(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.footer(block: Footer<T>.() -> Footer<T>): T = - Footer(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.footer(block: Footer<T>.() -> Unit): T { + val elem = Footer(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.h6: H6<T> get() = H6(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.h6(block: H6<T>.() -> H6<T>): T = - H6(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.h6(block: H6<T>.() -> Unit): T { + val elem = H6(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.hr: Hr<T> get() = Hr(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.hr(block: Hr<T>.() -> Hr<T>): T = - Hr(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.hr(block: Hr<T>.() -> Unit): T { + val elem = Hr(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.link: Link<T> get() = Link(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.link(block: Link<T>.() -> Link<T>): T = - Link(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.link(block: Link<T>.() -> Unit): T { + val elem = Link(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.meta: Meta<T> get() = Meta(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.meta(block: Meta<T>.() -> Meta<T>): T = - Meta(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.meta(block: Meta<T>.() -> Unit): T { + val elem = Meta(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.`var`: Var<T> get() = Var(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.`var`(block: Var<T>.() -> Var<T>): T = - Var(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.`var`(block: Var<T>.() -> Unit): T { + val elem = Var(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.h1: H1<T> get() = H1(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.h1(block: H1<T>.() -> H1<T>): T = - H1(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.h1(block: H1<T>.() -> Unit): T { + val elem = H1(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.q: Q<T> get() = Q(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.q(block: Q<T>.() -> Q<T>): T = Q(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.q(block: Q<T>.() -> Unit): T { + val elem = Q(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.output: Output<T> get() = Output(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.output(block: Output<T>.() -> Output<T>): T = - Output(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.output(block: Output<T>.() -> Unit): T { + val elem = Output(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.li: Li<T> get() = Li(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.li(block: Li<T>.() -> Li<T>): T = - Li(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.li(block: Li<T>.() -> Unit): T { + val elem = Li(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.span: Span<T> get() = Span(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.span(block: Span<T>.() -> Span<T>): T = - Span(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.span(block: Span<T>.() -> Unit): T { + val elem = Span(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.time: Time<T> get() = Time(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.time(block: Time<T>.() -> Time<T>): T = - Time(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.time(block: Time<T>.() -> Unit): T { + val elem = Time(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.caption: Caption<T> get() = Caption(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.caption(block: Caption<T>.() -> Caption<T>): T = - Caption(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.caption(block: Caption<T>.() -> Unit): T { + val elem = Caption(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.progress: Progress<T> get() = Progress(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.progress(block: Progress<T>.() -> Progress<T>): T - = Progress(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.progress(block: Progress<T>.() -> Unit): T { + val elem = Progress(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.dl: Dl<T> get() = Dl(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.dl(block: Dl<T>.() -> Dl<T>): T = - Dl(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.dl(block: Dl<T>.() -> Unit): T { + val elem = Dl(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.s: S<T> get() = S(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.s(block: S<T>.() -> S<T>): T = S(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.s(block: S<T>.() -> Unit): T { + val elem = S(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.h3: H3<T> get() = H3(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.h3(block: H3<T>.() -> H3<T>): T = - H3(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.h3(block: H3<T>.() -> Unit): T { + val elem = H3(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.cite: Cite<T> get() = Cite(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.cite(block: Cite<T>.() -> Cite<T>): T = - Cite(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.cite(block: Cite<T>.() -> Unit): T { + val elem = Cite(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.abbr: Abbr<T> get() = Abbr(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.abbr(block: Abbr<T>.() -> Abbr<T>): T = - Abbr(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.abbr(block: Abbr<T>.() -> Unit): T { + val elem = Abbr(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.tr: Tr<T> get() = Tr(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.tr(block: Tr<T>.() -> Tr<T>): T = - Tr(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.tr(block: Tr<T>.() -> Unit): T { + val elem = Tr(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.`param`: Param<T> get() = Param(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.`param`(block: Param<T>.() -> Param<T>): T = - Param(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.`param`(block: Param<T>.() -> Unit): T { + val elem = Param(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.colgroup: Colgroup<T> get() = Colgroup(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.colgroup(block: Colgroup<T>.() -> Colgroup<T>): T - = Colgroup(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.colgroup(block: Colgroup<T>.() -> Unit): T { + val elem = Colgroup(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.dfn: Dfn<T> get() = Dfn(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.dfn(block: Dfn<T>.() -> Dfn<T>): T = - Dfn(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.dfn(block: Dfn<T>.() -> Unit): T { + val elem = Dfn(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.br: Br<T> get() = Br(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.br(block: Br<T>.() -> Br<T>): T = - Br(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.br(block: Br<T>.() -> Unit): T { + val elem = Br(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.head: Head<T> get() = Head(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.head(block: Head<T>.() -> Head<T>): T = - Head(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.head(block: Head<T>.() -> Unit): T { + val elem = Head(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.table: Table<T> get() = Table(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.table(block: Table<T>.() -> Table<T>): T = - Table(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.table(block: Table<T>.() -> Unit): T { + val elem = Table(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.template: Template<T> get() = Template(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.template(block: Template<T>.() -> Template<T>): T - = Template(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.template(block: Template<T>.() -> Unit): T { + val elem = Template(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.kbd: Kbd<T> get() = Kbd(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.kbd(block: Kbd<T>.() -> Kbd<T>): T = - Kbd(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.kbd(block: Kbd<T>.() -> Unit): T { + val elem = Kbd(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.h5: H5<T> get() = H5(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.h5(block: H5<T>.() -> H5<T>): T = - H5(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.h5(block: H5<T>.() -> Unit): T { + val elem = H5(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.u: U<T> get() = U(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.u(block: U<T>.() -> U<T>): T = U(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.u(block: U<T>.() -> Unit): T { + val elem = U(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.noscript: Noscript<T> get() = Noscript(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.noscript(block: Noscript<T>.() -> Noscript<T>): T - = Noscript(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.noscript(block: Noscript<T>.() -> Unit): T { + val elem = Noscript(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.root: Root<T> get() = Root(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.root(block: Root<T>.() -> Root<T>): T = - Root(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.root(block: Root<T>.() -> Unit): T { + val elem = Root(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.div: Div<T> get() = Div(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.div(block: Div<T>.() -> Div<T>): T = - Div(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.div(block: Div<T>.() -> Unit): T { + val elem = Div(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.select: Select<T> get() = Select(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.select(block: Select<T>.() -> Select<T>): T = - Select(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.select(block: Select<T>.() -> Unit): T { + val elem = Select(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.`header`: Header<T> get() = Header(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.`header`(block: Header<T>.() -> Header<T>): T = - Header(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.`header`(block: Header<T>.() -> Unit): T { + val elem = Header(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.datalist: Datalist<T> get() = Datalist(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.datalist(block: Datalist<T>.() -> Datalist<T>): T - = Datalist(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.datalist(block: Datalist<T>.() -> Unit): T { + val elem = Datalist(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.bdi: Bdi<T> get() = Bdi(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.bdi(block: Bdi<T>.() -> Bdi<T>): T = - Bdi(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.bdi(block: Bdi<T>.() -> Unit): T { + val elem = Bdi(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.rb: Rb<T> get() = Rb(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.rb(block: Rb<T>.() -> Rb<T>): T = - Rb(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.rb(block: Rb<T>.() -> Unit): T { + val elem = Rb(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.input: Input<T> get() = Input(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.input(block: Input<T>.() -> Input<T>): T = - Input(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.input(block: Input<T>.() -> Unit): T { + val elem = Input(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.canvas: Canvas<T> get() = Canvas(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.canvas(block: Canvas<T>.() -> Canvas<T>): T = - Canvas(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.canvas(block: Canvas<T>.() -> Unit): T { + val elem = Canvas(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.b: B<T> get() = B(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.b(block: B<T>.() -> B<T>): T = B(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.b(block: B<T>.() -> Unit): T { + val elem = B(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.ol: Ol<T> get() = Ol(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.ol(block: Ol<T>.() -> Ol<T>): T = - Ol(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.ol(block: Ol<T>.() -> Unit): T { + val elem = Ol(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.code: Code<T> get() = Code(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.code(block: Code<T>.() -> Code<T>): T = - Code(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.code(block: Code<T>.() -> Unit): T { + val elem = Code(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.dd: Dd<T> get() = Dd(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.dd(block: Dd<T>.() -> Dd<T>): T = - Dd(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.dd(block: Dd<T>.() -> Unit): T { + val elem = Dd(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.title: Title<T> get() = Title(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.title(block: Title<T>.() -> Title<T>): T = - Title(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.title(block: Title<T>.() -> Unit): T { + val elem = Title(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.thead: Thead<T> get() = Thead(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.thead(block: Thead<T>.() -> Thead<T>): T = - Thead(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.thead(block: Thead<T>.() -> Unit): T { + val elem = Thead(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.em: Em<T> get() = Em(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.em(block: Em<T>.() -> Em<T>): T = - Em(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.em(block: Em<T>.() -> Unit): T { + val elem = Em(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.fieldset: Fieldset<T> get() = Fieldset(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.fieldset(block: Fieldset<T>.() -> Fieldset<T>): T - = Fieldset(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.fieldset(block: Fieldset<T>.() -> Unit): T { + val elem = Fieldset(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.area: Area<T> get() = Area(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.area(block: Area<T>.() -> Area<T>): T = - Area(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.area(block: Area<T>.() -> Unit): T { + val elem = Area(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.sup: Sup<T> get() = Sup(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.sup(block: Sup<T>.() -> Sup<T>): T = - Sup(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.sup(block: Sup<T>.() -> Unit): T { + val elem = Sup(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.style: Style<T> get() = Style(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.style(block: Style<T>.() -> Style<T>): T = - Style(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.style(block: Style<T>.() -> Unit): T { + val elem = Style(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.nav: Nav<T> get() = Nav(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.nav(block: Nav<T>.() -> Nav<T>): T = - Nav(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.nav(block: Nav<T>.() -> Unit): T { + val elem = Nav(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.ul: Ul<T> get() = Ul(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.ul(block: Ul<T>.() -> Ul<T>): T = - Ul(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.ul(block: Ul<T>.() -> Unit): T { + val elem = Ul(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.tfoot: Tfoot<T> get() = Tfoot(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.tfoot(block: Tfoot<T>.() -> Tfoot<T>): T = - Tfoot(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.tfoot(block: Tfoot<T>.() -> Unit): T { + val elem = Tfoot(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.bdo: Bdo<T> get() = Bdo(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.bdo(block: Bdo<T>.() -> Bdo<T>): T = - Bdo(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.bdo(block: Bdo<T>.() -> Unit): T { + val elem = Bdo(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.script: Script<T> get() = Script(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.script(block: Script<T>.() -> Script<T>): T = - Script(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.script(block: Script<T>.() -> Unit): T { + val elem = Script(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.section: Section<T> get() = Section(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.section(block: Section<T>.() -> Section<T>): T = - Section(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.section(block: Section<T>.() -> Unit): T { + val elem = Section(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.meter: Meter<T> get() = Meter(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.meter(block: Meter<T>.() -> Meter<T>): T = - Meter(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.meter(block: Meter<T>.() -> Unit): T { + val elem = Meter(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.small: Small<T> get() = Small(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.small(block: Small<T>.() -> Small<T>): T = - Small(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.small(block: Small<T>.() -> Unit): T { + val elem = Small(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.form: Form<T> get() = Form(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.form(block: Form<T>.() -> Form<T>): T = - Form(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.form(block: Form<T>.() -> Unit): T { + val elem = Form(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.base: Base<T> get() = Base(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.base(block: Base<T>.() -> Base<T>): T = - Base(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.base(block: Base<T>.() -> Unit): T { + val elem = Base(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.blockquote: Blockquote<T> get() = Blockquote(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> - T.blockquote(block: Blockquote<T>.() -> Blockquote<T>): T = Blockquote(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.blockquote(block: Blockquote<T>.() -> Unit): T { + val elem = Blockquote(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.audio: Audio<T> get() = Audio(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.audio(block: Audio<T>.() -> Audio<T>): T = - Audio(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.audio(block: Audio<T>.() -> Unit): T { + val elem = Audio(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.a: A<T> get() = A(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.a(block: A<T>.() -> A<T>): T = A(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.a(block: A<T>.() -> Unit): T { + val elem = A(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.article: Article<T> get() = Article(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.article(block: Article<T>.() -> Article<T>): T = - Article(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.article(block: Article<T>.() -> Unit): T { + val elem = Article(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.detailscomplete: DetailsComplete<T> get() = DetailsComplete(this.self()) public fun <T : Element<T,Z>, Z : Element<*,*>> - T.detailscomplete(block: DetailsComplete<T>.() -> DetailsComplete<T>): T = - DetailsComplete(this).block().l + T.detailscomplete(block: DetailsComplete<T>.() -> Unit): T { + val elem = DetailsComplete(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.rtc: Rtc<T> get() = Rtc(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.rtc(block: Rtc<T>.() -> Rtc<T>): T = - Rtc(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.rtc(block: Rtc<T>.() -> Unit): T { + val elem = Rtc(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.`object`: Object<T> get() = Object(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.`object`(block: Object<T>.() -> Object<T>): T = - Object(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.`object`(block: Object<T>.() -> Unit): T { + val elem = Object(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.main: Main<T> get() = Main(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.main(block: Main<T>.() -> Main<T>): T = - Main(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.main(block: Main<T>.() -> Unit): T { + val elem = Main(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.video: Video<T> get() = Video(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.video(block: Video<T>.() -> Video<T>): T = - Video(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.video(block: Video<T>.() -> Unit): T { + val elem = Video(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.iframe: Iframe<T> get() = Iframe(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.iframe(block: Iframe<T>.() -> Iframe<T>): T = - Iframe(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.iframe(block: Iframe<T>.() -> Unit): T { + val elem = Iframe(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.del: Del<T> get() = Del(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.del(block: Del<T>.() -> Del<T>): T = - Del(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.del(block: Del<T>.() -> Unit): T { + val elem = Del(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.pre: Pre<T> get() = Pre(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.pre(block: Pre<T>.() -> Pre<T>): T = - Pre(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.pre(block: Pre<T>.() -> Unit): T { + val elem = Pre(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.wbr: Wbr<T> get() = Wbr(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.wbr(block: Wbr<T>.() -> Wbr<T>): T = - Wbr(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.wbr(block: Wbr<T>.() -> Unit): T { + val elem = Wbr(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.map: Map<T> get() = Map(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.map(block: Map<T>.() -> Map<T>): T = - Map(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.map(block: Map<T>.() -> Unit): T { + val elem = Map(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.figure: Figure<T> get() = Figure(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.figure(block: Figure<T>.() -> Figure<T>): T = - Figure(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.figure(block: Figure<T>.() -> Unit): T { + val elem = Figure(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.summary: Summary<T> get() = Summary(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.summary(block: Summary<T>.() -> Summary<T>): T = - Summary(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.summary(block: Summary<T>.() -> Unit): T { + val elem = Summary(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.body: Body<T> get() = Body(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.body(block: Body<T>.() -> Body<T>): T = - Body(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.body(block: Body<T>.() -> Unit): T { + val elem = Body(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.img: Img<T> get() = Img(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.img(block: Img<T>.() -> Img<T>): T = - Img(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.img(block: Img<T>.() -> Unit): T { + val elem = Img(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.optgroup: Optgroup<T> get() = Optgroup(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.optgroup(block: Optgroup<T>.() -> Optgroup<T>): T - = Optgroup(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.optgroup(block: Optgroup<T>.() -> Unit): T { + val elem = Optgroup(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.ins: Ins<T> get() = Ins(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.ins(block: Ins<T>.() -> Ins<T>): T = - Ins(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.ins(block: Ins<T>.() -> Unit): T { + val elem = Ins(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.svg: Svg<T> get() = Svg(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.svg(block: Svg<T>.() -> Svg<T>): T = - Svg(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.svg(block: Svg<T>.() -> Unit): T { + val elem = Svg(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.samp: Samp<T> get() = Samp(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.samp(block: Samp<T>.() -> Samp<T>): T = - Samp(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.samp(block: Samp<T>.() -> Unit): T { + val elem = Samp(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.td: Td<T> get() = Td(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.td(block: Td<T>.() -> Td<T>): T = - Td(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.td(block: Td<T>.() -> Unit): T { + val elem = Td(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.dialog: Dialog<T> get() = Dialog(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.dialog(block: Dialog<T>.() -> Dialog<T>): T = - Dialog(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.dialog(block: Dialog<T>.() -> Unit): T { + val elem = Dialog(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.ruby: Ruby<T> get() = Ruby(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.ruby(block: Ruby<T>.() -> Ruby<T>): T = - Ruby(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.ruby(block: Ruby<T>.() -> Unit): T { + val elem = Ruby(this) + elem.block() + return elem.l +} public inline val <T : Element<T,Z>, Z : Element<*,*>> T.button: Button<T> get() = Button(this.self()) -public fun <T : Element<T,Z>, Z : Element<*,*>> T.button(block: Button<T>.() -> Button<T>): T = - Button(this).block().l +public fun <T : Element<T,Z>, Z : Element<*,*>> T.button(block: Button<T>.() -> Unit): T { + val elem = Button(this) + elem.block() + return elem.l +} From fa0b87aa4a654157956cc499458f21f8a197c4c6 Mon Sep 17 00:00:00 2001 From: Miguel Gamboa <miguelgamboa@outlook.com> Date: Tue, 21 May 2024 17:49:30 +0100 Subject: [PATCH 08/11] New Kotin doc buider. Fix Kotlin examples to manage partials with a Receiver. --- .../kotlin/htmlflow/HtmlFlowExtensions.kt | 35 ++++---- .../test/TestKotlinExtensionsOnPartials.kt | 82 +++++++++---------- 2 files changed, 60 insertions(+), 57 deletions(-) diff --git a/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt b/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt index 9fb0202..d6a7c7a 100644 --- a/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt +++ b/src/main/kotlin/htmlflow/HtmlFlowExtensions.kt @@ -1,37 +1,39 @@ package htmlflow +//import jdk.internal.org.jline.utils.ShutdownHooks import htmlflow.continuations.HtmlContinuationSuspendableTerminationNode import htmlflow.visitor.HtmlVisitor import htmlflow.visitor.PreprocessingVisitor -//import jdk.internal.org.jline.utils.ShutdownHooks -import org.xmlet.htmlapifaster.* -import java.util.concurrent.CompletableFuture +import org.xmlet.htmlapifaster.Element +import org.xmlet.htmlapifaster.Html +import org.xmlet.htmlapifaster.Text +/** + * Alternative close tag function for `__()`. + */ inline val <T : Element<*, Z>, Z : Element<*,*>> T.l: Z get() = this.`__`() - /** - * Experimental extension to check the behavior of HTML builders for lambdas with an Element receiver. - * After the AutoDsl2kt automatically generate Kotlin extensions maybe this funcion is useless. + * Root property of HTML element. */ -inline fun <T : Element<*, Z>, Z : Element<*,*>> T.add(block: T.() -> Unit): T { - block() - return this -} - - -public inline val HtmlPage.html: Html<HtmlPage> +inline val HtmlPage.html: Html<HtmlPage> get() { (this.visitor as HtmlVisitor).write(HtmlPage.HEADER) return Html(self()) } +/** + * Root builder of HTML element with lambda with receiver. + */ inline fun HtmlPage.html(block : Html<HtmlPage>.() -> Unit) : HtmlPage { (this.visitor as HtmlVisitor).write(HtmlPage.HEADER) return Html(self()).also { it.block() }.l } +/** + * Text node property. + */ inline var <T : Element<T,Z>, Z : Element<*,*>> T.text : T get() = self() set(value) { @@ -44,8 +46,6 @@ inline var <T : Element<T,Z>, Z : Element<*,*>> T.text : T ) } - - /** * @param T type of the Element receiver * @param Z type of the parent Element of the receiver @@ -70,6 +70,11 @@ inline fun <T : Element<*,*>, Z : Element<*,*>, M> Element<T, Z>.await(crossinli return this.self() } +/** + * Appendable extension to build an HtmlDoc. + */ +fun Appendable.doc(block: HtmlDoc.() -> Unit): HtmlDoc = HtmlFlow.doc(this).also(block) + /** * @param M type of the model (aka context object) */ diff --git a/src/test/kotlin/htmlflow/test/TestKotlinExtensionsOnPartials.kt b/src/test/kotlin/htmlflow/test/TestKotlinExtensionsOnPartials.kt index 36965cc..6ffa7f5 100644 --- a/src/test/kotlin/htmlflow/test/TestKotlinExtensionsOnPartials.kt +++ b/src/test/kotlin/htmlflow/test/TestKotlinExtensionsOnPartials.kt @@ -22,10 +22,9 @@ class TestKotlinExtensionsOnPartials { /** * Sample showcase of data binding with HtmlDoc */ - private fun trackDoc(out: Appendable, track: Track) { - HtmlFlow - .doc(out) - .html { + private fun Appendable.trackDoc(track: Track) { + doc { + html { body { ul { li { text(format("Artist: %s", track.artist)) } @@ -33,9 +32,10 @@ class TestKotlinExtensionsOnPartials { if (track.diedDate != null) { li { text(format("Died in %d", track.diedDate.year)) } } - } - } - } + } // ul + } // body + } // html + } // doc } /** @@ -60,7 +60,7 @@ class TestKotlinExtensionsOnPartials { } val spaceOddity = Track("David Bowie", "Space Oddity", LocalDate.of(2016, 1, 10)) val actual = StringBuilder() - trackDoc(actual, spaceOddity) + actual.trackDoc(spaceOddity) assertEquals(actual.toString(), trackView.render(spaceOddity)) // trackView.setOut(System.out).write(spaceOddity); } @@ -68,10 +68,9 @@ class TestKotlinExtensionsOnPartials { /** * Sample showcase of loop with HtmlDoc */ - private fun playlistDoc(out: Appendable, tracks: List<Track>) { - HtmlFlow - .doc(out) - .html { + private fun Appendable.playlistDoc(tracks: List<Track>) { + doc { + html { body { table { tr { @@ -85,6 +84,7 @@ class TestKotlinExtensionsOnPartials { } // table } // body } // html + } // doc } /** @@ -116,7 +116,7 @@ class TestKotlinExtensionsOnPartials { Track("Queen", "Under Pressure") ) val actual = StringBuilder() - playlistDoc(actual, tracks) + actual.playlistDoc(tracks) assertEquals(actual.toString(), playlistView.render(tracks)) // playlistView.setOut(System.out).write(tracks); } @@ -153,7 +153,7 @@ class TestKotlinExtensionsOnPartials { .fromIterable(tracks) .delayElements(Duration.ofMillis(10)) val expected = StringBuilder() - playlistDoc(expected, tracks) + expected.playlistDoc(tracks) playlistView.renderAsync(tracksFlux).thenAccept { actual: String? -> assertEquals( expected.toString(), @@ -194,7 +194,7 @@ class TestKotlinExtensionsOnPartials { .fromIterable(tracks) .delayElements(Duration.ofMillis(10)) val expected = StringBuilder() - playlistDoc(expected, tracks) + expected.playlistDoc(tracks) runBlocking { val actual = playlistView.render(tracksFlux) assertEquals( @@ -203,39 +203,37 @@ class TestKotlinExtensionsOnPartials { ) } } - private fun partialInputField(container: Div<*>, label: String, id: String, value: Any) { - container - .div { - attrClass("form-group") - label { text(label) } - input { - attrClass("form-control") - attrType(EnumTypeInputType.TEXT) - attrId(id) - attrName(id) - attrValue(value.toString()) - } - } + private fun Div<*>.partialInputField(label: String, id: String, value: Any) { + div { + attrClass("form-group") + label { text(label) } + input { + attrClass("form-control") + attrType(EnumTypeInputType.TEXT) + attrId(id) + attrName(id) + attrValue(value.toString()) + } // input + } // div } - private fun ownerTemplate(container: Div<*>) { - container - .h2 { text("Owner") } - .form { - attrMethod(EnumMethodType.POST) - div { - attrClass("form-group has-feedback") - dyn { owner: Owner -> - partialInputField(this, "Name", "name", owner.name) - partialInputField(this, "Address", "address", owner.address) - } + private fun Div<*>.partialOwner() { + h2 { text("Owner") } + form { + attrMethod(EnumMethodType.POST) + div { + attrClass("form-group has-feedback") + dyn { owner: Owner -> + partialInputField("Name", "name", owner.name) + partialInputField("Address", "address", owner.address) } - } + } // div + } // form } private fun navbarFragment(nav: Nav<*>) { } - private fun ownerView(navbar: (Nav<*>) -> Unit, content: (Div<*>) -> Unit): HtmlView<Owner> { + private fun ownerView(navbar: (Nav<*>) -> Unit, content: Div<*>.() -> Unit): HtmlView<Owner> { return view<Owner> { html { head { @@ -254,7 +252,7 @@ class TestKotlinExtensionsOnPartials { } @Test fun testOwnerView() { - val view = ownerView(::navbarFragment, ::ownerTemplate) + val view = ownerView(::navbarFragment) { partialOwner() } // view.setOut(System.out).write(Owner("Ze Manel", "Rua da Alfandega")) } From 513a225bd43a49cbfeaa87f2800320c71f313beb Mon Sep 17 00:00:00 2001 From: Miguel Gamboa <miguelgamboa@outlook.com> Date: Tue, 21 May 2024 17:53:29 +0100 Subject: [PATCH 09/11] [maven-release-plugin] prepare release htmlflow-4.6 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index cd631c5..e9f67d7 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>com.github.xmlet</groupId> <artifactId>htmlflow</artifactId> - <version>4.6-SNAPSHOT</version> + <version>4.6</version> <packaging>jar</packaging> <name>${project.groupId}:${project.artifactId}</name> <description> @@ -29,7 +29,7 @@ <connection>scm:git:git@github.com:xmlet/HtmlFlow.git</connection> <developerConnection>scm:git:git@github.com:xmlet/HtmlFlow.git</developerConnection> <url>git@github.com:xmlet/HtmlFlow.git</url> - <tag>HEAD</tag> + <tag>htmlflow-4.6</tag> </scm> <distributionManagement> <snapshotRepository> From b0b2243505ffda32fbc438090423a3acbdd3ad84 Mon Sep 17 00:00:00 2001 From: Miguel Gamboa <miguelgamboa@outlook.com> Date: Tue, 21 May 2024 17:53:29 +0100 Subject: [PATCH 10/11] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index e9f67d7..8f7e549 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>com.github.xmlet</groupId> <artifactId>htmlflow</artifactId> - <version>4.6</version> + <version>4.7-SNAPSHOT</version> <packaging>jar</packaging> <name>${project.groupId}:${project.artifactId}</name> <description> @@ -29,7 +29,7 @@ <connection>scm:git:git@github.com:xmlet/HtmlFlow.git</connection> <developerConnection>scm:git:git@github.com:xmlet/HtmlFlow.git</developerConnection> <url>git@github.com:xmlet/HtmlFlow.git</url> - <tag>htmlflow-4.6</tag> + <tag>HEAD</tag> </scm> <distributionManagement> <snapshotRepository> From 73db51a84246d5669171a51e992f398ac2e93680 Mon Sep 17 00:00:00 2001 From: Miguel Gamboa <miguelgamboa@outlook.com> Date: Tue, 21 May 2024 18:38:04 +0100 Subject: [PATCH 11/11] Update README --- Readme.md | 8 ++++---- .../test/TestKotlinExtensionsOnPartials.kt | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Readme.md b/Readme.md index 878eea8..f70829f 100644 --- a/Readme.md +++ b/Readme.md @@ -1,7 +1,7 @@ # HtmlFlow [![Build Status](https://sonarcloud.io/api/project_badges/measure?project=com.github.xmlet%3Ahtmlflow&metric=alert_status)](https://sonarcloud.io/dashboard?id=com.github.xmlet%3Ahtmlflow) -[![Maven Central Version](https://maven-badges.herokuapp.com/maven-central/com.github.xmlet/htmlflow/badge.svg)](http://search.maven.org/#search%7Cga%7C1%7Cxmlet%20htmlflow) +[![Maven Central Version](https://maven-badges.herokuapp.com/maven-central/com.github.xmlet/htmlflow/badge.svg)](https://search.maven.org/artifact/com.github.xmlet/htmlflow) [![Coverage Status](https://sonarcloud.io/api/project_badges/measure?project=com.github.xmlet%3Ahtmlflow&metric=coverage)](https://sonarcloud.io/component_measures?id=com.github.xmlet%3Ahtmlflow&metric=Coverage) [![javadoc HtmlApiFaster](https://img.shields.io/badge/javadocs-HtmlApiFaster-blue)](https://javadoc.io/doc/com.github.xmlet/htmlApiFaster/latest/org/xmlet/htmlapifaster/package-summary.html) [![javadoc HtmlFlow](https://img.shields.io/badge/javadocs-HtmlFlow-blue)](https://javadoc.io/doc/com.github.xmlet/htmlflow) @@ -9,7 +9,7 @@ [![Petclinic Sample](https://img.shields.io/badge/petclinic-Spring%20boot%20sample%20with%20HtmlFlow-blue)](https://github.com/xmlet/spring-petclinic) [**HtmlFlow**](https://htmlflow.org/) is a Java DSL to write **typesafe HTML** -in a fluent style. +in a fluent style, in both **Java** or **Kotlin** (for Kotlin check the [examples](https://htmlflow.org/features#data-binding)) You may use the utility `Flowifier.fromHtml(String html)` if you need the HtmlFlow definition for an existing HTML source: @@ -125,10 +125,10 @@ Bonus points it also produces only valid HTML according to HTML 5.2. ## Installation First, in order to include it to your Gradle project, simply add the following dependency, -or use any other form provided in [Maven Central Repository](https://search.maven.org/artifact/com.github.xmlet/htmlflow/4.4/jar): +or use any other form provided in [Maven Central Repository](https://search.maven.org/artifact/com.github.xmlet/htmlflow/4.6/jar): ```xml -implementation 'com.github.xmlet:htmlflow:4.4' +implementation 'com.github.xmlet:htmlflow:4.6' ``` You can also download the artifact directly from [Maven diff --git a/src/test/kotlin/htmlflow/test/TestKotlinExtensionsOnPartials.kt b/src/test/kotlin/htmlflow/test/TestKotlinExtensionsOnPartials.kt index 6ffa7f5..813aad9 100644 --- a/src/test/kotlin/htmlflow/test/TestKotlinExtensionsOnPartials.kt +++ b/src/test/kotlin/htmlflow/test/TestKotlinExtensionsOnPartials.kt @@ -19,6 +19,25 @@ import java.util.* * and HtmlFlow site examples. */ class TestKotlinExtensionsOnPartials { + + private fun testOpeningExampleOfReadme() { + System.out.doc { + html { + head { + title { text("HtmlFlow") } + } + body { + div { + attrClass("container") + h1 { text("My first HtmlFlow page") } + img { attrSrc("http://bit.ly/2MoHwrU") } + p { text("Typesafe is awesome! :-)") } + } + }// body + } //html + } // doc + } + /** * Sample showcase of data binding with HtmlDoc */