Merge remote branch 'buchanan/fxcup23'

This commit is contained in:
Jeff Balogh 2010-05-26 17:36:24 -07:00
Родитель 0eed0cfe84 007fbbe24a
Коммит 1aa1b9b1a4
64 изменённых файлов: 3083 добавлений и 23 удалений

Просмотреть файл

@ -133,12 +133,12 @@
"display_username": "My Persona",
"popularity": 0,
"license": null,
"footer": "My_Persona_footer.png",
"footer": "BCBG_Persona_footer2.png",
"movers": null,
"author": "Persona Author",
"submit": "2009-03-30 20:55:48",
"accentcolor": "8d8d97",
"header": "My_Persona_header.png",
"header": "BCBG_Persona_header2.png",
"textcolor": "ffffff",
"approve": "2009-03-30 23:17:40",
"persona_id": 813,

196
apps/firefoxcup/__init__.py Normal file
Просмотреть файл

@ -0,0 +1,196 @@
# coding=utf8
from django.conf import settings
from tower import ugettext_lazy as _
email_enabled = False
tags = {
'all': [
'#worldcup',
'#football',
'#soccer',
'#south africa2010',
'#wcup2010'],
'af': '#Wêreldbeker',
'ar': ['كأس العالم','مونديال','المونديال','كأس العالم لكرة القدم'],
'da': ['#vm', 'Fodbold VM'],
'de': '#wm',
'es': '#mundial',
'fr': ['#mondial', '#coupedumonde'],
'it': '#IlMondiale',
'ja': '#W杯',
'ko': '#월드컵',
'nl': ['#wk', '#wereldbeker', '#oranje'],
'ru': 'ЧМ',
'sr': 'Светско првенство',
'sk': 'Svetový pohár',
'sl': 'Svetovni pokal',
}
teams = [
{
'id': 'algeria',
'name': _('Algeria'),
'persona_id': 216601,
},
{
'id': 'argentina',
'name': _('Argentina'),
'persona_id': 216091,
},
{
'id': 'australia',
'name': _('Australia'),
'persona_id': 216602,
},
{
'id': 'brazil',
'name': _('Brazil'),
'persona_id': 216603,
},
{
'id': 'cameroon',
'name': _('Cameroon'),
'persona_id': 216605,
},
{
'id': 'chile',
'name': _('Chile'),
'persona_id': 216606,
},
{
'id': 'cote',
'name': _("Cote d'Ivoire"),
'persona_id': 216626,
},
{
'id': 'denmark',
'name': _('Denmark'),
'persona_id': 216608,
},
{
'id': 'england',
'name': _('England'),
'persona_id': 215499,
},
{
'id': 'france',
'name': _('France'),
'persona_id': 215503,
},
{
'id': 'germany',
'name': _('Germany'),
'persona_id': 215502,
},
{
'id': 'ghana',
'name': _('Ghana'),
'persona_id': 216610,
},
{
'id': 'greece',
'name': _('Greece'),
'persona_id': 216618,
},
{
'id': 'honduras',
'name': _('Honduras'),
'persona_id': 216624,
},
{
'id': 'italy',
'name': _('Italy'),
'persona_id': 215504,
},
{
'id': 'japan',
'name': _('Japan'),
'persona_id': 215506,
},
{
'id': 'mexico',
'name': _('Mexico'),
'persona_id': 216597,
},
{
'id': 'netherlands',
'name': _('Netherlands'),
'persona_id': 216093,
},
{
'id': 'korea-dpr',
'name': _('North Korea'),
'persona_id': 216630,
},
{
'id': 'new-zealand',
'name': _('New Zealand'),
'persona_id': 216627,
},
{
'id': 'nigeria',
'name': _('Nigeria'),
'persona_id': 216629,
},
{
'id': 'paraguay',
'name': _('Paraguay'),
'persona_id': 216631,
},
{
'id': 'portugal',
'name': _('Portugal'),
'persona_id': 216635,
},
{
'id': 'serbia',
'name': _('Serbia'),
'persona_id': 216641,
},
{
'id': 'slovakia',
'name': _('Slovakia'),
'persona_id': 216646,
},
{
'id': 'slovenia',
'name': _('Slovenia'),
'persona_id': 216648,
},
{
'id': 'south-africa',
'name': _('South Africa'),
'persona_id': 216652,
},
{
'id': 'korea-republic',
'name': _('South Korea'),
'persona_id': 216668,
},
{
'id': 'spain',
'name': _('Spain'),
'persona_id': 215498,
},
{
'id': 'switzerland',
'name': _('Switzerland'),
'persona_id': 216670,
},
{
'id': 'usa',
'name': _('United States'),
'persona_id': 215507,
},
{
'id': 'uruguay',
'name': _('Uruguay'),
'persona_id': 216672,
}]
for team in teams:
team['flag'] = '%simg/firefoxcup/flags/%s.png' % (settings.MEDIA_URL, team['id'])
team['persona'] = None
twitter_languages = """
ar da de en es fa fi fr hu is it ja nl no pl pt ru sv th""".split()

15
apps/firefoxcup/models.py Normal file
Просмотреть файл

@ -0,0 +1,15 @@
from django.db import models
import amo.models
class FirefoxcupStat(amo.models.ModelBase):
"""
Keeps record of daily ADU counts for Firefox Cup personas.
Used to calculate 'Average Fans' over time of Firefox Cup campaign
"""
persona = models.ForeignKey('addons.Persona')
adu = models.IntegerField()
class Meta:
db_table = 'firefoxcup_stats'

Просмотреть файл

