From 40fc5e9604ef478b757373e30f2277467e946813 Mon Sep 17 00:00:00 2001 From: Harvey Tindall Date: Mon, 22 Feb 2021 16:40:37 +0000 Subject: [PATCH] Fix email editor when plaintext setting enabled --- Makefile | 2 +- api.go | 2 +- config.go | 1 - css/base.css | 8 +++++++ email.go | 1 - go.mod | 3 ++- go.sum | 5 +++++ models.go | 1 + package-lock.json | 5 +++++ package.json | 1 + ts/modules/settings.ts | 25 +++++++++++++-------- ts/modules/stripmd.ts | 49 ++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 89 insertions(+), 14 deletions(-) create mode 100644 ts/modules/stripmd.ts diff --git a/Makefile b/Makefile index 9b59660..a27f7f7 100644 --- a/Makefile +++ b/Makefile @@ -63,7 +63,7 @@ compile-debug: $(GOBINARY) mod download $(info Building) mkdir -p build - cd build && CGO_ENABLED=0 $(GOBINARY) build -o ./jfa-go ../*.go -ldflags "-X main.version=$(VERSION) -X main.commit=$(COMMIT)" + cd build && CGO_ENABLED=0 $(GOBINARY) build -ldflags "-X main.version=$(VERSION) -X main.commit=$(COMMIT)" -o ./jfa-go ../*.go compress: upx --lzma build/jfa-go diff --git a/api.go b/api.go index 859137c..62a8b52 100644 --- a/api.go +++ b/api.go @@ -1514,7 +1514,7 @@ func (app *appContext) GetEmail(gc *gin.Context) { respondBool(500, false, gc) return } - gc.JSON(200, customEmailDTO{Content: content, Variables: variables, Values: values, HTML: email.HTML}) + gc.JSON(200, customEmailDTO{Content: content, Variables: variables, Values: values, HTML: email.HTML, Plaintext: email.Text}) } // @Summary Logout by deleting refresh token from cookies. diff --git a/config.go b/config.go index 5f9e725..6c96c3e 100644 --- a/config.go +++ b/config.go @@ -33,7 +33,6 @@ func (app *appContext) loadConfig() error { for _, key := range app.config.Section("files").Keys() { if name := key.Name(); name != "html_templates" && name != "lang_files" { - fmt.Println(name) key.SetValue(key.MustString(filepath.Join(app.dataPath, (key.Name() + ".json")))) } } diff --git a/css/base.css b/css/base.css index e11c8af..7a347da 100644 --- a/css/base.css +++ b/css/base.css @@ -409,3 +409,11 @@ p.top { padding-bottom: 0.5rem; margin-bottom: -0.5rem; } + +pre { + white-space: pre-wrap; /* css-3 */ + white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ +} diff --git a/email.go b/email.go index 2e77af6..bc74060 100644 --- a/email.go +++ b/email.go @@ -571,6 +571,5 @@ func (emailer *Emailer) constructWelcome(username string, app *appContext, noSub // calls the send method in the underlying emailClient. func (emailer *Emailer) send(email *Email, address ...string) error { - fmt.Printf("%+v\n", email) return emailer.sender.send(emailer.fromName, emailer.fromAddr, email, address...) } diff --git a/go.mod b/go.mod index 5f24224..048cd1d 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ replace github.com/hrfee/jfa-go/ombi => ./ombi require ( github.com/dgrijalva/jwt-go v3.2.0+incompatible + github.com/evanw/esbuild v0.8.50 // indirect github.com/fatih/color v1.10.0 github.com/fsnotify/fsnotify v1.4.9 github.com/gin-contrib/pprof v1.3.0 @@ -40,7 +41,7 @@ require ( github.com/ugorji/go v1.2.0 // indirect github.com/writeas/go-strip-markdown v2.0.1+incompatible golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 // indirect - golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c // indirect + golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43 // indirect golang.org/x/tools v0.1.0 // indirect google.golang.org/protobuf v1.25.0 // indirect gopkg.in/ini.v1 v1.62.0 diff --git a/go.sum b/go.sum index 49e3bda..91e5f2f 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,8 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanw/esbuild v0.8.50 h1:97YxSC9Ni9zu82601vI93cSUS0C+WUcPPNIARuGcQtI= +github.com/evanw/esbuild v0.8.50/go.mod h1:y2AFBAGVelPqPodpdtxWWqe6n2jYf5FrsJbligmRmuw= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= @@ -283,11 +285,14 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43 h1:SgQ6LNaYJU0JIuEHv9+s6EbhSCwYeAf5Yvj6lpYlqAE= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/models.go b/models.go index 40acc4a..cd99ede 100644 --- a/models.go +++ b/models.go @@ -195,4 +195,5 @@ type customEmailDTO struct { Variables []string `json:"variables"` Values map[string]interface{} `json:"values"` HTML string `json:"html"` + Plaintext string `json:"plaintext"` } diff --git a/package-lock.json b/package-lock.json index 2d795b8..e11da1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1438,6 +1438,11 @@ "resolved": "https://registry.npm.taobao.org/remixicon/download/remixicon-2.5.0.tgz", "integrity": "sha1-teJFiUoVUKojeT+V2s6tv5atGkE=" }, + "remove-markdown": { + "version": "0.3.0", + "resolved": "https://registry.npm.taobao.org/remove-markdown/download/remove-markdown-0.3.0.tgz", + "integrity": "sha1-XktmdJOpNXlyjz1S7MHbnKUF3Jg=" + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", diff --git a/package.json b/package.json index 4c05eb7..5d7b768 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "lodash": "^4.17.19", "mjml": "^4.8.0", "remixicon": "^2.5.0", + "remove-markdown": "^0.3.0", "typescript": "^4.0.3" }, "devDependencies": {} diff --git a/ts/modules/settings.ts b/ts/modules/settings.ts index 81840ac..102813d 100644 --- a/ts/modules/settings.ts +++ b/ts/modules/settings.ts @@ -1,5 +1,6 @@ import { _get, _post, toggleLoader } from "../modules/common.js"; import { Marked } from "@ts-stack/markdown"; +import { stripMarkdown } from "../modules/stripmd.js"; interface settingsBoolEvent extends Event { detail: boolean; @@ -672,17 +673,12 @@ class ombiDefaults { } } -interface Email { - subject: string; - html: string; - text: string; -} - interface templateEmail { content: string; variables: string[]; values: { [key: string]: string }; html: string; + plaintext: string; } interface emailListEl { @@ -700,6 +696,7 @@ class EmailEditor { private _variables = document.getElementById("editor-variables") as HTMLDivElement; private _textArea = document.getElementById("textarea-editor") as HTMLTextAreaElement; private _preview = document.getElementById("editor-preview") as HTMLDivElement; + private _previewContent: HTMLElement; // private _timeout: number; // private _finishInterval = 200; @@ -734,7 +731,12 @@ class EmailEditor { } this._templ = req.response as templateEmail; this._textArea.value = this._templ.content; - this._preview.innerHTML = this._templ.html; + if (this._templ.html == "") { + this._preview.innerHTML = `
`;
+                } else {
+                    this._preview.innerHTML = this._templ.html;
+                }
+                this._previewContent = document.getElementById("preview-content");
                 this.loadPreview();
                 this._content = this._templ.content;
                 const colors = ["info", "urge", "positive", "neutral"];
@@ -764,8 +766,13 @@ class EmailEditor {
             if (value === undefined) { value = variable; }
             content = content.replace(new RegExp(variable, "g"), value);
         }
-        content = Marked.parse(content)
-        document.getElementById("preview-content").innerHTML = content;
+        if (this._templ.html == "") {
+            content = stripMarkdown(content);
+            this._previewContent.textContent = content;
+        } else {
+            content = Marked.parse(content);
+            this._previewContent.innerHTML = content;
+        }
         // _post("/config/emails/" + this._currentID + "/test", { "content": this._textArea.value }, (req: XMLHttpRequest) => {
         //     if (req.readyState == 4) {
         //         if (req.status != 200) {
diff --git a/ts/modules/stripmd.ts b/ts/modules/stripmd.ts
new file mode 100644
index 0000000..cc184cf
--- /dev/null
+++ b/ts/modules/stripmd.ts
@@ -0,0 +1,49 @@
+const removeMd = require("remove-markdown");
+
+export function stripMarkdown(md: string): string {
+    let foundOpenSquare = false;
+    let openSquare = -1;
+	let openBracket = -1;
+	let closeBracket = -1;
+	let openSquares: number[] = [];
+	let closeBrackets: number[] = [];
+	let links: string[] = [];
+	let foundOpen = false;
+    for (let i = 0; i < md.length; i++) {
+        const c = md.charAt(i);
+		if (!foundOpenSquare && !foundOpen && c != '[' && c != ']') {
+			continue;
+		}
+		if (c == '[' && md.charAt(i-1) != '!') {
+			foundOpenSquare = true;
+			openSquare = i;
+		} else if (c == ']') {
+			if (md.charAt(i+1) == '(') {
+				foundOpenSquare = false;
+				foundOpen = true;
+				openBracket = i + 1;
+				continue;
+			}
+		} else if (c == ')') {
+			closeBracket = i;
+			openSquares.push(openSquare);
+			closeBrackets.push(closeBracket);
+			links.push(md.slice(openBracket+1, closeBracket))
+			openBracket = -1;
+			closeBracket = -1;
+			openSquare = -1;
+			foundOpenSquare = false;
+			foundOpen = false;
+		}
+	}
+	let fullLinks: string[] = new Array(openSquares.length);
+	for (let i = 0; i < openSquares.length; i++) {
+		if (openSquares[i] != -1 && closeBrackets[i] != -1) {
+			fullLinks[i] = md.slice(openSquares[i], closeBrackets[i]+1)
+		}
+	}
+	for (let i = 0; i < openSquares.length; i++) {
+        md = md.replace(fullLinks[i], links[i]);
+	}
+    return removeMd(md);
+}