Merge remote branch 'buchanan/fxcup23'
|
@ -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,
|
||||
|
|
|
@ -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()
|
|
@ -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 %}
|
|
@ -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)
|
|
@ -0,0 +1,7 @@
|
|||
from django.conf.urls.defaults import patterns, url
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url('^$', views.index, name='firefoxcup.index'),
|
||||
)
|
|
@ -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;
|
||||
}
|
||||
|
||||
/* }}} */
|
После Ширина: | Высота: | Размер: 3.0 KiB |
После Ширина: | Высота: | Размер: 1.2 KiB |
После Ширина: | Высота: | Размер: 20 KiB |
После Ширина: | Высота: | Размер: 6.7 KiB |
После Ширина: | Высота: | Размер: 73 KiB |
После Ширина: | Высота: | Размер: 3.2 KiB |
После Ширина: | Высота: | Размер: 3.2 KiB |
После Ширина: | Высота: | Размер: 3.1 KiB |
После Ширина: | Высота: | Размер: 2.9 KiB |
После Ширина: | Высота: | Размер: 3.2 KiB |
После Ширина: | Высота: | Размер: 3.4 KiB |
После Ширина: | Высота: | Размер: 3.0 KiB |
После Ширина: | Высота: | Размер: 2.8 KiB |
После Ширина: | Высота: | Размер: 2.6 KiB |
После Ширина: | Высота: | Размер: 2.9 KiB |
После Ширина: | Высота: | Размер: 2.6 KiB |
После Ширина: | Высота: | Размер: 2.7 KiB |
После Ширина: | Высота: | Размер: 2.6 KiB |
После Ширина: | Высота: | Размер: 3.0 KiB |
После Ширина: | Высота: | Размер: 3.0 KiB |
После Ширина: | Высота: | Размер: 2.8 KiB |
После Ширина: | Высота: | Размер: 2.7 KiB |
После Ширина: | Высота: | Размер: 3.0 KiB |
После Ширина: | Высота: | Размер: 3.2 KiB |
После Ширина: | Высота: | Размер: 3.0 KiB |
После Ширина: | Высота: | Размер: 2.9 KiB |
После Ширина: | Высота: | Размер: 2.7 KiB |
После Ширина: | Высота: | Размер: 3.2 KiB |
После Ширина: | Высота: | Размер: 2.6 KiB |
После Ширина: | Высота: | Размер: 2.9 KiB |
После Ширина: | Высота: | Размер: 3.4 KiB |
После Ширина: | Высота: | Размер: 3.3 KiB |
После Ширина: | Высота: | Размер: 3.2 KiB |
После Ширина: | Высота: | Размер: 2.8 KiB |
После Ширина: | Высота: | Размер: 3.2 KiB |
После Ширина: | Высота: | Размер: 3.0 KiB |
После Ширина: | Высота: | Размер: 2.8 KiB |
После Ширина: | Высота: | Размер: 3.1 KiB |
После Ширина: | Высота: | Размер: 3.3 KiB |
После Ширина: | Высота: | Размер: 3.7 KiB |
После Ширина: | Высота: | Размер: 125 KiB |
После Ширина: | Высота: | Размер: 11 KiB |
После Ширина: | Высота: | Размер: 8.4 KiB |
После Ширина: | Высота: | Размер: 4.1 KiB |
|
@ -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';
|
||||
}
|
|
@ -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
|
||||
|
|
34
settings.py
|
@ -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>
|
2
urls.py
|
@ -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:
|
||||
|
|