Archived
1
0
This commit is contained in:
Jeff Becker 2016-04-25 15:57:49 -04:00
parent 6797e68ddd
commit 5c66f4684a
No known key found for this signature in database
GPG Key ID: AB950234D6EA286B
5 changed files with 196 additions and 30 deletions

View File

@ -4,8 +4,7 @@
// insert a backlink for a post given its short hash // insert a backlink for a post given its short hash
function nntpchan_backlink(shorthash) function nntpchan_backlink(shorthash) {
{
var elem = document.getElementById("postform_message"); var elem = document.getElementById("postform_message");
if ( elem ) if ( elem )
{ {
@ -13,18 +12,6 @@ function nntpchan_backlink(shorthash)
} }
} }
var banner_count = 3;
// inject a banner into an element
function nntpchan_inject_banners(elem, prefix) {
var n = Math.floor(Math.random() * banner_count);
var banner = prefix + "static/banner_"+n+".jpg";
var e = document.createElement("img");
e.src = banner;
e.id = "nntpchan_banner";
elem.appendChild(e);
}
function get_storage() { function get_storage() {
var st = null; var st = null;
if (window.localStorage) { if (window.localStorage) {
@ -47,8 +34,180 @@ function enable_theme(prefix, name) {
} }
} }
function main() {
// do other initialization here // call an api method
// handler(json_object) on success
// handler(null) on fail
function nntpchan_apicall(url, handler, err_handler) {
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
if (ajax.readyState == XMLHttpRequest.DONE ) {
var status = ajax.status;
var j = null;
if (status == 200) {
// found
try {
j = JSON.parse(ajax.responseText);
} catch (e) {} // ignore parse error
} else if (status == 410) {
if (err_handler) {err_handler("cannot fetch post: api disabled");}
return;
}
handler(j);
}
};
ajax.open("GET", url);
ajax.send();
}
// build post from json
// inject into parent
// if j is null then inject "not found" post
function nntpchan_buildpost(parent, j) {
var post = document.createElement("div");
if (j) {
// huehuehue
post.innerHTML = j.PostMarkup;
} else {
post.setAttribute("class", "notfound post");
post.appendChild(document.createTextNode("post not found"));
}
parent.appendChild(post);
}
// inject post hover behavior
function inject_hover(prefix, el, parent) {
if (!prefix) { throw "prefix is not defined"; }
console.log(el, parent);
var timeout;
var idx = -2;
var linkhash = el.backlinkhash;
var elem = document.createElement("span");
elem.setAttribute("class", "backlink_rewritten");
elem.appendChild(document.createTextNode(">>"+linkhash.substr(0,10)));
parent.appendChild(elem);
parent.removeChild(el);
elem.onclick = function(ev) {
if(elem.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.appendChild(document.createTextNode("not found"));
} else {
// wrap backlink
nntpchan_buildpost(wrapper, j);
}
elem.appendChild(wrapper);
elem.backlink = false;
}, function(msg) {
var wrapper = document.createElement("div");
wrapper.setAttribute("class", "hover "+linkhash);
wrapper.appendChild(document.createTextNode(msg));
elem.appendChild(wrapper);
elem.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]);
}
elem.backlink = true;
}
};
elem.backlink = true;
}
function livechan_got_post(widget, j) {
// do scroll
while (widget.children.length > 20) {
// remove top element
widget.children.removeChild(widget.children[0]);
}
nntpchan_buildpost(widget, j);
// scroll to bottom
widget.scrollTop = widget.scrollHeight;
}
// inject post form into an element
function inject_postform(prefix, parent) {
}
// inject livechan widget into parent
function inject_livechan_widget(prefix, parent) {
if ( "WebSocket" in window ) {
var url = "ws://"+document.location.host+prefix+"live";
if ( document.location.protocol == "https:" ) {
url = "wss://"+document.location.host+prefix+"live";
}
var socket = new WebSocket(url);
var progress = function(str) {
parent.innerHTML = "<pre>livechan: "+str+"</pre>";
};
progress("initialize");
socket.onopen = function () {
progress("connected");
}
socket.onmessage = function(ev) {
var j = null;
try {
j = JSON.parse(ev.data);
} catch(e) {
// ignore
}
if (j) {
console.log(j);
livechan_got_post(parent, j);
}
}
socket.onclose = function(ev) {
progress("connection closed");
setTimeout(function(){ parent.innerHTML = ""; }, 5000);
}
} else {
parent.innerHTML = "<pre>livechan mode requires websocket support</pre>";
setTimeout(function() {
parent.innerHTML = "";
}, 5000);
}
}
function ukko_livechan(prefix) {
var ukko = document.getElementById("ukko_threads");
if (ukko) {
// remove children
ukko.innerHTML = "";
inject_livechan_widget(prefix, ukko);
}
}
var banner_count = 3;
// inject a banner into an element
function nntpchan_inject_banners(elem, prefix) {
var n = Math.floor(Math.random() * banner_count);
var banner = prefix + "static/banner_"+n+".jpg";
var e = document.createElement("img");
e.src = banner;
e.id = "nntpchan_banner";
elem.appendChild(e);
}
function init(prefix) {
// inject posthover ...
var elems = document.getElementsByClassName("backlink");
// ... for backlinks
for ( var idx = 0 ; idx < elems.length ; idx ++ ) {
// uncomment to do reply hover
//inject_hover(prefix, elems[idx], elems[idx].parentNode);
}
} }
// apply themes // apply themes

