1/* 2 * jquery.socialshareprivacy.js | 2 Klicks fuer mehr Datenschutz 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 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 (jQuery) { 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 = jQuery('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 = jQuery('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 = jQuery("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 jQuery.fn.socialSharePrivacy = function (settings) { 84 var defaults = { 85 'services' : { 86 'facebook' : { 87 'status' : 'on', 88 'dummy_img' : '/wp-content/plugins/wp-social-share-privacy-plugin-fr/images/dummy_facebook.png', 89 'txt_info' : 'En cliquant sur ce bouton, vous acceptez de transmettre des informations concernant votre navigation à Facebook. Un second clic vous permet de partager du contenu sur Facebook.<em>i</em>.', 90 'txt_fb_off' : 'Activer l\'envoie d\'information à Facebook', 91 'txt_fb_on' : 'Désactiver l\'envoie d\'information à Facebook', 92 'perma_option' : 'on', 93 'display_name' : 'Facebook', 94 'referrer_track' : '', 95 'language' : 'fr_FR', 96 'action' : 'recommend' 97 }, 98 'twitter' : { 99 'status' : 'on', 100 'dummy_img' : '/wp-content/plugins/wp-social-share-privacy-plugin-fr/images/dummy_twitter.png',
101 'txt_info' : 'En cliquant sur ce bouton, vous acceptez de transmettre des informations concernant votre navigation à Twitter. Un second clic vous permet de partager du contenu sur Twitter.<em>i</em>.', 102 'txt_twitter_off' : 'Activer l\'envoie d\'information à Twitter', 103 'txt_twitter_on' : 'Désactiver l\'envoie d\'information à Twitter', 104 'perma_option' : 'on', 105 'display_name' : 'Twitter', 106 'referrer_track' : '', 107 'tweet_text' : getTweetText, 108 'language' : 'en' 109 }, 110 'gplus' : { 111 'status' : 'on', 112 'dummy_img' : '/wp-content/plugins/wp-social-share-privacy-plugin-fr/images/dummy_gplus.png', 113 'txt_info' : 'En cliquant sur ce bouton, vous acceptez de transmettre des informations concernant votre navigation à Google+. Un second clic vous permet de partager du contenu sur Google+. <em>i</em>.', 114 'txt_gplus_off' : 'Activer l\'envoie d\'information à Google+', 115 'txt_gplus_on' : 'Désactiver l\'envoie d\'information à Google+', 116 'perma_option' : 'on', 117 'display_name' : 'Google+', 118 'referrer_track' : '', 119 'language' : 'de' 120 } 121 }, 122 'info_link' : 'http://www.heise.de/ct/artikel/2-Klicks-fuer-mehr-Datenschutz-1333879.html', 123 'txt_help' : 'Si vous activez ces boutons en cliquant dessus, des informations seront transmises à Facebook, Twitter ou Google et des traceurs peuvent être installés par ces plateformes. Pour plus de détails, cliquez sur le <em>i</em>', 124 'settings_perma' : 'Activer en permanence', 125 'cookie_path' : '/', 126 'cookie_domain' : document.location.host, 127 'cookie_expires' : '365', 128 'css_path' : '/wp-content/plugins/wp-social-share-privacy-plugin-fr/wp-social-share-privacy.css', 129 'uri' : getURI 130 }; 131 132 // Standardwerte des Plug-Ings mit den vom User angegebenen Optionen ueberschreiben 133 var options = jQuery.extend(true, defaults, settings); 134 135 var facebook_on = (options.services.facebook.status === 'on'); 136 var twitter_on = (options.services.twitter.status === 'on'); 137 var gplus_on = (options.services.gplus.status === 'on'); 138 139 // check if at least one service is "on" 140 if (!facebook_on && !twitter_on && !gplus_on) { 141 return; 142 } 143 144 // insert stylesheet into document and prepend target element 145 if (options.css_path.length > 0) { 146 jQuery('head').append('<link rel="stylesheet" type="text/css" href="' + options.css_path + '" />'); 147 } 148 jQuery(this).prepend('<ul class="social_share_privacy_area"></ul>'); 149 var context = jQuery('.social_share_privacy_area', this); 150 151 // canonical uri that will be shared 152 var uri = options.uri; 153 if (typeof uri === 'function') { 154 uri = uri(); 155 } 156 157 return this.each(function () { 158 159 // 160 // Facebook 161 // 162 if (facebook_on) { 163 var fb_enc_uri = (options.services.facebook.referrer_track != '' ) ? encodeURIComponent(options.services.facebook.referrer_track) : encodeURIComponent(uri); 164 var fb_code = '<iframe src="http://www.facebook.com/plugins/like.php?locale=' + options.services.facebook.language + '&href=' + fb_enc_uri + '&send=false&layout=button_count&width=120&show_faces=false&action=' + options.services.facebook.action + '&colorscheme=light&font&height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:145px; height:21px;" allowTransparency="true"></iframe>'; 165 var fb_dummy_btn = '<img src="' + options.services.facebook.dummy_img + '" alt="Facebook "Like"-Dummy" class="fb_like_privacy_dummy" />'; 166 167 context.append('<li class="facebook help_info"><span class="info">' + options.services.facebook.txt_info + '</span><span class="switch off">' + options.services.facebook.txt_fb_off + '</span><div class="fb_like dummy_btn">' + fb_dummy_btn + '</div></li>'); 168 169 var jQuerycontainer_fb = jQuery('li.facebook', context); 170 171 jQuery('li.facebook div.fb_like img.fb_like_privacy_dummy,li.facebook span.switch', context).live('click', function () { 172 if (jQuerycontainer_fb.find('span.switch').hasClass('off')) { 173 jQuerycontainer_fb.addClass('info_off'); 174 jQuerycontainer_fb.find('span.switch').addClass('on').removeClass('off').html(options.services.facebook.txt_fb_on); 175 jQuerycontainer_fb.find('img.fb_like_privacy_dummy').replaceWith(fb_code); 176 } else { 177 jQuerycontainer_fb.removeClass('info_off'); 178 jQuerycontainer_fb.find('span.switch').addClass('off').removeClass('on').html(options.services.facebook.txt_fb_off); 179 jQuerycontainer_fb.find('.fb_like').html(fb_dummy_btn); 180 } 181 }); 182 } 183 184 // 185 // Twitter 186 // 187 if (twitter_on) { 188 var text = options.services.twitter.tweet_text; 189 if (typeof text === 'function') { 190 text = text(); 191 } 192 // 120 is the max character count left after twitters automatic url shortening with t.co 193 text = abbreviateText(text, '120'); 194 195 var twitter_enc_uri = encodeURIComponent(uri + options.services.twitter.referrer_track); 196 var twitter_count_url = encodeURIComponent(uri); 197 var twitter_code = '<iframe allowtransparency="true" frameborder="0" scrolling="no" src="http://platform.twitter.com/widgets/tweet_button.html?url=' + twitter_enc_uri + '&counturl=' + twitter_count_url + '&
197text=' + text + '&count=horizontal&lang=' + options.services.twitter.language + '" style="width:130px; height:25px;"></iframe>'; 198 var twitter_dummy_btn = '<img src="' + options.services.twitter.dummy_img + '" alt=""Tweet this"-Dummy" class="tweet_this_dummy" />'; 199 200 context.append('<li class="twitter help_info"><span class="info">' + options.services.twitter.txt_info + '</span><span class="switch off">' + options.services.twitter.txt_twitter_off + '</span><div class="tweet dummy_btn">' + twitter_dummy_btn + '</div></li>'); 201 202 var jQuerycontainer_tw = jQuery('li.twitter', context); 203 204 jQuery('li.twitter div.tweet img,li.twitter span.switch', context).live('click', function () { 205 if (jQuerycontainer_tw.find('span.switch').hasClass('off')) { 206 jQuerycontainer_tw.addClass('info_off'); 207 jQuerycontainer_tw.find('span.switch').addClass('on').removeClass('off').html(options.services.twitter.txt_twitter_on); 208 jQuerycontainer_tw.find('img.tweet_this_dummy').replaceWith(twitter_code); 209 } else { 210 jQuerycontainer_tw.removeClass('info_off'); 211 jQuerycontainer_tw.find('span.switch').addClass('off').removeClass('on').html(options.services.twitter.txt_twitter_off); 212 jQuerycontainer_tw.find('.tweet').html(twitter_dummy_btn); 213 } 214 }); 215 } 216 217 // 218 // Google+ 219 // 220 if (gplus_on) { 221 // fuer G+ wird die URL nicht encoded, da das zu einem Fehler fuehrt 222 var gplus_uri = uri + options.services.gplus.referrer_track; 223 224 // we use the Google+ "asynchronous" code, standard code is flaky if inserted into dom after load 225 var gplus_code = '<div class="g-plusone" data-size="medium" data-href="' + gplus_uri + '"></div><script type="text/javascript">window.___gcfg = {lang: "' + options.services.gplus.language + '"}; (function() { var po = document.createElement("script"); po.type = "text/javascript"; po.async = true; po.src = "https://apis.google.com/js/plusone.js"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(po, s); })(); </script>'; 226 var gplus_dummy_btn = '<img src="' + options.services.gplus.dummy_img + '" alt=""Google+1"-Dummy" class="gplus_one_dummy" />'; 227 228 context.append('<li class="gplus help_info"><span class="info">' + options.services.gplus.txt_info + '</span><span class="switch off">' + options.services.gplus.txt_gplus_off + '</span><div class="gplusone dummy_btn">' + gplus_dummy_btn + '</div></li>'); 229 230 var jQuerycontainer_gplus = jQuery('li.gplus', context); 231 232 jQuery('li.gplus div.gplusone img,li.gplus span.switch', context).live('click', function () { 233 if (jQuerycontainer_gplus.find('span.switch').hasClass('off')) { 234 jQuerycontainer_gplus.addClass('info_off'); 235 jQuerycontainer_gplus.find('span.switch').addClass('on').removeClass('off').html(options.services.gplus.txt_gplus_on); 236 jQuerycontainer_gplus.find('img.gplus_one_dummy').replaceWith(gplus_code); 237 } else { 238 jQuerycontainer_gplus.removeClass('info_off'); 239 jQuerycontainer_gplus.find('span.switch').addClass('off').removeClass('on').html(options.services.gplus.txt_gplus_off); 240 jQuerycontainer_gplus.find('.gplusone').html(gplus_dummy_btn); 241 } 242 }); 243 } 244 245 // 246 // Der Info/Settings-Bereich wird eingebunden 247 // 248 context.append('<li class="settings_info"><div class="settings_info_menu off perma_option_off"><a href="' + options.info_link + '"><span class="help_info icon"><span class="info">' + options.txt_help + '</span></span></a></div></li>'); 249 250 // Info-Overlays mit leichter Verzoegerung einblenden 251 jQuery('.help_info:not(.info_off)', context).live('mouseenter', function () { 252 var jQueryinfo_wrapper = jQuery(this); 253 var timeout_id = window.setTimeout(function () { jQuery(jQueryinfo_wrapper).addClass('display'); }, 500); 254 jQuery(this).data('timeout_id', timeout_id); 255 }); 256 jQuery('.help_info', context).live('mouseleave', function () { 257 var timeout_id = jQuery(this).data('timeout_id'); 258 window.clearTimeout(timeout_id); 259 if (jQuery(this).hasClass('display')) { 260 jQuery(this).removeClass('display'); 261 } 262 }); 263 264 var facebook_perma = (options.services.facebook.perma_option === 'on'); 265 var twitter_perma = (options.services.twitter.perma_option === 'on'); 266 var gplus_perma = (options.services.gplus.perma_option === 'on'); 267
268 // Menue zum dauerhaften Einblenden der aktiven Dienste via Cookie einbinden 269 // Die IE7 wird hier ausgenommen, da er kein JSON kann und die Cookies hier ueber JSON-Struktur abgebildet werden 270 if (((facebook_on && facebook_perma) 271 || (twitter_on && twitter_perma) 272 || (gplus_on && gplus_perma)) 273 && (!jQuery.browser.msie || (jQuery.browser.msie && jQuery.browser.version > 7.0))) { 274 275 // Cookies abrufen 276 var cookie_list = document.cookie.split(';'); 277 var cookies = '{'; 278 var i = 0; 279 for (; i < cookie_list.length; i += 1) { 280 var foo = cookie_list[i].split('='); 281 cookies += '"' + jQuery.trim(foo[0]) + '":"' + jQuery.trim(foo[1]) + '"'; 282 if (i < cookie_list.length - 1) { 283 cookies += ','; 284 } 285 } 286 cookies += '}'; 287 cookies = JSON.parse(cookies); 288 289 // Container definieren 290 var jQuerycontainer_settings_info = jQuery('li.settings_info', context); 291 292 // Klasse entfernen, die das i-Icon alleine formatiert, da Perma-Optionen eingeblendet werden 293 jQuerycontainer_settings_info.find('.settings_info_menu').removeClass('perma_option_off'); 294 295 // Perma-Optionen-Icon (.settings) und Formular (noch versteckt) einbinden 296 jQuerycontainer_settings_info.find('.settings_info_menu').append('<span class="settings">Einstellungen</span><form><fieldset><legend>' + options.settings_perma + '</legend></fieldset></form>'); 297 298 299 // Die Dienste mit <input> und <label>, sowie checked-Status laut Cookie, schreiben 300 var checked = ' checked="checked"'; 301 if (facebook_on && facebook_perma) { 302 var perma_status_facebook = cookies.socialSharePrivacy_facebook === 'perma_on' ? checked : ''; 303 jQuerycontainer_settings_info.find('form fieldset').append( 304 '<input type="checkbox" name="perma_status_facebook" id="perma_status_facebook"' 305 + perma_status_facebook + ' /><label for="perma_status_facebook">' 306 + options.services.facebook.display_name + '</label>' 307 ); 308 } 309 310 if (twitter_on && twitter_perma) { 311 var perma_status_twitter = cookies.socialSharePrivacy_twitter === 'perma_on' ? checked : ''; 312 jQuerycontainer_settings_info.find('form fieldset').append( 313 '<input type="checkbox" name="perma_status_twitter" id="perma_status_twitter"' 314 + perma_status_twitter + ' /><label for="perma_status_twitter">' 315 + options.services.twitter.display_name + '</label>' 316 ); 317 } 318 319 if (gplus_on && gplus_perma) { 320 var perma_status_gplus = cookies.socialSharePrivacy_gplus === 'perma_on' ? checked : ''; 321 jQuerycontainer_settings_info.find('form fieldset').append( 322 '<input type="checkbox" name="perma_status_gplus" id="perma_status_gplus"' 323 + perma_status_gplus + ' /><label for="perma_status_gplus">' 324 + options.services.gplus.display_name + '</label>' 325 ); 326 } 327 328 // Cursor auf Pointer setzen fuer das Zahnrad 329 jQuerycontainer_settings_info.find('span.settings').css('cursor', 'pointer'); 330 331 // Einstellungs-Menue bei mouseover ein-/ausblenden 332 jQuery(jQuerycontainer_settings_info.find('span.settings'), context).live('mouseenter', function () { 333 var timeout_id = window.setTimeout(function () { jQuerycontainer_settings_info.find('.settings_info_menu').removeClass('off').addClass('on'); }, 500); 334 jQuery(this).data('timeout_id', timeout_id); 335 }); 336 jQuery(jQuerycontainer_settings_info, context).live('mouseleave', function () { 337 var timeout_id = jQuery(this).data('timeout_id'); 338 window.clearTimeout(timeout_id); 339 jQuerycontainer_settings_info.find('.settings_info_menu').removeClass('on').addClass('off'); 340 }); 341 342 // Klick-Interaktion auf <input> um Dienste dauerhaft ein- oder auszuschalten (Cookie wird gesetzt oder geloescht) 343 jQuery(jQuerycontainer_settings_info.find('fieldset input')).live('click', function (event) { 344 var click = event.target.id; 345 var service = click.substr(click.lastIndexOf('_') + 1, click.length); 346 var cookie_name = 'socialSharePrivacy_' + service; 347 348 if (jQuery('#' + event.target.id + ':checked').length) { 349 cookieSet(cookie_name, 'perma_on', options.cookie_expires, options.cookie_path, options.cookie_domain); 350 jQuery('form fieldset label[for=' + click + ']', context).addClass('checked'); 351 } else { 352 cookieDel(cookie_name, 'perma_on', options.cookie_path, options.cookie_domain); 353 jQuery('form fieldset label[for=' + click + ']', context).removeClass('checked'); 354 } 355 }); 356
357 // Dienste automatisch einbinden, wenn entsprechendes Cookie vorhanden ist 358 if (facebook_on && facebook_perma && cookies.socialSharePrivacy_facebook === 'perma_on') { 359 jQuery('li.facebook span.switch', context).click(); 360 } 361 if (twitter_on && twitter_perma && cookies.socialSharePrivacy_twitter === 'perma_on') { 362 jQuery('li.twitter span.switch', context).click(); 363 } 364 if (gplus_on && gplus_perma && cookies.socialSharePrivacy_gplus === 'perma_on') { 365 jQuery('li.gplus span.switch', context).click(); 366 } 367 } 368 }); // this.each(function () 369 }; // jQuery.fn.socialSharePrivacy = function (settings) { 370}(jQuery));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.