Subversion-Projekte lars-tiefland.cienc

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
8 lars 1
'use strict';
2
 
3
var $ = require('jquery');
4
var url = require('url');
5
 
6
var Shariff = function(element, options) {
7
    var self = this;
8
 
9
    // the DOM element that will contain the buttons
10
    this.element = element;
11
 
12
    // Ensure elemnt is empty
13
    $(element).empty();
14
 
15
    this.options = $.extend({}, this.defaults, options, $(element).data());
16
 
17
    // available services. /!\ Browserify can't require dynamically by now.
18
    var availableServices = [
19
        require('./services/addthis'),
20
        require('./services/diaspora'),
21
        require('./services/facebook'),
22
        require('./services/flattr'),
23
        require('./services/googleplus'),
24
        require('./services/info'),
25
        require('./services/linkedin'),
26
        require('./services/mail'),
27
        require('./services/pinterest'),
28
        require('./services/reddit'),
29
        require('./services/stumbleupon'),
30
        require('./services/twitter'),
31
        require('./services/whatsapp'),
32
        require('./services/xing'),
33
        require('./services/tumblr'),
34
        require('./services/threema')
35
    ];
36
 
37
    // filter available services to those that are enabled and initialize them
38
    this.services = $.map(this.options.services, function(serviceName) {
39
        var service;
40
        availableServices.forEach(function(availableService) {
41
            availableService = availableService(self);
42
            if (availableService.name === serviceName) {
43
                service = availableService;
44
                return null;
45
            }
46
        });
47
        return service;
48
    });
49
 
50
    this._addButtonList();
51
 
52
    if (this.options.backendUrl !== null) {
53
        this.getShares().then( $.proxy( this._updateCounts, this ) );
54
    }
55
 
56
};
57
 
