github.com/primecitizens/pcz/std@v0.2.1/ui/html/builder.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright 2023 The Prime Citizens 3 4 //go:build js 5 6 package html 7 8 import ( 9 "github.com/primecitizens/pcz/std/core/mark" 10 "github.com/primecitizens/pcz/std/ffi/js" 11 ) 12 13 // Builder builds HTMLElement.innerHTML 14 type Builder struct { 15 elem js.Ref 16 17 _buffer mark.SelfPointing 18 buf []byte 19 20 buffer [256]byte 21 } 22 23 func (b *Builder) Reset(targetElem js.Ref) *Builder { 24 b.elem = targetElem 25 b.buf = b.buffer[:0:len(b.buffer)] 26 reset(targetElem) 27 return b 28 } 29 30 func (b *Builder) Close() { 31 free(b.elem) 32 } 33 34 func (b *Builder) Int(v int64, base int) *Builder { 35 b.clearLocalBuf() 36 integer(b.elem, js.True, js.Pointer(&v), uint32(base)) 37 return b 38 } 39 40 func (b *Builder) Uint(v uint64, base int) *Builder { 41 b.clearLocalBuf() 42 integer(b.elem, js.False, js.Pointer(&v), uint32(base)) 43 return b 44 } 45 46 func (b *Builder) Float(v float64) *Builder { 47 b.clearLocalBuf() 48 float(b.elem, v) 49 return b 50 } 51 52 func (b *Builder) JSHtml(html ...js.String) *Builder { 53 b.clearLocalBuf() 54 buf_jsstr(b.elem, js.False, js.SliceData(html), js.SizeU(len(html))) 55 return b 56 } 57 58 func (b *Builder) JSText(text ...js.String) *Builder { 59 b.clearLocalBuf() 60 buf_jsstr(b.elem, js.True, js.SliceData(text), js.SizeU(len(text))) 61 return b 62 } 63 64 func (b *Builder) Text(text ...string) *Builder { 65 var ( 66 x string 67 replace string 68 ) 69 70 for _, s := range text { 71 last := 0 72 for i := 0; i < len(s); i++ { 73 switch s[i] { 74 case '&': 75 replace = "&" 76 case '\'': 77 replace = "'" 78 case '<': 79 replace = "<" 80 case '>': 81 replace = ">" 82 case '"': 83 replace = """ 84 default: 85 continue 86 } 87 88 if x = s[last:i]; len(x) != 0 { 89 b.write(x) 90 } 91 last = i + 1 92 b.write(replace) 93 } 94 95 if x = s[last:]; len(x) != 0 { 96 b.write(x) 97 } 98 } 99 100 return b 101 } 102 103 // TODO 104 func (b *Builder) Url(quote bool, u string) *Builder { 105 return b 106 } 107 108 // TODO 109 func (b *Builder) JSUrl(quote byte, u js.String) *Builder { 110 return b 111 } 112 113 func (b *Builder) Html(html ...string) *Builder { 114 for _, s := range html { 115 b.write(s) 116 } 117 118 return b 119 } 120 121 func (b *Builder) TextBlock(htmlBegin, htmlEnd string, text ...string) *Builder { 122 b.write(htmlBegin) 123 b.Text(text...) 124 b.write(htmlEnd) 125 return b 126 } 127 128 func (b *Builder) Discard() *Builder { 129 b.Reset(b.elem) 130 return b 131 } 132 133 // Flush buffered content to innerHTML. 134 func (b *Builder) Flush(append bool) *Builder { 135 b.clearLocalBuf() 136 flush(b.elem, js.Bool(append)) 137 return b 138 } 139 140 func (b *Builder) clearLocalBuf() { 141 if buf := b.buf; len(buf) > 0 { 142 buf_str(b.elem, js.SliceData(buf), js.SizeU(len(buf))) 143 b.buf = buf[:0] 144 } 145 } 146 147 func (b *Builder) write(s string) { 148 buf := b.buf 149 for len(s) > 0 { 150 if write := min(cap(buf)-len(buf), len(s)); write > 0 { 151 buf = append(buf, s[:write]...) 152 s = s[write:] 153 } 154 155 if len(s) > 0 { 156 buf_str(b.elem, js.SliceData(buf), js.SizeU(len(buf))) 157 buf = buf[:0] 158 } 159 } 160 161 b.buf = buf 162 }