@ -0,0 +1,166 @@
{% extends 'base.html' %}
{% block title %}{{ _('Firefox Cup') }}{% endblock %}
{% block site_header %}{% endblock %}
{% block site_css %}
{{ css('firefoxcup') }}
{% endblock %}
{% block main_content %}
<div id="wrapper">
<div id="doc">
<ul id="header">
<li class="first"><a href="http://www.mozilla.com/">{{ _('Mozilla') }}</a></li>
<li><a href="http://addons.mozilla.org/">{{ _('Add-Ons') }}</a></li>
<li><a href="http://support.mozilla.com/">{{ _('Support') }}</a></li>
<li>{% include 'includes/lang_switcher.html' %}</li>
</ul>
<div id="main-feature">
<h1><img src="{{ MEDIA_URL }}img/firefoxcup/logo.png" alt="{{ _('Firefox Cup') }}" /></h1>
<h2>{{ _('Install Personas to support your team and compete for the Firefox Cup.') }}</h2>
<div id="download">
<a href="http://www.mozilla.com/firefox/">
<span class="title">{{ _('Get Firefox') }}</span>
<span>{{ _('Upgrade to Firefox 3.6 and experience the best of the Web and Firefox Cup.') }}</span>
</a>
</div>
</div>
<div id="main-content">
<h2>{{ _('Personas show your passion as your team plays for glory.') }}</h2>
<div id="personas" class="pager pager-with-tabs">
<div id="personas-header">
<h3>{{ _('Roll over to try, click to apply') }}</h3>
<ul id="personas-nav" class="pager-tabs">
<li class="first"><a href="#p1">{{ _('1') }}</a></li>
<li><a href="#p2">{{ _('2') }}</a></li>
<li><a href="#p3">{{ _('3') }}</a></li>
<li><a href="#p4">{{ _('4') }}</a></li>
</ul>
</div>
<div class="pager-content">
{% for teams_batch in teams|batch(8) %}
<div class="personas-contents {% if loop.index == 1 %}default-page{% endif %}" id="feature-p{{ loop.index }}">
<ul class="personas-list">
{% for team in teams_batch %}
<li>{{ persona_preview(team.persona, size='small', linked=False) if team.persona else 'Persona not found' }}</li>
{% endfor %}
</ul>
</div>
{% endfor %}
</div>
<p>{{ _('Dress up your Firefox in team spirits and share the love with friends. The team with the most fans using Personas wins the Firefox Cup!') }}</p>
</div>
</div>
<div id="sidebar">
<ul class="subfeatures">
{% if email_enabled %}
<li id="email">
<a href="#">
<span class="title">{{ _('Sign Up!') }}</span>
<span>{{ _('Stay current with Firefox Cup news by email.') }}</span>
</a>
</li>
{% endif %}
<li id="featured">
<a href="https://addons.mozilla.org/en-US/firefox/addon/725/" id="featured-footiefox">
<span class="title">{{ _('FootieFox') }}</span>
<span>{{ _("Don't miss a moment of action. FootieFox shows latest scores in your Firefox.") }}</span>
</a>
<a href="http://rockyourfirefox.com/" id="featured-rockyourfirefox">
<span class="title">{{ _('Rock Your Firefox') }}</span>
<span>{{ _("Discover new add-ons to brighten your day.") }}</span>
</a>
<a href="https://addons.mozilla.org/" id="featured-amo">
<span class="title">{{ _('Get Personal') }}</span>
<span>{{ _("Adapt Firefox to the way you browse with 1,000s of free add-ons.") }}</span>
</a>
</li>
<li id="facebook">
<a href="http://www.facebook.com/#!/Firefox">
<span class="title">{{ _('Stay Connected!') }}</span>
<span>{{ _('Become a Fan') }}</span>
</a>
</li>
</ul>
</div>
<div id="secondary-content">
<div id="teams-section">
<h2>{{ _('Find Your Team Persona') }}</h2>
<p>{{ _("Rollover your country's flag to preview Personas, then click to install. At the end of the tournament, the team whose fans used Personas the most wins the Firefox Cup.") }}</p>
</div>
<table id="teams">
<thead>
<tr>
<th>{{ _('Flag') }}</th>
<th>{{ _('Country') }}</th>
<th>{{ _('Average Fans') }}</th>
<th>{{ _('Total Fans') }}</th>
</tr>
<tr><td colspan="5"></td></tr>
</thead>
<tbody>
{% for team in teams %}
<tr>
<td class="persona"><img class="persona-preview" src="{{ team.flag }}" alt="{{ _('Flag') }}" data-browsertheme="{{ team.persona.json_data if team.persona }}" /></td>
<td>{{ team.name }}</td>
<td>###,###</td>
<td>{{ team.persona.popularity|numberfmt if team.persona else '###,###' }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<table id="tweets">
<thead>
<tr>
<th><img src="{{ MEDIA_URL }}img/firefoxcup/twitter.png" alt="Twitter" height="38" width="37" /> {{ _('Follow our tweets') }}</th>
</tr>
<tr><td></td></tr>
</thead>
<tbody>
{% for tweet in tweets %}
<tr><td>{{ tweet }}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div><!-- end #doc -->
</div><!-- end #wrapper -->
{% endblock %}
{% block footer %}{% endblock %}
{% block site_js %}{% endblock %}
{% block js %}
{{ js('firefoxcup') }}
<script>
var classOptions = ['default', 'amo', 'rockyourfirefox'];
var choice = Math.floor(Math.random() * classOptions.length);
$('body').addClass(classOptions[choice]);
</script>
{% endblock %}

45
apps/firefoxcup/tests.py Normal file
Просмотреть файл

@ -0,0 +1,45 @@
import json
from StringIO import StringIO
from mock import patch, Mock
from nose.tools import eq_
from pyquery import PyQuery as pq
import test_utils
from twitter import _process_tweet, search, _search_query, _prepare_lang
class TestFirefoxCup(test_utils.TestCase):
def twitter_results(self):
return StringIO(json.dumps({'results': [{'text': 'text'}]}))
def test_prepare_lang(self):
"""Always use short lang code (e.g. en-US -> en)"""
eq_(_prepare_lang('en-US'), 'en')
"""Bad lang codes should fall back to 'all'"""
eq_(_prepare_lang('bad-lang-code'), 'all')
def test_process_tweet(self):
"""URLs and tags are linkified"""
a = map(_process_tweet,
['http://www.mozilla.com', '#hash', '@person'])
for v in a:
# use PyQuery to check for <a> tag
assert pq(v).is_('a')
def test_search_query_encoded(self):
"""Search query string is URL encoded"""
a = _search_query(['foo', '#bar'], 'en')
eq_(a, 'lang=en&ors=foo+%23bar')
@patch('firefoxcup.twitter.urllib2.urlopen')
def test_search_data_decoded(self, urlopen):
"""Search results are JSON decoded,
and only the tweet content is returned"""
urlopen.return_value = self.twitter_results()
a = search([])
eq_(a, ['text'])

Просмотреть файл

@ -0,0 +1,64 @@
from hashlib import md5
import json
import logging
from urllib import urlencode
import urllib2
from django.core.cache import cache
from bleach import Bleach
import jinja2
import ttp
from . import twitter_languages
log = logging.getLogger('z.firefoxcup')
parser = ttp.Parser()
bleach = Bleach()
def _prepare_lang(lang):
lang = lang.split('-')[0]
if lang not in twitter_languages:
lang = 'all'
return lang
def _search_query(tags, lang):
return urlencode({
'ors': ' '.join(tags),
'lang': lang})
def search(tags, lang='all', check_cache=True):
lang = _prepare_lang(lang)
url = "http://search.twitter.com/search.json?" + _search_query(tags, lang)
# build cache key
hash = md5(url).hexdigest()
cache_key = "%s:%s" % ("firefoxcup-twitter", hash)
cache_time = 60
if check_cache:
cached = cache.get(cache_key)
if cached is not None:
return cached
try:
json_data = urllib2.urlopen(url)
except urllib2.URLError, e:
log.error("Couldn't open (%s): %s" % (url, e))
return
# decode JSON
data = json.load(json_data)['results']
# we only want the text, throw the other data away
tweets = [tweet['text'] for tweet in data]
tweets = map(_process_tweet, tweets)
cache.set(cache_key, tweets, cache_time)
return tweets
def _process_tweet(tweet):
# linkify urls, tags (e.g. #hashtag, @someone)
tweet = parser.parse(tweet).html
return jinja2.Markup(tweet)

7
apps/firefoxcup/urls.py Normal file
Просмотреть файл

@ -0,0 +1,7 @@
from django.conf.urls.defaults import patterns, url
from . import views
urlpatterns = patterns('',
url('^$', views.index, name='firefoxcup.index'),
)

31
apps/firefoxcup/views.py Normal file
Просмотреть файл

@ -0,0 +1,31 @@
import jingo
from addons.models import Persona
from twitter import search
from . import tags, email_enabled
from . import teams as teams_config
import logging
log = logging.getLogger('z.firefoxcup')
# Create your views here.
def index(request):
tweets = search(tags['all'], lang=request.LANG)
if len(tweets) < 15:
extra = search(tags['all'], 'all')
tweets.extend(extra)
# we only want 15 tweets
tweets = tweets[:15]
teams = dict((t['persona_id'], t) for t in teams_config)
for persona in Persona.objects.filter(persona_id__in=teams.keys()):
teams[persona.persona_id]['persona'] = persona
return jingo.render(request, 'firefoxcup/index.html', {
'tweets': tweets,
'teams': teams.values(),
'email_enabled': email_enabled,
})

Просмотреть файл

@ -0,0 +1,586 @@
/* {{{ Layout */
a,
a:link,
a:visited {
color: #0080be;
}
a:hover,
a:active {
color: #005580;
}
body {
background: #fff url(../../img/firefoxcup/background-repeat.jpg) top center repeat-x;
}
body, h1, h2, h3, h4, h5, h6 {
font-family: "helvetica neue",arial,helvetica,sans-serif;
}
#wrapper {
background: url(../../img/firefoxcup/background.jpg) top center no-repeat;
}
#doc {
width: 990px;
overflow: auto;
}
.section {
max-width: none;
min-height: 0;
min-width: 0;
padding: 0;
width: auto;
}
#footer .section {
width: 990px;
text-align: left;
}
/* }}}
/* {{{ Header */
#header {
float: right;
}
#header li {
float: left;
border-left: 1px solid #209b1e;
padding: 0 10px;
margin-top: 15px;
height: 25px;
}
#header li.first {
padding-left: 0;
border-left: 0;
}
#header a,
#header a:link,
#header a:visited,
#header a:hover,
#header a:active {
color: #fff;
text-decoration: underline;
display: block;
padding: 5px 0;
}
#header .languages label {
color: #fff;
font-weight: normal;
}
#header .languages button,
#header .languages select {
vertical-align: middle;
}
/* }}} */
/* {{{ Main Feature */
#main-feature {
color: #fff;
}
#main-feature h1 {
float: left;
}
#main-feature h2 {
float: left;
font-size: 24px;
color: #fff;
width: 330px;
margin-top: 60px;
margin-right: 35px;
line-height: 1.5;
}
/* }}} */
/* {{{ Download */
#download {
float: left;
width: 280px;
margin-top: 45px;
background: url(../../img/firefoxcup/background-download.png) top right no-repeat;
}
#download a,
#download a span {
display: block;
color: #fff;
}
#download a span.title {
font-size: 24px;
line-height: 1.5;
padding: 15px 0 0 5px;
color: #fff;
}
#download a span {
padding: 0 90px 5px 5px;
}
#download a:link,
#download a:visited,
#download a:hover,
#download a:active {
text-decoration: none;
}
#download a:hover span.title,
#download a:active span.title {
text-decoration: underline;
}
/* }}} */
/* {{{ Main Content */
#main-content {
clear: both;
float: left;
display: inline;
width: 575px;
padding: 35px 15px 15px 35px;
margin: 0 35px 25px 25px;
background: #fff;
color: #333;
border: 1px solid #eee;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-moz-box-shadow: 1px 1px 2px rgba(0,0,0,0.1), 0 -20px 45px rgba(0,0,0,0.08) inset;
-webkit-box-shadow: 1px 1px 2px rgba(0,0,0,0.1), 0 -20px 45px rgba(0,0,0,0.08) inset;
min-height: 300px;
background: #fff url(../../img/firefoxcup/preview-uk.jpg) 10px 100px no-repeat;
}
#main-content h2 {
color: #333;
float: left;
width: 235px;
font-size: 20px;
margin-right: 15px;
line-height: 1.3;
}
#personas {
float: left;
width: 325px;
}
#personas-header h3 {
color: #666;
font-size: 13px;
float: left;
margin-left: 5px;
margin-top: 5px;
padding-right: 25px;
background: url(../../img/firefoxcup/arrow.png) 100% 50% no-repeat;
}
#personas-nav {
float: right;
}
#personas-nav li {
float: left;
}
#personas-nav li a {
border-left: 1px solid #13a5ff;
padding: 0 8px;
display: block;
}
#personas-nav li a.selected {
color: #666;
}
#personas-nav li.first a {
border-left: 0;
}
.pager-content {
clear: both;
}
ul.personas-list {
}
.personas-list li {
float: left;
width: 150px;
margin: 5px;
}
.persona-small .persona-preview [data-browsertheme] {
width: 150px;
height: 50px;
border: none !important;
}
.persona-inner {
padding: 0;
}
.persona-hover .persona-inner {
background: none;
}
#personas p {
margin-left: 5px;
padding: 20px 0;
clear: both;
}
/* }}} */
/* {{{ Sidebar */
#sidebar {
float: left;
width: 275px;
}
#sidebar .subfeatures li {
}
#sidebar .subfeatures li a:link,
#sidebar .subfeatures li a:visited,
#sidebar .subfeatures li a:hover,
#sidebar .subfeatures li a:active {
color: #333;
text-decoration: none;
}
#sidebar .subfeatures li a:hover,
#sidebar .subfeatures li a:active {
color: #000;
border-color: #ccc;
}
#sidebar .subfeatures li a {
display: block;
padding: 17px 20px 20px 20px;
padding-left: 75px;
background: #fff;
background-repeat: no-repeat;
background-position: 10px 20px;
margin: 0 0 20px 0;
border: 1px solid #eee;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-moz-box-shadow: 1px 1px 2px rgba(0,0,0,0.1), 0 -20px 45px rgba(0,0,0,0.08) inset;
-webkit-box-shadow: 1px 1px 2px rgba(0,0,0,0.1), 0 -20px 45px rgba(0,0,0,0.08) inset;
}
#sidebar .subfeatures span.title {
font-size: 22px;
}
#sidebar .subfeatures span {
display: block;
}
#sidebar .subfeatures li#featured a {
display: block;
min-height: 80px;
}
#sidebar .subfeatures li a#featured-footiefox {
background-image: url(../../img/firefoxcup/footiefox.png);
}
#sidebar .subfeatures li a#featured-rockyourfirefox {
background-image: url(../../img/firefoxcup/rockyourfirefox.png);
background-position: 0 0;
}
#sidebar .subfeatures li a#featured-amo {
background-image: url(../../img/firefoxcup/addons.png);
background-position: 10px 20px;
}
#sidebar #email a {
background-image: url(../../img/firefoxcup/email.png);
min-height: 62px;
}
#sidebar #facebook a {
background-image: url(../../img/firefoxcup/facebook.png);
min-height: 54px;
}
.default #sidebar .subfeatures li a#featured-footiefox { display: block; }
.default #sidebar .subfeatures li a#featured-rockyourfirefox,
.default #sidebar .subfeatures li a#featured-amo { display: none; }
.rockyourfirefox #sidebar .subfeatures li a#featured-rockyourfirefox { display: block; }
.rockyourfirefox #sidebar .subfeatures li a#featured-footiefox,
.rockyourfirefox #sidebar .subfeatures li a#featured-amo { display: none; }
.amo #sidebar .subfeatures li a#featured-amo { display: block; }
.amo #sidebar .subfeatures li a#featured-footiefox,
.amo #sidebar .subfeatures li a#featured-rockyourfirefox { display: none; }
/* }}} */
/* {{{ Teams Personas */
#secondary-content {
clear: both;
padding-left: 25px;
}
#secondary-content h2 {
font-size: 22px;
color: #333;
}
#teams-section {
width: 625px;
}
#teams {
width: 625px;
float: left;
border-collapse: separate;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-moz-box-shadow: 1px 1px 2px rgba(0,0,0,0.1), 0 -20px 45px rgba(0,0,0,0.08) inset;
-webkit-box-shadow: 1px 1px 2px rgba(0,0,0,0.1), 0 -20px 45px rgba(0,0,0,0.08) inset;
margin: 25px 35px 25px 0;
}
#teams th,
#teams td {
padding: 8px 12px;
}
#teams thead th {
text-align: center;
background-color: #48b4d5;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(87,200,231)), color-stop(1, rgb(54,168,206)));
background-image: -moz-linear-gradient(center top, rgb(87,200,231) 0%, rgb(54,168,206) 100%);
color: #fff;
font-size: 16px;
padding: 12px;
border-left: 1px solid #4cb8d8;
border-right: 1px solid #71c7e0;
}
#teams thead th:first-child {
-webkit-border-top-left-radius: 10px;
-moz-border-radius-topleft: 10px;
border-top-left-radius: 10px;
border-left: 0;
}
#teams thead th:last-child {
-webkit-border-top-right-radius: 10px;
-moz-border-radius-topright: 10px;
border-top-right-radius: 10px;
border-right: 0;
}
#teams thead td {
background: #a8e3f6;
padding: 1px;
}
#teams tbody td {
background: #fff;
border-left: 1px solid #fff;
border-right: 1px solid #c0e2ec;
vertical-align: middle;
}
#teams tbody tr:nth-child(even) td {
background: #dff4fa;
}
#teams tbody td:first-child {
border-left: 1px solid #eee;
}
#teams tbody td:last-child {
border-right: 1px solid #eee;
}
#teams tbody tr:last-child td {
border-bottom: 1px solid #eee;
}
#teams tbody tr:last-child td:first-child {
-webkit-border-bottom-left-radius: 10px;
-moz-border-radius-bottomleft: 10px;
border-bottom-left-radius: 10px;
}
#teams tbody tr:last-child td:last-child {
-webkit-border-bottom-right-radius: 10px;
-moz-border-radius-bottomright: 10px;
border-bottom-right-radius: 10px;
}
#teams tfoot { display: none; }
#teams tfoot td {
-webkit-border-bottom-right-radius: 10px;
-webkit-border-bottom-left-radius: 10px;
-moz-border-radius-bottomright: 10px;
-moz-border-radius-bottomleft: 10px;
border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px;
background: #fff;
padding: 5px;
}
#teams img {
display: block;
margin: 0 auto;
}
/* }}} */
/* {{{ Tweets */
#tweets {
width: 275px;
float: left;
display: inline;
border-collapse: separate;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-moz-box-shadow: 1px 1px 2px rgba(0,0,0,0.1), 0 -20px 45px rgba(0,0,0,0.08) inset;
-webkit-box-shadow: 1px 1px 2px rgba(0,0,0,0.1), 0 -20px 45px rgba(0,0,0,0.08) inset;
margin: 25px 0;
}
#tweets th,
#tweets td {
padding: 8px 12px;
}
#tweets thead th {
background-color: #58cf50;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(95,219,87)), color-stop(1, rgb(82,196,74)));
background-image: -moz-linear-gradient(center top, rgb(95,219,87) 0%, rgb(82,196,74) 100%);
color: #fff;
font-size: 16px;
padding: 4px 12px;
-webkit-border-top-left-radius: 10px;
-moz-border-radius-topleft: 10px;
border-top-left-radius: 10px;
-webkit-border-top-right-radius: 10px;
-moz-border-radius-topright: 10px;
border-top-right-radius: 10px;
}
#tweets thead th a {
display: block;
background: url(../../img/firefoxcup/twitter.png) 0 50% no-repeat;
padding: 12px 0;
padding-left: 50px;
}
#tweets thead th a:link,
#tweets thead th a:visited,
#tweets thead th a:hover,
#tweets thead th a:active {
color: #fff;
}
#tweets thead th a:hover,
#tweets thead th a:active {
text-decoration: underline;
}
#tweets thead th img {
vertical-align: middle;
margin-right: 8px;
}
#tweets thead td {
background: #d5ead5;
padding: 1px;
}
#tweets tbody td {
background: #fff;
border-width: 1px;
border-style: solid;
border-color: #f2fcf1 #eee #e3f8df #eee;
}
#tweets tbody tr:nth-child(even) td {
background: #e3f8df;
}
#tweets tbody td:first-child {
border-left: 1px solid #eee;
}
#tweets tbody td:last-child {
border-right: 1px solid #eee;
}
#tweets tbody tr:last-child td {
border-bottom: 1px solid #eee;
}
#tweets tbody tr:last-child td:first-child {
-webkit-border-bottom-left-radius: 10px;
-moz-border-radius-bottomleft: 10px;
border-bottom-left-radius: 10px;
}
#tweets tbody tr:last-child td:last-child {
-webkit-border-bottom-right-radius: 10px;
-moz-border-radius-bottomright: 10px;
border-bottom-right-radius: 10px;
}
#tweets tfoot { display: none; }
#tweets tfoot td {
-webkit-border-bottom-right-radius: 10px;
-webkit-border-bottom-left-radius: 10px;
-moz-border-radius-bottomright: 10px;
-moz-border-radius-bottomleft: 10px;
border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px;
background: #fff;
padding: 5px;
}
/* }}} */
/* {{{ Reset AMO Styles */
table {
border-bottom: 0;
}
thead th {
border: 0;
}
tbody {
border: 0;
}
tbody tr th, tbody tr td {
border-top: 0;
}
/* }}} */

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Двоичные данные
media/img/firefoxcup/addons.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.0 KiB