58
Shariff.prototype = {
59
 
60
    // Defaults may be over either by passing "options" to constructor method
61
    // or by setting data attributes.
62
    defaults: {
63
        theme      : 'color',
64
 
65
        // URL to backend that requests social counts. null means "disabled"
66
        backendUrl : null,
67
 
68
        // Link to the "about" page
69
        infoUrl: 'http://ct.de/-2467514',
70
 
71
        // localisation: "de" or "en"
72
        lang: 'de',
73
 
74
        // fallback language for not fully localized services
75
        langFallback: 'en',
76
 
77
        mailUrl: function() {
78
            var shareUrl = url.parse(this.getURL(), true);
79
            shareUrl.query.view = 'mail';
80
            delete shareUrl.search;
81
            return url.format(shareUrl);
82
        },
83
 
84
        // if
85
        mailSubject: function() {
86
            return this.getMeta('DC.title') || this.getTitle();
87
        },
88
 
89
        mailBody: function() { return '<' + this.getURL() + '>'; },
90
 
91
        // Media (e.g. image) URL to be shared
92
        mediaUrl: null,
93
 
94
 
95
        // horizontal/vertical
96
        orientation: 'horizontal',
97
 
98
        // a string to suffix current URL
99
        referrerTrack: null,
100
 
101
        // services to be enabled in the following order
102
        services   : ['twitter', 'facebook', 'googleplus', 'info'],
103
 
104
        title: function() {
105
            return $('head title').text();
106
        },
107
 
108
        twitterVia: null,
109
 
110
        flattrUser: null,
111
 
112
        flattrCategory: null,
113
 
114
        // build URI from rel="canonical" or document.location
115
        url: function() {
116
            var url = global.document.location.href;
117
            var canonical = $('link[rel=canonical]').attr('href') || this.getMeta('og:url') || '';
118
 
119
            if (canonical.length > 0) {
120
                if (canonical.indexOf('http') < 0) {
121
                    canonical = global.document.location.protocol + '//' + global.document.location.host + canonical;
122
                }
123
                url = canonical;
124
            }
125
 
126
            return url;
127
        }
128
    },
129
 
130
    $socialshareElement: function() {
131
        return $(this.element);
132
    },
133
 
134
    getLocalized: function(data, key) {
135
        if (typeof data[key] === 'object') {
136
            if (typeof data[key][this.options.lang] === 'undefined') {
137
            	return data[key][this.options.langFallback];
138
            } else {
139
            	return data[key][this.options.lang];
140
            }
141
        } else if (typeof data[key] === 'string') {
142
            return data[key];
143
        }
144
        return undefined;
145
    },
146
 
147
    // returns content of <meta name="" content=""> tags or '' if empty/non existant
148
    getMeta: function(name) {
149
        var metaContent = $('meta[name="' + name + '"],[property="' + name + '"]').attr('content');
150
        return metaContent || '';
151
    },
152
 
153
    getInfoUrl: function() {
154
        return this.options.infoUrl;
155
    },
156
 
157
    getURL: function() {
158
        return this.getOption('url');
159
    },
160
 
161
    getOption: function(name) {
162
        var option = this.options[name];
163
        return (typeof option === 'function') ? $.proxy(option, this)() : option;
164
    },
165
 
166
    getTitle: function() {
167
        return this.getOption('title');
168
    },
169
 
170
    getReferrerTrack: function() {
171
        return this.options.referrerTrack || '';
172
    },
173
 
174
    // returns shareCounts of document
175
    getShares: function() {
176
        var baseUrl = url.parse(this.options.backendUrl, true);
177
        baseUrl.query.url = this.getURL();
178
        delete baseUrl.search;
179
        return $.getJSON(url.format(baseUrl));
180
    },
181
 
182
    // add value of shares for each service
183
    _updateCounts: function(data) {
184
        var self = this;
185
        $.each(data, function(key, value) {
186
            if(value >= 1000) {
187
                value = Math.round(value / 1000) + 'k';
188
            }
189
            $(self.element).find('.' + key + ' a').append('<span class="share_count">' + value);
190
        });
191
    },
192
 
193
    // add html for button-container
194
    _addButtonList: function() {
195
        var self = this;
196
 
197
        var $socialshareElement = this.$socialshareElement();
198
 
199
        var themeClass = 'theme-' + this.options.theme;
200
        var orientationClass = 'orientation-' + this.options.orientation;
201
        var serviceCountClass = 'col-' + this.options.services.length;
202
 
203
        var $buttonList = $('<ul>').addClass(themeClass).addClass(orientationClass).addClass(serviceCountClass);
204
 
205
        // add html for service-links
206
        this.services.forEach(function(service) {
207
            var $li = $('<li class="shariff-button">').addClass(service.name);
208
            var $shareText = '<span class="share_text">' + self.getLocalized(service, 'shareText');
209
 
210
            var $shareLink = $('<a>')
211
              .attr('href', service.shareUrl)
212
              .append($shareText);
213
 
214
            if (typeof service.faName !== 'undefined') {
215
                $shareLink.prepend('<span class="fa ' +  service.faName + '">');
216
            }
217
 
218
            if (service.popup) {
219
                $shareLink.attr('data-rel', 'popup');
220
            } else if (service.blank) {
221
                $shareLink.attr('target', '_blank');
222
            }
223
            $shareLink.attr('title', self.getLocalized(service, 'title'));
224
 
225
            // add attributes for screen readers
226
            $shareLink.attr('role', 'button');
227
            $shareLink.attr('aria-label', self.getLocalized(service, 'title'));
228
 
229
            $li.append($shareLink);
230
 
231
            $buttonList.append($li);
232
        });
233
 
234
        // event delegation
235
        $buttonList.on('click', '[data-rel="popup"]', function(e) {
236
            e.preventDefault();
237
 
238
            var url = $(this).attr('href');
239
            var windowName = '_blank';
240
            var windowSizeX = '600';
241
            var windowSizeY = '460';
242
            var windowSize = 'width=' + windowSizeX + ',height=' + windowSizeY;
243
 
244
            global.window.open(url, windowName, windowSize);
245
 
246
        });
247
 
248
        $socialshareElement.append($buttonList);
249
    }
250
};
251
 
252
module.exports = Shariff;
253
 
254
// export Shariff class to global (for non-Node users)
255
global.Shariff = Shariff;
256
 
257
// initialize .shariff elements
258
$('.shariff').each(function() {
259
    if (!this.hasOwnProperty('shariff')) {
260
        this.shariff = new Shariff(this);
261
    }
262
});