@ckeditor/ckeditor5-mention
Advanced tools
Comparing version 11.0.0 to 12.0.0
Changelog | ||
========= | ||
## [12.0.0](https://github.com/ckeditor/ckeditor5-mention/compare/v11.0.0...v12.0.0) (2019-07-04) | ||
### Bug fixes | ||
* It should be possible to type before a mention which is at the beginning of a block. Closes [#77](https://github.com/ckeditor/ckeditor5-mention/issues/77). ([946e762](https://github.com/ckeditor/ckeditor5-mention/commit/946e762)) | ||
* Mentions should work when different UTF character classes are used in the feed configuration. Closes [#38](https://github.com/ckeditor/ckeditor5-mention/issues/38). ([764f099](https://github.com/ckeditor/ckeditor5-mention/commit/764f099)) | ||
* Partial mentions should not be downcasted (e.g. not copied to clipboard). Closes [#24](https://github.com/ckeditor/ckeditor5-mention/issues/24). ([8956b1f](https://github.com/ckeditor/ckeditor5-mention/commit/8956b1f)) | ||
### Other changes | ||
* Moved the `TextWatcher` util to `@ckeditor/ckeditor5-typing`. ([a644043](https://github.com/ckeditor/ckeditor5-mention/commit/a644043)) | ||
### BREAKING CHANGES | ||
* The `TextWatcher` util was moved to `@ckeditor/ckeditor5-typing`. | ||
## [11.0.0](https://github.com/ckeditor/ckeditor5-mention/compare/v10.0.0...v11.0.0) (2019-06-05) | ||
@@ -5,0 +22,0 @@ |
{ | ||
"name": "@ckeditor/ckeditor5-mention", | ||
"version": "11.0.0", | ||
"version": "12.0.0", | ||
"description": "Mention feature for CKEditor 5.", | ||
@@ -13,19 +13,20 @@ "keywords": [ | ||
"dependencies": { | ||
"@ckeditor/ckeditor5-core": "^12.1.1", | ||
"@ckeditor/ckeditor5-ui": "^13.0.0", | ||
"@ckeditor/ckeditor5-utils": "^12.1.1" | ||
"@ckeditor/ckeditor5-core": "^12.2.0", | ||
"@ckeditor/ckeditor5-ui": "^13.0.1", | ||
"@ckeditor/ckeditor5-typing": "^12.1.0", | ||
"@ckeditor/ckeditor5-utils": "^13.0.0" | ||
}, | ||
"devDependencies": { | ||
"@ckeditor/ckeditor5-basic-styles": "^11.1.1", | ||
"@ckeditor/ckeditor5-block-quote": "^11.1.0", | ||
"@ckeditor/ckeditor5-clipboard": "^11.0.2", | ||
"@ckeditor/ckeditor5-editor-classic": "^12.1.1", | ||
"@ckeditor/ckeditor5-engine": "^13.1.1", | ||
"@ckeditor/ckeditor5-font": "^11.1.1", | ||
"@ckeditor/ckeditor5-link": "^11.0.2", | ||
"@ckeditor/ckeditor5-paragraph": "^11.0.2", | ||
"@ckeditor/ckeditor5-table": "^13.0.0", | ||
"@ckeditor/ckeditor5-basic-styles": "^11.1.2", | ||
"@ckeditor/ckeditor5-block-quote": "^11.1.1", | ||
"@ckeditor/ckeditor5-clipboard": "^12.0.0", | ||
"@ckeditor/ckeditor5-editor-classic": "^12.1.2", | ||
"@ckeditor/ckeditor5-engine": "^13.2.0", | ||
"@ckeditor/ckeditor5-font": "^11.2.0", | ||
"@ckeditor/ckeditor5-link": "^11.1.0", | ||
"@ckeditor/ckeditor5-paragraph": "^11.0.3", | ||
"@ckeditor/ckeditor5-table": "^13.0.1", | ||
"@ckeditor/ckeditor5-typing": "^12.0.2", | ||
"@ckeditor/ckeditor5-undo": "^11.0.2", | ||
"@ckeditor/ckeditor5-widget": "^11.0.2", | ||
"@ckeditor/ckeditor5-undo": "^11.0.3", | ||
"@ckeditor/ckeditor5-widget": "^11.0.3", | ||
"eslint": "^5.5.0", | ||
@@ -32,0 +33,0 @@ "eslint-config-ckeditor5": "^1.0.11", |
@@ -7,3 +7,2 @@ CKEditor 5 mention feature | ||
[![Build Status](https://travis-ci.org/ckeditor/ckeditor5-mention.svg?branch=master)](https://travis-ci.org/ckeditor/ckeditor5-mention) | ||
[![BrowserStack Status](https://automate.browserstack.com/automate/badge.svg?badge_key=d3hvenZqQVZERFQ5d09FWXdyT0ozVXhLaVltRFRjTTUyZGpvQWNmWVhUUT0tLUZqNlJ1YWRUd0RvdEVOaEptM1B2Q0E9PQ==--c9d3dee40b9b4471ff3fb516d9ecf8d09292c7e0)](https://automate.browserstack.com/public-build/d3hvenZqQVZERFQ5d09FWXdyT0ozVXhLaVltRFRjTTUyZGpvQWNmWVhUUT0tLUZqNlJ1YWRUd0RvdEVOaEptM1B2Q0E9PQ==--c9d3dee40b9b4471ff3fb516d9ecf8d09292c7e0) | ||
[![Coverage Status](https://coveralls.io/repos/github/ckeditor/ckeditor5-mention/badge.svg?branch=master)](https://coveralls.io/github/ckeditor/ckeditor5-mention?branch=master) | ||
@@ -10,0 +9,0 @@ <br> |
@@ -18,13 +18,14 @@ /** | ||
/** | ||
* Indicates whether the current browser supports ES2018 Unicode punctuation groups `\p{P}`. | ||
* Indicates whether the current browser supports ES2018 Unicode groups like `\p{P}` or `\p{L}`. | ||
* | ||
* @type {Boolean} | ||
*/ | ||
isPunctuationGroupSupported: ( function() { | ||
let punctuationSupported = false; | ||
// Feature detection for Unicode punctuation groups. It's added in ES2018. Currently Firefox and Edge does not support it. | ||
isUnicodeGroupSupported: ( function() { | ||
let isSupported = false; | ||
// Feature detection for Unicode groups. Added in ES2018. Currently Firefox and Edge do not support it. | ||
// See https://github.com/ckeditor/ckeditor5-mention/issues/44#issuecomment-487002174. | ||
try { | ||
punctuationSupported = '.'.search( new RegExp( '[\\p{P}]', 'u' ) ) === 0; | ||
isSupported = 'ć'.search( new RegExp( '[\\p{L}]', 'u' ) ) === 0; | ||
} catch ( error ) { | ||
@@ -34,4 +35,4 @@ // Firefox throws a SyntaxError when the group is unsupported. | ||
return punctuationSupported; | ||
return isSupported; | ||
}() ) | ||
}; |
@@ -101,3 +101,6 @@ /** | ||
*/ | ||
throw new CKEditorError( 'mentioncommand-incorrect-marker: The marker must be a single character.' ); | ||
throw new CKEditorError( | ||
'mentioncommand-incorrect-marker: The marker must be a single character.', | ||
this | ||
); | ||
} | ||
@@ -131,3 +134,6 @@ | ||
*/ | ||
throw new CKEditorError( 'mentioncommand-incorrect-id: The item id must start with the marker character.' ); | ||
throw new CKEditorError( | ||
'mentioncommand-incorrect-id: The item id must start with the marker character.', | ||
this | ||
); | ||
} | ||
@@ -134,0 +140,0 @@ |
@@ -43,2 +43,3 @@ /** | ||
// Upcast conversion. | ||
editor.conversion.for( 'upcast' ).elementToAttribute( { | ||
@@ -56,2 +57,3 @@ view: { | ||
// Downcast conversion. | ||
editor.conversion.for( 'downcast' ).attributeToElement( { | ||
@@ -61,2 +63,3 @@ model: 'mention', | ||
} ); | ||
editor.conversion.for( 'downcast' ).add( preventPartialMentionDowncast ); | ||
@@ -104,2 +107,27 @@ doc.registerPostFixer( writer => removePartialMentionPostFixer( writer, doc, model.schema ) ); | ||
// A converter that blocks partial mention from being converted. | ||
// | ||
// This converter is registered with 'highest' priority in order to consume mention attribute before it is converted by | ||
// any other converters. This converter only consumes partial mention - those whose `_text` attribute is not equal to text with mention | ||
// attribute. This may happen when copying part of mention text. | ||
// | ||
// @param {module:engine/conversion/dwoncastdispatcher~DowncastDispatcher} | ||
function preventPartialMentionDowncast( dispatcher ) { | ||
dispatcher.on( 'attribute:mention', ( evt, data, conversionApi ) => { | ||
const mention = data.attributeNewValue; | ||
if ( !data.item.is( 'textProxy' ) || !mention ) { | ||
return; | ||
} | ||
const start = data.range.start; | ||
const textNode = start.textNode || start.nodeAfter; | ||
if ( textNode.data != mention._text ) { | ||
// Consume item to prevent partial mention conversion. | ||
conversionApi.consumable.consume( data.item, evt.name ); | ||
} | ||
}, { priority: 'highest' } ); | ||
} | ||
// Creates a mention element from the mention data. | ||
@@ -128,3 +156,4 @@ // | ||
// Model post-fixer that disallows typing with selection when the selection is placed after the text node with the mention attribute. | ||
// Model post-fixer that disallows typing with selection when the selection is placed after the text node with the mention attribute or | ||
// before a text node with mention attribute. | ||
// | ||
@@ -138,3 +167,3 @@ // @param {module:engine/model/writer~Writer} writer | ||
if ( selection.isCollapsed && selection.hasAttribute( 'mention' ) && isNodeBeforeAText( focus ) ) { | ||
if ( selection.isCollapsed && selection.hasAttribute( 'mention' ) && shouldNotTypeWithMentionAt( focus ) ) { | ||
writer.removeSelectionAttribute( 'mention' ); | ||
@@ -144,6 +173,15 @@ | ||
} | ||
} | ||
function isNodeBeforeAText( position ) { | ||
return position.nodeBefore && position.nodeBefore.is( 'text' ); | ||
} | ||
// Helper function to detect if mention attribute should be removed from selection. | ||
// This check makes only sense if the selection has mention attribute. | ||
// | ||
// The mention attribute should be removed from a selection when selection focus is placed: | ||
// a) after a text node | ||
// b) the position is at parents start - the selection will set attributes from node after. | ||
function shouldNotTypeWithMentionAt( position ) { | ||
const isAtStart = position.isAtStart; | ||
const isAfterAMention = position.nodeBefore && position.nodeBefore.is( 'text' ); | ||
return isAfterAMention || isAtStart; | ||
} | ||
@@ -150,0 +188,0 @@ |
@@ -20,3 +20,3 @@ /** | ||
import TextWatcher from './textwatcher'; | ||
import TextWatcher from '@ckeditor/ckeditor5-typing/src/textwatcher'; | ||
@@ -132,3 +132,6 @@ import MentionsView from './ui/mentionsview'; | ||
*/ | ||
throw new CKEditorError( 'mentionconfig-incorrect-marker: The marker must be provided and it must be a single character.' ); | ||
throw new CKEditorError( | ||
'mentionconfig-incorrect-marker: The marker must be provided and it must be a single character.', | ||
null | ||
); | ||
} | ||
@@ -218,13 +221,7 @@ | ||
const watcher = this._getWatcher( marker ); | ||
const mentionMarker = editor.model.markers.get( 'mention' ); | ||
const text = watcher.last; | ||
const textMatcher = createTextMatcher( marker ); | ||
const matched = textMatcher( text ); | ||
const matchedTextLength = matched.marker.length + matched.feedText.length; | ||
// Create a range on matched text. | ||
const end = model.createPositionAt( model.document.selection.focus ); | ||
const start = end.getShiftedBy( -matchedTextLength ); | ||
const start = model.createPositionAt( mentionMarker.getStart() ); | ||
const range = model.createRange( start, end ); | ||
@@ -280,3 +277,3 @@ | ||
* @param {Number} minimumCharacters | ||
* @returns {module:mention/textwatcher~TextWatcher} | ||
* @returns {module:typing/textwatcher~TextWatcher} | ||
*/ | ||
@@ -286,9 +283,6 @@ _setupTextWatcherForFeed( marker, minimumCharacters ) { | ||
const watcher = new TextWatcher( editor, createTestCallback( marker, minimumCharacters ), createTextMatcher( marker ) ); | ||
const watcher = new TextWatcher( editor.model, createTestCallback( marker, minimumCharacters ) ); | ||
watcher.on( 'matched', ( evt, data ) => { | ||
const matched = data.matched; | ||
const selection = editor.model.document.selection; | ||
const focus = selection.focus; | ||
@@ -309,4 +303,3 @@ | ||
const { feedText, marker } = matched; | ||
const feedText = getFeedText( marker, data.text ); | ||
const matchedTextLength = marker.length + feedText.length; | ||
@@ -358,15 +351,2 @@ | ||
/** | ||
* Returns the registered text watcher for the marker. | ||
* | ||
* @private | ||
* @param {String} marker | ||
* @returns {module:mention/textwatcher~TextWatcher} | ||
*/ | ||
_getWatcher( marker ) { | ||
const { watcher } = this._mentionsConfigurations.get( marker ); | ||
return watcher; | ||
} | ||
/** | ||
* Shows the mentions balloon. If the panel is already visible, it will reposition it. | ||
@@ -565,15 +545,16 @@ * | ||
const numberOfCharacters = minimumCharacters == 0 ? '*' : `{${ minimumCharacters },}`; | ||
const patternBase = featureDetection.isPunctuationGroupSupported ? '\\p{Ps}\\p{Pi}"\'' : '\\(\\[{"\''; | ||
return new RegExp( buildPattern( patternBase, marker, numberOfCharacters ), 'u' ); | ||
} | ||
const openAfterCharacters = featureDetection.isUnicodeGroupSupported ? '\\p{Ps}\\p{Pi}"\'' : '\\(\\[{"\''; | ||
const mentionCharacters = featureDetection.isUnicodeGroupSupported ? '\\p{L}\\p{N}' : 'a-zA-ZÀ-ž0-9'; | ||
// Helper to build a RegExp pattern string for the marker. | ||
// | ||
// @param {String} whitelistedCharacters | ||
// @param {String} marker | ||
// @param {Number} minimumCharacters | ||
// @returns {String} | ||
function buildPattern( whitelistedCharacters, marker, numberOfCharacters ) { | ||
return `(^|[ ${ whitelistedCharacters }])([${ marker }])([_a-zA-Z0-9À-ž]${ numberOfCharacters }?)$`; | ||
// The pattern consists of 3 groups: | ||
// - 0 (non-capturing): Opening sequence - start of the line, space or an opening punctuation character like "(" or "\"", | ||
// - 1: The marker character, | ||
// - 2: Mention input (taking the minimal length into consideration to trigger the UI), | ||
// | ||
// 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 })$`; | ||
return new RegExp( pattern, 'u' ); | ||
} | ||
@@ -596,13 +577,8 @@ | ||
// @returns {Function} | ||
function createTextMatcher( marker ) { | ||
function getFeedText( marker, text ) { | ||
const regExp = createRegExp( marker, 0 ); | ||
return text => { | ||
const match = text.match( regExp ); | ||
const match = text.match( regExp ); | ||
const marker = match[ 2 ]; | ||
const feedText = match[ 3 ]; | ||
return { marker, feedText }; | ||
}; | ||
return match[ 2 ]; | ||
} | ||
@@ -609,0 +585,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
52689
4
14
1337
25
+ Added@ckeditor/ckeditor5-typing@12.2.0(transitive)
- Removed@ckeditor/ckeditor5-utils@12.1.1(transitive)