passkeys
4 days ago
profile
2 weeks ago
wp2fa-dialog.js
2 weeks ago
wp2fa-premium-badge-dialog.js
2 weeks ago
wp2fa-wizard-backup-codes.js
2 weeks ago
wp2fa-wizard-email.js
2 weeks ago
wp2fa-wizard-totp.js
2 weeks ago
wp2fa-wizard.js
2 weeks ago
wp2fa-premium-badge-dialog.js
199 lines
| 1 | /** |
| 2 | * WP 2FA - Premium badge dialog handler. |
| 3 | * |
| 4 | * Opens a reusable premium upsell dialog when a premium badge is clicked. |
| 5 | * Content is driven by window.wp2faPremiumBadgeDialog.pages. |
| 6 | * |
| 7 | * @package wp-2fa |
| 8 | * @since 4.1.0 |
| 9 | */ |
| 10 | |
| 11 | ( function () { |
| 12 | 'use strict'; |
| 13 | |
| 14 | var config = window.wp2faPremiumBadgeDialog || {}; |
| 15 | if ( ! window.wp2faDialog ) { |
| 16 | return; |
| 17 | } |
| 18 | |
| 19 | function isObject( value ) { |
| 20 | return value && 'object' === typeof value && ! Array.isArray( value ); |
| 21 | } |
| 22 | |
| 23 | function getPageConfig( key ) { |
| 24 | var pages = isObject( config.pages ) ? config.pages : {}; |
| 25 | return isObject( pages[ key ] ) ? pages[ key ] : {}; |
| 26 | } |
| 27 | |
| 28 | function mergeObjects( base, override ) { |
| 29 | var out = {}; |
| 30 | var k; |
| 31 | for ( k in base ) { |
| 32 | if ( Object.prototype.hasOwnProperty.call( base, k ) ) { |
| 33 | out[ k ] = base[ k ]; |
| 34 | } |
| 35 | } |
| 36 | for ( k in override ) { |
| 37 | if ( Object.prototype.hasOwnProperty.call( override, k ) ) { |
| 38 | out[ k ] = override[ k ]; |
| 39 | } |
| 40 | } |
| 41 | return out; |
| 42 | } |
| 43 | |
| 44 | function getContextKey( trigger ) { |
| 45 | var explicit = trigger.getAttribute( 'data-wp2fa-premium-context' ); |
| 46 | if ( explicit ) { |
| 47 | return explicit; |
| 48 | } |
| 49 | |
| 50 | if ( config.currentPage && config.currentTab ) { |
| 51 | return config.currentPage + ':' + config.currentTab; |
| 52 | } |
| 53 | |
| 54 | if ( config.currentTab ) { |
| 55 | return 'tab:' + config.currentTab; |
| 56 | } |
| 57 | |
| 58 | if ( config.currentPage ) { |
| 59 | return config.currentPage; |
| 60 | } |
| 61 | |
| 62 | if ( config.currentScreen ) { |
| 63 | return 'screen:' + config.currentScreen; |
| 64 | } |
| 65 | |
| 66 | return 'default'; |
| 67 | } |
| 68 | |
| 69 | function renderBullets( bullets, target ) { |
| 70 | if ( ! Array.isArray( bullets ) || bullets.length < 1 ) { |
| 71 | return; |
| 72 | } |
| 73 | |
| 74 | var list = document.createElement( 'ul' ); |
| 75 | list.className = 'wp2fa-premium-dialog-list'; |
| 76 | |
| 77 | bullets.forEach( function ( bullet ) { |
| 78 | if ( ! isObject( bullet ) || ! bullet.title ) { |
| 79 | return; |
| 80 | } |
| 81 | |
| 82 | var item = document.createElement( 'li' ); |
| 83 | item.className = 'wp2fa-premium-dialog-list-item'; |
| 84 | |
| 85 | var icon = document.createElement( 'span' ); |
| 86 | icon.className = 'wp2fa-premium-dialog-list-icon'; |
| 87 | icon.setAttribute( 'aria-hidden', 'true' ); |
| 88 | |
| 89 | var textWrap = document.createElement( 'div' ); |
| 90 | textWrap.className = 'wp2fa-premium-dialog-list-text'; |
| 91 | |
| 92 | var title = document.createElement( 'strong' ); |
| 93 | title.className = 'wp2fa-premium-dialog-list-title'; |
| 94 | title.textContent = bullet.title; |
| 95 | textWrap.appendChild( title ); |
| 96 | |
| 97 | if ( bullet.description ) { |
| 98 | var description = document.createElement( 'span' ); |
| 99 | description.className = 'wp2fa-premium-dialog-list-description'; |
| 100 | description.textContent = bullet.description; |
| 101 | textWrap.appendChild( description ); |
| 102 | } |
| 103 | |
| 104 | item.appendChild( icon ); |
| 105 | item.appendChild( textWrap ); |
| 106 | list.appendChild( item ); |
| 107 | } ); |
| 108 | |
| 109 | target.appendChild( list ); |
| 110 | } |
| 111 | |
| 112 | function renderContent( dialogData ) { |
| 113 | var wrap = document.createElement( 'div' ); |
| 114 | wrap.className = 'wp2fa-premium-dialog'; |
| 115 | |
| 116 | if ( dialogData.intro ) { |
| 117 | var intro = document.createElement( 'p' ); |
| 118 | intro.className = 'wp2fa-premium-dialog-intro'; |
| 119 | intro.textContent = dialogData.intro; |
| 120 | wrap.appendChild( intro ); |
| 121 | } |
| 122 | |
| 123 | if ( dialogData.description ) { |
| 124 | var description = document.createElement( 'p' ); |
| 125 | description.className = 'wp2fa-premium-dialog-description'; |
| 126 | description.textContent = dialogData.description; |
| 127 | wrap.appendChild( description ); |
| 128 | } |
| 129 | |
| 130 | renderBullets( dialogData.bullets, wrap ); |
| 131 | |
| 132 | if ( dialogData.screenshotUrl ) { |
| 133 | var screenshot = document.createElement( 'img' ); |
| 134 | screenshot.className = 'wp2fa-premium-dialog-screenshot'; |
| 135 | screenshot.src = dialogData.screenshotUrl; |
| 136 | screenshot.alt = dialogData.screenshotAlt || ''; |
| 137 | wrap.appendChild( screenshot ); |
| 138 | } |
| 139 | |
| 140 | if ( isObject( dialogData.cta ) && dialogData.cta.text && dialogData.cta.url ) { |
| 141 | // Use ctaPremium when user has an active license (enabled=false means premium). |
| 142 | var ctaData = dialogData.cta; |
| 143 | if ( ! config.enabled && isObject( dialogData.ctaPremium ) && dialogData.ctaPremium.text && dialogData.ctaPremium.url ) { |
| 144 | ctaData = dialogData.ctaPremium; |
| 145 | } |
| 146 | var cta = document.createElement( 'a' ); |
| 147 | cta.className = 'wp2fa-premium-dialog-cta'; |
| 148 | cta.href = ctaData.url; |
| 149 | cta.target = '_blank'; |
| 150 | cta.rel = 'noopener noreferrer'; |
| 151 | cta.textContent = ctaData.text; |
| 152 | wrap.appendChild( cta ); |
| 153 | } |
| 154 | |
| 155 | return wrap.outerHTML; |
| 156 | } |
| 157 | |
| 158 | function openPremiumDialog( trigger ) { |
| 159 | var defaultData = getPageConfig( 'default' ); |
| 160 | var key = getContextKey( trigger ); |
| 161 | var pageData = getPageConfig( key ); |
| 162 | var dialogData = mergeObjects( defaultData, pageData ); |
| 163 | |
| 164 | if ( ! dialogData.title ) { |
| 165 | dialogData.title = 'Premium feature'; |
| 166 | } |
| 167 | |
| 168 | window.wp2faDialog.open( { |
| 169 | htmlTitle: dialogData.title, |
| 170 | content: renderContent( dialogData ), |
| 171 | buttons: [], |
| 172 | size: 'large', |
| 173 | modalClass: 'wp2fa-premium-dialog-modal' |
| 174 | } ); |
| 175 | } |
| 176 | |
| 177 | document.addEventListener( 'click', function ( event ) { |
| 178 | var trigger = event.target.closest( '.wp2fa-premium-badge' ); |
| 179 | if ( ! trigger ) { |
| 180 | return; |
| 181 | } |
| 182 | |
| 183 | event.preventDefault(); |
| 184 | event.stopPropagation(); |
| 185 | openPremiumDialog( trigger ); |
| 186 | }, true ); |
| 187 | |
| 188 | document.addEventListener( 'keydown', function ( event ) { |
| 189 | var active = document.activeElement; |
| 190 | var isBadge = active && active.matches && active.matches( '.wp2fa-premium-badge' ); |
| 191 | if ( ! isBadge || ( 'Enter' !== event.key && ' ' !== event.key ) ) { |
| 192 | return; |
| 193 | } |
| 194 | |
| 195 | event.preventDefault(); |
| 196 | openPremiumDialog( active ); |
| 197 | } ); |
| 198 | } )(); |
| 199 |