WordPress.org

Make WordPress Core

Changeset 39075


Ignore:
Timestamp:
11/01/2016 08:05:48 PM (4 years ago)
Author:
iseulde
Message:

TinyMCE: wptextpattern: Handle unconverted inline patterns

Make sure the right text is matched when it already contains characters of the pattern.
Adds two more unit tests.

Fixes #37693.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/js/tinymce/plugins/wptextpattern/plugin.js

    r38773 r39075  
    1616    }
    1717
     18    /**
     19     * Escapes characters for use in a Regular Expression.
     20     *
     21     * @param  {String} string Characters to escape
     22     *
     23     * @return {String}        Escaped characters
     24     */
     25    function escapeRegExp( string ) {
     26        return string.replace( /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&' );
     27    }
     28
    1829    tinymce.PluginManager.add( 'wptextpattern', function( editor ) {
    1930        var VK = tinymce.util.VK;
    20 
    21         var spacePatterns = [
     31        var settings = editor.settings.wptextpattern || {};
     32
     33        var spacePatterns = settings.space || [
    2234            { regExp: /^[*-]\s/, cmd: 'InsertUnorderedList' },
    2335            { regExp: /^1[.)]\s/, cmd: 'InsertOrderedList' }
    2436        ];
    2537
    26         var enterPatterns = [
     38        var enterPatterns = settings.enter || [
    2739            { start: '##', format: 'h2' },
    2840            { start: '###', format: 'h3' },
     
    3446        ];
    3547
    36         var inlinePatterns = [
     48        var inlinePatterns = settings.inline || [
    3749            { start: '`', end: '`', format: 'code' }
    3850        ];
     
    8294            var zero;
    8395
     96            // We need a non empty text node with an offset greater than zero.
    8497            if ( ! node || node.nodeType !== 3 || ! node.data.length || ! offset ) {
    8598                return;
    8699            }
    87100
     101            // The ending character should exist in the patterns registered.
    88102            if ( tinymce.inArray( chars, node.data.charAt( offset - 1 ) ) === -1 ) {
    89103                return;
    90104            }
    91105
    92             function findStart( node ) {
    93                 var i = inlinePatterns.length;
    94                 var offset;
    95 
    96                 while ( i-- ) {
    97                     pattern = inlinePatterns[ i ];
    98                     offset = node.data.indexOf( pattern.end );
    99 
    100                     if ( offset !== -1 ) {
    101                         return offset;
    102                     }
    103                 }
    104             }
    105 
    106             startOffset = findStart( node );
    107             endOffset = node.data.lastIndexOf( pattern.end );
    108 
    109             if ( startOffset === endOffset || endOffset === -1 ) {
    110                 return;
    111             }
    112 
    113             if ( endOffset - startOffset <= pattern.start.length ) {
    114                 return;
    115             }
    116 
    117             if ( node.data.slice( startOffset + pattern.start.length, endOffset ).indexOf( pattern.start.slice( 0, 1 ) ) !== -1 ) {
     106            var string = node.data.slice( 0, offset );
     107
     108            tinymce.each( inlinePatterns, function( p ) {
     109                var regExp = new RegExp( escapeRegExp( p.start ) + '\\S+' + escapeRegExp( p.end ) + '$' );
     110                var match = string.match( regExp );
     111
     112                if ( ! match ) {
     113                    return;
     114                }
     115
     116                // Don't allow pattern characters in the text.
     117                if ( node.data.slice( match.index + p.start.length, offset - p.end.length ).indexOf( p.start.slice( 0, 1 ) ) !== -1 ) {
     118                    return;
     119                }
     120
     121                startOffset = match.index;
     122                endOffset = offset - p.end.length;
     123                pattern = p;
     124
     125                return false;
     126            } );
     127
     128            if ( ! pattern ) {
    118129                return;
    119130            }
  • trunk/tests/qunit/index.html

    r38810 r39075  
    492492        </div><!-- end widget templates -->
    493493        <script src="../../src/wp-includes/js/tinymce/tinymce.js"></script>
     494        <script src="../../src/wp-includes/js/tinymce/plugins/wptextpattern/plugin.js"></script>
    494495        <script src="editor/js/utils.js"></script>
    495496        <script src="wp-includes/js/tinymce/plugins/wptextpattern/plugin.js"></script>
  • trunk/tests/qunit/wp-includes/js/tinymce/plugins/wptextpattern/plugin.js

    r37668 r39075  
    156156                    skin: false,
    157157                    plugins: 'wptextpattern',
     158                    wptextpattern: {
     159                        inline: [
     160                            { start: '`', end: '`', format: 'code' },
     161                            { start: '``', end: '``', format: 'bold' }
     162                        ]
     163                    },
    158164                    init_instance_callback: function() {
    159165                        editor = arguments[0];
     
    300306    } );
    301307
    302     QUnit.test( 'Inline: single.', function( assert ) {
     308    QUnit.test( 'Inline: single character.', function( assert ) {
    303309        type( '`test`', function() {
    304310            assert.equal( editor.getContent(), '<p><code>test</code></p>' );
     
    307313    } );
    308314
     315    QUnit.test( 'Inline: two characters.', function( assert ) {
     316        type( '``test``', function() {
     317            assert.equal( editor.getContent(), '<p><strong>test</strong></p>' );
     318            assert.equal( editor.selection.getRng().startOffset, 1 );
     319        }, assert.async() );
     320    } );
     321
    309322    QUnit.test( 'Inline: after typing.', function( assert ) {
    310323        editor.setContent( '<p>test test test</p>' );
     
    312325
    313326        type( '`', function() {
    314             editor.selection.setCursorLocation( editor.$( 'p' )[0].firstChild, 11 );
     327            editor.selection.setCursorLocation( editor.$( 'p' )[0].firstChild, 10 );
    315328        }, '`', function() {
    316329            assert.equal( editor.getContent(), '<p>test <code>test</code> test</p>' );
     
    324337        }, assert.async() );
    325338    } );
     339
     340    QUnit.test( 'Convert with previously unconverted pattern', function( assert ) {
     341        editor.setContent( '<p>`test` test&nbsp;</p>' );
     342        editor.selection.setCursorLocation( editor.$( 'p' )[0].firstChild, 12 );
     343
     344        type( '`test`', function() {
     345            assert.equal( editor.getContent(), '<p>`test` test&nbsp;<code>test</code></p>' );
     346        }, assert.async() );
     347    } );
    326348} )( window.jQuery, window.QUnit, window.tinymce, window.setTimeout );
Note: See TracChangeset for help on using the changeset viewer.