Двоичные данные
media/img/firefoxcup/arrow.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичные данные
media/img/firefoxcup/background-download.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 20 KiB

Двоичные данные
media/img/firefoxcup/background-repeat.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.7 KiB

Двоичные данные
media/img/firefoxcup/background.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 73 KiB

Двоичные данные
media/img/firefoxcup/email.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.2 KiB

Двоичные данные
media/img/firefoxcup/facebook.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.2 KiB

Двоичные данные
media/img/firefoxcup/flags/algeria.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.1 KiB

Двоичные данные
media/img/firefoxcup/flags/argentina.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичные данные
media/img/firefoxcup/flags/australia.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.2 KiB

Двоичные данные
media/img/firefoxcup/flags/brazil.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.4 KiB

Двоичные данные
media/img/firefoxcup/flags/cameroon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.0 KiB

Двоичные данные
media/img/firefoxcup/flags/chile.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.8 KiB

Двоичные данные
media/img/firefoxcup/flags/cote.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.6 KiB

Двоичные данные
media/img/firefoxcup/flags/denmark.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичные данные
media/img/firefoxcup/flags/england.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.6 KiB

Двоичные данные
media/img/firefoxcup/flags/france.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.7 KiB

Двоичные данные
media/img/firefoxcup/flags/germany.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.6 KiB

