README.md
1Social Share Privacy
2====================
3
4Social Share Privacy is a jQuery plugin that lets you add social share buttons
5to your website that don't allow the social sites to track your users. The buttons
6are first disabled and a user needs to click them to enable them. So in order to
7e.g. like a site on facebook with these social share buttons a user needs to click
8two times. But in return for this extra click a user can only be tracked be this
9third party sites when he decides to enable the buttons. Using the settings menu
10a user can also permanently enable a social share button.
11
12Supported share services:
13
14 * [Buffer](#buffer-options-buffer)
15 * [Delicious](#delicious-options-delicious)
16 * [Disqus](#disqus-options-disqus)
17 * [EMail](#email-options-mail)
18 * [Facebook](#facebook-options-facebook)
19 * [Flattr](#flattr-options-flattr)
20 * [Google+](#google-options-gplus)
21 * [Hacker News](#hacker-news-options-hackernews)
22 * [Linked in](#linked-in-options-linkedin)
23 * [Pinterest](#pinterest-options-pinterest)
24 * [reddit](#reddit-options-reddit)
25 * [Stumble Upon](#stumble-upon-options-stumbleupon)
26 * [Tumblr](#tumblr-options-tumblr)
27 * [Twitter](#twitter-options-twitter)
28 * [XING](#xing-options-xing)
29
30Note that Tumblr and email are just normal links and thus always enabled.
31
32This is a fork of socialSharePrivacy by Heise. In this fork the service support
33was made extensible, some services where added and some bugs fixed. It has some
34incompatible changes, though (consolidated option names, use of the boolean values
35`true` and `false` instead of the strings `"on"` and `"off"` etc.).
36
37The original can be found here:
38[http://www.heise.de/extras/socialshareprivacy/](http://www.heise.de/extras/socialshareprivacy/)
39
40The Delicious support was heavily inspired by the delicious button jQuery plugin:
41[http://code.google.com/p/delicious-button/](http://code.google.com/p/delicious-button/)
42The style for this button was atually copied and only slightly adapted from this plugin.
43
44Overview
45--------
46
47 * [Dependencies](#dependencies)
48 * [How to use](#how-to-use)
49 * [Methods](#methods)
50 * [Events](#events)
51 * [Options](#options)
52 * [Global Options](#global-options)
53 * [Common Service Options](#common-service-options)
54 * [Custom Services](#custom-services)
55 * [Helper Functions](#helper-functions-jqueryfnsocialshareprivacy)
56 * [Pack.sh](#packsh)
57 * [Known Issues](#known-issues)
58 * [License](#license)
59
60<span id="dependencies">Dependencies</span>
61-------------------------------------------
62
63 * [jQuery](http://jquery.com/)
64 * [jQuery cookies plugin](https://github.com/panzi/jQuery-Cookies) (optional)
65 * [uglifyjs](https://npmjs.org/package/uglify-js) (optional)
66 * [uglifycss](https://npmjs.org/package/uglifycss) (optional)
67
68The jQuery cookies plugin is needed in order to enable services permanently.
69However, you can plug in you own replacement to store this options differently
70(e.g. via ajax in the user profile or in the browsers local store). For an
71example that stores the perma options in HTML5 local storage instead of cookies
72see the file
73[jquery.socialshareprivacy.localstorage.js](https://github.com/panzi/SocialSharePrivacy/blob/master/scripts/jquery.socialshareprivacy.localstorage.js).
74
75<span id="how-to-use">How to use</span>
76----------------------------------------
77
78```html
79<html>
80<head>
81…
82<script type="text/javascript" src="jquery.js"></script>
83<script type="text/javascript" src="jquery.socialshareprivacy.min.js"></script>
84<script type="text/javascript">
85$(document).ready(function () {
86 $('.share').socialSharePrivacy();
87});
88</script>
89…
90</head>
91<body>
92…
93<div class="share"></div>
94…
95</body>
96</html>
97```
98
99You only need to include the JavaScript files of the services you want to use. I
100recommend to pack all needed files into one using a JavaScript packer/compressor.
101The included [pack.sh](#packsh) script can do that for you, if you've got
102[uglifyjs](https://npmjs.org/package/uglify-js) and [uglifycss](https://npmjs.org/package/uglifycss)
103installed.
104
105However, for your convenience I provide these precompiled versions of the scripts:
106
107 * [jquery.socialshareprivacy.min.js](http://panzi.github.com/SocialSharePrivacy/javascripts/jquery.socialshareprivacy.min.js) <sup>1</sup>
108 * [jquery.socialshareprivacy.min.autoload.js](http://panzi.github.com/SocialSharePrivacy/javascripts/jquery.socialshareprivacy.min.autoload.js) <sup>2</sup>
109 * [jquery.socialshareprivacy.min.de.js](http://panzi.github.com/SocialSharePrivacy/javascripts/jquery.socialshareprivacy.min.de.js) <sup>3</sup>
110 * [jquery.socialshareprivacy.min.fr.js](http://panzi.github.com/SocialSharePrivacy/javascripts/jquery.socialshareprivacy.min.fr.js) <sup>3</sup>
111 * [jquery.socialshareprivacy.min.nl.js](http://panzi.github.com/SocialSharePrivacy/javascripts/jquery.socialshareprivacy.min.nl.js) <sup>3</sup>
112 * [jquery.socialshareprivacy.min.ru.js](http://panzi.github.com/SocialSharePrivacy/javascripts/jquery.socialshareprivacy.min.ru.js) <sup>3</sup>
113 * [jquery.socialshareprivacy.min.css](http://panzi.github.com/SocialSharePrivacy/stylesheets/jquery.socialshareprivacy.min.css)
114
1151 This file contains all JavaScripts except the `jquery.socialshareprivacy.localstorage.js` module and the translations.
1162 This file contains the same as 1, but it also automatically initializes elements with the attribute `data-social-share-privacy="true"` set.
1173 These files contain only translation strings and have to be included in addition to `jquery.socialshareprivacy.min.js`.
118
119You can also asynchronously load the buttons if you use the `jquery.socialshareprivacy.min.autoload.js` script:
120
121```html
122<html>
123<head>
124…
125<script type="text/javascript" src="jquery.js"></script>
126…
127</head>
128<body>
129…
130<div data-social-share-privacy="true"></div>
131…
132<div data-social-share-privacy="true"></div>
133…
134<script type="text/javascript">
135(function () {
136 var s = document.createElement('script');
137 var t = document.getElementsByTagName('script')[0];
138
139 s.type = 'text/javascript';
140 s.async = true;
141 s.src = 'jquery.socialshareprivacy.min.autoload.js';
142
143 t.parentNode.insertBefore(s, t);
144})();
145</script>
146</body>
147</html>
148```
149
150<span id="methods">Methods</span>
151---------------------------------
152
153### socialSharePrivacy
154
155**Signature:**
156```javascript
157.socialSharePrivacy([options])
158```
159
160Add social share buttons to all elements in the set. Returns `this`.
161
162### destroy
163
164**Signature:**
165```javascript
166.socialSharePrivacy("destroy")
167```
168Remove all social share buttons. This will return all elements in the set back
169to their pre-init state. Returns `this`.
170
171### disable
172
173**Signature:**
174```javascript
175.socialSharePrivacy("disable", [service_name])
176```
177
178Disable the named service or disable all services if no `service_name` is given.
179Returns `this`.
180
181### enable
182
183**Signature:**
184```javascript
185.socialSharePrivacy("enable", [service_name])
186```
187
188Enable the named service or enable all services if no `service_name` is given.
189Returns `this`.
190
191### option
192
193**Signature:**
194```javascript
195.socialSharePrivacy("option", option_name, [value])
196```
197
198Get or set an option. If no `value` is specified it will act as a getter.
199Returns `this` when acting as setter.
200
201### options
202
203**Signature:**
204```javascript
205.socialSharePrivacy("options", [options])
206```
207
208Get or set all options. If no `options` are specified it will act as a getter.
209Returns `this` when acting as setter.
210
211### toggle
212
213**Signature:**
214```javascript
215.socialSharePrivacy("toggle", [service_name])
216```
217
218Toggle the named service or toggle all services if no `service_name` is given.
219Returns `this`.
220
221<span id="events">Events</span>
222-------------------------------
223
224### socialshareprivacy:create
225
226This event is emitted after the `socialSharePrivacy` method created a Social
227Share privacy widget. The event object will have an `options` attribute holding
228the option object of the initialized widget.
229
230### socialshareprivacy:destroy
231
232This event is emitted before a Social Share Privacy widget is destroyed.
233
234### socialshareprivacy:disable
235
236This event is emitted after a certain service was disabled. The event object
237will have a `serviceName` property, holding the name of the service that was
238disabled, and an `isClick` property, wich is `true` if a click by a user caused
239this event (`false` if it was disabled via JavaScript).
240
241### socialshareprivacy:enable
242
243This event is emitted after a certain service was enabled. The event object
244will have a `serviceName` property, holding the name of the service that was
245enabled, and an `isClick` property, wich is `true` if a click by a user caused
246this event (`false` if it was enabled via JavaScript).
247
248<span id="options">Options</span>
249---------------------------------
250
251Options can be set globally via `$.fn.socialSharePrivacy.settings`, via an
252options object passed to the `socialSharePrivacy` function or via `data-*`
253attributes of the share element. If options are defined in more than one way
254the `data-*` attributes will overwrite the options from the passed options
255object and the options from passed options object will overwrite the
256globally defined options.
257
258### `data-*` attributes
259
260In order to pass the options as `data-*` attributes simply prepend `data-` to
261all option names. For the language option you can also use the standard `lang`
262attribute. If you want to set an option of an service just use a `data-*`
263attribute that includes dots (`.`) as if it where a JavaScript property
264expression:
265
266```html
267<div class="share"
268 lang="de"
269 data-uri="http://example.com/"
270 data-image="http://example.com/image.png"
271 data-services.tumblr.type="photo"
272 data-order="facebook twitter tumblr"></div>
273```
274
275If you want you can combine all options of a service and pass a JSON string as
276attribute value:
277
278```html
279<div class="share"
280 lang="de"
281 data-uri="http://example.com/"
282 data-image="http://example.com/image.png"
283 data-services.tumblr='{"type":"photo"}'
284 data-order="facebook twitter tumblr"></div>
285```
286
287You can also do this for all services:
288
289```html
290<div class="share"
291 lang="de"
292 data-uri="http://example.com/"
293 data-image="http://example.com/image.png"
294 data-services='{"tumblr":{"type":"photo"}}'
295 data-order="facebook twitter tumblr"></div>
296```
297
298Or even all options at once:
299
300```html
301<div class="share"
302 data-options='{
303 "language" : "de",
304 "uri" : "http://example.com/",
305 "image" : "http://example.com/image.png",
306 "services" : {
307 "tumblr" : {
308 "type" : "photo"
309 }
310 },
311 "order" : ["facebook", "twitter", "tumblr"]
312 }'></div>
313```
314
315Actually these aren't JSON objects but JavaScript expressions. This way
316you can pass JavaScript code that will evaluate the option values when the
317`socialSharePrivacy` function is called. You can even pass a whole new
318service implementation inline, if you want:
319
320```html
321<div class="share"
322 data-options="{
323 language : document.documentElement.lang,
324 title : document.title,
325 services : {
326 my_inline_service : {
327 status : true,
328 dummy_line_img : 'dummy.png',
329 dummy_alt : 'DISABLED',
330 display_name : 'My Inline Service',
331 txt_info : 'Click to enable.',
332 perma_option : true,
333 button : function (options, uri, settings) {
334 return $('<div>ENABLED</div>');
335 }
336 }
337 }
338 }"></div>
339```
340
341The main advantage of using the `data-*` attributes is, that you can easily
342render several *different* share elements on your webserver and then initialize
343them with one single JavaScript function call (no need for uniqe element IDs
344and separate JavaScript calls for each element).
345
346**NOTE:** When passing service options via `data-*` attributes all option
347values (except the common service options) are treated as strings. If you
348need to pass values of other types (numbers, booleans, arrays or functions)
349you need to use the JavaScript object syntax.
350
351### <span id="global-options">Global Options</span>
352
353Set these options like this:
354
355```javascript
356$.fn.socialSharePrivacy.settings.title = "Title of the thing to share.";
357…
358```
359
360Or like this:
361
362```html
363<script type="application/x-social-share-privacy-settings">
364{
365 path_prefix: "/socialshareprivacy",
366 css_path: "socialshareprivacy.css",
367 …
368}
369</script>
370```
371
372The version using `script` tags uses again JavaScript expressions to enable
373inline service definitions.
374
375<table>
376<thead>
377<tr>
378<th>Option</th>
379<th>Default Value</th>
380<th>Description</th>
381</tr>
382</thead>
383<tbody>
384<tr>
385<td>info_link</td>
386<td><a href="http://panzi.github.com/SocialSharePrivacy/">http://panzi.github.com/SocialSharePrivacy/</a></td>
387<td>The link of the <em>i</em>-icon that links users to more information about this.</td>
388</tr>
389<tr>
390<td>info_link_target</td>
391<td></td>
392<td>The target attribute of the info link. Possible values are <code>_blank</code>,
393<code>_self</code>, <code>_parent</code>, <code>_top</code> or a frame name.</td>
394</tr>
395<tr>
396<td>txt_settings</td>
397<td>Settings</td>
398<td>The text of the settings icon.</td>
399</tr>
400<tr>
401<td>txt_help</td>
402<td>[Text]</td>
403<td>Tooltip text of the settings menu.</td>
404</tr>
405<tr>
406<td>settings_perma</td>
407<td>[Text]</td>
408<td>Headline of the settings menu.</td>
409</tr>
410<tr>
411<td>layout</td>
412<td>line</td>
413<td>Possible values: <code>line</code> or <code>box</code></td>
414</tr>
415<tr>
416<td>set_perma_option</td>
417<td>function (service_name, settings)</td>
418<td>Function that stores the perma setting of the service specified by service_name.</td>
419</tr>
420<tr>
421<td>del_perma_option</td>
422<td>function (service_name, settings)</td>
423<td>Function that removes the perma setting of the service specified by service_name.</td>
424</tr>
425<tr>
426<td>get_perma_options</td>
427<td>function (settings)</td>
428<td>Function that gets the perma setting of all services in an object where the keys are
429the service names and the values are boolean. Services that are missing are assumed as
430false.</td>
431</tr>
432<tr>
433<td>get_perma_option</td>
434<td>function (service_name, settings)</td>
435<td>Function that gets the perma setting of the service specified by service_name.
436Returns a boolean value.<br/>
437<br/>
438Only one of the two functions get_perma_options and get_perma_option
439need to be implemented. In that case the respective other needs to be set to
440null.</td>
441</tr>
442<tr>
443<td>perma_option</td>
444<td>true (if the jQuery cookies plugin is installed)</td>
445<td>Give users the posibility to permanently enable services. (Boolean)</td>
446</tr>
447<tr>
448<td>cookie_path</td>
449<td>/</td>
450<td></td>
451</tr>
452<tr>
453<td>cookie_domain</td>
454<td><code>document.location.hostname</code></td>
455<td></td>
456</tr>
457<tr>
458<td>cookie_expires</td>
459<td>365</td>
460<td>Days until the cookie expires.</td>
461</tr>
462<tr>
463<td>path_prefix</td>
464<td></td>
465<td>Prefix to all paths (css_path, dummy_line_img, dummy_box_img)</td>
466</tr>
467<tr>
468<td>css_path</td>
469<td>socialshareprivacy/socialshareprivacy.css</td>
470<td></td>
471</tr>
472<tr>
473<td>language</td>
474<td>en</td>
475<td></td>
476</tr>
477<tr>
478<td>uri</td>
479<td>[Function]</td>
480<td>URI of the thing to share that is passed on to the share services. The default function
481uses the value of the first <code>link</code> element with the <code>rel</code> attribute
482<code>canonical</code> or the first <code>meta</code> element with the <code>property</code>
483attribute <code>og:url</code> it can find or <code>location.href</code> if there are no such
484elements. (Function or string)</td>
485</tr>
486<tr>
487<td>title</td>
488<td></td>
489<td>The title to pass to any share service that want's one.</td>
490</tr>
491<tr>
492<td>description</td>
493<td></td>
494<td>The description to pass to any share service that want's one.</td>
495</tr>
496<tr>
497<td>image</td>
498<td></td>
499<td>Image URL to pass to any share service that want's one.</td>
500</tr>
501<tr>
502<td>embed</td>
503<td></td>
504<td>HTML embed code to pass to any share service that want's one.</td>
505</tr>
506<tr>
507<td>ignore_fragment</td>
508<td>true</td>
509<td>Ignore the <code>#fragment</code> part of the url. (Boolean)</td>
510</tr>
511</tbody>
512</table>
513
514### <span id="common-service-options">Common Service Options</span>
515
516<table>
517<thead>
518<tr>
519<th>Option</th>
520<th>Default Value</th>
521<th>Description</th>
522</tr>
523</thead>
524<tbody>
525<tr>
526<td>status</td>
527<td>true</td>
528<td>Enable/disable this service. (Boolean)</td>
529</tr>
530<tr>
531<td>class_name</td>
532<td>[service specific]</td>
533<td>The HTML class of the share button wrapper. Per default it is the key of the
534service as it is registered in <code>jQuery.fn.socialSharePrivacy.settings.services</code>.</td>
535</tr>
536<tr>
537<td>button_class</td>
538<td></td>
539<td>HTML class of the share button. Per default the same as class_name.</td>
540</tr>
541<tr>
542<td>dummy_line_img</td>
543<td></td>
544<td>Placeholder image for deactivated button in <code>line</code> layout.</td>
545</tr>
546<tr>
547<td>dummy_box_img</td>
548<td></td>
549<td>Placeholder image for deactivated button in <code>box</code> layout.</td>
550</tr>
551<tr>
552<td>dummy_alt</td>
553<td>[Text]</td>
554<td>Alt text of the placeholder image.</td>
555</tr>
556<tr>
557<td>txt_info</td>
558<td>[Text]</td>
559<td>Help text for deactivated button.</td>
560</tr>
561<tr>
562<td>txt_off</td>
563<td>[Text]</td>
564<td>Status text if button is deactivated.</td>
565</tr>
566<tr>
567<td>txt_on</td>
568<td>[Text]</td>
569<td>Status text if button is activated.</td>
570</tr>
571<tr>
572<td>perma_option</td>
573<td>true</td>
574<td>Give users the posibility to permanently enable this service.<br/>
575(Boolean)</td>
576</tr>
577<tr>
578<td>display_name</td>
579<td>[Text]</td>
580<td>Name of the service.</td>
581</tr>
582<tr>
583<td>referrer_track</td>
584<td></td>
585<td>A string that is appended to the URI for this service, so you can track from
586where your users are coming.</td>
587</tr>
588<tr>
589<td>language</td>
590<td></td>
591<td>Override the global language just for this service.</td>
592</tr>
593<tr>
594<td>path_prefix</td>
595<td></td>
596<td>Override the global <code>path_prefix</code> just for this service.</td>
597</tr>
598</tbody>
599</table>
600
601### <span id="buffer-options-buffer">Buffer Options</span> (`buffer`)
602
603See also: [official documentation](http://bufferapp.com/extras/button)
604
605Example:
606
607```javascript
608$(document).ready(function () {
609 $('#share').socialSharePrivacy({
610 services: {
611 buffer: {
612 text : 'Some descriptive text...'
613 }
614 }
615 });
616});
617```
618
619<table>
620<thead>
621<tr>
622<th>Option</th>
623<th>Default Value</th>
624<th>Description</th>
625</tr>
626</thead>
627<tbody>
628<tr>
629<td>text</td>
630<td><a href="#gettitleoptions-uri-settings">jQuery.fn.socialSharePrivacy.getTitle</a></td>
631<td>Tweet text (excluding the URL). It will be truncated to 120 characters, leaving
632place for 20 characters for the shortened URL. (Function or string)</td>
633</tr>
634<tr>
635<td>via</td>
636<td></td>
637<td>Twitter username (without the leading <code>@</code>). (Function or string)</td>
638</tr>
639<tr>
640<td>picture</td>
641<td><a href="#getimageoptions-uri-settings">jQuery.fn.socialSharePrivacy.getImage</a></td>
642<td>URL of image that represents the thing to share. (Function or string)</td>
643</tr>
644</tbody>
645</table>
646
647
648### <span id="delicious-options-delicious">Delicious Options</span> (`delicious`)
649
650See also: [official documentation](http://delicious.com/tools)
651
652Example:
653
654```javascript
655$(document).ready(function () {
656 $('#share').socialSharePrivacy({
657 services: {
658 delicious: {
659 title : 'Bookmark title'
660 }
661 }
662 });
663});
664```
665
666<table>
667<thead>
668<tr>
669<th>Option</th>
670<th>Default Value</th>
671<th>Description</th>
672</tr>
673</thead>
674<tbody>
675<tr>
676<td>title</td>
677<td><a href="#gettitleoptions-uri-settings">jQuery.fn.socialSharePrivacy.getTitle</a></td>
678<td>Title of the new bookmark. (Function or string)</td>
679</tr>
680</tbody>
681</table>
682
683### <span id="disqus-options-disqus">Disqus Options</span> (`disqus`)
684
685See also: [official documentation](http://socialshareprivacy.disqus.com/admin/universal/)
686
687**WARNING:** This is a hack. Using this Disqus button will break any usage of the comment
688count code as shown on the linked page above. This button does of course not interfere
689with the main Disqus widget.
690
691Example:
692
693```javascript
694$(document).ready(function () {
695 $('#share').socialSharePrivacy({
696 services: {
697 disqus: {
698 shortname : 'myforumshortname',
699 count : 'reactions'
700 }
701 }
702 });
703});
704```
705
706<table>
707<thead>
708<tr>
709<th>Option</th>
710<th>Default Value</th>
711<th>Description</th>
712</tr>
713</thead>
714<tbody>
715<tr>
716<td>shortname</td>
717<td></td>
718<td>Your Disqus forum shortname. If an empty string is given it tries to use
719<code>window.disqus_shortname</code>. (String)</td>
720</tr>
721<tr>
722<td>count</td>
723<td>comments</td>
724<td>What count to show.<br/>
725Possible values: <code>comments</code> or <code>reactions</code></td>
726</tr>
727<tr>
728<td>onclick</td>
729<td></td>
730<td>Function to call when the Disqus button was clicked. (Function or String)</td>
731</tr>
732</tbody>
733</table>
734
735### <span id="email-options-mail">EMail Options</span> (`mail`)
736
737<table>
738<thead>
739<tr>
740<th>Option</th>
741<th>Default Value</th>
742<th>Description</th>
743</tr>
744</thead>
745<tbody>
746<tr>
747<td>subject</td>
748<td><a href="#gettitleoptions-uri-settings">jQuery.fn.socialSharePrivacy.getTitle</a></td>
749<td>Subject of the new email. (Function or string)</td>
750</tr>
751<tr>
752<td>body</td>
753<td>[Function]</td>
754<td>Body of the new email. (Function or string)</td>
755</tr>
756</tbody>
757</table>
758
759### <span id="facebook-options-facebook">Facebook Options</span> (`facebook`)
760
761Note that facebook only supports certain languages and requires the region suffix (e.g.
762`en_US`). The facebook service ensures that only supported language strings are sent
763to facebook, because otherwise facebook fails to render anything.
764
765See also: [official documentation](http://developers.facebook.com/docs/reference/plugins/like/)
766
767Example:
768
769```javascript
770$(document).ready(function () {
771 $('#share').socialSharePrivacy({
772 services: {
773 facebook: {
774 action : 'recommend',
775 colorscheme : 'dark'
776 }
777 }
778 });
779});
780```
781
782<table>
783<thead>
784<tr>
785<th>Option</th>
786<th>Default Value</th>
787<th>Description</th>
788</tr>
789</thead>
790<tbody>
791<tr>
792<td>action</td>
793<td>like</td>
794<td>Possible values: <code>like</code> or <code>recommend</code></td>
795</tr>
796<tr>
797<td>colorscheme</td>
798<td>light</td>
799<td>Possible values: <code>light</code> or <code>dark</code></td>
800</tr>
801<tr>
802<td>font</td>
803<td></td>
804<td>Possible values: <code>arial</code>, <code>lucida grande</code>, <code>segoe ui</code>, <code>tahoma</code>,
805<code>trebuchet ms</code> or <code>verdana</code></td>
806</tr>
807</tbody>
808</table>
809
810### <span id="flattr-options-flattr">Flattr Options</span> (`flattr`)
811
812See also: [official documentation](http://developers.flattr.net/button/)
813
814Example:
815```javascript
816$(document).ready(function () {
817 $('#share').socialSharePrivacy({
818 services: {
819 flattr: {
820 uid : 'yourflattrid',
821 category : 'Text'
822 }
823 }
824 });
825});
826```
827
828<table>
829<thead>
830<tr>
831<th>Option</th>
832<th>Default Value</th>
833<th>Description</th>
834</tr>
835</thead>
836<tbody>
837<tr>
838<td>title</td>
839<td><a href="#gettitleoptions-uri-settings">jQuery.fn.socialSharePrivacy.getTitle</a></td>
840<td>Title of the thing to share. (Function or string)</td>
841</tr>
842<tr>
843<td>description</td>
844<td><a href="#getdescriptionoptions-uri-settings">jQuery.fn.socialSharePrivacy.getDescription</a></td>
845<td>Description of the thing to share. (Function or string)</td>
846</tr>
847<tr>
848<td>uid</td>
849<td></td>
850<td>Flattr username.</td>
851</tr>
852<tr>
853<td>category</td>
854<td></td>
855<td>Possible values: <code>Text</code>, <code>Images</code>, <code>Video</code>, <code>Software</code>, <code>People</code> or
856<code>Other</code></td>
857</tr>
858<tr>
859<td>tags</td>
860<td></td>
861<td>Multiple tags are seperated by a comma <code>,</code>. Only alpha characters are supported in tags.</td>
862</tr>
863<tr>
864<td>popout</td>
865<td></td>
866<td>When set to <code>0</code> no popout will appear when the Flattr button is hovered.</td>
867</tr>
868<tr>
869<td>hidden</td>
870<td></td>
871<td>When set to <code>1</code> your content will not be publicly listed on Flattr.</td>
872</tr>
873</tbody>
874</table>
875
876### <span id="google-options-gplus">Google+ Options</span> (`gplus`)
877
878There are no Google+ specific options.
879
880See also: [official documentation](http://www.google.com/webmasters/+1/button/)
881
882### <span id="hacker-news-options-hackernews">Hacker News Options</span> (`hackernews`)
883
884See also: [HNSearch API documentation](http://www.hnsearch.com/api)
885
886<table>
887<thead>
888<tr>
889<th>Option</th>
890<th>Default Value</th>
891<th>Description</th>
892</tr>
893</thead>
894<tbody>
895<tr>
896<td>title</td>
897<td><a href="#gettitleoptions-uri-settings">jQuery.fn.socialSharePrivacy.getTitle</a></td>
898<td>Title of the news to share. (Function or string)</td>
899</tr>
900</tbody>
901</table>
902
903### <span id="pinterest-options-pinterest">Pinterest Options</span> (`pinterest`)
904
905See also: [official documentation](http://business.pinterest.com/widget-builder/#do_pin_it_button)
906
907<table>
908<thead>
909<tr>
910<th>Option</th>
911<th>Default Value</th>
912<th>Description</th>
913</tr>
914</thead>
915<tbody>
916<tr>
917<td>title</td>
918<td><a href="#gettitleoptions-uri-settings">jQuery.fn.socialSharePrivacy.getTitle</a></td>
919<td>Title of the thing to share. (Function or string)</td>
920</tr>
921<tr>
922<td>description</td>
923<td><a href="#getdescriptionoptions-uri-settings">jQuery.fn.socialSharePrivacy.getDescription</a></td>
924<td>Description of the thing to share. (Function or string)</td>
925</tr>
926<tr>
927<td>media</td>
928<td><a href="#getimageoptions-uri-settings">jQuery.fn.socialSharePrivacy.getImage</a></td>
929<td>URL of image that represents the thing to share. (Function or string)</td>
930</tr>
931</tbody>
932</table>
933
934### <span id="linked-in-options-linkedin">Linked in Options</span> (`linkedin`)
935
936See also: [official documentation](http://developer.linkedin.com/share-plugin)
937
938<table>
939<thead>
940<tr>
941<th>Option</th>
942<th>Default Value</th>
943<th>Description</th>
944</tr>
945</thead>
946<tbody>
947<tr>
948<td>onsuccess</td>
949<td></td>
950<td>Name of a callback function that shall invoked when the link was successfully shared.
951The shared url will be passed as a parameter. (String)</td>
952</tr>
953<tr>
954<td>onerror</td>
955<td></td>
956<td>Name of a callback function that shall invoked if link sharing failed.
957The shared url will be passed as a parameter. (String)</td>
958</tr>
959<tr>
960<td>showzero</td>
961<td>false</td>
962<td>Even show count and no placeholder if there are zero shares. (Boolean)</td>
963</tr>
964</tbody>
965</table>
966
967### <span id="reddit-options-reddit">Reddit Options</span> (`reddit`)
968
969See also: [official documentation](http://www.reddit.com/buttons/)
970
971Example:
972
973```javascript
974$(document).ready(function () {
975 $('#share').socialSharePrivacy({
976 services: {
977 reddit: {
978 newwindow : false,
979 bgcolor : '#ffff00'
980 }
981 }
982 });
983});
984```
985
986<table>
987<thead>
988<tr>
989<th>Option</th>
990<th>Default Value</th>
991<th>Description</th>
992</tr>
993</thead>
994<tbody>
995<tr>
996<td>title</td>
997<td><a href="#gettitleoptions-uri-settings">jQuery.fn.socialSharePrivacy.getTitle</a></td>
998<td>Title of the thing to share. (Function or string)</td>
999</tr>
1000<tr>
1001<td>target</td>
1002<td></td>
1003<td>A cummunity to target.</td>
1004</tr>
1005<tr>
1006<td>newwindow</td>
1007<td>1</td>
1008<td>Opens reddit in a new window when set to <code>1</code>. Set this option to an empty string or
1009anything that evaluates to false to open reddit in the same window.</td>
1010</tr>
1011<tr>
1012<td>bgcolor</td>
1013<td>transparent</td>
1014<td>HTML color.</td>
1015</tr>
1016<tr>
1017<td>bordercolor</td>
1018<td></td>
1019<td>HTML color.</td>
1020</tr>
1021</tbody>
1022</table>
1023
1024### <span id="stumble-upon-options-stumbleupon">Stumble Upon Options</span> (`stumbleupon`)
1025
1026There are no Stumble Upon specific options.
1027
1028See also: [official documentation](http://www.stumbleupon.com/dt/badges/create)
1029
1030### <span id="tumblr-options-tumblr">Tumblr Options</span> (`tumblr`)
1031
1032See also: [official documentation](http://www.tumblr.com/docs/en/buttons)
1033
1034Example:
1035
1036```javascript
1037$(document).ready(function () {
1038 $('#share').socialSharePrivacy({
1039 services: {
1040 tumblr: {
1041 type : 'photo',
1042 photo : 'http://example.com/example.png'
1043 }
1044 }
1045 });
1046});
1047```
1048
1049<table>
1050<thead>
1051<tr>
1052<th>Option</th>
1053<th>Default Value</th>
1054<th>Description</th>
1055</tr>
1056</thead>
1057<tbody>
1058<tr>
1059<td>type</td>
1060<td>link</td>
1061<td>Possible values: <code>link</code>, <code>quote</code>, <code>photo</code> or <code>video</code></td>
1062</tr>
1063<tr>
1064<td>name</td>
1065<td><a href="#gettitleoptions-uri-settings">jQuery.fn.socialSharePrivacy.getTitle</a></td>
1066<td>Title of the thing to share. (Function or string)<br/>
1067<br/>
1068This option is only defined for the type <code>link</code>.</td>
1069</tr>
1070<tr>
1071<td>description</td>
1072<td><a href="#getdescriptionoptions-uri-settings">jQuery.fn.socialSharePrivacy.getDescription</a></td>
1073<td>Description of the thing to share. (Function or string)<br/>
1074<br/>
1075This option is only defined for the type <code>link</code>.</td>
1076</tr>
1077<tr>
1078<td>quote</td>
1079<td>[Function]</td>
1080<td>Quote to share. (Function or string)<br/>
1081<br/>
1082This option is only defined for the type <code>quote</code>.</td>
1083</tr>
1084<tr>
1085<td>photo</td>
1086<td><a href="#getimageoptions-uri-settings">jQuery.fn.socialSharePrivacy.getImage</a></td>
1087<td>Image URL of the thing to share. (Function or string)<br/>
1088<br/>
1089This option is only defined for the type <code>photo</code>.</td>
1090</tr>
1091<tr>
1092<td>clickthrou</td>
1093<td>[Function]</td>
1094<td>The URL to where you get when you click the image. Per default it's the
1095shared URI including the referrer_track. (Function or string)<br/>
1096<br/>
1097This option is only defined for the type <code>photo</code>.</td>
1098</tr>
1099<tr>
1100<td>embed</td>
1101<td><a href="#getembedoptions-uri-settings">jQuery.fn.socialSharePrivacy.getEmbed</a></td>
1102<td>Embed code of the thing to share. (Function or string)<br/>
1103<br/>
1104This option is only defined for the type <code>video</code>.</td>
1105</tr>
1106<tr>
1107<td>caption</td>
1108<td><a href="#getdescriptionoptions-uri-settings">jQuery.fn.socialSharePrivacy.getDescription</a></td>
1109<td>Caption of the thing to share. (Function or string)<br/>
1110<br/>
1111This option is only defined for the types <code>photo</code> and <code>video</code>.</td>
1112</tr>
1113</tbody>
1114</table>
1115
1116### <span id="twitter-options-twitter">Twitter Options</span> (`twitter`)
1117
1118See also: [official documentation](https://twitter.com/about/resources/buttons#tweet)
1119
1120Example:
1121
1122```javascript
1123$(document).ready(function () {
1124 $('#share').socialSharePrivacy({
1125 services: {
1126 twitter: {
1127 hashtags : 'win'
1128 }
1129 }
1130 });
1131});
1132```
1133
1134<table>
1135<thead>
1136<tr>
1137<th>Option</th>
1138<th>Default Value</th>
1139<th>Description</th>
1140</tr>
1141</thead>
1142<tbody>
1143<tr>
1144<td>text</td>
1145<td><a href="#gettitleoptions-uri-settings">jQuery.fn.socialSharePrivacy.getTitle</a></td>
1146<td>Tweet text (excluding the URL). It will be truncated to 120 characters, leaving
1147place for 20 characters for the shortened URL. (Function or string)</td>
1148</tr>
1149<tr>
1150<td>via</td>
1151<td></td>
1152<td>Twitter username (without the leading <code>@</code>).</td>
1153</tr>
1154<tr>
1155<td>related</td>
1156<td></td>
1157<td>Twitter username (without the leading <code>@</code>).</td>
1158</tr>
1159<tr>
1160<td>hashtags</td>
1161<td></td>
1162<td>Hashtag to add to the tweet (without the leading <code>#</code>).</td>
1163</tr>
1164<tr>
1165<td>dnt</td>
1166<td>true</td>
1167<td>Do not tailor.</td>
1168</tr>
1169</tbody>
1170</table>
1171
1172### <span id="xing-options-xing">XING Options</span> (`xing`)
1173
1174There are no XING specific options.
1175
1176Note that the view counter will not work unless the XING button is enabled by the
1177user.
1178
1179See also: [official documentation](https://www.xing.com/app/share?op=button_builder)
1180
1181<span id="custom-services">Custom Services</span>
1182-------------------------------------------------
1183
1184```javascript
1185(function ($, undefined) {
1186 $.fn.socialSharePrivacy.settings.services.myservice = {
1187 /* default values for common service options... */
1188 'button': function (options, uri, settings) {
1189 return $('<iframe scrolling="no" frameborder="0" allowtransparency="true"></iframe>').attr(
1190 'src', 'http://myservice.example/?' + $.param({
1191 url: uri + options.referrer_track
1192 });
1193 }
1194 };
1195})(jQuery);
1196```
1197
1198### <span id="helper-functions-jqueryfnsocialshareprivacy">Helper Functions</span> (`jQuery.fn.socialSharePrivacy.*`)
1199
1200Some helper functions that might be handy to use in your custom service.
1201
1202#### <span id="absurlurl--baseurl">absurl(url [, baseurl])</span>
1203
1204Build an absolute url using a base url.
1205The provided base url has to be a valid absolute url. It will not be validated!
1206If no base url is given the documents base url/location is used.
1207Schemes that behave other than http might not work.
1208This function tries to support `file:`-urls, but might fail in some cases.
1209`email:`-urls aren't supported at all (don't make sense anyway).
1210
1211#### <span id="abbreviatetexttext-length">abbreviateText(text, length)</span>
1212
1213Abbreviate at last blank before length and add `"\u2026"` (…, horizontal ellipsis).
1214The length is the number of UTF-8 encoded bytes, not the number of unicode code
1215points, because twitters 140 "characters" are actually bytes.
1216
1217#### <span id="escapehtmltext">escapeHtml(text)</span>
1218
1219Escapes text so it can be used safely in HTML strings.
1220
1221<table>
1222<thead>
1223<tr>
1224<th>Character</th>
1225<th>Replacement</th>
1226</tr>
1227</thead>
1228<tbody>
1229<tr>
1230<td><code><</code></td>
1231<td><code>&lt;</code></td>
1232</tr>
1233<tr>
1234<td><code>></code></td>
1235<td><code>&gt;</code></td>
1236</tr>
1237<tr>
1238<td><code>&</code></td>
1239<td><code>&amp;</code></td>
1240</tr>
1241<tr>
1242<td><code>"</code></td>
1243<td><code>&quot;</code></td>
1244</tr>
1245<tr>
1246<td><code>'</code></td>
1247<td><code>&#39;</code></td>
1248</tr>
1249</tbody>
1250</table>
1251
1252#### <span id="formatnumber-number">formatNumber(number)</span>
1253
1254Format a number to be displayed in a typical number bubble. It will
1255abbreviate numbers bigger than 9999 using the `K` suffix, rounding the
1256number to the closest thousand and it inserts thousands delimeter
1257characters.
1258
1259Example:
1260
1261```javascript
1262$.fn.socialSharePrivacy.formatNumber(1234) => "1,234"
1263$.fn.socialSharePrivacy.formatNumber(12345) => "12K"
1264$.fn.socialSharePrivacy.formatNumber(1234567) => "1,235K"
1265```
1266
1267#### <span id="gettitleoptions-uri-settings">getTitle(options, uri, settings)</span>
1268
1269Lookup title of shared thing in several places:
1270
1271 * `settings.title`, which may be a string or a function with the same parameters.
1272 * `$('meta[name="DC.title"]').attr('content') + ' - ' + $('meta[name="DC.creator"]').attr('content')`
1273 * `$('meta[name="DC.title"]').attr('content')`
1274 * `$('meta[property="og:title"]').attr('content')`
1275 * `$('title').text()`
1276
1277The element of the share button is passed as `this`.
1278
1279#### <span id="getimageoptions-uri-settings">getImage(options, uri, settings)</span>
1280
1281Lookup image URL of shared thing in several places:
1282
1283 * `settings.image`, which may be a string or a function with the same parameters.
1284 * `$('meta[property="image"], meta[property="og:image"], meta[property="og:image:url"], ' +`<br/>
1285 `'meta[name="twitter:image"], link[rel="image_src"], itemscope *[itemprop="image"]').`<br/>
1286 `first().attr('content'` / `'src'` / `'href')`
1287 * `$('img').filter(':visible').filter(function () { return $(this).parents('.social_share_privacy_area').length === 0; })`,
1288 using the image with the biggest area.
1289 * `$('link[rel~="shortcut"][rel~="icon"]').attr('href')`
1290 * `'http://www.google.com/s2/favicons?'+$.param({domain:location.hostname})`
1291
1292The element of the share button is passed as `this`.
1293
1294#### <span id="getembedoptions-uri-settings">getEmbed(options, uri, settings)</span>
1295
1296Lookup image URL of shared thing in several places:
1297
1298 * `settings.embed`, which may be a string or a function with the same parameters.
1299
1300If there is no embed code found it will construct it's own embed code. For this it
1301first searches for a meta element with the name `twitter:player` and use it's
1302content as the `src` of an iframe element. If meta tags with the names
1303`twitter:player:width` and `twitter:player:height` are found they are used for the
1304width and height attributes of the iframe. If no `twitter:player` meta elements is
1305found the url of the current page will be used as the iframe `src`
1306(`uri + options.referrer_track`).
1307
1308The element of the share button is passed as `this`.
1309
1310#### <span id="getdescriptionoptions-uri-settings">getDescription(options, uri, settings)</span>
1311
1312Lookup description of shared thing in several places:
1313
1314 * `settings.description`, which may be a string or a function with the same parameters.
1315 * `$('meta[name="twitter:description"]').attr('content')`
1316 * `$('meta[itemprop="description"]').attr('content')`
1317 * `$('meta[name="description"]').attr('content')`
1318 * `$('article, p').first().text()`
1319 * `$('body').text()`
1320
1321If not defined in `settings.description` the found text is truncated at 3500 bytes.
1322
1323The element of the share button is passed as `this`.
1324
1325<span id="packsh">Pack.sh</span>
1326---------------------------------
1327
1328You can use `pack.sh` to pack the modules and languages you want.
1329
1330Example:
1331
1332```sh
1333./pack.sh -m twitter,facebook,gplus -l de,fr
1334```
1335
1336This generates these files:
1337
1338```
1339build/jquery.socialshareprivacy.min.js
1340build/jquery.socialshareprivacy.min.autoload.js
1341build/jquery.socialshareprivacy.min.de.js
1342build/jquery.socialshareprivacy.min.fr.js
1343build/jquery.socialshareprivacy.min.css
1344```
1345
1346These files then contain only the JavaScript/CSS code for Twitter, Facebook and Google+.
1347`jquery.socialshareprivacy.min.de.js` and `jquery.socialshareprivacy.min.fr.js` only
1348contain translation strings, so you need to include them after `jquery.socialshareprivacy.min.js`
1349in your HTML document.
1350
1351### Usage
1352
1353 Usage:
1354 ./pack.sh [options]
1355
1356 Options:
1357 -h Print this help message.
1358 -m <modules> Comma separated list of JavaScript modules to pack. Possible values:
1359 all, all-services, none, buffer, delicious, disqus,
1360 facebook, flattr, gplus, hackernews, linkedin,
1361 localstorage, mail, pinterest, reddit, stumbleupon, tumblr,
1362 twitter, xing
1363 'all-services' includes all social share services but not the
1364 jquery.socialshareprivacy.localstorage.js module.
1365 default: all-services
1366
1367 -l <languages> Comma separated list of languages to pack. Possible values:
1368 all, none, de, fr, nl
1369 default: all
1370
1371 -c <enabled> Pack stylesheets. Possible values: on, off (default: on)
1372 -p <path> Prefix to stylesheet and dummy image paths. (empty per default)
1373 -s <path> Stylesheet path in the generated JavaScript file.
1374 default: stylesheets/jquery.socialshareprivacy.min.css
1375 -o <directory> Output directory. (default: build)
1376
1377<span id="known-issues">Known Issues</span>
1378-------------------------------------------
1379
1380In Internet Explorer <= 8 the Disqus widget doesn't work the first time you enable it.
1381You have to disable and then enable it again. I could not figure out what might cause
1382this.
1383
1384It is recommended to declare a compatibility mode of Internet Explorer >= 9. E.g. add
1385this to the head of your HTML documents:
1386
1387```html
1388<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
1389```
1390
1391Internet Explorer <= 7 is not supported.
1392
1393<span id="license">License</span>
1394---------------------------------
1395
1396Most of this plugin is licensed under the [MIT license](http://www.opensource.org/licenses/mit-license.php):
1397
1398Copyright (c) 2012 Mathias Panzenböck
1399Copyright (c) 2011 Hilko Holweg, Sebastian Hilbig, Nicolas Heiringhoff,
1400Juergen Schmidt, Heise Zeitschriften Verlag GmbH & Co. KG, http://www.heise.de
1401
1402Permission is hereby granted, free of charge, to any person obtaining a copy of
1403this software and associated documentation files (the "Software"), to deal in
1404the Software without restriction, including without limitation the rights to
1405use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
1406the Software, and to permit persons to whom the Software is furnished to do so,
1407subject to the following conditions:
1408
1409The above copyright notice and this permission notice shall be included in all
1410copies or substantial portions of the Software.
1411
1412THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1413IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
1414FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
1415COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
1416IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1417CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1418
1419The file `stylesheets/jquery.socialshareprivacy.delicious.css` is licensed under
1420the Apache License, Version 2.0:
1421
1422Copyright (c) 2012 Mathias Panzenböck
1423Copyright (c) 2010 [Mike @ moretechtips.net]
1424
1425Licensed under the Apache License, Version 2.0 (the "License");
1426you may not use this file except in compliance with the License.
1427You may obtain a copy of the License at
1428
1429> [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
1430
1431Unless required by applicable law or agreed to in writing, software
1432distributed under the License is distributed on an "AS IS" BASIS,
1433WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1434See the License for the specific language governing permissions and
1435limitations under the License.
1436