Вход Регистрация
Файл: wordpress/wp-admin/js/press-this.js
Строк: 846
<?php
/**
 * PressThis App
 *
 */
( function( $, window ) {
    var 
PressThis = function() {
        var 
editor$mediaList$mediaThumbWrap,
            
saveAlert             false,
            
editLinkVisible       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( /<!--[sS]*?(-->|$)/g'' )
                .
replace( /<(script|style)[^>]*>[sS]*?(</1>|$)/ig'' )
                .
replace( /</?[a-z][sS]*?(>|$)/ig'' );
        }

        
/**
         * Strip HTML tags and convert HTML entities.
         *
         * @param text string Text.
         * @returns string Sanitized text.
         */
        
function sanitizeTexttext ) {
            var 
_text stripTagstext );

            try {
                
textarea.innerHTML _text;
                
_text stripTagstextarea.value );
            } catch ( 
er ) {}

            return 
_text;
        }

        
/**
         * Allow only HTTP or protocol relative URLs.
         *
         * @param url string The URL.
         * @returns string Processed URL.
         */
        
function checkUrlurl ) {
            
url = $.trimurl || '' );

            if ( /^(?:
https?:)?///.test( url ) ) {
                
url stripTagsurl );
                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( $( '<span>' ).text( $image.attr( 'alt' ) ) );
            });

            return sanitizeText( 
$element.text() );
        }

        /**
         * Prepare the form data for saving.
         */
        function prepareFormData() {
            var 
$form = $( '#pressthis-form' ),
                
$input = $( '<input type="hidden" name="post_category[]" value="">' );

            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,
                keepFocus = $( document.activeElement ).hasClass( 'draft-button' );

            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 ) {
                var 
$link$button;

                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 ) {
                    
$link = $( '.edit-post-link' );
                    
$button = $( '.draft-button' );
                    editLinkVisible = true;

                    
$button.fadeOut( 200, function() {
                        
$button.removeClass( 'is-saving' );
                        
$link.fadeIn( 200, function() {
                            var active = document.activeElement;
                            // Different browsers move the focus to different places when the button is disabled.
                            if ( keepFocus && ( active === 
$button[0] || $( active ).hasClass( 'post-actions' ) || active.nodeName === 'BODY' ) ) {
                                
$link.focus();
                            }
                        });
                    });
                }
            }).fail( function() {
                renderError( __( 'serverError' ) );
            });
        }

        function resetDraftButton() {
            if ( editLinkVisible ) {
                editLinkVisible = false;

                $( '.edit-post-link' ).fadeOut( 200, function() {
                    $( '.draft-button' ).removeClass( 'is-saving' ).fadeIn( 200 );
                });
            }
        }

        /**
         * 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 = '<a href="' + link + '"><img class="
alignnone size-full" src="' + src + '" /></a>';
            } else {
                newContent = '[embed]' + src + '[/embed]';
            }

            if ( ! hasSetFocus ) {
                editor.setContent( '<p>' + newContent + '</p>' + 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 = $( '<li>' ).append( $( '<div class="category selected" tabindex="0" role="checkbox" aria-checked="true">' )
                            .attr( 'data-term-id', newCat.term_id )
                            .text( newCat.name ) );

                        if ( newCat.parent ) {
                            if ( ! 
$ul || ! $ul.length ) {
                                
$parent = $wrap.find( 'div[data-term-id="' + newCat.parent + '"]' ).parent();
                                
$ul = $parent.find( 'ul.children:first' );

                                if ( ! 
$ul.length ) {
                                    
$ul = $( '<ul class="children">' ).appendTo( $parent );
                                }
                            }

                            
$ul.prepend( $node );
                        } else {
                            
$wrap.prepend( $node );
                        }

                        
$node.focus();
                    } );

                    refreshCatsCache();
                }
            } );
        }

        /* ***************************************************************
         * RENDERING FUNCTIONS
         *************************************************************** */

        /**
         * Hide the form letting users enter a URL to be scanned, if a URL was already passed.
         */
        function renderToolsVisibility() {
            if ( data.hasData ) {
                $( '#scanbar' ).hide();
            }
        }

        /**
         * Render error notice
         *
         * @param msg string Notice/error message
         * @param error string error|notice CSS class for display
         */
        function renderNotice( msg, error ) {
            var 
$alerts = $( '.editor-wrapper div.alerts' ),
                className = error ? 'is-error' : 'is-notice';

            
$alerts.append( $( '<p class="alert ' + className + '">' ).text( msg ) );
        }

        /**
         * Render error notice
         *
         * @param msg string Error message
         */
        function renderError( msg ) {
            renderNotice( msg, true );
        }

        function clearNotices() {
            $( 'div.alerts' ).empty();
        }

        /**
         * Render notices on page load, if any already
         */
        function renderStartupNotices() {
            // Render errors sent in the data, if any
            if ( data.errors ) {
                $.each( data.errors, function( i, msg ) {
                    renderError( msg );
                } );
            }
        }

        /**
         * Add an image to the list of found images.
         */
        function addImg( src, displaySrc, i ) {
            var 
$element = $mediaThumbWrap.clone().addClass( 'is-image' );

            
$element.attr( 'data-wp-src', src ).css( 'background-image', 'url(' + displaySrc + ')' )
                .find( 'span' ).text( __( 'suggestedImgAlt' ).replace( '%d', i + 1 ) );

            
$mediaList.append( $element );
        }

        /**
         * Render the detected images and embed for selection, if any
         */
        function renderDetectedMedia() {
            var found = 0;

            
$mediaList = $( 'ul.media-list' );
            
$mediaThumbWrap = $( '<li class="suggested-media-thumbnail" tabindex="0"><span class="screen-reader-text"></span></li>' );

            if ( data._embeds ) {
                $.each( data._embeds, function ( i, src ) {
                    var displaySrc = '',
                        cssClass = '',
                        
$element = $mediaThumbWrap.clone().addClass( 'is-embed' );

                    src = checkUrl( src );

                    if ( src.indexOf( 'youtube.com/' ) > -1 ) {
                        displaySrc = 'https://i.ytimg.com/vi/' + src.replace( /.+v=([^&]+).*/, '$1' ) + '/hqdefault.jpg';
                        cssClass += ' is-video';
                    } else if ( src.indexOf( 'youtu.be/' ) > -1 ) {
                        displaySrc = 'https://i.ytimg.com/vi/' + src.replace( //([^/])$/, '$1' ) + '/hqdefault.jpg';
                        cssClass += ' is-video';
                    } else if ( src.indexOf( 'dailymotion.com' ) > -1 ) {
                        displaySrc = src.replace( '/video/', '/thumbnail/video/' );
                        cssClass += ' is-video';
                    } else if ( src.indexOf( 'soundcloud.com' ) > -1 ) {
                        cssClass += ' is-audio';
                    } else if ( src.indexOf( 'twitter.com' ) > -1 ) {
                        cssClass += ' is-tweet';
                    } else {
                        cssClass += ' is-video';
                    }

                    
$element.attr( 'data-wp-src', src ).find( 'span' ).text( __( 'suggestedEmbedAlt' ).replace( '%d', i + 1 ) );

                    if ( displaySrc ) {
                        
$element.css( 'background-image', 'url(' + displaySrc + ')' );
                    }

                    
$mediaList.append( $element );
                    found++;
                } );
            }

            if ( data._images ) {
                $.each( data._images, function( i, src ) {
                    var displaySrc, img = new Image();

                    src = checkUrl( src );
                    displaySrc = src.replace( /^(http[^?]+)(?.*)?$/, '$1' );

                    if ( src.indexOf( 'files.wordpress.com/' ) > -1 ) {
                        displaySrc = displaySrc.replace( /?.*$/, '' ) + '?w=' + smallestWidth;
                    } else if ( src.indexOf( 'gravatar.com/' ) > -1 ) {
                        displaySrc = displaySrc.replace( /?.*$/, '' ) + '?s=' + smallestWidth;
                    } else {
                        displaySrc = src;
                    }

                    img.onload = function() {
                        if ( ( img.width && img.width < 256 ) ||
                            ( img.height && img.height < 128 ) ) {

                            return;
                        }

                        addImg( src, displaySrc, i );
                    };

                    img.src = src;
                    found++;
                } );
            }

            if ( found ) {
                $( '.media-list-container' ).addClass( 'has-media' );
            }
        }

        /* ***************************************************************
         * MONITORING FUNCTIONS
         *************************************************************** */

        /**
         * Interactive navigation behavior for the options modal (post format, tags, categories)
         */
        function monitorOptionsModal() {
            var 
$postOptions  = $( '.post-options' ),
                
$postOption   = $( '.post-option' ),
                
$settingModal = $( '.setting-modal' ),
                
$modalClose   = $( '.modal-close' );

            
$postOption.on( 'click', function() {
                var index = $( this ).index(),
                    
$targetSettingModal = $settingModal.eq( index );

                
$postOptions.addClass( isOffScreen )
                    .one( transitionEndEvent, function() {
                        $( this ).addClass( isHidden );
                    } );

                
$targetSettingModal.removeClass( offscreenHidden )
                    .one( transitionEndEvent, function() {
                        $( this ).find( '.modal-close' ).focus();
                    } );
            } );

            
$modalClose.on( 'click', function() {
                var 
$targetSettingModal = $( this ).parent(),
                    index = 
$targetSettingModal.index();

                
$postOptions.removeClass( offscreenHidden );
                
$targetSettingModal.addClass( isOffScreen );

                if ( transitionEndEvent ) {
                    
$targetSettingModal.one( transitionEndEvent, function() {
                        $( this ).addClass( isHidden );
                        
$postOption.eq( index - 1 ).focus();
                    } );
                } else {
                    setTimeout( function() {
                        
$targetSettingModal.addClass( isHidden );
                        
$postOption.eq( index - 1 ).focus();
                    }, 350 );
                }
            } );
        }

        /**
         * Interactive behavior for the sidebar toggle, to show the options modals
         */
        function openSidebar() {
            sidebarIsOpen = true;

            $( '.options' ).removeClass( 'closed' ).addClass( 'open' );
            $( '.press-this-actions, #scanbar' ).addClass( isHidden );
            $( '.options-panel-back' ).removeClass( isHidden );

            $( '.options-panel' ).removeClass( offscreenHidden )
                .one( transitionEndEvent, function() {
                    $( '.post-option:first' ).focus();
                } );
        }

        function closeSidebar() {
            sidebarIsOpen = false;

            $( '.options' ).removeClass( 'open' ).addClass( 'closed' );
            $( '.options-panel-back' ).addClass( isHidden );
            $( '.press-this-actions, #scanbar' ).removeClass( isHidden );

            $( '.options-panel' ).addClass( isOffScreen )
                .one( transitionEndEvent, function() {
                    $( this ).addClass( isHidden );
                    // Reset to options list
                    $( '.post-options' ).removeClass( offscreenHidden );
                    $( '.setting-modal').addClass( offscreenHidden );
                });
        }

        /**
         * Interactive behavior for the post title's field placeholder
         */
        function monitorPlaceholder() {
            var 
$titleField = $( '#title-container' ),
                
$placeholder = $( '.post-title-placeholder' );

            
$titleField.on( 'focus', function() {
                
$placeholder.addClass( 'is-hidden' );
                resetDraftButton();
            }).on( 'blur', function() {
                if ( ! 
$titleField.text() && ! $titleField.html() ) {
                    
$placeholder.removeClass( 'is-hidden' );
                }
            }).on( 'keyup', function() {
                saveAlert = true;
            }).on( 'paste', function( event ) {
                var text, range,
                    clipboard = event.originalEvent.clipboardData || window.clipboardData;

                if ( clipboard ) {
                    try{
                        text = clipboard.getData( 'Text' ) || clipboard.getData( 'text/plain' );

                        if ( text ) {
                            text = $.trim( text.replace( /s+/g, ' ' ) );

                            if ( window.getSelection ) {
                                range = window.getSelection().getRangeAt(0);

                                if ( range ) {
                                    if ( ! range.collapsed ) {
                                        range.deleteContents();
                                    }

                                    range.insertNode( document.createTextNode( text ) );
                                }
                            } else if ( document.selection ) {
                                range = document.selection.createRange();

                                if ( range ) {
                                    range.text = text;
                                }
                            }
                        }
                    } catch ( er ) {}

                    event.preventDefault();
                }

                saveAlert = true;

                setTimeout( function() {
                    
$titleField.text( getTitleText() );
                }, 50 );
            });

            if ( 
$titleField.text() || $titleField.html() ) {
                
$placeholder.addClass('is-hidden');
            }
        }

        function toggleCatItem( 
$element ) {
            if ( 
$element.hasClass( 'selected' ) ) {
                
$element.removeClass( 'selected' ).attr( 'aria-checked', 'false' );
            } else {
                
$element.addClass( 'selected' ).attr( 'aria-checked', 'true' );
            }
        }

        function monitorCatList() {
            $( '.categories-select' ).on( 'click.press-this keydown.press-this', function( event ) {
                var 
$element = $( event.target );

                if ( 
$element.is( 'div.category' ) ) {
                    if ( event.type === 'keydown' && event.keyCode !== 32 ) {
                        return;
                    }

                    toggleCatItem( 
$element );
                    event.preventDefault();
                }
            });
        }

        /* ***************************************************************
         * PROCESSING FUNCTIONS
         *************************************************************** */

        /**
         * Calls all the rendring related functions to happen on page load
         */
        function render(){
            // We're on!
            renderToolsVisibility();
            renderDetectedMedia();
            renderStartupNotices();

            if ( window.tagBox ) {
                window.tagBox.init();
            }
        }

        /**
         * Set app events and other state monitoring related code.
         */
        function monitor() {
            $( document ).on( 'tinymce-editor-init', function( event, ed ) {
                editor = ed;

                editor.on( 'nodechange', function() {
                    hasSetFocus = true;
                    resetDraftButton();
                } );
            }).on( 'click.press-this keypress.press-this', '.suggested-media-thumbnail', function( event ) {
                if ( event.type === 'click' || event.keyCode === 13 ) {
                    insertSelectedMedia( $( this ) );
                }
            });

            // Publish, Draft and Preview buttons
            $( '.post-actions' ).on( 'click.press-this', function( event ) {
                var 
$target = $( event.target ),
                    
$button = $target.closest( 'button' );

                if ( 
$button.length ) {
                    if ( 
$button.hasClass( 'draft-button' ) ) {
                        
$button.addClass( 'is-saving' );
                        submitPost( 'draft' );
                    } else if ( 
$button.hasClass( 'publish-button' ) ) {
                        submitPost( 'publish' );
                    } else if ( 
$button.hasClass( 'preview-button' ) ) {
                        prepareFormData();
                        window.opener && window.opener.focus();

                        $( '#wp-preview' ).val( 'dopreview' );
                        $( '#pressthis-form' ).attr( 'target', '_blank' ).submit().attr( 'target', '' );
                        $( '#wp-preview' ).val( '' );
                    }
                } else if ( 
$target.hasClass( 'edit-post-link' ) && window.opener ) {
                    window.opener.focus();
                    window.self.close();
                }
            });

            monitorOptionsModal();
            monitorPlaceholder();
            monitorCatList();

            $( '.options' ).on( 'click.press-this', function() {
                if ( $( this ).hasClass( 'open' ) ) {
                    closeSidebar();
                } else {
                    openSidebar();
                }
            });

            // Close the sidebar when focus moves outside of it.
            $( '.options-panel, .options-panel-back' ).on( 'focusout.press-this', function() {
                setTimeout( function() {
                    var node = document.activeElement,
                        
$node = $( node );

                    if ( sidebarIsOpen && node && ! 
$node.hasClass( 'options-panel-back' ) &&
                        ( node.nodeName === 'BODY' ||
                            ( ! 
$node.closest( '.options-panel' ).length &&
                            ! 
$node.closest( '.options' ).length ) ) ) {

                        closeSidebar();
                    }
                }, 50 );
            });

            $( '#post-formats-select input' ).on( 'change', function() {
                var 
$this = $( this );

                if ( 
$this.is( ':checked' ) ) {
                    $( '#post-option-post-format' ).text( $( 'label[for="' + $this.attr( '
id' ) + '"]' ).text() || '' );
                }
            } );

            $( window ).on( 'beforeunload.press-this', function() {
                if ( saveAlert || ( editor && editor.isDirty() ) ) {
                    return __( 'saveAlert' );
                }
            } );

            $( 'button.add-cat-toggle' ).on( 'click.press-this', function() {
                var 
$this = $( this );

                
$this.toggleClass( 'is-toggled' );
                
$this.attr( 'aria-expanded', 'false' === $this.attr( 'aria-expanded' ) ? 'true' : 'false' );
                $( '.setting-modal .add-category, .categories-search-wrapper' ).toggleClass( 'is-hidden' );
            } );

            $( 'button.add-cat-submit' ).on( 'click.press-this', saveNewCategory );

            $( '.categories-search' ).on( 'keyup.press-this', function() {
                var search = $( this ).val().toLowerCase() || '';

                // Don't search when less thasn 3 extended ASCII chars
                if ( /[x20-xFF]+/.test( search ) && search.length < 2 ) {
                    return;
                }

                $.each( catsCache, function( i, cat ) {
                    cat.node.removeClass( 'is-hidden searched-parent' );
                } );

                if ( search ) {
                    $.each( catsCache, function( i, cat ) {
                        if ( cat.text.indexOf( search ) === -1 ) {
                            cat.node.addClass( 'is-hidden' );
                        } else {
                            cat.parents.addClass( 'searched-parent' );
                        }
                    } );
                }
            } );

            return true;
        }

        function refreshCatsCache() {
            $( '.categories-select' ).find( 'li' ).each( function() {
                var 
$this = $( this );

                catsCache.push( {
                    node: 
$this,
                    parents: 
$this.parents( 'li' ),
                    text: 
$this.children( '.category' ).text().toLowerCase()
                } );
            } );
        }

        // Let's go!
        $( document ).ready( function() {
            render();
            monitor();
            refreshCatsCache();
        });

        // Expose public methods?
        return {
            renderNotice: renderNotice,
            renderError: renderError
        };
    };

    window.wp = window.wp || {};
    window.wp.pressThis = new PressThis();

}( jQuery, window ));
?>
Онлайн: 0
Реклама