1(function (global, factory) { 2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 typeof define === 'function' && define.amd ? define(factory) : 4 (global = global || self, global.ShareButtons = factory()); 5}(this, function () { 'use strict'; 6 7 var w = window; 8 var d = w.document; 9 10 /** 11 * Class to display the buttons of social networks. 12 */ 13 function ShareButtons() { 14 15 var FB_LINK_FORMAT = 'https://www.facebook.com/sharer/sharer.php?u={0}"e={1}', 16 VK_LINK_FORMAT = 'https://vk.com/share.php?url={0}&title={1}', 17 TW_LINK_FORMAT = 'https://twitter.com/intent/tweet?url={0}&text={1}', 18 TG_LINK_FORMAT = 'https://t.me/share/url?url={0}&text={1}', 19 POCKET_LINK_FORMAT = 'https://getpocket.com/edit?url={0}&title={1}', 20 RE_LINK_FORMAT = 'https://reddit.com/submit?url={0}&title={1}', 21 EV_LINK_FORMAT = 'https://www.evernote.com/clip.action?url={0}&t={1}', 22 IN_LINK_FORMAT = 'https://www.linkedin.com/shareArticle?mini=true&url={0}&title={1}&summary={2}&source={0}', 23 PI_LINK_FORMAT = 'https://pinterest.com/pin/create/button/?url={0}&media={0}&description={1}', 24 SK_LINK_FORMAT = 'https://web.skype.com/share?url={0}&source=button&text={1}', 25 WA_LINK_FORMAT = 'https://wa.me/?text={0}%20{1}', 26 OK_LINK_FORMAT = 'https://connect.ok.ru/dk?st.cmd=WidgetSharePreview&service=odnoklassniki&st.shareUrl={0}', 27 TU_LINK_FORMAT = 'https://www.tumblr.com/widgets/share/tool?posttype=link&title={0}&caption={0}&content={1}&canonicalUrl={1}&shareSource=tumblr_share_button', 28 HN_LINK_FORMAT = 'https://news.ycombinator.com/submitlink?t={0}&u={1}', 29 XI_LINK_FORMAT = 'https://www.xing.com/app/user?op=share;url={0};title={1}', 30 MAIL_LINK_FORMAT = 'mailto:?subject={0}&body={1}', 31 FB_CLASS_NAME = 'fb', 32 VK_CLASS_NAME = 'vk', 33 TW_CLASS_NAME = 'tw', 34 TG_CLASS_NAME = 'tg', 35 PK_CLASS_NAME = 'pk', 36 RE_CLASS_NAME = 're', 37 EV_CLASS_NAME = 'ev', 38 IN_CLASS_NAME = 'in', 39 PI_CLASS_NAME = 'pi', 40 SK_CLASS_NAME = 'sk', 41 WA_CLASS_NAME = 'wa', 42 OK_CLASS_NAME = 'ok', 43 TU_CLASS_NAME = 'tu', 44 HN_CLASS_NAME = 'hn', 45 XI_CLASS_NAME = 'xi', 46 MAIL_CLASS_NAME = 'mail', 47 PRINT_CLASS_NAME = 'print', 48 COPY_CLASS_NAME = 'copy', 49 SHARE_CLASS_NAME = 'share', 50 SHARE_LOG_TAG = 'navigator.share(): ', 51 NOT_SUPPORTED_MESSAGE = 'This feature is not supported on this browser or operating system.'; 52 53 /** 54 * Method for get string in the special format by arguments 55 * from https://wcoder.github.io/notes/string-format-for-string-formating-in-javascript 56 * @param {string} str 57 * @param {Array} args 58 */ 59 var stringFormat = function (str, args) { 60 return str.replace(/\{(\d+)\}/g, function (m, n) { 61 return args[n] || m; 62 }); 63 }; 64 65 /** 66 * Method for merge array of strings to the special format string 67 * @param {Array} texts 68 */ 69 var mergeForTitle = function (texts) { 70 return texts.filter(el => (typeof el === 'string') && (el.trim() != '')).join(' - '); 71 }; 72 73 /** 74 * Log method for debug 75 * @param {string} text log message 76 */ 77 var log = function (text) { 78 w.console.log(text); 79 }; 80 81 /** 82 * Set display=none for elements by selector 83 * @param {string} selector selector of elements 84 */ 85 var hideAll = function (selector) { 86 var elements = d.querySelectorAll(selector); 87 for (var i = 0; i < elements.length; i++) { 88 elements[i].style.display = 'none'; 89 } 90 }; 91 92 /** 93 * Method for initialize class for all elements 94 */ 95 this.i = function () { 96 var i, share = d.querySelectorAll('.share-btn'); 97 98 for (i = share.length; i--;) { 99 initForElement(share[i]); 100 } 101 102 // Check if navigator.clipboard is supported. If not, hide all share-buttons. 103 if (!w.navigator.clipboard) { 104 hideAll('[data-id="' + COPY_CLASS_NAME + '"]'); 105 log('navigator.clipboard(): ' + NOT_SUPPORTED_MESSAGE); 106 } 107 108 // Check if navigator.share is supported. If not, hide all share-buttons. 109 if (!w.navigator.canShare) { 110 hideAll('[data-id="' + SHARE_CLASS_NAME + '"]'); 111 log(SHARE_LOG_TAG + NOT_SUPPORTED_MESSAGE); 112 } 113 }; 114 115 /** 116 * Method for initialize class for all elements 117 * @param {HTMLElement} el Parent container 118 */ 119 var initForElement = function (el) { 120 var i, a = el.querySelectorAll('a'); 121 122 for (i = a.length; i--;) { 123 prepareLink(a[i], { 124 id: '', 125 url: getUrl(el), 126 title: getTitle(el), 127 desc: getDesc(el) 128 }); 129 } 130 }; 131 132 /** 133 * Method for handling click event to link 134 * @param {HTMLElement} el 135 * @param {Object} options 136 */ 137 var prepareLink = function (el, options) { 138 options.id = getAttribute(el, 'data-id'); 139 if (options.id) { 140 removeEventListener(el, 'click'); 141 addEventListener(el, 'click', options); 142 } 143 }; 144 145 /** 146 * Method for getting url from page or options 147 * @param {HTMLElement} share 148 */ 149 var getUrl = function (share) { 150 return getAttribute(share, 'data-url') || w.location.href || ' '; 151 }; 152 153 /** 154 * Method for getting title from page or options 155 * @param {HTMLElement} share 156 */ 157 var getTitle = function (share) { 158 var title = getAttribute(share, 'data-title'); 159 160 if (typeof title === 'string') { 161 return title; 162 } 163 164 return d.title || ''; 165 }; 166 167 /** 168 * Method for getting description from page or options 169 * @param {HTMLElement} share 170 */
171 var getDesc = function (share) { 172 var metaDesc = d.querySelector('meta[name=description]'); 173 var desc = getAttribute(share, 'data-desc'); 174 175 if (typeof desc === 'string') { 176 return desc; 177 } 178 179 return (metaDesc && getAttribute(metaDesc, 'content')) || ''; 180 }; 181 182 /** 183 * Counter for generated cache's share button's index. 184 * This to reference added share buttons' listeners. 185 */ 186 var refCounter = 0; 187 188 /** 189 * List of added listeners' for share buttons. 190 * This to index listeners' for update or removal purpose. 191 */ 192 var listenersCache = {}; 193 194 /** 195 * Method for detaching event to the element 196 * @param {HTMLElement} el 197 * @param {string} eventName 198 */ 199 var removeEventListener = function (el, eventName) { 200 var cachedRef = el.getAttribute('data-sharebtn-ref'); 201 202 if (cachedRef) { 203 if (el.removeEventListener) { 204 el.removeEventListener(eventName, listenersCache[cachedRef]); 205 } else { 206 el.detachEvent('on' + eventName, listenersCache[cachedRef+'ie']); 207 } 208 } 209 }; 210 211 /** 212 * Method for attaching event to the element 213 * @param {HTMLElement} el 214 * @param {string} eventName 215 * @param {Object} opt 216 */ 217 var addEventListener = function (el, eventName, opt) { 218 var handler = function () { 219 share(opt.id, opt.url, opt.title, opt.desc); 220 }; 221 var iehandler = function () { 222 handler.call(el); 223 }; 224 var cachedRef = el.getAttribute('data-sharebtn-ref'); 225 226 if (!cachedRef) { 227 cachedRef = ++refCounter; 228 el.setAttribute('data-sharebtn-ref', cachedRef); 229 } 230 231 listenersCache[cachedRef] = handler; 232 listenersCache[cachedRef+'ie'] = iehandler; 233 234 if (el.addEventListener) { 235 el.addEventListener(eventName, handler); 236 } else { 237 el.attachEvent('on' + eventName, iehandler); 238 } 239 }; 240 241 /** 242 * Method for get attribute value by name 243 * @param {HTMLElement} el 244 * @param {string} attrName 245 */ 246 var getAttribute = function (el, attrName) { 247 return el.getAttribute(attrName); 248 }; 249 250 /** 251 * Method for encoding text to URL format 252 * @param {string} text 253 */ 254 var encode = function (text) { 255 return encodeURIComponent(text); 256 }; 257 258 /** 259 * Method for decoding URL format to text 260 * @param {string} text 261 */ 262 var decode = function (text) { 263 return decodeURIComponent(text); 264 }; 265 266 /** 267 * Method for handling chosen links 268 * @param {string} id 269 * @param {string} urlDef 270 * @param {string} titleDef 271 * @param {string} descDef 272 */ 273 var share = function (id, urlDef, titleDef, descDef) { 274 var url = encode(urlDef), 275 desc = encode(descDef), 276 title = encode(titleDef), 277 text = title || desc || ''; 278 279 switch (id) { 280 case FB_CLASS_NAME: 281 popupCenter( 282 stringFormat(FB_LINK_FORMAT, [url, title]), 283 titleDef); 284 break; 285 286 case VK_CLASS_NAME: 287 popupCenter( 288 stringFormat(VK_LINK_FORMAT, [ 289 url, 290 mergeForTitle([title, desc]) 291 ]), 292 titleDef); 293 break; 294 295 case TW_CLASS_NAME: 296 popupCenter( 297 stringFormat(TW_LINK_FORMAT, [ 298 url, 299 mergeForTitle([title, desc]) 300 ]), 301 titleDef); 302 break; 303 304 case TG_CLASS_NAME: 305 popupCenter(
306 stringFormat(TG_LINK_FORMAT, [ 307 url, 308 mergeForTitle([title, desc]) 309 ]), 310 titleDef); 311 break; 312 313 case PK_CLASS_NAME: 314 popupCenter( 315 stringFormat(POCKET_LINK_FORMAT, [ 316 url, 317 mergeForTitle([title, desc]) 318 ]), 319 titleDef); 320 break; 321 322 case RE_CLASS_NAME: 323 popupCenter( 324 stringFormat(RE_LINK_FORMAT, [url, title]), 325 titleDef); 326 break; 327 328 case EV_CLASS_NAME: 329 popupCenter( 330 stringFormat(EV_LINK_FORMAT, [url, title]), 331 titleDef); 332 break; 333 334 case IN_CLASS_NAME: 335 popupCenter( 336 stringFormat(IN_LINK_FORMAT, [ 337 url, 338 title, 339 mergeForTitle([title, desc]) 340 ]), 341 titleDef); 342 break; 343 344 case PI_CLASS_NAME: 345 popupCenter( 346 stringFormat(PI_LINK_FORMAT, [ 347 url, 348 mergeForTitle([title, desc]) 349 ]), 350 titleDef); 351 break; 352 353 case SK_CLASS_NAME: 354 popupCenter( 355 stringFormat(SK_LINK_FORMAT, [ 356 url, 357 mergeForTitle([title, desc]) 358 ]), 359 titleDef); 360 break; 361 362 case WA_CLASS_NAME: 363 popupCenter( 364 stringFormat(WA_LINK_FORMAT, [ 365 mergeForTitle([title, desc]), 366 url 367 ]), 368 titleDef); 369 break; 370 371 case OK_CLASS_NAME: 372 popupCenter( 373 stringFormat(OK_LINK_FORMAT, [ url ]), 374 titleDef); 375 break; 376 377 case TU_CLASS_NAME: 378 popupCenter( 379 stringFormat(TU_LINK_FORMAT, [ 380 mergeForTitle([title, desc]), 381 url 382 ]), 383 titleDef); 384 break; 385 386 case HN_CLASS_NAME: 387 popupCenter( 388 stringFormat(HN_LINK_FORMAT, [ 389 mergeForTitle([title, desc]), 390 url 391 ]), 392 titleDef); 393 break; 394 395 case XI_CLASS_NAME: 396 popupCenter( 397 stringFormat(XI_LINK_FORMAT, [ 398 url, 399 mergeForTitle([title, desc]) 400 ]), 401 titleDef); 402 break; 403 404 case MAIL_CLASS_NAME: 405 if (title.length > 0 && desc.length > 0) { 406 text = mergeForTitle([title, desc]); 407 } 408 if (url.length > 0) { 409 text = text + ' / ' + url; 410 } 411 412 w.location.href = stringFormat(MAIL_LINK_FORMAT, [title, text]); 413 break; 414 415 case PRINT_CLASS_NAME: 416 myprint(); 417 break; 418 419 case COPY_CLASS_NAME: 420 w.navigator.clipboard.writeText(decode(url)); 421 break; 422 423 case SHARE_CLASS_NAME: 424 text = decode(mergeForTitle([title, desc])); 425 var shareData = { 426 title: text, 427 text: text, 428 url: decode(url), 429 }; 430 431 w.navigator.share(shareData) 432 .then(function () {}) 433 .catch(function (err) { 434 log(SHARE_LOG_TAG + 'Error', err); 435 }); 436 break; 437 438 default: 439 break; 440 } 441 }; 442 443 /** 444 * Method for opening popup window 445 * @param {string} url 446 */ 447 var popupCenter = function (url, title) { 448 var _w = 600, 449 _h = 400, 450 dualScreenLeft = typeof w.screenLeft !== 'undefined' ? w.screenLeft : screen.left, 451 dualScreenTop = typeof w.screenTop !== 'undefined' ? w.screenTop : screen.top, 452 width = w.innerWidth || d.documentElement.clientWidth || screen.width, 453 height = w.innerHeight || d.documentElement.clientHeight || screen.height, 454 left = ((width / 2) - (_w / 2)) + dualScreenLeft, 455 top = ((height / 3) - (_h / 3)) + dualScreenTop, 456 windowFormat = 'resizable,toolbar=yes,location=yes,scrollbars=yes,menubar=yes,width={0},height={1},top={2},left={3}', 457 newWindow = w.open(url, '', stringFormat(windowFormat, [_w, _h, top, left])); 458 459 if (newWindow !== null && newWindow.focus) { 460 newWindow.focus(); 461 } 462 }; 463 464 var myprint = function() { 465 document.querySelectorAll('.no-print, [aria-modal]').forEach(el=>el.classList.add('d-none')); 466 window.print(); 467 document.querySelectorAll('.no-print, [aria-modal]').forEach(el=>el.classList.remove('d-none')); 468 } 469 } 470 471 // start 472 var shareButtons = new ShareButtons(); 473 shareButtons.i(); 474 475 return { 476 update: function () { 477 shareButtons.i(); 478 } 479 }; 480 481}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.