aboutsummaryrefslogtreecommitdiff
path: root/ui/messages/html/parser.go
diff options
context:
space:
mode:
authorTulir Asokan <tulir@maunium.net>2019-04-10 22:49:33 +0300
committerTulir Asokan <tulir@maunium.net>2019-04-10 22:49:33 +0300
commita9199dd9f2fa4b79a3c8b16d2cd46446651fdb81 (patch)
tree1483d3b282f81b9367fefddd5f03053c4c9d171a /ui/messages/html/parser.go
parentdb0e24ccc268d0a9c7575d660a9397e53747894b (diff)
Split container/text HTML entities and add support for <hr>
Diffstat (limited to 'ui/messages/html/parser.go')
-rw-r--r--ui/messages/html/parser.go97
1 files changed, 57 insertions, 40 deletions
diff --git a/ui/messages/html/parser.go b/ui/messages/html/parser.go
index 9e08ab7..51f5cb0 100644
--- a/ui/messages/html/parser.go
+++ b/ui/messages/html/parser.go
@@ -102,8 +102,10 @@ func (parser *htmlParser) listToEntity(node *html.Node) Entity {
}
func (parser *htmlParser) basicFormatToEntity(node *html.Node) Entity {
- entity := &BaseEntity{
- Tag: node.Data,
+ entity := &ContainerEntity{
+ BaseEntity: &BaseEntity{
+ Tag: node.Data,
+ },
Children: parser.nodeToEntities(node.FirstChild),
}
switch node.Data {
@@ -151,12 +153,14 @@ func (parser *htmlParser) parseColor(node *html.Node, mainName, altName string)
}
func (parser *htmlParser) headerToEntity(node *html.Node) Entity {
- length := int(node.Data[1] - '0')
- prefix := strings.Repeat("#", length) + " "
- return (&BaseEntity{
- Tag: node.Data,
- Text: prefix,
- Children: parser.nodeToEntities(node.FirstChild),
+ return (&ContainerEntity{
+ BaseEntity: &BaseEntity{
+ Tag: node.Data,
+ },
+ Children: append(
+ []Entity{NewTextEntity(strings.Repeat("#", int(node.Data[1]-'0')) + " ")},
+ parser.nodeToEntities(node.FirstChild)...
+ ),
}).AdjustStyle(AdjustStyleBold)
}
@@ -164,29 +168,36 @@ func (parser *htmlParser) blockquoteToEntity(node *html.Node) Entity {
return NewBlockquoteEntity(parser.nodeToEntities(node.FirstChild))
}
-func (parser *htmlParser) linkToEntity(node *html.Node) Entity {
- entity := &BaseEntity{
- Tag: "a",
+func (parser *htmlParser) linkToEntity(node *html.Node) (entity Entity) {
+ entity = &ContainerEntity{
+ BaseEntity: &BaseEntity{
+ Tag: "a",
+ },
Children: parser.nodeToEntities(node.FirstChild),
}
href := parser.getAttribute(node, "href")
if len(href) == 0 {
- return entity
+ return
}
match := matrixToURL.FindStringSubmatch(href)
if len(match) == 2 {
- entity.Children = nil
pillTarget := match[1]
- entity.Text = pillTarget
+ textEntity := &TextEntity{
+ BaseEntity: &BaseEntity{
+ Tag: "a",
+ },
+ Text: pillTarget,
+ }
if pillTarget[0] == '@' {
if member := parser.room.GetMember(pillTarget); member != nil {
- entity.Text = member.Displayname
- entity.Style = entity.Style.Foreground(widget.GetHashColor(pillTarget))
+ textEntity.Text = member.Displayname
+ textEntity.Style = textEntity.Style.Foreground(widget.GetHashColor(pillTarget))
}
}
+ entity = textEntity
}
// TODO add click action and underline on hover for links
- return entity
+ return
}
func (parser *htmlParser) imageToEntity(node *html.Node) Entity {
@@ -197,8 +208,10 @@ func (parser *htmlParser) imageToEntity(node *html.Node) Entity {
alt = "[inline image]"
}
}
- entity := &BaseEntity{
- Tag: "img",
+ entity := &TextEntity{
+ BaseEntity: &BaseEntity{
+ Tag: "img",
+ },
Text: alt,
}
// TODO add click action and underline on hover for inline images
@@ -239,12 +252,13 @@ func (parser *htmlParser) syntaxHighlight(text, language string) Entity {
if token.Value == "\n" {
children[i] = NewBreakEntity()
} else {
- children[i] = &BaseEntity{
- Tag: token.Type.String(),
- Text: token.Value,
- Style: styleEntryToStyle(style.Get(token.Type)),
-
- DefaultHeight: 1,
+ children[i] = &TextEntity{
+ BaseEntity: &BaseEntity{
+ Tag: token.Type.String(),
+ Style: styleEntryToStyle(style.Get(token.Type)),
+ DefaultHeight: 1,
+ },
+ Text: token.Value,
}
}
}
@@ -265,7 +279,7 @@ func (parser *htmlParser) codeblockToEntity(node *html.Node) Entity {
}
}
parser.keepLinebreak = true
- text := (&BaseEntity{
+ text := (&ContainerEntity{
Children: parser.nodeToEntities(node.FirstChild),
}).PlainText()
parser.keepLinebreak = false
@@ -295,10 +309,12 @@ func (parser *htmlParser) tagNodeToEntity(node *html.Node) Entity {
case "mx-reply":
return nil
default:
- return &BaseEntity{
- Tag: node.Data,
+ return &ContainerEntity{
+ BaseEntity: &BaseEntity{
+ Tag: node.Data,
+ Block: parser.isBlockTag(node.Data),
+ },
Children: parser.nodeToEntities(node.FirstChild),
- Block: parser.isBlockTag(node.Data),
}
}
}
@@ -312,20 +328,19 @@ func (parser *htmlParser) singleNodeToEntity(node *html.Node) Entity {
if len(node.Data) == 0 {
return nil
}
- return &BaseEntity{
- Tag: "text",
- Text: node.Data,
- }
+ return NewTextEntity(node.Data)
case html.ElementNode:
return parser.tagNodeToEntity(node)
case html.DocumentNode:
if node.FirstChild.Data == "html" && node.FirstChild.NextSibling == nil {
return parser.singleNodeToEntity(node.FirstChild)
}
- return &BaseEntity{
- Tag: "html",
+ return &ContainerEntity{
+ BaseEntity: &BaseEntity{
+ Tag: "html",
+ Block: true,
+ },
Children: parser.nodeToEntities(node.FirstChild),
- Block: true,
}
default:
return nil
@@ -376,10 +391,10 @@ func Parse(room *rooms.Room, evt *mautrix.Event, senderDisplayname string) Entit
parser := htmlParser{room: room}
root := parser.Parse(htmlData)
- beRoot := root.(*BaseEntity)
+ beRoot := root.(*ContainerEntity)
beRoot.Block = false
if len(beRoot.Children) > 0 {
- beChild, ok := beRoot.Children[0].(*BaseEntity)
+ beChild, ok := beRoot.Children[0].(*ContainerEntity)
if ok && beChild.Tag == "p" {
// Hacky fix for m.emote
beChild.Block = false
@@ -387,8 +402,10 @@ func Parse(room *rooms.Room, evt *mautrix.Event, senderDisplayname string) Entit
}
if evt.Content.MsgType == mautrix.MsgEmote {
- root = &BaseEntity{
- Tag: "emote",
+ root = &ContainerEntity{
+ BaseEntity: &BaseEntity{
+ Tag: "emote",
+ },
Children: []Entity{
NewTextEntity("* "),
NewTextEntity(senderDisplayname).AdjustStyle(AdjustStyleTextColor(widget.GetHashColor(evt.Sender))),