Merge branch 'master' of github.com:vichan-devel/Tinyboard

Conflicts:
	js/post-hider.js
This commit is contained in:
czaks 2013-08-05 06:03:40 -04:00
commit a84c4510fc
252 changed files with 22377 additions and 4883 deletions

18
templates/error.html Normal file
View file

@ -0,0 +1,18 @@
<div style="text-align:center">
<h2 style="margin:20px 0">{{ message }}</h2>
{% if board %}
<p>
<a href="{{ config.root }}{% if mod %}{{ config.file_mod }}?/{% endif %}{{ board.dir }}{{ config.file_index }}">
{% trans 'Go back' %}
</a>
</p>
{% endif %}
</div>
{% if debug and config.debug %}
<hr>
<h3>{% trans 'Error information' %}</h3>
<pre style="white-space:pre-wrap;font-size: 10px;">
{{ debug }}
</pre>
<hr>
{% endif %}

View file

@ -22,7 +22,8 @@
{% include 'attention_bar.html' %}
{% include 'post_form.html' %}
{% if config.blotter %}<hr /><div class="blotter">{{ config.blotter }}</div>{% endif %}
{% if config.global_message %}<hr /><div class="blotter">{{ config.global_message }}</div>{% endif %}
<hr />
<form name="postcontrols" action="{{ config.post_url }}" method="post">
<input type="hidden" name="board" value="{{ board.uri }}" />

View file

@ -4,6 +4,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=yes">
{% if config.meta_keywords %}<meta name="keywords" content="{{ config.meta_keywords }}">{% endif %}
{% if config.default_stylesheet.1 != '' %}<link rel="stylesheet" type="text/css" id="stylesheet" href="{{ config.uri_stylesheets }}{{ config.default_stylesheet.1 }}">{% endif %}
{% if config.font_awesome %}<link rel="stylesheet" media="screen" href="{{ config.root }}{{ config.font_awesome_css }}">{% endif %}
<script type="text/javascript">var configRoot="{{ config.root }}";</script>
{% if not nojavascript %}
<script type="text/javascript" src="{{ config.url_javascript }}"></script>
@ -12,17 +13,31 @@
{% endif %}
{% endif %}
{% if config.recaptcha %}<style type="text/css">{% raw %}
.recaptcha_image_cell {
background: none !important;
#recaptcha_area {
float: none !important;
padding: 0 !important;
}
table.recaptchatable {
#recaptcha_logo, #recaptcha_privacy {
display: none;
}
#recaptcha_table {
border: none !important;
}
#recaptcha_logo, #recaptcha_tagline {
display: none;
float: right;
#recaptcha_table tr:first-child {
height: auto;
}
.recaptchatable a {
display: block;
.recaptchatable img {
float: none !important;
}
#recaptcha_response_field {
font-size: 10pt !important;
border: 1px solid #a9a9a9 !important;
padding: 1px !important;
}
td.recaptcha_image_cell {
background: transparent !important;
}
.recaptchatable, #recaptcha_area tr, #recaptcha_area td, #recaptcha_area th {
padding: 0 !important;
}
{% endraw %}</style>{% endif %}

View file

