From 5e1e95852821e138caf20c3f8ee23e3941e42bbc Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 15 Nov 2016 00:16:06 -0500 Subject: better progressive enhancement of editor --- enhancers.txt | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++ got/page.html.got | 1 + got/view_blob.got | 3 -- src/edit/enhancers.go | 79 ++++++++++++++++++++++++++++++++++++++++++++ src/edit/views.go | 38 ++++++++++----------- static/mde.js | 20 ----------- static/style.css | 35 ++++++++++++++++++++ 7 files changed, 225 insertions(+), 42 deletions(-) create mode 100644 enhancers.txt create mode 100644 src/edit/enhancers.go delete mode 100644 static/mde.js diff --git a/enhancers.txt b/enhancers.txt new file mode 100644 index 0000000..22c684b --- /dev/null +++ b/enhancers.txt @@ -0,0 +1,91 @@ +--boundary +X-Thing: Pattern + +text/markdown +--boundary +X-Thing: Head + + + + +--boundary +X-Thing: Tail + + +--boundary +X-Thing: Pattern + +text/*; */*+xml +--boundary +X-Thing: Head + + + + + + + + + + + + + + + + + + + + + +--boundary +X-Thing: Tail + + +--boundary-- diff --git a/got/page.html.got b/got/page.html.got index c061d50..7f2c16c 100644 --- a/got/page.html.got +++ b/got/page.html.got @@ -13,5 +13,6 @@ {{.body}} + {{.tail}} diff --git a/got/view_blob.got b/got/view_blob.got index 95692b0..752d5c7 100644 --- a/got/view_blob.got +++ b/got/view_blob.got @@ -32,6 +32,3 @@ -{{if eq .ctype "text/markdown"}} - -{{end}} diff --git a/src/edit/enhancers.go b/src/edit/enhancers.go new file mode 100644 index 0000000..b732ab2 --- /dev/null +++ b/src/edit/enhancers.go @@ -0,0 +1,79 @@ +package main + +import ( + "io" + "io/ioutil" + "os" + "mime/multipart" + "strings" + "path" + + "fmt" +) + +type enhancer struct { + pattern []string + head string + tail string +} + +func loadEnhancers(filename string) []enhancer { + file, err := os.Open(filename) + errcheck(err) + + reader := multipart.NewReader(file, "boundary") + + var s uint8 = 0 + var e enhancer + var ret []enhancer + for { + part, err := reader.NextPart() + if err == io.EOF { + return ret + } + errcheck(err) + + k := part.Header.Get("X-Thing") + v, err := ioutil.ReadAll(part) + errcheck(err) + + switch k { + case "Pattern": + patterns := strings.Split(string(v), ";") + for i := range patterns { + patterns[i] = strings.TrimSpace(patterns[i]) + } + s |= 1<<0 + e.pattern = patterns + case "Head": + s |= 1<<1 + e.head = string(v) + case "Tail": + s |= 1<<2 + e.tail = string(v) + default: + panic("unknown X-Thing: "+k) + } + if s == 1<<0 | 1<<1 | 1<<2 { + ret = append(ret, e) + s = 0 + } + } +} + +var enhancers = loadEnhancers("enhancers.txt") + +func getEnhancer(ctype string) (head, tail string) { + fmt.Fprintf(os.Stderr, "enhancers = %q\n", enhancers) + for _, enhancer := range enhancers { + for _, pattern := range enhancer.pattern { + matched, err := path.Match(pattern, ctype) + errcheck(err) + fmt.Fprintf(os.Stderr, "Match(%q, %q) => %q\n", pattern, ctype, matched) + if matched { + return enhancer.head, enhancer.tail + } + } + } + return "", "" +} diff --git a/src/edit/views.go b/src/edit/views.go index 1d3176d..a2890d4 100644 --- a/src/edit/views.go +++ b/src/edit/views.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "bytes" "io" "path" @@ -24,11 +25,12 @@ var ( tmplDeleted = newTemplate("got/deleted.got") ) -func renderPage(w io.Writer, title, head, body string) error { +func renderPage(w io.Writer, title, head, body, tail string) error { return tmplPage.Execute(w, map[string]string{ "title": title, "head": head, "body": body, + "tail": tail, }) } @@ -47,8 +49,8 @@ func renderViewTree(w io.Writer, upath string, tree GitTree) error { } // Component Render - var buf bytes.Buffer - err := tmplViewTree.Execute(&buf, map[string]interface{}{ + var body bytes.Buffer + err := tmplViewTree.Execute(&body, map[string]interface{}{ "path": upath, "files": files, }) @@ -56,7 +58,7 @@ func renderViewTree(w io.Writer, upath string, tree GitTree) error { return err } // Page render - return renderPage(w, upath, "", buf.String()) + return renderPage(w, upath, "", body.String(), "") } func renderViewBlob(w io.Writer, upath string, file GitFile) error { @@ -67,8 +69,8 @@ func renderViewBlob(w io.Writer, upath string, file GitFile) error { } ctype := getctype(upath, content) // Component render - var buf bytes.Buffer - err = tmplViewBlob.Execute(&buf, map[string]string{ + var body bytes.Buffer + err = tmplViewBlob.Execute(&body, map[string]string{ "path": upath, "ctype": ctype, "content": string(content), @@ -76,38 +78,36 @@ func renderViewBlob(w io.Writer, upath string, file GitFile) error { if err != nil { return err } - head := "" - if ctype == "text/markdown" { - head += "\n" - head += "\n" - head += "\n" - } + + head, tail := getEnhancer(ctype) + head = fmt.Sprintf("\n%s", template.JSEscapeString(ctype), head); + // Page render - return renderPage(w, upath, head, buf.String()) + return renderPage(w, upath, head, body.String(), tail) } func renderModified(w io.Writer, upath string) error { // Component render - var buf bytes.Buffer - err := tmplModified.Execute(&buf, map[string]string{ + var body bytes.Buffer + err := tmplModified.Execute(&body, map[string]string{ "path": upath, }) if err != nil { return err } // Page render - return renderPage(w, upath, "", buf.String()) + return renderPage(w, upath, "", body.String(), "") } func renderDeleted(w io.Writer, upath string) error { // Component render - var buf bytes.Buffer - err := tmplDeleted.Execute(&buf, map[string]string{ + var body bytes.Buffer + err := tmplDeleted.Execute(&body, map[string]string{ "path": upath, }) if err != nil { return err } // Page render - return renderPage(w, upath, "", buf.String()) + return renderPage(w, upath, "", body.String(), "") } diff --git a/static/mde.js b/static/mde.js deleted file mode 100644 index 7471110..0000000 --- a/static/mde.js +++ /dev/null @@ -1,20 +0,0 @@ -(function() { - var textarea = document.getElementsByTagName("textarea")[0]; - var form = textarea.form; - var container = document.createElement('div'); - /*container.innerHTML = - "

I know it looks funny in the editor, but to set the page "+ - "title (what appears in the tab name/window bar), put this at "+ - "the top of the page:

\n"+ - "
---\ntitle: \"Your Title Here\"\n---\n
";*/ - form.insertBefore(container, textarea); - container.appendChild(textarea); - - var simplemde = new SimpleMDE({ - autoDownloadFontAwesome: false, - element: textarea, - promptURLs: true, - forceSync: true, - showIcons: ["code", "table"], - }); -})(); diff --git a/static/style.css b/static/style.css index cad83c0..2ce7fa8 100644 --- a/static/style.css +++ b/static/style.css @@ -34,3 +34,38 @@ input[type=file] { background: #EEEEEE; border-radius: 4px; } + +kbd, code, samp, tt, pre { + background: #DDDDFF; + white-space: pre; +} +pre { + margin: auto 2em; + padding: .5em; + overflow: auto; + border: solid 1px #AAAAAA; +} + +aside { + padding: 10px; + border-radius: 4px; + border: solid 1px #ddd; + background: rgb(240, 240, 240); + opacity: 0.7; +} + +.CodeMirror { + /* match Firefox's built-in style for textearea */ + border: 1px solid rgb(232, 232, 231); +} +.CodeMirror .cm-trailingspace { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAACCAYAAAB/qH1jAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QUXCToH00Y1UgAAACFJREFUCNdjPMDBUc/AwNDAAAFMTAwMDA0OP34wQgX/AQBYgwYEx4f9lQAAAABJRU5ErkJggg==); + background-position: bottom left; + background-repeat: repeat-x; +} +.CodeMirror .cm-spell-error:not(.cm-url):not(.cm-comment):not(.cm-tag):not(.cm-word) { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAACCAYAAAB/qH1jAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QUXCToH00Y1UgAAACFJREFUCNdjPMDBUc/AwNDAAAFMTAwMDA0OP34wQgX/AQBYgwYEx4f9lQAAAABJRU5ErkJggg==) !important; + background-position: bottom left !important; + background-repeat: repeat-x !important; + background-color: transparent !important; +} -- cgit v1.2.3