Make WordPress Core

Changeset 33452


Ignore:
Timestamp:
07/27/2015 11:15:15 PM (10 years ago)
Author:
iseulde
Message:

TinyMCE: wptextpattern: headings on enter

Fixes #31441.

Location:
trunk
Files:
2 edited

Legend:

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

    r33205 r33452  
    1515        var $$ = editor.$,
    1616            VK = tinymce.util.VK,
    17             patterns = [],
    18             canUndo = false;
    19 
    20         /**
    21          * Add a pattern to format with a callback.
    22          *
    23          * @since 4.3.0
    24          *
    25          * @param {RegExp}   regExp   RegEx pattern.
    26          * @param {Function} callback Callback.
    27          */
    28         function add( regExp, callback ) {
    29             patterns.push( {
    30                 regExp: regExp,
    31                 callback: callback
    32             } );
    33         }
    34 
    35         add( /^[*-]\s/, function() {
    36             this.execCommand( 'InsertUnorderedList' );
    37         } );
    38 
    39         add( /^1[.)]\s/, function() {
    40             this.execCommand( 'InsertOrderedList' );
    41         } );
    42 
    43         add( /^>\s/, function() {
    44             this.formatter.toggle( 'blockquote' );
    45         } );
    46 
    47         add( /^(#{2,6})\s/, function() {
    48             this.formatter.toggle( 'h' + arguments[1].length );
    49         } );
     17            canUndo = false,
     18            spacePatterns = [
     19                { regExp: /^[*-]\s/, cmd: 'InsertUnorderedList' },
     20                { regExp: /^1[.)]\s/, cmd: 'InsertOrderedList' }
     21            ],
     22            enterPatterns = [
     23                { start: '##', format: 'h2' },
     24                { start: '###', format: 'h3' },
     25                { start: '####', format: 'h4' },
     26                { start: '#####', format: 'h5' },
     27                { start: '######', format: 'h6' },
     28                { start: '>', format: 'blockquote' }
     29            ];
    5030
    5131        editor.on( 'selectionchange', function() {
     
    5838                event.preventDefault();
    5939            }
     40
     41            if ( event.keyCode === VK.ENTER && ! VK.modifierPressed( event ) ) {
     42                enter();
     43            }
     44        }, true );
     45
     46        editor.on( 'keyup', function( event ) {
     47            if ( event.keyCode === VK.SPACEBAR || ! VK.modifierPressed( event ) ) {
     48                space();
     49            }
    6050        } );
    6151
    62         editor.on( 'keyup', function( event ) {
    63             var rng, node, text, parent, child;
    64 
    65             if ( event.keyCode !== VK.SPACEBAR ) {
    66                 return;
    67             }
    68 
    69             rng = editor.selection.getRng();
    70             node = rng.startContainer;
    71 
    72             if ( ! node || node.nodeType !== 3 ) {
    73                 return;
    74             }
    75 
    76             text = node.nodeValue;
    77             parent = editor.dom.getParent( node, 'p' );
     52        function firstNode( node ) {
     53            var parent = editor.dom.getParent( node, 'p' ),
     54                child;
    7855
    7956            if ( ! parent ) {
     
    9370            }
    9471
    95             if ( ! child.nodeValue ) {
     72            if ( ! child.data ) {
    9673                child = child.nextSibling;
    9774            }
    9875
    99             if ( child !== node ) {
     76            return child;
     77        }
     78
     79        function space() {
     80            var rng = editor.selection.getRng(),
     81                node = rng.startContainer,
     82                text;
     83
     84            if ( firstNode( node ) !== node ) {
    10085                return;
    10186            }
    10287
    103             tinymce.each( patterns, function( pattern ) {
    104                 var args,
    105                     replace = text.replace( pattern.regExp, function() {
    106                         args = arguments;
    107                         return '';
    108                     } );
     88            text = node.data;
     89
     90            tinymce.each( spacePatterns, function( pattern ) {
     91                var replace = text.replace( pattern.regExp, '' );
    10992
    11093                if ( text === replace ) {
     
    119102
    120103                editor.undoManager.transact( function() {
    121                     var $$parent;
     104                    var parent = node.parentNode,
     105                        $$parent;
    122106
    123107                    if ( replace ) {
    124108                        $$( node ).replaceWith( document.createTextNode( replace ) );
    125109                    } else  {
    126                         $$parent = $$( node.parentNode );
     110                        $$parent = $$( parent );
    127111
    128112                        $$( node ).remove();
     
    134118
    135119                    editor.selection.setCursorLocation( parent );
    136 
    137                     pattern.callback.apply( editor, args );
     120                    editor.execCommand( pattern.cmd );
    138121                } );
    139122
     
    145128                return false;
    146129            } );
    147         } );
     130        }
     131
     132        function enter() {
     133            var selection = editor.selection,
     134                rng = selection.getRng(),
     135                offset = rng.startOffset,
     136                start = rng.startContainer,
     137                node = firstNode( start ),
     138                i = enterPatterns.length,
     139                text, pattern;
     140
     141            if ( ! node ) {
     142                return;
     143            }
     144
     145            text = node.data;
     146
     147            while ( i-- ) {
     148                 if ( text.indexOf( enterPatterns[ i ].start ) === 0 ) {
     149                    pattern = enterPatterns[ i ];
     150                    break;
     151                 }
     152            }
     153
     154            if ( ! pattern ) {
     155                return;
     156            }
     157
     158            if ( node === start ) {
     159                if ( tinymce.trim( text ) === pattern.start ) {
     160                    return;
     161                }
     162
     163                offset = Math.max( 0, offset - pattern.start.length );
     164            }
     165
     166            editor.undoManager.add();
     167
     168            editor.undoManager.transact( function() {
     169                node.deleteData( 0, pattern.start.length );
     170
     171                editor.formatter.apply( pattern.format, {}, start );
     172
     173                rng.setStart( start, offset );
     174                rng.collapse( true );
     175                selection.setRng( rng );
     176            } );
     177        }
    148178    } );
    149179} )( window.tinymce, window.setTimeout );
  • trunk/tests/qunit/wp-includes/js/tinymce/plugins/wptextpattern/plugin.js

    r32832 r33452  
    145145        }, assert.async() );
    146146    } );
     147
     148    QUnit.test( 'Heading 3', function( assert ) {
     149        editor.setContent( '<p>### test</p>' );
     150        editor.selection.setCursorLocation( editor.$( 'p' )[0].firstChild, 8 );
     151
     152        type( '\n', function() {
     153            assert.equal( editor.getContent(), '<h3>test</h3>\n<p>&nbsp;</p>' );
     154        }, assert.async() );
     155    } );
     156
     157    QUnit.test( 'Heading 3 with elements.', function( assert ) {
     158        editor.setContent( '<p>###<del>test</del></p>' );
     159        editor.selection.setCursorLocation( editor.$( 'del' )[0].firstChild, 4 );
     160
     161        type( '\n', function() {
     162            assert.equal( editor.getContent(), '<h3><del>test</del></h3>\n<p>&nbsp;</p>' );
     163        }, assert.async() );
     164    } );
     165
     166    QUnit.test( 'Don\'t convert without content', function( assert ) {
     167        editor.setContent( '<p>###&nbsp;</p>' );
     168        editor.selection.setCursorLocation( editor.$( 'p' )[0].firstChild, 4 );
     169
     170        type( '\n', function() {
     171            assert.equal( editor.getContent(), '<p>###&nbsp;</p>\n<p>&nbsp;</p>' );
     172        }, assert.async() );
     173    } );
    147174} )( window.jQuery, window.QUnit, window.tinymce, window.Utils.type, window.setTimeout );
Note: See TracChangeset for help on using the changeset viewer.