@ -1,61 +1,61 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript">
{% if config.quick_reply %}
var new_reply_string = "{{ config.button_reply }}";
{% endif %}
{% if not no_post_form %}
var active_page = "index";
{% else %}
var active_page = "ukko";
{% endif %}
</script>
{% include 'header.html' %}
<title>{{ board.url }} - {{ board.title|e }}</title>
</head>
<body>
{{ boardlist.top }}
{% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr />{% endif %}
{% if config.url_banner %}<img class="banner" src="{{ config.url_banner }}" {% if config.banner_width or config.banner_height %}style="{% if config.banner_width %}width:{{ config.banner_width }}px{% endif %};{% if config.banner_width %}height:{{ config.banner_height }}px{% endif %}" {% endif %}alt="" />{% endif %}
<header>
<h1>{{ board.url }} - {{ board.title|e }}</h1>
<div class="subtitle">
{% if board.subtitle %}
{{ board.subtitle|e }}
{% endif %}
{% if mod %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %}
</div>
</header>
{% include 'attention_bar.html' %}
{% if not no_post_form %}
{% include 'post_form.html' %}
{% else %}
{% include 'boardlist.html' %}
{% endif %}
{% if config.blotter %}<hr /><div class="blotter">{{ config.blotter }}</div>{% endif %}
<hr />
<form name="postcontrols" action="{{ config.post_url }}" method="post">
<input type="hidden" name="board" value="{{ board.uri }}" />
{% if mod %}<input type="hidden" name="mod" value="1" />{% endif %}
{{ body }}
{% include 'report_delete.html' %}
</form>
<div class="pages">{{ btn.prev }} {% for page in pages %}
[<a {% if page.selected %}class="selected"{% endif %}{% if not page.selected %}href="{{ page.link }}"{% endif %}>{{ page.num }}</a>]{% if loop.last %} {% endif %}
{% endfor %} {{ btn.next }}</div>
{{ boardlist.bottom }}
<footer>
<p class="unimportant" style="margin-top:20px;text-align:center;">Powered by <a href="http://tinyboard.org/">Tinyboard</a> {{ config.version }} | <a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2013 Tinyboard Development Group</p>
{% for footer in config.footer %}<p class="unimportant" style="text-align:center;">{{ footer }}</p>{% endfor %}
</footer>
<script type="text/javascript">{% raw %}
ready();
{% endraw %}</script>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript">
{% if config.quick_reply %}
var new_reply_string = "{{ config.button_reply }}";
{% endif %}
{% if not no_post_form %}
var active_page = "index";
{% else %}
var active_page = "ukko";
{% endif %}
</script>
{% include 'header.html' %}
<title>{{ board.url }} - {{ board.title|e }}</title>
</head>
<body>
{{ boardlist.top }}
{% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr />{% endif %}
{% if config.url_banner %}<img class="banner" src="{{ config.url_banner }}" {% if config.banner_width or config.banner_height %}style="{% if config.banner_width %}width:{{ config.banner_width }}px{% endif %};{% if config.banner_width %}height:{{ config.banner_height }}px{% endif %}" {% endif %}alt="" />{% endif %}
<header>
<h1>{{ board.url }} - {{ board.title|e }}</h1>
<div class="subtitle">
{% if board.subtitle %}
{{ board.subtitle|e }}
{% endif %}
{% if mod %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %}
</div>
</header>
{% include 'attention_bar.html' %}
{% if not no_post_form %}
{% include 'post_form.html' %}
{% else %}
{% include 'boardlist.html' %}
{% endif %}
{% if config.global_message %}<hr /><div class="blotter">{{ config.global_message }}</div>{% endif %}
<hr />
<form name="postcontrols" action="{{ config.post_url }}" method="post">
<input type="hidden" name="board" value="{{ board.uri }}" />
{% if mod %}<input type="hidden" name="mod" value="1" />{% endif %}
{{ body }}
{% include 'report_delete.html' %}
</form>
<div class="pages">{{ btn.prev }} {% for page in pages %}
[<a {% if page.selected %}class="selected"{% endif %}{% if not page.selected %}href="{{ page.link }}"{% endif %}>{{ page.num }}</a>]{% if loop.last %} {% endif %}
{% endfor %} {{ btn.next }}</div>
{{ boardlist.bottom }}
<footer>
<p class="unimportant" style="margin-top:20px;text-align:center;">Powered by <a href="http://tinyboard.org/">Tinyboard</a> {{ config.version }} | <a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2013 Tinyboard Development Group</p>
{% for footer in config.footer %}<p class="unimportant" style="text-align:center;">{{ footer }}</p>{% endfor %}
</footer>
<script type="text/javascript">{% raw %}
ready();
{% endraw %}</script>
</body>
</html>

View file

@ -0,0 +1,54 @@
<div style="max-width:700px;margin:auto">
<h2 style="text-align:center">Pre-installation tests</h2>
<table class="modlog" style="margin-top:10px;max-width:600px">
<tr>
<th>Category</th>
<th>Test</th>
<th>Result</th>
</tr>
{% set errors = 0 %}
{% set warnings = 0 %}
{% for test in tests %}
<tr>
<td class="minimal"><strong>{{ test.category }}</strong></td>
<td>{{ test.name }}</td>
<td class="minimal" style="text-align:center">
{% if test.result %}
<i style="font-size:11pt;color:#090" class="icon-check-sign"></i>
{% else %}
{% if test.required %}
{% set errors = errors + 1 %}
<i style="font-size:11pt;color:#d00" class="icon-exclamation-sign"></i>
{% else %}
{% set warnings = warnings + 1 %}
<i style="font-size:11pt;color:#f80" class="icon-warning-sign"></i>
{% endif %}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% if errors or warnings %}
<p><strong>There were {{ errors }} error(s) and {{ warnings }} warning(s).</strong></p>
<ul>
{% for test in tests if not test.result%}
<li style="margin-bottom:5px">
{% if test.required %}
<i style="font-size:11pt;color:#d00" class="icon-exclamation-sign"></i> <strong>Error:</strong>
{% else %}
<i style="font-size:11pt;color:#f80" class="icon-warning-sign"></i> <strong>Warning:</strong>
{% endif %}
{{ test.message }}
</li>
{% endfor %}
</ul>
{% if errors %}
<p style="text-align:center"><a href="?step=2">Clik here to ignore errors and attempt installing anyway (not recommended).</a></p>
{% else %}
<p style="text-align:center"><a href="?step=2">Clik here to proceed with installation.</a></p>
{% endif %}
{% else %}
<p>There were no errors or warnings. Good!</p>
<p style="text-align:center"><a href="?step=2">Clik here to proceed with installation.</a></p>
{% endif %}
</div>

View file

@ -0,0 +1,95 @@
<form action="?step=3" method="post" autocomplete="off">
<fieldset>
<legend>Database (MySQL)</legend>
<label for="db_server">Server:</label>
<input type="text" id="db_server" name="db[server]" value="{{ config.db.server }}">
<label for="db_db">Database:</label>
<input type="text" id="db_db" name="db[database]" value="{{ config.db.database }}">
<label for="db_prefix">Table prefix (optional):</label>
<input type="text" id="db_prefix" name="db[prefix]" value="{{ config.db.prefix }}">
<label for="db_user">Username:</label>
<input type="text" id="db_user" name="db[user]" value="{{ config.db.user }}">
<label for="db_pass">Password:</label>
<input type="password" id="db_pass" name="db[password]" value="">
</fieldset>
<p style="text-align:center" class="unimportant">The following is all later configurable. For more options, <a href="http://tinyboard.org/docs/?p=Config">edit your configuration files</a> after installing.</p>
<fieldset>
<legend>Cookies</legend>
<label for="cookies_mod">Moderator cookie:</label>
<input type="text" id="cookies_mod" name="cookies[mod]" value="{{ config.cookies.mod }}">
<label for="cookies_salt">Secure salt:</label>
<input type="text" id="cookies_salt" name="cookies[salt]" value="{{ config.cookies.salt }}" size="40">
</fieldset>
<fieldset>
<legend>Flood control</legend>
<label for="flood_time">Seconds before each post:</label>
<input type="text" id="flood_time" name="flood_time" value="{{ config.flood_time }}">
<label for="flood_time_ip">Seconds before you can repost something (post the exact same text):</label>
<input type="text" id="flood_time_ip" name="flood_time_ip" value="{{ config.flood_time_ip }}">
<label for="flood_time_same">Same as above, but with a different IP address:</label>
<input type="text" id="flood_time_same" name="flood_time_same" value="{{ config.flood_time_same }}">
<label for="max_body">Maximum post body length:</label>
<input type="text" id="max_body" name="max_body" value="{{ config.max_body }}">
<label for="reply_limit">Replies in a thread before it can no longer be bumped:</label>
<input type="text" id="reply_limit" name="reply_limit" value="{{ config.reply_limit }}">
<label for="max_links">Maximum number of links in a single post:</label>
<input type="text" id="max_links" name="max_links" value="{{ config.max_links }}">
</fieldset>
<fieldset>
<legend>Images</legend>
<label for="max_filesize">Maximum image filesize (bytes):</label>
<input type="text" id="max_filesize" name="max_filesize" value="{{ config.max_filesize }}">
<label for="thumb_width">Thumbnail width:</label>
<input type="text" id="thumb_width" name="thumb_width" value="{{ config.thumb_width }}">
<label for="thumb_height">Thumbnail height:</label>
<input type="text" id="thumb_height" name="thumb_height" value="{{ config.thumb_height }}">
<label for="max_width">Maximum image width:</label>
<input type="text" id="max_width" name="max_width" value="{{ config.max_width }}">
<label for="max_height">Maximum image height:</label>
<input type="text" id="max_height" name="max_height" value="{{ config.max_height }}">
</fieldset>
<fieldset>
<legend>Display</legend>
<label for="threads_per_page">Threads per page:</label>
<input type="text" id="threads_per_page" name="threads_per_page" value="{{ config.threads_per_page }}">
<label for="max_pages">Page limit:</label>
<input type="text" id="max_pages" name="max_pages" value="{{ config.max_pages }}">
<label for="threads_preview">Number of replies to show per thread on the index page:</label>
<input type="text" id="threads_preview" name="threads_preview" value="{{ config.threads_preview }}">
</fieldset>
<fieldset>
<legend>Directories</legend>
<label for="root">Root URI (include trailing slash):</label>
<input type="text" id="root" name="root" value="{{ config.root }}" size="40">
</fieldset>
<fieldset>
<legend>Miscellaneous</legend>
<label for="secure_trip_salt">Secure trip (##) salt:</label>
<input type="text" id="secure_trip_salt" name="secure_trip_salt" value="{{ config.secure_trip_salt }}" size="40">
</fieldset>
<p style="text-align:center">
<input type="submit" value="Complete installation">
</p>
</form>

View file

@ -1,232 +1,271 @@
{% raw %}
/* gettext-compatible _ function, example of usage:
*
* > // Loading pl_PL.json here (containing polish translation strings generated by tools/i18n_compile.php)
* > alert(_("Hello!"));
* Witaj!
*/
function _(s) {
return (typeof l10n != 'undefined' && typeof l10n[s] != 'undefined') ? l10n[s] : s;
}
/* printf-like formatting function, example of usage:
*
* > alert(fmt("There are {0} birds on {1} trees", [3,4]));
* There are 3 birds on 4 trees
* > // Loading pl_PL.json here (containing polish translation strings generated by tools/locale_compile.php)
* > alert(fmt(_("{0} users"), [3]));
* 3 uzytkownikow
*/
function fmt(s,a) {
return s.replace(/\{([0-9]+)\}/g, function(x) { return a[x[1]]; });
}
var saved = {};
var selectedstyle = '{% endraw %}{{ config.default_stylesheet.0|addslashes }}{% raw %}';
var styles = {
{% endraw %}
{% for stylesheet in stylesheets %}{% raw %}'{% endraw %}{{ stylesheet.name|addslashes }}{% raw %}' : '{% endraw %}{{ stylesheet.uri|addslashes }}{% raw %}',
{% endraw %}{% endfor %}{% raw %}
};
function changeStyle(styleName, link) {
localStorage.stylesheet = styleName;
if (!document.getElementById('stylesheet')) {
var s = document.createElement('link');
s.rel = 'stylesheet';
s.type = 'text/css';
s.id = 'stylesheet';
var x = document.getElementsByTagName('head')[0];
x.appendChild(s);
}
document.getElementById('stylesheet').href = styles[styleName];
selectedstyle = styleName;
if (document.getElementsByClassName('styles').length != 0) {
var styleLinks = document.getElementsByClassName('styles')[0].childNodes;
for (i = 0; i < styleLinks.length; i++) {
styleLinks[i].className = '';
}
}
if (link) {
link.className = 'selected';
}
}
if (localStorage.stylesheet) {
for (styleName in styles) {
if (styleName == localStorage.stylesheet) {
changeStyle(styleName);
break;
}
}
}
function init_stylechooser() {
var newElement = document.createElement('div');
newElement.className = 'styles';
for (styleName in styles) {
var style = document.createElement('a');
style.innerHTML = '[' + styleName + ']';
style.onclick = function() {
changeStyle(this.innerHTML.substring(1, this.innerHTML.length - 1), this);
};
if (styleName == selectedstyle) {
style.className = 'selected';
}
style.href = 'javascript:void(0);';
newElement.appendChild(style);
}
document.getElementsByTagName('body')[0].insertBefore(newElement, document.getElementsByTagName('body')[0].lastChild.nextSibling);
}
function get_cookie(cookie_name) {
var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)');
if (results)
return (unescape(results[2]));
else
return null;
}
function highlightReply(id) {
if (typeof window.event != "undefined" && event.which == 2) {
// don't highlight on middle click
return true;
}
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++)
{
if (divs[i].className.indexOf('post') != -1)
divs[i].className = divs[i].className.replace(/highlighted/, '');
}
if (id) {
var post = document.getElementById('reply_'+id);
if (post)
post.className += ' highlighted';
}
}
function generatePassword() {
var pass = '';
var chars = '{% endraw %}{{ config.genpassword_chars }}{% raw %}';
for (var i = 0; i < 8; i++) {
var rnd = Math.floor(Math.random() * chars.length);
pass += chars.substring(rnd, rnd + 1);
}
return pass;
}
function dopost(form) {
if (form.elements['name']) {
localStorage.name = form.elements['name'].value.replace(/( |^)## .+$/, '');
}
if (form.elements['email'] && form.elements['email'].value != 'sage') {
localStorage.email = form.elements['email'].value;
}
saved[document.location] = form.elements['body'].value;
sessionStorage.body = JSON.stringify(saved);
return form.elements['body'].value != "" || form.elements['file'].value != "";
}
function citeReply(id) {
var body = document.getElementById('body');
if (document.selection) {
// IE
body.focus();
var sel = document.selection.createRange();
sel.text = '>>' + id + '\n';
} else if (body.selectionStart || body.selectionStart == '0') {
// Mozilla
var start = body.selectionStart;
var end = body.selectionEnd;
body.value = body.value.substring(0, start) + '>>' + id + '\n' + body.value.substring(end, body.value.length);
} else {
// ???
body.value += '>>' + id + '\n';
}
}
function rememberStuff() {
if (document.forms.post) {
if (document.forms.post.password) {
if (!localStorage.password)
localStorage.password = generatePassword();
document.forms.post.password.value = localStorage.password;
}
if (localStorage.name && document.forms.post.elements['name'])
document.forms.post.elements['name'].value = localStorage.name;
if (localStorage.email && document.forms.post.elements['email'])
document.forms.post.elements['email'].value = localStorage.email;
if (window.location.hash.indexOf('q') == 1)
citeReply(window.location.hash.substring(2));
if (sessionStorage.body) {
var saved = JSON.parse(sessionStorage.body);
if (get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}')) {
// Remove successful posts
var successful = JSON.parse(get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}'));
for (var url in successful) {
saved[url] = null;
}
sessionStorage.body = JSON.stringify(saved);
document.cookie = '{% endraw %}{{ config.cookies.js }}{% raw %}={};expires=0;path=/;';
}
if (saved[document.location]) {
document.forms.post.body.value = saved[document.location];
}
}
if (localStorage.body) {
document.forms.post.body.value = localStorage.body;
localStorage.body = '';
}
}
}
function init() {
init_stylechooser();
if (document.forms.postcontrols) {
document.forms.postcontrols.password.value = localStorage.password;
}
if (window.location.hash.indexOf('q') != 1 && window.location.hash.substring(1))
highlightReply(window.location.hash.substring(1));
}
var RecaptchaOptions = {
theme : 'clean'
};
onready_callbacks = [];
function onready(fnc) {
onready_callbacks.push(fnc);
}
function ready() {
for (var i = 0; i < onready_callbacks.length; i++) {
onready_callbacks[i]();
}
}
onready(init);
{% endraw %}{% if config.google_analytics %}{% raw %}
var _gaq = _gaq || [];_gaq.push(['_setAccount', '{% endraw %}{{ config.google_analytics }}{% raw %}']);{% endraw %}{% if config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', '{% endraw %}{{ config.google_analytics_domain }}{% raw %}']){% endraw %}{% endif %}{% if not config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', 'none']){% endraw %}{% endif %}{% raw %};_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();{% endraw %}{% endif %}
{% raw %}
/* gettext-compatible _ function, example of usage:
*
* > // Loading pl_PL.json here (containing polish translation strings generated by tools/i18n_compile.php)
* > alert(_("Hello!"));
* Witaj!
*/
function _(s) {
return (typeof l10n != 'undefined' && typeof l10n[s] != 'undefined') ? l10n[s] : s;
}
/* printf-like formatting function, example of usage:
*
* > alert(fmt("There are {0} birds on {1} trees", [3,4]));
* There are 3 birds on 4 trees
* > // Loading pl_PL.json here (containing polish translation strings generated by tools/locale_compile.php)
* > alert(fmt(_("{0} users"), [3]));
* 3 uzytkownikow
*/
function fmt(s,a) {
return s.replace(/\{([0-9]+)\}/g, function(x) { return a[x[1]]; });
}
var saved = {};
var selectedstyle = '{% endraw %}{{ config.default_stylesheet.0|addslashes }}{% raw %}';
var styles = {
{% endraw %}
{% for stylesheet in stylesheets %}{% raw %}'{% endraw %}{{ stylesheet.name|addslashes }}{% raw %}' : '{% endraw %}{{ stylesheet.uri|addslashes }}{% raw %}',
{% endraw %}{% endfor %}{% raw %}
};
var board_name = false;
function changeStyle(styleName, link) {
{% endraw %}
{% if config.stylesheets_board %}{% raw %}
if (board_name) {
stylesheet_choices[board_name] = styleName;
localStorage.board_stylesheets = JSON.stringify(stylesheet_choices);
}
{% endraw %}{% else %}
localStorage.stylesheet = styleName;
{% endif %}
{% raw %}
if (!document.getElementById('stylesheet')) {
var s = document.createElement('link');
s.rel = 'stylesheet';
s.type = 'text/css';
s.id = 'stylesheet';
var x = document.getElementsByTagName('head')[0];
x.appendChild(s);
}
document.getElementById('stylesheet').href = styles[styleName];
selectedstyle = styleName;
if (document.getElementsByClassName('styles').length != 0) {
var styleLinks = document.getElementsByClassName('styles')[0].childNodes;
for (var i = 0; i < styleLinks.length; i++) {
styleLinks[i].className = '';
}
}
if (link) {
link.className = 'selected';
}
}
{% endraw %}
{% if config.stylesheets_board %}
{# This is such an unacceptable mess. There needs to be an easier way. #}
var matches = document.URL.match(/\/(\w+)\/($|{{ config.dir.res|replace({'/': '\\/'}) }}{{ config.file_page|replace({'%d': '\\d+', '.': '\\.'}) }}|{{ config.file_index|replace({'.': '\\.'}) }}|{{ config.file_page|replace({'%d': '\\d+', '.': '\\.'}) }})/);
{% raw %}
if (matches) {
board_name = matches[1];
}
if (!localStorage.board_stylesheets) {
localStorage.board_stylesheets = '{}';
}
var stylesheet_choices = JSON.parse(localStorage.board_stylesheets);
if (board_name && stylesheet_choices[board_name]) {
for (var styleName in styles) {
if (styleName == stylesheet_choices[board_name]) {
changeStyle(styleName);
break;
}
}
}
{% endraw%}
{% else %}
{% raw %}
if (localStorage.stylesheet) {
for (var styleName in styles) {
if (styleName == localStorage.stylesheet) {
changeStyle(styleName);
break;
}
}
}
{% endraw %}
{% endif %}
{% raw %}
function init_stylechooser() {
var newElement = document.createElement('div');
newElement.className = 'styles';
for (styleName in styles) {
var style = document.createElement('a');
style.innerHTML = '[' + styleName + ']';
style.onclick = function() {
changeStyle(this.innerHTML.substring(1, this.innerHTML.length - 1), this);
};
if (styleName == selectedstyle) {
style.className = 'selected';
}
style.href = 'javascript:void(0);';
newElement.appendChild(style);
}
document.getElementsByTagName('body')[0].insertBefore(newElement, document.getElementsByTagName('body')[0].lastChild.nextSibling);
}
function get_cookie(cookie_name) {
var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)');
if (results)
return (unescape(results[2]));
else
return null;
}
function highlightReply(id) {
if (typeof window.event != "undefined" && event.which == 2) {
// don't highlight on middle click
return true;
}
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++)
{
if (divs[i].className.indexOf('post') != -1)
divs[i].className = divs[i].className.replace(/highlighted/, '');
}
if (id) {
var post = document.getElementById('reply_'+id);
if (post)
post.className += ' highlighted';
}
}
function generatePassword() {
var pass = '';
var chars = '{% endraw %}{{ config.genpassword_chars }}{% raw %}';
for (var i = 0; i < 8; i++) {
var rnd = Math.floor(Math.random() * chars.length);
pass += chars.substring(rnd, rnd + 1);
}
return pass;
}
function dopost(form) {
if (form.elements['name']) {
localStorage.name = form.elements['name'].value.replace(/( |^)## .+$/, '');
}
if (form.elements['email'] && form.elements['email'].value != 'sage') {
localStorage.email = form.elements['email'].value;
}
saved[document.location] = form.elements['body'].value;
sessionStorage.body = JSON.stringify(saved);
return form.elements['body'].value != "" || form.elements['file'].value != "";
}
function citeReply(id) {
var body = document.getElementById('body');
if (document.selection) {
// IE
body.focus();
var sel = document.selection.createRange();
sel.text = '>>' + id + '\n';
} else if (body.selectionStart || body.selectionStart == '0') {
// Mozilla
var start = body.selectionStart;
var end = body.selectionEnd;
body.value = body.value.substring(0, start) + '>>' + id + '\n' + body.value.substring(end, body.value.length);
} else {
// ???
body.value += '>>' + id + '\n';
}
}
function rememberStuff() {
if (document.forms.post) {
if (document.forms.post.password) {
if (!localStorage.password)
localStorage.password = generatePassword();
document.forms.post.password.value = localStorage.password;
}
if (localStorage.name && document.forms.post.elements['name'])
document.forms.post.elements['name'].value = localStorage.name;
if (localStorage.email && document.forms.post.elements['email'])
document.forms.post.elements['email'].value = localStorage.email;
if (window.location.hash.indexOf('q') == 1)
citeReply(window.location.hash.substring(2));
if (sessionStorage.body) {
var saved = JSON.parse(sessionStorage.body);
if (get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}')) {
// Remove successful posts
var successful = JSON.parse(get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}'));
for (var url in successful) {
saved[url] = null;
}
sessionStorage.body = JSON.stringify(saved);
document.cookie = '{% endraw %}{{ config.cookies.js }}{% raw %}={};expires=0;path=/;';
}
if (saved[document.location]) {
document.forms.post.body.value = saved[document.location];
}
}
if (localStorage.body) {
document.forms.post.body.value = localStorage.body;
localStorage.body = '';
}
}
}
function init() {
init_stylechooser();
if (document.forms.postcontrols) {
document.forms.postcontrols.password.value = localStorage.password;
}
if (window.location.hash.indexOf('q') != 1 && window.location.hash.substring(1))
highlightReply(window.location.hash.substring(1));
}
var RecaptchaOptions = {
theme : 'clean'
};
onready_callbacks = [];
function onready(fnc) {
onready_callbacks.push(fnc);
}
function ready() {
for (var i = 0; i < onready_callbacks.length; i++) {
onready_callbacks[i]();
}
}
onready(init);
{% endraw %}{% if config.google_analytics %}{% raw %}
var _gaq = _gaq || [];_gaq.push(['_setAccount', '{% endraw %}{{ config.google_analytics }}{% raw %}']);{% endraw %}{% if config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', '{% endraw %}{{ config.google_analytics_domain }}{% raw %}']){% endraw %}{% endif %}{% if not config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', 'none']){% endraw %}{% endif %}{% raw %};_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();{% endraw %}{% endif %}

