File: /home/pokaorgani/public_html/wp-content/plugins/so-widgets-bundle/base/inc/fields/js/media-field.js
/* global jQuery, soWidgets */
( function( $ ) {
const setupMediaField = function( e ) {
const $field = $( this );
const $media = $field.find( '> .media-field-wrapper' );
const $inputField = $field.find( '.siteorigin-widget-input' ).not( '.media-fallback-external' );
const $externalField = $field.find( '.media-fallback-external' );
if ( $field.attr( 'data-initialized' ) ) {
return;
}
$field.attr( 'data-initialized', true );
// Handle the media uploader.
$media.find( '.media-upload-button' ).on( 'click', function( e ) {
e.preventDefault();
if ( typeof window.top.wp.media === 'undefined' ) {
return;
}
const $$ = $( this );
let frame = $( this ).data( 'frame' );
// If the media frame already exists, reopen it.
if ( frame ) {
frame.open();
return false;
}
// Create the media frame.
frame = window.top.wp.media( {
// Set the title of the modal.
title: $$.data( 'choose' ),
// Tell the modal to show only images.
library: {
type: $$.data( 'library' ).split( ',' ).map( function( v ) {
return v.trim();
} )
},
// Customize the submit button.
button: {
// Set the text of the button.
text: $$.data( 'update' ),
// Tell the button not to close the modal, since we're
// going to refresh the page when the image is selected.
close: false
}
} );
// If there's a selected image, highlight it.
frame.on( 'open', function() {
const selection = frame.state().get( 'selection' );
const selectedImage = $field.find( '.siteorigin-widget-input[type="hidden"]' ).val();
if ( selectedImage ) {
selection.add( window.top.wp.media.attachment( selectedImage ) );
}
} );
// Store the frame.
$$.data( 'frame', frame );
// When an image is selected, run a callback.
frame.on( 'select', function() {
// Grab the selected attachment.
const attachment = frame.state().get( 'selection' ).first().attributes;
$field.find( '.current .thumbnail' ).attr( 'title', attachment.title );
$field.find( '.current .title' ).html( attachment.title );
$inputField.val( attachment.id );
$inputField.trigger( 'change', { silent: true } );
const $thumbnail = $field.find( '.current .thumbnail' );
if ( typeof attachment.sizes !== 'undefined' ) {
if ( typeof attachment.sizes.thumbnail !== 'undefined' ) {
$thumbnail.attr( 'src', attachment.sizes.thumbnail.url ).fadeIn();
} else {
$thumbnail.attr( 'src', attachment.sizes.full.url ).fadeIn();
}
}
else{
$thumbnail.attr( 'src', attachment.icon ).fadeIn();
}
$field.find( '.media-remove-button' ).removeClass( 'remove-hide' ).attr( 'tabindex', 0 );
frame.close();
} );
// Finally, open the modal.
frame.open();
});
$field.find( 'a.media-remove-button' )
.on( 'click', function( e ) {
e.preventDefault();
$inputField.val( '' );
$field.find( '.current .title' ).empty();
$inputField.trigger( 'change', { silent: true } );
// Clear the src attribute first, then hide the thumbnail.
const $thumbnail = $field.find( '.current .thumbnail' );
$thumbnail.attr( 'src', '' );
$thumbnail.fadeOut( 'fast' );
$( this ).addClass( 'remove-hide' ).attr( 'tabindex', -1 );
} );
let dialog;
let activeImportField = null;
const reflowDialog = function() {
if ( ! dialog ) {
return;
}
const results = dialog.find( '.so-widgets-image-results' );
if ( results.length === 0 ) {
return;
}
const width = results.width(),
perRow = Math.floor( width / 276 ),
spare = ( width - perRow * 276 ),
resultWidth = spare / perRow + 260;
results.find( '.so-widgets-result-image' ).css( {
'width' : resultWidth + 'px',
'height' : resultWidth / 1.4 + 'px',
} );
};
$( window ).on( 'resize', reflowDialog );
const setupDialog = function( $currentField ) {
if ( ! dialog ) {
// Create the dialog.
dialog = $( $('#so-widgets-bundle-tpl-image-search-dialog').html().trim() ).appendTo( window.top.document.body );
dialog.find( '.close' ).on( 'click keyup', function( e ) {
if ( e.type == 'keyup' && ! window.sowbForms.isEnter( e ) ) {
return;
}
dialog.hide();
// Only clear the importing class when dialog is manually closed, not during import.
if ( ! dialog.hasClass( 'so-widgets-importing' ) ) {
$( '.so-importing-image' ).removeClass( 'so-importing-image' );
activeImportField = null;
}
} );
const results = dialog.find( '.so-widgets-image-results' );
const fetchImages = function( query, page ) {
dialog.find( '.so-widgets-results-loading' ).fadeIn( 'fast' );
dialog.find( '.so-widgets-results-loading strong' ).html(
dialog.find( '.so-widgets-results-loading strong' ).data( 'loading' )
);
dialog.find( '.so-widgets-results-more' ).hide();
$.get(
ajaxurl,
{
'action' : 'so_widgets_image_search',
'q' : query,
'page' : page,
'_sononce' : dialog.find( 'input[name="_sononce"]' ).val()
},
function( response ) {
if ( response.error ) {
alert( response.message );
return;
}
results.removeClass( 'so-loading' );
$.each( response.items, function( i, r ) {
const result = $( $( '#so-widgets-bundle-tpl-image-search-result' ).html().trim() )
.appendTo( results )
.addClass( 'source-' + r.source );
const img = result.find( '.so-widgets-result-image' );
// Preload the image.
img.css( 'background-image', 'url(' + r.thumbnail + ')' );
img.data( 'thumbnail', r.thumbnail );
img.data( 'preview', r.preview );
if ( r.url ) {
img.attr( {
'href': r.url,
'target': '_blank'
} );
}
if ( r.full_url ) {
img.data( {
'full_url' : r.full_url,
'import_signature' : r.import_signature
} );
img.attr( 'href', r.full_url );
}
if ( r.source === 'shutterstock' ) {
img.append( $('#so-widgets-bundle-tpl-image-search-result-sponsored').html() );
}
} );
if ( page === 1 ) {
dialog.find( '#so-widgets-image-search-suggestions ul' ).empty();
$.each( response.keywords, function( i, r ) {
dialog.find( '#so-widgets-image-search-suggestions' ).show();
dialog.find( '#so-widgets-image-search-suggestions ul' ).append(
$( '<li></li>' ).append( $( '<a href="#"></a>' ).html( r ).data( 'keyword', r ) )
);
} );
}
dialog.find( '.so-widgets-results-loading' ).fadeOut( 'fast' );
reflowDialog();
dialog
.find( '.so-widgets-results-more' ).show()
.find( 'button' ).data( { 'query': query, 'page' : page + 1 } );
}
);
};
// Setup the search.
dialog.find( '#so-widgets-image-search-form' ).on( 'submit', function( e ) {
e.preventDefault();
// Perform the search.
const q = dialog.find( '.so-widgets-search-input' ).val();
results.empty();
if ( q !== '' ) {
// Send the query to the server.
fetchImages( q, 1 );
}
} );
// Clicking on the related search buttons.
dialog.on( 'click', '.so-keywords-list a', function( e ) {
e.preventDefault();
const $$ = $( this ).trigger( 'blur' );
dialog.find('.so-widgets-search-input').val( $$.data( 'keyword' ) );
dialog.find( '#so-widgets-image-search-form' ).trigger( 'submit' );
} );
// Clicking on the more button.
dialog.find( '.so-widgets-results-more button' ).on( 'click', function() {
const $$ = $( this );
fetchImages( $$.data( 'query' ), $$.data( 'page' ) );
} );
let hoverTimeout;
// Clicking on an image to import it.
dialog.on( 'click', '.so-widgets-result-image', function( e ) {
const $$ = $( this );
if ( ! $$.data( 'full_url' ) ) {
return;
}
e.preventDefault();
if ( confirm( dialog.data( 'confirm-import' ) ) ) {
dialog.addClass( 'so-widgets-importing' );
const postId = $( '#post_ID' ).val();
if ( postId === null ) {
postId = '';
}
// Send the message to import the URL.
$.get(
ajaxurl,
{
'action' : 'so_widgets_image_import',
'full_url' : $$.data( 'full_url' ),
'import_signature' : $$.data( 'import_signature' ),
'post_id' : postId,
'_sononce' : dialog.find( 'input[name="_sononce"]' ).val()
},
function( response ) {
if ( response.error === false ) {
// This was a success.
const $currentField = activeImportField;
if ( $currentField && $currentField.length ) {
// Update field.
const $inputField = $currentField.find( '.siteorigin-widget-input' ).not( '.media-fallback-external' );
$inputField.val( response.attachment_id );
$inputField.trigger( 'change' );
// Update the thumbnail.
const $thumbnail = $currentField.find( '.current .thumbnail' );
$thumbnail.attr( 'src', response.thumb );
$thumbnail.fadeIn();
$currentField.find( '.media-remove-button' )
.removeClass( 'remove-hide' )
.attr( 'tabindex', 0 );
$currentField.removeClass( 'so-importing-image' );
activeImportField = null;
}
dialog.hide();
} else {
alert( response.message );
dialog.find( '.so-widgets-results-loading' ).hide();
}
// Clean up dialog state after import (success or failure).
dialog.removeClass( 'so-widgets-importing' );
dialog.find( '#so-widgets-image-search-frame' ).removeClass( 'so-widgets-importing' );
}
);
// Clear the dialog.
dialog.find( '.so-widgets-results-loading' ).fadeIn( 'fast' );
dialog.find( '.so-widgets-results-loading strong' ).html(
dialog.find( '.so-widgets-results-loading strong' ).data( 'importing' )
);
dialog.find( '.so-widgets-results-more' ).hide();
dialog.find( '#so-widgets-image-search-frame' ).addClass( 'so-widgets-importing' );
}
} );
// Hovering over an image to preview it.
const previewWindow = dialog.find( '.so-widgets-preview-window' );
dialog
.on( 'mouseenter', '.so-widgets-result-image', function() {
const $$ = $( this ),
preview = $$.data( 'preview' );
clearTimeout( hoverTimeout );
hoverTimeout = setTimeout( function() {
// Scale the preview sizes.
let scalePreviewX = 1, scalePreviewY = 1;
if ( preview[1] > $( window ).outerWidth() * 0.33 ) {
scalePreviewX = $( window ).outerWidth() * 0.33 / preview[1];
}
if ( preview[2] > $( window ).outerHeight() * 0.5 ) {
scalePreviewY = $( window ).outerHeight() * 0.5 / preview[2];
}
let scalePreview = Math.min( scalePreviewX, scalePreviewY );
// Never upscale.
if ( scalePreview > 1 ) {
scalePreview = 1;
}
previewWindow.show()
.find( '.so-widgets-preview-window-inside' )
.css( {
'background-image' : 'url(' + $$.data( 'thumbnail' ) + ')',
'width' : preview[1] * scalePreview + 'px',
'height' : preview[2] * scalePreview + 'px',
} )
.append( $( '<img />' ).attr( 'src', preview[0] ) );
dialog.trigger( 'mousemove' );
}, 1000 );
} )
.on( 'mouseleave', '.so-widgets-result-image', function() {
previewWindow.hide().find( 'img' ).remove();
clearTimeout( hoverTimeout );
} );
let lastX, lastY;
dialog.on( 'mousemove', function( e ) {
if ( e.clientX ) {
lastX = e.clientX;
}
if ( e.clientY ) {
lastY = e.clientY;
}
if ( previewWindow.is( ':visible' ) ) {
const ph = previewWindow.outerHeight(),
pw = previewWindow.outerWidth(),
wh = $( window ).outerHeight(),
ww = $( window ).outerWidth();
// Calculate the top position.
let top = lastY - ph / 2;
top = Math.max( top, 10 );
top = Math.min( top, wh - 10 - ph );
// Calculate the left position.
const left = ( lastX < ww / 2 ) ? lastX + 15 : lastX - 15 - pw;
// Figure out where the preview needs to go.
previewWindow.css( {
'top': top + 'px',
'left': left + 'px',
} );
}
} );
}
dialog.show();
dialog.find( '.so-widgets-search-input' ).trigger( 'focus' );
};
// Handle displaying the image search dialog.
$media.find( '.find-image-button' ).on( 'click', function( e ) {
e.preventDefault();
// Clear any existing importing class and add it to current field.
$( '.so-importing-image' ).removeClass( 'so-importing-image' );
$field.addClass( 'so-importing-image' );
// Store direct reference to the current field for later use.
activeImportField = $field;
setupDialog( $field );
} );
$inputField.on( 'change', function( event, data ) {
if ( ! ( data && data.silent ) ) {
const newVal = $inputField.val();
if ( newVal) {
const $thumbnail = $field.find( '.current .thumbnail' );
const attachment = window.top.wp.media.attachment( newVal );
attachment.fetch().done( function() {
if ( attachment.has( 'sizes' ) ) {
const sizes = attachment.get( 'sizes' );
if ( typeof sizes.thumbnail !== 'undefined' ) {
$thumbnail.attr( 'src', sizes.thumbnail.url ).fadeIn();
}
else {
$thumbnail.attr( 'src', sizes.full.url ).fadeIn();
}
}
else {
$thumbnail.attr( 'src', attachment.get('icon') ).fadeIn();
}
$field.find( '.media-remove-button' ).removeClass( 'remove-hide' ).attr( 'tabindex', 0 );
} );
} else {
$field.find( 'a.media-remove-button' ).trigger( 'click' );
}
}
if ( typeof data == 'undefined' || ! data.external ) {
$externalField.trigger( 'change', { internal: true } );
}
} );
// Ensure both state both the media field and external field are kept up to date.
$externalField.on( 'change', function( event, data ) {
if (
// Prevent direct input on external triggering the internal field.
! $( event.currentTarget ).hasClass( 'media-fallback-external' ) &&
(
typeof data == 'undefined' ||
! data.internal
)
) {
$inputField.trigger( 'change', { external: true } );
}
} );
};
// If the current page isn't the site editor, set up the Media field now.
if (
window.top === window.self &&
(
typeof pagenow === 'string' &&
pagenow !== 'site-editor'
)
) {
$( document ).on( 'sowsetupformfield', '.siteorigin-widget-field-type-media', setupMediaField );
}
// Add support for the Site Editor.
window.addEventListener( 'message', function( e ) {
if ( e.data && e.data.action === 'sowbBlockFormInit' ) {
$( '.siteorigin-widget-field-type-media' ).each( function() {
if ( $( this ).attr( 'data-initialized' ) ) {
return;
}
setupMediaField.call( this );
} );
}
} );
} )( jQuery );