diff --git a/apps/addons/templates/addons/details.html b/apps/addons/templates/addons/details.html index fd93d342c1..29949e8ceb 100644 --- a/apps/addons/templates/addons/details.html +++ b/apps/addons/templates/addons/details.html @@ -110,12 +110,12 @@ {% endif %} {% if settings.NEW_COLLECTIONS %} +
{{ favorites_widget(addon) }} {% include 'addons/includes/collection_add_widget.html' %} + {{ sharing_widget(addon) }} +
{% endif %} - - {{ sharing_box(addon) }} - {# /secondary #} {# /featured-inner #} diff --git a/apps/bandwagon/helpers.py b/apps/bandwagon/helpers.py index ae6668c048..eff937827a 100644 --- a/apps/bandwagon/helpers.py +++ b/apps/bandwagon/helpers.py @@ -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, }) diff --git a/apps/bandwagon/templates/bandwagon/ajax_list.html b/apps/bandwagon/templates/bandwagon/ajax_list.html index 051cc8df0d..c7952b933b 100644 --- a/apps/bandwagon/templates/bandwagon/ajax_list.html +++ b/apps/bandwagon/templates/bandwagon/ajax_list.html @@ -3,7 +3,7 @@ {% for collection in collections %}
  • - {{ collection.name }} + {{ collection.name }}
  • {% endfor %} diff --git a/apps/bandwagon/templates/bandwagon/collection_widgets.html b/apps/bandwagon/templates/bandwagon/collection_widgets.html index edcaf00eb6..7e9eaefbfd 100644 --- a/apps/bandwagon/templates/bandwagon/collection_widgets.html +++ b/apps/bandwagon/templates/bandwagon/collection_widgets.html @@ -1,16 +1,15 @@ {% if request.user.is_authenticated() %} {% set is_watching = c.id in request.amo_user.watching %} -
    +
    {{ _('Stop Watching') if is_watching else _('Watch this Collection') }} - {{ sharing_box(c) }} + class="widget watch{{ ' watching' if is_watching }}" + href="{{ c.watch_url() }}">{{ _('Stop Watching') if is_watching else _('Watch this Collection') }} + {{ sharing_widget(c, show_email=False) }} {# - #} {% if request.check_ownership(c, require_owner=False) and condensed %} - + {% endif %}
    {% endif %} \ No newline at end of file diff --git a/apps/sharing/helpers.py b/apps/sharing/helpers.py index 54a419fd56..6630d7670a 100644 --- a/apps/sharing/helpers.py +++ b/apps/sharing/helpers.py @@ -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 diff --git a/apps/sharing/templates/sharing/sharing_box.html b/apps/sharing/templates/sharing/sharing_box.html index 9c29bcdcd5..7aac716efb 100644 --- a/apps/sharing/templates/sharing/sharing_box.html +++ b/apps/sharing/templates/sharing/sharing_box.html @@ -1,34 +1,23 @@ -
    - {% if obj.__class__.__name__ == 'Addon' %} - - {% elif obj.__class__.__name__ == 'Collection' %} - - {% endif %} - {# /share-frame, /share-arrow #} -
    {# /share-this #} +
    diff --git a/apps/sharing/templates/sharing/sharing_widget.html b/apps/sharing/templates/sharing/sharing_widget.html new file mode 100644 index 0000000000..314c1b8c2a --- /dev/null +++ b/apps/sharing/templates/sharing/sharing_widget.html @@ -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 %} +
    + {{ sharemsg }} + +
    \ No newline at end of file diff --git a/media/css/main-mozilla.css b/media/css/main-mozilla.css index 9551e38658..208eed5482 100644 --- a/media/css/main-mozilla.css +++ b/media/css/main-mozilla.css @@ -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; diff --git a/media/css/main.css b/media/css/main.css index 49c05efb94..e8de4ddf9b 100644 --- a/media/css/main.css +++ b/media/css/main.css @@ -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 */ } diff --git a/media/css/zamboni/zamboni.css b/media/css/zamboni/zamboni.css index 21342b5c50..f2f94060df 100644 --- a/media/css/zamboni/zamboni.css +++ b/media/css/zamboni/zamboni.css @@ -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; } diff --git a/media/js/amo2009/global.js b/media/js/amo2009/global.js index f17859bc70..6ba5819c0d 100644 --- a/media/js/amo2009/global.js +++ b/media/js/amo2009/global.js @@ -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 diff --git a/media/js/zamboni/collections.js b/media/js/zamboni/collections.js index 712acc535a..deb8024244 100644 --- a/media/js/zamboni/collections.js +++ b/media/js/zamboni/collections.js @@ -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 }; + } + } + }); + }); diff --git a/templates/base.html b/templates/base.html index 629c851dce..2e612527c2 100644 --- a/templates/base.html +++ b/templates/base.html @@ -93,7 +93,11 @@ {% block content %}{% endblock %} {% endblock %} - + {# js #} {% block site_js %}