View file

@ -41,11 +41,11 @@
<label for="reason">{% trans 'Message' %}</label>
</th>
<td>
<input type="checkbox" id="public_message" name="public_message">
<input type="checkbox" id="public_message" name="public_message"{% if config.mod.check_ban_message %} checked{% endif %}>
<input type="text" name="message" id="message" size="35" maxlength="200" value="{{ config.mod.default_ban_message|e }}">
<span class="unimportant">({% trans 'public; attached to post' %})</span>
<script type="text/javascript">
document.getElementById('message').disabled = true;
document.getElementById('message').disabled = !document.getElementById('public_message').checked;
document.getElementById('public_message').onchange = function() {
document.getElementById('message').disabled = !this.checked;
}

View file

@ -0,0 +1,63 @@
<div style="max-width:800px;margin:auto">
<p>
Any changes you make here will simply be appended to <code>{{ file }}</code>. If you wish to make the most of Tinyboard's customizability, you can instead edit the file directly. This page is intended for making quick changes and for those who don't have a basic understanding of PHP code.
</p>
{% if boards|count %}
<ul>
{% if board %}
<li><a href="?/config">Edit site-wide config</a></li>
{% endif %}
{% for _board in boards if _board.uri != board %}
<li>
<a href="?/config/{{ _board.uri }}">Edit config for {{ config.board_abbreviation|sprintf(_board.uri) }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
{% if readonly %}
<p>Tinyboard does not have the required permissions to edit <code>{{ file }}</code>. To make changes, you will need to change the file's permissions first or manually edit the code.</p>
{% endif %}
{% if not readonly %}<form method="post" action="">{% endif %}
<textarea name="code" id="code" style="margin:auto;width:100%;height:500px{% if readonly %};background:#eee" readonly{% else %}"{% endif %}>
{{ php }}
</textarea>
<ul style="padding:0;text-align:center;list-style:none">
<li><input name="save" type="submit" value="{% trans 'Save changes' %}"{% if readonly %} disabled{% endif %}></li>
</ul>
{% if not readonly %}</form>{% endif %}
</div>
<script type="text/javascript">
var observe;
if (window.attachEvent) {
observe = function (element, event, handler) {
element.attachEvent('on'+event, handler);
};
}
else {
observe = function (element, event, handler) {
element.addEventListener(event, handler, false);
};
}
var text = document.getElementById('code');
function resize () {
text.style.height = 'auto';
text.style.height = text.scrollHeight+'px';
}
/* 0-timeout to get the already changed text */
function delayedResize () {
window.setTimeout(resize, 0);
}
observe(text, 'change', resize);
observe(text, 'cut', delayedResize);
observe(text, 'paste', delayedResize);
observe(text, 'drop', delayedResize);
observe(text, 'keydown', delayedResize);
resize();
</script>

View file

@ -1,10 +1,25 @@
<p>
Any changes you make here will simply be appended to <code>{{ file }}</code>. If you wish to make the most of Tinyboard's customizability, you can instead edit the file directly. This page is intended for making quick changes and for those who don't have a basic understanding of PHP code.
</p>
{% if boards|count %}
<ul>
{% if board %}
<li><a href="?/config">Edit site-wide config</a></li>
{% endif %}
{% for _board in boards if _board.uri != board %}
<li>
<a href="?/config/{{ _board.uri }}">Edit config for {{ config.board_abbreviation|sprintf(_board.uri) }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
<form method="post" action="">
<table class="mod config-editor">
<tr>
<th class="minimal">Name</th>
<th>Value</th>
<th class="minimal">Type</th>
<th>Description</th>
<th class="minimal">{% trans 'Name' %}</th>
<th>{% trans 'Value' %}</th>
<th class="minimal">{% trans 'Type' %}</th>
<th>{% trans 'Description' %}</th>
</tr>
{% for var in conf if var.type != 'array' %}
{% if var.name|count == 1 %}
@ -25,6 +40,13 @@
<td>
{% if var.type == 'string' %}
<input name="{{ name }}" type="text" value="{{ var.value|e }}">
{% elseif var.permissions %}
<select name="{{ name }}">
<option value="{{ constant('JANITOR') }}"{% if var.value == constant('JANITOR')%} selected{% endif %}>JANITOR</option>
<option value="{{ constant('MOD') }}"{% if var.value == constant('MOD')%} selected{% endif %}>MOD</option>
<option value="{{ constant('ADMIN') }}"{% if var.value == constant('ADMIN')%} selected{% endif %}>ADMIN</option>
<option value="{{ constant('DISABLED') }}"{% if var.value == constant('DISABLED')%} selected{% endif %}>DISABLED</option>
</select>
{% elseif var.type == 'integer' %}
<input name="{{ name }}" type="number" value="{{ var.value|e }}">
{% elseif var.type == 'boolean' %}
@ -42,8 +64,8 @@
{{ var.type|e }}
</td>
<td>
{{ var.comment|join('<br>') }}
<td style="word-wrap:break-word;width:50%">
{{ var.comment|join(' ') }}
</td>
</tr>
{% endfor %}

View file

@ -94,7 +94,7 @@
{% if mod|hasPermission(config.mod.rebuild) %}
<li><a href="?/rebuild">{% trans 'Rebuild' %}</a></li>
{% endif %}
{% if mod|hasPermission(config.mod.show_config) %}
{% if mod|hasPermission(config.mod.edit_config) %}
<li><a href="?/config">{% trans 'Configuration' %}</a></li>
{% endif %}
@ -102,17 +102,29 @@
</fieldset>
{% if mod|hasPermission(config.mod.search) %}
<fieldset>
<legend>{% trans 'Search' %}</legend>
<ul>
<li>
{% include 'mod/search_form.html' %}
</li>
</ul>
</fieldset>
<fieldset>
<legend>{% trans 'Search' %}</legend>
<ul>
<li>
{% include 'mod/search_form.html' %}
</li>
</ul>
</fieldset>
{% endif %}
{% if config.mod.dashboard_links|count %}
<fieldset>
<legend>{% trans 'Other' %}</legend>
<ul>
{% for label,link in config.mod.dashboard_links %}
<li><a href="{{ link }}">{{ label }}</a></li>
{% endfor %}
</ul>
</fieldset>
{% endif %}
{% if config.debug %}
<fieldset>
<legend>{% trans 'Debug' %}</legend>

View file

@ -1,4 +1,4 @@
<table class="modlog">
<table class="modlog" style="word-wrap: break-word;">
<tr>
<th>Time</th>
<th>Board</th>
@ -24,7 +24,7 @@
{% else %}
{% set thread = post.id %}
{% endif %}
<a href="{{ config.root ~ post.board ~ '/' ~ config.dir.res}}{{ config.file_page|sprintf(thread) }}#{{ post.id }}">
<a href="?/{{ post.board ~ '/' ~ config.dir.res}}{{ config.file_page|sprintf(thread) }}#{{ post.id }}">
{{ post.id }}
</a>
</td>

View file

@ -32,7 +32,7 @@
{% trans %}Comment{% endtrans %}
</th>
<td>
<textarea name="body" id="body" rows="8" cols="35">{% if raw %}{{ post.body | e }}{% else %}{{ post.body_nomarkup }}{% endif %}</textarea>
<textarea name="body" id="body" rows="8" cols="35">{% if raw %}{{ post.body }}{% else %}{{ post.body_nomarkup }}{% endif %}</textarea>
</td>
</tr>
</table>

View file

@ -18,7 +18,11 @@
{% endif %}
</td>
<td class="minimal">
<a href="?/IP/{{ log.ip }}">{{ log.ip }}</a>
{% if mod|hasPermission(config.mod.show_ip_modlog) %}
<a href="?/IP/{{ log.ip }}">{{ log.ip }}</a>
{% else %}
<em>hidden</em>
{% endif %}
</td>
<td class="minimal">
<span title="{{ log.time|date(config.post_date) }}">{{ log.time|ago }}</span>

View file

@ -1,26 +1,26 @@
{% if error %}<h2 style="text-align:center">{{ error }}</h2>{% endif %}
<form action="" method="post">
<table style="margin-top:25px;">
<tr>
<th>
{% trans 'Username' %}
</th>
<td>
<input type="text" name="username" size="20" maxlength="30" value="{{ username|e }}">
</td>
</tr>
<tr>
<th>
{% trans 'Password' %}
</th>
<td>
<input type="password" name="password" size="20" maxlength="30" value="">
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" name="login" value="{% trans %}Continue{% endtrans %}" />
</td>
</table>
</form>
{% if error %}<h2 style="text-align:center">{{ error }}</h2>{% endif %}
<form action="" method="post">
<table style="margin-top:25px;">
<tr>
<th>
{% trans 'Username' %}
</th>
<td>
<input type="text" name="username" size="20" maxlength="30" value="{{ username|e }}">
</td>
</tr>
<tr>
<th>
{% trans 'Password' %}
</th>
<td>
<input type="password" name="password" size="20" maxlength="30" value="">
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" name="login" value="{% trans %}Continue{% endtrans %}" />
</td>
</table>
</form>

View file

@ -52,7 +52,7 @@
<em>{% trans 'no subject' %}</em>
{% endif %}
<small class="unimportant">
&mdash; {% trans 'by' %} {{ post.name }} {% trans 'at' %} {{ notice.time|date(config.post_date) }}
&mdash; {% trans 'by' %} {{ post.name }} {% trans 'at' %} {{ post.time|date(config.post_date) }}
</small>
</h2>
<p>

View file

@ -39,7 +39,7 @@
</tr>
{% endfor %}
</table>
{% endif %}
{% endif %}
{% if search_type == 'bans' %}
<table class="modlog" style="width:100%">
@ -125,7 +125,7 @@
</tr>
{% endfor %}
</table>
{% endif %}
{% endif %}
{% if search_type == 'log' %}
<table class="modlog">
@ -166,7 +166,98 @@
</tr>
{% endfor %}
</table>
{% endif %}
{% endif %}
{% if search_type == 'posts' %}
<table class="modlog" style="word-wrap: break-word;">
<tr>
<th>Time</th>
<th>Board</th>
<th>ID</th>
<th>Thread</th>
<th>IP</th>
<th>Name</th>
<th>Subject</th>
<th>File</th>
<th>Body (snippet)</th>
</tr>
{% for post in results %}
<tr>
<td class="minimal">
<small>{{ post.time | ago }} ago</small>
</td>
<td class="minimal">
<a href="?/{{ config.board_path|sprintf(post.board) }}{{ config.file_index }}">{{ config.board_abbreviation|sprintf(post.board) }}</a>
</td>
<td class="minimal">
{% if post.thread %}
{% set thread = post.thread %}
{% else %}
{% set thread = post.id %}
{% endif %}
<a href="?/{{ post.board ~ '/' ~ config.dir.res}}{{ config.file_page|sprintf(thread) }}#{{ post.id }}">
{{ post.id }}
</a>
</td>
<td class="minimal">
<small>
{% if post.thread %}
{{ post.thread }}
{% else %}
(OP)
{% endif %}
</small>
</td>
<td class="minimal">
{% if mod|hasPermission(config.mod.show_ip, post.board) %}
<a href="?/IP/{{ post.ip }}">
{{ post.ip }}
</a>
{% else %}
<em>hidden</em>
{% endif %}
</td>
<td style="max-width:100px">
<small>
{% if post.email|length > 0 %}
{# start email #}
<a class="email" href="mailto:{{ post.email }}">
{% endif %}
{% set capcode = post.capcode|capcode %}
<span {% if capcode.name %}style="{{ capcode.name }}" {% endif %}class="name">{{ post.name }}</span>
{% if post.trip|length > 0 %}
<span {% if capcode.trip %}style="{{ capcode.trip }}" {% endif %}class="trip">{{ post.trip }}</span>
{% endif %}
{% if post.email|length > 0 %}
{# end email #}
</a>
{% endif %}
{% if capcode %}
{{ capcode.cap }}
{% endif %}
</small>
</td>
<td style="max-width:250px">
{% if post.subject %}
<small>{{ post.subject }}</small>
{% else %}
&ndash;
{% endif %}
</td>
<td style="max-width:200px">
{% if post.file %}
<small>{{ post.filename }} ({{ post.filesize | filesize }})</small>
{% else %}
&ndash;
{% endif %}
</td>
<td>
<small><em>{{ post.snippet }}</em></small>
</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% if result_count > results|count %}
<p class="unimportant" style="text-align:center;word-wrap:break-word">

View file

@ -1,25 +1,25 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
{% include 'header.html' %}
<title>{{ title }}</title>
</head>
<body>
{% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr>{% endif %}
<header>
<h1>{{ title }}</h1>
<div class="subtitle">
{% if subtitle %}
{{ subtitle }}
{% endif %}
{% if mod and not hide_dashboard_link %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %}
</div>
</header>
{{ body }}
<hr>
<footer>
<p class="unimportant" style="margin-top:20px;text-align:center;">Powered by <a href="http://tinyboard.org/">Tinyboard</a> {{ config.version }} | <a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2013 Tinyboard Development Group</p>
</footer>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
{% include 'header.html' %}
<title>{{ title }}</title>
</head>
<body>
{% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr>{% endif %}
<header>
<h1>{{ title }}</h1>
<div class="subtitle">
{% if subtitle %}
{{ subtitle }}
{% endif %}
{% if mod and not hide_dashboard_link %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %}
</div>
</header>
{{ body }}
<hr>
<footer>
<p class="unimportant" style="margin-top:20px;text-align:center;">Powered by <a href="http://tinyboard.org/">Tinyboard</a> {{ config.version }} | <a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2013 Tinyboard Development Group</p>
</footer>
</body>
</html>

View file

@ -4,6 +4,9 @@
{{ antibot.html() }}
<input type="hidden" name="board" value="{{ board.uri }}">
{{ antibot.html() }}
{% if current_page %}
<input type="hidden" name="page" value="{{ current_page }}">
{% endif %}
{% if mod %}<input type="hidden" name="mod" value="1">{% endif %}
<table>
{% if not config.field_disable_name or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri)) %}<tr>
@ -67,21 +70,6 @@
</td>
</tr>
{% endif %}
{% if config.imgcaptcha %}
<tr>
<th>
{% trans %}Verification{% endtrans %}
{{ antibot.html() }}
</th>
<td>
<input type="hidden" name="imgcaptcha_hash" id="imgcaptcha_hash" value="kucaj stad, kucu hakierze">
<img src="{{ config.imgcaptcha_filler }}" width="{{ config.imgcaptcha_width }}px" height="{{ config.imgcaptcha_height }}px" id="imgcaptcha_img"></img><br>
{{ config.imgcaptcha_question }} <input type="text" name="imgcaptcha_verify" id="imgcaptcha_verify" value=""></input><br>
<a href="javascript:ic_odswiezKapcze()">Odswiez</a>
{{ antibot.html() }}
</td>
</tr>
{% endif %}
<tr>
<th>
{% trans %}File{% endtrans %}
@ -103,7 +91,7 @@
</td>
</tr>
{% endif %}
{% if mod %}
{% if mod and ((not id and post.mod|hasPermission(config.mod.sticky, board.uri)) or (not id and post.mod|hasPermission(config.mod.lock, board.uri)) or post.mod|hasPermission(config.mod.rawhtml, board.uri)) %}
<tr>
<th>
{% trans %}Flags{% endtrans %}

View file

@ -1,111 +1,111 @@
{% filter remove_whitespace %}
{# tabs and new lines will be ignored #}
<div class="post reply" id="reply_{{ post.id }}">
<p class="intro"{% if not index %} id="{{ post.id }}"{% endif %}>
<input type="checkbox" class="delete" name="delete_{{ post.id }}" id="delete_{{ post.id }}" />
<label for="delete_{{ post.id }}">
{% if post.subject|length > 0 %}
{# show subject #}
<span class="subject">{{ post.subject|bidi_cleanup }}</span>
{% endif %}
{% if post.email|length > 0 %}
{# start email #}
<a class="email" href="mailto:{{ post.email }}">
{% endif %}
{% set capcode = post.capcode|capcode %}
<span {% if capcode.name %}style="{{ capcode.name }}" {% endif %}class="name">{{ post.name|bidi_cleanup }}</span>
{% if post.trip|length > 0 %}
<span {% if capcode.trip %}style="{{ capcode.trip }}" {% endif %}class="trip">{{ post.trip }}</span>
{% endif %}
{% if post.email|length > 0 %}
{# end email #}
</a>
{% endif %}
{% if capcode %}
{{ capcode.cap }}
{% endif %}
{% if post.mod and post.mod|hasPermission(config.mod.show_ip, board.uri) %}
[<a style="margin:0;" href="?/IP/{{ post.ip }}">{{ post.ip }}</a>]
{% endif %}
<time datetime="{{ post.time|date('%Y-%m-%dT%H:%M:%S') }}{{ timezone() }}">{{ post.time|date(config.post_date) }}</time>
</label>
{% if config.poster_ids %}
ID: {{ post.ip|poster_id(post.thread) }}
{% endif %}
<a class="post_no" {% if not index %}onclick="highlightReply({{ post.id }})" {% endif %}href="{{ post.link }}">No.</a>
<a class="post_no"
{% if not index %}
onclick="citeReply({{ post.id }});"
{% endif %}
href="{% if index %}
{{ post.link('q') }}
{% else %}
javascript:void(0);
{% endif %}">
{{ post.id }}
</a>
</p>
{% if post.embed %}
{{ post.embed }}
{% elseif post.file == 'deleted' %}
<img src="{{ config.image_deleted }}" alt="" />
{% elseif post.file and post.file %}
<p class="fileinfo">File: <a href="{{ config.uri_img }}{{ post.file }}">{{ post.file }}</a> <span class="unimportant">
(
{% if post.thumb == 'spoiler' %}
Spoiler Image,
{% endif %}
{{ post.filesize|filesize }}
{% if post.filex and post.filey %}
, {{ post.filex}}x{{ post.filey }}
{% if config.show_ratio %}
, {{ post.ratio }}
{% endif %}
{% endif %}
{% if config.show_filename and post.filename %}
,
{% if post.filename|length > config.max_filename_display %}
<span class="postfilename" title="{{ post.filename|bidi_cleanup }}">{{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }}</span>
{% else %}
<span class="postfilename">{{ post.filename|bidi_cleanup }}</span>
{% endif %}
{% endif %}
{% if post.thumb != 'file' and config.image_identification %}
,
<span class='image_id'>
<a href="http://imgops.com/{{ config.domain }}{{ config.uri_img }}{{ post.file }}">io</a>
{% if post.file|extension == 'jpg' %}
<a href="http://regex.info/exif.cgi?url={{ config.domain }}{{ config.uri_img }}{{ post.file }}">e</a>
{% endif %}
<a href="http://www.google.com/searchbyimage?image_url={{ config.domain }}{{ config.uri_img }}{{ post.file }}">g</a>
<a href="http://www.tineye.com/search?url={{ config.domain }}{{ config.uri_img }}{{ post.file }}">t</a>
</span>
{% endif %}
)
</span>
</p>
<a href="{{ config.uri_img }}{{ post.file }}" target="_blank"{% if post.thumb == 'file' %} class="file"{% endif %}>
<img src="
{% if post.thumb == 'file' %}
{{ config.root }}
{% if config.file_icons[post.filename|extension] %}
{{ config.file_thumb|sprintf(config.file_icons[post.filename|extension]) }}
{% else %}
{{ config.file_thumb|sprintf(config.file_icons.default) }}
{% endif %}
{% elseif post.thumb == 'spoiler' %}
{{ config.root }}{{ config.spoiler_image }}
{% else %}
{{ config.uri_thumb }}{{ post.thumb }}
{% endif %}" style="width:{{ post.thumbx }}px;height:{{ post.thumby }}px" alt="" />
</a>
{% endif %}
{{ post.postControls }}
<div class="body">
{% endfilter %}{% if index %}{{ post.body|truncate_body(post.link) }}{% else %}{{ post.body }}{% endif %}{% filter remove_whitespace %}
</div>
</div>
<br/>
{% endfilter %}
{% filter remove_whitespace %}
{# tabs and new lines will be ignored #}
<div class="post reply" id="reply_{{ post.id }}">
<p class="intro"{% if not index %} id="{{ post.id }}"{% endif %}>
<input type="checkbox" class="delete" name="delete_{{ post.id }}" id="delete_{{ post.id }}" />
<label for="delete_{{ post.id }}">
{% if post.subject|length > 0 %}
{# show subject #}
<span class="subject">{{ post.subject|bidi_cleanup }}</span>
{% endif %}
{% if post.email|length > 0 %}
{# start email #}
<a class="email" href="mailto:{{ post.email }}">
{% endif %}
{% set capcode = post.capcode|capcode %}
<span {% if capcode.name %}style="{{ capcode.name }}" {% endif %}class="name">{{ post.name|bidi_cleanup }}</span>
{% if post.trip|length > 0 %}
<span {% if capcode.trip %}style="{{ capcode.trip }}" {% endif %}class="trip">{{ post.trip }}</span>
{% endif %}
{% if post.email|length > 0 %}
{# end email #}
</a>
{% endif %}
{% if capcode %}
{{ capcode.cap }}
{% endif %}
{% if post.mod and post.mod|hasPermission(config.mod.show_ip, board.uri) %}
[<a style="margin:0;" href="?/IP/{{ post.ip }}">{{ post.ip }}</a>]
{% endif %}
<time datetime="{{ post.time|date('%Y-%m-%dT%H:%M:%S') }}{{ timezone() }}">{{ post.time|date(config.post_date) }}</time>
</label>
{% if config.poster_ids %}
ID: {{ post.ip|poster_id(post.thread) }}
{% endif %}
<a class="post_no" {% if not index %}onclick="highlightReply({{ post.id }})" {% endif %}href="{{ post.link }}">No.</a>
<a class="post_no"
{% if not index %}
onclick="citeReply({{ post.id }});"
{% endif %}
href="{% if index %}
{{ post.link('q') }}
{% else %}
javascript:void(0);
{% endif %}">
{{ post.id }}
</a>
</p>
{% if post.embed %}
{{ post.embed }}
{% elseif post.file == 'deleted' %}
<img src="{{ config.image_deleted }}" alt="" />
{% elseif post.file and post.file %}
<p class="fileinfo">File: <a href="{{ config.uri_img }}{{ post.file }}">{{ post.file }}</a> <span class="unimportant">
(
{% if post.thumb == 'spoiler' %}
Spoiler Image,
{% endif %}
{{ post.filesize|filesize }}
{% if post.filex and post.filey %}
, {{ post.filex}}x{{ post.filey }}
{% if config.show_ratio %}
, {{ post.ratio }}
{% endif %}
{% endif %}
{% if config.show_filename and post.filename %}
,
{% if post.filename|length > config.max_filename_display %}
<span class="postfilename" title="{{ post.filename|e|bidi_cleanup }}">{{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }}</span>
{% else %}
<span class="postfilename">{{ post.filename|e|bidi_cleanup }}</span>
{% endif %}
{% endif %}
{% if post.thumb != 'file' and config.image_identification %}
,
<span class='image_id'>
<a href="http://imgops.com/{{ config.domain }}{{ config.uri_img }}{{ post.file }}">io</a>
{% if post.file|extension == 'jpg' %}
<a href="http://regex.info/exif.cgi?url={{ config.domain }}{{ config.uri_img }}{{ post.file }}">e</a>
{% endif %}
<a href="http://www.google.com/searchbyimage?image_url={{ config.domain }}{{ config.uri_img }}{{ post.file }}">g</a>
<a href="http://www.tineye.com/search?url={{ config.domain }}{{ config.uri_img }}{{ post.file }}">t</a>
</span>
{% endif %}
)
</span>
</p>
<a href="{{ config.uri_img }}{{ post.file }}" target="_blank"{% if post.thumb == 'file' %} class="file"{% endif %}>
<img src="
{% if post.thumb == 'file' %}
{{ config.root }}
{% if config.file_icons[post.filename|extension] %}
{{ config.file_thumb|sprintf(config.file_icons[post.filename|extension]) }}
{% else %}
{{ config.file_thumb|sprintf(config.file_icons.default) }}
{% endif %}
{% elseif post.thumb == 'spoiler' %}
{{ config.root }}{{ config.spoiler_image }}
{% else %}
{{ config.uri_thumb }}{{ post.thumb }}
{% endif %}" style="width:{{ post.thumbx }}px;height:{{ post.thumby }}px" alt="" />
</a>
{% endif %}
{{ post.postControls }}
<div class="body">
{% endfilter %}{% if index %}{{ post.body|truncate_body(post.link) }}{% else %}{{ post.body }}{% endif %}{% filter remove_whitespace %}
</div>
</div>
<br/>
{% endfilter %}

View file

@ -23,9 +23,9 @@
{% if config.show_filename and post.filename %}
,
{% if post.filename|length > config.max_filename_display %}
<span class="postfilename" title="{{ post.filename|bidi_cleanup }}">{{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }}</span>
<span class="postfilename" title="{{ post.filename|e|bidi_cleanup }}">{{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }}</span>
{% else %}
<span class="postfilename">{{ post.filename|bidi_cleanup }}</span>
<span class="postfilename">{{ post.filename|e|bidi_cleanup }}</span>
{% endif %}
{% endif %}
{% if post.thumb != 'file' and config.image_identification %}
@ -100,13 +100,25 @@
{{ post.id }}
</a>
{% if post.sticky %}
<img class="icon" title="Sticky" src="{{ config.image_sticky }}" alt="Sticky" />
{% if config.font_awesome %}
<i class="icon-pushpin icon"></i>
{% else %}
<img class="icon" title="Sticky" src="{{ config.image_sticky }}" alt="Sticky" />
{% endif %}
{% endif %}
{% if post.locked %}
<img class="icon" title="Locked" src="{{ config.image_locked }}" alt="Locked" />
{% if config.font_awesome %}
<i class="icon-lock icon"></i>
{% else %}
<img class="icon" title="Locked" src="{{ config.image_locked }}" alt="Locked" />
{% endif %}
{% endif %}
{% if post.bumplocked and (config.mod.view_bumplock < 0 or (post.mod and post.mod|hasPermission(config.mod.view_bumplock, board.uri))) %}
<img class="icon" title="Bumplocked" src="{{ config.image_bumplocked }}" alt="Bumplocked" />
{% if config.font_awesome %}
<i class="icon-anchor icon"></i>
{% else %}
<img class="icon" title="Bumplocked" src="{{ config.image_bumplocked }}" alt="Bumplocked" />
{% endif %}
{% endif %}
{% if index %}
<a href="{{ post.root }}{{ board.dir }}{{ config.dir.res }}{{ config.file_page|sprintf(post.id) }}">[{% trans %}Reply{% endtrans %}]</a>
@ -145,4 +157,4 @@
{% include 'post_reply.html' %}
{% endfor %}
<br class="clear"/>{% if hr %}<hr/>{% endif %}
</div>
</div>

View file

@ -1,32 +1,33 @@
CREATE TABLE IF NOT EXISTS `posts_{{ board }}` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`thread` int(11) DEFAULT NULL,
`subject` varchar(100) DEFAULT NULL,
`email` varchar(30) DEFAULT NULL,
`name` varchar(35) DEFAULT NULL,
`trip` varchar(15) DEFAULT NULL,
`capcode` varchar(50) DEFAULT NULL,
`body` text NOT NULL,
`body_nomarkup` text DEFAULT NULL,
`time` int(11) NOT NULL,
`bump` int(11) DEFAULT NULL,
`thumb` varchar(50) DEFAULT NULL,
`thumbwidth` int(11) DEFAULT NULL,
`thumbheight` int(11) DEFAULT NULL,
`file` varchar(50) DEFAULT NULL,
`filewidth` int(11) DEFAULT NULL,
`fileheight` int(11) DEFAULT NULL,
`filesize` int(11) DEFAULT NULL,
`filename` text DEFAULT NULL,
`filehash` text DEFAULT NULL,
`password` varchar(20) DEFAULT NULL,
`ip` varchar(45) NOT NULL,
`sticky` int(1) NOT NULL,
`locked` int(1) NOT NULL,
`sage` int(1) NOT NULL,
`embed` text,
UNIQUE KEY `id` (`id`),
KEY `thread_id` (`thread`, `id`),
KEY `time` (`time`),
FULLTEXT KEY `body` (`body`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS ``posts_{{ board }}`` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`thread` int(11) DEFAULT NULL,
`subject` varchar(100) DEFAULT NULL,
`email` varchar(30) DEFAULT NULL,
`name` varchar(35) DEFAULT NULL,
`trip` varchar(15) DEFAULT NULL,
`capcode` varchar(50) DEFAULT NULL,
`body` text NOT NULL,
`body_nomarkup` text,
`time` int(11) NOT NULL,
`bump` int(11) DEFAULT NULL,
`thumb` varchar(50) DEFAULT NULL,
`thumbwidth` int(11) DEFAULT NULL,
`thumbheight` int(11) DEFAULT NULL,
`file` varchar(50) DEFAULT NULL,
`filewidth` int(11) DEFAULT NULL,
`fileheight` int(11) DEFAULT NULL,
`filesize` int(11) DEFAULT NULL,
`filename` text,
`filehash` text CHARACTER SET ascii,
`password` varchar(20) DEFAULT NULL,
`ip` varchar(39) CHARACTER SET ascii NOT NULL,
`sticky` int(1) NOT NULL,
`locked` int(1) NOT NULL,
`sage` int(1) NOT NULL,
`embed` text,
UNIQUE KEY `id` (`id`),
KEY `thread_id` (`thread`,`id`),
KEY `time` (`time`),
FULLTEXT KEY `body` (`body`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;

View file

@ -25,7 +25,7 @@
$settings['no_recent'] = (int) $settings['no_recent'];
$query = query("SELECT * FROM `news` ORDER BY `time` DESC" . ($settings['no_recent'] ? ' LIMIT ' . $settings['no_recent'] : '')) or error(db_error());
$query = query("SELECT * FROM ``news`` ORDER BY `time` DESC" . ($settings['no_recent'] ? ' LIMIT ' . $settings['no_recent'] : '')) or error(db_error());
$news = $query->fetchAll(PDO::FETCH_ASSOC);
return Element('themes/basic/index.html', Array(

View file

@ -37,9 +37,9 @@
$recent_posts = array();
$stats = array();
$query = query(sprintf("SELECT *, `id` AS `thread_id`, (SELECT COUNT(*) FROM `posts_%s` WHERE `thread` = `thread_id`) AS `reply_count`, '%s' AS `board` FROM `posts_%s` WHERE `thread` IS NULL ORDER BY `bump` DESC", $board_name, $board_name, $board_name)) or error(db_error());
$query = query(sprintf("SELECT *, `id` AS `thread_id`, (SELECT COUNT(*) FROM ``posts_%s`` WHERE `thread` = `thread_id`) AS `reply_count`, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL ORDER BY `bump` DESC", $board_name, $board_name, $board_name)) or error(db_error());
while ($post = $query->fetch()) {
while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
$post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ? $post['thread'] : $post['id']));
$post['board_name'] = $board['name'];
$post['file'] = $config['uri_thumb'] . $post['thumb'];

View file

@ -7,7 +7,7 @@
<link rel="stylesheet" media="screen" href="{{ config.url_stylesheet }}"/>
</head>
<body>
<h1>{{ settings.title }}</h1>
{{ boardlist.top }}
<header>
<h1>{{ settings.title }}</h1>
<div class="subtitle">{{ settings.subtitle }}</div>
@ -15,16 +15,16 @@
<div class="ban">
{% if news|count == 0 %}
<p style="text-align:center" class="unimportant">(No news to show.)</p>
<p style="text-align:center" class="unimportant">{% trans %}(No news to show.){% endtrans %}</p>
{% else %}
{% for entry in news %}
<h2 id="{{ entry.id }}">
{% if entry.subject %}
{{ entry.subject }}
{% else %}
<em>no subject</em>
<em>{% trans %}no subject{% endtrans %}</em>
{% endif %}
<span class="unimportant"> &mdash; by {{ entry.name }} at {{ entry.time|date(config.post_date) }}</span>
<span class="unimportant"> &mdash; {% trans %}by{% endtrans %} {{ entry.name }} {% trans %}at{% endtrans %} {{ entry.time|date(config.post_date) }}</span>
</h2>
<p>{{ entry.body }}</p>
{% endfor %}

View file

@ -36,7 +36,7 @@
public static function news($settings) {
global $config;
$query = query("SELECT * FROM `news` ORDER BY `time` DESC") or error(db_error());
$query = query("SELECT * FROM ``news`` ORDER BY `time` DESC") or error(db_error());
$news = $query->fetchAll(PDO::FETCH_ASSOC);
return Element('themes/categories/news.html', Array(

View file

@ -36,7 +36,7 @@
public static function news($settings) {
global $config;
$query = query("SELECT * FROM `news` ORDER BY `time` DESC") or error(db_error());
$query = query("SELECT * FROM ``news`` ORDER BY `time` DESC") or error(db_error());
$news = $query->fetchAll(PDO::FETCH_ASSOC);
return Element('themes/frameset/news.html', Array(

View file

@ -42,12 +42,12 @@
foreach ($boards as &$_board) {
if (in_array($_board['uri'], $this->excluded))
continue;
$query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` WHERE `file` IS NOT NULL AND `file` != 'deleted' AND `thumb` != 'spoiler' UNION ALL ", $_board['uri'], $_board['uri']);
$query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `file` IS NOT NULL AND `file` != 'deleted' AND `thumb` != 'spoiler' UNION ALL ", $_board['uri'], $_board['uri']);
}
$query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int)$settings['limit_images'], $query);
$query = query($query) or error(db_error());
while ($post = $query->fetch()) {
while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
openBoard($post['board']);
// board settings won't be available in the template file, so generate links now
@ -62,12 +62,12 @@
foreach ($boards as &$_board) {
if (in_array($_board['uri'], $this->excluded))
continue;
$query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` UNION ALL ", $_board['uri'], $_board['uri']);
$query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` UNION ALL ", $_board['uri'], $_board['uri']);
}
$query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int)$settings['limit_posts'], $query);
$query = query($query) or error(db_error());
while ($post = $query->fetch()) {
while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
openBoard($post['board']);
$post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ? $post['thread'] : $post['id'])) . '#' . $post['id'];
@ -78,40 +78,37 @@
}
// Total posts
$query = 'SELECT SUM(`top`) AS `count` FROM (';
$query = 'SELECT SUM(`top`) FROM (';
foreach ($boards as &$_board) {
if (in_array($_board['uri'], $this->excluded))
continue;
$query .= sprintf("SELECT MAX(`id`) AS `top` FROM `posts_%s` UNION ALL ", $_board['uri']);
$query .= sprintf("SELECT MAX(`id`) AS `top` FROM ``posts_%s`` UNION ALL ", $_board['uri']);
}
$query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query);
$query = query($query) or error(db_error());
$res = $query->fetch();
$stats['total_posts'] = number_format($res['count']);
$stats['total_posts'] = number_format($query->fetchColumn());
// Unique IPs
$query = 'SELECT COUNT(DISTINCT(`ip`)) AS `count` FROM (';
$query = 'SELECT COUNT(DISTINCT(`ip`)) FROM (';
foreach ($boards as &$_board) {
if (in_array($_board['uri'], $this->excluded))
continue;
$query .= sprintf("SELECT `ip` FROM `posts_%s` UNION ALL ", $_board['uri']);
$query .= sprintf("SELECT `ip` FROM ``posts_%s`` UNION ALL ", $_board['uri']);
}
$query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query);
$query = query($query) or error(db_error());
$res = $query->fetch();
$stats['unique_posters'] = number_format($res['count']);
$stats['unique_posters'] = number_format($query->fetchColumn());
// Active content
$query = 'SELECT SUM(`filesize`) AS `count` FROM (';
$query = 'SELECT SUM(`filesize`) FROM (';
foreach ($boards as &$_board) {
if (in_array($_board['uri'], $this->excluded))
continue;
$query .= sprintf("SELECT `filesize` FROM `posts_%s` UNION ALL ", $_board['uri']);
$query .= sprintf("SELECT `filesize` FROM ``posts_%s`` UNION ALL ", $_board['uri']);
}
$query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query);
$query = query($query) or error(db_error());
$res = $query->fetch();
$stats['active_content'] = $res['count'];
$stats['active_content'] = $query->fetchColumn();
return Element('themes/recent/recent.html', Array(
'settings' => $settings,

View file

@ -61,9 +61,8 @@
// debug just the graphing (not updating) with the --debug switch
if (!isset($argv[1]) || $argv[1] != '--debug') {
// Update graph
$query = query(sprintf("SELECT MAX(`id`) AS `count` FROM `posts_%s`", $board));
$count = $query->fetch();
$count = $count['count'];
$query = query(sprintf("SELECT MAX(`id`) FROM ``posts_%s``", $board));
$count = $query->fetchColumn();
if (!rrd_update($file, Array(
'-t',

View file

@ -19,7 +19,7 @@
$threads = array();
foreach ($boards as $board) {
$query = query(sprintf("SELECT `id` AS `thread_id`, (SELECT `time` FROM `posts_%s` WHERE `thread` = `thread_id` OR `id` = `thread_id` ORDER BY `time` DESC LIMIT 1) AS `lastmod` FROM `posts_%s` WHERE `thread` IS NULL", $board, $board)) or error(db_error());
$query = query(sprintf("SELECT `id` AS `thread_id`, (SELECT `time` FROM ``posts_%s`` WHERE `thread` = `thread_id` OR `id` = `thread_id` ORDER BY `time` DESC LIMIT 1) AS `lastmod` FROM ``posts_%s`` WHERE `thread` IS NULL", $board, $board)) or error(db_error());
$threads[$board] = $query->fetchAll(PDO::FETCH_ASSOC);
}

View file

@ -25,7 +25,7 @@
foreach($boards as &$_board) {
if(in_array($_board['uri'], explode(' ', $this->settings['exclude'])))
continue;
$query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` WHERE `thread` IS NULL UNION ALL ", $_board['uri'], $_board['uri']);
$query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL UNION ALL ", $_board['uri'], $_board['uri']);
}
$query = preg_replace('/UNION ALL $/', 'ORDER BY `bump` DESC', $query);
$query = query($query) or error(db_error());
@ -48,7 +48,7 @@
$post['filename'], $post['ip'], $post['sticky'], $post['locked'], $post['sage'], $post['embed'], $mod ? '?/' : $config['root'], $mod
);
$posts = prepare(sprintf("SELECT * FROM `posts_%s` WHERE `thread` = :id ORDER BY `id` DESC LIMIT :limit", $post['board']));
$posts = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE `thread` = :id ORDER BY `id` DESC LIMIT :limit", $post['board']));
$posts->bindValue(':id', $post['id']);
$posts->bindValue(':limit', ($post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']), PDO::PARAM_INT);
$posts->execute() or error(db_error($posts));
@ -66,7 +66,7 @@
}
if ($posts->rowCount() == ($post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview'])) {
$ct = prepare(sprintf("SELECT COUNT(`id`) as `num` FROM `posts_%s` WHERE `thread` = :thread UNION ALL SELECT COUNT(`id`) FROM `posts_%s` WHERE `file` IS NOT NULL AND `thread` = :thread", $post['board'], $post['board']));
$ct = prepare(sprintf("SELECT COUNT(`id`) as `num` FROM ``posts_%s`` WHERE `thread` = :thread UNION ALL SELECT COUNT(`id`) FROM `posts_%s` WHERE `file` IS NOT NULL AND `thread` = :thread", $post['board'], $post['board']));
$ct->bindValue(':thread', $post['id'], PDO::PARAM_INT);
$ct->execute() or error(db_error($count));

View file

@ -1,37 +1,115 @@
(function(){
var cache = new Array(),
thread = false,
loading = false;
loading = false,
ukkotimer = false;
if (localStorage.hiddenboards !== null) {
localStorage.hiddenboards = "{}";
}
// Load data from HTML5 localStorage
var hiddenboards = JSON.parse(localStorage.hiddenboards);
var storeboards = function() {
localStorage.hiddenboards = JSON.stringify(hiddenboards);
};
$(document).ready(function() {
$(window).on('scroll', function() {
if($(window).scrollTop() + $(window).height() + 100 > $(document).height() && !loading && overflow.length > 0) {
var addukkohide = function() {
var ukkohide = $('<a href="javascript:void(0);" class="unimportant ukkohide"></a>');
var board = $(this).next().data("board");
var hr = $("<hr />");
$(this).append(ukkohide);
$(this).append(hr);
if (hiddenboards[board] !== true) {
ukkohide.html(_("(hide threads from this board)"));
hr.hide();
}
else {
ukkohide.html(_("(show threads from this board)"));
$(this).next().hide();
}
ukkohide.click(function() {
hiddenboards[board] = (hiddenboards[board] !== true);
if (hiddenboards[board] !== true) {
$('[data-board="'+board+'"]:not([data-cached="yes"])').show().prev().
find('.ukkohide').html(_("(hide threads from this board)")).
parent().find('hr').hide();
}
else {
$('[data-board="'+board+'"]:not([data-cached="yes"])').hide().prev().
find('.ukkohide').html(_("(show threads from this board)"))
.parent().find('hr').show();
}
storeboards();
return false;
});
};
$("h2").each(addukkohide);
$('.pages').hide();
var loadnext = function() {
if (overflow.length == 0) {
$('.pages').show().html(_("No more threads to display"));
}
while($(window).scrollTop() + $(window).height() + 1000 > $(document).height() && !loading && overflow.length > 0) {
var page = '../' + overflow[0].board + '/' + overflow[0].page;
thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"]');
if (thread.length > 0 && thread.attr("data-cached") !== 'yes') { // already present
overflow.shift();
continue;
}
var boardheader = $('<h2><a href="/' + overflow[0].board + '/">/' + overflow[0].board + '/</a> </h2>');
if($.inArray(page, cache) != -1) {
thread = $('div#thread_' + overflow[0].id);
if(thread.length > 0) {
thread.prepend('<h2><a href="/' + overflow[0].board + '/">/' + overflow[0].board + '/</a></h2>');
$('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).css('display', 'block'));
overflow.shift();
if (thread.length > 0) {
$('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).attr("data-cached", "no").css('display', 'block'));
boardheader.insertBefore(thread);
addukkohide.call(boardheader);
$(document).trigger('new_post', thread);
}
overflow.shift();
} else {
loading = true;
$('.pages').show().html(_("Loading..."));
$.get(page, function(data) {
cache.push(page);
$(data).find('div[id*="thread_"]').each(function() {
$('body').prepend($(this).css('display', 'none').attr('data-board', overflow[0].board));
var checkout = $(this).attr('id').replace('thread_', '');
if ($('div#thread_' + checkout + '[data-board="' + overflow[0].board + '"]').length == 0) {
$('form[name="postcontrols"]').prepend($(this).css('display', 'none').attr("data-cached", "yes").attr('data-board', overflow[0].board));
}
});
thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"]');
thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"][data-cached="yes"]');
if(thread.length > 0) {
thread.prepend('<h2><a href="/' + overflow[0].board + '/">/' + overflow[0].board + '/</a></h2>');
$('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).css('display', 'block'));
overflow.shift();
$('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).attr("data-cached", "no").css('display', 'block'));
boardheader.insertBefore(thread);
addukkohide.call(boardheader);
$(document).trigger('new_post', thread);
}
overflow.shift();
loading = false;
$('.pages').hide().html("");
});
break;
}
}
});
clearTimeout(ukkotimer);
ukkotimer = setTimeout(loadnext, 1000);
};
});
$(window).on('scroll', loadnext);
ukkotimer = setTimeout(loadnext, 1000);
});
})();

View file

@ -1,51 +1,52 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript">
var active_page = "thread";
</script>
{% include 'header.html' %}
<title>{{ board.url }} - {% if config.thread_subject_in_title and thread.subject %}{{ thread.subject }}{% else %}{{ board.title|e }}{% endif %}</title>
</head>
<body>
{{ boardlist.top }}
{% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr />{% endif %}
{% if config.url_banner %}<img class="banner" src="{{ config.url_banner }}" {% if config.banner_width or config.banner_height %}style="{% if config.banner_width %}width:{{ config.banner_width }}px{% endif %};{% if config.banner_width %}height:{{ config.banner_height }}px{% endif %}" {% endif %}alt="" />{% endif %}
<header>
<h1>{{ board.url }} - {{ board.title|e }}</h1>
<div class="subtitle">
{% if board.subtitle %}
{{ board.subtitle|e }}
{% endif %}
{% if mod %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %}
</div>
</header>
<div class="banner">{% trans %}Posting mode: Reply{% endtrans %} <a class="unimportant" href="{{ return }}">[{% trans %}Return{% endtrans %}]</a></div>
{% include 'attention_bar.html' %}
{% include 'post_form.html' %}
{% if config.blotter %}<hr /><div class="blotter">{{ config.blotter }}</div>{% endif %}
<hr />
<form name="postcontrols" action="{{ config.post_url }}" method="post">
<input type="hidden" name="board" value="{{ board.uri }}" />
{% if mod %}<input type="hidden" name="mod" value="1" />{% endif %}
{{ body }}
{% include 'report_delete.html' %}
</form>
<a href="{{ return }}">[{% trans %}Return{% endtrans %}]</a>
{{ boardlist.bottom }}
<footer>
<p class="unimportant" style="margin-top:20px;text-align:center;">Powered by <a href="http://tinyboard.org/">Tinyboard</a> {{ config.version }} | <a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2013 Tinyboard Development Group</p>
{% for footer in config.footer %}<p class="unimportant" style="text-align:center;">{{ footer }}</p>{% endfor %}
</footer>
<script type="text/javascript">{% raw %}
ready();
{% endraw %}</script>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript">
var active_page = "thread";
</script>
{% include 'header.html' %}
<title>{{ board.url }} - {% if config.thread_subject_in_title and thread.subject %}{{ thread.subject }}{% else %}{{ board.title|e }}{% endif %}</title>
</head>
<body>
{{ boardlist.top }}
{% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr />{% endif %}
{% if config.url_banner %}<img class="banner" src="{{ config.url_banner }}" {% if config.banner_width or config.banner_height %}style="{% if config.banner_width %}width:{{ config.banner_width }}px{% endif %};{% if config.banner_width %}height:{{ config.banner_height }}px{% endif %}" {% endif %}alt="" />{% endif %}
<header>
<h1>{{ board.url }} - {{ board.title|e }}</h1>
<div class="subtitle">
{% if board.subtitle %}
{{ board.subtitle|e }}
{% endif %}
{% if mod %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %}
</div>
</header>
<div class="banner">{% trans %}Posting mode: Reply{% endtrans %} <a class="unimportant" href="{{ return }}">[{% trans %}Return{% endtrans %}]</a></div>
{% include 'attention_bar.html' %}
{% include 'post_form.html' %}
{% if config.global_message %}<hr /><div class="blotter">{{ config.global_message }}</div>{% endif %}
<hr />
<form name="postcontrols" action="{{ config.post_url }}" method="post">
<input type="hidden" name="board" value="{{ board.uri }}" />
{% if mod %}<input type="hidden" name="mod" value="1" />{% endif %}
{{ body }}
{% include 'report_delete.html' %}
</form>
<a href="{{ return }}">[{% trans %}Return{% endtrans %}]</a>
{{ boardlist.bottom }}
<footer>
<p class="unimportant" style="margin-top:20px;text-align:center;">Powered by <a href="http://tinyboard.org/">Tinyboard</a> {{ config.version }} | <a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2013 Tinyboard Development Group</p>
{% for footer in config.footer %}<p class="unimportant" style="text-align:center;">{{ footer }}</p>{% endfor %}
</footer>
<script type="text/javascript">{% raw %}
ready();
{% endraw %}</script>
</body>
</html>