Двоичные данные
media/img/firefoxcup/flags/ghana.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.0 KiB

Двоичные данные
media/img/firefoxcup/flags/greece.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.0 KiB

Двоичные данные
media/img/firefoxcup/flags/honduras.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.8 KiB

Двоичные данные
media/img/firefoxcup/flags/italy.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.7 KiB

Двоичные данные
media/img/firefoxcup/flags/japan.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.0 KiB

Двоичные данные
media/img/firefoxcup/flags/korea-dpr.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.2 KiB

Двоичные данные
media/img/firefoxcup/flags/korea-republic.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.0 KiB

Двоичные данные
media/img/firefoxcup/flags/mexico.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичные данные
media/img/firefoxcup/flags/netherlands.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.7 KiB

Двоичные данные
media/img/firefoxcup/flags/new-zealand.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.2 KiB

Двоичные данные
media/img/firefoxcup/flags/nigeria.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.6 KiB

Двоичные данные
media/img/firefoxcup/flags/paraguay.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичные данные
media/img/firefoxcup/flags/portugal.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.4 KiB

Двоичные данные
media/img/firefoxcup/flags/serbia.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.3 KiB

Двоичные данные
media/img/firefoxcup/flags/slovakia.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.2 KiB

Двоичные данные
media/img/firefoxcup/flags/slovenia.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.8 KiB

