modul-share-buttons

RPICMS SHare Buttons
git clone git://archive.git.mtrnord.blog/RpicmsTeam/modul-share-buttons.git
Log | Files | Refs | README | LICENSE

jquery.socialshareprivacy.js (25081B)


      1 /*
      2  * jquery.socialshareprivacy.js | 2 Klicks fuer mehr Datenschutz (1.6)
      3  *
      4  * http://www.heise.de/extras/socialshareprivacy/
      5  * http://www.heise.de/ct/artikel/2-Klicks-fuer-mehr-Datenschutz-1333879.html
      6  *
      7  * Copyright (c) 2011-2014 Hilko Holweg, Sebastian Hilbig, Nicolas Heiringhoff, Juergen Schmidt,
      8  * Heise Zeitschriften Verlag GmbH & Co. KG, http://www.heise.de
      9  *
     10  * is released under the MIT License http://www.opensource.org/licenses/mit-license.php
     11  *
     12  * Spread the word, link to us if you can.
     13  */
     14 (function ($) {
     15 
     16     "use strict";
     17 
     18     //
     19     // helper functions
     20     // 
     21 
     22     // abbreviate at last blank before length and add "\u2026" (horizontal ellipsis)
     23     function abbreviateText(text, length) {
     24         var abbreviated = decodeURIComponent(text);
     25         if (abbreviated.length <= length) {
     26             return text;
     27         }
     28 
     29         var lastWhitespaceIndex = abbreviated.substring(0, length - 1).lastIndexOf(' ');
     30         abbreviated = encodeURIComponent(abbreviated.substring(0, lastWhitespaceIndex)) + "\u2026";
     31 
     32         return abbreviated;
     33     }
     34 
     35     // returns content of <meta name="" content=""> tags or '' if empty/non existant
     36     function getMeta(name) {
     37         var metaContent = $('meta[name="' + name + '"]').attr('content');
     38         return metaContent || '';
     39     }
     40     
     41     // create tweet text from content of <meta name="DC.title"> and <meta name="DC.creator">
     42     // fallback to content of <title> tag
     43     function getTweetText() {
     44         var title = getMeta('DC.title');
     45         var creator = getMeta('DC.creator');
     46 
     47         if (title.length > 0 && creator.length > 0) {
     48             title += ' - ' + creator;
     49         } else {
     50             title = $('title').text();
     51         }
     52 
     53         return encodeURIComponent(title);
     54     }
     55 
     56     // build URI from rel="canonical" or document.location
     57     function getURI() {
     58         var uri = document.location.href;
     59         var canonical = $("link[rel=canonical]").attr("href");
     60 
     61         if (canonical && canonical.length > 0) {
     62             if (canonical.indexOf("http") < 0) {
     63                 canonical = document.location.protocol + "//" + document.location.host + canonical;
     64             }
     65             uri = canonical;
     66         }
     67 
     68         return uri;
     69     }
     70 
     71     function cookieSet(name, value, days, path, domain) {
     72         var expires = new Date();
     73         expires.setTime(expires.getTime() + (days * 24 * 60 * 60 * 1000));
     74         document.cookie = name + '=' + value + '; expires=' + expires.toUTCString() + '; path=' + path + '; domain=' + domain;
     75     }
     76     function cookieDel(name, value, path, domain) {
     77         var expires = new Date();
     78         expires.setTime(expires.getTime() - 100);
     79         document.cookie = name + '=' + value + '; expires=' + expires.toUTCString() + '; path=' + path + '; domain=' + domain;
     80     }
     81 
     82     // extend jquery with our plugin function
     83     $.fn.socialSharePrivacy = function (settings) {
     84         var defaults = {
     85             'services' : {
     86                 'facebook' : {
     87                     'status'            : 'on',
     88                     'dummy_img'         : '../../core/backend/admin/modules/share_buttons/socialshareprivacy/images/dummy_facebook.png',
     89                     'perma_option'      : 'on',
     90                     'referrer_track'    : '',
     91                     'action'            : 'recommend',
     92                     'layout'            : 'button_count',
     93                     'sharer'            : {
     94                         'status'        : 'off',
     95                         'dummy_img'     : '../../core/backend/admin/modules/share_buttons/socialshareprivacy/images/dummy_facebook_share_de.png',
     96                         'img'           : '../../core/backend/admin/modules/share_buttons/socialshareprivacy/images/dummy_facebook_share_active_de.png'
     97                     }
     98                 },
     99                 'twitter' : {
    100                     'status'            : 'on',
    101                     'dummy_img'         : '../../core/backend/admin/modules/share_buttons/socialshareprivacy/images/dummy_twitter.png',
    102                     'perma_option'      : 'on',
    103                     'referrer_track'    : '',
    104                     'tweet_text'        : getTweetText,
    105                     'count'             : 'horizontal'
    106                 },
    107                 'gplus' : {
    108                     'status'            : 'on',
    109                     'dummy_img'         : '../../core/backend/admin/modules/share_buttons/socialshareprivacy/images/dummy_gplus.png',
    110                     'perma_option'      : 'on',
    111                     'referrer_track'    : '',
    112                     'size'              : 'medium'
    113                 }
    114             },
    115             'info_link'         : 'http://www.heise.de/ct/artikel/2-Klicks-fuer-mehr-Datenschutz-1333879.html',
    116             'cookie_path'       : '/',
    117             'cookie_domain'     : document.location.host,
    118             'cookie_expires'    : '365',
    119             'css_path'          : '../../core/backend/admin/modules/share_buttons/socialshareprivacy/socialshareprivacy.css',
    120             'uri'               : getURI,
    121             'language'          : 'de',
    122             'lang_path'         : '../../core/backend/admin/modules/share_buttons/socialshareprivacy/lang/',
    123             'skin'              : 'light',
    124             'alignment'         : 'horizontal',
    125             'switch_alignment'  : 'left',
    126             'perma_orientation' : 'down'
    127         };
    128 
    129         // Standardwerte des Plug-Ins mit den vom User angegebenen Optionen ueberschreiben
    130         var options = $.extend(true, defaults, settings);
    131 
    132         var facebook_on        = (options.services.facebook.status === 'on');
    133         var facebook_sharer_on = (options.services.facebook.sharer.status === 'on');
    134         var twitter_on         = (options.services.twitter.status  === 'on');
    135         var gplus_on           = (options.services.gplus.status    === 'on');
    136 
    137         // check if at least one service is "on"
    138         if (!facebook_on && !twitter_on && !gplus_on) {
    139             return;
    140         }
    141 
    142         // insert stylesheet into document and prepend target element
    143         if (options.css_path.length > 0 && $(window).data('socialshareprivacy_css') != '1') {
    144             // IE fix (noetig fuer IE < 9 - wird hier aber fuer alle IE gemacht)
    145             if (document.createStyleSheet) {
    146                 document.createStyleSheet(options.css_path);
    147             }
    148             else {
    149                 $('head').append('<link rel="stylesheet" type="text/css" href="' + options.css_path + '" />');
    150             }
    151 
    152             $(window).data('socialshareprivacy_css','1');
    153         }
    154 
    155         var language;
    156 
    157         function loadLangFile() {
    158             var d = $.Deferred();
    159 
    160             $.getJSON(options.lang_path + options.language+'.lang', function(data) {
    161                 language = data;
    162                 d.resolve();
    163             }).fail(function(s){
    164                 if(typeof console !== "undefined") {
    165                     console.log('Error ' + s.status + ' while loading the language file ('+options.lang_path+options.language+'.lang)');
    166                 }
    167                 d.reject();
    168             });
    169 
    170             return d.promise();
    171         }
    172 
    173         return this.each(function () {
    174             $('div#socialshareprivacy').each(function(){
    175             var iteration = this;
    176 
    177             $.when(
    178                 loadLangFile())
    179             .then( function() {
    180                 $(iteration).prepend('<ul class="social_share_privacy_area clearfix"></ul>');
    181                 var context = $('.social_share_privacy_area', iteration);
    182 
    183                 // Class for dark skinning
    184                 if(options.skin == 'dark') {
    185                     $(context).addClass('skin-dark');
    186                 }
    187 
    188                 // Class for alignment
    189                 if(options.alignment == 'vertical') {
    190                     $(context).addClass('vertical');
    191 
    192                     if(options.switch_alignment == 'right' &&
    193                         ((facebook_on && options.services.facebook.layout == 'box_count') || (!facebook_on)) &&
    194                         ((twitter_on && options.services.twitter.count == 'vertical') || (!twitter_on)) &&
    195                         ((gplus_on && options.services.gplus.size == 'tall') || (!gplus_on))) {
    196                         $(context).addClass('switch_right');
    197                     }
    198                 }
    199 
    200                 // canonical uri that will be shared
    201                 var uri = options.uri;
    202                 if (typeof uri === 'function') {
    203                     uri = uri(context);
    204                 }
    205 
    206                 //
    207                 // Facebook
    208                 //
    209                 if (facebook_on) {
    210                     var fb_dummy_btn;
    211                     var fb_code;
    212 
    213                     var fb_height = options.services.facebook.layout == 'box_count' ? '61' : '21';
    214                     var fb_width  = options.services.facebook.layout == 'box_count' ? '90' : '130';
    215 
    216                     var fb_enc_uri = encodeURIComponent(uri + options.services.facebook.referrer_track);
    217 
    218                     if (facebook_sharer_on) {
    219                         fb_dummy_btn = '<img src="' + options.services.facebook.sharer.dummy_img + '" alt="Facebook &quot;Share&quot;-Dummy" class="fb_like_privacy_dummy" />';
    220                         fb_code = '<a href="#" onclick="window.open(\'https://www.facebook.com/sharer/sharer.php?u=' + fb_enc_uri + '\', \'facebook-share-dialog\', \'width=626,height=436\'); return false;"><img src="'+options.services.facebook.sharer.img+'" alt="" /></a>';
    221                     }
    222                     else {
    223                         fb_dummy_btn = '<img src="' + options.services.facebook.dummy_img + '" alt="Facebook &quot;Like&quot;-Dummy" class="fb_like_privacy_dummy" />';
    224                         fb_code = '<iframe src="//www.facebook.com/plugins/like.php?locale=' + language.services.facebook.language + '&amp;href=' + fb_enc_uri + '&amp;width=' + fb_width + '&amp;layout=' + options.services.facebook.layout + '&amp;action=' + options.services.facebook.action + '&amp;show_faces=false&amp;share=false&amp;height=' + fb_height + '&amp;colorscheme=' + options.skin + '" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:' + fb_width + 'px; height:' + fb_height + 'px;" allowTransparency="true"></iframe>';
    225                     }
    226                     context.append('<li class="facebook help_info clearfix"><span class="info">' + language.services.facebook.txt_info + '</span><a href="#" class="switch off">' + language.services.facebook.txt_fb_off + '</a><div class="fb_like dummy_btn">' + fb_dummy_btn + '</div></li>');
    227 
    228                     var $container_fb = $('li.facebook', context);
    229                     $(context).on('click', 'li.facebook div.fb_like img.fb_like_privacy_dummy,li.facebook .switch', function (e) {
    230                         e.preventDefault();
    231                         if ($container_fb.find('.switch').hasClass('off')) {
    232                             $container_fb.addClass('info_off');
    233                             $container_fb.find('.switch').addClass('on').removeClass('off').html(language.services.facebook.txt_fb_on);
    234                             $container_fb.find('img.fb_like_privacy_dummy').replaceWith(fb_code);
    235                         }
    236                         else {
    237                             $container_fb.removeClass('info_off');
    238                             $container_fb.find('.switch').addClass('off').removeClass('on').html(language.services.facebook.txt_fb_off);
    239                             $container_fb.find('.fb_like').html(fb_dummy_btn);
    240                         }
    241                     });
    242                 }
    243 
    244                 //
    245                 // Twitter
    246                 //
    247                 if (twitter_on) {
    248                     var text = options.services.twitter.tweet_text;
    249                     if (typeof text === 'function') {
    250                         text = text();
    251                     }
    252                     // 120 is the max character count left after twitters automatic url shortening with t.co
    253                     text = abbreviateText(text, '120');
    254 
    255                     var tw_height = options.services.twitter.count == 'horizontal' ? '25' : '62';
    256                     var tw_width  = options.services.twitter.count == 'horizontal' ? '130' : '83';
    257 
    258                     var twitter_enc_uri = encodeURIComponent(uri + options.services.twitter.referrer_track);
    259                     var twitter_count_url = encodeURIComponent(uri);
    260                     var twitter_code = '<iframe allowtransparency="true" frameborder="0" scrolling="no" src="//platform.twitter.com/widgets/tweet_button.html?url=' + twitter_enc_uri + '&amp;counturl=' + twitter_count_url + '&amp;text=' + text + '&amp;count=' + options.services.twitter.count + '&amp;lang=' + language.services.twitter.language + '&amp;dnt=true" style="width:' + tw_width + 'px; height:' + tw_height + 'px;"></iframe>';
    261                     var twitter_dummy_btn = '<img src="' + options.services.twitter.dummy_img + '" alt="&quot;Tweet this&quot;-Dummy" class="tweet_this_dummy" />';
    262 
    263                     context.append('<li class="twitter help_info clearfix"><span class="info">' + language.services.twitter.txt_info + '</span><a href="#" class="switch off">' + language.services.twitter.txt_twitter_off + '</a><div class="tweet dummy_btn">' + twitter_dummy_btn + '</div></li>');
    264 
    265                     var $container_tw = $('li.twitter', context);
    266 
    267                     $(context).on('click', 'li.twitter div.tweet img,li.twitter .switch', function (e) {
    268                         e.preventDefault();
    269                         if ($container_tw.find('.switch').hasClass('off')) {
    270                             $container_tw.addClass('info_off');
    271                             $container_tw.find('.switch').addClass('on').removeClass('off').html(language.services.twitter.txt_twitter_on);
    272                             $container_tw.find('img.tweet_this_dummy').replaceWith(twitter_code);
    273                         }
    274                         else {
    275                             $container_tw.removeClass('info_off');
    276                             $container_tw.find('.switch').addClass('off').removeClass('on').html(language.services.twitter.txt_twitter_off);
    277                             $container_tw.find('.tweet').html(twitter_dummy_btn);
    278                         }
    279                     });
    280                 }
    281 
    282                 //
    283                 // Google+
    284                 //
    285                 if (gplus_on) {
    286                     // fuer G+ wird die URL nicht encoded, da das zu einem Fehler fuehrt
    287                     var gplus_uri = uri + options.services.gplus.referrer_track;
    288                     
    289                     // we use the Google+ "asynchronous" code, standard code is flaky if inserted into dom after load
    290                     var gplus_code = '<div class="g-plusone" data-size="' + options.services.gplus.size + '" data-href="' + gplus_uri + '"></div><script type="text/javascript">window.___gcfg = {lang: "' + language.services.gplus.language + '"}; (function() { var po = document.createElement("script"); po.type = "text/javascript"; po.async = true; po.src = "https://apis.google.com/js/platform.js"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(po, s); })(); </script>';
    291                     var gplus_dummy_btn = '<img src="' + options.services.gplus.dummy_img + '" alt="&quot;Google+1&quot;-Dummy" class="gplus_one_dummy" />';
    292 
    293                     context.append('<li class="gplus help_info clearfix"><span class="info">' + language.services.gplus.txt_info + '</span><a href="#" class="switch off">' + language.services.gplus.txt_gplus_off + '</a><div class="gplusone dummy_btn">' + gplus_dummy_btn + '</div></li>');
    294 
    295                     var $container_gplus = $('li.gplus', context);
    296 
    297                     $(context).on('click', 'li.gplus div.gplusone img,li.gplus .switch', function (e) {
    298                         e.preventDefault();
    299                         if ($container_gplus.find('.switch').hasClass('off')) {
    300                             $container_gplus.addClass('info_off');
    301                             $container_gplus.find('.switch').addClass('on').removeClass('off').html(language.services.gplus.txt_gplus_on);
    302                             $container_gplus.find('img.gplus_one_dummy').replaceWith(gplus_code);
    303                         }
    304                         else {
    305                             $container_gplus.removeClass('info_off');
    306                             $container_gplus.find('.switch').addClass('off').removeClass('on').html(language.services.gplus.txt_gplus_off);
    307                             $container_gplus.find('.gplusone').html(gplus_dummy_btn);
    308                         }
    309                     });
    310                 }
    311 
    312                 //
    313                 // Der Info/Settings-Bereich wird eingebunden
    314                 //
    315                 context.append('<li class="settings_info ' + options.perma_orientation + '"><div class="settings_info_menu off perma_option_off"><a href="' + options.info_link + '"><span class="help_info icon"><span class="info">' + language.txt_help + '</span></span></a></div></li>');
    316 
    317                 // Info-Overlays mit leichter Verzoegerung einblenden
    318                 $(context).on('mouseenter', '.help_info:not(.info_off)', function () {
    319                     var $info_wrapper = $(this);
    320                     var timeout_id = window.setTimeout(function () { $($info_wrapper).addClass('display'); }, 500);
    321                     $(this).data('timeout_id', timeout_id);
    322                 });
    323                 $(context).on('mouseleave', '.help_info', function () {
    324                     var timeout_id = $(this).data('timeout_id');
    325                     window.clearTimeout(timeout_id);
    326                     if ($(this).hasClass('display')) {
    327                         $(this).removeClass('display');
    328                     }
    329                 });
    330 
    331                 var facebook_perma = (options.services.facebook.perma_option === 'on');
    332                 var twitter_perma  = (options.services.twitter.perma_option  === 'on');
    333                 var gplus_perma    = (options.services.gplus.perma_option    === 'on');
    334 
    335                 // Menue zum dauerhaften Einblenden der aktiven Dienste via Cookie einbinden
    336                 if ((facebook_on && facebook_perma) || (twitter_on && twitter_perma) || (gplus_on && gplus_perma)) {
    337 
    338                     // Cookies abrufen
    339                     var cookie_list = document.cookie.split(';');
    340                     var cookies = '{';
    341                     var i = 0;
    342                     for (; i < cookie_list.length; i += 1) {
    343                         var foo = cookie_list[i].split('=');
    344                         // Spaces and Quotes getting removed
    345                         foo[0] = $.trim(foo[0].replace(/"/g, ''));
    346                         foo[1] = $.trim(foo[1].replace(/"/g, ''));
    347                         cookies += '"' + foo[0] + '":"' + foo[1] + '"';
    348                         if (i < cookie_list.length - 1) {
    349                             cookies += ',';
    350                         }
    351                     }
    352                     cookies += '}';
    353                     cookies = jQuery.parseJSON(cookies);
    354 
    355                     // Container definieren
    356                     var $container_settings_info = $('li.settings_info', context);
    357 
    358                     // Klasse entfernen, die das i-Icon alleine formatiert, da Perma-Optionen eingeblendet werden
    359                     $container_settings_info.find('.settings_info_menu').removeClass('perma_option_off');
    360 
    361                     // Perma-Optionen-Icon (.settings) und Formular (noch versteckt) einbinden
    362                     $container_settings_info.find('.settings_info_menu').append('<a href="#" class="settings">' + language.settings + '</a><form><fieldset><legend>' + language.settings_perma + '</legend></fieldset></form>');
    363 
    364 
    365                     var random = 'r' + Math.floor(Math.random()*101);
    366 
    367                     // Die Dienste mit <input> und <label>, sowie checked-Status laut Cookie, schreiben
    368                     var checked = ' checked="checked"';
    369                     if (facebook_on && facebook_perma) {
    370                         var perma_status_facebook = cookies.socialSharePrivacy_facebook === 'perma_on' ? checked : '';
    371                         $container_settings_info.find('form fieldset').append(
    372                             '<input type="checkbox" name="perma_status_facebook" id="' + random + '_perma_status_facebook"' + perma_status_facebook + ' /><label for="'+random+'_perma_status_facebook">' + language.services.facebook.perma_display_name + '</label>'
    373                         );
    374                     }
    375 
    376                     if (twitter_on && twitter_perma) {
    377                         var perma_status_twitter = cookies.socialSharePrivacy_twitter === 'perma_on' ? checked : '';
    378                         $container_settings_info.find('form fieldset').append(
    379                             '<input type="checkbox" name="perma_status_twitter" id="' + random + '_perma_status_twitter"' + perma_status_twitter + ' /><label for="'+random+'_perma_status_twitter">' + language.services.twitter.perma_display_name + '</label>'
    380                         );
    381                     }
    382 
    383                     if (gplus_on && gplus_perma) {
    384                         var perma_status_gplus = cookies.socialSharePrivacy_gplus === 'perma_on' ? checked : '';
    385                         $container_settings_info.find('form fieldset').append(
    386                             '<input type="checkbox" name="perma_status_gplus" id="'+random+'_perma_status_gplus"' + perma_status_gplus + ' /><label for="'+random+'_perma_status_gplus">' + language.services.gplus.perma_display_name + '</label>'
    387                         );
    388                     }
    389 
    390                     // Settings-Menue per Tastatur erreichbar machen, die Mouseevents werden getriggert
    391                     $(context).on('click', 'li.settings_info .settings', function (e) {
    392                         e.preventDefault();
    393                         if($(this).data('keyb') == 'on') {
    394                             $('li.settings_info', context).trigger('mouseleave');
    395                             $(this).data('keyb','off');
    396                         }
    397                         else {
    398                             $('li.settings_info .settings', context).trigger('mouseenter');
    399                             $(this).data('keyb','on');
    400                         }
    401                     });
    402 
    403                     // Einstellungs-Menue bei mouseover ein-/ausblenden
    404                     $(context).on('mouseenter', 'li.settings_info .settings', function () {
    405                         var timeout_id = window.setTimeout(function () { $container_settings_info.find('.settings_info_menu').removeClass('off').addClass('on'); }, 500);
    406                         $(this).data('timeout_id', timeout_id);
    407                     });
    408                     $(context).on('mouseleave', 'li.settings_info', function () {
    409                         var timeout_id = $(this).data('timeout_id');
    410                         window.clearTimeout(timeout_id);
    411                         $container_settings_info.find('.settings_info_menu').removeClass('on').addClass('off');
    412                     });
    413 
    414                     // Klick-Interaktion auf <input> um Dienste dauerhaft ein- oder auszuschalten (Cookie wird gesetzt oder geloescht)
    415                     $(context).on('click', 'li.settings_info fieldset input', function (event) {
    416                         var click = event.target.id;
    417                         var service = click.substr(click.lastIndexOf('_') + 1, click.length);
    418                         var cookie_name = 'socialSharePrivacy_' + service;
    419 
    420                         if ($('#' + event.target.id + ':checked').length) {
    421                             cookieSet(cookie_name, 'perma_on', options.cookie_expires, options.cookie_path, options.cookie_domain);
    422                             $('form fieldset label[for=' + click + ']', context).addClass('checked');
    423                         }
    424                         else {
    425                             cookieDel(cookie_name, 'perma_on', options.cookie_path, options.cookie_domain);
    426                             $('form fieldset label[for=' + click + ']', context).removeClass('checked');
    427                         }
    428                     });
    429 
    430                     // Dienste automatisch einbinden, wenn entsprechendes Cookie vorhanden ist
    431                     if (facebook_on && facebook_perma && cookies.socialSharePrivacy_facebook === 'perma_on') {
    432                         $('li.facebook .switch', context).click();
    433                     }
    434                     if (twitter_on && twitter_perma && cookies.socialSharePrivacy_twitter === 'perma_on') {
    435                         $('li.twitter .switch', context).click();
    436                     }
    437                     if (gplus_on && gplus_perma && cookies.socialSharePrivacy_gplus === 'perma_on') {
    438                         $('li.gplus .switch', context).click();
    439                     }
    440                 }
    441             }); // .then()
    442         });
    443         }); // this.each(function ()
    444     }; // $.fn.socialSharePrivacy = function (settings) {
    445 }(jQuery));