New popup in JS, ported sharing to new style

This commit is contained in:
Matt Claypotch 2010-08-26 19:29:00 -07:00
Родитель db3a0c6b3a
Коммит b34b5bdc4d
13 изменённых файлов: 206 добавлений и 110 удалений

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

@ -110,12 +110,12 @@
{% endif %}
{% if settings.NEW_COLLECTIONS %}
<div class="widgets">
{{ favorites_widget(addon) }}
{% include 'addons/includes/collection_add_widget.html' %}
{{ sharing_widget(addon) }}
</div>
{% endif %}
{{ sharing_box(addon) }}
</div>{# /secondary #}
</div>{# /featured-inner #}

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

@ -145,7 +145,6 @@ def collection_widgets(context, collection, condensed=False):
c = dict(context.items())
request = c['request']
if collection and request.user.is_authenticated():
c.update({'condensed': condensed,
'c': collection,
})

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

@ -3,7 +3,7 @@
{% for collection in collections %}
<li {{ collection.has_addon|class_selected(True) }}
data-id="{{ collection.id }}">
<span class="collectionitem">{{ collection.name }}</span><a title="{{ _('View this collection') }}" class="outlink" href="{{ collection.get_url_path() }}"></a>
<span>{{ collection.name }}</span><a title="{{ _('View this collection') }}" class="outlink" href="{{ collection.get_url_path() }}"></a>
</li>
{% endfor %}
</ul>

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

@ -1,16 +1,15 @@
{% if request.user.is_authenticated() %}
{% set is_watching = c.id in request.amo_user.watching %}
<div class="collection_widgets">
<div class="collection_widgets{{ ' condensed' if condensed }} widgets">
<a title="{{ (_('Stop Watching') if is_watching else _('Watch this Collection')) if condensed }}"
class="watch{{ ' watching' if is_watching }}"
href="{{ c.watch_url() }}">{{ _('Stop Watching') if is_watching else _('Watch this Collection') }}</a>
{{ sharing_box(c) }}
class="widget watch{{ ' watching' if is_watching }}"
href="{{ c.watch_url() }}"><span>{{ _('Stop Watching') if is_watching else _('Watch this Collection') }}</span></a>
{{ sharing_widget(c, show_email=False) }}
{#
<a title="{{ _('Share this Collection') }}" class="share" href="#"></a>
<a title="{{ _('Copy this Collection') }}" class="copy" href="#"></a>
#}
{% if request.check_ownership(c, require_owner=False) and condensed %}
<a title="{{ _('Edit this Collection') }}" class="edit" href="{{ c.edit_url() }}"></a>
<a title="{{ _('Edit this Collection') }}" class="widget edit" href="{{ c.edit_url() }}"></a>
{% endif %}
</div>
{% endif %}

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

@ -6,33 +6,41 @@ from amo.helpers import login_link
from .models import ServiceBase, EMAIL
@register.inclusion_tag('sharing/sharing_box.html')
@register.inclusion_tag('sharing/sharing_widget.html')
@jinja2.contextfunction
def sharing_box(context, obj, show_email=True):
request = context['request']
opts = {}
def sharing_widget(context, obj, show_email=True):
c = dict(context.items())
services = list(sharing.SERVICES_LIST)
if not show_email:
services.remove(EMAIL)
for service in sharing.SERVICES_LIST:
service_opts = {}
if service == EMAIL and not request.user.is_authenticated():
service_opts['url'] = login_link(context)
service_opts['target'] = '_self'
else:
url = obj.share_url() + '?service=%s' % service.shortname
service_opts['url'] = url
service_opts['target'] = '_blank'
opts[service] = service_opts
share_counts = obj.share_counts()
counts = {}
for service in services:
short = service.shortname
counts[short] = service.count_term(share_counts[short])
c.update({
'show_email': show_email,
'base_url': obj.share_url(),
'counts': counts,
'services': services,
'obj': obj,
})
return c
@register.inclusion_tag('sharing/sharing_box.html')
@jinja2.contextfunction
def sharing_box(context):
request = context['request']
c = dict(context.items())
c.update({
'request': request,
'user': request.user,
'obj': obj,
'services': services,
'service_opts': opts,
'services': sharing.SERVICES_LIST,
'email_service': EMAIL,
'show_email': show_email,
})
return c

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

@ -1,34 +1,23 @@
<div class="share-this">
{% if obj.__class__.__name__ == 'Addon' %}
<a class="share" href="#">{{ _('Share this Add-on') }}</a>
{% elif obj.__class__.__name__ == 'Collection' %}
<a class="share" href="#">{{ _('Share this Collection') }}</a>
{% endif %}
<div class="share-arrow"><div class="share-frame">
{% cache obj %}
<div class="share-networks share-content">
<ul>
{% for service in services %}
{% set opts = service_opts[service] %}
{% set share_counts = obj.share_counts() %}
<li class="{{ service.shortname }}">
<span class="share-link">
<a class="uniquify" target="{{ opts.target }}" href="{{ opts.url }}">
{{ service.label }}
</a>
</span>
<span class="share-count">
{{ service.count_term(share_counts[service.shortname]) }}
</span>
</li>
{% endfor %}
</ul>
</div>{# /share-networks #}
{% endcache %}
<div id="sharing-popup" class="popup">
<div class="share-networks share-content">
<ul>
{% for service in services %}
<li class="{{ service.shortname }}">
<span class="share-link">
<a class="uniquify" target="{{ '_self' if service==EMAIL else '_blank' }}" href="#">
{{ service.label }}
</a>
</span>
<span class="share-count">
</span>
</li>
{% endfor %}
</ul>
</div>{# /share-networks #}
{% if request.user.is_authenticated() and show_email %}
{% if request.user.is_authenticated() or True %}
<div class="share-email share-content">
<form action="{{ remora_url(service_opts[email_service].url) }}"
<form action=""
method="post">
{{ cake_csrf_token() }}
{# TODO uncakeify #}
@ -65,7 +54,4 @@
</div>
</div>{# /share-email #}
{% endif %}
</div></div>{# /share-frame, /share-arrow #}
</div>{# /share-this #}
</div>

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

@ -0,0 +1,11 @@
{% if obj.__class__.__name__ == 'Addon' %}
{% set sharemsg = _('Share this Addon') %}
{% elif obj.__class__.__name__ == 'Collection' %}
{% set sharemsg = _('Share this Collection') %}
{% endif %}
<div class="share widget"
data-share-counts="{{ counts|json }}"
data-base-url="{{ obj.share_url() }}?service=">
<a title="{{ sharemsg if condensed }}" class="share" href="#"><span>{{ sharemsg }}</span></a>
<div class="share-me popup-shim{{ ' left' if condensed }}{{ ' no-email' if not show_email }}"></div>
</div>

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

@ -2538,7 +2538,7 @@ html[xmlns] .clearfix {
}
.addon-collections li .collectionitem, .collection-add > span {
padding-left: 20px;
padding-left: 22px;
background-image: url(../../img/amo2009/icons/icons.png);
background-repeat: no-repeat;
background-position: 0px -300px;

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

@ -468,7 +468,6 @@ button.link {
.subscribers,
.category,
.tags,
.share,
.digg,
.delicious,
.facebook,
@ -486,10 +485,6 @@ button.link {
background-position: 0 2px;
}
.share {
background-position: 0 -100px;
}
.addons {
background-position: 0 -200px;
padding-bottom: 7px;
@ -2453,10 +2448,14 @@ ol.pagination li a:active {
/* @group Share This */
.share-this {
width: 200px;
clear:left;
float:left;
#sharing-popup {
width: 280px;
left: -55px;
padding: 0;
}
.condensed #sharing-popup.left {
left: -184px;
}
.share-arrow {
@ -2479,16 +2478,19 @@ ol.pagination li a:active {
padding: 0;
}
.share-content {
#sharing-popup div {
-moz-border-radius:5px;
-webkit-border-radius:5px;
border-radius:5px;
margin: 0;
}
.share-networks ul {
padding: 0 0 0 0.8em;
display: table;
-moz-box-sizing: border-box;
margin: 0;
width:100%;
}
.html-rtl .share-networks ul {
@ -2522,7 +2524,7 @@ ol.pagination li a:active {
padding-left:15px;
}
.share-networks li.email {
.no-email .share-networks li.email {
display: none; /* shown with js */
}

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

@ -2524,7 +2524,6 @@ label > .optional {
background-repeat: no-repeat;
background-position: 0 4px;
background-image: url(../../img/zamboni/icons/checks.png);
font-weight: bold;
}
#ajax_collections_list li:hover {
@ -2722,7 +2721,7 @@ td.remove {
background-image: url(../../img/zamboni/icons/collections.png);
white-space: nowrap;
background-position: 0 -500px;
padding-left: 20px;
padding-left: 22px;
}
.addon-favorite span.msg {
font-weight: bold;
@ -2797,34 +2796,45 @@ a.outlink:hover {
margin-bottom: 1em;
}
.collection_widgets > a {
.widgets a.widget,
.widgets .widget > a {
background-image: url(../../img/zamboni/icons/collections.png);
background-repeat: no-repeat;
padding-left: 22px;
margin-right: .8em;
text-indent: -9000px;
}
.collection_widgets > a[title] {
.collection_widgets div.widget {
display: inline-block;
}
.collection_widgets.condensed a.widget,
.collection_widgets.condensed .widget > a{
padding-left: 16px;
}
.collection_widgets .edit {
.widgets.condensed a.widget > span,
.widgets.condensed .widget > a > span {
display: none;
}
.widgets .edit {
margin-left: .5em;
background-position: 0 -350px;
}
.collection_widgets .edit:hover { background-position: 0 -300px; }
.collection_widgets .copy { background-position: 0 -50px; }
.collection_widgets .copy:hover { background-position: 0 0px; }
.collection_widgets .watch { background-position: 0 -750px; }
.collection_widgets .watch:hover { background-position: 0 -700px;}
.collection_widgets .watching { background-position: 0 -650px; }
.collection_widgets .share { background-position: 0 -600px; }
.collection_widgets .share:hover { background-position: 0 -550px; }
.widgets a.edit:hover { background-position: 0 -300px; }
.widgets a.copy { background-position: 0 -50px; }
.widgets a.copy:hover { background-position: 0 0px; }
.widgets a.watch { background-position: 0 -750px; }
.widgets a.watch:hover { background-position: 0 -700px;}
.widgets a.watching { background-position: 0 -650px; }
.widgets.condensed a.share { background-position: 0 -600px; }
.widgets a.share, .widgets.condensed a.share:hover { background-position: 0 -550px; }
.addon-favorite.ajax-loading span,
.collection-add.ajax-loading span,
.collection_widgets > a.ajax-loading,
.collection_widgets > a.ajax-loading:hover {
.widgets a.widget.ajax-loading,
.widgets .widget.ajax-loading > a,
.widgets > a.widget.ajax-loading:hover,
.widgets > .widget.ajax-loading > a:hover {
background-image: url(../../img/zamboni/loading-white.gif);
background-position: left bottom;
}

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

@ -486,6 +486,59 @@ jQuery(window).load(function() {
document.createElement('abbr');
});
function makeBlurHideCallback(el) {
var hider = function(e) {
_root = el.get(0);
// Bail if the click was somewhere on the popup.
if (e.type == 'click' &&
_root == e.target ||
_.indexOf($(e.target).parents(), _root) != -1) {
return;
}
el.hide();
el.unbind();
el.undelegate();
$(document.body).unbind('click newPopup', hider);
};
return hider;
}
// makes an element into a popup.
// click_target defines the element/elements that display the popup.
// opts takes three optional fields:
// callback: a function to run before displaying the popup. Returning
// false from the function cancels the popup.
// container: if set the popup will be appended to the container before
// being displayed.
// hideme: defaults to true, if set to false, popup will not be hidden
// when the user clicks outside of it.
$.fn.popup = function(click_target, opts) {
opts = opts || {};
var $ct = $(click_target),
$popup = this,
callback = opts.callback || false,
container = opts.container || false;
hideme = opts.hideme || false;
$ct.click(function(e) {
e.preventDefault();
setTimeout(function(){
$(document.body).bind('click popup', makeBlurHideCallback($popup));
}, 0);
var resp = callback ? (callback.apply($popup, [this, e])) : true;
if (resp) {
$ct.trigger("popup_show", [this, $popup, e]);
if (resp.container || container)
$popup.detach().appendTo(resp.container || container);
setTimeout(function(){
$popup.show();
}, 0);
}
});
return this;
};
/* Initialization things that get run on every page. */
$(".hidden").hide(); // hide anything that should be hidden

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

@ -531,7 +531,7 @@ $(document).ready(function () {
}
}
$('#details-edit form, body.collection-create form, .collection-add-dropdown').delegate('#id_name', 'keyup', slugify)
$('#details-edit form').delegate('#id_name', 'keyup', slugify)
.delegate('#id_name', 'blur', slugify)
.delegate('#edit_slug', 'click', show_slug_edit)
.delegate('#id_slug', 'change', function() {
@ -617,32 +617,24 @@ $(document).ready(function () {
dropdown.delegate('#ajax_collections_list li', 'click', handleToggle)
.delegate('#collections-new form', 'submit', handleSubmit)
.delegate('#ajax_new_collection', 'click', handleNew)
.delegate('#collections-new-cancel', 'click', handleClick);
.delegate('#collections-new-cancel', 'click', handleClick)
.delegate('#id_name', 'blur', slugify)
.delegate('#edit_slug', 'click', show_slug_edit)
.delegate('#id_slug', 'change', function() {
url_customized = true;
if (!$('#id_slug').val()) {
url_customized = false;
slugify();
}
});
// Clear popup when we click outside it.
setTimeout(function(){
$(document.body).bind('click newPopup', cb(dropdown));
$(document.body).bind('click newPopup', makeBlurHideCallback(dropdown));
}, 0);
};
$(document.body).delegate("div.collection-add", 'click', handleClick);
function cb(el) {
var hider = function(e) {
_root = el.get(0);
// Bail if the click was somewhere on the popup.
if (e.type == 'click' &&
_root == e.target ||
_.indexOf($(e.target).parents(), _root) != -1) {
return;
}
el.hide();
el.unbind();
el.undelegate();
$(document.body).unbind('click newPopup', hider);
};
return hider;
}
function stopPropagation(e) {
e.stopPropagation();
}
@ -715,4 +707,36 @@ $(document).ready(function () {
});
});
//New sharing interaction
$("#sharing-popup").popup(".share.widget a.share", {
callback: function(el, $popup) {
var $top = $(el).parents(".widgets");
var $container = $(".share-me", $top);
if ($(this).is(':visible') && $("#sharing-popup", $container).length ) {
return false;
} else {
var $widget = $(".share.widget", $top);
var base_url = $widget.attr('data-base-url');
var counts = $.parseJSON($widget.attr("data-share-counts"));
if (counts) {
for (s in counts) {
if (!counts.hasOwnProperty(s)) continue;
var c = counts[s];
var $li = $("li." + s, this);
$(".share-count", $li).text(c);
$(".uniquify", $li).attr("href", base_url + s);
}
} else {
return false;
}
if ($container.hasClass("left")) {
this.addClass("left");
} else {
this.removeClass("left");
}
return { 'container' : $container };
}
}
});
});

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

@ -93,7 +93,11 @@
{% block content %}{% endblock %}
{% endblock %}
</div>
<div class="hidden" id="popup-staging">
{{ sharing_box() }}
{% block popups %}
{% endblock %}
</div>
{# js #}
{% block site_js %}
<script src="{{ url('jsi18n') }}/build:{{ BUILD_ID_JS }}"></script>