Двоичные данные
media/img/firefoxcup/flags/south-africa.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.2 KiB

Двоичные данные
media/img/firefoxcup/flags/spain.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.0 KiB

Двоичные данные
media/img/firefoxcup/flags/switzerland.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.8 KiB

Двоичные данные
media/img/firefoxcup/flags/uruguay.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.1 KiB

Двоичные данные
media/img/firefoxcup/flags/usa.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.3 KiB

Двоичные данные
media/img/firefoxcup/footiefox.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.7 KiB

Двоичные данные
media/img/firefoxcup/logo.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 125 KiB

Двоичные данные
media/img/firefoxcup/preview-uk.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 11 KiB

Двоичные данные
media/img/firefoxcup/rockyourfirefox.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 8.4 KiB

Двоичные данные
media/img/firefoxcup/twitter.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.1 KiB

1
media/js/amo2009/amo2009.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,510 @@
// Submit on locale choice
jQuery(function($) {
var f = $('form.languages');
f.find('select').change(function(){ this.form.submit(); });
});
/**
* Initializes pagers on this page after the document has been loaded
*/
YAHOO.util.Event.onDOMReady(function ()
{
var pagers = YAHOO.util.Dom.getElementsByClassName('pager');
for (var i = 0; i < pagers.length; i++) {
new Mozilla.Pager(pagers[i]);
}
});
// create namespace
if (typeof Mozilla == 'undefined') {
var Mozilla = {};
}
/**
* Pager widget
*
* @param DOMElement container
*/
Mozilla.Pager = function(container)
{
this.container = container;
if (!this.container.id) {
YAHOO.util.Dom.generateId(this.container, 'mozilla-pager-');
}
var pager_content_nodes = YAHOO.util.Dom.getElementsByClassName(
'pager-content', 'div', this.container);
this.id = this.container.id;
this.page_container = pager_content_nodes[0];
this.pages_by_id = {};
this.pages = [];
this.previous_page = null;
this.current_page = null;
this.in_animation = null;
this.out_animation = null;
this.random_start_page = (YAHOO.util.Dom.hasClass(this.container, 'pager-random'));
if (YAHOO.util.Dom.hasClass(this.container, 'pager-with-tabs')) {
var pager_tab_nodes = YAHOO.util.Dom.getElementsByClassName(
'pager-tabs', 'ul', this.container);
this.tabs = pager_tab_nodes[0];
} else {
this.tabs = null;
}
if (YAHOO.util.Dom.hasClass(this.container, 'pager-with-nav')) {
this.drawNav();
} else {
this.nav = null;
}
this.history =
(!YAHOO.util.Dom.hasClass(this.container, 'pager-no-history'));
// add pages
var page_nodes = YAHOO.util.Dom.getChildrenBy(this.page_container,
function (n) { return (n.nodeName == 'DIV'); });
if (this.tabs) {
// initialize pages with tabs
var tab_nodes = YAHOO.util.Dom.getChildrenBy(this.tabs,
function (n)
{
return (!YAHOO.util.Dom.hasClass(n, 'pager-not-tab'));
});
var index = 0;
for (var i = 0; i < page_nodes.length; i++) {
if (i < tab_nodes.length) {
var tab_node = YAHOO.util.Dom.getFirstChildBy(tab_nodes[i],
function(n) { return (n.nodeName == 'A'); });
if (tab_node) {
this.addPage(new Mozilla.Page(page_nodes[i], index,
tab_node));
index++;
}
}
}
} else {
// initialize pages without tabs
for (var i = 0; i < page_nodes.length; i++) {
this.addPage(new Mozilla.Page(page_nodes[i], i));
}
}
// initialize current page
var current_page = null;
if (this.history) {
var hash = location.hash;
hash = (hash.substring(0, 1) == '#') ? hash.substring(1) : hash;
if (hash.length) {
current_page = this.pages_by_id[hash];
if (current_page) {
this.setPage(current_page);
}
}
// check if window location changes from back/forward button use
// this doesn't matter in IE and Opera but is nice for Firefox and
// recent Safari users.
function setupInterval(pager)
{
var interval_function = function()
{
pager.checkLocation();
}
setInterval(interval_function,
(Mozilla.Pager.LOCATION_INTERVAL * 1000), pager);
}
setupInterval(this);
}
if (!current_page && this.pages.length > 0) {
if (this.random_start_page) {
this.setPage(this.getPseudoRandomPage());
} else {
var def_page = YAHOO.util.Dom.getFirstChildBy(this.page_container,
function(n){return YAHOO.util.Dom.hasClass(n, 'default-page')});
if (def_page) {
var def_id;
if (def_page.id.substring(0, 5) == 'page-') {
def_id = def_page.id.substring(5);
} else {
def_id = def_page.id;
}
this.setPage(this.pages_by_id[def_id]);
} else {
this.setPage(this.pages[0]);
}
}
}
}
Mozilla.Pager.prototype.getPseudoRandomPage = function()
{
var page = null;
if (this.pages.length > 0) {
var now = new Date();
page = this.pages[now.getSeconds() % this.pages.length];
}
return page;
}
Mozilla.Pager.PAGE_DURATION = 0.15; // seconds
Mozilla.Pager.LOCATION_INTERVAL = 0.20; // seconds
Mozilla.Pager.NEXT_TEXT = 'Next';
Mozilla.Pager.PREV_TEXT = 'Previous';
Mozilla.Pager.PAGE_NUMBER_TEXT = '%s / %s';
Mozilla.Pager.prototype.prevPageWithAnimation = function()
{
var index = this.current_page.index - 1;
if (index < 0) {
index = this.pages.length - 1;
}
this.setPageWithAnimation(this.pages[index]);
}
Mozilla.Pager.prototype.nextPageWithAnimation = function()
{
var index = this.current_page.index + 1;
if (index >= this.pages.length) {
index = 0;
}
this.setPageWithAnimation(this.pages[index]);
}
Mozilla.Pager.prototype.drawNav = function()
{
// create previous link
this.prev = document.createElement('a');
this.prev.href = '#';
YAHOO.util.Dom.addClass(this.prev, 'pager-prev');
this.prev.title = Mozilla.Pager.PREV_TEXT;
this.prev.appendChild(document.createTextNode(''));
this.prev_insensitive = document.createElement('span');
this.prev_insensitive.style.display = 'none';
YAHOO.util.Dom.addClass(this.prev_insensitive, 'pager-prev-insensitive');
YAHOO.util.Event.on(this.prev, 'click',
function (e)
{
YAHOO.util.Event.preventDefault(e);
this.prevPageWithAnimation();
},
this, true);
YAHOO.util.Event.on(this.prev, 'dblclick',
function (e)
{
YAHOO.util.Event.preventDefault(e);
},
this, true);
// create next link
this.next = document.createElement('a');
this.next.href = '#';
YAHOO.util.Dom.addClass(this.next, 'pager-next');
this.next.title = Mozilla.Pager.NEXT_TEXT;
this.next.appendChild(document.createTextNode(''));
this.next_insensitive = document.createElement('span');
this.next_insensitive.style.display = 'none';
YAHOO.util.Dom.addClass(this.next_insensitive, 'pager-next-insensitive');
YAHOO.util.Event.on(this.next, 'click',
function (e)
{
YAHOO.util.Event.preventDefault(e);
this.nextPageWithAnimation();
},
this, true);
YAHOO.util.Event.on(this.next, 'dblclick',
function (e)
{
YAHOO.util.Event.preventDefault(e);
},
this, true);
// create navigation element
var divider = document.createElement('span');
divider.appendChild(document.createTextNode('|'));
YAHOO.util.Dom.addClass(divider, 'pager-nav-divider');
this.page_number = document.createElement('span');
YAHOO.util.Dom.addClass(this.page_number, 'pager-nav-page-number');
this.nav = document.createElement('div');
YAHOO.util.Dom.addClass(this.nav, 'pager-nav');
this.nav.appendChild(this.page_number);
this.nav.appendChild(this.prev_insensitive);
this.nav.appendChild(this.prev);
this.nav.appendChild(divider);
this.nav.appendChild(this.next);
this.nav.appendChild(this.next_insensitive);
this.container.insertBefore(this.nav, this.page_container);
}
Mozilla.Pager.prototype.checkLocation = function()
{
var hash = location.hash;
hash = (hash.substring(0, 1) == '#') ? hash.substring(1) : hash;
var current_hash = this.current_page.id;
if (hash && hash !== current_hash) {
var page = this.pages_by_id[hash];
if (page) {
this.setPageWithAnimation(page);
this.current_page.focusTab(); // for accessibility
}
}
}
Mozilla.Pager.prototype.addPage = function(page)
{
this.pages_by_id[page.id] = page;
this.pages.push(page);
if (page.tab) {
YAHOO.util.Event.on(page.tab, 'click',
function (e)
{
YAHOO.util.Event.preventDefault(e);
this.setPageWithAnimation(page);
},
this, true);
}
}
Mozilla.Pager.prototype.update = function()
{
if (this.tabs) {
this.updateTabs();
}
if (this.nav) {
this.updateNav();
}
}
Mozilla.Pager.prototype.updateTabs = function()
{
var class_name = this.tabs.className;
class_name = class_name.replace(/pager-selected-[\w-]+/g, '');
class_name = class_name.replace(/^\s+|\s+$/g,'');
this.tabs.className = class_name;
this.current_page.selectTab();
YAHOO.util.Dom.addClass(this.tabs,
'pager-selected-' + this.current_page.id);
}
Mozilla.Pager.prototype.updateNav = function()
{
// update page number
var page_number = this.current_page.index + 1;
var page_count = this.pages.length;
var text = Mozilla.Pager.PAGE_NUMBER_TEXT.replace(/%s/, page_number);
text = text.replace(/%s/, page_count);
if (this.page_number.firstChild) {
this.page_number.replaceChild(document.createTextNode(text),
this.page_number.firstChild);
} else {
this.page_number.appendChild(document.createTextNode(text));
}
// update previous link
this.setPrevSensitivity(this.current_page.index != 0);
// update next link
this.setNextSensitivity(this.current_page.index != this.pages.length - 1);
}
Mozilla.Pager.prototype.setPrevSensitivity = function(sensitive)
{
if (sensitive) {
this.prev_insensitive.style.display = 'none';
this.prev.style.display = 'inline';
} else {
this.prev_insensitive.style.display = 'inline';
this.prev.style.display = 'none';
}
}
Mozilla.Pager.prototype.setNextSensitivity = function(sensitive)
{
if (sensitive) {
this.next_insensitive.style.display = 'none';
this.next.style.display = 'inline';
} else {
this.next_insensitive.style.display = 'inline';
this.next.style.display = 'none';
}
}
Mozilla.Pager.prototype.setPage = function(page)
{
if (this.current_page !== page) {
if (this.current_page) {
this.current_page.deselectTab();
this.current_page.hide();
}
if (this.previous_page) {
this.previous_page.hide();
}
this.previous_page = this.current_page;
this.current_page = page;
this.current_page.show();
this.update();
}
}
Mozilla.Pager.prototype.setPageWithAnimation = function(page)
{
if (this.current_page !== page) {
if (this.history) {
// set address bar to current page
var base_location = location.href.split('#')[0];
location.href = base_location + '#' + page.id;
}
// deselect last selected page (not necessarily previous page)
if (this.current_page) {
this.current_page.deselectTab();
}
// start opacity at current opacity if page was changed while another
// page was fading in
if (this.in_animation && this.in_animation.isAnimated()) {
var start_opacity = parseFloat(YAHOO.util.Dom.getStyle(
this.page_container, 'opacity'));
this.in_animation.stop(false);
} else {
var start_opacity = 1.0;
}
// fade out if we're not already fading out
if (!this.out_animation || !this.out_animation.isAnimated()) {
// only set previous page if we are not already fading out
this.previous_page = this.current_page;
this.out_animation = new YAHOO.util.Anim(this.page_container,
{ opacity: { from: start_opacity, to: 0 } },
Mozilla.Pager.PAGE_DURATION, YAHOO.util.Easing.easeOut);
this.out_animation.onComplete.subscribe(this.fadeInPage,
this, true);
this.out_animation.animate();
}
// always set current page
this.current_page = page;
this.update();
}
// for Safari 1.5.x bug setting window.location.
return false;
}
Mozilla.Pager.prototype.fadeInPage = function()
{
if (this.previous_page) {
this.previous_page.hide();
}
this.current_page.show();
this.in_animation = new YAHOO.util.Anim(this.page_container,
{ opacity: { from: 0, to: 1 } }, Mozilla.Pager.PAGE_DURATION,
YAHOO.util.Easing.easeIn);
this.in_animation.animate();
}
/**
* Page in a pager
*
* @param DOMElement element
* @param DOMElement tab_element
*/
Mozilla.Page = function(element, index, tab_element)
{
this.element = element;
if (!this.element.id) {
YAHOO.util.Dom.generateId(this.element, 'mozilla-pager-page-');
}
// Change element id so updating the window.location does not navigate to
// the page. This is mostly for IE.
if (this.element.id.substring(0, 5) == 'page-') {
this.id = this.element.id.substring(5);
} else {
this.id = this.element.id;
}
this.element.id = 'page-' + this.id;
this.index = index;
if (tab_element) {
this.tab = tab_element;
this.tab.href = '#' + this.id;
} else {
this.tab = null;
}
this.hide();
}
Mozilla.Page.prototype.selectTab = function()
{
if (this.tab) {
YAHOO.util.Dom.addClass(this.tab, 'selected');
}
}
Mozilla.Page.prototype.deselectTab = function()
{
if (this.tab) {
YAHOO.util.Dom.removeClass(this.tab, 'selected');
}
}
Mozilla.Page.prototype.focusTab = function()
{
if (this.tab) {
this.tab.focus();
}
}
Mozilla.Page.prototype.hide = function()
{
this.element.style.display = 'none';
}
Mozilla.Page.prototype.show = function()
{
this.element.style.display = 'block';
}

