Changeset 39150
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/js/tinymce/plugins/wptextpattern/plugin.js
r39077 r39150 4 4 * @since 4.3.0 5 5 * 6 * This plugin can automatically format text patterns as you type. It includes two patterns: 6 * This plugin can automatically format text patterns as you type. It includes several groups of patterns. 7 * 8 * Start of line patterns: 9 * As-you-type: 7 10 * - Unordered list (`* ` and `- `). 8 11 * - Ordered list (`1. ` and `1) `). 9 12 * 13 * On enter: 14 * - h2 (## ). 15 * - h3 (### ). 16 * - h4 (#### ). 17 * - h5 (##### ). 18 * - h6 (###### ). 19 * - blockquote (> ). 20 * - hr (---). 21 * 22 * Inline patterns: 23 * - <code> (`) (backtick). 24 * 10 25 * If the transformation in unwanted, the user can undo the change by pressing backspace, 11 26 * using the undo shortcut, or the undo button in the toolbar. 27 * 28 * Setting for the patterns can be overridden by plugins by using the `tiny_mce_before_init` PHP filter. 29 * The setting name is `wptextpattern` and the value is an object containing override arrays for each 30 * patterns group. There are three groups: "space", "enter", and "inline". Example (PHP): 31 * 32 * add_filter( 'tiny_mce_before_init', 'my_mce_init_wptextpattern' ); 33 * function my_mce_init_wptextpattern( $init ) { 34 * $init['wptextpattern'] = wp_json_encode( array( 35 * 'inline' => array( 36 * array( 'delimiter' => '**', 'format' => 'bold' ), 37 * array( 'delimiter' => '__', 'format' => 'italic' ), 38 * ), 39 * ) ); 40 * 41 * return $init; 42 * } 43 * 44 * Note that setting this will override the default text patterns. You will need to include them 45 * in your settings array if you want to keep them working. 12 46 */ 13 47 ( function( tinymce, setTimeout ) { … … 47 81 48 82 var inlinePatterns = settings.inline || [ 49 { start: '`', end: '`', format: 'code' }83 { delimiter: '`', format: 'code' } 50 84 ]; 51 85 52 86 var canUndo; 53 var chars = [];54 55 tinymce.each( inlinePatterns, function( pattern ) {56 tinymce.each( ( pattern.start + pattern.end ).split( '' ), function( c ) {57 if ( tinymce.inArray( chars, c ) === -1 ) {58 chars.push( c );59 }60 } );61 } );62 87 63 88 editor.on( 'selectionchange', function() { … … 101 126 } 102 127 103 // The ending character should exist in the patterns registered.104 if ( tinymce.inArray( chars, node.data.charAt( offset - 1 ) ) === -1 ) {105 return;106 }107 108 128 var string = node.data.slice( 0, offset ); 129 var lastChar = node.data.charAt( offset - 1 ); 109 130 110 131 tinymce.each( inlinePatterns, function( p ) { 111 var regExp = new RegExp( escapeRegExp( p.start ) + '\\S+' + escapeRegExp( p.end ) + '$' ); 132 // Character before selection should be delimiter. 133 if ( lastChar !== p.delimiter.slice( -1 ) ) { 134 return; 135 } 136 137 var escDelimiter = escapeRegExp( p.delimiter ); 138 var delimiterFirstChar = p.delimiter.charAt( 0 ); 139 var regExp = new RegExp( '(.*)' + escDelimiter + '.+' + escDelimiter + '$' ); 112 140 var match = string.match( regExp ); 113 141 … … 116 144 } 117 145 118 // Don't allow pattern characters in the text. 119 if ( node.data.slice( match.index + p.start.length, offset - p.end.length ).indexOf( p.start.slice( 0, 1 ) ) !== -1 ) { 146 startOffset = match[1].length; 147 endOffset = offset - p.delimiter.length; 148 149 var before = string.charAt( startOffset - 1 ); 150 var after = string.charAt( startOffset + p.delimiter.length ); 151 152 // test*test* => format applied 153 // test *test* => applied 154 // test* test* => not applied 155 if ( startOffset && /\S/.test( before ) ) { 156 if ( /\s/.test( after ) || before === delimiterFirstChar ) { 157 return; 158 } 159 } 160 161 // Do not replace when only whitespace and delimiter characters. 162 if ( ( new RegExp( '^[\\s' + escapeRegExp( delimiterFirstChar ) + ']+$' ) ).test( string.slice( startOffset, endOffset ) ) ) { 120 163 return; 121 164 } 122 165 123 startOffset = match.index;124 endOffset = offset - p.end.length;125 166 pattern = p; 126 167 … … 143 184 zero = node.splitText( offset - startOffset ); 144 185 145 node.deleteData( 0, pattern. start.length );146 node.deleteData( node.data.length - pattern. end.length, pattern.end.length );186 node.deleteData( 0, pattern.delimiter.length ); 187 node.deleteData( node.data.length - pattern.delimiter.length, pattern.delimiter.length ); 147 188 148 189 editor.formatter.apply( pattern.format, {}, node ); -
trunk/tests/qunit/wp-includes/js/tinymce/plugins/wptextpattern/plugin.js
r39075 r39150 158 158 wptextpattern: { 159 159 inline: [ 160 { start: '`', end: '`', format: 'code' }, 161 { start: '``', end: '``', format: 'bold' } 160 { delimiter: '`', format: 'code' }, 161 { delimiter: '``', format: 'bold' }, 162 { delimiter: '```', format: 'italic' } 162 163 ] 163 164 }, … … 320 321 } ); 321 322 323 QUnit.test( 'Inline: allow spaces within text.', function( assert ) { 324 type( '`a a`', function() { 325 assert.equal( editor.getContent(), '<p><code>a a</code></p>' ); 326 assert.equal( editor.selection.getRng().startOffset, 1 ); 327 }, assert.async() ); 328 } ); 329 330 QUnit.test( 'Inline: disallow \\S-delimiter-\\s.', function( assert ) { 331 type( 'a` a`', function() { 332 assert.equal( editor.getContent(), '<p>a` a`</p>' ); 333 assert.equal( editor.selection.getRng().startOffset, 5 ); 334 }, assert.async() ); 335 } ); 336 337 QUnit.test( 'Inline: allow \\s-delimiter-\\s.', function( assert ) { 338 type( 'a ` a`', function() { 339 assert.equal( editor.getContent(), '<p>a <code> a</code></p>' ); 340 assert.equal( editor.selection.getRng().startOffset, 1 ); 341 }, assert.async() ); 342 } ); 343 344 QUnit.test( 'Inline: allow \\S-delimiter-\\S.', function( assert ) { 345 type( 'a`a`', function() { 346 assert.equal( editor.getContent(), '<p>a<code>a</code></p>' ); 347 assert.equal( editor.selection.getRng().startOffset, 1 ); 348 }, assert.async() ); 349 } ); 350 322 351 QUnit.test( 'Inline: after typing.', function( assert ) { 323 352 editor.setContent( '<p>test test test</p>' ); … … 332 361 } ); 333 362 334 QUnit.test( 'Inline: no change .', function( assert ) {335 type( 'test `` ```', function() {336 assert.equal( editor.getContent(), '<p>test `` ```</p>' );337 }, assert.async() ); 338 } ); 339 340 QUnit.test( ' Convert with previously unconverted pattern', function( assert ) {363 QUnit.test( 'Inline: no change without content.', function( assert ) { 364 type( 'test `` ``` ````', function() { 365 assert.equal( editor.getContent(), '<p>test `` ``` ````</p>' ); 366 }, assert.async() ); 367 } ); 368 369 QUnit.test( 'Inline: convert with previously unconverted pattern.', function( assert ) { 341 370 editor.setContent( '<p>`test` test </p>' ); 342 371 editor.selection.setCursorLocation( editor.$( 'p' )[0].firstChild, 12 ); … … 346 375 }, assert.async() ); 347 376 } ); 377 378 QUnit.test( 'Inline: convert with previous pattern characters.', function( assert ) { 379 editor.setContent( '<p>test``` 123</p>' ); 380 editor.selection.setCursorLocation( editor.$( 'p' )[0].firstChild, 11 ); 381 382 type( '``456``', function() { 383 assert.equal( editor.getContent(), '<p>test``` 123<strong>456</strong></p>' ); 384 }, assert.async() ); 385 } ); 386 387 QUnit.test( 'Inline: disallow after previous pattern characters and leading space.', function( assert ) { 388 editor.setContent( '<p>test``` 123</p>' ); 389 editor.selection.setCursorLocation( editor.$( 'p' )[0].firstChild, 11 ); 390 391 type( '``` 456```', function() { 392 assert.equal( editor.getContent(), '<p>test``` 123``` 456```</p>' ); 393 }, assert.async() ); 394 } ); 348 395 } )( window.jQuery, window.QUnit, window.tinymce, window.setTimeout );
Note: See TracChangeset
for help on using the changeset viewer.