From 1b7526ff2f06ba41a8e091eccd4e00f74c6751e7 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sat, 30 Apr 2016 12:25:15 -0400 Subject: [PATCH] initial dynamic reply code --- build-js.sh | 18 ++ contrib/js/backlink.js | 190 +++++++++++++++++++- contrib/static/nntpchan.js | 19 +- contrib/templates/default/post.mustache | 2 +- contrib/templates/default/postform.mustache | 2 +- 5 files changed, 225 insertions(+), 6 deletions(-) diff --git a/build-js.sh b/build-js.sh index e29bd80..0cd3b97 100755 --- a/build-js.sh +++ b/build-js.sh @@ -14,6 +14,16 @@ if [ ! -f $GOPATH/bin/minify ]; then fi outfile=$(readlink -e ./contrib/static/nntpchan.js) +lint() { + if [ "x$(which jslint)" == "x" ] ; then + # no jslint + true + else + echo "jslint: $1" + jslint --browser $1 + fi +} + mini() { echo "minify $1" echo "" >> $2 @@ -21,6 +31,14 @@ mini() { $GOPATH/bin/minify --mime=text/javascript >> $2 < $1 } +# do linting too +if [ "x$1" == "xlint" ] ; then + echo "linting..." + for f in ./contrib/js/*.js ; do + lint $f + done +fi + echo -e "//For source code and license information please check https://github.com/majestrate/nntpchan \n" > $outfile mini ./contrib/js/main.js_ $outfile diff --git a/contrib/js/backlink.js b/contrib/js/backlink.js index 4f89ba8..20e4063 100644 --- a/contrib/js/backlink.js +++ b/contrib/js/backlink.js @@ -1,9 +1,193 @@ -// insert a backlink for a post given its short hash -function nntpchan_backlink(shorthash) { + +var dynreply; + +function getReplyTo() { + if(!dynreply) { + var e = document.getElementById("postform-container"); + if (e) { + // use existing postform + dynreply = new DynReply(e); + } else { + // build a new postform + dynreply = new DynReply(); + } + } + return dynreply; +} + +function table_insert_row(table, header, items) { + var tr = document.createElement("tr"); + // insert header element + var th = document.createElement("th"); + th.appendChild(header); + tr.appendChild(th); + // insert the rest of the elements + for (var idx = 0; idx < items.length; idx ++ ) { + var elem = document.createElement("td"); + elem.appendChild(items[idx]); + tr.appendChild(elem); + } +} + +/** + build dynamic reply box +*/ +function DynReply(existingElem) { + if (existingElem) { + // wrap existing post form + this.elem = existingElem; + this.form = this.elem.querySelector("form"); + return; + } + + // build new post form + + var elem = document.createElement("div"); + elem.setAttribute("id", "postform-container"); + + this.elem = elem; + // build post form + this.form = document.createElement("form"); + this.form.enctype = "multipart/form-data"; + this.form.name = "post"; + this.form.method = "post"; + // reference + elem = document.createElement("input"); + elem.setAttribute("id", "postform_reference"); + elem.name = "reference"; + elem.type = "hidden"; + this.form.appendChild(elem); + + var table = document.createElement("table"); + table.setAttribute("class", "postform"); + var tbody = document.createElement("tbody"); + + // name + elem = document.createElement("input"); + elem.setAttribute("name", "name"); + elem.setAttribute("value", "Anonymous"); + table_insert_row(tbody, document.createTextNode("Name"), [elem]) + + // subject + elem = document.createElement("input"); + elem.setAttribute("name", "subject"); + elem.setAttribute("value", ""); + // submit + var submit = document.createElement("input"); + submit.setAttribute("type", "submit"); + submit.setAttribute("value", "reply"); + submit.setAttribute("class", "button"); + table_insert_row(tbody, document.createTextNode("Subject"), [elem, submit]); + + // Comment + elem = document.createElement("textarea"); + elem.setAttribute("id", "postform_message"); + elem.setAttribute("name", "message"); + elem.setAttribute("cols", "40"); + elem.setAttribute("rows", "5"); + table_insert_row(tbody, document.createTextNode("Comment"), [elem]); + + // file + elem = document.createElement("input"); + elem.setAttribute("class", "postform_attachment"); + elem.setAttribute("id", "postform_attachments"); + elem.setAttribute("type", "file"); + elem.setAttribute("name", "attachment_uploaded"); + elem.setAttribute("multiple", "multiple"); + table_insert_row(tbody, document.createTextNode("Files"), [elem]); + + // dubs + elem = document.createElement("input"); + elem.setAttribute("type", "checkbox"); + elem.setAttribute("name", "dubs"); + table_insert_row(tbody, document.createTextNode("Get Dubs"), [elem]); + + // captcha + elem = document.createElement("img"); + elem.setAttribute("id", "captcha_img"); + elem.alt = "captcha"; + table_insert_row(tbody, document.createTextNode("Captcha"), [elem]); + + // captcha solution + elem = document.createElement("input"); + elem.name = "captcha"; + elem.autocomplete = "off"; + table_insert_row(tbody, document.createTextNode("Name"), [elem]) + + table.appendChild(tbody); + this.form.appendChild(table); + this.elem.appendChild(this.form); + + parent.appendChild(this.elem); + + this.board = null; + this.roothash = null; + this.prefix = null; +} + +DynReply.prototype.update = function() { + if (this.prefix) { + // update captcha + this.updateCaptcha(); + if (this.board && this.roothash) { + // update post form + var ref = document.getElementById("postform_reference"); + ref.value = this.roothash; + this.form.action = this.prefix + "post/" + this.board; + } + } +} + +DynReply.prototype.show = function() { + this.update(); + this.elem.style.display = 'inline'; +} + +DynReply.prototype.updateCaptcha = function() { + if (this.prefix) { + var captcha_img = document.getElementById("captcha_img"); + captcha_img.src = this.prefix + "captcha/img"; + } +} + +DynReply.prototype.setPrefix = function(prefix) { + this.prefix = prefix; +} + +DynReply.prototype.hide = function() { + this.elem.style.display = 'none'; +} + + +DynReply.prototype.setBoard = function(boardname) { + if (boardname) { + this.board = boardname; + } +} + +DynReply.prototype.setRoot = function(roothash) { + if (roothash) { + this.roothash = roothash; + } +} + +// reply box function +function nntpchan_reply(prefix, parent, shorthash) { + if (prefix && parent && parent.roothash && parent.boardname) { + var boardname = parent.boardname; + var roothash = parent.roothash; + var replyto = getReplyTo(); + // set target + replyto.setBoard(boardname); + replyto.setRoot(roothash); + replyto.setPrefix(prefix); + // show it + replyto.show(); + } var elem = document.getElementById("postform_message"); if ( elem ) { - elem.value += ">>" + shorthash.substr(0,10) + "\n"; + elem.value += ">>" + shorthash.substr(0,10) + "\n"; } } diff --git a/contrib/static/nntpchan.js b/contrib/static/nntpchan.js index 4206a22..ce459cc 100644 --- a/contrib/static/nntpchan.js +++ b/contrib/static/nntpchan.js @@ -11,7 +11,22 @@ handler(j);}};ajax.open("GET",url);ajax.send();} function nntpchan_buildpost(parent,j){var post=document.createElement("div");if(j){post.innerHTML=j.PostMarkup;inject_hover_for_element(post);}else{post.setAttribute("class","notfound post");post.appendChild(document.createTextNode("post not found"));} parent.appendChild(post);} /* ./contrib/js/backlink.js */ -function nntpchan_backlink(shorthash){var elem=document.getElementById("postform_message");if(elem) +var dynreply;function getReplyTo(){if(!dynreply){var e=document.getElementById("postform-container");if(e){dynreply=new DynReply(e);}else{dynreply=new DynReply();}} +return dynreply;} +function table_insert_row(table,header,items){var tr=document.createElement("tr");var th=document.createElement("th");th.appendChild(header);tr.appendChild(th);for(var idx=0;idx{{post.Subject}} {{post.Name}} - No.{{post.ShortHash}} + No.{{post.ShortHash}} [{{#i18n.Translations}}{{reply_label}}{{/i18n.Translations}}] {{{post.Pubkey}}} diff --git a/contrib/templates/default/postform.mustache b/contrib/templates/default/postform.mustache index 64727d6..236a4c0 100644 --- a/contrib/templates/default/postform.mustache +++ b/contrib/templates/default/postform.mustache @@ -10,7 +10,7 @@ }}
{{{csrf}}} - +