| 1 |
(function () { |
| 2 |
'use strict'; |
| 3 |
|
| 4 |
document.addEventListener( 'DOMContentLoaded', function () { |
| 5 |
if ( ! document.body.classList.contains( 'wpvr-tour-list' ) ) { |
| 6 |
return; |
| 7 |
} |
| 8 |
|
| 9 |
var wrap = document.querySelector( '#wpbody-content > .wrap' ); |
| 10 |
if ( ! wrap ) { |
| 11 |
return; |
| 12 |
} |
| 13 |
|
| 14 |
prepareHeader( wrap ); |
| 15 |
prepareToolbar( wrap ); |
| 16 |
prepareSearch( wrap ); |
| 17 |
prepareCheckboxes( wrap ); |
| 18 |
prepareEmptyState( wrap ); |
| 19 |
prepareShortcodeCopy(); |
| 20 |
revealCompletedLayout(); |
| 21 |
} ); |
| 22 |
|
| 23 |
function prepareShortcodeCopy() { |
| 24 |
document.addEventListener( 'click', function ( event ) { |
| 25 |
var copyButton = event.target.closest( '.wpvr-copy-shortcode-listing' ); |
| 26 |
|
| 27 |
if ( ! copyButton ) { |
| 28 |
return; |
| 29 |
} |
| 30 |
|
| 31 |
event.preventDefault(); |
| 32 |
event.stopPropagation(); |
| 33 |
event.stopImmediatePropagation(); |
| 34 |
|
| 35 |
copyShortcode( copyButton.getAttribute( 'data-shortcode' ) || '' ) |
| 36 |
.then( function () { |
| 37 |
showListingToast( 'success', 'Shortcode copied.' ); |
| 38 |
} ) |
| 39 |
.catch( function () { |
| 40 |
showListingToast( 'error', 'Unable to copy shortcode.' ); |
| 41 |
} ); |
| 42 |
}, true ); |
| 43 |
} |
| 44 |
|
| 45 |
function copyShortcode( shortcode ) { |
| 46 |
if ( navigator.clipboard && window.isSecureContext ) { |
| 47 |
return navigator.clipboard.writeText( shortcode ); |
| 48 |
} |
| 49 |
|
| 50 |
return new Promise( function ( resolve, reject ) { |
| 51 |
var textArea = document.createElement( 'textarea' ); |
| 52 |
|
| 53 |
textArea.value = shortcode; |
| 54 |
textArea.setAttribute( 'readonly', '' ); |
| 55 |
textArea.style.position = 'fixed'; |
| 56 |
textArea.style.top = '-9999px'; |
| 57 |
textArea.style.opacity = '0'; |
| 58 |
document.body.appendChild( textArea ); |
| 59 |
textArea.focus(); |
| 60 |
textArea.select(); |
| 61 |
textArea.setSelectionRange( 0, textArea.value.length ); |
| 62 |
|
| 63 |
try { |
| 64 |
if ( document.execCommand( 'copy' ) ) { |
| 65 |
resolve(); |
| 66 |
} else { |
| 67 |
reject( new Error( 'Copy command failed.' ) ); |
| 68 |
} |
| 69 |
} catch ( error ) { |
| 70 |
reject( error ); |
| 71 |
} finally { |
| 72 |
textArea.remove(); |
| 73 |
} |
| 74 |
} ); |
| 75 |
} |
| 76 |
|
| 77 |
function showListingToast( type, message ) { |
| 78 |
var currentToast = document.querySelector( '.wpvr-listing-toast' ); |
| 79 |
if ( currentToast ) { |
| 80 |
currentToast.remove(); |
| 81 |
} |
| 82 |
|
| 83 |
var toast = document.createElement( 'div' ); |
| 84 |
toast.className = 'wpvr-toast wpvr-toast--' + type + ' wpvr-listing-toast'; |
| 85 |
toast.setAttribute( 'role', 'status' ); |
| 86 |
toast.setAttribute( 'aria-live', 'polite' ); |
| 87 |
toast.textContent = message; |
| 88 |
document.body.appendChild( toast ); |
| 89 |
|
| 90 |
window.setTimeout( function () { |
| 91 |
if ( toast.parentNode ) { |
| 92 |
toast.remove(); |
| 93 |
} |
| 94 |
}, 3200 ); |
| 95 |
} |
| 96 |
|
| 97 |
function revealCompletedLayout() { |
| 98 |
window.requestAnimationFrame( function () { |
| 99 |
window.requestAnimationFrame( function () { |
| 100 |
document.body.classList.add( 'wpvr-tour-list-ready' ); |
| 101 |
} ); |
| 102 |
} ); |
| 103 |
} |
| 104 |
|
| 105 |
function prepareHeader( wrap ) { |
| 106 |
var heading = wrap.querySelector( 'h1.wp-heading-inline' ); |
| 107 |
if ( ! heading ) { |
| 108 |
return; |
| 109 |
} |
| 110 |
|
| 111 |
var header = document.createElement( 'div' ); |
| 112 |
header.className = 'wpvr-listing-header'; |
| 113 |
heading.parentNode.insertBefore( header, heading ); |
| 114 |
header.appendChild( heading ); |
| 115 |
|
| 116 |
Array.prototype.slice.call( wrap.children ).forEach( function ( child ) { |
| 117 |
if ( child.classList && child.classList.contains( 'page-title-action' ) ) { |
| 118 |
header.appendChild( child ); |
| 119 |
} |
| 120 |
} ); |
| 121 |
|
| 122 |
var notices = document.querySelectorAll( |
| 123 |
'#wpvr-promotional-banner, #wpvr-ui-mode-notice, #wpvr-license-fallback-notice, #wpvr-onboarding-notice, .wpvr-migration-notice' |
| 124 |
); |
| 125 |
if ( notices.length ) { |
| 126 |
var noticeArea = document.createElement( 'div' ); |
| 127 |
noticeArea.className = 'wpvr-listing-notices'; |
| 128 |
wrap.insertBefore( noticeArea, header ); |
| 129 |
Array.prototype.forEach.call( notices, function ( notice ) { |
| 130 |
noticeArea.appendChild( notice ); |
| 131 |
} ); |
| 132 |
} |
| 133 |
} |
| 134 |
|
| 135 |
function prepareToolbar( wrap ) { |
| 136 |
var topNav = wrap.querySelector( '#posts-filter .tablenav.top' ); |
| 137 |
var search = wrap.querySelector( '#posts-filter .search-box' ); |
| 138 |
if ( topNav && search ) { |
| 139 |
topNav.appendChild( search ); |
| 140 |
} |
| 141 |
} |
| 142 |
|
| 143 |
function prepareSearch( wrap ) { |
| 144 |
var input = wrap.querySelector( '#post-search-input' ); |
| 145 |
var submit = wrap.querySelector( '#search-submit' ); |
| 146 |
var form = wrap.querySelector( '#posts-filter' ); |
| 147 |
|
| 148 |
if ( input ) { |
| 149 |
input.placeholder = 'Search Tour'; |
| 150 |
input.setAttribute( 'aria-label', 'Search Tour' ); |
| 151 |
} |
| 152 |
|
| 153 |
if ( submit ) { |
| 154 |
submit.setAttribute( 'aria-label', 'Search Tour' ); |
| 155 |
} |
| 156 |
|
| 157 |
if ( input && form ) { |
| 158 |
bindLiveSearch( wrap, form, input ); |
| 159 |
} |
| 160 |
} |
| 161 |
|
| 162 |
function bindLiveSearch( wrap, form, input ) { |
| 163 |
var debounceTimer = null; |
| 164 |
var activeRequest = null; |
| 165 |
var liveStatus = document.createElement( 'span' ); |
| 166 |
|
| 167 |
liveStatus.className = 'screen-reader-text'; |
| 168 |
liveStatus.setAttribute( 'aria-live', 'polite' ); |
| 169 |
form.appendChild( liveStatus ); |
| 170 |
|
| 171 |
input.addEventListener( 'input', function ( event ) { |
| 172 |
if ( event.isComposing ) { |
| 173 |
return; |
| 174 |
} |
| 175 |
|
| 176 |
window.clearTimeout( debounceTimer ); |
| 177 |
debounceTimer = window.setTimeout( function () { |
| 178 |
requestSearchResults( wrap, form, input, liveStatus ); |
| 179 |
}, 350 ); |
| 180 |
} ); |
| 181 |
|
| 182 |
function requestSearchResults( listingWrap, listingForm, searchInput, status ) { |
| 183 |
var requestUrl = buildSearchUrl( listingForm, searchInput.value ); |
| 184 |
|
| 185 |
if ( activeRequest ) { |
| 186 |
activeRequest.abort(); |
| 187 |
} |
| 188 |
|
| 189 |
activeRequest = new AbortController(); |
| 190 |
listingForm.classList.add( 'wpvr-listing-searching' ); |
| 191 |
listingForm.setAttribute( 'aria-busy', 'true' ); |
| 192 |
|
| 193 |
window.fetch( requestUrl.toString(), { |
| 194 |
credentials: 'same-origin', |
| 195 |
headers: { |
| 196 |
'X-Requested-With': 'XMLHttpRequest', |
| 197 |
}, |
| 198 |
signal: activeRequest.signal, |
| 199 |
} ) |
| 200 |
.then( function ( response ) { |
| 201 |
if ( ! response.ok ) { |
| 202 |
throw new Error( 'Search request failed.' ); |
| 203 |
} |
| 204 |
|
| 205 |
return response.text(); |
| 206 |
} ) |
| 207 |
.then( function ( html ) { |
| 208 |
var parsedDocument = new window.DOMParser().parseFromString( html, 'text/html' ); |
| 209 |
var nextTable = parsedDocument.querySelector( 'table.wp-list-table' ); |
| 210 |
var nextBottomNav = parsedDocument.querySelector( '#posts-filter .tablenav.bottom' ); |
| 211 |
var currentTable = listingForm.querySelector( 'table.wp-list-table' ); |
| 212 |
var currentBottomNav = listingForm.querySelector( '.tablenav.bottom' ); |
| 213 |
var hasResults = ! nextTable || ! nextTable.querySelector( 'tbody .no-items' ); |
| 214 |
|
| 215 |
if ( ! nextTable || ! currentTable ) { |
| 216 |
throw new Error( 'Search results were not found.' ); |
| 217 |
} |
| 218 |
|
| 219 |
currentTable.replaceWith( nextTable ); |
| 220 |
if ( hasResults && nextBottomNav ) { |
| 221 |
if ( currentBottomNav ) { |
| 222 |
currentBottomNav.replaceWith( nextBottomNav ); |
| 223 |
} else { |
| 224 |
nextTable.insertAdjacentElement( 'afterend', nextBottomNav ); |
| 225 |
} |
| 226 |
} else if ( currentBottomNav ) { |
| 227 |
currentBottomNav.remove(); |
| 228 |
} |
| 229 |
|
| 230 |
window.history.replaceState( {}, '', requestUrl.toString() ); |
| 231 |
prepareCheckboxes( listingWrap ); |
| 232 |
prepareEmptyState( listingWrap ); |
| 233 |
status.textContent = 'Search results updated.'; |
| 234 |
} ) |
| 235 |
.catch( function ( error ) { |
| 236 |
if ( error.name !== 'AbortError' ) { |
| 237 |
status.textContent = 'Unable to update search results.'; |
| 238 |
} |
| 239 |
} ) |
| 240 |
.finally( function () { |
| 241 |
listingForm.classList.remove( 'wpvr-listing-searching' ); |
| 242 |
listingForm.removeAttribute( 'aria-busy' ); |
| 243 |
} ); |
| 244 |
} |
| 245 |
} |
| 246 |
|
| 247 |
function buildSearchUrl( form, searchTerm ) { |
| 248 |
var url = new URL( window.location.href ); |
| 249 |
var formData = new window.FormData( form ); |
| 250 |
var ignoredFields = [ 'action', 'action2', 'post[]', '_wpnonce', '_wp_http_referer' ]; |
| 251 |
|
| 252 |
formData.forEach( function ( value, key ) { |
| 253 |
if ( ignoredFields.indexOf( key ) === -1 && typeof value === 'string' ) { |
| 254 |
url.searchParams.set( key, value ); |
| 255 |
} |
| 256 |
} ); |
| 257 |
|
| 258 |
url.searchParams.set( 's', searchTerm ); |
| 259 |
url.searchParams.delete( 'paged' ); |
| 260 |
|
| 261 |
return url; |
| 262 |
} |
| 263 |
|
| 264 |
function prepareCheckboxes( wrap ) { |
| 265 |
var table = wrap.querySelector( 'table.wp-list-table' ); |
| 266 |
if ( ! table ) { |
| 267 |
return; |
| 268 |
} |
| 269 |
|
| 270 |
var selectAll = table.querySelectorAll( |
| 271 |
'thead .check-column input[type="checkbox"], tfoot .check-column input[type="checkbox"]' |
| 272 |
); |
| 273 |
|
| 274 |
function rowCheckboxes() { |
| 275 |
return table.querySelectorAll( 'tbody .check-column input[type="checkbox"][name="post[]"]' ); |
| 276 |
} |
| 277 |
|
| 278 |
function updateSelectAll() { |
| 279 |
var rows = rowCheckboxes(); |
| 280 |
var checked = table.querySelectorAll( |
| 281 |
'tbody .check-column input[type="checkbox"][name="post[]"]:checked' |
| 282 |
).length; |
| 283 |
|
| 284 |
Array.prototype.forEach.call( selectAll, function ( checkbox ) { |
| 285 |
checkbox.checked = rows.length > 0 && checked === rows.length; |
| 286 |
checkbox.indeterminate = checked > 0 && checked < rows.length; |
| 287 |
} ); |
| 288 |
} |
| 289 |
|
| 290 |
Array.prototype.forEach.call( selectAll, function ( checkbox ) { |
| 291 |
checkbox.addEventListener( 'change', function () { |
| 292 |
var shouldCheck = checkbox.checked; |
| 293 |
Array.prototype.forEach.call( rowCheckboxes(), function ( rowCheckbox ) { |
| 294 |
rowCheckbox.checked = shouldCheck; |
| 295 |
} ); |
| 296 |
updateSelectAll(); |
| 297 |
} ); |
| 298 |
} ); |
| 299 |
|
| 300 |
table.addEventListener( 'change', function ( event ) { |
| 301 |
if ( |
| 302 |
event.target.matches( |
| 303 |
'tbody .check-column input[type="checkbox"][name="post[]"]' |
| 304 |
) |
| 305 |
) { |
| 306 |
updateSelectAll(); |
| 307 |
} |
| 308 |
} ); |
| 309 |
|
| 310 |
updateSelectAll(); |
| 311 |
} |
| 312 |
|
| 313 |
function prepareEmptyState( wrap ) { |
| 314 |
var emptyCell = wrap.querySelector( 'table.wp-list-table tbody .no-items td' ); |
| 315 |
if ( ! emptyCell ) { |
| 316 |
return; |
| 317 |
} |
| 318 |
|
| 319 |
var emptyState = document.createElement( 'div' ); |
| 320 |
emptyState.className = 'wpvr-listing-empty'; |
| 321 |
emptyState.innerHTML = |
| 322 |
'<svg class="wpvr-listing-empty__icon" aria-hidden="true" width="65" height="52" viewBox="0 0 65 52" fill="none" xmlns="http://www.w3.org/2000/svg">' + |
| 323 |
'<path d="M0.5 3.18066C0.500022 1.22699 2.42411 -0.0335511 3.95801 0.733398L3.99023 0.749023L4.02344 0.759766C9.84718 2.70101 19.5527 5.28906 32.167 5.28906C44.7758 5.28902 53.8382 3.02515 60.3164 0.757812L60.3467 0.74707L60.375 0.733398C61.9089 -0.0335512 63.833 1.22699 63.833 3.18066V48.2139C63.833 50.1557 62.202 51.4916 60.2959 50.9512C53.831 48.6897 44.7724 46.1055 32.167 46.1055C19.5455 46.1055 10.8021 48.6965 4.02344 50.9561C2.43759 51.4847 0.5 50.146 0.5 48.2139V3.18066Z" fill="white" stroke="black"/>' + |
| 324 |
'<path d="M30.8906 18.7724C30.8906 18.1456 30.7687 17.5251 30.5318 16.9461C30.2949 16.367 29.9477 15.8409 29.5099 15.3978C29.0722 14.9546 28.5525 14.6031 27.9806 14.3633C27.4087 14.1234 26.7957 14 26.1767 14C25.5576 14 24.9447 14.1234 24.3727 14.3633C23.8008 14.6031 23.2811 14.9546 22.8434 15.3978C22.4057 15.8409 22.0585 16.367 21.8216 16.9461C21.5847 17.5251 21.4627 18.1456 21.4627 18.7724C21.4627 20.0381 21.9594 21.2519 22.8434 22.1469C23.7274 23.0419 24.9265 23.5447 26.1767 23.5447C27.4269 23.5447 28.6259 23.0419 29.5099 22.1469C30.394 21.2519 30.8906 20.0381 30.8906 18.7724ZM35.6093 21.3304L30.3143 29.6677L27.4436 25.0158L17.9273 37.8618H46L35.6093 21.3304Z" fill="black"/>' + |
| 325 |
'</svg>' + |
| 326 |
'<p>No tour created.</p>' + |
| 327 |
'<button type="button" class="wpvr-listing-empty__button">Add Your First Tour</button>'; |
| 328 |
|
| 329 |
emptyCell.textContent = ''; |
| 330 |
emptyCell.appendChild( emptyState ); |
| 331 |
|
| 332 |
emptyState.querySelector( 'button' ).addEventListener( 'click', function () { |
| 333 |
var addButton = wrap.querySelector( |
| 334 |
'.wpvr-listing-header .page-title-action:not(.wpvr-import-button)' |
| 335 |
); |
| 336 |
if ( addButton ) { |
| 337 |
addButton.click(); |
| 338 |
} |
| 339 |
} ); |
| 340 |
} |
| 341 |
} )(); |
| 342 |
|