impala add-on listing pages!
This commit is contained in:
Родитель
cbd9f69277
Коммит
a0b67759dc
|
@ -163,6 +163,13 @@ def addon_listing_items(context, addons, show_date=False,
|
|||
return new_context(**locals())
|
||||
|
||||
|
||||
@register.inclusion_tag('addons/impala/listing/items.html')
|
||||
@jinja2.contextfunction
|
||||
def impala_addon_listing_items(context, addons, show_date=False,
|
||||
show_downloads=False, src=None, notes={}):
|
||||
return new_context(**locals())
|
||||
|
||||
|
||||
@register.inclusion_tag('addons/listing/items_compact.html')
|
||||
@jinja2.contextfunction
|
||||
def addon_listing_items_compact(context, addons, show_date=False, src=None):
|
||||
|
@ -181,6 +188,12 @@ def addon_listing_header(context, url_base, sort_opts, selected):
|
|||
return new_context(**locals())
|
||||
|
||||
|
||||
@register.inclusion_tag('addons/impala/listing/sorter.html')
|
||||
@jinja2.contextfunction
|
||||
def impala_addon_listing_header(context, url_base, sort_opts, selected):
|
||||
return new_context(**locals())
|
||||
|
||||
|
||||
@register.filter
|
||||
@jinja2.contextfilter
|
||||
@register.inclusion_tag('addons/impala/addon_grid.html')
|
||||
|
|
|
@ -788,8 +788,13 @@ class Addon(amo.models.OnChangeMixin, amo.models.ModelBase):
|
|||
random.shuffle(specific_locale)
|
||||
return specific_locale + no_locale
|
||||
|
||||
def is_no_restart(self):
|
||||
"""Is this a no-restart add-on?"""
|
||||
files = self.current_version.all_files
|
||||
return files and files[0].no_restart
|
||||
|
||||
def is_featured(self, app, lang):
|
||||
"""is add-on globally featured for this app and language?"""
|
||||
"""Is add-on globally featured for this app and language?"""
|
||||
return self.id in Addon.featured(app, lang)
|
||||
|
||||
def is_category_featured(self, app, lang=None):
|
||||
|
@ -815,7 +820,7 @@ class Addon(amo.models.OnChangeMixin, amo.models.ModelBase):
|
|||
|
||||
@amo.cached_property
|
||||
def tags_partitioned_by_developer(self):
|
||||
"Returns a tuple of developer tags and user tags for this addon."
|
||||
"""Returns a tuple of developer tags and user tags for this addon."""
|
||||
tags = self.tags.not_blacklisted()
|
||||
if self.is_persona:
|
||||
return models.query.EmptyQuerySet(), tags
|
||||
|
|
|
@ -22,12 +22,7 @@
|
|||
<div class="category" class="more-info">{{ cat }}</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
<div class="rating">
|
||||
{{ addon.average_rating|stars }}
|
||||
{% if addon.total_reviews %}
|
||||
({{ addon.total_reviews|numberfmt }})
|
||||
{% endif %}
|
||||
</div>
|
||||
{{ impala_reviews_link(addon) }}
|
||||
</div>
|
||||
</a>
|
||||
<div class="more">
|
||||
|
|
|
@ -52,11 +52,9 @@
|
|||
<h2 class="addon"{{ addon.name|locale_html }}>
|
||||
{{ addon.name }}
|
||||
<span class="version-number">{{ version.version }}</span>
|
||||
{%- with files = addon.current_version.all_files %}
|
||||
{%- if files and files[0].no_restart -%}
|
||||
<span class="no-restart">{{ _('No Restart') }}</span>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% if addon.is_no_restart() %}
|
||||
<span class="no-restart">{{ _('No Restart') }}</span>
|
||||
{% endif %}
|
||||
</h2>
|
||||
<h4 class="author">{{ _('by') }} {{ users_list(addon.listed_authors) }}</h4>
|
||||
</hgroup>
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
{% from "addons/impala/listing/macros.html" import heading, item_info %}
|
||||
{% set collection = collection or None %}
|
||||
{% set username = request.amo_user.username if request.user.is_authenticated() else '' %}
|
||||
|
||||
{% cache addons, extra=[collection, username] %}
|
||||
{% for addon in addons %}
|
||||
<div class="item addon">
|
||||
<div class="info">
|
||||
{{ heading(request, addon, collection=collection) }}
|
||||
{% if addon.is_persona() %}
|
||||
{{ persona_preview(addon.persona, linked=False) }}
|
||||
{% else %}
|
||||
<p class="desc">{{ addon.summary|truncate(250)|nl2br }}</p>
|
||||
{% endif %}
|
||||
{% if notes and notes[addon.id] %}
|
||||
<div class="collector-note">
|
||||
<b>{{ _("Collector's Note") }}</b>
|
||||
{{ notes[addon.id] }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="more c">
|
||||
{{ item_info(addon, amo, show_date) }}
|
||||
</div>
|
||||
{% if settings.PERF_THRESHOLD and addon.ts_slowness >= settings.PERF_THRESHOLD %}
|
||||
{{ impala_performance_note(amount=addon.ts_slowness, listing=True) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{{ install_button(addon, impala=True, collection=collection) }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endcache %}
|
|
@ -0,0 +1,36 @@
|
|||
{% macro heading(request, addon, collection) %}
|
||||
<h3>
|
||||
{% if collection %}
|
||||
{% set collection_path = '?src=collection&collection_id=' + collection.uuid %}
|
||||
{% else %}
|
||||
{% set collection_path = '' %}
|
||||
{% endif %}
|
||||
<a href="{{ addon.get_url_path(impala=True) + collection_path }}">
|
||||
<img src="{{ addon.icon_url }}">{{ addon.name }}</a>
|
||||
{% if addon.is_no_restart() %}
|
||||
<span class="no-restart">{{ _('No Restart') }}</span>
|
||||
{% endif %}
|
||||
{% if addon.is_featured(request.APP, request.LANG) %}
|
||||
<span class="featured">{{ _('Featured') }}</span>
|
||||
{% endif %}
|
||||
</h3>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro item_info(addon, amo, show_date) %}
|
||||
{{ impala_reviews_link(addon) }}
|
||||
<div class="adu">
|
||||
{% with num=addon.average_daily_users %}
|
||||
{# L10n: {0} is the number of users. #}
|
||||
{{ ngettext('{0} user', '{0} users', num)|f(num|numberfmt) }}
|
||||
{% endwith %}
|
||||
</div>
|
||||
{% if show_date in ('created', 'new', 'newest', 'updated') %}
|
||||
<div class="updated">
|
||||
{% if show_date in ('created', 'new', 'newest') %}
|
||||
{{ _('Added {0}')|f(addon.created|datetime) }}
|
||||
{% elif show_date == 'updated' %}
|
||||
{{ _('Updated {0}')|f(addon.last_updated|datetime) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
|
@ -0,0 +1,8 @@
|
|||
<ul id="sorter" class="c">
|
||||
<li>{{ _('Sort by:') }}</li>
|
||||
{% for value, title in sort_opts %}
|
||||
<li {{ value|class_selected(selected) }}>
|
||||
<a href="{{ url_base|urlparams(sort=value) }}">{{ title }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
|
@ -2,7 +2,7 @@
|
|||
{% if listing %}
|
||||
<div class="performance-note">
|
||||
{{ _('This add-on can slow down Firefox.') }}
|
||||
<a href="#">{{ _('More…')|safe }}</a>
|
||||
<a href="#">{{ _('Explain…')|safe }}</a>
|
||||
<div class="popup warning hidden">
|
||||
<p class="msg">
|
||||
{% trans amount=amount|int %}
|
||||
|
|
|
@ -358,6 +358,15 @@ class TestAddonModels(test_utils.TestCase):
|
|||
a.status = amo.STATUS_LISTED
|
||||
assert a.is_selfhosted(), 'listed add-on => is_selfhosted()'
|
||||
|
||||
def test_is_no_restart(self):
|
||||
a = Addon.objects.get(pk=3615)
|
||||
f = a.current_version.all_files[0]
|
||||
eq_(f.no_restart, False)
|
||||
eq_(a.is_no_restart(), False)
|
||||
|
||||
f.update(no_restart=True)
|
||||
eq_(Addon.objects.get(pk=3615).is_no_restart(), True)
|
||||
|
||||
def test_is_featured(self):
|
||||
"""Test if an add-on is globally featured"""
|
||||
a = Addon.objects.get(pk=1003)
|
||||
|
|
|
@ -324,6 +324,11 @@ class BaseFilter(object):
|
|||
def _filter(self, field):
|
||||
return getattr(self, 'filter_%s' % field)()
|
||||
|
||||
def filter_featured(self):
|
||||
ids = Addon.featured_random(self.request.APP, self.request.LANG)
|
||||
qs = Addon.objects
|
||||
return qs.filter(id__in=ids) if ids else qs.none()
|
||||
|
||||
def filter_popular(self):
|
||||
return (Addon.objects.order_by('-weekly_downloads')
|
||||
.with_index(addons='downloads_type_idx'))
|
||||
|
|
|
@ -100,6 +100,12 @@ def paginator(pager):
|
|||
return Paginator(pager).render()
|
||||
|
||||
|
||||
@register.filter
|
||||
def impala_paginator(pager):
|
||||
t = env.get_template('amo/impala/paginator.html')
|
||||
return jinja2.Markup(t.render(pager=pager))
|
||||
|
||||
|
||||
@register.filter
|
||||
def mobile_paginator(pager):
|
||||
t = env.get_template('amo/mobile/paginator.html')
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
{% if pager.paginator.num_pages > 1 %}
|
||||
<nav class="paginator c">
|
||||
<p class="num">
|
||||
{# L10n: {0} is a page number. #}
|
||||
<a href="{{ pager.url|urlparams(page=pager.number) }}">
|
||||
{{ _('Page {0}')|f(pager.number) }}</a>
|
||||
</p>
|
||||
<p class="rel">
|
||||
<a href="{{ pager.url|urlparams(page=1) }}"
|
||||
{% if not pager.has_previous() %}class="disabled"{% endif %}>
|
||||
◂◂</a>
|
||||
<a href="{{ pager.url|urlparams(page=pager.previous_page_number()) }}"
|
||||
class="button{% if not pager.has_previous() %} disabled{% endif %}">
|
||||
◂ {{ _('Previous') }}</a>
|
||||
<a href="{{ pager.url|urlparams(page=pager.next_page_number()) }}"
|
||||
class="button{% if not pager.has_next() %} disabled{% endif %}">
|
||||
{{ _('Next') }} ▸</a>
|
||||
<a href="{{ pager.url|urlparams(page=pager.paginator.num_pages) }}"
|
||||
{% if not pager.has_next() %}class="disabled"{% endif %}>
|
||||
▸▸</a>
|
||||
</p>
|
||||
<p class="pos">
|
||||
{# L10n: first and second arguments are the result range (e.g., 1-20);
|
||||
third argument is the number of total results (e.g., 1,000). #}
|
||||
{% trans begin=pager.start_index(), end=pager.end_index(),
|
||||
count=pager.paginator.count|numberfmt %}
|
||||
Showing <b>{{ begin }}</b>–<b>{{ end }}</b> of <b>{{ count }}</b>
|
||||
{% endtrans %}
|
||||
</p>
|
||||
</nav>
|
||||
{% endif %}
|
|
@ -7,7 +7,7 @@
|
|||
<h2>{{ _('Explore') }}</h2>
|
||||
<ul>
|
||||
{% for sort, title in extras %}
|
||||
<li><em><a href="{{ base_url|urlparams(sort=sort) }}">{{ title }}</a></em></li>
|
||||
<li class="s-{{ sort }}"><em><a href="{{ base_url|urlparams(sort=sort) }}">{{ title }}</a></em></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
{{ page_title(category.name if category else _('Extensions')) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block extrahead %}
|
||||
{% if category %}
|
||||
{% block bodyclass %}s-{{ sorting }}{% endblock %}
|
||||
|
||||
{% if category %}
|
||||
{% block extrahead %}
|
||||
<style>
|
||||
#c-{{ category.id }} a {
|
||||
background: #ecf5fe;
|
||||
|
@ -16,27 +18,28 @@
|
|||
color: inherit;
|
||||
}
|
||||
</style>
|
||||
<link rel="canonical" href="{{ category.get_url_path() }}">
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% set sort = {'featured': 'featured',
|
||||
'created': 'newest',
|
||||
'popular': 'popular',
|
||||
'rating': 'averagerating'}[sorting] %}
|
||||
{% if not sort %}
|
||||
{% set sort = 'updated' %}
|
||||
{% endif %}
|
||||
|
||||
{% if category %}
|
||||
{% set feed = url('browse.extensions.rss', category.slug) %}
|
||||
{% else %}
|
||||
{% set feed = url('browse.extensions.rss') %}
|
||||
{% endif %}
|
||||
|
||||
{% set feed_url = feed|urlparams(sort=sort) %}
|
||||
|
||||
{% block rss_feed %}
|
||||
{% with sort = {'featured': 'featured',
|
||||
'created': 'newest',
|
||||
'popular': 'popular',
|
||||
'rating': 'averagerating'}[sorting] %}
|
||||
{% if not sort %}
|
||||
{% set sort = 'updated' %}
|
||||
{% endif %}
|
||||
|
||||
{% if category %}
|
||||
{% set feed = url('browse.extensions.rss', category.slug) %}
|
||||
{% else %}
|
||||
{% set feed = url('browse.extensions.rss') %}
|
||||
{% endif %}
|
||||
<link rel="alternate" type="application/rss+xml" title="RSS"
|
||||
href="{{ feed }}?sort={{ sort }}">
|
||||
{% endwith %}
|
||||
<link rel="alternate" type="application/rss+xml" title="RSS"
|
||||
href="{{ feed_url }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
|
|
@ -1,9 +1,39 @@
|
|||
{% extends "browse/impala/base_listing.html" %}
|
||||
|
||||
{% if category %}
|
||||
{% set url_base = url('i_browse.extensions', category.slug) %}
|
||||
{% else %}
|
||||
{% set url_base = url('i_browse.extensions') %}
|
||||
{% endif %}
|
||||
|
||||
{% set extras = (
|
||||
('featured', _('Featured')),
|
||||
('popular', _('Most Popular')),
|
||||
('rating', _('Top Rated')),
|
||||
('updated', _('Last Updated')),
|
||||
) %}
|
||||
|
||||
{% block primary %}
|
||||
<section class="primary">
|
||||
<div class="island c">
|
||||
<h2>{{ category.name if category else _('Extensions') }}</h2>
|
||||
<div class="island hero c">
|
||||
<header>
|
||||
{% with heading = {'featured': _('Featured Extensions'),
|
||||
'created': _('Newest Extensions'),
|
||||
'popular': _('Most Popular Extensions'),
|
||||
'rating': _('Top Rated Extensions'),
|
||||
'updated': _('Last Updated Extensions')}[sorting] %}
|
||||
<h2>{{ category.name if category else heading }}</h2>
|
||||
{% endwith %}
|
||||
<a href="{{ feed_url }}" class="feed">{{ _('Subscribe') }}</a>
|
||||
{{ impala_addon_listing_header(url_base, extras, sorting) }}
|
||||
</header>
|
||||
|
||||
{{ impala_addon_listing_items(addons.object_list, src='category',
|
||||
show_date=sorting, show_downloads=sorting=='popular') }}
|
||||
|
||||
{% if sorting != 'featured' %}
|
||||
{{ addons|impala_paginator }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,7 +2,6 @@ from django.conf.urls.defaults import patterns, url
|
|||
from django.shortcuts import redirect
|
||||
|
||||
from amo.urlresolvers import reverse
|
||||
from amo.utils import urlparams
|
||||
from browse.feeds import CategoriesRss, FeaturedRss, SearchToolsRss
|
||||
from . import views
|
||||
|
||||
|
|
|
@ -56,6 +56,10 @@ class AddonFilter(BaseFilter):
|
|||
('rating', _lazy(u'Rating')))
|
||||
|
||||
|
||||
class ImpalaAddonFilter(AddonFilter):
|
||||
opts = AddonFilter.opts + (('featured', _lazy(u'Featured')),)
|
||||
|
||||
|
||||
class ESAddonFilter(ESBaseFilter):
|
||||
opts = AddonFilter.opts
|
||||
|
||||
|
@ -153,12 +157,10 @@ def _extensions(request, category=None, is_impala=False, template=None):
|
|||
|
||||
if ('sort' not in request.GET and not request.MOBILE
|
||||
and category and category.count > 4):
|
||||
if is_impala:
|
||||
return impala_category_landing(request, category)
|
||||
else:
|
||||
return category_landing(request, category)
|
||||
return category_landing(request, category, is_impala)
|
||||
|
||||
addons, filter = addon_listing(request, [TYPE])
|
||||
addons, filter = addon_listing(request, [TYPE],
|
||||
ImpalaAddonFilter if is_impala else AddonFilter)
|
||||
|
||||
if category:
|
||||
addons = addons.filter(categories__id=category.id)
|
||||
|
@ -172,12 +174,12 @@ def _extensions(request, category=None, is_impala=False, template=None):
|
|||
|
||||
|
||||
@mobile_template('browse/{mobile/}extensions.html')
|
||||
def extensions(request, category=None, is_impala=False, template=None):
|
||||
return _extensions(request, category, is_impala, template)
|
||||
def extensions(request, category=None, template=None):
|
||||
return _extensions(request, category, False, template)
|
||||
|
||||
|
||||
def impala_extensions(request, category=None, is_impala=True, template=None):
|
||||
return _extensions(request, category, is_impala,
|
||||
def impala_extensions(request, category=None, template=None):
|
||||
return _extensions(request, category, True,
|
||||
'browse/impala/extensions.html')
|
||||
|
||||
|
||||
|
@ -231,26 +233,20 @@ class CategoryLandingFilter(BaseFilter):
|
|||
return manual_order(filter, self.ids, pk_name='addons.id')
|
||||
|
||||
|
||||
def _category_landing(request, category,
|
||||
template='browse/category_landing.html'):
|
||||
def category_landing(request, category, is_impala=False):
|
||||
base = (Addon.objects.listed(request.APP).exclude(type=amo.ADDON_PERSONA)
|
||||
.filter(categories__id=category.id))
|
||||
filter = CategoryLandingFilter(request, base, category,
|
||||
key='browse', default='featured')
|
||||
if is_impala:
|
||||
template = 'browse/impala/category_landing.html'
|
||||
else:
|
||||
template = 'browse/category_landing.html'
|
||||
return jingo.render(request, template,
|
||||
{'category': category, 'filter': filter,
|
||||
'search_cat': '%s,0' % category.type})
|
||||
|
||||
|
||||
def category_landing(request, category):
|
||||
return _category_landing(request, category)
|
||||
|
||||
|
||||
def impala_category_landing(request, category):
|
||||
return _category_landing(request, category,
|
||||
'browse/impala/category_landing.html')
|
||||
|
||||
|
||||
def es_category_landing(request, category):
|
||||
# TODO: Match CategoryLandingFilter.
|
||||
qs = (Addon.search().filter(type=TYPE, app=request.APP.id,
|
||||
|
|
|
@ -28,6 +28,13 @@ def reviews_link(addon, collection_uuid=None, link_to_list=False):
|
|||
collection_uuid=collection_uuid))
|
||||
|
||||
|
||||
@jingo.register.function
|
||||
def impala_reviews_link(addon, collection_uuid=None):
|
||||
t = jingo.env.get_template('reviews/impala/reviews_link.html')
|
||||
return jinja2.Markup(t.render(addon=addon,
|
||||
collection_uuid=collection_uuid))
|
||||
|
||||
|
||||
@jingo.register.function
|
||||
def mobile_reviews_link(addon):
|
||||
t = jingo.env.get_template('reviews/mobile/reviews_link.html')
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
{% set base = url('addons.i_detail', addon.slug)|urlparams('reviews') %}
|
||||
{% if collection_uuid %}
|
||||
{% set base = base|urlparams(collection_uuid=collection_uuid) %}
|
||||
{% endif %}
|
||||
|
||||
<div class="rating">
|
||||
{% with num=addon.total_reviews %}
|
||||
{% if num %}
|
||||
{{ addon.average_rating|float|stars }}
|
||||
<a href="{{ base }}">({{ num|numberfmt }})</a>
|
||||
{% else %}
|
||||
<b>{{ _('Not yet rated') }}</b>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
</div>
|
|
@ -26,7 +26,7 @@
|
|||
.notavail {
|
||||
font-family: @sans-stack;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
line-height: 12px;
|
||||
padding: 1px 0 1px 18px;
|
||||
margin-right: 14px; /* Match the padding of .install. */
|
||||
background: url(../../img/impala/no.png) 0 30% no-repeat;
|
||||
|
@ -285,7 +285,7 @@
|
|||
}
|
||||
|
||||
#reviews .review {
|
||||
border-bottom: 1px dotted #C9DDF2;
|
||||
border-bottom: 1px dotted @border-blue;
|
||||
overflow: hidden;
|
||||
&.no-reviews {
|
||||
border-bottom: 0;
|
||||
|
@ -295,7 +295,7 @@
|
|||
}
|
||||
padding: 1em 0;
|
||||
h3 {
|
||||
color: #333333;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
line-height: 16px;
|
||||
font-style: italic;
|
||||
|
@ -414,18 +414,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
.no-restart {
|
||||
background: none repeat scroll 0 0 #E8933A;
|
||||
border-radius: 2px 2px 2px 2px;
|
||||
color: #FFFFFF;
|
||||
.no-restart,
|
||||
.featured {
|
||||
background-color: #e8933a;
|
||||
border-radius: 2px;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
font-family: Arial;
|
||||
font-size: 9px;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
margin-left: 6px;
|
||||
font: bold 9px/11px Arial;
|
||||
margin-left: 4px;
|
||||
padding: 3px 6px;
|
||||
text-transform: uppercase;
|
||||
vertical-align: 3px;
|
||||
}
|
||||
}
|
||||
.featured {
|
||||
background-color: #093;
|
||||
}
|
||||
|
|
|
@ -131,7 +131,8 @@
|
|||
}
|
||||
.extra {
|
||||
.notavail {
|
||||
color: #C00000;
|
||||
color: @error-red;
|
||||
display: block;
|
||||
margin: 0 0 4px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@import 'lib';
|
||||
|
||||
.p-light {
|
||||
color: #777777;
|
||||
color: #777;
|
||||
font-size: 17px;
|
||||
line-height: 1.3em;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
|||
|
||||
&.fox {
|
||||
background-image: url("../../img/developers/hub-addon-fox.png");
|
||||
background-color: #FFFFFF;
|
||||
background-color: #fff;
|
||||
background-position: 420px center;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
|
@ -34,23 +34,22 @@
|
|||
text-decoration: none;
|
||||
display: inline-block;
|
||||
img {
|
||||
background-color: #FFFFFF;
|
||||
display: inline-block;
|
||||
border: 1px solid #BCDCF2;
|
||||
.border-radius(4px);
|
||||
.box-shadow(0 2px 3px #D1E5F4);
|
||||
margin-left: 1em;
|
||||
opacity: 0.8;
|
||||
padding: 6px;
|
||||
background-color: #fff;
|
||||
display: inline-block;
|
||||
border: 1px solid #BCDCF2;
|
||||
.border-radius(4px);
|
||||
.box-shadow(0 2px 3px #D1E5F4);
|
||||
margin-left: 1em;
|
||||
opacity: 0.8;
|
||||
padding: 6px;
|
||||
}
|
||||
&:hover img {
|
||||
opacity: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
div {
|
||||
padding: 5px 0 0 15px;
|
||||
}
|
||||
div {
|
||||
padding: 5px 0 0 15px;
|
||||
}
|
||||
}
|
||||
p {
|
||||
.p-light;
|
||||
|
@ -58,7 +57,7 @@
|
|||
}
|
||||
h2 {
|
||||
font-family: @serif-stack;
|
||||
color: #C63717;
|
||||
color: @red;
|
||||
font-size: 25px;
|
||||
margin-bottom: 0.5em;
|
||||
strong {
|
||||
|
@ -133,7 +132,7 @@
|
|||
}
|
||||
}
|
||||
.jetpack-builder, .jetpack-sdk {
|
||||
padding: 1em 0em 1em 100px;
|
||||
padding: 1em 0 1em 100px;
|
||||
position: relative;
|
||||
img {
|
||||
position: absolute;
|
||||
|
@ -142,7 +141,7 @@
|
|||
}
|
||||
}
|
||||
.jetpack_footer {
|
||||
color: #555555;
|
||||
color: #555;
|
||||
margin-top: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -193,7 +192,7 @@
|
|||
padding: 1em 0;
|
||||
}
|
||||
p {
|
||||
color: #555555;
|
||||
color: #555;
|
||||
font-family: @sans-stack;
|
||||
line-height: 1.3em;
|
||||
margin-bottom: 1em;
|
||||
|
|
|
@ -301,12 +301,12 @@ button.search-button {
|
|||
}
|
||||
|
||||
.header-search input {
|
||||
background: url("../../img/icons/search.png") no-repeat scroll 8px center #FFFFFF;
|
||||
background: url(../../img/icons/search.png) no-repeat scroll 8px center #fff;
|
||||
float: left;
|
||||
border: 0 none;
|
||||
.border-radius(4px);
|
||||
.box-shadow(0 0 2px rgba(0, 0, 0, 0.4) inset);
|
||||
font-family: Trebuchet MS;
|
||||
font-family: "Trebuchet MS";
|
||||
font-size: 14px;
|
||||
height: 30px;
|
||||
padding: 0 0 0 32px;
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
@link: #447BC4;
|
||||
@note-gray: #999;
|
||||
@red: #C63717;
|
||||
@error-red: #C00000;
|
||||
@orange: #D16B00;
|
||||
@border-blue: #C9DDF2;
|
||||
|
||||
|
||||
// Font Stacks
|
||||
|
@ -118,4 +121,3 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
@import 'lib';
|
||||
|
||||
header .feed {
|
||||
/* TODO(cvan): sprite-ify */
|
||||
background: url(../../img/impala/feed.png) no-repeat 0 50%;
|
||||
float: right;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.html-rtl header .feed {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#sorter {
|
||||
color: @note-gray;
|
||||
font-family: @sans-stack;
|
||||
font-size: 11px;
|
||||
margin: 10px 0 15px;
|
||||
li {
|
||||
float: left;
|
||||
margin: 0;
|
||||
&:first-child + li a {
|
||||
border-left-width: 0;
|
||||
}
|
||||
&.selected a {
|
||||
color: @orange;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
a {
|
||||
border-left: 1px solid #ccc;
|
||||
padding: 0 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.html-rtl #sorter {
|
||||
float: right;
|
||||
li {
|
||||
float: right;
|
||||
&:first-child + li a {
|
||||
border-left-width: 1px;
|
||||
}
|
||||
&:last-child a {
|
||||
border-left: 0 none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
border-top: 1px dotted @border-blue;
|
||||
color: @note-gray;
|
||||
display: table;
|
||||
padding: 20px 0;
|
||||
width: 100%;
|
||||
&:hover {
|
||||
background-color: fadeOut(@border-blue, 90%);
|
||||
.install-shell {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
&.incompatible {
|
||||
&:hover {
|
||||
.extra .notavail {
|
||||
color: @error-red;
|
||||
}
|
||||
}
|
||||
.info {
|
||||
opacity: 0.4;
|
||||
}
|
||||
.install-shell {
|
||||
font: 10px/12px Arial;
|
||||
visibility: visible;
|
||||
.install,
|
||||
br {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
h3 {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
line-height: 18px;
|
||||
img {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 25px;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
}
|
||||
}
|
||||
h3, .desc {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
p {
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
}
|
||||
.rating a {
|
||||
color: @note-gray;
|
||||
}
|
||||
.rating,
|
||||
.adu,
|
||||
.updated {
|
||||
display: inline-block;
|
||||
}
|
||||
.adu {
|
||||
color: #093;
|
||||
}
|
||||
.adu:before,
|
||||
.updated:before {
|
||||
color: @note-gray;
|
||||
content: '\00B7';
|
||||
}
|
||||
.info,
|
||||
.install-shell {
|
||||
display: table-cell;
|
||||
}
|
||||
.info {
|
||||
padding-left: 58px;
|
||||
}
|
||||
.install-shell {
|
||||
text-align: right;
|
||||
padding: 0 10px;
|
||||
min-width: 190px;
|
||||
visibility: hidden;
|
||||
white-space: nowrap;
|
||||
.install-note {
|
||||
text-align: left;
|
||||
}
|
||||
.extra .notavail {
|
||||
color: @note-gray;
|
||||
}
|
||||
}
|
||||
.collector-note,
|
||||
.performance-note {
|
||||
background-color: #e0effd;
|
||||
float: left;
|
||||
line-height: 18px;
|
||||
margin-top: 0.5em;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
.performance-note {
|
||||
background-color: #fff3cc;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.html-rtl .item {
|
||||
.collector-note,
|
||||
.performance-note {
|
||||
float: right;
|
||||
}
|
||||
h3 img {
|
||||
right: 25px;
|
||||
}
|
||||
.info {
|
||||
padding: 0 58px 0 0;
|
||||
}
|
||||
.install-shell {
|
||||
text-align: left;
|
||||
.install-note {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
.paginator {
|
||||
margin-top: 1em;
|
||||
.disabled {
|
||||
opacity: 0.25;
|
||||
pointer-events: none;
|
||||
}
|
||||
p {
|
||||
float: left;
|
||||
margin-top: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.pos,
|
||||
.num a {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
.pos,
|
||||
.num {
|
||||
padding: 7px 0 9px;
|
||||
width: 25%;
|
||||
}
|
||||
.pos {
|
||||
text-align: right;
|
||||
}
|
||||
.rel {
|
||||
text-align: center;
|
||||
width: 50%;
|
||||
a {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
margin-left: 7px;
|
||||
padding: 7px 14px 9px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.html-rtl .paginator {
|
||||
p {
|
||||
float: right;
|
||||
}
|
||||
.pos {
|
||||
text-align: left;
|
||||
}
|
||||
.num {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
|
@ -56,6 +56,7 @@ div.popup-shim {
|
|||
.modal {
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
line-height: 15px;
|
||||
margin-top: 5px;
|
||||
background: #fff;
|
||||
padding: 10px;
|
||||
|
|
|
@ -155,6 +155,19 @@ a {
|
|||
}
|
||||
}
|
||||
|
||||
.s-featured #side-nav .s-featured a,
|
||||
.s-popular #side-nav .s-popular a,
|
||||
.s-rating #side-nav .s-rating a {
|
||||
background: #ecf5fe;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.s-featured #side-nav .s-featured a:after,
|
||||
.s-popular #side-nav .s-popular a:after,
|
||||
.s-rating #side-nav .s-rating a:after {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.cols {
|
||||
.width-calc(~'100% + 1em');
|
||||
overflow: auto;
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 292 B |
|
@ -1,4 +1,17 @@
|
|||
$(function () {
|
||||
$('.performance-note .popup').each(function(i,p) {
|
||||
var $p = $(this),
|
||||
$a = $p.siblings('a').first();
|
||||
$p.popup($a, {width: 300, pointTo: $a});
|
||||
});
|
||||
|
||||
$('.item.addon').each(function(i,p){
|
||||
var $this = $(this);
|
||||
if ($this.find('.concealed').length) {
|
||||
$this.addClass('incompatible');
|
||||
}
|
||||
});
|
||||
|
||||
if (!$("body").hasClass('addon-details')) return;
|
||||
$(".previews").zCarousel({
|
||||
btnNext: ".previews .next",
|
||||
|
@ -115,10 +128,10 @@ $(function () {
|
|||
|
||||
// Show add-on ID when icon is clicked
|
||||
if ($("#addon[data-id], #persona[data-id]").exists()) {
|
||||
$("#addon .icon").click(function() {
|
||||
window.location.hash = "id=" + $("#addon, #persona").attr("data-id");
|
||||
})
|
||||
$("#addon .icon").click(function() {
|
||||
window.location.hash = "id=" + $("#addon, #persona").attr("data-id");
|
||||
});
|
||||
}
|
||||
|
||||
$("#abuse-modal").modal('#report-abuse', { delegate: '#page' });
|
||||
$('#abuse-modal').modal('#report-abuse', {delegate: '#page'});
|
||||
});
|
||||
|
|
|
@ -421,6 +421,8 @@ MINIFY_BUNDLES = {
|
|||
'css/impala/collections.less',
|
||||
'css/impala/abuse.less',
|
||||
'css/impala/prose.less',
|
||||
'css/impala/paginator.less',
|
||||
'css/impala/listing.less',
|
||||
),
|
||||
'zamboni/discovery-pane': (
|
||||
'css/zamboni/discovery-pane.css',
|
||||
|
|
Загрузка…
Ссылка в новой задаче