Make WordPress Core

Ticket #42059: 42059.diff

File 42059.diff, 5.9 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..4d2c986554 100644
    a b window.wp = window.wp || {}; 
    234234                function getShortcodeWrapperInfo( content, cursorPosition ) {
    235235                        var contentShortcodes = getShortCodePositionsInText( content );
    236236
    237                         return _.find( contentShortcodes, function( element ) {
    238                                 return cursorPosition >= element.startIndex && cursorPosition <= element.endIndex;
    239                         } );
     237                        for ( var i = 0; i < contentShortcodes.length; i++ ) {
     238                                var element = contentShortcodes[ i ];
     239
     240                                if ( cursorPosition >= element.startIndex && cursorPosition <= element.endIndex ) {
     241                                        return element;
     242                                }
     243                        }
    240244                }
    241245
    242246                /**
    window.wp = window.wp || {}; 
    245249                 * @param {string} content The content we want to scan for shortcodes.
    246250                 */
    247251                function getShortcodesInText( content ) {
    248                         var shortcodes = content.match( /\[+([\w_-])+/g );
     252                        var shortcodes = content.match( /\[+([\w_-])+/g ),
     253                                result = [];
    249254
    250                         return _.uniq(
    251                                 _.map( shortcodes, function( element ) {
    252                                         return element.replace( /^\[+/g, '' );
    253                                 } )
    254                         );
     255                        for ( var i = 0; i < shortcodes.length; i++ ) {
     256                                var shortcode = shortcodes[ i ].replace( /^\[+/g, '' );
     257
     258                                if ( result.indexOf( shortcode ) === -1 ) {
     259                                        result.push( shortcode );
     260                                }
     261                        }
     262
     263                        return result;
    255264                }
    256265
    257266                /**
    window.wp = window.wp || {}; 
    335344                                shortcodesDetails.push( shortcodeInfo );
    336345                        }
    337346
     347                        /**
     348                         * Get all URL matches, and treat them as embeds.
     349                         *
     350                         * Since there isn't a good way to detect if a URL by itself on a line is a previewable
     351                         * object, it's best to treat all of them as such.
     352                         *
     353                         * This means that the selection will capture the whole URL, in a similar way shrotcodes
     354                         * are treated.
     355                         */
     356                        var urlRegexp = new RegExp(
     357                                '(^|[\\n\\r][\\n\\r]|<p>)(https?:\\/\\/[^\s"]+?)(<\\/p>\s*|[\\n\\r][\\n\\r]|$)', 'gi'
     358                        );
     359
     360                        while ( shortcodeMatch = urlRegexp.exec( content ) ) {
     361                                shortcodeInfo = {
     362                                        shortcodeName: 'url',
     363                                        showAsPlainText: false,
     364                                        startIndex: shortcodeMatch.index,
     365                                        endIndex: shortcodeMatch.index + shortcodeMatch[ 0 ].length,
     366                                        length: shortcodeMatch[ 0 ].length,
     367                                        isPreviewable: true,
     368                                        urlAtStartOfContent: shortcodeMatch[ 1 ] === '',
     369                                        urlAtEndOfContent: shortcodeMatch[ 3 ] === ''
     370                                };
     371
     372                                shortcodesDetails.push( shortcodeInfo );
     373                        }
     374
    338375                        return shortcodesDetails;
    339376                }
    340377
    window.wp = window.wp || {}; 
    412449
    413450                        var isCursorStartInShortcode = getShortcodeWrapperInfo( content, cursorStart );
    414451                        if ( isCursorStartInShortcode && isCursorStartInShortcode.isPreviewable ) {
    415                                 cursorStart = isCursorStartInShortcode.startIndex;
     452                                /**
     453                                 * If a URL is at the start or the end of the content,
     454                                 * the selection doesn't work, because it inserts a marker in the text,
     455                                 * which breaks the embedURL detection.
     456                                 *
     457                                 * The best way to avoid that and not modify the user content is to
     458                                 * adjust the cursor to either after or before URL.
     459                                 */
     460                                if (isCursorStartInShortcode.urlAtStartOfContent) {
     461                                        cursorStart = isCursorStartInShortcode.endIndex;
     462                                }
     463                                else {
     464                                        cursorStart = isCursorStartInShortcode.startIndex;
     465                                }
    416466                        }
    417467
    418468                        var isCursorEndInShortcode = getShortcodeWrapperInfo( content, cursorEnd );
    419469                        if ( isCursorEndInShortcode && isCursorEndInShortcode.isPreviewable ) {
    420                                 cursorEnd = isCursorEndInShortcode.endIndex;
     470                                if (isCursorEndInShortcode.urlAtEndOfContent) {
     471                                        cursorEnd = isCursorEndInShortcode.startIndex;
     472                                }
     473                                else {
     474                                        cursorEnd = isCursorEndInShortcode.endIndex;
     475                                }
    421476                        }
    422477
    423478                        return {
    window.wp = window.wp || {}; 
    455510                                mode = htmlModeCursorStartPosition !== htmlModeCursorEndPosition ? 'range' : 'single',
    456511
    457512                                selectedText = null,
    458                                 cursorMarkerSkeleton = getCursorMarkerSpan( $$, '&#65279;' );
     513                                cursorMarkerSkeleton = getCursorMarkerSpan( $$, '&#65279;' ).attr( 'data-mce-type','bookmark' );
    459514
    460515                        if ( mode === 'range' ) {
    461516                                var markedText = textArea.value.slice( htmlModeCursorStartPosition, htmlModeCursorEndPosition ),
    window.wp = window.wp || {}; 
    470525                        textArea.value = [
    471526                                textArea.value.slice( 0, htmlModeCursorStartPosition ), // text until the cursor/selection position
    472527                                cursorMarkerSkeleton.clone()                                                    // cursor/selection start marker
    473                                         .addClass( 'mce_SELRES_start')[0].outerHTML,
     528                                        .addClass( 'mce_SELRES_start' )[0].outerHTML,
    474529                                selectedText,                                                                                   // selected text with end cursor/position marker
    475530                                textArea.value.slice( htmlModeCursorEndPosition )               // text from last cursor/selection position to end
    476531                        ].join( '' );
    window.wp = window.wp || {}; 
    487542                 * @param {Object} editor TinyMCE editor instance.
    488543                 */
    489544                function focusHTMLBookmarkInVisualEditor( editor ) {
    490                         var startNode = editor.$( '.mce_SELRES_start' ),
    491                                 endNode = editor.$( '.mce_SELRES_end' );
     545                        var startNode = editor.$( '.mce_SELRES_start' ).attr( 'data-mce-bogus', 1 ),
     546                                endNode = editor.$( '.mce_SELRES_end' ).attr( 'data-mce-bogus', 1 );
    492547
    493548                        if ( startNode.length ) {
    494549                                editor.focus();
    window.wp = window.wp || {}; 
    507562
    508563                        scrollVisualModeToStartElement( editor, startNode );
    509564
    510 
    511565                        removeSelectionMarker( startNode );
    512566                        removeSelectionMarker( endNode );
    513567                }
    window.wp = window.wp || {}; 
    675729                                 * This way we can adjust the selection to properly select only the content, ignoring
    676730                                 * whitespace inserted around the selected object by the Editor.
    677731                                 */
    678                                 startElement.attr('data-mce-object-selection', 'true');
    679                                 endElement.attr('data-mce-object-selection', 'true');
     732                                startElement.attr( 'data-mce-object-selection', 'true' );
     733                                endElement.attr( 'data-mce-object-selection', 'true' );
    680734
    681735                                editor.$( startNode ).before( startElement[0] );
    682736                                editor.$( startNode ).after( endElement[0] );