12
media/js/firefoxcup/yahoo-dom-event.js поставляемый Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -23,3 +23,4 @@ django-pylibmc==0.2.1
-e git://github.com/clouserw/tower.git#egg=tower
-e git://github.com/jbalogh/django-queryset-transform.git#egg=django-queryset-transform
-e git://github.com/jsocol/commonware.git#egg=commonware
-e git://github.com/abuchanan/twitter-text-python.git#egg=twitter-text-python

Просмотреть файл

@ -106,7 +106,7 @@ ADMIN_MEDIA_PREFIX = '/admin-media/'
# paths that don't require an app prefix
SUPPORTED_NONAPPS = ('admin', 'developers', 'editors', 'img', 'jsi18n',
'localizers', 'media', 'statistics', 'services')
'localizers', 'media', 'statistics', 'services', 'firefoxcup')
DEFAULT_APP = 'firefox'
# paths that don't require a locale prefix
@ -207,6 +207,7 @@ INSTALLED_APPS = (
'discovery',
'editors',
'files',
'firefoxcup',
'jingo_minify',
'nick',
'pages',
@ -253,7 +254,15 @@ SELENIUM_CONFIG = {}
# Tells the extract script what files to look for l10n in and what function
# handles the extraction. The Tower library expects this.
DOMAIN_METHODS = {
'firefoxcup': [
('apps/firefoxcup/**.py',
'tower.management.commands.extract.extract_tower_python'),
('apps/firefoxcup/templates/firefoxcup/**.html',
'tower.management.commands.extract.extract_tower_template'),
],
'messages': [
('apps/firefoxcup/**',
'ignore'),
('apps/**.py',
'tower.management.commands.extract.extract_tower_python'),
('**/templates/**.html',
@ -273,6 +282,13 @@ DOMAIN_METHODS = {
],
}
# These domains will not be merged into z-keys.pot and will use separate PO
# files.
STANDALONE_DOMAINS = [
'javascript',
'firefoxcup',
]
# Bundles is a dictionary of two dictionaries, css and js, which list css files
# and js files that can be bundled together by the minify app.
MINIFY_BUNDLES = {
@ -292,6 +308,13 @@ MINIFY_BUNDLES = {
'zamboni/discovery-pane': (
'css/zamboni/discovery-pane.css',
),
# CSS files specific to /firefoxcup/
'firefoxcup': (
'css/firefoxcup/reset-fonts-grids.css',
'css/main.css',
'css/zamboni/zamboni.css',
'css/firefoxcup/firefoxcup.css',
),
},
'js': {
# JS files common to the entire site.
@ -324,6 +347,15 @@ MINIFY_BUNDLES = {
# Collections
'js/zamboni/collections.js',
),
# JS files specific to /firefoxcup/
'firefoxcup': (
'js/zamboni/jquery-1.4.2.min.js',
'js/firefoxcup/yahoo-dom-event.js',
'js/firefoxcup/animation-min.js',
'js/zamboni/jquery.hoverIntent.min.js',
'js/zamboni/personas.js',
'js/firefoxcup/firefoxcup.js',
),
}
}

Просмотреть файл

@ -13,10 +13,12 @@
<meta charset="utf-8">
{{ css('common') }}
{{ css('zamboni/z') }}
<!--[if IE]><link rel="stylesheet" href="{{ MEDIA_URL }}css/ie.css"><![endif]-->
<!--[if IE 7]><link rel="stylesheet" href="{{ MEDIA_URL }}css/ie7.css"><![endif]-->
{% block site_css %}
{{ css('common') }}
{{ css('zamboni/z') }}
<!--[if IE]><link rel="stylesheet" href="{{ MEDIA_URL }}css/ie.css"><![endif]-->
<!--[if IE 7]><link rel="stylesheet" href="{{ MEDIA_URL }}css/ie7.css"><![endif]-->
{% endblock %}
{% block extrahead %}{% endblock %}
<noscript><link rel="stylesheet" href="{{ MEDIA_URL }}css/nojs.css"></noscript>
@ -77,11 +79,15 @@
</div>
{# js #}
<script src="{{ url('jsi18n') }}/build:{{ BUILD_ID_JS }}"></script>
{{ js('common') }}
<script async defer src="{{ url('addons.buttons.js') }}/build:{{ BUILD_ID_JS }}"></script>
{% block site_js %}
<script src="{{ url('jsi18n') }}/build:{{ BUILD_ID_JS }}"></script>
{{ js('common') }}
<script async defer src="{{ url('addons.buttons.js') }}/build:{{ BUILD_ID_JS }}"></script>
{% endblock %}
{% block js %}{% endblock %}
{% include "footer.html" %}
{% block footer %}
{% include "footer.html" %}
{% endblock %}
{# Webtrends Stats Tracking #}
<script defer src="{{ MEDIA_URL }}js/webtrends/webtrends-v0.1.js"></script>
<noscript>

Просмотреть файл

@ -1,17 +1,7 @@
<div id="footer" role="contentinfo">
<div class="section">
<div class="primary">
<form class="languages go" method="get" action="">
<label for="language">{{ _('Other languages:') }}</label>
<select id="language" name="lang" dir="ltr">
{% for code, name in LANGUAGES|dictsort -%}
<option value="{{ code }}" {{ code|ifeq(LANG|lower, "selected") }}>
{{ name }}
</option>
{%- endfor %}
</select>
<button type="submit">{{ _('Go') }}</button>
</form>
{% include 'includes/lang_switcher.html' %}
<p>{% trans legalurl="http://www.mozilla.com/en-US/about/legal.html#site", ccurl="http://creativecommons.org/licenses/by-sa/3.0/" -%}
Except where otherwise <a href="{{ legalurl }}">noted</a>, content on this site is licensed under the
<strong><a href="{{ ccurl }}">Creative Commons Attribution Share-Alike License v3.0</a></strong> or any later version

Просмотреть файл

@ -0,0 +1,11 @@
<form class="languages go" method="get" action="">
<label for="language">{{ _('Other languages:') }}</label>
<select id="language" name="lang" dir="ltr">
{% for code, name in LANGUAGES|dictsort -%}
<option value="{{ code }}" {{ code|ifeq(LANG|lower, "selected") }}>
{{ name }}
</option>
{%- endfor %}
</select>
<button type="submit">{{ _('Go') }}</button>
</form>

Просмотреть файл

@ -68,6 +68,8 @@ urlpatterns = patterns('',
('^personas/film and tv/?$',
lambda r: redirect('browse.personas', 'film-and-tv', permanent=True)),
# Firefox Cup page, /firefoxcup
('^firefoxcup/', include('firefoxcup.urls'))
)
if settings.DEBUG: