2016-04-30 21:25:15 +05:00
|
|
|
|
|
|
|
var dynreply;
|
|
|
|
|
|
|
|
function getReplyTo() {
|
|
|
|
if(!dynreply) {
|
2016-04-30 21:56:24 +05:00
|
|
|
var e = document.getElementById("postform_container");
|
2016-04-30 21:25:15 +05:00
|
|
|
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);
|
|
|
|
}
|
2016-04-30 21:41:23 +05:00
|
|
|
table.appendChild(tr);
|
2016-04-30 21:25:15 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
build dynamic reply box
|
|
|
|
*/
|
|
|
|
function DynReply(existingElem) {
|
|
|
|
if (existingElem) {
|
|
|
|
// wrap existing post form
|
|
|
|
this.elem = existingElem;
|
|
|
|
this.form = this.elem.querySelector("form");
|
2016-05-01 01:03:39 +05:00
|
|
|
this._error = document.getElementById("postform_msg");
|
2016-05-01 01:09:59 +05:00
|
|
|
this.url = this.form.action + "?t=json";
|
2016-04-30 21:25:15 +05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// build new post form
|
|
|
|
|
|
|
|
var elem = document.createElement("div");
|
2016-04-30 21:56:24 +05:00
|
|
|
elem.setAttribute("id", "postform_container");
|
2016-04-30 21:25:15 +05:00
|
|
|
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");
|
2016-05-01 01:03:39 +05:00
|
|
|
var err_elem = document.createElement("span");
|
|
|
|
err_elem.setAttribute("id", "postform_msg");
|
2016-05-01 01:36:21 +05:00
|
|
|
this._error = err_elem;
|
2016-05-01 01:03:39 +05:00
|
|
|
table_insert_row(tbody, document.createTextNode("Name"), [elem, err_elem])
|
2016-04-30 21:25:15 +05:00
|
|
|
|
|
|
|
// subject
|
|
|
|
elem = document.createElement("input");
|
|
|
|
elem.setAttribute("name", "subject");
|
|
|
|
elem.setAttribute("value", "");
|
|
|
|
// submit
|
|
|
|
var submit = document.createElement("input");
|
|
|
|
submit.setAttribute("value", "reply");
|
|
|
|
submit.setAttribute("class", "button");
|
2016-05-01 19:31:14 +05:00
|
|
|
submit.setAttribute("type", "submit");
|
2016-05-01 01:03:39 +05:00
|
|
|
submit.setAttribute("id", "postform_submit");
|
2016-04-30 21:25:15 +05:00
|
|
|
table_insert_row(tbody, document.createTextNode("Subject"), [elem, submit]);
|
|
|
|
|
2016-05-01 01:03:39 +05:00
|
|
|
|
2016-04-30 21:25:15 +05:00
|
|
|
// 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";
|
2016-05-01 19:31:14 +05:00
|
|
|
table_insert_row(tbody, document.createTextNode("Solution"), [elem])
|
2016-04-30 21:25:15 +05:00
|
|
|
|
|
|
|
table.appendChild(tbody);
|
|
|
|
this.form.appendChild(table);
|
|
|
|
this.elem.appendChild(this.form);
|
2016-04-30 21:39:46 +05:00
|
|
|
document.body.appendChild(this.elem);
|
2016-04-30 21:25:15 +05:00
|
|
|
this.board = null;
|
|
|
|
this.roothash = null;
|
|
|
|
this.prefix = null;
|
2016-05-01 01:03:39 +05:00
|
|
|
this.url = null;
|
2016-04-30 21:25:15 +05:00
|
|
|
}
|
|
|
|
|
2016-04-30 23:44:06 +05:00
|
|
|
DynReply.prototype.moveTo = function(x,y) {
|
2016-05-01 00:09:01 +05:00
|
|
|
x = window.screenX - x ;
|
2016-05-01 00:02:09 +05:00
|
|
|
this.elem.setAttribute("style", "top: "+y+"px; right: "+x+"px;");
|
2016-04-30 23:44:06 +05:00
|
|
|
}
|
|
|
|
|
2016-04-30 21:25:15 +05:00
|
|
|
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");
|
2016-04-30 22:06:29 +05:00
|
|
|
ref.setAttribute("value", this.roothash);
|
2016-05-01 01:03:39 +05:00
|
|
|
this.url = this.prefix + "post/" + this.board + "?t=json";
|
2016-04-30 21:25:15 +05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DynReply.prototype.show = function() {
|
2016-04-30 21:29:51 +05:00
|
|
|
console.log("show dynreply");
|
2016-04-30 21:25:15 +05:00
|
|
|
this.update();
|
|
|
|
this.elem.style.display = 'inline';
|
|
|
|
}
|
|
|
|
|
2016-05-01 01:03:39 +05:00
|
|
|
DynReply.prototype.hide = function() {
|
|
|
|
console.log("hide dynreply");
|
|
|
|
this.elem.style.display = "none";
|
|
|
|
}
|
|
|
|
|
|
|
|
DynReply.prototype.post = function(cb, err_cb) {
|
|
|
|
if (this.url && this.form) {
|
|
|
|
var data = new FormData(this.form);
|
|
|
|
var ajax = new XMLHttpRequest();
|
|
|
|
ajax.onreadystatechange = function(ev) {
|
|
|
|
if (ajax.readyState == XMLHttpRequest.DONE) {
|
|
|
|
var j = null;
|
|
|
|
try {
|
|
|
|
j = JSON.parse(ajax.responseText);
|
|
|
|
cb(j);
|
|
|
|
} catch (e) {
|
|
|
|
if(err_cb) {
|
|
|
|
err_cb(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ajax.open("POST", this.url);
|
|
|
|
ajax.send(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-30 21:25:15 +05:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-01 01:03:39 +05:00
|
|
|
DynReply.prototype.showError = function(msg) {
|
|
|
|
console.log("error in dynreply: "+msg);
|
|
|
|
this._error.setAttribute("class", "error");
|
2016-05-01 01:14:47 +05:00
|
|
|
this._error.appendChild(document.createTextNode(msg));
|
2016-05-01 01:20:27 +05:00
|
|
|
this.updateCaptcha();
|
2016-05-01 01:03:39 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
DynReply.prototype.showMessage = function(msg) {
|
|
|
|
this._error.setAttribute("class", "message");
|
2016-05-01 01:14:47 +05:00
|
|
|
this._error.appendChild(document.createTextNode(msg));
|
2016-05-01 01:11:20 +05:00
|
|
|
var e = this._error;
|
2016-05-01 01:03:39 +05:00
|
|
|
setTimeout(function() {
|
|
|
|
// clear it
|
2016-05-01 01:11:20 +05:00
|
|
|
e.innerHTML = "";
|
2016-05-01 01:03:39 +05:00
|
|
|
}, 2000);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-04-30 21:25:15 +05:00
|
|
|
// reply box function
|
2016-04-30 23:44:06 +05:00
|
|
|
function nntpchan_reply(parent, shorthash) {
|
|
|
|
if (parent) {
|
2016-04-30 21:35:21 +05:00
|
|
|
var boardname = parent.getAttribute("boardname");
|
2016-04-30 22:03:18 +05:00
|
|
|
var roothash = parent.getAttribute("root");
|
2016-04-30 21:25:15 +05:00
|
|
|
var replyto = getReplyTo();
|
|
|
|
// set target
|
|
|
|
replyto.setBoard(boardname);
|
|
|
|
replyto.setRoot(roothash);
|
|
|
|
// show it
|
|
|
|
replyto.show();
|
|
|
|
}
|
2016-04-27 17:21:12 +05:00
|
|
|
var elem = document.getElementById("postform_message");
|
|
|
|
if ( elem )
|
|
|
|
{
|
2016-04-30 21:25:15 +05:00
|
|
|
elem.value += ">>" + shorthash.substr(0,10) + "\n";
|
2016-04-27 17:21:12 +05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// inject post hover behavior
|
|
|
|
function inject_hover(prefix, el, parent) {
|
|
|
|
if (!prefix) { throw "prefix is not defined"; }
|
|
|
|
var linkhash = el.getAttribute("backlinkhash");
|
|
|
|
if (!linkhash) { throw "linkhash undefined"; }
|
|
|
|
console.log("rewrite linkhash "+linkhash);
|
|
|
|
|
|
|
|
var elem = document.createElement("span");
|
|
|
|
elem.setAttribute("class", "backlink_rewritten");
|
|
|
|
elem.appendChild(document.createTextNode(">>"+linkhash.substr(0,10)));
|
|
|
|
if (!parent) {
|
|
|
|
parent = el.parentNode;
|
|
|
|
}
|
|
|
|
parent.removeChild(el);
|
|
|
|
parent.appendChild(elem);
|
|
|
|
|
|
|
|
elem.onclick = function(ev) {
|
|
|
|
if(parent.backlink) {
|
|
|
|
nntpchan_apicall(prefix+"api/find?hash="+linkhash, function(j) {
|
|
|
|
var wrapper = document.createElement("div");
|
|
|
|
wrapper.setAttribute("class", "hover "+linkhash);
|
|
|
|
if (j == null) {
|
|
|
|
// not found?
|
|
|
|
wrapper.setAttribute("class", "hover notfound-hover "+linkhash);
|
|
|
|
wrapper.appendChild(document.createTextNode("not found"));
|
|
|
|
} else {
|
|
|
|
// wrap backlink
|
|
|
|
nntpchan_buildpost(wrapper, j);
|
|
|
|
}
|
|
|
|
parent.appendChild(wrapper);
|
|
|
|
parent.backlink = false;
|
|
|
|
}, function(msg) {
|
|
|
|
var wrapper = document.createElement("div");
|
|
|
|
wrapper.setAttribute("class", "hover "+linkhash);
|
|
|
|
wrapper.appendChild(document.createTextNode(msg));
|
|
|
|
parent.appendChild(wrapper);
|
|
|
|
parent.backlink = false;
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
var elems = document.getElementsByClassName(linkhash);
|
|
|
|
if (!elems) throw "bad state, no backlinks open?";
|
|
|
|
for (var idx = 0 ; idx < elems.length; idx ++ ) {
|
|
|
|
elems[idx].parentNode.removeChild(elems[idx]);
|
|
|
|
}
|
|
|
|
parent.backlink = true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
parent.backlink = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// inject post hover for all backlinks in an element
|
|
|
|
function inject_hover_for_element(elem) {
|
|
|
|
var elems = elem.getElementsByClassName("backlink");
|
|
|
|
var ls = [];
|
|
|
|
var l = elems.length;
|
|
|
|
for ( var idx = 0 ; idx < l ; idx ++ ) {
|
|
|
|
var e = elems[idx];
|
|
|
|
ls.push(e);
|
|
|
|
}
|
|
|
|
for( var elem in ls ) {
|
|
|
|
inject_hover(prefix, ls[elem]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function init(prefix) {
|
|
|
|
// inject posthover ...
|
|
|
|
inject_hover_for_element(document);
|
2016-05-01 01:03:39 +05:00
|
|
|
// initialize replyto widget
|
2016-04-30 22:18:17 +05:00
|
|
|
var rpl = getReplyTo();
|
2016-04-30 22:22:17 +05:00
|
|
|
rpl.setPrefix(prefix);
|
2016-05-01 01:03:39 +05:00
|
|
|
|
|
|
|
// position replyto widget
|
2016-04-30 22:18:17 +05:00
|
|
|
var e = rpl.elem;
|
2016-04-30 23:54:24 +05:00
|
|
|
e.setAttribute("draggable", "true");
|
2016-04-30 23:44:06 +05:00
|
|
|
var mouseDownX, mouseDownY;
|
|
|
|
|
2016-05-01 00:10:15 +05:00
|
|
|
var originalX = window.screenX - 150;
|
2016-04-30 23:44:06 +05:00
|
|
|
var originalY = 10;
|
|
|
|
rpl.moveTo(originalX, originalY);
|
2016-05-01 01:28:26 +05:00
|
|
|
|
2016-04-30 23:52:19 +05:00
|
|
|
e.addEventListener("dragstart", function(ev) {
|
2016-04-30 23:44:06 +05:00
|
|
|
mouseDownX = ev.clientX;
|
|
|
|
mouseDownY = ev.clientY;
|
2016-05-01 01:32:10 +05:00
|
|
|
if (!ev.ctrlKey) {
|
2016-05-01 01:25:27 +05:00
|
|
|
ev.preventDefault();
|
|
|
|
}
|
2016-04-30 23:52:19 +05:00
|
|
|
}, false);
|
2016-04-30 23:44:06 +05:00
|
|
|
|
2016-04-30 23:52:19 +05:00
|
|
|
e.addEventListener("dragend", function(ev) {
|
2016-05-01 00:03:54 +05:00
|
|
|
var x = originalX + ev.clientX - mouseDownX;
|
2016-04-30 23:57:07 +05:00
|
|
|
var y = originalY + ev.clientY - mouseDownY;
|
2016-05-01 00:13:52 +05:00
|
|
|
x -= window.screenLeft;
|
|
|
|
y -= window.screenTop;
|
|
|
|
rpl.moveTo(x, y);
|
|
|
|
originalX = x;
|
|
|
|
originalY = y;
|
2016-04-30 23:52:19 +05:00
|
|
|
}, false);
|
2016-05-01 01:03:39 +05:00
|
|
|
|
|
|
|
// add replyto post handlers
|
|
|
|
e = document.getElementById("postform_submit");
|
2016-05-01 19:31:14 +05:00
|
|
|
var postit = function() {
|
2016-05-01 01:03:39 +05:00
|
|
|
var f = document.querySelector("form");
|
|
|
|
// do ajax request to post data
|
|
|
|
var r = getReplyTo();
|
|
|
|
r.post(function(j) {
|
|
|
|
if(j.error) {
|
|
|
|
// an error happened
|
2016-05-01 01:19:08 +05:00
|
|
|
r.showError(j.error);
|
2016-05-01 01:03:39 +05:00
|
|
|
} else {
|
|
|
|
// we're good
|
|
|
|
r.showMessage("posted as "+j.message_id);
|
2016-05-01 01:20:27 +05:00
|
|
|
r.updateCaptcha();
|
2016-05-01 01:03:39 +05:00
|
|
|
}
|
|
|
|
}, function(err) {
|
2016-05-01 01:19:08 +05:00
|
|
|
r.showError(err);
|
2016-05-01 01:03:39 +05:00
|
|
|
});
|
2016-05-01 01:18:08 +05:00
|
|
|
r.showMessage("posting... ");
|
2016-05-01 01:03:39 +05:00
|
|
|
}
|
2016-05-01 19:31:14 +05:00
|
|
|
e.onclick = postit;
|
|
|
|
var f = document.querySelector("form");
|
2016-05-01 19:34:05 +05:00
|
|
|
f.onsubmit = function() {
|
|
|
|
postit();
|
|
|
|
return false;
|
|
|
|
}
|
2016-05-01 19:31:14 +05:00
|
|
|
|
2016-04-27 17:21:12 +05:00
|
|
|
}
|
|
|
|
|