From b95159df1903331512501e731cbcf6dfd3f4358c Mon Sep 17 00:00:00 2001
From: Volker Schukai <volker.schukai@schukai.com>
Date: Fri, 10 Feb 2023 20:05:00 +0100
Subject: [PATCH] feat: add, remove and attributes modification

---
 application/source/html/generate.go           | 74 +++++++++++++++++++
 application/source/types/page-data.go         | 34 +++++++--
 .../examples/example1/html/de/test1.html      | 14 ++--
 .../examples/example1/html/en/test2.html      |  2 +-
 .../examples/example1/html/en/test3.html      |  2 +-
 .../examples/example1/html/en/test4.html      | 12 +++
 .../examples/example1/template/data.yaml      | 22 ++++++
 7 files changed, 145 insertions(+), 15 deletions(-)
 create mode 100644 development/examples/example1/html/en/test4.html

diff --git a/application/source/html/generate.go b/application/source/html/generate.go
index 32a0dd7..ec0da82 100644
--- a/application/source/html/generate.go
+++ b/application/source/html/generate.go
@@ -2,8 +2,10 @@ package html
 
 import (
 	"encoding/json"
+	"github.com/andybalholm/cascadia"
 	"gitlab.schukai.com/oss/bob/types"
 	"gitlab.schukai.com/oss/libraries/go/markup/html/engine"
+	"golang.org/x/net/html"
 	"gopkg.in/yaml.v3"
 	"os"
 	"path"
@@ -104,5 +106,77 @@ func Generate(data *types.PageData, name string) (string, error) {
 	stringWriter := &strings.Builder{}
 	e.ProcessHtml(stringWriter, strings.NewReader(string(template)))
 
+	return doModifications(data, stringWriter.String())
+
+}
+
+func doModifications(page *types.PageData, from string) (string, error) {
+
+	node, err := html.Parse(strings.NewReader(from))
+	if err != nil {
+		return "", err
+	}
+
+	for _, m := range page.Modifications.Remove {
+
+		selector, err := cascadia.Parse(m)
+		if err != nil {
+			return "", err
+		}
+		list := cascadia.QueryAll(node, selector)
+		for _, n := range list {
+			if n.Parent != nil {
+				n.Parent.RemoveChild(n)
+			}
+		}
+
+	}
+
+	for _, m := range page.Modifications.Add {
+		selector, err := cascadia.Parse(m.Selector)
+		if err != nil {
+			return "", err
+		}
+		list := cascadia.QueryAll(node, selector)
+		for _, n := range list {
+			if n.Parent != nil {
+
+				nodes, err := html.ParseFragment(strings.NewReader(m.Html), n)
+				if err != nil {
+					return "", err
+				}
+
+				for _, added := range nodes {
+					n.InsertBefore(added, n.FirstChild)
+				}
+			}
+		}
+	}
+
+	for _, m := range page.Modifications.SetAttribute {
+		selector, err := cascadia.Parse(m.Selector)
+		if err != nil {
+			return "", err
+		}
+		list := cascadia.QueryAll(node, selector)
+		for _, n := range list {
+			if n.Parent != nil {
+				attr := n.Attr
+				attr = append(attr, html.Attribute{
+					Key: m.Name,
+					Val: m.Value,
+				})
+
+				n.Attr = attr
+			}
+		}
+	}
+
+	stringWriter := &strings.Builder{}
+	err = html.Render(stringWriter, node)
+	if err != nil {
+		return "", err
+	}
 	return stringWriter.String(), nil
+
 }
diff --git a/application/source/types/page-data.go b/application/source/types/page-data.go
index 6994066..c5c7166 100644
--- a/application/source/types/page-data.go
+++ b/application/source/types/page-data.go
@@ -25,15 +25,33 @@ type Translations struct {
 	KeyValues map[string]any `yaml:"translations"`
 }
 
+type AddModification struct {
+	Selector string `yaml:"selector"`
+	Html     string `yaml:"html"`
+}
+
+type SetAttributeModification struct {
+	Selector string `yaml:"selector"`
+	Name     string `yaml:"name"`
+	Value    string `yaml:"value"`
+}
+
+type Modifications struct {
+	Remove       []string                   `yaml:"remove"`
+	Add          []AddModification          `yaml:"add"`
+	SetAttribute []SetAttributeModification `yaml:"attributes"`
+}
+
 type PageData struct {
-	Export       string            `yaml:"export"`
-	Lang         string            `yaml:"lang"`
-	Title        string            `yaml:"title"`
-	Meta         map[string]string `yaml:"meta"`
-	Images       []Image           `yaml:"images"`
-	Anchors      []Anchor          `yaml:"anchors"`
-	Text         []Text            `yaml:"text"`
-	Translations []Translations    `yaml:"translations"`
+	Export        string            `yaml:"export"`
+	Lang          string            `yaml:"lang"`
+	Title         string            `yaml:"title"`
+	Meta          map[string]string `yaml:"meta"`
+	Images        []Image           `yaml:"images"`
+	Anchors       []Anchor          `yaml:"anchors"`
+	Text          []Text            `yaml:"text"`
+	Translations  []Translations    `yaml:"translations"`
+	Modifications Modifications     `yaml:"modifications"`
 }
 
 func NewPageData() *PageData {
diff --git a/development/examples/example1/html/de/test1.html b/development/examples/example1/html/de/test1.html
index bc15af1..5f16bd5 100644
--- a/development/examples/example1/html/de/test1.html
+++ b/development/examples/example1/html/de/test1.html
@@ -28,15 +28,19 @@
     <link rel="icon" href="/favicon.svg" type="image/svg+xml"/>
     <link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
 
-    <script id="translations" type="application/json" data-monster-role="translation">{"key1":"value1 gfgf66","key2":"value2 gg","key3":{"one":"value3 tgtgt","two":"value4 trzrtz"}}</script>
+    <script id="translations" type="application/json" data-monster-role="translation">{"key1":"value1","key2":"value2","key3":{"one":"value3","two":"value4"}}</script>
     
     
-    <script id="mainscript" src="/script/main22.mjs" type="module"></script>
+    <script id="mainscript" src="/script/main22.mjs" type="module" data-xyz="YES"></script>
 </head>
 
 <body>
+
+
+<a id="test-link-test-html" href="/test.html" title="test-link" hreflang="">test-link</a>
+
 <header>
-    <div class="gradient"></div>
+    
 </header>
 
 <monster-state>
@@ -45,12 +49,12 @@
   PbGkNUOFk6DZqgHCNGg2T4QAQBoIiRSAwBE4VA4FACKgkB5NGReASFZEmxsQ0whPDi9BiACYQAInXhwOUtgCUQoORFCGt/g4QAIQA7" id="tickyesdata-image-gi-4013311193"/>
     <h1 class="deco">Bad xxxx</h1>
     <p>The request was incorrect, the server could not process it.</p><p>
-</p><div class="infobox">
+</p><div class="infobox"><b><span>GURKE</span></b>
     <div>
 
         <ul>
 
-            <li>Try submitting your<a id="yes-a-html" href="/a.html" title="Yes" hreflang="">request</a> again (sometimes this helps).</li>
+            <li>Try submitting your<a id="yes-a-html" href="/a.html" title="Yes" hreflang="">request</a>again (sometimes this helps).</li>
             <li>Contact support if you continue to have problems.</li>
 
             <li>If you received this message as a result of a request to the server API, then check the structure
diff --git a/development/examples/example1/html/en/test2.html b/development/examples/example1/html/en/test2.html
index ecd0791..c2246c0 100644
--- a/development/examples/example1/html/en/test2.html
+++ b/development/examples/example1/html/en/test2.html
@@ -47,7 +47,7 @@
 
         <ul>
 
-            <li>Try submitting your<a id="yes-a-html" href="/a.html" title="Yes" hreflang="">request</a> again (sometimes this helps).</li>
+            <li>Try submitting your<a id="yes-a-html" href="/a.html" title="Yes" hreflang="">request</a>again (sometimes this helps).</li>
             <li>Contact support if you continue to have problems.</li>
 
             <li>If you received this message as a result of a request to the server API, then check the structure
diff --git a/development/examples/example1/html/en/test3.html b/development/examples/example1/html/en/test3.html
index a628f9e..02b8c61 100644
--- a/development/examples/example1/html/en/test3.html
+++ b/development/examples/example1/html/en/test3.html
@@ -47,7 +47,7 @@
 
         <ul>
 
-            <li>Try submitting your<a id="yes-a-html" href="/a.html" title="Yes" hreflang="">request</a> again (sometimes this helps).</li>
+            <li>Try submitting your<a id="yes-a-html" href="/a.html" title="Yes" hreflang="">request</a>again (sometimes this helps).</li>
             <li>Contact support if you continue to have problems.</li>
 
             <li>If you received this message as a result of a request to the server API, then check the structure
diff --git a/development/examples/example1/html/en/test4.html b/development/examples/example1/html/en/test4.html
new file mode 100644
index 0000000..4ddb0f4
--- /dev/null
+++ b/development/examples/example1/html/en/test4.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html><html lang="en"><head>
+
+</head>
+
+<body>
+
+<main>
+
+<p>Das ist ein Text<a id="a-html" href="a.html" title="" hreflang="">one-time password</a>.</p>
+</main>
+
+</body></html>
\ No newline at end of file
diff --git a/development/examples/example1/template/data.yaml b/development/examples/example1/template/data.yaml
index 2f5a7f0..84b808c 100755
--- a/development/examples/example1/template/data.yaml
+++ b/development/examples/example1/template/data.yaml
@@ -52,6 +52,16 @@ test1.html:
             key3:
                 one: value3
                 two: value4
+    modifications:
+        remove: 
+          - .gradient
+        add: 
+          - selector: .infobox
+            html: <b><span>GURKE</span></b>
+        attributes: 
+          - selector: '#mainscript'
+            name: data-xyz
+            value: YES
 test2.html:
     export: en/test2.html
     lang: en
@@ -92,6 +102,10 @@ test2.html:
         - text: 'You   can   try    the following steps:'
           id: you-can-try-the-foll-3363859033
     translations: []
+    modifications:
+        remove: []
+        add: []
+        attributes: []
 test3.html:
     export: en/test3.html
     lang: en
@@ -132,6 +146,10 @@ test3.html:
         - text: 'You   can   try    the following steps:'
           id: you-can-try-the-foll-3363859033
     translations: []
+    modifications:
+        remove: []
+        add: []
+        attributes: []
 test4.html:
     export: en/test4.html
     lang: en
@@ -151,3 +169,7 @@ test4.html:
         - text: .
           id: id1000
     translations: []
+    modifications:
+        remove: []
+        add: []
+        attributes: []
-- 
GitLab