diff --git a/projects/plugins/jetpack/changelog/gold-remove-thickbox b/projects/plugins/jetpack/changelog/gold-remove-thickbox new file mode 100644 index 0000000000000..8e0c4f65afa4e --- /dev/null +++ b/projects/plugins/jetpack/changelog/gold-remove-thickbox @@ -0,0 +1,4 @@ +Significance: minor +Type: enhancement + +Remove thickbox integration for Payments features, and thus remove jQuery dependency. diff --git a/projects/plugins/jetpack/extensions/blocks/donations/donations.php b/projects/plugins/jetpack/extensions/blocks/donations/donations.php index 4e27efb6ca09a..086dea6539cf1 100644 --- a/projects/plugins/jetpack/extensions/blocks/donations/donations.php +++ b/projects/plugins/jetpack/extensions/blocks/donations/donations.php @@ -106,8 +106,7 @@ function render_block( $attr, $content ) { return ''; } - Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME, array( 'thickbox' ) ); - add_thickbox(); + Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME ); require_once JETPACK__PLUGIN_DIR . '/_inc/lib/class-jetpack-currencies.php'; diff --git a/projects/plugins/jetpack/extensions/blocks/subscriptions/subscriptions.php b/projects/plugins/jetpack/extensions/blocks/subscriptions/subscriptions.php index 322e53232c78c..bc5e1ce67fa93 100644 --- a/projects/plugins/jetpack/extensions/blocks/subscriptions/subscriptions.php +++ b/projects/plugins/jetpack/extensions/blocks/subscriptions/subscriptions.php @@ -366,16 +366,7 @@ function get_element_styles_from_attributes( $attributes ) { * @return string */ function render_block( $attributes ) { - // We only want the sites that have newsletter plans to be graced by this JavaScript and thickbox. - if ( has_newsletter_plans() ) { - // We only want the sites that have newsletter plans to be graced by this JavaScript and thickbox. - Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME, array( 'thickbox' ) ); - if ( ! wp_style_is( 'enqueued' ) ) { - wp_enqueue_style( 'thickbox' ); - } - } else { - Jetpack_Gutenberg::load_styles_as_required( FEATURE_NAME ); - } + Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME ); $subscribe_email = ''; diff --git a/projects/plugins/jetpack/extensions/shared/memberships-modal.js b/projects/plugins/jetpack/extensions/shared/memberships-modal.js new file mode 100644 index 0000000000000..7389712651745 --- /dev/null +++ b/projects/plugins/jetpack/extensions/shared/memberships-modal.js @@ -0,0 +1,268 @@ +/* + * Thickbox 3.1 - One Box To Rule Them All. jQuery was removed by Automattic. VErsion was heavily modified and features removed. + * By Cody Lindley (http://www.codylindley.com) + * Copyright (c) 2007 cody lindley + * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php + */ + +/*!!!!!!!!!!!!!!!!! edit below this line at your own risk !!!!!!!!!!!!!!!!!!!!!!!*/ + +let TB_WIDTH = 0; +let TB_HEIGHT = 0; +function show( element ) { + element.style.display = 'block'; + element.style.visibility = 'visible'; +} + +//add thickbox to href & area elements that have a class of .thickbox +function a8c_tb_init( domChunk ) { + document.querySelectorAll( domChunk ).forEach( function ( el ) { + el.addEventListener( + 'click', + function () { + const t = this.title || this.name || null; + const a = this.href || this.alt; + const g = this.rel || false; + a8c_tb_show( t, a, g ); + this.blur(); + return false; + }, + false + ); + } ); +} + +export const a8c_tb_show = function ( caption, url ) { + //function called when the user clicks on a thickbox link + document.querySelectorAll( 'body', 'html' ).forEach( el => { + el.style.height = '100%'; + el.style.width = '100%'; + } ); + document.querySelector( 'html' ).style.overflow = 'hidden'; + // try { + if ( typeof document.body.style.maxHeight === 'undefined' ) { + //if IE 6 + + if ( document.getElementById( 'TB_HideSelect' ) === null ) { + //iframe to hide select elements in ie6 + document + .querySelector( 'body' ) + .insertAdjacentHTML( + 'beforeend', + "
" + ); + document.getElementById( 'TB_overlay' ).addEventListener( 'click', a8c_tb_remove, false ); + } + } else if ( document.getElementById( 'TB_overlay' ) === null ) { + document + .querySelector( 'body' ) + .insertAdjacentHTML( 'beforeend', "
" ); + document.getElementById( 'TB_overlay' ).addEventListener( 'click', a8c_tb_remove, false ); + } + + if ( a8c_tb_detectMacXFF() ) { + document.getElementById( 'TB_overlay' ).classList.add( 'TB_overlayMacFFBGHack' ); //use png overlay so hide flash + } else { + document.getElementById( 'TB_overlay' ).classList.add( 'TB_overlayBG' ); //use background and opacity + } + + if ( caption === null ) { + caption = ''; + } + + //code to show html + const queryString = url.replace( /^[^?]+\??/, '' ); + const params = a8c_tb_parseQuery( queryString ); + TB_WIDTH = params.width * 1 + 30 || 630; //defaults to 630 if no paramaters were added to URL + TB_HEIGHT = params.height * 1 + 40 || 440; //defaults to 440 if no paramaters were added to URL + const ajaxContentW = TB_WIDTH - 30; + const ajaxContentH = TB_HEIGHT - 45; + + if ( url.indexOf( 'TB_iframe' ) !== -1 ) { + // either iframe or ajax window + const urlNoQuery = url.split( 'TB_' ); + document.getElementById( 'TB_iframeContent' )?.remove(); + if ( params.modal !== 'true' ) { + //iframe no modal + document + .getElementById( 'TB_window' ) + .insertAdjacentHTML( + 'beforeend', + "
" + + caption + + "
close or Esc Key
" + ); + } else { + //iframe modal + document.getElementById( 'TB_overlay' ).removeEventListener( 'click', a8c_tb_remove, false ); + document + .getElementById( 'TB_window' ) + .insertAdjacentHTML( + 'beforeend', + "" + ); + } + } else if ( document.getElementById( 'TB_window' ).style.display !== 'block' ) { + // not an iframe, ajax + if ( params.modal !== 'true' ) { + //ajax no modal + document + .getElementById( 'TB_window' ) + .insertAdjacentHTML( + 'beforeend', + "
" + + caption + + "
close or Esc Key
" + ); + } else { + //ajax modal + document.getElementById( 'TB_overlay' ).removeEventListener( 'click', a8c_tb_remove ); + document + .getElementById( 'TB_window' ) + .insertAdjacentHTML( + 'beforeend', + "
" + ); + } + } else { + //this means the window is already up, we are just loading new content via ajax + document.getElementById( 'TB_ajaxContent' )[ 0 ].style.width = ajaxContentW + 'px'; + document.getElementById( 'TB_ajaxContent' )[ 0 ].style.height = ajaxContentH + 'px'; + document.getElementById( 'TB_ajaxContent' )[ 0 ].scrollTop = 0; + document.getElementById( 'TB_ajaxWindowTitle' ).html( caption ); + } + + document + .getElementById( 'TB_closeWindowButton' ) + .addEventListener( 'click', a8c_tb_remove, false ); + + if ( url.indexOf( 'TB_inline' ) !== -1 ) { + document + .getElementById( 'TB_ajaxContent' ) + .append( document.getElementById( params.inlineId ).children() ); + document.getElementById( 'TB_window' ).unload = function () { + document + .getElementById( params.inlineId ) + .append( document.getElementById( 'TB_ajaxContent' ).children() ); // move elements back when you're finished + }; + a8c_tb_position(); + show( document.getElementById( 'TB_window' ) ); + } else if ( url.indexOf( 'TB_iframe' ) !== -1 ) { + a8c_tb_position(); + const isSafari = /^((?!chrome|android).)*safari/i.test( navigator.userAgent ); + + if ( isSafari ) { + //safari needs help because it will not fire iframe onload + show( document.getElementById( 'TB_window' ) ); + } + } else { + document + .getElementById( 'TB_ajaxContent' ) + .load( ( url += '&random=' + new Date().getTime() ), function () { + //to do a post change this load method + a8c_tb_position(); + a8c_tb_init( '#TB_ajaxContent a.thickbox' ); + show( document.getElementById( 'TB_window' ) ); + } ); + } + + if ( ! params.modal ) { + document.onkeyup = function ( e ) { + let keycode = null; + if ( e === null ) { + // ie + keycode = event.keyCode; + } else { + // mozilla + keycode = e.which; + } + if ( keycode === 27 ) { + // close + a8c_tb_remove(); + } + }; + } +}; + +export const a8c_tb_remove = function () { + document.getElementById( 'TB_imageOff' )?.removeEventListener( 'click', a8c_tb_remove ); + document.getElementById( 'TB_closeWindowButton' )?.removeEventListener( 'click', a8c_tb_remove ); + document.getElementById( 'TB_window' )?.remove(); + document.querySelectorAll( '#TB_window,#TB_overlay,#TB_HideSelect' ).forEach( el => { + el.dispatchEvent( new Event( 'unload' ) ); + el.remove(); + } ); + if ( typeof document.body.style.maxHeight === 'undefined' ) { + //if IE 6 + document.querySelectorAll( 'body', 'html' ).forEach( function ( el ) { + el.style.height = 'auto'; + el.style.width = 'auto'; + } ); + } + document.querySelector( 'html' ).style.overflow = ''; + document.onkeydown = ''; + document.onkeyup = ''; + return false; +}; + +function a8c_tb_position() { + document.getElementById( 'TB_window' ).style.marginLeft = + '-' + parseInt( TB_WIDTH / 2, 10 ) + 'px'; + document.getElementById( 'TB_window' ).style.width = TB_WIDTH + 'px'; + // Not supporting IR6 anymore + // if ( ! ( jQuery.browser.msie && jQuery.browser.version < 7 ) ) { + // // take away IE6 + // document.getElementById( 'TB_window' ).style.marginTop = + // '-' + parseInt( TB_HEIGHT / 2, 10 ) + 'px'; + // } +} + +function a8c_tb_parseQuery( query ) { + const Params = {}; + if ( ! query ) { + return Params; + } // return empty object + const Pairs = query.split( /[;&]/ ); + for ( let i = 0; i < Pairs.length; i++ ) { + const KeyVal = Pairs[ i ].split( '=' ); + if ( ! KeyVal || KeyVal.length !== 2 ) { + continue; + } + const key = unescape( KeyVal[ 0 ] ); + let val = unescape( KeyVal[ 1 ] ); + val = val.replace( /\+/g, ' ' ); + Params[ key ] = val; + } + return Params; +} + +function a8c_tb_detectMacXFF() { + const userAgent = navigator.userAgent.toLowerCase(); + if ( userAgent.indexOf( 'mac' ) !== -1 && userAgent.indexOf( 'firefox' ) !== -1 ) { + return true; + } +} diff --git a/projects/plugins/jetpack/extensions/shared/memberships.js b/projects/plugins/jetpack/extensions/shared/memberships.js index ef66fbce19f87..87aba887205ee 100644 --- a/projects/plugins/jetpack/extensions/shared/memberships.js +++ b/projects/plugins/jetpack/extensions/shared/memberships.js @@ -1,4 +1,4 @@ -/* global tb_show, tb_remove */ +import { a8c_tb_show, a8c_tb_remove } from './memberships-modal'; /** * Since "close" button is inside our checkout iframe, in order to close it, it has to pass a message to higher scope to close the modal. @@ -11,20 +11,19 @@ function handleIframeResult( eventFromIframe ) { const data = JSON.parse( eventFromIframe.data ); if ( data && data.action === 'close' ) { window.removeEventListener( 'message', handleIframeResult ); - tb_remove(); + a8c_tb_remove(); } } } -function setUpThickbox( button ) { +function setUpModal( button ) { button.addEventListener( 'click', event => { event.preventDefault(); const url = button.getAttribute( 'href' ); window.scrollTo( 0, 0 ); - tb_show( null, url + '&display=alternate&TB_iframe=true', null ); + a8c_tb_show( null, url + '&display=alternate&TB_iframe=true' ); window.addEventListener( 'message', handleIframeResult, false ); - const tbWindow = document.querySelector( '#TB_window' ); - tbWindow.classList.add( 'jetpack-memberships-modal' ); + document.getElementById( 'TB_window' ).classList.add( 'jetpack-memberships-modal' ); // This line has to come after the Thickbox has opened otherwise Firefox doesn't scroll to the top. window.scrollTo( 0, 0 ); @@ -39,10 +38,10 @@ export const initializeMembershipButtons = selector => { } try { - setUpThickbox( button ); + setUpModal( button ); } catch ( err ) { // eslint-disable-next-line no-console - console.error( 'Problem setting up Thickbox', err ); + console.error( 'Problem setting up Modal', err ); } button.setAttribute( 'data-jetpack-memberships-button-initialized', 'true' ); diff --git a/projects/plugins/jetpack/extensions/shared/memberships.scss b/projects/plugins/jetpack/extensions/shared/memberships.scss index 1a7f0a739736e..67ce5cdd444f9 100644 --- a/projects/plugins/jetpack/extensions/shared/memberships.scss +++ b/projects/plugins/jetpack/extensions/shared/memberships.scss @@ -37,3 +37,151 @@ BODY.modal-open { overflow: hidden; } + +/* ----------------------------------------------------------------------------------------------------------------*/ +/* ---------->>> global settings needed for thickbox <<<-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------------------------------------*/ +*{padding: 0; margin: 0;} + +/* ----------------------------------------------------------------------------------------------------------------*/ +/* ---------->>> thickbox specific link and font settings <<<------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------------------------------------*/ +#TB_window { + font: 12px Arial, Helvetica, sans-serif; + color: #333333; +} + +#TB_secondLine { + font: 10px Arial, Helvetica, sans-serif; + color:#666666; +} + +#TB_window a:link {color: #666666;} +#TB_window a:visited {color: #666666;} +#TB_window a:hover {color: #000;} +#TB_window a:active {color: #666666;} +#TB_window a:focus{color: #666666;} + +/* ----------------------------------------------------------------------------------------------------------------*/ +/* ---------->>> Modal settings <<<-----------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------------------------------------*/ +#TB_overlay { + position: fixed; + z-index:100; + top: 0px; + left: 0px; + height:100%; + width:100%; +} + +.TB_overlayMacFFBGHack {background-color: rgba(0,0,0,0.5) ;} +.TB_overlayBG { + background-color:#000; + filter:alpha(opacity=75); + -moz-opacity: 0.75; + opacity: 0.75; +} + +#TB_window { + position: fixed; + background: #ffffff; + z-index: 102; + display: block; + visibility: visible; + color:#000000; + border: 4px solid #525252; + text-align:left; + top:50%; + left:50%; +} + +#TB_window img#TB_Image { + display:block; + margin: 15px 0 0 15px; + border-right: 1px solid #ccc; + border-bottom: 1px solid #ccc; + border-top: 1px solid #666; + border-left: 1px solid #666; +} + +#TB_caption{ + height:25px; + padding:7px 30px 10px 25px; + float:left; +} + +#TB_closeWindow{ + height:25px; + padding:11px 25px 10px 0; + float:right; +} + +#TB_closeAjaxWindow{ + padding:7px 10px 5px 0; + margin-bottom:1px; + text-align:right; + float:right; +} + +#TB_ajaxWindowTitle{ + float:left; + padding:7px 0 5px 10px; + margin-bottom:1px; +} + +#TB_title{ + background-color:#e8e8e8; + height:27px; +} + +#TB_ajaxContent{ + clear:both; + padding:2px 15px 15px 15px; + overflow:auto; + text-align:left; + line-height:1.4em; +} + +#TB_ajaxContent.TB_modal{ + padding:15px; +} + +#TB_ajaxContent p{ + padding:5px 0px 5px 0px; +} + +#TB_load{ + position: fixed; + display:none; + height:200px; + width:200px; + z-index:103; + top: 50%; + left: 50%; + margin: -100px 0 0 -100px; /* -height/2 0 0 -width/2 */ +} + + + +#TB_HideSelect{ + z-index:99; + position:fixed; + top: 0; + left: 0; + background-color:#fff; + border:none; + filter:alpha(opacity=0); + -moz-opacity: 0; + opacity: 0; + height:100%; + width:100%; +} + + +#TB_iframeContent{ + clear:both; + border:none; + margin-bottom:-1px; + margin-top:1px; + _margin-bottom:1px; +} diff --git a/projects/plugins/jetpack/modules/memberships/class-jetpack-memberships.php b/projects/plugins/jetpack/modules/memberships/class-jetpack-memberships.php index 429cff680a328..c89aa962df9a2 100644 --- a/projects/plugins/jetpack/modules/memberships/class-jetpack-memberships.php +++ b/projects/plugins/jetpack/modules/memberships/class-jetpack-memberships.php @@ -297,7 +297,7 @@ public function should_render_button_preview( $block ) { * @return string|void */ public function render_button( $attributes, $content = null, $block = null ) { - Jetpack_Gutenberg::load_assets_as_required( self::$button_block_name, array( 'thickbox', 'wp-polyfill' ) ); + Jetpack_Gutenberg::load_assets_as_required( self::$button_block_name, array( 'wp-polyfill' ) ); if ( $this->should_render_button_preview( $block ) ) { return $this->render_button_preview( $attributes, $content ); @@ -316,8 +316,6 @@ public function render_button( $attributes, $content = null, $block = null ) { return; } - add_thickbox(); - if ( ! empty( $content ) ) { $block_id = esc_attr( wp_unique_id( 'recurring-payments-block-' ) ); $content = str_replace( 'recurring-payments-id', $block_id, $content );