mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-04-27 03:00:12 -04:00
508 lines
16 KiB
HTML
508 lines
16 KiB
HTML
## The contents of this file are subject to the Common Public Attribution.
|
|
## License Version 1.0. (the "License"); you may not use this file except in
|
|
## compliance with the License. You may obtain a copy of the License at
|
|
## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
|
|
## License Version 1.1, but Sections 14 and 15 have been added to cover use of
|
|
## software over a computer network and provide for limited attribution for the
|
|
## Original Developer. In addition, Exhibit A has been modified to be consistent
|
|
## with Exhibit B.
|
|
##
|
|
## Software distributed under the License is distributed on an "AS IS" basis,
|
|
## WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
## the specific language governing rights and limitations under the License.
|
|
##
|
|
## The Original Code is Reddit.
|
|
##
|
|
## The Original Developer is the Initial Developer. The Initial Developer of
|
|
## the Original Code is CondeNet, Inc.
|
|
##
|
|
## All portions of the code written by CondeNet are Copyright (c) 2006-2010
|
|
## CondeNet, Inc. All Rights Reserved.
|
|
################################################################################
|
|
|
|
<%!
|
|
from r2.lib.filters import spaceCompress, unsafe
|
|
from r2.lib.template_helpers import add_sr
|
|
from r2.lib.utils import cols, long_datetime, timesince
|
|
%>
|
|
<%def name="tags(**kw)">
|
|
%for k, v in kw.iteritems():
|
|
%if v:
|
|
${k.strip('_')}="${v}" \
|
|
%endif
|
|
%endfor
|
|
</%def>
|
|
|
|
## override the link _class so that we can globally update
|
|
## the way links are handled (if need be)
|
|
<%def name="_a(**kw)">
|
|
<a ${tags(**kw)}>${caller.body()}</a>
|
|
</%def>
|
|
|
|
<%def name="_a_buffered(body, **kw)" buffered="True">
|
|
<a ${tags(**kw)}>${body}</a>
|
|
</%def>
|
|
|
|
|
|
|
|
## thing should be global
|
|
<%def name="_id(arg)">
|
|
id="${arg}_${thing and thing._fullname or ''}"
|
|
</%def>
|
|
|
|
<%def name="submit_form(onsubmit='', action='', _class='', method='post', _id='', **params)">
|
|
<form class="${_class or ''}" onsubmit="${onsubmit or ''}"
|
|
action="${action or ''}" ${_id and "id='" + _id + "'" or ""} method="${method}"
|
|
%if c.cname:
|
|
target="_top"
|
|
%endif
|
|
>
|
|
%if c.user_is_loggedin:
|
|
<input type="hidden" name="uh" value="${c.user.modhash()}" />
|
|
%endif
|
|
%for key, value in params.iteritems():
|
|
<input type="hidden" name="${key}" value="${value}" />
|
|
%endfor
|
|
${caller.body()}
|
|
</form>
|
|
</%def>
|
|
|
|
<%def name="first_defined(*kw)">
|
|
%if not kw or kw[0] == UNDEFINED or not kw[0]:
|
|
${first_defined(kw[1:])}
|
|
%endif
|
|
</%def>
|
|
|
|
<%def name="error_field(error_name, field_name, kind='span')">
|
|
<${kind} class="error ${error_name} field-${field_name}"
|
|
style="${'' if error_name in c.errors else 'display:none'}">
|
|
%if error_name in c.errors:
|
|
${c.errors[error_name].message}
|
|
%endif
|
|
</${kind}>
|
|
</%def>
|
|
|
|
<%def name="success_field(success_str, kind='p', successful=False, hide='')">
|
|
<${kind} class="error success">
|
|
%if successful:
|
|
${success_str}
|
|
%endif
|
|
</${kind}>
|
|
<script type="text/javascript">
|
|
function fire_success() {
|
|
$('success').innerHTML = "${success_str}";
|
|
%if hide:
|
|
hide(document.getElementById('${hide}'));
|
|
%endif
|
|
}
|
|
</script>
|
|
</%def>
|
|
|
|
<%def name="img_link(link_text, img, path, _id='', target='', img_id = None, **kw)">
|
|
<%
|
|
if (not target or target == '_parent') and c.cname:
|
|
target = '_top'
|
|
if target:
|
|
kw['target'] = target
|
|
|
|
path = add_sr(path, sr_path = False)
|
|
kw['target'] = target
|
|
%>
|
|
<%call expr="_a(href=path, _id=_id, **kw)">
|
|
<img ${("id='%s'" % img_id) if img_id else ''} src="${img}" alt="${link_text}"/>
|
|
</%call>
|
|
</%def>
|
|
|
|
<%def name="plain_link(link_text, path, _sr_path = True, nocname=False, fmt='', target='', **kw)">
|
|
## caching comment:
|
|
## in addition to the args, this function also makes use of c.cname,
|
|
## and, via add_sr, both c.site.name and c.render_style.
|
|
##
|
|
## This function is called by (among other places) NavMenu as the
|
|
## primary rendering view. Any changes to the c-usage of this function
|
|
## will have to be propagated up.
|
|
<%
|
|
if (not target or target == '_parent') and c.cname:
|
|
target = '_top'
|
|
if c.cname and path.startswith('http://'):
|
|
target = '_top'
|
|
if target:
|
|
kw['target'] = target
|
|
|
|
link = _a_buffered(link_text,
|
|
href=add_sr(path, sr_path=_sr_path, nocname=nocname),
|
|
**kw)
|
|
%>
|
|
|
|
${unsafe((fmt % link) if fmt else link)}
|
|
</%def>
|
|
|
|
|
|
<%def name="text_with_links(txt, _sr_path = False, nocname=False, **kw)">
|
|
<%
|
|
from r2.lib.filters import _force_unicode
|
|
for key, (text, href) in kw.iteritems():
|
|
kw[key]=spaceCompress(capture(plain_link, text, href, _sr_path=_sr_path, nocname=nocname))
|
|
txt = _force_unicode(txt) % kw
|
|
txt = txt.replace(" <", " <").replace("> ", "> ")
|
|
|
|
%>
|
|
${unsafe(txt)}
|
|
</%def>
|
|
|
|
<%def name="text_with_js(txt, _sr_path = False, **kw)">
|
|
<%
|
|
for key, (text, js) in kw.iteritems():
|
|
kw[key]=spaceCompress(capture(plain_link, text, "#",
|
|
onclick = js, _sr_path=_sr_path))
|
|
txt = txt % kw
|
|
txt = txt.replace(" <", " <").replace("> ", "> ")
|
|
|
|
%>
|
|
${unsafe(txt)}
|
|
</%def>
|
|
|
|
|
|
<%def name="language_tool(name='lang', allow_blank = False,
|
|
default_lang = g.lang,
|
|
show_regions = False,
|
|
all_langs = False)">
|
|
<%
|
|
langs = g.all_languages if all_langs else g.languages
|
|
if not show_regions:
|
|
langs = [x for x in langs if len(x) == 2]
|
|
%>
|
|
%if langs:
|
|
<select id="${name}" name="${name}">
|
|
%if allow_blank:
|
|
<option ${(not default_lang) and "selected='selected'" or ""}>
|
|
</option>
|
|
%endif
|
|
%for x in langs:
|
|
<option ${x == default_lang and "selected='selected'" or ""}>
|
|
${g.lang_name[x]} [${x}]
|
|
</option>
|
|
%endfor
|
|
</select>
|
|
%endif
|
|
</%def>
|
|
|
|
<%def name="language_checkboxes(default = 'all')">
|
|
<%
|
|
all_checked, some_checked = "checked='checked'", ""
|
|
if default != "all":
|
|
all_checked, some_checked = some_checked, all_checked
|
|
%>
|
|
<input type="radio" name="all-langs" id="all-langs" value="all"
|
|
onclick="clear_all_langs(this)" ${all_checked}/>
|
|
<label for="all-langs">${_("all languages")}</label>
|
|
<br/>
|
|
<input type="radio" name="all-langs" id="some-langs" value="some"
|
|
${some_checked}/>
|
|
<label for="some-langs">${_("some languages")}</label>
|
|
<hr/>
|
|
<table>
|
|
<%
|
|
all_langs = [x for x in g.all_languages if len(x) == 2]
|
|
%>
|
|
%for col in cols(all_langs, 3):
|
|
<tr>
|
|
%for lang in col:
|
|
<td style="padding-right: 15px; white-space: nowrap;">
|
|
<%
|
|
idname = "lang-" + lang
|
|
if default != "all" and lang in default:
|
|
checked = "checked='checked'"
|
|
else:
|
|
checked = ""
|
|
%>
|
|
<input type="checkbox" name="${idname}" id="${idname}"
|
|
onclick="check_some_langs(this)" ${checked}/>
|
|
<label for="${idname}">${g.lang_name[lang]}</label>
|
|
</td>
|
|
%endfor
|
|
</tr>
|
|
%endfor
|
|
</table>
|
|
</%def>
|
|
|
|
<%def name="separator(separator_char)">
|
|
<span class="separator">${separator_char}</span>
|
|
</%def>
|
|
|
|
<%def name="optionalstyle(style)">
|
|
%if request.get.get('style') != "off":
|
|
style="${style}"
|
|
%endif
|
|
</%def>
|
|
|
|
<%def name="checkbox(name, text, val)">
|
|
<input type="checkbox" ${'checked="checked"' if val else ''}
|
|
name="${name}">
|
|
${text}
|
|
</input>
|
|
</%def>
|
|
|
|
<%def name="image_upload(post_target, current_image = None, onsubmit = '',
|
|
onchange = '', label = '', form_id = 'image-upload')">
|
|
<form id="${form_id}" enctype="multipart/form-data"
|
|
class="image-upload"
|
|
target="upload-iframe"
|
|
%if onsubmit:
|
|
onsubmit="${onsubmit}"
|
|
%endif
|
|
action="${post_target}" method="post">
|
|
%if label:
|
|
<label for="file">${label}</label>
|
|
%endif
|
|
<input type="hidden" name="uh" value="${c.modhash}" />
|
|
%if not c.default_sr:
|
|
<input type="hidden" name="r" value="${c.site.name}" />
|
|
%endif
|
|
<input type="hidden" name="formid" value="${form_id}" />
|
|
<input type="file" name="file" id="file"
|
|
onchange="$(this).next().show(); ${onchange}"/>
|
|
<button id="submit-img" class="submit-img"
|
|
type="submit" name="upload"
|
|
onclick="$(this).siblings('.img-status').show().html('${_('uploading')}'); return true;"
|
|
style="display: none;" >
|
|
${_('upload')}
|
|
</button>
|
|
|
|
<span style="display: none;" class="error img-status"></span>
|
|
<script type="text/javascript">
|
|
function on_image_success(img) {}
|
|
function create_new_image(name) {}
|
|
|
|
function completedUploadImage(status, img_src, name, errors, form_id) {
|
|
form_id = $.with_default(form_id, "${form_id}");
|
|
var form = $("#" + form_id);
|
|
if (status)
|
|
form.find(".img-status").show().html(status);
|
|
else
|
|
form.find(".img-status").hide().html("");
|
|
$.map(errors, function(e) {
|
|
if(e[1])
|
|
form.find("." + e[0]).html(e[1]).show();
|
|
else
|
|
form.find("." + e[0]).html('').hide();
|
|
});
|
|
if(img_src) {
|
|
form.get(0).reset();
|
|
var img = (name) ? $("#img-preview-" + name) :
|
|
form.find("img.img-preview:first");
|
|
if(!$.defined(img) || img.length == 0)
|
|
img = create_new_image(name);
|
|
if(img_src.indexOf("?") == -1)
|
|
img_src += "?v=" + Math.random();
|
|
if(img)
|
|
img.attr("src", "").attr("src", img_src);
|
|
img.show().parent().show();
|
|
form.find(".delete-img").show();
|
|
form.find(".submit-img").hide();
|
|
on_image_success(img);
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<iframe src="about:blank" width="600" height="200"
|
|
style="display: none;"
|
|
name="upload-iframe" id="upload-iframe"></iframe>
|
|
|
|
<div id="img-preview-container" class="img-preview-container"
|
|
style="${'' if current_image else 'display:none;'}">
|
|
<img id="img-preview-upload" alt="header preview"
|
|
class="img-preview"
|
|
%if current_image:
|
|
src="${current_image}"
|
|
%else:
|
|
src="/static/kill.png"
|
|
%endif
|
|
/><br />
|
|
</div>
|
|
%if caller:
|
|
${caller.body()}
|
|
%endif
|
|
</form>
|
|
<script type="text/javascript">
|
|
$(function() {
|
|
var max_width = 0;
|
|
$(".preftable th *").each(function() {
|
|
max_width = Math.max(max_width, $(this).width());
|
|
}).each(function() {
|
|
$(this).width(max_width);
|
|
});
|
|
});
|
|
|
|
</script>
|
|
</%def>
|
|
|
|
|
|
<%def name="js_preamble()">
|
|
<%
|
|
from r2.lib.template_helpers import get_domain
|
|
%>
|
|
var reddit = {
|
|
/* is the user logged in */
|
|
logged: ${c.user_is_loggedin and ("'%s'" % c.user.name) or "false"},
|
|
/* the subreddit's name (for posts) */
|
|
post_site: "${c.site.name if not c.default_sr else ''}",
|
|
/* are we in an iframe */
|
|
cnameframe: ${"true" if (c.cname and not c.authorized_cname) else "false"},
|
|
/* this page's referer */
|
|
referer: "${request.referer or ""}",
|
|
/* the user's voting hash */
|
|
modhash: ${"'%s'" % c.modhash or "false"},
|
|
/* the current rendering style */
|
|
renderstyle: "${c.render_style}",
|
|
/* current domain */
|
|
cur_domain: "${get_domain(cname = c.frameless_cname, subreddit = False,
|
|
no_www = True)}",
|
|
/* where do ajax request go? */
|
|
ajax_domain: "${get_domain(cname=c.authorized_cname, subreddit = False)}",
|
|
/* debugging? */
|
|
debug: ${"true" if g.debug else "false"},
|
|
vl: {},
|
|
sr: {},
|
|
status_msg: {
|
|
fetching: "${_('fetching title...')}",
|
|
submitting: "${_('submitting...')}",
|
|
loading: "${_('loading...')}"
|
|
},
|
|
tofetch: [],
|
|
trackers: {}
|
|
};
|
|
</%def>
|
|
|
|
<%def name="logout(top=False,dest=None,a_class='')">
|
|
<form method="post" action="/logout" class="logout hover"
|
|
%if top:
|
|
target="_top"
|
|
%endif
|
|
>
|
|
<input type="hidden" name="uh" value="${c.modhash}"/>
|
|
<input type="hidden" name="top" value="${'on' if top else 'off'}"/>
|
|
%if dest:
|
|
<input type="hidden" name="dest" value="${dest}"/>
|
|
%endif
|
|
|
|
<a href="javascript:void(0)" onclick="$(this).parent().submit()"
|
|
%if a_class:
|
|
class="${a_class}"
|
|
%endif
|
|
>
|
|
${_("logout")}
|
|
</a>
|
|
</form>
|
|
</%def>
|
|
|
|
<%def name="block_field(title, description = '', css_class= '', **kw)">
|
|
<div class="roundfield ${css_class}"
|
|
%for k, v in kw.iteritems():
|
|
${k}="${v}"
|
|
%endfor
|
|
>
|
|
<span class="title">${title}</span>
|
|
 
