Make WordPress Core

Ticket #42059: 42059.2.diff

File 42059.2.diff, 9.7 KB (added by biskobe, 7 years ago)
  • src/wp-admin/js/editor.js

    diff --git a/src/wp-admin/js/editor.js b/src/wp-admin/js/editor.js
    index 0e47b3e022..961fc8b831 100644
    a b window.wp = window.wp || {}; 
    9999
    100100                                editorHeight = parseInt( textarea.style.height, 10 ) || 0;
    101101
    102                                 // Save the selection
    103                                 addHTMLBookmarkInTextAreaContent( $textarea, $ );
     102                                var keepSelection = false;
     103                                if (editor) {
     104                                        keepSelection = editor.getParam( 'wp_keep_editor_selection' )
     105                                }
     106                                else {
     107                                        keepSelection = window.tinyMCEPreInit.mceInit[ id ] &&
     108                                                                        window.tinyMCEPreInit.mceInit[ id ]['wp_keep_editor_selection']
     109                                }
     110
     111                                if ( keepSelection ) {
     112                                        // Save the selection
     113                                        addHTMLBookmarkInTextAreaContent( $textarea );
     114                                }
    104115
    105116                                if ( editor ) {
    106117                                        editor.show();
    window.wp = window.wp || {}; 
    116127                                                }
    117128                                        }
    118129
    119                                         // Restore the selection
    120                                         focusHTMLBookmarkInVisualEditor( editor );
     130                                        if ( editor.getParam( 'wp_keep_editor_selection' ) ) {
     131                                                // Restore the selection
     132                                                focusHTMLBookmarkInVisualEditor( editor );
     133                                        }
    121134                                } else {
    122135                                        tinymce.init( window.tinyMCEPreInit.mceInit[ id ] );
    123136                                }
    window.wp = window.wp || {}; 
    132145                                        return false;
    133146                                }
    134147
    135                                 var selectionRange = null;
    136148                                if ( editor ) {
    137149                                        // Don't resize the textarea in iOS. The iframe is forced to 100% height there, we shouldn't match it.
    138150                                        if ( ! tinymce.Env.iOS ) {
    window.wp = window.wp || {}; 
    150162                                                }
    151163                                        }
    152164
    153                                         selectionRange = findBookmarkedPosition( editor );
     165                                        var selectionRange = null;
     166
     167                                        if ( editor.getParam( 'wp_keep_editor_selection' ) ) {
     168                                                selectionRange = findBookmarkedPosition( editor );
     169                                        }
    154170
    155171                                        editor.hide();
    156172
    window.wp = window.wp || {}; 
    234250                function getShortcodeWrapperInfo( content, cursorPosition ) {
    235251                        var contentShortcodes = getShortCodePositionsInText( content );
    236252
    237                         return _.find( contentShortcodes, function( element ) {
    238                                 return cursorPosition >= element.startIndex && cursorPosition <= element.endIndex;
    239                         } );
     253                        for ( var i = 0; i < contentShortcodes.length; i++ ) {
     254                                var element = contentShortcodes[ i ];
     255
     256                                if ( cursorPosition >= element.startIndex && cursorPosition <= element.endIndex ) {
     257                                        return element;
     258                                }
     259                        }
    240260                }
    241261
    242262                /**
    window.wp = window.wp || {}; 
    245265                 * @param {string} content The content we want to scan for shortcodes.
    246266                 */
    247267                function getShortcodesInText( content ) {
    248                         var shortcodes = content.match( /\[+([\w_-])+/g );
     268                        var shortcodes = content.match( /\[+([\w_-])+/g ),
     269                                result = [];
    249270
    250                         return _.uniq(
    251                                 _.map( shortcodes, function( element ) {
    252                                         return element.replace( /^\[+/g, '' );
    253                                 } )
    254                         );
     271                        for ( var i = 0; i < shortcodes.length; i++ ) {
     272                                var shortcode = shortcodes[ i ].replace( /^\[+/g, '' );
     273
     274                                if ( result.indexOf( shortcode ) === -1 ) {
     275                                        result.push( shortcode );
     276                                }
     277                        }
     278
     279                        return result;
    255280                }
    256281
    257282                /**
    window.wp = window.wp || {}; 
    335360                                shortcodesDetails.push( shortcodeInfo );
    336361                        }
    337362
     363                        /**
     364                         * Get all URL matches, and treat them as embeds.
     365                         *
     366                         * Since there isn't a good way to detect if a URL by itself on a line is a previewable
     367                         * object, it's best to treat all of them as such.
     368                         *
     369                         * This means that the selection will capture the whole URL, in a similar way shrotcodes
     370                         * are treated.
     371                         */
     372                        var urlRegexp = new RegExp(
     373                                '(^|[\\n\\r][\\n\\r]|<p>)(https?:\\/\\/[^\s"]+?)(<\\/p>\s*|[\\n\\r][\\n\\r]|$)', 'gi'
     374                        );
     375
     376                        while ( shortcodeMatch = urlRegexp.exec( content ) ) {
     377                                shortcodeInfo = {
     378                                        shortcodeName: 'url',
     379                                        showAsPlainText: false,
     380                                        startIndex: shortcodeMatch.index,
     381                                        endIndex: shortcodeMatch.index + shortcodeMatch[ 0 ].length,
     382                                        length: shortcodeMatch[ 0 ].length,
     383                                        isPreviewable: true,
     384                                        urlAtStartOfContent: shortcodeMatch[ 1 ] === '',
     385                                        urlAtEndOfContent: shortcodeMatch[ 3 ] === ''
     386                                };
     387
     388                                shortcodesDetails.push( shortcodeInfo );
     389                        }
     390
    338391                        return shortcodesDetails;
    339392                }
    340393
    window.wp = window.wp || {}; 
    412465
    413466                        var isCursorStartInShortcode = getShortcodeWrapperInfo( content, cursorStart );
    414467                        if ( isCursorStartInShortcode && isCursorStartInShortcode.isPreviewable ) {
    415                                 cursorStart = isCursorStartInShortcode.startIndex;
     468                                /**
     469                                 * If a URL is at the start or the end of the content,
     470                                 * the selection doesn't work, because it inserts a marker in the text,
     471                                 * which breaks the embedURL detection.
     472                                 *
     473                                 * The best way to avoid that and not modify the user content is to
     474                                 * adjust the cursor to either after or before URL.
     475                                 */
     476                                if (isCursorStartInShortcode.urlAtStartOfContent) {
     477                                        cursorStart = isCursorStartInShortcode.endIndex;
     478                                }
     479                                else {
     480                                        cursorStart = isCursorStartInShortcode.startIndex;
     481                                }
    416482                        }
    417483
    418484                        var isCursorEndInShortcode = getShortcodeWrapperInfo( content, cursorEnd );
    419485                        if ( isCursorEndInShortcode && isCursorEndInShortcode.isPreviewable ) {
    420                                 cursorEnd = isCursorEndInShortcode.endIndex;
     486                                if (isCursorEndInShortcode.urlAtEndOfContent) {
     487                                        cursorEnd = isCursorEndInShortcode.startIndex;
     488                                }
     489                                else {
     490                                        cursorEnd = isCursorEndInShortcode.endIndex;
     491                                }
    421492                        }
    422493
    423494                        return {
    window.wp = window.wp || {}; 
    455526                                mode = htmlModeCursorStartPosition !== htmlModeCursorEndPosition ? 'range' : 'single',
    456527
    457528                                selectedText = null,
    458                                 cursorMarkerSkeleton = getCursorMarkerSpan( $$, '&#65279;' );
     529                                cursorMarkerSkeleton = getCursorMarkerSpan( $$, '&#65279;' ).attr( 'data-mce-type','bookmark' );
    459530
    460531                        if ( mode === 'range' ) {
    461532                                var markedText = textArea.value.slice( htmlModeCursorStartPosition, htmlModeCursorEndPosition ),
    window.wp = window.wp || {}; 
    470541                        textArea.value = [
    471542                                textArea.value.slice( 0, htmlModeCursorStartPosition ), // text until the cursor/selection position
    472543                                cursorMarkerSkeleton.clone()                                                    // cursor/selection start marker
    473                                         .addClass( 'mce_SELRES_start')[0].outerHTML,
     544                                        .addClass( 'mce_SELRES_start' )[0].outerHTML,
    474545                                selectedText,                                                                                   // selected text with end cursor/position marker
    475546                                textArea.value.slice( htmlModeCursorEndPosition )               // text from last cursor/selection position to end
    476547                        ].join( '' );
    window.wp = window.wp || {}; 
    487558                 * @param {Object} editor TinyMCE editor instance.
    488559                 */
    489560                function focusHTMLBookmarkInVisualEditor( editor ) {
    490                         var startNode = editor.$( '.mce_SELRES_start' ),
    491                                 endNode = editor.$( '.mce_SELRES_end' );
     561                        var startNode = editor.$( '.mce_SELRES_start' ).attr( 'data-mce-bogus', 1 ),
     562                                endNode = editor.$( '.mce_SELRES_end' ).attr( 'data-mce-bogus', 1 );
    492563
    493564                        if ( startNode.length ) {
    494565                                editor.focus();
    window.wp = window.wp || {}; 
    505576                                }
    506577                        }
    507578
    508                         scrollVisualModeToStartElement( editor, startNode );
    509 
     579                        if ( editor.getParam( 'wp_keep_scroll_position' ) ) {
     580                                scrollVisualModeToStartElement( editor, startNode );
     581                        }
    510582
    511583                        removeSelectionMarker( startNode );
    512584                        removeSelectionMarker( endNode );
    window.wp = window.wp || {}; 
    548620                        var elementTop = editor.$( element ).offset().top,
    549621                                TinyMCEContentAreaTop = editor.$( editor.getContentAreaContainer() ).offset().top,
    550622
     623                                toolbarHeight = getToolbarHeight( editor ),
     624
    551625                                edTools = $( '#wp-content-editor-tools' ),
    552                                 edToolsHeight = edTools.height(),
    553                                 edToolsOffsetTop = edTools.offset().top,
     626                                edToolsHeight = 0,
     627                                edToolsOffsetTop = 0;
    554628
    555                                 toolbarHeight = getToolbarHeight( editor ),
     629                        if ( edTools.length ) {
     630                                edToolsHeight = edTools.height();
     631                                edToolsOffsetTop = edTools.offset().top;
     632                        }
    556633
    557                                 windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,
     634                        var windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,
    558635
    559636                                selectionPosition = TinyMCEContentAreaTop + elementTop,
    560637                                visibleAreaHeight = windowHeight - ( edToolsHeight + toolbarHeight );
    window.wp = window.wp || {}; 
    675752                                 * This way we can adjust the selection to properly select only the content, ignoring
    676753                                 * whitespace inserted around the selected object by the Editor.
    677754                                 */
    678                                 startElement.attr('data-mce-object-selection', 'true');
    679                                 endElement.attr('data-mce-object-selection', 'true');
     755                                startElement.attr( 'data-mce-object-selection', 'true' );
     756                                endElement.attr( 'data-mce-object-selection', 'true' );
    680757
    681758                                editor.$( startNode ).before( startElement[0] );
    682759                                editor.$( startNode ).after( endElement[0] );
    window.wp = window.wp || {}; 
    776853                                end = selection.end || selection.start;
    777854
    778855                        if ( textArea.focus ) {
    779                                 // focus and scroll to the position
    780                                 setTimeout( function() {
    781                                         if ( textArea.blur ) {
    782                                                 // defocus before focusing
    783                                                 textArea.blur();
    784                                         }
    785                                         textArea.focus();
    786                                 }, 100 );
     856                                if ( editor.getParam( 'wp_keep_scroll_position' ) ) {
     857                                        // focus and scroll to the position
     858                                        setTimeout( function() {
     859                                                if ( textArea.blur ) {
     860                                                        // defocus before focusing
     861                                                        textArea.blur();
     862                                                }
     863                                                textArea.focus();
     864                                        }, 100 );
     865                                }
    787866
    788867                                textArea.focus();
    789868                        }
  • src/wp-includes/class-wp-editor.php

    diff --git a/src/wp-includes/class-wp-editor.php b/src/wp-includes/class-wp-editor.php
    index 1a402beeb7..0ff14c10aa 100644
    a b private static function default_settings() { 
    981981                        'end_container_on_empty_block' => true,
    982982                        'wpeditimage_html5_captions' => true,
    983983                        'wp_lang_attr' => get_bloginfo( 'language' ),
     984                        'wp_keep_editor_selection' => false,
     985                        'wp_keep_scroll_position' => false,
    984986                        'wp_shortcut_labels' => wp_json_encode( $shortcut_labels ),
    985987                );
    986988