| @@ -547,8 +547,10 @@ | ||
| 547 | 547 | } ); |
| 548 | 548 | |
| 549 | 549 | // Press This button |
| 550 | 550 | forEachNode( group.querySelectorAll( 'a.share-press-this' ), function ( pressThisButton ) { |
| 551 | + // Unpredictable, but stable per page load so repeat clicks reuse the same popup. | |
| 552 | + var pressThisWindowName = 'wp-press-this-' + Math.random().toString( 36 ).slice( 2 ); | |
| 551 | 553 | pressThisButton.addEventListener( 'click', function ( event ) { |
| 552 | 554 | event.preventDefault(); |
| 553 | 555 | event.stopPropagation(); |
| 554 | 556 | |
| @@ -569,9 +571,9 @@ | ||
| 569 | 571 | |
| 570 | 572 | if ( |
| 571 | 573 | ! window.open( |
| 572 | 574 | pressThisButton.getAttribute( 'href' ), |
| 573 | - 't', | |
| 575 | + pressThisWindowName, | |
| 574 | 576 | 'toolbar=0,resizable=1,scrollbars=1,status=1,width=720,height=570' |
| 575 | 577 | ) |
| 576 | 578 | ) { |
| 577 | 579 | document.location.href = pressThisButton.getAttribute( 'href' ); |
| @@ -609,6 +611,113 @@ | ||
| 609 | 611 | function ( node ) { |
| 610 | 612 | node.classList.add( 'share-service-visible' ); |
| 611 | 613 | } |
| 612 | 614 | ); |
| 615 | + } | |
| 616 | + | |
| 617 | + // ---------------------------- SHARE POPUPS ---------------------------- // | |
| 618 | + | |
| 619 | + // Services that open their share link in a popup publish the window features | |
| 620 | + // they need in `window.WPCOM_sharing_popups`, keyed by the service name that | |
| 621 | + // also appears in the link's `share-<service>` class. Sharing_Source::js_dialog() | |
| 622 | + // prints that map in an inline script after this file, and the one delegated | |
| 623 | + // listener below serves every service, with only one popup open at a time. | |
| 624 | + // | |
| 625 | + // The Sharing Buttons block runs a parallel popup handler in | |
| 626 | + // extensions/blocks/sharing-buttons/view.js; a change here usually belongs there too. | |
| 627 | + var sharePopup; | |
| 628 | + var sharePopupNames = {}; | |
| 629 | + | |
| 630 | + // Popup names are unpredictable, so another page cannot pre-register one and | |
| 631 | + // claim the popup. They are stable per service per page load, so repeat clicks | |
| 632 | + // on a service reuse its window. | |
| 633 | + function getSharePopupName( service ) { | |
| 634 | + if ( typeof sharePopupNames[ service ] !== 'string' ) { | |
| 635 | + sharePopupNames[ service ] = | |
| 636 | + 'wpcom' + service + '-' + Math.random().toString( 36 ).slice( 2 ); | |
| 637 | + } | |
| 638 | + | |
| 639 | + return sharePopupNames[ service ]; | |
| 640 | + } | |
| 641 | + | |
| 642 | + // Find the share link a click landed on. Sharing buttons nest at most one | |
| 643 | + // element inside the anchor, and this stays as shallow as the per-service | |
| 644 | + // handlers it replaces, so nothing that used to reach its own click handler | |
| 645 | + // starts being claimed by this one instead. | |
| 646 | + function getShareLink( target ) { | |
| 647 | + if ( target.nodeName === 'A' ) { | |
| 648 | + return target; | |
| 649 | + } | |
| 650 | + | |
| 651 | + var parent = target.parentNode; | |
| 652 | + return parent && parent.nodeName === 'A' ? parent : null; | |
| 653 | + } | |
| 654 | + | |
| 655 | + // Find the popup service a share link belongs to, if it belongs to one. | |
| 656 | + function getSharePopupService( link ) { | |
| 657 | + var popups = window.WPCOM_sharing_popups; | |
| 658 | + if ( ! popups ) { | |
| 659 | + return null; | |
| 660 | + } | |
| 661 | + | |
| 662 | + var prefix = 'share-'; | |
| 663 | + var classes = ( link.getAttribute( 'class' ) || '' ).split( /\s+/ ); | |
| 664 | + for ( var i = 0; i < classes.length; i++ ) { | |
| 665 | + if ( classes[ i ].indexOf( prefix ) !== 0 ) { | |
| 666 | + continue; | |
| 667 | + } | |
| 668 | + | |
| 669 | + var service = classes[ i ].slice( prefix.length ); | |
| 670 | + if ( typeof popups[ service ] === 'string' ) { | |
| 671 | + return service; | |
| 672 | + } | |
| 673 | + } | |
| 674 | + | |
| 675 | + return null; | |
| 676 | + } | |
| 677 | + | |
| 678 | + function openSharePopup( event ) { | |
| 679 | + var target = event.target; | |
| 680 | + if ( ! target || target.nodeType !== 1 ) { | |
| 681 | + return; | |
| 682 | + } | |
| 683 | + | |
| 684 | + var link = getShareLink( target ); | |
| 685 | + if ( ! link ) { | |
| 686 | + return; | |
| 687 | + } | |
| 688 | + | |
| 689 | + var service = getSharePopupService( link ); | |
| 690 | + if ( ! service ) { | |
| 691 | + return; | |
| 692 | + } | |
| 693 | + | |
| 694 | + event.preventDefault(); | |
| 695 | + | |
| 696 | + // If there's another sharing window open, close it. | |
| 697 | + if ( sharePopup ) { | |
| 698 | + sharePopup.close(); | |
| 699 | + } | |
| 700 | + | |
| 701 | + sharePopup = window.open( | |
| 702 | + link.getAttribute( 'href' ), | |
| 703 | + getSharePopupName( service ), | |
| 704 | + window.WPCOM_sharing_popups[ service ] | |
| 705 | + ); | |
| 706 | + } | |
| 707 | + | |
| 708 | + // Listen on `document.body`, where the per-service handlers this replaces listened, | |
| 709 | + // so a page script that stops a click from propagating past the body keeps having | |
| 710 | + // the same effect it always had. The bind flag has to be global: if this file is | |
| 711 | + // enqueued twice under different handles, each copy gets its own closure, and two | |
| 712 | + // listeners would open two popups per click. Compare against `true` so a page | |
| 713 | + // element named after the flag cannot clobber it and leave every button dead. | |
| 714 | + // | |
| 715 | + // This has to stay below the `is.post-load` listener above: both dereference | |
| 716 | + // `document.body`, and if this file is ever evaluated before the body exists it | |
| 717 | + // should fail where it already failed, after `init()` has registered, rather than | |
| 718 | + // take the rest of the file down with it. | |
| 719 | + if ( window.WPCOM_sharing_popups_bound !== true ) { | |
| 720 | + document.body.addEventListener( 'click', openSharePopup ); | |
| 721 | + window.WPCOM_sharing_popups_bound = true; | |
| 613 | 722 | } |
| 614 | 723 | } )(); |