diff --git a/common/templates/templates.go b/common/templates/templates.go index f528801d..f856daaa 100644 --- a/common/templates/templates.go +++ b/common/templates/templates.go @@ -612,10 +612,40 @@ func (c *CTemplateSet) compileRangeNode(con CContext, node *parse.RangeNode) { } } +// ! Temporary, we probably want something that is good with non-struct pointers too +// For compileSubSwitch and compileSubTemplate +func (c *CTemplateSet) skipStructPointers(cur reflect.Value, id string) reflect.Value { + if cur.Kind() == reflect.Ptr { + c.detail("Looping over pointer") + for cur.Kind() == reflect.Ptr { + cur = cur.Elem() + } + c.detail("Data Kind:", cur.Kind().String()) + c.detail("Field Bit:", id) + } + return cur +} + +// For compileSubSwitch and compileSubTemplate +func (c *CTemplateSet) checkIfValid(cur reflect.Value, varHolder string, holdreflect reflect.Value, varBit string, multiline bool) { + if !cur.IsValid() { + c.critical("Debug Data:") + c.critical("Holdreflect:", holdreflect) + c.critical("Holdreflect.Kind():", holdreflect.Kind()) + if !c.config.SuperDebug { + c.critical("cur.Kind():", cur.Kind().String()) + } + c.critical("") + if !multiline { + panic(varHolder + varBit + "^\n" + "Invalid value. Maybe, it doesn't exist?") + } + panic(varBit + "^\n" + "Invalid value. Maybe, it doesn't exist?") + } +} + func (c *CTemplateSet) compileSubSwitch(con CContext, node *parse.CommandNode) { c.dumpCall("compileSubSwitch", con, node) - firstWord := node.Args[0] - switch n := firstWord.(type) { + switch n := node.Args[0].(type) { case *parse.FieldNode: c.detail("Field Node:", n.Ident) /* Use reflect to determine if the field is for a method, otherwise assume it's a variable. Variable declarations are coming soon! */ @@ -627,45 +657,19 @@ func (c *CTemplateSet) compileSubSwitch(con CContext, node *parse.CommandNode) { varBit += ".(" + cur.Type().Name() + ")" } - // ! Might not work so well for non-struct pointers - skipPointers := func(cur reflect.Value, id string) reflect.Value { - if cur.Kind() == reflect.Ptr { - c.detail("Looping over pointer") - for cur.Kind() == reflect.Ptr { - cur = cur.Elem() - } - c.detail("Data Kind:", cur.Kind().String()) - c.detail("Field Bit:", id) - } - return cur - } - var assLines string var multiline = false for _, id := range n.Ident { c.detail("Data Kind:", cur.Kind().String()) c.detail("Field Bit:", id) - cur = skipPointers(cur, id) - - if !cur.IsValid() { - c.error("Debug Data:") - c.error("Holdreflect:", con.HoldReflect) - c.error("Holdreflect.Kind():", con.HoldReflect.Kind()) - if !c.config.SuperDebug { - c.error("cur.Kind():", cur.Kind().String()) - } - c.error("") - if !multiline { - panic(con.VarHolder + varBit + "^\n" + "Invalid value. Maybe, it doesn't exist?") - } - panic(varBit + "^\n" + "Invalid value. Maybe, it doesn't exist?") - } + cur = c.skipStructPointers(cur, id) + c.checkIfValid(cur, con.VarHolder, con.HoldReflect, varBit, multiline) c.detail("in-loop varBit: " + varBit) if cur.Kind() == reflect.Map { cur = cur.MapIndex(reflect.ValueOf(id)) varBit += "[\"" + id + "\"]" - cur = skipPointers(cur, id) + cur = c.skipStructPointers(cur, id) if cur.Kind() == reflect.Struct || cur.Kind() == reflect.Interface { // TODO: Move the newVarByte declaration to the top level or to the if level, if a dispInt is only used in a particular if statement @@ -1385,15 +1389,60 @@ func (c *CTemplateSet) compileSubTemplate(pcon CContext, node *parse.TemplateNod con.TemplateName = fname if node.Pipe != nil { for _, cmd := range node.Pipe.Cmds { - firstWord := cmd.Args[0] - switch firstWord.(type) { + switch p := cmd.Args[0].(type) { + case *parse.FieldNode: + // TODO: Incomplete but it should cover the basics + cur := pcon.HoldReflect + + var varBit string + if cur.Kind() == reflect.Interface { + cur = cur.Elem() + varBit += ".(" + cur.Type().Name() + ")" + } + + for _, id := range p.Ident { + c.detail("Data Kind:", cur.Kind().String()) + c.detail("Field Bit:", id) + cur = c.skipStructPointers(cur, id) + c.checkIfValid(cur, pcon.VarHolder, pcon.HoldReflect, varBit, false) + + if cur.Kind() != reflect.Interface { + cur = cur.FieldByName(id) + varBit += "." + id + } + + // TODO: Handle deeply nested pointers mixed with interfaces mixed with pointers better + if cur.Kind() == reflect.Interface { + cur = cur.Elem() + varBit += ".(" + // TODO: Surely, there's a better way of doing this? + if cur.Type().PkgPath() != "main" && cur.Type().PkgPath() != "" { + c.importMap["html/template"] = "html/template" + varBit += strings.TrimPrefix(cur.Type().PkgPath(), "html/") + "." + } + varBit += cur.Type().Name() + ")" + } + } + con.VarHolder = pcon.VarHolder + varBit + con.HoldReflect = cur case *parse.DotNode: con.VarHolder = pcon.VarHolder con.HoldReflect = pcon.HoldReflect case *parse.NilNode: panic("Nil is not a command x.x") default: - c.detail("Unknown Node: ", firstWord) + c.critical("Unknown Param Type:", p) + pvar := reflect.ValueOf(p) + c.critical("param kind:", pvar.Kind().String()) + c.critical("param type:", pvar.Type().Name()) + if pvar.Kind() == reflect.Ptr { + c.critical("Looping over pointer") + for pvar.Kind() == reflect.Ptr { + pvar = pvar.Elem() + } + c.critical("concrete kind:", pvar.Kind().String()) + c.critical("concrete type:", pvar.Type().Name()) + } panic("") } } @@ -1527,3 +1576,7 @@ func (c *CTemplateSet) error(args ...interface{}) { log.Println(args...) } } + +func (c *CTemplateSet) critical(args ...interface{}) { + log.Println(args...) +} diff --git a/public/global.js b/public/global.js index c7eeb8b3..4fe797f0 100644 --- a/public/global.js +++ b/public/global.js @@ -388,17 +388,19 @@ function mainInit(){ $('.show_on_edit').removeClass("edit_opened"); runHook("close_edit"); - let formAction = this.form.getAttribute("action"); $.ajax({ - url: formAction, + url: this.form.getAttribute("action"), type: "POST", dataType: "json", - error: ajaxError, data: { topic_name: topicNameInput, topic_status: topicStatusInput, topic_content: topicContentInput, - topic_js: 1 + js: 1 + }, + error: ajaxError, + success: (data,status,xhr) => { + if("Content" in data) $(".topic_content").html(data["Content"]); } }); }); diff --git a/routes/topic.go b/routes/topic.go index 6525a1f8..a46dcfd9 100644 --- a/routes/topic.go +++ b/routes/topic.go @@ -616,10 +616,22 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User, s return common.InternalErrorJSQ(err, w, r, isJs) } + // TODO: Avoid the load to get this faster? + topic, err = common.Topics.Get(topic.ID) + if err == sql.ErrNoRows { + return common.PreErrorJSQ("The updated topic doesn't exist.", w, r, isJs) + } else if err != nil { + return common.InternalErrorJSQ(err, w, r, isJs) + } + if !isJs { http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther) } else { - _, _ = w.Write(successJSONBytes) + outBytes, err := json.Marshal(JsonReply{common.ParseMessage(topic.Content, topic.ParentID, "forums")}) + if err != nil { + return common.InternalErrorJSQ(err, w, r, isJs) + } + w.Write(outBytes) } return nil } diff --git a/templates/topic_alt.html b/templates/topic_alt.html index e990c1b7..6c3861c3 100644 --- a/templates/topic_alt.html +++ b/templates/topic_alt.html @@ -14,7 +14,7 @@