|
|
%if description:
|
|
<span class="gray">${description}</span>
|
|
%endif
|
|
<div class="roundfield-content">
|
|
${caller.body()}
|
|
</div>
|
|
</div>
|
|
</%def>
|
|
|
|
<%def name="block_field(kind, title, description = '', css_class= '', **kw)">
|
|
<div class="${kind} ${css_class}"
|
|
%for k, v in kw.iteritems():
|
|
${k}="${v}"
|
|
%endfor
|
|
>
|
|
<span class="title">${title}</span>
|
|
 
|
|
%if description:
|
|
<span class="gray">${description}</span>
|
|
%endif
|
|
<div class="${kind}-content">
|
|
${caller.body()}
|
|
</div>
|
|
</div>
|
|
</%def>
|
|
|
|
<%def name="round_field(title, description = '', css_class= '', **kw)">
|
|
<%call expr="block_field('roundfield', title, description = description, css_class= css_class, **kw)">
|
|
${caller.body()}
|
|
</%call>
|
|
</%def>
|
|
|
|
<%def name="line_field(title, description = '', css_class= '', **kw)">
|
|
<%call expr="block_field('linefield', title, description = description, css_class= css_class, **kw)">
|
|
${caller.body()}
|
|
</%call>
|
|
</%def>
|
|
|
|
<%def name="reddit_selector(default_sr, sr_searches, subreddits)">
|
|
<div id="sr-autocomplete-area">
|
|
<input id="sr-autocomplete" name="sr" type="text"
|
|
autocomplete="off"
|
|
onkeyup="sr_name_up(event)"
|
|
onkeydown="return sr_name_down(event)"
|
|
onblur="hide_sr_name_list()"
|
|
value = "${default_sr}" />
|
|
<ul id="sr-drop-down">
|
|
<li class="sr-name-row"
|
|
onmouseover="highlight_reddit(this)"
|
|
onmousedown="return sr_dropdown_mdown(this)"
|
|
onmouseup="sr_dropdown_mup(this)">nothin</li>
|
|
</ul>
|
|
</div>
|
|
<script type="text/javascript">
|
|
reddit.sr_cache = ${unsafe(sr_searches)};
|
|
</script>
|
|
${error_field("SUBREDDIT_NOEXIST", "sr", "div")}
|
|
${error_field("SUBREDDIT_NOTALLOWED", "sr", "div")}
|
|
${error_field("SUBREDDIT_REQUIRED", "sr", "div")}
|
|
|
|
<div id="suggested-reddits">
|
|
<span class="">${_("popular choices")} </span>
|
|
<ul>
|
|
%for name in subreddits:
|
|
<li>
|
|
<a href="#" tabindex="100" onclick="set_sr_name(this); return false">${name}</a> 
|
|
</li>
|
|
%endfor
|
|
</ul>
|
|
</div>
|
|
</%def>
|
|
|
|
<%def name="timestamp(thing, since=None)">
|
|
## todo: use pubdate attribute once things are <article> tags.
|
|
## note: comment and link templates will pass a CachedVariable stub as since.
|
|
<time title="${long_datetime(thing._date)}" datetime="${thing._date.isoformat()}">
|
|
${unsafe(since or timesince(thing._date))}
|
|
</time>
|
|
</%def>
|
|
|
|
<%def name="percentage(slice, total)">
|
|
%if total is None or total == "" or total == 0 or slice is None or slice == "":
|
|
--
|
|
%else:
|
|
${int(100 * slice / total)}%
|
|
%endif
|
|
</%def>
|
|
|
|
<%def name="pretty_button(label, func=None, func_vars='', extra_class='')">
|
|
<a class="pretty-button ${extra_class}" href="#"
|
|
%if func is None:
|
|
onclick="alert('please don\'t do that again');return false;"
|
|
%elif func_vars:
|
|
onclick="return ${func}($(this), ${func_vars})"
|
|
%else:
|
|
onclick="return ${func}($(this))"
|
|
%endif
|
|
>
|
|
${label}
|
|
</a>
|
|
</%def>
|