├── .eslintignore
├── .eslintrc.json
├── .gitignore
├── README.md
├── analytics.js
├── async-test.html
├── bower.json
├── count.js
├── dist
├── openshare.js
├── openshare.min.js
└── test.js
├── lib
├── countReduce.js
├── dashToCamel.js
├── init.js
├── initializeCountNode.js
├── initializeNodes.js
├── initializeShareNode.js
├── initializeWatcher.js
├── setData.js
├── share.js
└── storeCount.js
├── package.json
├── share.js
├── src
├── browser.js
├── index.js
├── modules
│ ├── count-api.js
│ ├── count-transforms.js
│ ├── count.js
│ ├── data-attr.js
│ ├── events.js
│ ├── open-share.js
│ ├── share-api.js
│ └── share-transforms.js
└── test.js
└── test.html
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist
2 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "airbnb",
3 | "rules": {
4 | "new-cap": [0, { "capIsNew": true }],
5 | "max-len": [2, 200],
6 | "no-plusplus": 0,
7 | "no-mixed-operators": 0,
8 | "no-alert": 0,
9 | "no-restricted-syntax": 0,
10 | "no-param-reassign": 0,
11 | "no-new": 0,
12 | "no-console": 0,
13 | "global-require": 0,
14 | "one-var": 0,
15 | "consistent-return": 0,
16 | "no-underscore-dangle": 0,
17 | "no-use-before-define": 0,
18 | "no-shadow": 0
19 | },
20 | "env": {
21 | "browser": true,
22 | "node": true
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .jscsrc
3 | .jshintrc
4 | .vhost
5 | .sass-cache
6 | npm-debug.log
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OpenShare
2 |
3 | OpenShare provides straightforward, declarative, and completely customizable API wrappers for sharing and counting on major social networks and platforms. Zero styling, maximum flexibility. But, unlike other social sharing tools, we don't retarget and profit from your users. Your data is your data — this is OpenShare.
4 |
5 | [Check out the examples](http://openshare.social/examples) to see OpenShare in action or [dive right into the documentation](https://github.com/dsurgeons/OpenShare/wiki).
6 |
7 | * [Getting Started](https://github.com/dsurgeons/OpenShare/wiki/1.-Getting-Started)
8 | * [Data Attribute API](https://github.com/dsurgeons/OpenShare/wiki/2.-Data-Attribute-API)
9 | * [JavaScript API](https://github.com/dsurgeons/OpenShare/wiki/3.-JavaScript-API)
10 | * [Automated Analytics Integrations](https://github.com/dsurgeons/OpenShare/wiki/4.-Automated-Analytics-Integrations)
11 | * [Contributing](https://github.com/dsurgeons/OpenShare/wiki/5.-Contributing)
12 | * [Examples](http://openshare.social/examples)
13 |
14 |
15 | ---
16 | **Quick Start**
17 |
18 | ```
19 | $ npm install openshare --save
20 | ```
21 |
22 | ```html
23 |
27 | Share
28 |
29 |
31 |
32 | ```
33 |
34 | ---
35 | **MIT License (MIT)**
36 |
37 | Copyright (c) 2015 Digital Surgeons
38 |
39 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
40 |
41 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
42 |
43 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
44 |
--------------------------------------------------------------------------------
/analytics.js:
--------------------------------------------------------------------------------
1 | export default function (type, cb) {// eslint-disable-line
2 | const isGA = type === 'event' || type === 'social';
3 | const isTagManager = type === 'tagManager';
4 |
5 | if (isGA) checkIfAnalyticsLoaded(type, cb);
6 | if (isTagManager) setTagManager(cb);
7 | }
8 |
9 | function checkIfAnalyticsLoaded(type, cb) {
10 | if (window.ga) {
11 | if (cb) cb();
12 | // bind to shared event on each individual node
13 | listen((e) => {
14 | const platform = e.target.getAttribute('data-open-share');
15 | const target = e.target.getAttribute('data-open-share-link') ||
16 | e.target.getAttribute('data-open-share-url') ||
17 | e.target.getAttribute('data-open-share-username') ||
18 | e.target.getAttribute('data-open-share-center') ||
19 | e.target.getAttribute('data-open-share-search') ||
20 | e.target.getAttribute('data-open-share-body');
21 |
22 | if (type === 'event') {
23 | ga('send', 'event', { // eslint-disable-line no-undef
24 | eventCategory: 'OpenShare Click',
25 | eventAction: platform,
26 | eventLabel: target,
27 | transport: 'beacon',
28 | });
29 | }
30 |
31 | if (type === 'social') {
32 | ga('send', { // eslint-disable-line no-undef
33 | hitType: 'social',
34 | socialNetwork: platform,
35 | socialAction: 'share',
36 | socialTarget: target,
37 | });
38 | }
39 | });
40 | } else {
41 | setTimeout(() => {
42 | checkIfAnalyticsLoaded(type, cb);
43 | }, 1000);
44 | }
45 | }
46 |
47 | function setTagManager(cb) {
48 | if (window.dataLayer && window.dataLayer[0]['gtm.start']) {
49 | if (cb) cb();
50 |
51 | listen(onShareTagManger);
52 |
53 | getCounts((e) => {
54 | const count = e.target ?
55 | e.target.innerHTML :
56 | e.innerHTML;
57 |
58 | const platform = e.target ?
59 | e.target.getAttribute('data-open-share-count-url') :
60 | e.getAttribute('data-open-share-count-url');
61 |
62 | window.dataLayer.push({
63 | event: 'OpenShare Count',
64 | platform,
65 | resource: count,
66 | activity: 'count',
67 | });
68 | });
69 | } else {
70 | setTimeout(() => {
71 | setTagManager(cb);
72 | }, 1000);
73 | }
74 | }
75 |
76 | function listen(cb) {
77 | // bind to shared event on each individual node
78 | [].forEach.call(document.querySelectorAll('[data-open-share]'), (node) => {
79 | node.addEventListener('OpenShare.shared', cb);
80 | });
81 | }
82 |
83 | function getCounts(cb) {
84 | const countNode = document.querySelectorAll('[data-open-share-count]');
85 |
86 | [].forEach.call(countNode, (node) => {
87 | if (node.textContent) cb(node);
88 | else node.addEventListener(`OpenShare.counted-${node.getAttribute('data-open-share-count-url')}`, cb);
89 | });
90 | }
91 |
92 | function onShareTagManger(e) {
93 | const platform = e.target.getAttribute('data-open-share');
94 | const target = e.target.getAttribute('data-open-share-link') ||
95 | e.target.getAttribute('data-open-share-url') ||
96 | e.target.getAttribute('data-open-share-username') ||
97 | e.target.getAttribute('data-open-share-center') ||
98 | e.target.getAttribute('data-open-share-search') ||
99 | e.target.getAttribute('data-open-share-body');
100 |
101 | window.dataLayer.push({
102 | event: 'OpenShare Share',
103 | platform,
104 | resource: target,
105 | activity: 'share',
106 | });
107 | }
108 |
--------------------------------------------------------------------------------
/async-test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Open Share
9 |
10 |
11 |
12 |
13 |
14 |
15 |
168 |
169 |
170 |
171 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "open-share",
3 | "version": "0.8.1",
4 | "authors": [
5 | "Digital Surgeons",
6 | "Adam Chambers"
7 | ],
8 | "main": "dist/open-share.js",
9 | "license": "MIT"
10 | }
11 |
--------------------------------------------------------------------------------
/count.js:
--------------------------------------------------------------------------------
1 | import Init from './lib/init';
2 | import cb from './lib/initializeCountNode';
3 |
4 | function init() {
5 | Init({
6 | api: 'count',
7 | selector: '[data-open-share-count]:not([data-open-share-node])',
8 | cb,
9 | })();
10 | }
11 | export default () => {
12 | if (document.readyState === 'complete') {
13 | init();
14 | }
15 | document.addEventListener('readystatechange', () => {
16 | if (document.readyState === 'complete') {
17 | init();
18 | }
19 | }, false);
20 | return require('./src/modules/count-api')();
21 | };
22 |
--------------------------------------------------------------------------------
/dist/openshare.js:
--------------------------------------------------------------------------------
1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o -1) {
150 | var providers = provider.split(',');
151 | providers.forEach(function (p) {
152 | return analytics(p);
153 | });
154 | } else analytics(provider);
155 | }
156 | }
157 |
158 | function initializeWatcher(watcher, fn) {
159 | [].forEach.call(watcher, function (w) {
160 | var observer = new MutationObserver(function (mutations) {
161 | // target will match between all mutations so just use first
162 | fn(mutations[0].target);
163 | });
164 |
165 | observer.observe(w, {
166 | childList: true
167 | });
168 | });
169 | }
170 |
171 | function init$1(opts) {
172 | return function () {
173 | var initNodes = initializeNodes({
174 | api: opts.api || null,
175 | container: opts.container || document,
176 | selector: opts.selector,
177 | cb: opts.cb
178 | });
179 |
180 | initNodes();
181 |
182 | // check for mutation observers before using, IE11 only
183 | if (window.MutationObserver !== undefined) {
184 | initializeWatcher(document.querySelectorAll('[data-open-share-watch]'), initNodes);
185 | }
186 | };
187 | }
188 |
189 | /**
190 | * Object of transform functions for each openshare api
191 | * Transform functions passed into OpenShare instance when instantiated
192 | * Return object containing URL and key/value args
193 | */
194 | var ShareTransforms = {
195 |
196 | // set Twitter share URL
197 | twitter: function twitter(data) {
198 | var ios = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
199 |
200 | // if iOS user and ios data attribute defined
201 | // build iOS URL scheme as single string
202 | if (ios && data.ios) {
203 | var message = '';
204 |
205 | if (data.text) {
206 | message += data.text;
207 | }
208 |
209 | if (data.url) {
210 | message += ' - ' + data.url;
211 | }
212 |
213 | if (data.hashtags) {
214 | var tags = data.hashtags.split(',');
215 | tags.forEach(function (tag) {
216 | message += ' #' + tag;
217 | });
218 | }
219 |
220 | if (data.via) {
221 | message += ' via ' + data.via;
222 | }
223 |
224 | return {
225 | url: 'twitter://post?',
226 | data: {
227 | message: message
228 | }
229 | };
230 | }
231 |
232 | return {
233 | url: 'https://twitter.com/share?',
234 | data: data,
235 | popup: {
236 | width: 700,
237 | height: 296
238 | }
239 | };
240 | },
241 |
242 |
243 | // set Twitter retweet URL
244 | twitterRetweet: function twitterRetweet(data) {
245 | var ios = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
246 |
247 | // if iOS user and ios data attribute defined
248 | if (ios && data.ios) {
249 | return {
250 | url: 'twitter://status?',
251 | data: {
252 | id: data.tweetId
253 | }
254 | };
255 | }
256 |
257 | return {
258 | url: 'https://twitter.com/intent/retweet?',
259 | data: {
260 | tweet_id: data.tweetId,
261 | related: data.related
262 | },
263 | popup: {
264 | width: 700,
265 | height: 296
266 | }
267 | };
268 | },
269 |
270 |
271 | // set Twitter like URL
272 | twitterLike: function twitterLike(data) {
273 | var ios = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
274 |
275 | // if iOS user and ios data attribute defined
276 | if (ios && data.ios) {
277 | return {
278 | url: 'twitter://status?',
279 | data: {
280 | id: data.tweetId
281 | }
282 | };
283 | }
284 |
285 | return {
286 | url: 'https://twitter.com/intent/favorite?',
287 | data: {
288 | tweet_id: data.tweetId,
289 | related: data.related
290 | },
291 | popup: {
292 | width: 700,
293 | height: 296
294 | }
295 | };
296 | },
297 |
298 |
299 | // set Twitter follow URL
300 | twitterFollow: function twitterFollow(data) {
301 | var ios = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
302 |
303 | // if iOS user and ios data attribute defined
304 | if (ios && data.ios) {
305 | var iosData = data.screenName ? {
306 | screen_name: data.screenName
307 | } : {
308 | id: data.userId
309 | };
310 |
311 | return {
312 | url: 'twitter://user?',
313 | data: iosData
314 | };
315 | }
316 |
317 | return {
318 | url: 'https://twitter.com/intent/user?',
319 | data: {
320 | screen_name: data.screenName,
321 | user_id: data.userId
322 | },
323 | popup: {
324 | width: 700,
325 | height: 296
326 | }
327 | };
328 | },
329 |
330 |
331 | // set Facebook share URL
332 | facebook: function facebook(data) {
333 | return {
334 | url: 'https://www.facebook.com/dialog/feed?app_id=961342543922322&redirect_uri=http://facebook.com&',
335 | data: data,
336 | popup: {
337 | width: 560,
338 | height: 593
339 | }
340 | };
341 | },
342 |
343 |
344 | // set Facebook send URL
345 | facebookSend: function facebookSend(data) {
346 | return {
347 | url: 'https://www.facebook.com/dialog/send?app_id=961342543922322&redirect_uri=http://facebook.com&',
348 | data: data,
349 | popup: {
350 | width: 980,
351 | height: 596
352 | }
353 | };
354 | },
355 |
356 |
357 | // set YouTube play URL
358 | youtube: function youtube(data) {
359 | var ios = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
360 |
361 | // if iOS user
362 | if (ios && data.ios) {
363 | return {
364 | url: 'youtube:' + data.video + '?'
365 | };
366 | }
367 |
368 | return {
369 | url: 'https://www.youtube.com/watch?v=' + data.video + '?',
370 | popup: {
371 | width: 1086,
372 | height: 608
373 | }
374 | };
375 | },
376 |
377 |
378 | // set YouTube subcribe URL
379 | youtubeSubscribe: function youtubeSubscribe(data) {
380 | var ios = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
381 |
382 | // if iOS user
383 | if (ios && data.ios) {
384 | return {
385 | url: 'youtube://www.youtube.com/user/' + data.user + '?'
386 | };
387 | }
388 |
389 | return {
390 | url: 'https://www.youtube.com/user/' + data.user + '?',
391 | popup: {
392 | width: 880,
393 | height: 350
394 | }
395 | };
396 | },
397 |
398 |
399 | // set Instagram follow URL
400 | instagram: function instagram() {
401 | return {
402 | url: 'instagram://camera?'
403 | };
404 | },
405 |
406 |
407 | // set Instagram follow URL
408 | instagramFollow: function instagramFollow(data) {
409 | var ios = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
410 |
411 | // if iOS user
412 | if (ios && data.ios) {
413 | return {
414 | url: 'instagram://user?',
415 | data: data
416 | };
417 | }
418 |
419 | return {
420 | url: 'http://www.instagram.com/' + data.username + '?',
421 | popup: {
422 | width: 980,
423 | height: 655
424 | }
425 | };
426 | },
427 |
428 |
429 | // set Snapchat follow URL
430 | snapchat: function snapchat(data) {
431 | return {
432 | url: 'snapchat://add/' + data.username + '?'
433 | };
434 | },
435 |
436 |
437 | // set Google share URL
438 | google: function google(data) {
439 | return {
440 | url: 'https://plus.google.com/share?',
441 | data: data,
442 | popup: {
443 | width: 495,
444 | height: 815
445 | }
446 | };
447 | },
448 |
449 |
450 | // set Google maps URL
451 | googleMaps: function googleMaps(data) {
452 | var ios = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
453 |
454 | if (data.search) {
455 | data.q = data.search;
456 | delete data.search;
457 | }
458 |
459 | // if iOS user and ios data attribute defined
460 | if (ios && data.ios) {
461 | return {
462 | url: 'comgooglemaps://?',
463 | data: ios
464 | };
465 | }
466 |
467 | if (!ios && data.ios) {
468 | delete data.ios;
469 | }
470 |
471 | return {
472 | url: 'https://maps.google.com/?',
473 | data: data,
474 | popup: {
475 | width: 800,
476 | height: 600
477 | }
478 | };
479 | },
480 |
481 |
482 | // set Pinterest share URL
483 | pinterest: function pinterest(data) {
484 | return {
485 | url: 'https://pinterest.com/pin/create/bookmarklet/?',
486 | data: data,
487 | popup: {
488 | width: 745,
489 | height: 620
490 | }
491 | };
492 | },
493 |
494 |
495 | // set LinkedIn share URL
496 | linkedin: function linkedin(data) {
497 | return {
498 | url: 'http://www.linkedin.com/shareArticle?',
499 | data: data,
500 | popup: {
501 | width: 780,
502 | height: 492
503 | }
504 | };
505 | },
506 |
507 |
508 | // set Buffer share URL
509 | buffer: function buffer(data) {
510 | return {
511 | url: 'http://bufferapp.com/add?',
512 | data: data,
513 | popup: {
514 | width: 745,
515 | height: 345
516 | }
517 | };
518 | },
519 |
520 |
521 | // set Tumblr share URL
522 | tumblr: function tumblr(data) {
523 | return {
524 | url: 'https://www.tumblr.com/widgets/share/tool?',
525 | data: data,
526 | popup: {
527 | width: 540,
528 | height: 940
529 | }
530 | };
531 | },
532 |
533 |
534 | // set Reddit share URL
535 | reddit: function reddit(data) {
536 | return {
537 | url: 'http://reddit.com/submit?',
538 | data: data,
539 | popup: {
540 | width: 860,
541 | height: 880
542 | }
543 | };
544 | },
545 |
546 |
547 | // set Flickr follow URL
548 | flickr: function flickr(data) {
549 | var ios = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
550 |
551 | // if iOS user
552 | if (ios && data.ios) {
553 | return {
554 | url: 'flickr://photos/' + data.username + '?'
555 | };
556 | }
557 | return {
558 | url: 'http://www.flickr.com/photos/' + data.username + '?',
559 | popup: {
560 | width: 600,
561 | height: 650
562 | }
563 | };
564 | },
565 |
566 |
567 | // set WhatsApp share URL
568 | whatsapp: function whatsapp(data) {
569 | return {
570 | url: 'whatsapp://send?',
571 | data: data
572 | };
573 | },
574 |
575 |
576 | // set sms share URL
577 | sms: function sms(data) {
578 | var ios = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
579 |
580 | return {
581 | url: ios ? 'sms:&' : 'sms:?',
582 | data: data
583 | };
584 | },
585 |
586 |
587 | // set Email share URL
588 | email: function email(data) {
589 | var url = 'mailto:';
590 |
591 | // if to address specified then add to URL
592 | if (data.to !== null) {
593 | url += '' + data.to;
594 | }
595 |
596 | url += '?';
597 |
598 | return {
599 | url: url,
600 | data: {
601 | subject: data.subject,
602 | body: data.body
603 | }
604 | };
605 | },
606 |
607 |
608 | // set Github fork URL
609 | github: function github(data) {
610 | var ios = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
611 | // eslint-disable-line no-unused-vars
612 | var url = data.repo ? 'https://github.com/' + data.repo : data.url;
613 |
614 | if (data.issue) {
615 | url += '/issues/new?title=' + data.issue + '&body=' + data.body;
616 | }
617 |
618 | return {
619 | url: url + '?',
620 | popup: {
621 | width: 1020,
622 | height: 323
623 | }
624 | };
625 | },
626 |
627 |
628 | // set Dribbble share URL
629 | dribbble: function dribbble(data) {
630 | var ios = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
631 | // eslint-disable-line no-unused-vars
632 | var url = data.shot ? 'https://dribbble.com/shots/' + data.shot + '?' : data.url + '?';
633 | return {
634 | url: url,
635 | popup: {
636 | width: 440,
637 | height: 640
638 | }
639 | };
640 | },
641 | codepen: function codepen(data) {
642 | var url = data.pen && data.username && data.view ? 'https://codepen.io/' + data.username + '/' + data.view + '/' + data.pen + '?' : data.url + '?';
643 | return {
644 | url: url,
645 | popup: {
646 | width: 1200,
647 | height: 800
648 | }
649 | };
650 | },
651 | paypal: function paypal(data) {
652 | return {
653 | data: data
654 | };
655 | }
656 | };
657 |
658 | /**
659 | * OpenShare generates a single share link
660 | */
661 |
662 | var OpenShare = function () {
663 | function OpenShare(type, transform) {
664 | _classCallCheck(this, OpenShare);
665 |
666 | this.ios = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
667 | this.type = type;
668 | this.dynamic = false;
669 | this.transform = transform;
670 |
671 | // capitalized type
672 | this.typeCaps = type.charAt(0).toUpperCase() + type.slice(1);
673 | }
674 |
675 | // returns function named as type set in constructor
676 | // e.g twitter()
677 |
678 |
679 | _createClass(OpenShare, [{
680 | key: 'setData',
681 | value: function setData(data) {
682 | // if iOS user and ios data attribute defined
683 | // build iOS URL scheme as single string
684 | if (this.ios) {
685 | this.transformData = this.transform(data, true);
686 | this.mobileShareUrl = this.template(this.transformData.url, this.transformData.data);
687 | }
688 |
689 | this.transformData = this.transform(data);
690 | this.shareUrl = this.template(this.transformData.url, this.transformData.data);
691 | }
692 |
693 | // open share URL defined in individual platform functions
694 |
695 | }, {
696 | key: 'share',
697 | value: function share() {
698 | var _this = this;
699 |
700 | // if iOS share URL has been set then use timeout hack
701 | // test for native app and fall back to web
702 | if (this.mobileShareUrl) {
703 | (function () {
704 | var start = new Date().valueOf();
705 |
706 | setTimeout(function () {
707 | var end = new Date().valueOf();
708 |
709 | // if the user is still here, fall back to web
710 | if (end - start > 1600) {
711 | return;
712 | }
713 |
714 | window.location = _this.shareUrl;
715 | }, 1500);
716 |
717 | window.location = _this.mobileShareUrl;
718 |
719 | // open mailto links in same window
720 | })();
721 | } else if (this.type === 'email') {
722 | window.location = this.shareUrl;
723 |
724 | // open social share URLs in new window
725 | } else {
726 | // if popup object present then set window dimensions / position
727 | if (this.popup && this.transformData.popup) {
728 | return this.openWindow(this.shareUrl, this.transformData.popup);
729 | }
730 |
731 | window.open(this.shareUrl);
732 | }
733 | }
734 |
735 | // create share URL with GET params
736 | // appending valid properties to query string
737 |
738 | }, {
739 | key: 'template',
740 | value: function template(url, data) {
741 | //eslint-disable-line
742 | var nonURLProps = ['appendTo', 'innerHTML', 'classes'];
743 |
744 | var shareUrl = url,
745 | i = void 0;
746 |
747 | for (i in data) {
748 | // only append valid properties
749 | if (!data[i] || nonURLProps.indexOf(i) > -1) {
750 | continue; //eslint-disable-line
751 | }
752 |
753 | // append URL encoded GET param to share URL
754 | data[i] = encodeURIComponent(data[i]);
755 | shareUrl += i + '=' + data[i] + '&';
756 | }
757 |
758 | return shareUrl.substr(0, shareUrl.length - 1);
759 | }
760 |
761 | // center popup window supporting dual screens
762 |
763 | }, {
764 | key: 'openWindow',
765 | value: function openWindow(url, options) {
766 | //eslint-disable-line
767 | var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left,
768 | dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top,
769 | width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width,
770 | //eslint-disable-line
771 | height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height,
772 | //eslint-disable-line
773 | left = width / 2 - options.width / 2 + dualScreenLeft,
774 | top = height / 2 - options.height / 2 + dualScreenTop,
775 | newWindow = window.open(url, 'OpenShare', 'width=' + options.width + ', height=' + options.height + ', top=' + top + ', left=' + left);
776 |
777 | // Puts focus on the newWindow
778 | if (window.focus) {
779 | newWindow.focus();
780 | }
781 | }
782 | }]);
783 |
784 | return OpenShare;
785 | }();
786 |
787 | function setData(osInstance, osElement) {
788 | osInstance.setData({
789 | url: osElement.getAttribute('data-open-share-url'),
790 | text: osElement.getAttribute('data-open-share-text'),
791 | via: osElement.getAttribute('data-open-share-via'),
792 | hashtags: osElement.getAttribute('data-open-share-hashtags'),
793 | tweetId: osElement.getAttribute('data-open-share-tweet-id'),
794 | related: osElement.getAttribute('data-open-share-related'),
795 | screenName: osElement.getAttribute('data-open-share-screen-name'),
796 | userId: osElement.getAttribute('data-open-share-user-id'),
797 | link: osElement.getAttribute('data-open-share-link'),
798 | picture: osElement.getAttribute('data-open-share-picture'),
799 | caption: osElement.getAttribute('data-open-share-caption'),
800 | description: osElement.getAttribute('data-open-share-description'),
801 | user: osElement.getAttribute('data-open-share-user'),
802 | video: osElement.getAttribute('data-open-share-video'),
803 | username: osElement.getAttribute('data-open-share-username'),
804 | title: osElement.getAttribute('data-open-share-title'),
805 | media: osElement.getAttribute('data-open-share-media'),
806 | to: osElement.getAttribute('data-open-share-to'),
807 | subject: osElement.getAttribute('data-open-share-subject'),
808 | body: osElement.getAttribute('data-open-share-body'),
809 | ios: osElement.getAttribute('data-open-share-ios'),
810 | type: osElement.getAttribute('data-open-share-type'),
811 | center: osElement.getAttribute('data-open-share-center'),
812 | views: osElement.getAttribute('data-open-share-views'),
813 | zoom: osElement.getAttribute('data-open-share-zoom'),
814 | search: osElement.getAttribute('data-open-share-search'),
815 | saddr: osElement.getAttribute('data-open-share-saddr'),
816 | daddr: osElement.getAttribute('data-open-share-daddr'),
817 | directionsmode: osElement.getAttribute('data-open-share-directions-mode'),
818 | repo: osElement.getAttribute('data-open-share-repo'),
819 | shot: osElement.getAttribute('data-open-share-shot'),
820 | pen: osElement.getAttribute('data-open-share-pen'),
821 | view: osElement.getAttribute('data-open-share-view'),
822 | issue: osElement.getAttribute('data-open-share-issue'),
823 | buttonId: osElement.getAttribute('data-open-share-buttonId'),
824 | popUp: osElement.getAttribute('data-open-share-popup'),
825 | key: osElement.getAttribute('data-open-share-key')
826 | });
827 | }
828 |
829 | function share(e, os, openShare) {
830 | // if dynamic instance then fetch attributes again in case of updates
831 | if (openShare.dynamic) {
832 | setData(openShare, os);
833 | }
834 |
835 | openShare.share(e);
836 |
837 | // trigger shared event
838 | Events.trigger(os, 'shared');
839 | }
840 |
841 | // type contains a dash
842 | // transform to camelcase for function reference
843 | // TODO: only supports single dash, should should support multiple
844 | var dashToCamel = function dashToCamel(dash, type) {
845 | var nextChar = type.substr(dash + 1, 1);
846 | var group = type.substr(dash, 2);
847 |
848 | type = type.replace(group, nextChar.toUpperCase());
849 | return type;
850 | };
851 |
852 | function initializeShareNode(os) {
853 | // initialize open share object with type attribute
854 | var type = os.getAttribute('data-open-share');
855 | var dash = type.indexOf('-');
856 |
857 | if (dash > -1) {
858 | type = dashToCamel(dash, type);
859 | }
860 |
861 | var transform = ShareTransforms[type];
862 |
863 | if (!transform) {
864 | throw new Error('Open Share: ' + type + ' is an invalid type');
865 | }
866 |
867 | var openShare = new OpenShare(type, transform);
868 |
869 | // specify if this is a dynamic instance
870 | if (os.getAttribute('data-open-share-dynamic')) {
871 | openShare.dynamic = true;
872 | }
873 |
874 | // specify if this is a popup instance
875 | if (os.getAttribute('data-open-share-popup')) {
876 | openShare.popup = true;
877 | }
878 |
879 | // set all optional attributes on open share instance
880 | setData(openShare, os);
881 |
882 | // open share dialog on click
883 | os.addEventListener('click', function (e) {
884 | share(e, os, openShare);
885 | });
886 |
887 | os.addEventListener('OpenShare.trigger', function (e) {
888 | share(e, os, openShare);
889 | });
890 |
891 | os.setAttribute('data-open-share-node', type);
892 | }
893 |
894 | function round(x, precision) {
895 | if (typeof x !== 'number') {
896 | throw new TypeError('Expected value to be a number');
897 | }
898 |
899 | var exponent = precision > 0 ? 'e' : 'e-';
900 | var exponentNeg = precision > 0 ? 'e-' : 'e';
901 | precision = Math.abs(precision);
902 |
903 | return Number(Math.round(x + exponent + precision) + exponentNeg + precision);
904 | }
905 |
906 | function thousandify(num) {
907 | return round(num / 1000, 1) + 'K';
908 | }
909 |
910 | function millionify(num) {
911 | return round(num / 1000000, 1) + 'M';
912 | }
913 |
914 | function countReduce(el, count, cb) {
915 | if (count > 999999) {
916 | el.innerHTML = millionify(count);
917 | if (cb && typeof cb === 'function') cb(el);
918 | } else if (count > 999) {
919 | el.innerHTML = thousandify(count);
920 | if (cb && typeof cb === 'function') cb(el);
921 | } else {
922 | el.innerHTML = count;
923 | if (cb && typeof cb === 'function') cb(el);
924 | }
925 | }
926 |
927 | /*
928 | Sometimes social platforms get confused and drop share counts.
929 | In this module we check if the returned count is less than the count in
930 | localstorage.
931 | If the local count is greater than the returned count,
932 | we store the local count + the returned count.
933 | Otherwise, store the returned count.
934 | */
935 |
936 | var storeCount = function storeCount(t, count) {
937 | var isArr = t.type.indexOf(',') > -1;
938 | var local = Number(t.storeGet(t.type + '-' + t.shared));
939 |
940 | if (local > count && !isArr) {
941 | var latestCount = Number(t.storeGet(t.type + '-' + t.shared + '-latestCount'));
942 | t.storeSet(t.type + '-' + t.shared + '-latestCount', count);
943 |
944 | count = isNumeric$1(latestCount) && latestCount > 0 ? count += local - latestCount : count += local;
945 | }
946 |
947 | if (!isArr) t.storeSet(t.type + '-' + t.shared, count);
948 | return count;
949 | };
950 |
951 | function isNumeric$1(n) {
952 | return !isNaN(parseFloat(n)) && isFinite(n);
953 | }
954 |
955 | /**
956 | * Object of transform functions for each openshare api
957 | * Transform functions passed into OpenShare instance when instantiated
958 | * Return object containing URL and key/value args
959 | */
960 | var CountTransforms = {
961 |
962 | // facebook count data
963 | facebook: function facebook(url) {
964 | return {
965 | type: 'get',
966 | url: 'https://graph.facebook.com/?id=' + url,
967 | transform: function transform(xhr) {
968 | var fb = JSON.parse(xhr.responseText);
969 |
970 | var count = fb.share && fb.share.share_count || 0;
971 |
972 | return storeCount(this, count);
973 | }
974 | };
975 | },
976 |
977 |
978 | // pinterest count data
979 | pinterest: function pinterest(url) {
980 | return {
981 | type: 'jsonp',
982 | url: 'https://api.pinterest.com/v1/urls/count.json?callback=?&url=' + url,
983 | transform: function transform(data) {
984 | var count = data.count || 0;
985 | return storeCount(this, count);
986 | }
987 | };
988 | },
989 |
990 |
991 | // linkedin count data
992 | linkedin: function linkedin(url) {
993 | return {
994 | type: 'jsonp',
995 | url: 'https://www.linkedin.com/countserv/count/share?url=' + url + '&format=jsonp&callback=?',
996 | transform: function transform(data) {
997 | var count = data.count || 0;
998 | return storeCount(this, count);
999 | }
1000 | };
1001 | },
1002 |
1003 |
1004 | // reddit count data
1005 | reddit: function reddit(url) {
1006 | return {
1007 | type: 'get',
1008 | url: 'https://www.reddit.com/api/info.json?url=' + url,
1009 | transform: function transform(xhr) {
1010 | var reddit = JSON.parse(xhr.responseText);
1011 | var posts = reddit.data && reddit.data.children || null;
1012 | var ups = 0;
1013 |
1014 | if (posts) {
1015 | posts.forEach(function (post) {
1016 | ups += Number(post.data.ups);
1017 | });
1018 | }
1019 |
1020 | return storeCount(this, ups);
1021 | }
1022 | };
1023 | },
1024 |
1025 |
1026 | // google count data
1027 | google: function google(url) {
1028 | return {
1029 | type: 'post',
1030 | data: {
1031 | method: 'pos.plusones.get',
1032 | id: 'p',
1033 | params: {
1034 | nolog: true,
1035 | id: url,
1036 | source: 'widget',
1037 | userId: '@viewer',
1038 | groupId: '@self'
1039 | },
1040 | jsonrpc: '2.0',
1041 | key: 'p',
1042 | apiVersion: 'v1'
1043 | },
1044 | url: 'https://clients6.google.com/rpc',
1045 | transform: function transform(xhr) {
1046 | var google = JSON.parse(xhr.responseText);
1047 | var count = google.result && google.result.metadata && google.result.metadata.globalCounts && google.result.metadata.globalCounts.count || 0;
1048 | return storeCount(this, count);
1049 | }
1050 | };
1051 | },
1052 |
1053 |
1054 | // github star count
1055 | githubStars: function githubStars(repo) {
1056 | repo = repo.indexOf('github.com/') > -1 ? repo.split('github.com/')[1] : repo;
1057 | return {
1058 | type: 'get',
1059 | url: 'https://api.github.com/repos/' + repo,
1060 | transform: function transform(xhr) {
1061 | var count = JSON.parse(xhr.responseText).stargazers_count || 0;
1062 | return storeCount(this, count);
1063 | }
1064 | };
1065 | },
1066 |
1067 |
1068 | // github forks count
1069 | githubForks: function githubForks(repo) {
1070 | repo = repo.indexOf('github.com/') > -1 ? repo.split('github.com/')[1] : repo;
1071 | return {
1072 | type: 'get',
1073 | url: 'https://api.github.com/repos/' + repo,
1074 | transform: function transform(xhr) {
1075 | var count = JSON.parse(xhr.responseText).forks_count || 0;
1076 | return storeCount(this, count);
1077 | }
1078 | };
1079 | },
1080 |
1081 |
1082 | // github watchers count
1083 | githubWatchers: function githubWatchers(repo) {
1084 | repo = repo.indexOf('github.com/') > -1 ? repo.split('github.com/')[1] : repo;
1085 | return {
1086 | type: 'get',
1087 | url: 'https://api.github.com/repos/' + repo,
1088 | transform: function transform(xhr) {
1089 | var count = JSON.parse(xhr.responseText).watchers_count || 0;
1090 | return storeCount(this, count);
1091 | }
1092 | };
1093 | },
1094 |
1095 |
1096 | // dribbble likes count
1097 | dribbble: function dribbble(shot) {
1098 | shot = shot.indexOf('dribbble.com/shots') > -1 ? shot.split('shots/')[1] : shot;
1099 | var url = 'https://api.dribbble.com/v1/shots/' + shot + '/likes';
1100 | return {
1101 | type: 'get',
1102 | url: url,
1103 | transform: function transform(xhr, Events) {
1104 | var _this2 = this;
1105 |
1106 | var count = JSON.parse(xhr.responseText).length;
1107 |
1108 | // at this time dribbble limits a response of 12 likes per page
1109 | if (count === 12) {
1110 | var page = 2;
1111 | recursiveCount(url, page, count, function (finalCount) {
1112 | if (_this2.appendTo && typeof _this2.appendTo !== 'function') {
1113 | _this2.appendTo.appendChild(_this2.os);
1114 | }
1115 | countReduce(_this2.os, finalCount, _this2.cb);
1116 | Events.trigger(_this2.os, 'counted-' + _this2.url);
1117 | return storeCount(_this2, finalCount);
1118 | });
1119 | } else {
1120 | return storeCount(this, count);
1121 | }
1122 | }
1123 | };
1124 | },
1125 | twitter: function twitter(url) {
1126 | return {
1127 | type: 'get',
1128 | url: 'https://api.openshare.social/job?url=' + url + '&key=',
1129 | transform: function transform(xhr) {
1130 | var count = JSON.parse(xhr.responseText).count || 0;
1131 | return storeCount(this, count);
1132 | }
1133 | };
1134 | }
1135 | };
1136 |
1137 | function recursiveCount(url, page, count, cb) {
1138 | var xhr = new XMLHttpRequest();
1139 | xhr.open('GET', url + '?page=' + page);
1140 | xhr.addEventListener('load', function () {
1141 | //eslint-disable-line
1142 | var likes = JSON.parse(this.response);
1143 | count += likes.length;
1144 |
1145 | // dribbble like per page is 12
1146 | if (likes.length === 12) {
1147 | page++;
1148 | recursiveCount(url, page, count, cb);
1149 | } else {
1150 | cb(count);
1151 | }
1152 | });
1153 | xhr.send();
1154 | }
1155 |
1156 | /**
1157 | * Generate share count instance from one to many networks
1158 | */
1159 |
1160 | var Count = function () {
1161 | function Count(type, url) {
1162 | var _this3 = this;
1163 |
1164 | _classCallCheck(this, Count);
1165 |
1166 | // throw error if no url provided
1167 | if (!url) {
1168 | throw new Error('Open Share: no url provided for count');
1169 | }
1170 |
1171 | // check for Github counts
1172 | if (type.indexOf('github') === 0) {
1173 | if (type === 'github-stars') {
1174 | type = 'githubStars';
1175 | } else if (type === 'github-forks') {
1176 | type = 'githubForks';
1177 | } else if (type === 'github-watchers') {
1178 | type = 'githubWatchers';
1179 | } else {
1180 | console.error('Invalid Github count type. Try github-stars, github-forks, or github-watchers.');
1181 | }
1182 | }
1183 |
1184 | // if type is comma separate list create array
1185 | if (type.indexOf(',') > -1) {
1186 | this.type = type;
1187 | this.typeArr = this.type.split(',');
1188 | this.countData = [];
1189 |
1190 | // check each type supplied is valid
1191 | this.typeArr.forEach(function (t) {
1192 | if (!CountTransforms[t]) {
1193 | throw new Error('Open Share: ' + type + ' is an invalid count type');
1194 | }
1195 |
1196 | _this3.countData.push(CountTransforms[t](url));
1197 | });
1198 |
1199 | var count = this.storeGet(this.type + '-' + this.shared);
1200 |
1201 | if (count) {
1202 | if (this.appendTo && typeof this.appendTo !== 'function') {
1203 | this.appendTo.appendChild(this.os);
1204 | }
1205 | countReduce(this.os, count);
1206 | }
1207 |
1208 | // throw error if invalid type provided
1209 | } else if (!CountTransforms[type]) {
1210 | throw new Error('Open Share: ' + type + ' is an invalid count type');
1211 |
1212 | // single count
1213 | // store count URL and transform function
1214 | } else {
1215 | this.type = type;
1216 | this.countData = CountTransforms[type](url);
1217 | }
1218 | }
1219 |
1220 | // handle calling getCount / getCounts
1221 | // depending on number of types
1222 |
1223 |
1224 | _createClass(Count, [{
1225 | key: 'count',
1226 | value: function count(os, cb, appendTo) {
1227 | this.os = os;
1228 | this.appendTo = appendTo;
1229 | this.cb = cb;
1230 | this.url = this.os.getAttribute('data-open-share-count');
1231 | this.shared = this.os.getAttribute('data-open-share-count-url');
1232 | this.key = this.os.getAttribute('data-open-share-key');
1233 |
1234 | if (!Array.isArray(this.countData)) {
1235 | this.getCount();
1236 | } else {
1237 | this.getCounts();
1238 | }
1239 | }
1240 |
1241 | // fetch count either AJAX or JSONP
1242 |
1243 | }, {
1244 | key: 'getCount',
1245 | value: function getCount() {
1246 | var count = this.storeGet(this.type + '-' + this.shared);
1247 |
1248 | if (count) {
1249 | if (this.appendTo && typeof this.appendTo !== 'function') {
1250 | this.appendTo.appendChild(this.os);
1251 | }
1252 | countReduce(this.os, count);
1253 | }
1254 | this[this.countData.type](this.countData);
1255 | }
1256 |
1257 | // fetch multiple counts and aggregate
1258 |
1259 | }, {
1260 | key: 'getCounts',
1261 | value: function getCounts() {
1262 | var _this4 = this;
1263 |
1264 | this.total = [];
1265 |
1266 | var count = this.storeGet(this.type + '-' + this.shared);
1267 |
1268 | if (count) {
1269 | if (this.appendTo && typeof this.appendTo !== 'function') {
1270 | this.appendTo.appendChild(this.os);
1271 | }
1272 | countReduce(this.os, count);
1273 | }
1274 |
1275 | this.countData.forEach(function (countData) {
1276 | _this4[countData.type](countData, function (num) {
1277 | _this4.total.push(num);
1278 |
1279 | // total counts length now equals type array length
1280 | // so aggregate, store and insert into DOM
1281 | if (_this4.total.length === _this4.typeArr.length) {
1282 | var tot = 0;
1283 |
1284 | _this4.total.forEach(function (t) {
1285 | tot += t;
1286 | });
1287 |
1288 | if (_this4.appendTo && typeof _this4.appendTo !== 'function') {
1289 | _this4.appendTo.appendChild(_this4.os);
1290 | }
1291 |
1292 | var local = Number(_this4.storeGet(_this4.type + '-' + _this4.shared));
1293 | if (local > tot) {
1294 | // const latestCount = Number(this.storeGet(`${this.type}-${this.shared}-latestCount`));
1295 | // this.storeSet(`${this.type}-${this.shared}-latestCount`, tot);
1296 | //
1297 | // tot = isNumeric(latestCount) && latestCount > 0 ?
1298 | // tot += local - latestCount :
1299 | // tot += local;
1300 | tot = local;
1301 | }
1302 | _this4.storeSet(_this4.type + '-' + _this4.shared, tot);
1303 |
1304 | countReduce(_this4.os, tot);
1305 | }
1306 | });
1307 | });
1308 |
1309 | if (this.appendTo && typeof this.appendTo !== 'function') {
1310 | this.appendTo.appendChild(this.os);
1311 | }
1312 | }
1313 |
1314 | // handle JSONP requests
1315 |
1316 | }, {
1317 | key: 'jsonp',
1318 | value: function jsonp(countData, cb) {
1319 | var _this5 = this;
1320 |
1321 | // define random callback and assign transform function
1322 | var callback = Math.random().toString(36).substring(7).replace(/[^a-zA-Z]/g, '');
1323 | window[callback] = function (data) {
1324 | var count = countData.transform.apply(_this5, [data]) || 0;
1325 |
1326 | if (cb && typeof cb === 'function') {
1327 | cb(count);
1328 | } else {
1329 | if (_this5.appendTo && typeof _this5.appendTo !== 'function') {
1330 | _this5.appendTo.appendChild(_this5.os);
1331 | }
1332 | countReduce(_this5.os, count, _this5.cb);
1333 | }
1334 |
1335 | Events.trigger(_this5.os, 'counted-' + _this5.url);
1336 | };
1337 |
1338 | // append JSONP script tag to page
1339 | var script = document.createElement('script');
1340 | script.src = countData.url.replace('callback=?', 'callback=' + callback);
1341 | document.getElementsByTagName('head')[0].appendChild(script);
1342 |
1343 | return;
1344 | }
1345 |
1346 | // handle AJAX GET request
1347 |
1348 | }, {
1349 | key: 'get',
1350 | value: function get(countData, cb) {
1351 | var _this6 = this;
1352 |
1353 | var xhr = new XMLHttpRequest();
1354 |
1355 | // on success pass response to transform function
1356 | xhr.onreadystatechange = function () {
1357 | if (xhr.readyState === 4) {
1358 | if (xhr.status === 200) {
1359 | var count = countData.transform.apply(_this6, [xhr, Events]) || 0;
1360 |
1361 | if (cb && typeof cb === 'function') {
1362 | cb(count);
1363 | } else {
1364 | if (_this6.appendTo && typeof _this6.appendTo !== 'function') {
1365 | _this6.appendTo.appendChild(_this6.os);
1366 | }
1367 | countReduce(_this6.os, count, _this6.cb);
1368 | }
1369 |
1370 | Events.trigger(_this6.os, 'counted-' + _this6.url);
1371 | return;
1372 | } else if (countData.url.toLowerCase().indexOf('https://api.openshare.social/job?') === 0) {
1373 | console.warn('Please sign up for Twitter counts at https://openshare.social/twitter/auth');
1374 | var _count = 0;
1375 |
1376 | if (cb && typeof cb === 'function') {
1377 | cb(_count);
1378 | } else {
1379 | if (_this6.appendTo && typeof _this6.appendTo !== 'function') {
1380 | _this6.appendTo.appendChild(_this6.os);
1381 | }
1382 | countReduce(_this6.os, _count, _this6.cb);
1383 | }
1384 |
1385 | Events.trigger(_this6.os, 'counted-' + _this6.url);
1386 | } else {
1387 | console.warn('Failed to get API data from', countData.url, '. Please use the latest version of OpenShare.');
1388 | var _count2 = 0;
1389 |
1390 | if (cb && typeof cb === 'function') {
1391 | cb(_count2);
1392 | } else {
1393 | if (_this6.appendTo && typeof _this6.appendTo !== 'function') {
1394 | _this6.appendTo.appendChild(_this6.os);
1395 | }
1396 | countReduce(_this6.os, _count2, _this6.cb);
1397 | }
1398 |
1399 | Events.trigger(_this6.os, 'counted-' + _this6.url);
1400 | }
1401 | }
1402 | };
1403 |
1404 | countData.url = countData.url.startsWith('https://api.openshare.social/job?') && this.key ? countData.url + this.key : countData.url;
1405 |
1406 | xhr.open('GET', countData.url);
1407 | xhr.send();
1408 | }
1409 |
1410 | // handle AJAX POST request
1411 |
1412 | }, {
1413 | key: 'post',
1414 | value: function post(countData, cb) {
1415 | var _this7 = this;
1416 |
1417 | var xhr = new XMLHttpRequest();
1418 |
1419 | // on success pass response to transform function
1420 | xhr.onreadystatechange = function () {
1421 | if (xhr.readyState !== XMLHttpRequest.DONE || xhr.status !== 200) {
1422 | return;
1423 | }
1424 |
1425 | var count = countData.transform.apply(_this7, [xhr]) || 0;
1426 |
1427 | if (cb && typeof cb === 'function') {
1428 | cb(count);
1429 | } else {
1430 | if (_this7.appendTo && typeof _this7.appendTo !== 'function') {
1431 | _this7.appendTo.appendChild(_this7.os);
1432 | }
1433 | countReduce(_this7.os, count, _this7.cb);
1434 | }
1435 | Events.trigger(_this7.os, 'counted-' + _this7.url);
1436 | };
1437 |
1438 | xhr.open('POST', countData.url);
1439 | xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
1440 | xhr.send(JSON.stringify(countData.data));
1441 | }
1442 | }, {
1443 | key: 'storeSet',
1444 | value: function storeSet(type) {
1445 | var count = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
1446 | //eslint-disable-line
1447 | if (!window.localStorage || !type) {
1448 | return;
1449 | }
1450 |
1451 | localStorage.setItem('OpenShare-' + type, count);
1452 | }
1453 | }, {
1454 | key: 'storeGet',
1455 | value: function storeGet(type) {
1456 | //eslint-disable-line
1457 | if (!window.localStorage || !type) {
1458 | return;
1459 | }
1460 |
1461 | return localStorage.getItem('OpenShare-' + type);
1462 | }
1463 | }]);
1464 |
1465 | return Count;
1466 | }();
1467 |
1468 | function initializeCountNode(os) {
1469 | // initialize open share object with type attribute
1470 | var type = os.getAttribute('data-open-share-count');
1471 | var url = os.getAttribute('data-open-share-count-repo') || os.getAttribute('data-open-share-count-shot') || os.getAttribute('data-open-share-count-url');
1472 | var count = new Count(type, url);
1473 |
1474 | count.count(os);
1475 | os.setAttribute('data-open-share-node', type);
1476 | }
1477 |
1478 | function init() {
1479 | init$1({
1480 | selector: {
1481 | share: '[data-open-share]:not([data-open-share-node])',
1482 | count: '[data-open-share-count]:not([data-open-share-node])'
1483 | },
1484 | cb: {
1485 | share: initializeShareNode,
1486 | count: initializeCountNode
1487 | }
1488 | })();
1489 | }
1490 | var DataAttr = function DataAttr() {
1491 | if (document.readyState === 'complete') {
1492 | return init();
1493 | }
1494 | document.addEventListener('readystatechange', function () {
1495 | if (document.readyState === 'complete') {
1496 | init();
1497 | }
1498 | }, false);
1499 | };
1500 |
1501 | /**
1502 | * Global OpenShare API to generate instances programmatically
1503 | */
1504 | var ShareAPI = function ShareAPI() {
1505 | // global OpenShare referencing internal class for instance generation
1506 | var OpenShare$$1 = function () {
1507 | function OpenShare$$1(data, element) {
1508 | var _this8 = this;
1509 |
1510 | _classCallCheck(this, OpenShare$$1);
1511 |
1512 | if (!data.bindClick) data.bindClick = true;
1513 |
1514 | var dash = data.type.indexOf('-');
1515 |
1516 | if (dash > -1) {
1517 | data.type = dashToCamel(dash, data.type);
1518 | }
1519 |
1520 | var node = void 0;
1521 | this.element = element;
1522 | this.data = data;
1523 |
1524 | this.os = new OpenShare(data.type, ShareTransforms[data.type]);
1525 | this.os.setData(data);
1526 |
1527 | if (!element || data.element) {
1528 | element = data.element;
1529 | node = document.createElement(element || 'a');
1530 | if (data.type) {
1531 | node.classList.add('open-share-link', data.type);
1532 | node.setAttribute('data-open-share', data.type);
1533 | node.setAttribute('data-open-share-node', data.type);
1534 | }
1535 | if (data.innerHTML) node.innerHTML = data.innerHTML;
1536 | }
1537 | if (node) element = node;
1538 |
1539 | if (data.bindClick) {
1540 | element.addEventListener('click', function () {
1541 | _this8.share();
1542 | });
1543 | }
1544 |
1545 | if (data.appendTo) {
1546 | data.appendTo.appendChild(element);
1547 | }
1548 |
1549 | if (data.classes && Array.isArray(data.classes)) {
1550 | data.classes.forEach(function (cssClass) {
1551 | element.classList.add(cssClass);
1552 | });
1553 | }
1554 |
1555 | if (data.type.toLowerCase() === 'paypal') {
1556 | var action = data.sandbox ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr';
1557 |
1558 | var buyGIF = data.sandbox ? 'https://www.sandbox.paypal.com/en_US/i/btn/btn_buynow_LG.gif' : 'https://www.paypalobjects.com/en_US/i/btn/btn_buynow_LG.gif';
1559 |
1560 | var pixelGIF = data.sandbox ? 'https://www.sandbox.paypal.com/en_US/i/scr/pixel.gif' : 'https://www.paypalobjects.com/en_US/i/scr/pixel.gif';
1561 |
1562 | var paypalButton = '';
1563 |
1564 | var hiddenDiv = document.createElement('div');
1565 | hiddenDiv.style.display = 'none';
1566 | hiddenDiv.innerHTML = paypalButton;
1567 | document.body.appendChild(hiddenDiv);
1568 |
1569 | this.paypal = hiddenDiv.querySelector('form');
1570 | }
1571 |
1572 | this.element = element;
1573 | return element;
1574 | }
1575 |
1576 | // public share method to trigger share programmatically
1577 |
1578 |
1579 | _createClass(OpenShare$$1, [{
1580 | key: 'share',
1581 | value: function share(e) {
1582 | // if dynamic instance then fetch attributes again in case of updates
1583 | if (this.data.dynamic) {
1584 | //eslint-disable-next-line
1585 | this.os.setData(data); // data is not defined
1586 | }
1587 |
1588 | if (this.data.type.toLowerCase() === 'paypal') {
1589 | this.paypal.submit();
1590 | } else this.os.share(e);
1591 |
1592 | Events.trigger(this.element, 'shared');
1593 | }
1594 | }]);
1595 |
1596 | return OpenShare$$1;
1597 | }();
1598 |
1599 | return OpenShare$$1;
1600 | };
1601 |
1602 | /**
1603 | * count API
1604 | */
1605 |
1606 | var CountAPI = function CountAPI() {
1607 | //eslint-disable-line
1608 | // global OpenShare referencing internal class for instance generation
1609 | var Count$$1 = function Count$$1(_ref, cb) {
1610 | var type = _ref.type;
1611 | var url = _ref.url;
1612 | var _ref$appendTo = _ref.appendTo;
1613 | var appendTo = _ref$appendTo === undefined ? false : _ref$appendTo;
1614 | var element = _ref.element;
1615 | var classes = _ref.classes;
1616 | var _ref$key = _ref.key;
1617 | var key = _ref$key === undefined ? null : _ref$key;
1618 |
1619 | _classCallCheck(this, Count$$1);
1620 |
1621 | var countNode = document.createElement(element || 'span');
1622 |
1623 | countNode.setAttribute('data-open-share-count', type);
1624 | countNode.setAttribute('data-open-share-count-url', url);
1625 | if (key) countNode.setAttribute('data-open-share-key', key);
1626 |
1627 | countNode.classList.add('open-share-count');
1628 |
1629 | if (classes && Array.isArray(classes)) {
1630 | classes.forEach(function (cssCLass) {
1631 | countNode.classList.add(cssCLass);
1632 | });
1633 | }
1634 |
1635 | if (appendTo) {
1636 | return new Count(type, url).count(countNode, cb, appendTo);
1637 | }
1638 |
1639 | return new Count(type, url).count(countNode, cb);
1640 | };
1641 |
1642 | return Count$$1;
1643 | };
1644 |
1645 | var browser = function browser() {
1646 | DataAttr(OpenShare, Count, ShareTransforms, Events);
1647 | window.OpenShare = {
1648 | share: ShareAPI(OpenShare, ShareTransforms, Events),
1649 | count: CountAPI(),
1650 | analytics: analytics
1651 | };
1652 | };
1653 | var browser_js = browser();
1654 |
1655 | module.exports = browser_js;
1656 |
1657 | },{}]},{},[1]);
1658 |
--------------------------------------------------------------------------------
/dist/openshare.min.js:
--------------------------------------------------------------------------------
1 | !function t(e,n,r){function a(i,s){if(!n[i]){if(!e[i]){var u="function"==typeof require&&require;if(!s&&u)return u(i,!0);if(o)return o(i,!0);var p=new Error("Cannot find module '"+i+"'");throw p.code="MODULE_NOT_FOUND",p}var h=n[i]={exports:{}};e[i][0].call(h.exports,function(t){var n=e[i][1][t];return a(n?n:t)},h,h.exports,t,e,n,r)}return n[i].exports}for(var o="function"==typeof require&&require,i=0;i-1){var e=t.split(",");e.forEach(function(t){return E(t)})}else E(t)}}function d(t,e){[].forEach.call(t,function(t){var n=new MutationObserver(function(t){e(t[0].target)});n.observe(t,{childList:!0})})}function c(t){return function(){var e=p({api:t.api||null,container:t.container||document,selector:t.selector,cb:t.cb});e(),void 0!==window.MutationObserver&&d(document.querySelectorAll("[data-open-share-watch]"),e)}}function l(t,e){t.setData({url:e.getAttribute("data-open-share-url"),text:e.getAttribute("data-open-share-text"),via:e.getAttribute("data-open-share-via"),hashtags:e.getAttribute("data-open-share-hashtags"),tweetId:e.getAttribute("data-open-share-tweet-id"),related:e.getAttribute("data-open-share-related"),screenName:e.getAttribute("data-open-share-screen-name"),userId:e.getAttribute("data-open-share-user-id"),link:e.getAttribute("data-open-share-link"),picture:e.getAttribute("data-open-share-picture"),caption:e.getAttribute("data-open-share-caption"),description:e.getAttribute("data-open-share-description"),user:e.getAttribute("data-open-share-user"),video:e.getAttribute("data-open-share-video"),username:e.getAttribute("data-open-share-username"),title:e.getAttribute("data-open-share-title"),media:e.getAttribute("data-open-share-media"),to:e.getAttribute("data-open-share-to"),subject:e.getAttribute("data-open-share-subject"),body:e.getAttribute("data-open-share-body"),ios:e.getAttribute("data-open-share-ios"),type:e.getAttribute("data-open-share-type"),center:e.getAttribute("data-open-share-center"),views:e.getAttribute("data-open-share-views"),zoom:e.getAttribute("data-open-share-zoom"),search:e.getAttribute("data-open-share-search"),saddr:e.getAttribute("data-open-share-saddr"),daddr:e.getAttribute("data-open-share-daddr"),directionsmode:e.getAttribute("data-open-share-directions-mode"),repo:e.getAttribute("data-open-share-repo"),shot:e.getAttribute("data-open-share-shot"),pen:e.getAttribute("data-open-share-pen"),view:e.getAttribute("data-open-share-view"),issue:e.getAttribute("data-open-share-issue"),buttonId:e.getAttribute("data-open-share-buttonId"),popUp:e.getAttribute("data-open-share-popup"),key:e.getAttribute("data-open-share-key")})}function f(t,e,n){n.dynamic&&l(n,e),n.share(t),O.trigger(e,"shared")}function g(t){var e=t.getAttribute("data-open-share"),n=e.indexOf("-");n>-1&&(e=C(n,e));var r=x[e];if(!r)throw new Error("Open Share: "+e+" is an invalid type");var a=new L(e,r);t.getAttribute("data-open-share-dynamic")&&(a.dynamic=!0),t.getAttribute("data-open-share-popup")&&(a.popup=!0),l(a,t),t.addEventListener("click",function(e){f(e,t,a)}),t.addEventListener("OpenShare.trigger",function(e){f(e,t,a)}),t.setAttribute("data-open-share-node",e)}function b(t,e){if("number"!=typeof t)throw new TypeError("Expected value to be a number");var n=e>0?"e":"e-",r=e>0?"e-":"e";return e=Math.abs(e),Number(Math.round(t+n+e)+r+e)}function m(t){return b(t/1e3,1)+"K"}function w(t){return b(t/1e6,1)+"M"}function v(t,e,n){e>999999?(t.innerHTML=w(e),n&&"function"==typeof n&&n(t)):e>999?(t.innerHTML=m(e),n&&"function"==typeof n&&n(t)):(t.innerHTML=e,n&&"function"==typeof n&&n(t))}function y(t){return!isNaN(parseFloat(t))&&isFinite(t)}function A(t,e,n,r){var a=new XMLHttpRequest;a.open("GET",t+"?page="+e),a.addEventListener("load",function(){var a=JSON.parse(this.response);n+=a.length,12===a.length?(e++,A(t,e,n,r)):r(n)}),a.send()}function T(t){var e=t.getAttribute("data-open-share-count"),n=t.getAttribute("data-open-share-count-repo")||t.getAttribute("data-open-share-count-shot")||t.getAttribute("data-open-share-count-url"),r=new D(e,n);r.count(t),t.setAttribute("data-open-share-node",e)}function k(){c({selector:{share:"[data-open-share]:not([data-open-share-node])",count:"[data-open-share-count]:not([data-open-share-node])"},cb:{share:g,count:T}})()}var S=function(){function t(t,e){for(var n=0;n1600||(window.location=t.shareUrl)},1500),window.location=t.mobileShareUrl}();else if("email"===this.type)window.location=this.shareUrl;else{if(this.popup&&this.transformData.popup)return this.openWindow(this.shareUrl,this.transformData.popup);window.open(this.shareUrl)}}},{key:"template",value:function(t,e){var n=["appendTo","innerHTML","classes"],r=t,a=void 0;for(a in e)!e[a]||n.indexOf(a)>-1||(e[a]=encodeURIComponent(e[a]),r+=a+"="+e[a]+"&");return r.substr(0,r.length-1)}},{key:"openWindow",value:function(t,e){var n=void 0!==window.screenLeft?window.screenLeft:screen.left,r=void 0!==window.screenTop?window.screenTop:screen.top,a=window.innerWidth?window.innerWidth:document.documentElement.clientWidth?document.documentElement.clientWidth:screen.width,o=window.innerHeight?window.innerHeight:document.documentElement.clientHeight?document.documentElement.clientHeight:screen.height,i=a/2-e.width/2+n,s=o/2-e.height/2+r,u=window.open(t,"OpenShare","width="+e.width+", height="+e.height+", top="+s+", left="+i);window.focus&&u.focus()}}]),t}(),C=function(t,e){var n=e.substr(t+1,1),r=e.substr(t,2);return e=e.replace(r,n.toUpperCase())},_=function(t,e){var n=t.type.indexOf(",")>-1,r=Number(t.storeGet(t.type+"-"+t.shared));if(r>e&&!n){var a=Number(t.storeGet(t.type+"-"+t.shared+"-latestCount"));t.storeSet(t.type+"-"+t.shared+"-latestCount",e),e=e+=y(a)&&a>0?r-a:r}return n||t.storeSet(t.type+"-"+t.shared,e),e},N={facebook:function(t){return{type:"get",url:"https://graph.facebook.com/?id="+t,transform:function(t){var e=JSON.parse(t.responseText),n=e.share&&e.share.share_count||0;return _(this,n)}}},pinterest:function(t){return{type:"jsonp",url:"https://api.pinterest.com/v1/urls/count.json?callback=?&url="+t,transform:function(t){var e=t.count||0;return _(this,e)}}},linkedin:function(t){return{type:"jsonp",url:"https://www.linkedin.com/countserv/count/share?url="+t+"&format=jsonp&callback=?",transform:function(t){var e=t.count||0;return _(this,e)}}},reddit:function(t){return{type:"get",url:"https://www.reddit.com/api/info.json?url="+t,transform:function(t){var e=JSON.parse(t.responseText),n=e.data&&e.data.children||null,r=0;return n&&n.forEach(function(t){r+=Number(t.data.ups)}),_(this,r)}}},google:function(t){return{type:"post",data:{method:"pos.plusones.get",id:"p",params:{nolog:!0,id:t,source:"widget",userId:"@viewer",groupId:"@self"},jsonrpc:"2.0",key:"p",apiVersion:"v1"},url:"https://clients6.google.com/rpc",transform:function(t){var e=JSON.parse(t.responseText),n=e.result&&e.result.metadata&&e.result.metadata.globalCounts&&e.result.metadata.globalCounts.count||0;return _(this,n)}}},githubStars:function(t){return t=t.indexOf("github.com/")>-1?t.split("github.com/")[1]:t,{type:"get",url:"https://api.github.com/repos/"+t,transform:function(t){var e=JSON.parse(t.responseText).stargazers_count||0;return _(this,e)}}},githubForks:function(t){return t=t.indexOf("github.com/")>-1?t.split("github.com/")[1]:t,{type:"get",url:"https://api.github.com/repos/"+t,transform:function(t){var e=JSON.parse(t.responseText).forks_count||0;return _(this,e)}}},githubWatchers:function(t){return t=t.indexOf("github.com/")>-1?t.split("github.com/")[1]:t,{type:"get",url:"https://api.github.com/repos/"+t,transform:function(t){var e=JSON.parse(t.responseText).watchers_count||0;return _(this,e)}}},dribbble:function(t){t=t.indexOf("dribbble.com/shots")>-1?t.split("shots/")[1]:t;var e="https://api.dribbble.com/v1/shots/"+t+"/likes";return{type:"get",url:e,transform:function(t,n){var r=this,a=JSON.parse(t.responseText).length;if(12!==a)return _(this,a);var o=2;A(e,o,a,function(t){return r.appendTo&&"function"!=typeof r.appendTo&&r.appendTo.appendChild(r.os),v(r.os,t,r.cb),n.trigger(r.os,"counted-"+r.url),_(r,t)})}}},twitter:function(t){return{type:"get",url:"https://api.openshare.social/job?url="+t+"&key=",transform:function(t){var e=JSON.parse(t.responseText).count||0;return _(this,e)}}}},D=function(){function t(e,n){var a=this;if(r(this,t),!n)throw new Error("Open Share: no url provided for count");if(0===e.indexOf("github")&&("github-stars"===e?e="githubStars":"github-forks"===e?e="githubForks":"github-watchers"===e?e="githubWatchers":console.error("Invalid Github count type. Try github-stars, github-forks, or github-watchers.")),e.indexOf(",")>-1){this.type=e,this.typeArr=this.type.split(","),this.countData=[],this.typeArr.forEach(function(t){if(!N[t])throw new Error("Open Share: "+e+" is an invalid count type");a.countData.push(N[t](n))});var o=this.storeGet(this.type+"-"+this.shared);o&&(this.appendTo&&"function"!=typeof this.appendTo&&this.appendTo.appendChild(this.os),v(this.os,o))}else{if(!N[e])throw new Error("Open Share: "+e+" is an invalid count type");this.type=e,this.countData=N[e](n)}}return S(t,[{key:"count",value:function(t,e,n){this.os=t,this.appendTo=n,this.cb=e,this.url=this.os.getAttribute("data-open-share-count"),this.shared=this.os.getAttribute("data-open-share-count-url"),this.key=this.os.getAttribute("data-open-share-key"),Array.isArray(this.countData)?this.getCounts():this.getCount()}},{key:"getCount",value:function(){var t=this.storeGet(this.type+"-"+this.shared);t&&(this.appendTo&&"function"!=typeof this.appendTo&&this.appendTo.appendChild(this.os),v(this.os,t)),this[this.countData.type](this.countData)}},{key:"getCounts",value:function(){var t=this;this.total=[];var e=this.storeGet(this.type+"-"+this.shared);e&&(this.appendTo&&"function"!=typeof this.appendTo&&this.appendTo.appendChild(this.os),v(this.os,e)),this.countData.forEach(function(e){t[e.type](e,function(e){if(t.total.push(e),t.total.length===t.typeArr.length){var n=0;t.total.forEach(function(t){n+=t}),t.appendTo&&"function"!=typeof t.appendTo&&t.appendTo.appendChild(t.os);var r=Number(t.storeGet(t.type+"-"+t.shared));r>n&&(n=r),t.storeSet(t.type+"-"+t.shared,n),v(t.os,n)}})}),this.appendTo&&"function"!=typeof this.appendTo&&this.appendTo.appendChild(this.os)}},{key:"jsonp",value:function(t,e){var n=this,r=Math.random().toString(36).substring(7).replace(/[^a-zA-Z]/g,"");window[r]=function(r){var a=t.transform.apply(n,[r])||0;e&&"function"==typeof e?e(a):(n.appendTo&&"function"!=typeof n.appendTo&&n.appendTo.appendChild(n.os),v(n.os,a,n.cb)),O.trigger(n.os,"counted-"+n.url)};var a=document.createElement("script");a.src=t.url.replace("callback=?","callback="+r),document.getElementsByTagName("head")[0].appendChild(a)}},{key:"get",value:function(t,e){var n=this,r=new XMLHttpRequest;r.onreadystatechange=function(){if(4===r.readyState){if(200===r.status){var a=t.transform.apply(n,[r,O])||0;return e&&"function"==typeof e?e(a):(n.appendTo&&"function"!=typeof n.appendTo&&n.appendTo.appendChild(n.os),v(n.os,a,n.cb)),void O.trigger(n.os,"counted-"+n.url)}if(0===t.url.toLowerCase().indexOf("https://api.openshare.social/job?")){console.warn("Please sign up for Twitter counts at https://openshare.social/twitter/auth");var o=0;e&&"function"==typeof e?e(o):(n.appendTo&&"function"!=typeof n.appendTo&&n.appendTo.appendChild(n.os),v(n.os,o,n.cb)),O.trigger(n.os,"counted-"+n.url)}else{console.warn("Failed to get API data from",t.url,". Please use the latest version of OpenShare.");var i=0;e&&"function"==typeof e?e(i):(n.appendTo&&"function"!=typeof n.appendTo&&n.appendTo.appendChild(n.os),v(n.os,i,n.cb)),O.trigger(n.os,"counted-"+n.url)}}},t.url=t.url.startsWith("https://api.openshare.social/job?")&&this.key?t.url+this.key:t.url,r.open("GET",t.url),r.send()}},{key:"post",value:function(t,e){var n=this,r=new XMLHttpRequest;r.onreadystatechange=function(){if(r.readyState===XMLHttpRequest.DONE&&200===r.status){var a=t.transform.apply(n,[r])||0;e&&"function"==typeof e?e(a):(n.appendTo&&"function"!=typeof n.appendTo&&n.appendTo.appendChild(n.os),v(n.os,a,n.cb)),O.trigger(n.os,"counted-"+n.url)}},r.open("POST",t.url),r.setRequestHeader("Content-Type","application/json;charset=UTF-8"),r.send(JSON.stringify(t.data))}},{key:"storeSet",value:function(t){var e=arguments.length<=1||void 0===arguments[1]?0:arguments[1];window.localStorage&&t&&localStorage.setItem("OpenShare-"+t,e)}},{key:"storeGet",value:function(t){if(window.localStorage&&t)return localStorage.getItem("OpenShare-"+t)}}]),t}(),M=function(){return"complete"===document.readyState?k():void document.addEventListener("readystatechange",function(){"complete"===document.readyState&&k()},!1)},q=function(){var t=function(){function t(e,n){var a=this;r(this,t),e.bindClick||(e.bindClick=!0);var o=e.type.indexOf("-");o>-1&&(e.type=C(o,e.type));var i=void 0;if(this.element=n,this.data=e,this.os=new L(e.type,x[e.type]),this.os.setData(e),n&&!e.element||(n=e.element,i=document.createElement(n||"a"),e.type&&(i.classList.add("open-share-link",e.type),i.setAttribute("data-open-share",e.type),i.setAttribute("data-open-share-node",e.type)),e.innerHTML&&(i.innerHTML=e.innerHTML)),i&&(n=i),e.bindClick&&n.addEventListener("click",function(){a.share()}),e.appendTo&&e.appendTo.appendChild(n),e.classes&&Array.isArray(e.classes)&&e.classes.forEach(function(t){n.classList.add(t)}),"paypal"===e.type.toLowerCase()){var s=e.sandbox?"https://www.sandbox.paypal.com/cgi-bin/webscr":"https://www.paypal.com/cgi-bin/webscr",u=e.sandbox?"https://www.sandbox.paypal.com/en_US/i/btn/btn_buynow_LG.gif":"https://www.paypalobjects.com/en_US/i/btn/btn_buynow_LG.gif",p=e.sandbox?"https://www.sandbox.paypal.com/en_US/i/scr/pixel.gif":"https://www.paypalobjects.com/en_US/i/scr/pixel.gif",h="