WordPress.org

Make WordPress Core

Changeset 37741


Ignore:
Timestamp:
06/17/2016 08:40:04 PM (3 years ago)
Author:
azaozz
Message:

Editor: after inserting a link detect if the URL is broken, first run.

Props iseulde, azaozz.
See #36638.

Location:
trunk/src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/admin-ajax.php

    r37714 r37741  
    6565    'press-this-add-category', 'crop-image', 'generate-password', 'save-wporg-username', 'delete-plugin',
    6666    'search-plugins', 'search-install-plugins', 'activate-plugin', 'update-theme', 'delete-theme',
    67     'install-theme',
     67    'install-theme', 'test_url',
    6868);
    6969
  • trunk/src/wp-admin/includes/ajax-actions.php

    r37714 r37741  
    38333833    wp_send_json_success( $status );
    38343834}
     3835
     3836/**
     3837 * Ajax handler for testing if an URL exists. Used in the editor.
     3838 *
     3839 * @since 4.6.0
     3840 */
     3841function wp_ajax_test_url() {
     3842    if ( ! current_user_can( 'edit_posts' ) || ! wp_verify_nonce( $_POST['nonce'], 'wp-test-url' ) ) {
     3843        wp_send_json_error();
     3844    }
     3845
     3846    $href = esc_url_raw( $_POST['href'] );
     3847
     3848    // Relative URL
     3849    if ( strpos( $href, '//' ) !== 0 && in_array( $href[0], array( '/', '#', '?' ), true ) ) {
     3850        $href = get_bloginfo( 'url' ) . $href;
     3851    }
     3852
     3853    $response = wp_safe_remote_get( $href, array(
     3854        'timeout' => 15,
     3855        // Use an explicit user-agent
     3856        'user-agent' => 'WordPress URL Test',
     3857    ) );
     3858
     3859    $message = null;
     3860
     3861    if ( is_wp_error( $response ) ) {
     3862        $error = $response->get_error_message();
     3863
     3864        if ( strpos( $message, 'resolve host' ) !== false ) {
     3865            $message = array( 'error' => __( 'Invalid host name.' ) );
     3866        }
     3867
     3868        wp_send_json_error( $message );
     3869    }
     3870
     3871    if ( wp_remote_retrieve_response_code( $response ) === 404 ) {
     3872        wp_send_json_error( array( 'error' => __( 'Not found, HTTP error 404.' ) ) );
     3873    }
     3874
     3875    wp_send_json_success();
     3876}
  • trunk/src/wp-includes/class-wp-editor.php

    r37492 r37741  
    10641064            'Letter' => __( 'Letter' ),
    10651065            'Action' => __( 'Action' ),
     1066            'Invalid host name.' => __( 'Invalid host name.' ),
    10661067            'To move focus to other buttons use Tab or the arrow keys. To return focus to the editor press Escape or use one of the buttons.' =>
    10671068                __( 'To move focus to other buttons use Tab or the arrow keys. To return focus to the editor press Escape or use one of the buttons.' ),
     
    12841285        <?php
    12851286
    1286         if ( in_array( 'wplink', self::$plugins, true ) || in_array( 'link', self::$qt_buttons, true ) )
     1287        $has_wplink = in_array( 'wplink', self::$plugins, true );
     1288
     1289        if ( $has_wplink ) {
     1290            echo '<input type="hidden" id="_wplink_urltest_nonce" value="' . wp_create_nonce( 'wp-test-url' ) . '" />';
     1291        }
     1292
     1293        if ( $has_wplink || in_array( 'link', self::$qt_buttons, true ) ) {
    12871294            self::wp_link_dialog();
     1295        }
    12881296
    12891297        /**
  • trunk/src/wp-includes/css/editor.css

    r37740 r37741  
    17581758}
    17591759
     1760div.wp-link-preview a.wplink-url-error {
     1761    color: #a00;
     1762}
     1763
     1764div.wp-link-preview a.wplink-url-error:hover {
     1765    color: #f00;
     1766}
     1767
    17601768div.wp-link-input {
    17611769    float: left;
  • trunk/src/wp-includes/js/tinymce/plugins/wplink/plugin.js

    r37632 r37741  
    9494        var doingUndoRedoTimer;
    9595        var $ = window.jQuery;
     96        var urlErrors = {};
    9697
    9798        function getSelectedLink() {
     
    132133
    133134        function removePlaceholderStrings( content, dataAttr ) {
    134             if ( dataAttr ) {
    135                 content = content.replace( / data-wplink-edit="true"/g, '' );
    136             }
    137 
    138             return content.replace( /<a [^>]*?href="_wp_link_placeholder"[^>]*>([\s\S]+)<\/a>/g, '$1' );
     135            return content.replace( /(<a [^>]+>)([\s\S]*?)<\/a>/g, function( all, tag, text ) {
     136                if ( tag.indexOf( ' href="_wp_link_placeholder"' ) > -1 ) {
     137                    return text;
     138                }
     139
     140                if ( dataAttr ) {
     141                    tag = tag.replace( / data-wplink-edit="true"/g, '' );
     142                }
     143
     144                tag = tag.replace( / data-wplink-url-error="true"/g, '' );
     145
     146                return tag + text + '</a>';
     147            });
     148        }
     149
     150        function checkLink( node ) {
     151            var $link = editor.$( node );
     152            var href = $link.attr( 'href' );
     153
     154            if ( ! href || typeof $ === 'undefined' ) {
     155                return;
     156            }
     157
     158            // Early check
     159            if ( /^http/i.test( href ) && ! /\.[a-z]{2,63}(\/|$)/i.test( href ) ) {
     160                urlErrors[href] = tinymce.translate( 'Invalid host name.' );
     161            }
     162
     163            if ( urlErrors.hasOwnProperty( href ) ) {
     164                $link.attr( 'data-wplink-url-error', 'true' );
     165                return;
     166            } else {
     167                $link.removeAttr( 'data-wplink-url-error' );
     168            }
     169
     170            $.post(
     171                window.ajaxurl, {
     172                    action: 'test_url',
     173                    nonce: $( '#_wplink_urltest_nonce' ).val(),
     174                    href: href
     175                },
     176                'json'
     177            ).done( function( response ) {
     178                if ( response.success ) {
     179                    return;
     180                }
     181
     182                if ( response.data && response.data.error ) {
     183                    urlErrors[href] = response.data.error;
     184                    $link.attr( 'data-wplink-url-error', 'true' );
     185
     186                    if ( toolbar && toolbar.visible() ) {
     187                        toolbar.$el.find( '.wp-link-preview a' ).addClass( 'wplink-url-error' ).attr( 'title', editor.dom.encode( response.data.error ) );
     188                    }
     189                }
     190            });
    139191        }
    140192
     
    232284                    editor.$( linkNode ).text( text || href );
    233285                }
     286
     287                checkLink( linkNode );
    234288            }
    235289
     
    474528        editor.on( 'wptoolbar', function( event ) {
    475529            var linkNode = editor.dom.getParent( event.element, 'a' ),
    476                 $linkNode, href, edit;
     530                $linkNode, href, edit, title;
    477531
    478532            if ( typeof window.wpLink !== 'undefined' && window.wpLink.modalOpen ) {
     
    499553                    event.element = linkNode;
    500554                    event.toolbar = toolbar;
     555                    title = urlErrors.hasOwnProperty( href ) ? editor.dom.encode( urlErrors[ href ] ) : null;
     556
     557                    if ( $linkNode.attr( 'data-wplink-url-error' ) === 'true' ) {
     558                        toolbar.$el.find( '.wp-link-preview a' ).addClass( 'wplink-url-error' ).attr( 'title', title );
     559                    } else {
     560                        toolbar.$el.find( '.wp-link-preview a' ).removeClass( 'wplink-url-error' ).attr( 'title', null );
     561                    }
    501562                }
    502563            }
     
    556617                editToolbar.tempHide = false;
    557618                editor.execCommand( 'wp_link_cancel' );
    558             }
     619            },
     620            checkLink: checkLink
    559621        };
    560622    } );
  • trunk/src/wp-includes/js/tinymce/skins/wordpress/wp-content.css

    r37446 r37741  
    206206}
    207207
     208a[data-wplink-url-error],
     209a[data-wplink-url-error]:hover,
     210a[data-wplink-url-error]:focus {
     211    outline: 2px dotted #dc3232;
     212    position: relative;
     213}
     214
    208215/**
    209216 * WP Views
  • trunk/src/wp-includes/js/wplink.js

    r37630 r37741  
    435435            editor.nodeChanged();
    436436
     437            if ( link && editor.plugins.wplink ) {
     438                editor.plugins.wplink.checkLink( link );
     439            }
     440
    437441            // Audible confirmation message when a link has been inserted in the Editor.
    438442            wp.a11y.speak( wpLinkL10n.linkInserted );
Note: See TracChangeset for help on using the changeset viewer.