/** * PressThis App * */ ( function( $, window ) { var PressThis = function() { var editor, $mediaList, $mediaThumbWrap, saveAlert = false, textarea = document.createElement( 'textarea' ), sidebarIsOpen = false, settings = window.wpPressThisConfig || {}, data = window.wpPressThisData || {}, smallestWidth = 128, hasSetFocus = false, catsCache = [], isOffScreen = 'is-off-screen', isHidden = 'is-hidden', offscreenHidden = isOffScreen + ' ' + isHidden, transitionEndEvent = ( function() { var style = document.documentElement.style; if ( typeof style.transition !== 'undefined' ) { return 'transitionend'; } if ( typeof style.WebkitTransition !== 'undefined' ) { return 'webkitTransitionEnd'; } return false; }() ); /* *************************************************************** * HELPER FUNCTIONS *************************************************************** */ /** * Emulates our PHP __() gettext function, powered by the strings exported in pressThisL10n. * * @param key string Key of the string to be translated, as found in pressThisL10n. * @returns string Original or translated string, or empty string if no key. */ function __( key ) { if ( key && window.pressThisL10n ) { return window.pressThisL10n[key] || key; } return key || ''; } /** * Strips HTML tags * * @param string string Text to have the HTML tags striped out of. * @returns string Stripped text. */ function stripTags( string ) { string = string || ''; return string .replace( /|$)/g, '' ) .replace( /<(script|style)[^>]*>[\s\S]*?(<\/\1>|$)/ig, '' ) .replace( /<\/?[a-z][\s\S]*?(>|$)/ig, '' ); } /** * Strip HTML tags and convert HTML entities. * * @param text string Text. * @returns string Sanitized text. */ function sanitizeText( text ) { var _text = stripTags( text ); try { textarea.innerHTML = _text; _text = stripTags( textarea.value ); } catch ( er ) {} return _text; } /** * Allow only HTTP or protocol relative URLs. * * @param url string The URL. * @returns string Processed URL. */ function checkUrl( url ) { url = $.trim( url || '' ); if ( /^(?:https?:)?\/\//.test( url ) ) { url = stripTags( url ); return url.replace( /["\\]+/g, '' ); } return ''; } /** * Show UX spinner */ function showSpinner() { $( '.spinner' ).addClass( 'is-active' ); $( '.post-actions button' ).attr( 'disabled', 'disabled' ); } /** * Hide UX spinner */ function hideSpinner() { $( '.spinner' ).removeClass( 'is-active' ); $( '.post-actions button' ).removeAttr( 'disabled' ); } /** * Replace emoji images with chars and sanitize the text content. */ function getTitleText() { var $element = $( '#title-container' ); $element.find( 'img.emoji' ).each( function() { var $image = $( this ); $image.replaceWith( $( '' ).text( $image.attr( 'alt' ) ) ); }); return sanitizeText( $element.text() ); } /** * Prepare the form data for saving. */ function prepareFormData() { var $form = $( '#pressthis-form' ), $input = $( '' ); editor && editor.save(); $( '#post_title' ).val( getTitleText() ); // Make sure to flush out the tags with tagBox before saving if ( window.tagBox ) { $( 'div.tagsdiv' ).each( function() { window.tagBox.flushTags( this, false, 1 ); } ); } // Get selected categories $( '.categories-select .category' ).each( function( i, element ) { var $cat = $( element ); if ( $cat.hasClass( 'selected' ) ) { // Have to append a node as we submit the actual form on preview $form.append( $input.clone().val( $cat.attr( 'data-term-id' ) || '' ) ); } }); } /** * Submit the post form via AJAX, and redirect to the proper screen if published vs saved as a draft. * * @param action string publish|draft */ function submitPost( action ) { var data; saveAlert = false; showSpinner(); if ( 'publish' === action ) { $( '#post_status' ).val( 'publish' ); } prepareFormData(); data = $( '#pressthis-form' ).serialize(); $.ajax( { type: 'post', url: window.ajaxurl, data: data }).always( function() { hideSpinner(); clearNotices(); }).done( function( response ) { if ( ! response.success ) { renderError( response.data.errorMessage ); } else if ( response.data.redirect ) { if ( window.opener && settings.redirInParent ) { try { window.opener.location.href = response.data.redirect; } catch( er ) {} window.self.close(); } else { window.location.href = response.data.redirect; } } else if ( response.data.postSaved ) { // consider showing "Saved" message } }).fail( function() { renderError( __( 'serverError' ) ); }); } /** * Inserts the media a user has selected from the presented list inside the editor, as an image or embed, based on type * * @param type string img|embed * @param src string Source URL * @param link string Optional destination link, for images (defaults to src) */ function insertSelectedMedia( $element ) { var src, link, newContent = ''; if ( ! editor ) { return; } src = checkUrl( $element.attr( 'data-wp-src' ) || '' ); link = checkUrl( data.u ); if ( $element.hasClass( 'is-image' ) ) { if ( ! link ) { link = src; } newContent = ''; } else { newContent = '[embed]' + src + '[/embed]'; } if ( ! hasSetFocus ) { editor.setContent( '

' + newContent + '

' + editor.getContent() ); } else { editor.execCommand( 'mceInsertContent', false, newContent ); } } /** * Save a new user-generated category via AJAX */ function saveNewCategory() { var data, name = $( '#new-category' ).val(); if ( ! name ) { return; } data = { action: 'press-this-add-category', post_id: $( '#post_ID' ).val() || 0, name: name, new_cat_nonce: $( '#_ajax_nonce-add-category' ).val() || '', parent: $( '#new-category-parent' ).val() || 0 }; $.post( window.ajaxurl, data, function( response ) { if ( ! response.success ) { renderError( response.data.errorMessage ); } else { var $parent, $ul, $wrap = $( 'ul.categories-select' ); $.each( response.data, function( i, newCat ) { var $node = $( '
  • ' ).append( $( '