PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.0-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.0-beta
16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / modules / sharedaddy / sharing.js
jetpack / modules / sharedaddy Last commit date
images 2 months ago services 7 months ago admin-sharing-rtl.css 4 months ago admin-sharing-rtl.min.css 1 month ago admin-sharing.css 4 months ago admin-sharing.js 2 months ago admin-sharing.min.css 1 month ago amp-sharing.css 4 months ago recaptcha.php 1 month ago sharedaddy.php 7 months ago sharing-service.php 1 month ago sharing-sources.php 1 month ago sharing.css 4 months ago sharing.js 3 years ago sharing.php 2 months ago
sharing.js
615 lines
1 /* global WPCOM_sharing_counts */
2
3 // NOTE: This file intentionally does not make use of polyfills or libraries,
4 // including jQuery. Please keep all code as IE11-compatible vanilla ES5, and
5 // ensure everything is inside an IIFE to avoid global namespace pollution.
6 // Code follows WordPress browser support guidelines. For an up to date list,
7 // see https://make.wordpress.org/core/handbook/best-practices/browser-support/
8
9 ( function () {
10 var currentScript = document.currentScript;
11
12 // -------------------------- UTILITY FUNCTIONS -------------------------- //
13
14 // Helper function to load an external script.
15 function loadScript( url ) {
16 var script = document.createElement( 'script' );
17 var prev = currentScript || document.getElementsByTagName( 'script' )[ 0 ];
18 script.setAttribute( 'async', true );
19 script.setAttribute( 'src', url );
20 prev.parentNode.insertBefore( script, prev );
21 }
22
23 // Helper matches function (not a polyfill), compatible with IE 11.
24 function matches( el, sel ) {
25 if ( Element.prototype.matches ) {
26 return el.matches( sel );
27 }
28
29 if ( Element.prototype.msMatchesSelector ) {
30 return el.msMatchesSelector( sel );
31 }
32 }
33
34 // Helper closest parent node function (not a polyfill) based on
35 // https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
36 function closest( el, sel ) {
37 if ( el.closest ) {
38 return el.closest( sel );
39 }
40
41 var current = el;
42
43 do {
44 if ( matches( current, sel ) ) {
45 return current;
46 }
47 current = current.parentElement || current.parentNode;
48 } while ( current !== null && current.nodeType === 1 );
49
50 return null;
51 }
52
53 // Helper function to iterate over a NodeList
54 // (since IE 11 doesn't have NodeList.prototype.forEach)
55 function forEachNode( list, fn ) {
56 for ( var i = 0; i < list.length; i++ ) {
57 var node = list[ i ];
58 fn( node, i, list );
59 }
60 }
61
62 // Helper function to remove a node from the DOM.
63 function removeNode( node ) {
64 if ( node && node.parentNode ) {
65 node.parentNode.removeChild( node );
66 }
67 }
68
69 // Helper functions to show/hide a node, and check its status.
70 function hideNode( node ) {
71 if ( node ) {
72 node.style.display = 'none';
73 }
74 }
75
76 function showNode( node ) {
77 if ( node ) {
78 node.style.removeProperty( 'display' );
79 }
80 }
81
82 function isNodeHidden( node ) {
83 return ! node || node.style.display === 'none';
84 }
85
86 // ------------------------------- CLASSES ------------------------------- //
87
88 var PANE_SELECTOR = '.sharing-hidden .inner';
89 var PANE_DATA_ATTR = 'data-sharing-more-button-id';
90
91 // Implements a MoreButton class, which controls the lifecycle and behavior
92 // of a "more" button and its dialog.
93 function MoreButton( buttonEl ) {
94 this.button = buttonEl;
95 this.pane = closest( buttonEl, 'div' ).querySelector( PANE_SELECTOR );
96 this.openedBy = null;
97 this.recentlyOpenedByHover = false;
98
99 MoreButton.instances.push( this );
100 this.pane.setAttribute( PANE_DATA_ATTR, MoreButton.instances.length - 1 );
101
102 this.attachHandlers();
103 }
104
105 // Keep a reference to each instance, so we can get back to it from the DOM.
106 MoreButton.instances = [];
107
108 // Delay time configs.
109 MoreButton.hoverOpenDelay = 200;
110 MoreButton.recentOpenDelay = 400;
111 MoreButton.hoverCloseDelay = 300;
112
113 // Use this to avoid creating new instances for buttons which already have one.
114 MoreButton.instantiateOrReuse = function ( buttonEl ) {
115 var pane = closest( buttonEl, 'div' ).querySelector( PANE_SELECTOR );
116 var paneId = pane && pane.getAttribute( PANE_DATA_ATTR );
117
118 var existingInstance = MoreButton.instances[ paneId ];
119 if ( existingInstance ) {
120 return existingInstance;
121 }
122
123 return new MoreButton( buttonEl );
124 };
125
126 // Retrieve a button instance from the pane DOM element.
127 MoreButton.getButtonInstanceFromPane = function ( paneEl ) {
128 var paneId = paneEl && paneEl.getAttribute( PANE_DATA_ATTR );
129 return MoreButton.instances[ paneId ];
130 };
131
132 // Close all open More Button dialogs.
133 MoreButton.closeAll = function () {
134 for ( var i = 0; i < MoreButton.instances.length; i++ ) {
135 MoreButton.instances[ i ].close();
136 }
137 };
138
139 MoreButton.prototype.open = function () {
140 var offset;
141 var offsetParent;
142 var parentOffset = [ 0, 0 ];
143
144 function getOffsets( el ) {
145 var rect = el.getBoundingClientRect();
146 return [
147 rect.left + ( window.scrollX || window.pageXOffset || 0 ),
148 rect.top + ( window.scrollY || window.pageYOffset || 0 ),
149 ];
150 }
151
152 function getStyleValue( el, prop ) {
153 return parseInt( getComputedStyle( el ).getPropertyValue( prop ) || 0 );
154 }
155
156 offset = getOffsets( this.button );
157 offsetParent = this.button.offsetParent || document.documentElement;
158
159 while (
160 offsetParent &&
161 ( offsetParent === document.body || offsetParent === document.documentElement ) &&
162 getComputedStyle( offsetParent ).getPropertyValue( 'position' ) === 'static'
163 ) {
164 offsetParent = offsetParent.parentNode;
165 }
166
167 if ( offsetParent && offsetParent !== this.button && offsetParent.nodeType === 1 ) {
168 parentOffset = getOffsets( offsetParent );
169 parentOffset = [
170 parentOffset[ 0 ] + getStyleValue( offsetParent, 'border-left-width' ),
171 parentOffset[ 1 ] + getStyleValue( offsetParent, 'border-top-width' ),
172 ];
173 }
174
175 var positionLeft =
176 offset[ 0 ] - parentOffset[ 0 ] - getStyleValue( this.button, 'margin-left' );
177 var positionTop = offset[ 1 ] - parentOffset[ 1 ] - getStyleValue( this.button, 'margin-top' );
178
179 this.pane.style.left = positionLeft + 'px';
180 this.pane.style.top = positionTop + this.button.offsetHeight + 3 + 'px';
181
182 showNode( this.pane );
183 };
184
185 MoreButton.prototype.close = function () {
186 hideNode( this.pane );
187 this.openedBy = null;
188 };
189
190 MoreButton.prototype.toggle = function () {
191 if ( isNodeHidden( this.pane ) ) {
192 this.open();
193 } else {
194 this.close();
195 }
196 };
197
198 MoreButton.prototype.nonHoverOpen = function () {
199 clearTimeout( this.openTimer );
200 clearTimeout( this.closeTimer );
201
202 if ( this.recentlyOpenedByHover ) {
203 this.recentlyOpenedByHover = false;
204 clearTimeout( this.hoverOpenTimer );
205 this.open();
206 } else {
207 this.toggle();
208 }
209 };
210
211 MoreButton.prototype.resetCloseTimer = function () {
212 clearTimeout( this.closeTimer );
213 this.closeTimer = setTimeout( this.close.bind( this ), MoreButton.hoverCloseDelay );
214 };
215
216 MoreButton.prototype.attachHandlers = function () {
217 this.buttonClick = function ( event ) {
218 event.preventDefault();
219 event.stopPropagation();
220
221 this.openedBy = 'click';
222 this.nonHoverOpen();
223 }.bind( this );
224
225 this.buttonKeydown = function ( event ) {
226 if ( event.keyCode === 13 || event.keyCode === 32 ) {
227 event.preventDefault();
228 event.stopPropagation();
229
230 this.openedBy = 'keydown';
231 this.nonHoverOpen();
232 }
233 }.bind( this );
234
235 this.buttonEnter = function () {
236 if ( ! this.openedBy ) {
237 this.openTimer = setTimeout(
238 function () {
239 this.open();
240 this.openedBy = 'hover';
241 this.recentlyOpenedByHover = true;
242 this.hoverOpenTimer = setTimeout(
243 function () {
244 this.recentlyOpenedByHover = false;
245 }.bind( this ),
246 MoreButton.recentOpenDelay
247 );
248 }.bind( this ),
249 MoreButton.hoverOpenDelay
250 );
251 }
252 clearTimeout( this.closeTimer );
253 }.bind( this );
254
255 this.buttonLeave = function () {
256 if ( this.openedBy === 'hover' ) {
257 this.resetCloseTimer();
258 }
259 clearTimeout( this.openTimer );
260 }.bind( this );
261
262 this.paneEnter = function () {
263 clearTimeout( this.closeTimer );
264 }.bind( this );
265
266 this.paneLeave = function () {
267 if ( this.openedBy === 'hover' ) {
268 this.resetCloseTimer();
269 }
270 }.bind( this );
271
272 this.documentClick = function () {
273 this.close();
274 }.bind( this );
275
276 this.button.addEventListener( 'click', this.buttonClick );
277 this.button.addEventListener( 'keydown', this.buttonKeydown );
278 document.addEventListener( 'click', this.documentClick );
279
280 if ( document.ontouchstart === undefined ) {
281 // Non-touchscreen device: use hover/mouseout with delay
282 this.button.addEventListener( 'mouseenter', this.buttonEnter );
283 this.button.addEventListener( 'mouseleave', this.buttonLeave );
284 this.pane.addEventListener( 'mouseenter', this.paneEnter );
285 this.pane.addEventListener( 'mouseleave', this.paneLeave );
286 }
287 };
288
289 // ---------------------------- SHARE COUNTS ---------------------------- //
290
291 if ( window.sharing_js_options && window.sharing_js_options.counts ) {
292 var WPCOMSharing = {
293 done_urls: [],
294 get_counts: function () {
295 var url, requests, id, service, service_request;
296
297 if ( 'undefined' === typeof WPCOM_sharing_counts ) {
298 return;
299 }
300
301 for ( url in WPCOM_sharing_counts ) {
302 id = WPCOM_sharing_counts[ url ];
303
304 if ( 'undefined' !== typeof WPCOMSharing.done_urls[ id ] ) {
305 continue;
306 }
307
308 requests = {
309 // Pinterest handles share counts for both http and https
310 pinterest: [
311 window.location.protocol +
312 '//api.pinterest.com/v1/urls/count.json?callback=WPCOMSharing.update_pinterest_count&url=' +
313 encodeURIComponent( url ),
314 ],
315 };
316
317 for ( service in requests ) {
318 if ( ! document.querySelector( 'a[data-shared=sharing-' + service + '-' + id + ']' ) ) {
319 continue;
320 }
321
322 while ( ( service_request = requests[ service ].pop() ) ) {
323 loadScript( service_request );
324 }
325
326 if ( window.sharing_js_options.is_stats_active ) {
327 WPCOMSharing.bump_sharing_count_stat( service );
328 }
329 }
330
331 WPCOMSharing.done_urls[ id ] = true;
332 }
333 },
334 update_pinterest_count: function ( data ) {
335 if ( 'undefined' !== typeof data.count && data.count * 1 > 0 ) {
336 WPCOMSharing.inject_share_count(
337 'sharing-pinterest-' + WPCOM_sharing_counts[ data.url ],
338 data.count
339 );
340 }
341 },
342 inject_share_count: function ( id, count ) {
343 forEachNode(
344 document.querySelectorAll( 'a[data-shared=' + id + '] > span' ),
345 function ( span ) {
346 var countNode = span.querySelector( '.share-count' );
347 removeNode( countNode );
348 var newNode = document.createElement( 'span' );
349 newNode.className = 'share-count';
350 newNode.textContent = WPCOMSharing.format_count( count );
351 span.appendChild( newNode );
352 }
353 );
354 },
355 format_count: function ( count ) {
356 if ( count < 1000 ) {
357 return count;
358 }
359 if ( count >= 1000 && count < 10000 ) {
360 return String( count ).substring( 0, 1 ) + 'K+';
361 }
362 return '10K+';
363 },
364 bump_sharing_count_stat: function ( service ) {
365 new Image().src =
366 document.location.protocol +
367 '//pixel.wp.com/g.gif?v=wpcom-no-pv&x_sharing-count-request=' +
368 service +
369 '&r=' +
370 Math.random();
371 },
372 };
373 window.WPCOMSharing = WPCOMSharing;
374 }
375
376 // ------------------------ BUTTON FUNCTIONALITY ------------------------ //
377 function isUrlForCurrentHost( url ) {
378 var currentDomain = window.location.protocol + '//' + window.location.hostname + '/';
379
380 return String( url ).indexOf( currentDomain ) === 0;
381 }
382
383 function getEncodedFormFieldForSubmit( name, value ) {
384 // Encode the key and value into a URI-compatible string.
385 var encoded = encodeURIComponent( name ) + '=' + encodeURIComponent( value );
386
387 // In x-www-form-urlencoded, spaces should be `+`, not `%20`.
388 return encoded.replace( /%20/g, '+' );
389 }
390
391 function trackButtonClick( button ) {
392 var clickCount = getClickCountForButton( button );
393
394 setClickCountForButton( button, clickCount + 1 );
395 }
396
397 function setClickCountForButton( button, clickCount ) {
398 button.setAttribute( 'jetpack-share-click-count', clickCount );
399 }
400
401 function getClickCountForButton( button ) {
402 var currentClickCount = button.getAttribute( 'jetpack-share-click-count' );
403 if ( currentClickCount === null ) {
404 return 0;
405 }
406
407 return parseInt( currentClickCount, 10 );
408 }
409
410 function showEmailShareError( emailShareButton, sdUlGroup ) {
411 var sdContent = sdUlGroup.parentElement;
412 if ( ! sdContent.classList.contains( 'sd-content' ) ) {
413 return;
414 }
415
416 forEachNode( sdContent.querySelectorAll( '.share-email-error' ), function ( shareEmailError ) {
417 shareEmailError.parentElement.removeChild( shareEmailError );
418 } );
419
420 var newShareEmailError = document.createElement( 'div' );
421 newShareEmailError.className = 'share-email-error';
422
423 var newShareEmailErrorTitle = document.createElement( 'h6' );
424 newShareEmailErrorTitle.className = 'share-email-error-title';
425 newShareEmailErrorTitle.innerText = emailShareButton.getAttribute(
426 'data-email-share-error-title'
427 );
428 newShareEmailError.appendChild( newShareEmailErrorTitle );
429
430 var newShareEmailErrorText = document.createElement( 'p' );
431 newShareEmailErrorText.className = 'share-email-error-text';
432 newShareEmailErrorText.innerText = emailShareButton.getAttribute(
433 'data-email-share-error-text'
434 );
435 newShareEmailError.appendChild( newShareEmailErrorText );
436
437 sdContent.appendChild( newShareEmailError );
438 }
439
440 function recordEmailShareClick( emailShareTrackerUrl, emailShareNonce ) {
441 var request = new XMLHttpRequest();
442 request.open( 'POST', emailShareTrackerUrl, true );
443 request.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8' );
444 request.setRequestHeader( 'x-requested-with', 'XMLHttpRequest' );
445
446 request.send( getEncodedFormFieldForSubmit( 'email-share-nonce', emailShareNonce ) );
447 }
448
449 // Sharing initialization.
450 // Will run immediately or on `DOMContentLoaded`, depending on current page status.
451 function init() {
452 WPCOMSharing_do();
453 }
454 if ( document.readyState !== 'loading' ) {
455 init();
456 } else {
457 document.addEventListener( 'DOMContentLoaded', init );
458 }
459
460 // Set up sharing again whenever a new post loads, to pick up any new buttons.
461 document.body.addEventListener( 'is.post-load', WPCOMSharing_do );
462
463 // Set up sharing, updating counts and adding all button functionality.
464 function WPCOMSharing_do() {
465 if ( window.WPCOMSharing ) {
466 window.WPCOMSharing.get_counts();
467 }
468
469 forEachNode( document.querySelectorAll( '.sharedaddy a' ), function ( anchor ) {
470 var href = anchor.getAttribute( 'href' );
471 if ( href && href.indexOf( 'share=' ) !== -1 && href.indexOf( '&nb=1' ) === -1 ) {
472 anchor.setAttribute( 'href', href + '&nb=1' );
473 }
474 } );
475
476 // Show hidden buttons
477
478 // Touchscreen device: use click.
479 // Non-touchscreen device: use click if not already appearing due to a hover event
480
481 forEachNode(
482 document.querySelectorAll( '.sharedaddy a.sharing-anchor' ),
483 function ( buttonEl ) {
484 MoreButton.instantiateOrReuse( buttonEl );
485 }
486 );
487
488 if ( document.ontouchstart !== undefined ) {
489 document.body.classList.add( 'jp-sharing-input-touch' );
490 }
491
492 // Add click functionality
493 forEachNode( document.querySelectorAll( '.sharedaddy ul' ), function ( group ) {
494 if ( group.getAttribute( 'data-sharing-events-added' ) === 'true' ) {
495 return;
496 }
497 group.setAttribute( 'data-sharing-events-added', 'true' );
498
499 var printUrl = function ( uniqueId, urlToPrint ) {
500 var iframe = document.createElement( 'iframe' );
501 iframe.setAttribute(
502 'style',
503 'position:fixed; top:100; left:100; height:1px; width:1px; border:none;'
504 );
505 iframe.setAttribute( 'id', 'printFrame-' + uniqueId );
506 iframe.setAttribute( 'name', iframe.getAttribute( 'id' ) );
507 iframe.setAttribute( 'src', urlToPrint );
508 iframe.setAttribute(
509 'onload',
510 'frames["printFrame-' +
511 uniqueId +
512 '"].focus();frames["printFrame-' +
513 uniqueId +
514 '"].print();'
515 );
516 document.body.appendChild( iframe );
517 };
518
519 // Print button
520 forEachNode( group.querySelectorAll( 'a.share-print' ), function ( printButton ) {
521 printButton.addEventListener( 'click', function ( event ) {
522 event.preventDefault();
523 event.stopPropagation();
524
525 var ref = printButton.getAttribute( 'href' ) || '';
526 var doPrint = function () {
527 if ( ref.indexOf( '#print' ) === -1 ) {
528 var uid = new Date().getTime();
529 printUrl( uid, ref );
530 } else {
531 window.print();
532 }
533 };
534
535 // Is the button in a dropdown?
536 var pane = closest( printButton, PANE_SELECTOR );
537 if ( pane ) {
538 var moreButton = MoreButton.getButtonInstanceFromPane( pane );
539 if ( moreButton ) {
540 moreButton.close();
541 doPrint();
542 }
543 } else {
544 doPrint();
545 }
546 } );
547 } );
548
549 // Press This button
550 forEachNode( group.querySelectorAll( 'a.share-press-this' ), function ( pressThisButton ) {
551 pressThisButton.addEventListener( 'click', function ( event ) {
552 event.preventDefault();
553 event.stopPropagation();
554
555 var s = '';
556
557 if ( window.getSelection ) {
558 s = window.getSelection();
559 } else if ( document.getSelection ) {
560 s = document.getSelection();
561 } else if ( document.selection ) {
562 s = document.selection.createRange().text;
563 }
564
565 if ( s ) {
566 var href = pressThisButton.getAttribute( 'href' );
567 pressThisButton.setAttribute( 'href', href + '&sel=' + encodeURI( s ) );
568 }
569
570 if (
571 ! window.open(
572 pressThisButton.getAttribute( 'href' ),
573 't',
574 'toolbar=0,resizable=1,scrollbars=1,status=1,width=720,height=570'
575 )
576 ) {
577 document.location.href = pressThisButton.getAttribute( 'href' );
578 }
579 } );
580 } );
581
582 // Email button
583 forEachNode( group.querySelectorAll( 'a.share-email' ), function ( emailButton ) {
584 setClickCountForButton( emailButton, 0 );
585
586 var emailShareNonce = emailButton.getAttribute( 'data-email-share-nonce' );
587 var emailShareTrackerUrl = emailButton.getAttribute( 'data-email-share-track-url' );
588
589 if (
590 emailShareNonce &&
591 emailShareTrackerUrl &&
592 isUrlForCurrentHost( emailShareTrackerUrl )
593 ) {
594 emailButton.addEventListener( 'click', function () {
595 trackButtonClick( emailButton );
596
597 if ( getClickCountForButton( emailButton ) > 2 ) {
598 showEmailShareError( emailButton, group );
599 }
600
601 recordEmailShareClick( emailShareTrackerUrl, emailShareNonce );
602 } );
603 }
604 } );
605 } );
606
607 forEachNode(
608 document.querySelectorAll( 'li.share-email, li.share-custom a.sharing-anchor' ),
609 function ( node ) {
610 node.classList.add( 'share-service-visible' );
611 }
612 );
613 }
614 } )();
615