+ function inline() {
+ var rng = editor.selection.getRng();
+ var node = rng.startContainer;
+ var offset = rng.startOffset;
+ var startOffset;
+ var endOffset;
+ var pattern;
+ var format;
+ var zero;
+
+ if ( ! node || node.nodeType !== 3 || ! node.data.length || ! offset ) {
+ return;
+ }
+
+ if ( tinymce.inArray( chars, node.data.charAt( offset - 1 ) ) === -1 ) {
+ return;
+ }
+
+ function findStart( node ) {
+ var i = inlinePatterns.length;
+ var offset;
+
+ while ( i-- ) {
+ pattern = inlinePatterns[ i ];
+ offset = node.data.indexOf( pattern.end );
+
+ if ( offset !== -1 ) {
+ return offset;
+ }
+ }
+ }
+
+ startOffset = findStart( node );
+ endOffset = node.data.lastIndexOf( pattern.end );
+
+ if ( startOffset === endOffset || endOffset === -1 ) {
+ return;
+ }
+
+ if ( endOffset - startOffset <= pattern.start.length ) {
+ return;
+ }
+
+ if ( node.data.slice( startOffset + pattern.start.length, endOffset ).indexOf( pattern.start.slice( 0, 1 ) ) !== -1 ) {
+ return;
+ }
+
+ format = editor.formatter.get( pattern.format );
+
+ if ( format && format[0].inline ) {
+ editor.undoManager.add();
+
+ editor.undoManager.transact( function() {
+ node.insertData( offset, '\u200b' );
+
+ node = node.splitText( startOffset );
+ zero = node.splitText( offset - startOffset );
+
+ node.deleteData( 0, pattern.start.length );
+ node.deleteData( node.data.length - pattern.end.length, pattern.end.length );
+
+ editor.formatter.apply( pattern.format, {}, node );
+
+ editor.selection.setCursorLocation( zero, 1 );
+ } );
+
+ // We need to wait for native events to be triggered.
+ setTimeout( function() {
+ canUndo = 'space';
+
+ editor.once( 'selectionchange', function() {
+ var offset;
+
+ if ( zero ) {
+ offset = zero.data.indexOf( '\u200b' );
+
+ if ( offset !== -1 ) {
+ zero.deleteData( offset, offset + 1 );
+ }
+ }
+ } );
+ } );
+ }
+ }
+