diff --git a/src/mentionui.js b/src/mentionui.js index a1b33a6..e02e937 100644 --- a/src/mentionui.js +++ b/src/mentionui.js @@ -640,7 +640,7 @@ export function createRegExp( marker, minimumCharacters ) { const numberOfCharacters = minimumCharacters == 0 ? '*' : `{${ minimumCharacters },}`; const openAfterCharacters = env.features.isRegExpUnicodePropertySupported ? '\\p{Ps}\\p{Pi}"\'' : '\\(\\[{"\''; - const mentionCharacters = env.features.isRegExpUnicodePropertySupported ? '\\p{L}\\p{N}' : 'a-zA-ZÀ-ž0-9'; + const mentionCharacters = '\\S'; // The pattern consists of 3 groups: // - 0 (non-capturing): Opening sequence - start of the line, space or an opening punctuation character like "(" or "\"", @@ -649,7 +649,7 @@ export function createRegExp( marker, minimumCharacters ) { // // The pattern matches up to the caret (end of string switch - $). // (0: opening sequence )(1: marker )(2: typed mention )$ - const pattern = `(?:^|[ ${ openAfterCharacters }])([${ marker }])([_${ mentionCharacters }]${ numberOfCharacters })$`; + const pattern = `(?:^|[ ${ openAfterCharacters }])([${ marker }])([${ mentionCharacters }]${ numberOfCharacters })$`; return new RegExp( pattern, 'u' ); } diff --git a/tests/manual/mention.js b/tests/manual/mention.js index a9824ce..9c5a907 100644 --- a/tests/manual/mention.js +++ b/tests/manual/mention.js @@ -165,6 +165,12 @@ ClassicEditor '#a01', '#a02', '#a03', '#a04', '#a05', '#a06', '#a07', '#a08', '#a09', '#a10', '#a11', '#a12', '#a13', '#a14', '#a15', '#a16', '#a17', '#a18', '#a19', '#a20' ] + }, + { + marker: ':', + feed: [ + ':+1:', ':-1:', ':@(at-sign):', ':$(dollar-sign):', ':#(hash-sign):' + ] } ] } diff --git a/tests/manual/mention.md b/tests/manual/mention.md index 6493d6e..bed4ffc 100644 --- a/tests/manual/mention.md +++ b/tests/manual/mention.md @@ -21,6 +21,14 @@ The feeds: - ... - a20 +3. Static list of "special characters" items (`:` marker) + + - :+1: + - :-1: + - :@(at-sign): + - :$(dollar-sign): + - :#(hash-sign): + ### Interaction You can interact with mention panel with keyboard: diff --git a/tests/mentionui.js b/tests/mentionui.js index 7a20224..6561ae8 100644 --- a/tests/mentionui.js +++ b/tests/mentionui.js @@ -518,14 +518,14 @@ describe( 'MentionUI', () => { env.features.isRegExpUnicodePropertySupported = false; createRegExp( '@', 2 ); sinon.assert.calledOnce( regExpStub ); - sinon.assert.calledWithExactly( regExpStub, '(?:^|[ \\(\\[{"\'])([@])([_a-zA-ZÀ-ž0-9]{2,})$', 'u' ); + sinon.assert.calledWithExactly( regExpStub, '(?:^|[ \\(\\[{"\'])([@])([\\S]{2,})$', 'u' ); } ); it( 'returns a ES2018 RegExp for browsers supporting Unicode punctuation groups', () => { env.features.isRegExpUnicodePropertySupported = true; createRegExp( '@', 2 ); sinon.assert.calledOnce( regExpStub ); - sinon.assert.calledWithExactly( regExpStub, '(?:^|[ \\p{Ps}\\p{Pi}"\'])([@])([_\\p{L}\\p{N}]{2,})$', 'u' ); + sinon.assert.calledWithExactly( regExpStub, '(?:^|[ \\p{Ps}\\p{Pi}"\'])([@])([\\S]{2,})$', 'u' ); } ); } ); @@ -1916,7 +1916,11 @@ describe( 'MentionUI', () => { }, { marker: '$', - feed: [ '$a1', '$a2', '$a3', '$a4', '$a5' ] + feed: [ + '$a1', '$a2', '$a3', '$a4', + // A case of mention with a marker character from other feed. See #6398. + '$a@' + ] } ] } ); @@ -1971,6 +1975,43 @@ describe( 'MentionUI', () => { expect( mentionsView.items ).to.have.length( 3 ); } ); } ); + + it( 'should show panel for matched marker if it contains the other configured marker', () => { + setData( model, 'foo []' ); + + model.change( writer => { + writer.insertText( '@', doc.selection.getFirstPosition() ); + } ); + + return waitForDebounce() + .then( () => { + expect( panelView.isVisible ).to.be.true; + expect( editor.model.markers.has( 'mention' ) ).to.be.true; + expect( mentionsView.items ).to.have.length( 3 ); + + mentionsView.items.get( 0 ).children.get( 0 ).fire( 'execute' ); + } ) + .then( waitForDebounce ) + .then( () => { + expect( panelView.isVisible ).to.be.false; + expect( editor.model.markers.has( 'mention' ) ).to.be.false; + + model.change( writer => { + writer.insertText( '$a', doc.selection.getFirstPosition() ); + } ); + } ) + .then( waitForDebounce ) + .then( () => { + model.change( writer => { + writer.insertText( '@', doc.selection.getFirstPosition() ); + } ); + } ) + .then( waitForDebounce ) + .then( () => { + expect( panelView.isVisible ).to.be.true; + expect( editor.model.markers.has( 'mention' ) ).to.be.true; + } ); + } ); } ); function testExecuteKey( name, keyCode, feedItems ) {