chore: update module definition with new domain
This commit is contained in:
2
go.mod
2
go.mod
@@ -1,3 +1,3 @@
|
|||||||
module forge.capytal.company/loreddev/x
|
module code.capytal.cc/loreddev/x
|
||||||
|
|
||||||
go 1.23.3
|
go 1.23.3
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
// under the licenses is distributed on as "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
|
// under the licenses is distributed on as "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
|
||||||
// OF ANY KIND, either express or implied.
|
// OF ANY KIND, either express or implied.
|
||||||
//
|
//
|
||||||
// An original copy of this file can be found at http://forge.capytal.company/loreddev/x/tinyssert/tinyssert.go.
|
// An original copy of this file can be found at http://code.capytal.cc/loreddev/x/tinyssert/tinyssert.go.
|
||||||
|
|
||||||
// Package tinyssert is a minimal set of assertions functions for testing and simulation
|
// Package tinyssert is a minimal set of assertions functions for testing and simulation
|
||||||
// testing, all in one file.
|
// testing, all in one file.
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
//
|
//
|
||||||
// import (
|
// import (
|
||||||
// "log"
|
// "log"
|
||||||
// "forge.capytal.company/loreddev/x/tinyssert"
|
// "code.capytal.cc/loreddev/x/tinyssert"
|
||||||
// )
|
// )
|
||||||
//
|
//
|
||||||
// func main() {
|
// func main() {
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
//
|
//
|
||||||
// import (
|
// import (
|
||||||
// "log/slog"
|
// "log/slog"
|
||||||
// "forge.capytal.company/loreddev/x/tinyssert"
|
// "code.capytal.cc/loreddev/x/tinyssert"
|
||||||
// )
|
// )
|
||||||
//
|
//
|
||||||
// var logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{}))
|
// var logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{}))
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
// "flag"
|
// "flag"
|
||||||
// "log/slog"
|
// "log/slog"
|
||||||
//
|
//
|
||||||
// "forge.capytal.company/loreddev/x/tinyssert"
|
// "code.capytal.cc/loreddev/x/tinyssert"
|
||||||
// )
|
// )
|
||||||
//
|
//
|
||||||
// var debug = flag.Bool("debug", false, "Run the application in debug mode")
|
// var debug = flag.Bool("debug", false, "Run the application in debug mode")
|
||||||
|
|||||||
47
xhtml/ast/attributes/global.go
Normal file
47
xhtml/ast/attributes/global.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package attributes
|
||||||
|
|
||||||
|
import "slices"
|
||||||
|
|
||||||
|
type Global struct {
|
||||||
|
// TODO: Global attributes at
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes
|
||||||
|
// https://html.spec.whatwg.org/multipage/dom.html#global-attributes
|
||||||
|
|
||||||
|
class []string
|
||||||
|
lang string
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g Global) Class() []string {
|
||||||
|
return g.class
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Global) SetClass(class []string) {
|
||||||
|
g.class = class
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Global) AddClass(class string) {
|
||||||
|
g.class = append(g.class, class)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Global) DelClass(class string) {
|
||||||
|
g.class = slices.DeleteFunc(g.class, func(c string) bool {
|
||||||
|
return c == class
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Global) Lang() string {
|
||||||
|
return g.lang
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Global) SetLang(lang string) {
|
||||||
|
g.lang = lang
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g Global) ID() string {
|
||||||
|
return g.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Global) SetID(id string) {
|
||||||
|
g.id = id
|
||||||
|
}
|
||||||
34
xhtml/ast/attributes/shared.go
Normal file
34
xhtml/ast/attributes/shared.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package attributes
|
||||||
|
|
||||||
|
import "net/url"
|
||||||
|
|
||||||
|
type HRef struct {
|
||||||
|
href *url.URL
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a HRef) HRef() *url.URL {
|
||||||
|
return a.href
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *HRef) SetHref(uri *url.URL) {
|
||||||
|
a.href = uri
|
||||||
|
}
|
||||||
|
|
||||||
|
type Target struct {
|
||||||
|
target string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a Target) Target() string {
|
||||||
|
return a.target
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Target) SetTarget(t string) {
|
||||||
|
a.target = t
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
TargetSelf = "_self"
|
||||||
|
TargetBlank = "_blank"
|
||||||
|
TargetParent = "_parent"
|
||||||
|
TargetTop = "_top"
|
||||||
|
)
|
||||||
56
xhtml/ast/html.go
Normal file
56
xhtml/ast/html.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package ast
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
|
||||||
|
"code.capytal.cc/loreddev/x/xhtml/ast/attributes"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HTML struct {
|
||||||
|
version string
|
||||||
|
xmlns string
|
||||||
|
|
||||||
|
attributes.Global
|
||||||
|
BaseNode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n HTML) Kind() NodeKind {
|
||||||
|
return KindHTML
|
||||||
|
}
|
||||||
|
|
||||||
|
var KindHTML = NewNodeKind("html", &HTML{})
|
||||||
|
|
||||||
|
func (n HTML) Version() string {
|
||||||
|
return n.version
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *HTML) SetVersion(v string) {
|
||||||
|
n.version = v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n HTML) XMLNS() string {
|
||||||
|
return n.xmlns
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *HTML) SetXMLNS(ns string) {
|
||||||
|
n.xmlns = ns
|
||||||
|
}
|
||||||
|
|
||||||
|
type Custom struct {
|
||||||
|
tagName xml.Name
|
||||||
|
attributes []xml.Attr
|
||||||
|
|
||||||
|
attributes.Global
|
||||||
|
BaseNode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n Custom) Kind() NodeKind {
|
||||||
|
return KindUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
var KindUnknown = NewNodeKind("custom", &Custom{})
|
||||||
|
|
||||||
|
type Template struct {
|
||||||
|
attributes.Global
|
||||||
|
BaseNode
|
||||||
|
}
|
||||||
51
xhtml/ast/metadata.go
Normal file
51
xhtml/ast/metadata.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package ast
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"slices"
|
||||||
|
|
||||||
|
"code.capytal.cc/loreddev/x/xhtml/ast/attributes"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Base struct {
|
||||||
|
BaseNode
|
||||||
|
attributes.HRef
|
||||||
|
attributes.Target
|
||||||
|
attributes.Global
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n Base) Kind() NodeKind {
|
||||||
|
return KindBase
|
||||||
|
}
|
||||||
|
|
||||||
|
var KindBase = NewNodeKind("base", &Base{})
|
||||||
|
|
||||||
|
type Head struct {
|
||||||
|
BaseNode
|
||||||
|
profile []*url.URL
|
||||||
|
attributes.Global
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n Head) Kind() NodeKind {
|
||||||
|
return KindHead
|
||||||
|
}
|
||||||
|
|
||||||
|
var KindHead = NewNodeKind("head", &Head{})
|
||||||
|
|
||||||
|
func (n Head) Profile() []*url.URL {
|
||||||
|
return n.profile
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Head) SetProfile(uri []*url.URL) {
|
||||||
|
n.profile = uri
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Head) AddProfile(uri *url.URL) {
|
||||||
|
n.profile = append(n.profile, uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Head) DelProfile(uri *url.URL) {
|
||||||
|
n.profile = slices.DeleteFunc(n.profile, func(u *url.URL) bool {
|
||||||
|
return u.String() == uri.String()
|
||||||
|
})
|
||||||
|
}
|
||||||
199
xhtml/ast/node.go
Normal file
199
xhtml/ast/node.go
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
package ast
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type Node interface {
|
||||||
|
Kind() NodeKind
|
||||||
|
|
||||||
|
NextSibling() Node
|
||||||
|
SetNextSibling(Node)
|
||||||
|
|
||||||
|
PreviousSibling() Node
|
||||||
|
SetPreviousSibling(Node)
|
||||||
|
|
||||||
|
Parent() Node
|
||||||
|
SetParent(Node)
|
||||||
|
|
||||||
|
HasChildren() bool
|
||||||
|
ChildCount() uint
|
||||||
|
|
||||||
|
FirstChild() Node
|
||||||
|
LastChild() Node
|
||||||
|
|
||||||
|
AppendChild(self, v Node)
|
||||||
|
RemoveChild(self, v Node)
|
||||||
|
|
||||||
|
RemoveChildren(self Node)
|
||||||
|
ReplaceChild(self, v1, insertee Node)
|
||||||
|
|
||||||
|
InsertBefore(self, v1, insertee Node)
|
||||||
|
InsertAfter(self, v1, insertee Node)
|
||||||
|
}
|
||||||
|
|
||||||
|
type BaseNode struct {
|
||||||
|
next Node
|
||||||
|
prev Node
|
||||||
|
parent Node
|
||||||
|
fisrtChild Node
|
||||||
|
lastChild Node
|
||||||
|
childCount uint
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) NextSibling() Node {
|
||||||
|
return e.next
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) SetNextSibling(v Node) {
|
||||||
|
e.next = v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) PreviousSibling() Node {
|
||||||
|
return e.prev
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) SetPreviousSibling(v Node) {
|
||||||
|
e.prev = v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) Parent() Node {
|
||||||
|
return e.parent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) SetParent(v Node) {
|
||||||
|
e.parent = v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) HasChildren() bool {
|
||||||
|
return e.fisrtChild != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) ChildCount() uint {
|
||||||
|
return e.childCount
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) FirstChild() Node {
|
||||||
|
return e.fisrtChild
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) LastChild() Node {
|
||||||
|
return e.lastChild
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) AppendChild(self, v Node) {
|
||||||
|
ensureIsolated(v)
|
||||||
|
|
||||||
|
if e.fisrtChild == nil {
|
||||||
|
e.fisrtChild = v
|
||||||
|
v.SetNextSibling(nil)
|
||||||
|
v.SetPreviousSibling(nil)
|
||||||
|
} else {
|
||||||
|
l := e.lastChild
|
||||||
|
l.SetNextSibling(v)
|
||||||
|
v.SetPreviousSibling(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
v.SetParent(self)
|
||||||
|
e.lastChild = v
|
||||||
|
e.childCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) RemoveChild(self, v Node) {
|
||||||
|
if v.Parent() != self {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.childCount <= 0 {
|
||||||
|
e.childCount--
|
||||||
|
}
|
||||||
|
|
||||||
|
prev := v.PreviousSibling()
|
||||||
|
next := v.NextSibling()
|
||||||
|
|
||||||
|
if prev != nil {
|
||||||
|
prev.SetNextSibling(next)
|
||||||
|
} else {
|
||||||
|
e.fisrtChild = next
|
||||||
|
}
|
||||||
|
|
||||||
|
if next != nil {
|
||||||
|
next.SetNextSibling(prev)
|
||||||
|
} else {
|
||||||
|
e.lastChild = prev
|
||||||
|
}
|
||||||
|
|
||||||
|
v.SetParent(nil)
|
||||||
|
v.SetNextSibling(nil)
|
||||||
|
v.SetPreviousSibling(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) RemoveChildren(_ Node) {
|
||||||
|
for c := e.fisrtChild; c != nil; {
|
||||||
|
c.SetParent(nil)
|
||||||
|
c.SetPreviousSibling(nil)
|
||||||
|
next := c.NextSibling()
|
||||||
|
c.SetNextSibling(nil)
|
||||||
|
c = next
|
||||||
|
}
|
||||||
|
e.fisrtChild = nil
|
||||||
|
e.lastChild = nil
|
||||||
|
e.childCount = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) ReplaceChild(self, v1, insertee Node) {
|
||||||
|
e.InsertBefore(self, v1, insertee)
|
||||||
|
e.RemoveChild(self, v1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) InsertAfter(self, v1, insertee Node) {
|
||||||
|
e.InsertBefore(self, v1.NextSibling(), insertee)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BaseNode) InsertBefore(self, v1, insertee Node) {
|
||||||
|
e.childCount++
|
||||||
|
if v1 == nil {
|
||||||
|
e.AppendChild(self, insertee)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureIsolated(insertee)
|
||||||
|
|
||||||
|
if v1.Parent() == self {
|
||||||
|
c := v1
|
||||||
|
prev := c.PreviousSibling()
|
||||||
|
if prev != nil {
|
||||||
|
prev.SetNextSibling(insertee)
|
||||||
|
insertee.SetPreviousSibling(prev)
|
||||||
|
} else {
|
||||||
|
e.fisrtChild = insertee
|
||||||
|
insertee.SetPreviousSibling(nil)
|
||||||
|
}
|
||||||
|
insertee.SetNextSibling(c)
|
||||||
|
c.SetPreviousSibling(insertee)
|
||||||
|
insertee.SetParent(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ensureIsolated(e Node) {
|
||||||
|
if p := e.Parent(); p != nil {
|
||||||
|
p.RemoveChild(p, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodeKind string
|
||||||
|
|
||||||
|
var _ fmt.Stringer = NodeKind("")
|
||||||
|
|
||||||
|
func NewNodeKind(kind string, e Node) NodeKind {
|
||||||
|
k := NodeKind(kind)
|
||||||
|
if _, ok := elementKindList[k]; ok {
|
||||||
|
panic(fmt.Sprintf("Node kind %q is already registered", k))
|
||||||
|
}
|
||||||
|
elementKindList[k] = e
|
||||||
|
return k
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k NodeKind) String() string {
|
||||||
|
return string(k)
|
||||||
|
}
|
||||||
|
|
||||||
|
var elementKindList = make(map[NodeKind]Node)
|
||||||
1
xhtml/xhtml.go
Normal file
1
xhtml/xhtml.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package xhtml
|
||||||
24
xhtml/xhtml_test.go
Normal file
24
xhtml/xhtml_test.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package xhtml_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"log"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMain(t *testing.T) {
|
||||||
|
type Bold struct {
|
||||||
|
XMLName xml.Name `xml:"b"`
|
||||||
|
Content string `xml:",chardata"`
|
||||||
|
}
|
||||||
|
type test struct {
|
||||||
|
XMLName xml.Name `xml:"p"`
|
||||||
|
Content string `xml:",chardata"`
|
||||||
|
Bold []Bold `xml:"b"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var v test
|
||||||
|
xml.Unmarshal([]byte(`<p>Hello, <b>world</b></p>`), &v)
|
||||||
|
|
||||||
|
log.Printf("%#v", v)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user