View File

@ -394,7 +394,11 @@ input, textarea {
} }
.backlink, .backlink:hover, .backlink:visited, .backlink:visited:hover { .backlink_rewritten {
z-index: 5;
}
.backlink, .backlink:hover, .backlink:visited, .backlink:visited:hover, .backlink_rewritten {
margin-left: none; margin-left: none;
color: #D00 color: #D00
} }

View File

@ -20,7 +20,7 @@
<script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script> <script type="text/javascript" src="{{board.Prefix}}static/nntpchan.js"></script>
<title>{{board.Board}}</title> <title>{{board.Board}}</title>
</head> </head>
<body onload="main()"> <body>
<!-- begin navbar --> <!-- begin navbar -->
{{{board.Navbar}}} {{{board.Navbar}}}
<!-- end navbar --> <!-- end navbar -->
@ -55,10 +55,10 @@
<a href="{{board.Prefix}}catalog-{{board.Name}}.html"> {{#i18n.Translations}}{{catalog_label}}{{/i18n.Translations}} </a> <a href="{{board.Prefix}}catalog-{{board.Name}}.html"> {{#i18n.Translations}}{{catalog_label}}{{/i18n.Translations}} </a>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
var prefix = "{{board.Prefix}}";
var e = document.getElementById("nntpchan_banner"); var e = document.getElementById("nntpchan_banner");
nntpchan_inject_banners(e, "{{board.Prefix}}"); nntpchan_inject_banners(e, prefix);
init(prefix);
</script> </script>
<hr/> <hr/>
<footer> <footer>

View File

@ -19,7 +19,7 @@
<script src="{{thread.Prefix}}static/nntpchan.js" type="text/javascript"></script> <script src="{{thread.Prefix}}static/nntpchan.js" type="text/javascript"></script>
<title> {{thread.OP.Subject}} </title> <title> {{thread.OP.Subject}} </title>
</head> </head>
<body onload="main()"> <body>
<!-- begin navbar --> <!-- begin navbar -->
{{{thread.Navbar}}} {{{thread.Navbar}}}
<!-- end navbar --> <!-- end navbar -->
@ -45,9 +45,10 @@
<hr/> <hr/>
<div class="navLinks">[<a href="{{thread.BoardURL}}" accesskey="a">{{#i18n.Translations}}{{return}}{{/i18n.Translations}}</a>] [<a href="{{thread.Prefix}}catalog-{{thread.Board}}.html" accesskey="r">{{#i18n.Translations}}{{catalog_label}}{{/i18n.Translations}}</a>] [<a href="#thread_{{thread.OP.PostHash}}">{{#i18n.Translations}}{{to_top_label}}{{/i18n.Translations}}</a>] [<a href="#navlinks" accesskey="r" onclick="location.reload();">{{#i18n.Translations}}{{update}}{{/i18n.Translations}}</a>]</div> <div class="navLinks">[<a href="{{thread.BoardURL}}" accesskey="a">{{#i18n.Translations}}{{return}}{{/i18n.Translations}}</a>] [<a href="{{thread.Prefix}}catalog-{{thread.Board}}.html" accesskey="r">{{#i18n.Translations}}{{catalog_label}}{{/i18n.Translations}}</a>] [<a href="#thread_{{thread.OP.PostHash}}">{{#i18n.Translations}}{{to_top_label}}{{/i18n.Translations}}</a>] [<a href="#navlinks" accesskey="r" onclick="location.reload();">{{#i18n.Translations}}{{update}}{{/i18n.Translations}}</a>]</div>
<script type="text/javascript"> <script type="text/javascript">
var prefix = "{{thread.Prefix}}";
var e = document.getElementById("nntpchan_banner"); var e = document.getElementById("nntpchan_banner");
nntpchan_inject_banners(e, "{{thread.Prefix}}"); nntpchan_inject_banners(e, prefix);
init(prefix);
</script> </script>
<hr/> <hr/>
<footer> <footer>

View File

@ -12,7 +12,7 @@
<link id="current_theme" rel="stylesheet" href="{{prefix}}static/user.css" /> <link id="current_theme" rel="stylesheet" href="{{prefix}}static/user.css" />
<script type="text/javascript" src="{{prefix}}static/nntpchan.js"></script> <script type="text/javascript" src="{{prefix}}static/nntpchan.js"></script>
</head> </head>
<body onload="main()"> <body>
<center> <center>
<div id="nntpchan_banner"> <div id="nntpchan_banner">
</div> </div>
@ -21,10 +21,11 @@
{{{navbar}}} {{{navbar}}}
<!-- end navbar --> <!-- end navbar -->
<div class="board_header"> {{#i18n.Translations}}{{overboard_title}}{{/i18n.Translations}} </div> <div class="board_header"> {{#i18n.Translations}}{{overboard_title}}{{/i18n.Translations}} </div>
<div id="ukko_threads"> <div id="ukko_threads">
<pre><a href="#" onclick="ukko_livechan('{{prefix}}')">livechan</a></pre>
{{#threads}} {{#threads}}
<div class="thread" id="thread_{{OP.PostHash}}"> <div class="thread" id="thread_{{OP.PostHash}}">
<div class="ukko_thread_header"> <div class="ukko_thread_header">
<p>{{#i18n.Translations}}{{posted_on_label}}{{/i18n.Translations}} <a href="{{{BoardURL}}}"><span class="ukko_boardname">{{OP.Board}}</span></a></p> <p>{{#i18n.Translations}}{{posted_on_label}}{{/i18n.Translations}} <a href="{{{BoardURL}}}"><span class="ukko_boardname">{{OP.Board}}</span></a></p>
</div> </div>
{{{OP.Truncate.RenderPost}}} {{{OP.Truncate.RenderPost}}}
@ -36,10 +37,11 @@
{{/threads}} {{/threads}}
</div> </div>
<script type="text/javascript" > <script type="text/javascript" >
var prefix = "{{prefix}}";
var e = document.getElementById("nntpchan_banner"); var e = document.getElementById("nntpchan_banner");
nntpchan_inject_banners(e, "{{prefix}}"); nntpchan_inject_banners(e, prefix);
init(prefix);
</script> </script>
<hr/> <hr/>
<footer> <footer>
<p class="legal">All posts on this site are the responsibility of the individual poster and not the administration, pursuant to 47 U.S.C. § 230.</p> <p class="legal">All posts on this site are the responsibility of the individual poster and not the administration, pursuant to 47 U.S.C. § 230.</p>