{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-typing/src/texttransformation.js","webpack:///./node_modules/@ckeditor/ckeditor5-typing/src/textwatcher.js"],"names":["TRANSFORMATIONS","copyright","from","to","registeredTrademark","trademark","oneHalf","oneThird","twoThirds","oneForth","threeQuarters","lessThanOrEqual","greaterThanOrEqual","notEqual","arrowLeft","arrowRight","horizontalEllipsis","enDash","emDash","quotesPrimary","buildQuotesRegExp","quotesSecondary","quotesPrimaryEnGb","quotesSecondaryEnGb","quotesPrimaryPl","quotesSecondaryPl","TRANSFORMATION_GROUPS","symbols","mathematical","typography","quotes","DEFAULT_TRANSFORMATIONS","Plugin","normalizeFrom","RegExp","concat","escapeRegExp","normalizeTo","Array","getTextAttributesAfterPosition","position","textNode","nodeAfter","getAttributes","quoteCharacter","normalizeTransformations","config","extra","remove","isNotRemoved","transformation","includes","configured","include","filter","expandGroupsAndRemoveDuplicates","map","definitions","_step2","definedTransformations","Set","_iterator2","_createForOfIteratorHelper","s","n","done","transformationOrGroup","value","_step3","_iterator3","add","err","e","f","TextWatcher","model","testCallback","_this","this","Object","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_classCallCheck_js__WEBPACK_IMPORTED_MODULE_1__","hasMatch","set","on","isEnabled","_startListening","stopListening","document","selection","_this2","listenTo","evt","_ref","directChange","isCollapsed","_evaluateTextBeforeSelection","fire","batch","type","suffix","data","arguments","length","undefined","rangeBeforeSelection","createRange","createPositionAt","focus","parent","_getLastTextLine","getLastTextLine","text","range","testResult","eventData","assign","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_typeof_js__WEBPACK_IMPORTED_MODULE_0__","mix","ObservableMixin"],"mappings":"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","file":"js/chunk-20a5c945.b32d0ba3.js","sourcesContent":["/**\n * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/texttransformation\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport TextWatcher from './textwatcher';\nimport { escapeRegExp } from 'lodash-es';\n\n// All named transformations.\nconst TRANSFORMATIONS = {\n\t// Common symbols:\n\tcopyright: { from: '(c)', to: '©' },\n\tregisteredTrademark: { from: '(r)', to: '®' },\n\ttrademark: { from: '(tm)', to: '™' },\n\n\t// Mathematical:\n\toneHalf: { from: '1/2', to: '½' },\n\toneThird: { from: '1/3', to: '⅓' },\n\ttwoThirds: { from: '2/3', to: '⅔' },\n\toneForth: { from: '1/4', to: '¼' },\n\tthreeQuarters: { from: '3/4', to: '¾' },\n\tlessThanOrEqual: { from: '<=', to: '≤' },\n\tgreaterThanOrEqual: { from: '>=', to: '≥' },\n\tnotEqual: { from: '!=', to: '≠' },\n\tarrowLeft: { from: '<-', to: '←' },\n\tarrowRight: { from: '->', to: '→' },\n\n\t// Typography:\n\thorizontalEllipsis: { from: '...', to: '…' },\n\tenDash: { from: /(^| )(--)( )$/, to: [ null, '–', null ] },\n\temDash: { from: /(^| )(---)( )$/, to: [ null, '—', null ] },\n\t// Quotations:\n\t// English, US\n\tquotesPrimary: { from: buildQuotesRegExp( '\"' ), to: [ null, '“', null, '”' ] },\n\tquotesSecondary: { from: buildQuotesRegExp( '\\'' ), to: [ null, '‘', null, '’' ] },\n\n\t// English, UK\n\tquotesPrimaryEnGb: { from: buildQuotesRegExp( '\\'' ), to: [ null, '‘', null, '’' ] },\n\tquotesSecondaryEnGb: { from: buildQuotesRegExp( '\"' ), to: [ null, '“', null, '”' ] },\n\n\t// Polish\n\tquotesPrimaryPl: { from: buildQuotesRegExp( '\"' ), to: [ null, '„', null, '”' ] },\n\tquotesSecondaryPl: { from: buildQuotesRegExp( '\\'' ), to: [ null, '‚', null, '’' ] }\n};\n\n// Transformation groups.\nconst TRANSFORMATION_GROUPS = {\n\tsymbols: [ 'copyright', 'registeredTrademark', 'trademark' ],\n\tmathematical: [\n\t\t'oneHalf', 'oneThird', 'twoThirds', 'oneForth', 'threeQuarters',\n\t\t'lessThanOrEqual', 'greaterThanOrEqual', 'notEqual',\n\t\t'arrowLeft', 'arrowRight'\n\t],\n\ttypography: [ 'horizontalEllipsis', 'enDash', 'emDash' ],\n\tquotes: [ 'quotesPrimary', 'quotesSecondary' ]\n};\n\n// A set of default transformations provided by the feature.\nconst DEFAULT_TRANSFORMATIONS = [\n\t'symbols',\n\t'mathematical',\n\t'typography',\n\t'quotes'\n];\n\n/**\n * The text transformation plugin.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TextTransformation extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TextTransformation';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'typing', {\n\t\t\ttransformations: {\n\t\t\t\tinclude: DEFAULT_TRANSFORMATIONS\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst model = this.editor.model;\n\t\tconst modelSelection = model.document.selection;\n\n\t\tmodelSelection.on( 'change:range', () => {\n\t\t\t// Disable plugin when selection is inside a code block.\n\t\t\tthis.isEnabled = !modelSelection.anchor.parent.is( 'element', 'codeBlock' );\n\t\t} );\n\n\t\tthis._enableTransformationWatchers();\n\t}\n\n\t/**\n\t * Create new TextWatcher listening to the editor for typing and selection events.\n\t *\n\t * @private\n\t */\n\t_enableTransformationWatchers() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst input = editor.plugins.get( 'Input' );\n\t\tconst normalizedTransformations = normalizeTransformations( editor.config.get( 'typing.transformations' ) );\n\n\t\tconst testCallback = text => {\n\t\t\tfor ( const normalizedTransformation of normalizedTransformations ) {\n\t\t\t\tconst from = normalizedTransformation.from;\n\t\t\t\tconst match = from.test( text );\n\n\t\t\t\tif ( match ) {\n\t\t\t\t\treturn { normalizedTransformation };\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tconst watcherCallback = ( evt, data ) => {\n\t\t\tif ( !input.isInput( data.batch ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { from, to } = data.normalizedTransformation;\n\n\t\t\tconst matches = from.exec( data.text );\n\t\t\tconst replaces = to( matches.slice( 1 ) );\n\n\t\t\tconst matchedRange = data.range;\n\n\t\t\tlet changeIndex = matches.index;\n\n\t\t\tmodel.enqueueChange( writer => {\n\t\t\t\tfor ( let i = 1; i < matches.length; i++ ) {\n\t\t\t\t\tconst match = matches[ i ];\n\t\t\t\t\tconst replaceWith = replaces[ i - 1 ];\n\n\t\t\t\t\tif ( replaceWith == null ) {\n\t\t\t\t\t\tchangeIndex += match.length;\n\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst replacePosition = matchedRange.start.getShiftedBy( changeIndex );\n\t\t\t\t\tconst replaceRange = model.createRange( replacePosition, replacePosition.getShiftedBy( match.length ) );\n\t\t\t\t\tconst attributes = getTextAttributesAfterPosition( replacePosition );\n\n\t\t\t\t\tmodel.insertContent( writer.createText( replaceWith, attributes ), replaceRange );\n\n\t\t\t\t\tchangeIndex += replaceWith.length;\n\t\t\t\t}\n\t\t\t} );\n\t\t};\n\n\t\tconst watcher = new TextWatcher( editor.model, testCallback );\n\n\t\twatcher.on( 'matched:data', watcherCallback );\n\t\twatcher.bind( 'isEnabled' ).to( this );\n\t}\n}\n\n// Normalizes the configuration `from` parameter value.\n// The normalized value for the `from` parameter is a RegExp instance. If the passed `from` is already a RegExp instance,\n// it is returned unchanged.\n//\n// @param {String|RegExp} from\n// @returns {RegExp}\nfunction normalizeFrom( from ) {\n\tif ( typeof from == 'string' ) {\n\t\treturn new RegExp( `(${ escapeRegExp( from ) })$` );\n\t}\n\n\t// `from` is already a regular expression.\n\treturn from;\n}\n\n// Normalizes the configuration `to` parameter value.\n// The normalized value for the `to` parameter is a function that takes an array and returns an array. See more in the\n// configuration description. If the passed `to` is already a function, it is returned unchanged.\n//\n// @param {String|Array.|Function} to\n// @returns {Function}\nfunction normalizeTo( to ) {\n\tif ( typeof to == 'string' ) {\n\t\treturn () => [ to ];\n\t} else if ( to instanceof Array ) {\n\t\treturn () => to;\n\t}\n\n\t// `to` is already a function.\n\treturn to;\n}\n\n// For given `position` returns attributes for the text that is after that position.\n// The text can be in the same text node as the position (`foo[]bar`) or in the next text node (`foo[]<$text bold=\"true\">bar`).\n//\n// @param {module:engine/model/position~Position} position\n// @returns {Iterable.<*>}\nfunction getTextAttributesAfterPosition( position ) {\n\tconst textNode = position.textNode ? position.textNode : position.nodeAfter;\n\n\treturn textNode.getAttributes();\n}\n\n// Returns a RegExp pattern string that detects a sentence inside a quote.\n//\n// @param {String} quoteCharacter The character to create a pattern for.\n// @returns {String}\nfunction buildQuotesRegExp( quoteCharacter ) {\n\treturn new RegExp( `(^|\\\\s)(${ quoteCharacter })([^${ quoteCharacter }]*)(${ quoteCharacter })$` );\n}\n\n// Reads text transformation config and returns normalized array of transformations objects.\n//\n// @param {module:typing/texttransformation~TextTransformationDescription} config\n// @returns {Array.<{from:String,to:Function}>}\nfunction normalizeTransformations( config ) {\n\tconst extra = config.extra || [];\n\tconst remove = config.remove || [];\n\tconst isNotRemoved = transformation => !remove.includes( transformation );\n\n\tconst configured = config.include.concat( extra ).filter( isNotRemoved );\n\n\treturn expandGroupsAndRemoveDuplicates( configured )\n\t\t.filter( isNotRemoved ) // Filter out 'remove' transformations as they might be set in group\n\t\t.map( transformation => TRANSFORMATIONS[ transformation ] || transformation )\n\t\t.map( transformation => ( {\n\t\t\tfrom: normalizeFrom( transformation.from ),\n\t\t\tto: normalizeTo( transformation.to )\n\t\t} ) );\n}\n\n// Reads definitions and expands named groups if needed to transformation names.\n// This method also removes duplicated named transformations if any.\n//\n// @param {Array.} definitions\n// @returns {Array.}\nfunction expandGroupsAndRemoveDuplicates( definitions ) {\n\t// Set is using to make sure that transformation names are not duplicated.\n\tconst definedTransformations = new Set();\n\n\tfor ( const transformationOrGroup of definitions ) {\n\t\tif ( TRANSFORMATION_GROUPS[ transformationOrGroup ] ) {\n\t\t\tfor ( const transformation of TRANSFORMATION_GROUPS[ transformationOrGroup ] ) {\n\t\t\t\tdefinedTransformations.add( transformation );\n\t\t\t}\n\t\t} else {\n\t\t\tdefinedTransformations.add( transformationOrGroup );\n\t\t}\n\t}\n\n\treturn Array.from( definedTransformations );\n}\n\n/**\n * The text transformation definition object. It describes what should be replaced with what.\n *\n * The input value (`from`) can be passed either as a string or as a regular expression.\n *\n * * If a string is passed, it will be simply checked if the end of the input matches it.\n * * If a regular expression is passed, its entire length must be covered with capturing groups (e.g. `/(foo)(bar)$/`).\n * Also, since it is compared against the end of the input, it has to end with `$` to be correctly matched.\n * See examples below.\n *\n * The output value (`to`) can be passed as a string, as an array or as a function.\n *\n * * If a string is passed, it will be used as a replacement value as-is. Note that a string output value can be used only if\n * the input value is a string, too.\n * * If an array is passed, it has to have the same number of elements as there are capturing groups in the input value regular expression.\n * Each capture group will be replaced with a corresponding string from the passed array. If a given capturing group should not be replaced,\n * use `null` instead of passing a string.\n * * If a function is used, it should return an array as described above. The function is passed one parameter — an array with matches\n * by the regular expression. See the examples below.\n *\n * A simple string-to-string replacement:\n *\n *\t\t{ from: '(c)', to: '©' }\n *\n * Change quote styles using a regular expression. Note how all the parts are in separate capturing groups and the space at the beginning\n * and the text inside quotes are not replaced (`null` passed as the first and the third value in the `to` parameter):\n *\n *\t\t{\n *\t\t\tfrom: /(^|\\s)(\")([^\"]*)(\")$/,\n *\t\t\tto: [ null, '“', null, '”' ]\n *\t\t}\n *\n * Automatic uppercase after a dot using a callback:\n *\n *\t\t{\n *\t\t\tfrom: /(\\. )([a-z])$/,\n *\t\t\tto: matches => [ null, matches[ 1 ].toUpperCase() ]\n *\t\t}\n *\n * @typedef {Object} module:typing/texttransformation~TextTransformationDescription\n * @property {String|RegExp} from The string or regular expression to transform.\n * @property {String} to The text to transform compatible with `String.replace()`.\n */\n\n/**\n * The configuration of the {@link module:typing/texttransformation~TextTransformation} feature.\n *\n * Read more in {@link module:typing/texttransformation~TextTransformationConfig}.\n *\n * @member {module:typing/texttransformation~TextTransformationConfig} module:typing/typing~TypingConfig#transformations\n */\n\n/**\n * The configuration of the text transformation feature.\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n *\t\t\t\ttyping: {\n *\t\t\t\t\ttransformations: ... // Text transformation feature options.\n *\t\t\t\t}\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * By default, the feature comes pre-configured\n * (via {@link module:typing/texttransformation~TextTransformationConfig#include `config.typing.transformations.include`}) with the\n * following groups of transformations:\n *\n * * Typography (group name: `typography`)\n * - `ellipsis`: transforms `...` to `…`\n * - `enDash`: transforms ` -- ` to ` – `\n * - `emDash`: transforms ` --- ` to ` — `\n * * Quotations (group name: `quotes`)\n * - `quotesPrimary`: transforms `\"Foo bar\"` to `“Foo bar”`\n * - `quotesSecondary`: transforms `'Foo bar'` to `‘Foo bar’`\n * * Symbols (group name: `symbols`)\n * - `trademark`: transforms `(tm)` to `™`\n * - `registeredTrademark`: transforms `(r)` to `®`\n * - `copyright`: transforms `(c)` to `©`\n * * Mathematical (group name: `mathematical`)\n * - `oneHalf`: transforms `1/2` to: `½`\n * - `oneThird`: transforms `1/3` to: `⅓`\n * - `twoThirds`: transforms `2/3` to: `⅔`\n * - `oneForth`: transforms `1/4` to: `¼`\n * - `threeQuarters`: transforms `3/4` to: `¾`\n * - `lessThanOrEqual`: transforms `<=` to: `≤`\n * - `greaterThanOrEqual`: transforms `>=` to: `≥`\n * - `notEqual`: transforms `!=` to: `≠`\n * - `arrowLeft`: transforms `<-` to: `←`\n * - `arrowRight`: transforms `->` to: `→`\n * * Misc:\n * - `quotesPrimaryEnGb`: transforms `'Foo bar'` to `‘Foo bar’`\n * - `quotesSecondaryEnGb`: transforms `\"Foo bar\"` to `“Foo bar”`\n * - `quotesPrimaryPl`: transforms `\"Foo bar\"` to `„Foo bar”`\n * - `quotesSecondaryPl`: transforms `'Foo bar'` to `‚Foo bar’`\n *\n * In order to load additional transformations, use the\n * {@link module:typing/texttransformation~TextTransformationConfig#extra `transformations.extra` option}.\n *\n * In order to narrow down the list of transformations, use the\n * {@link module:typing/texttransformation~TextTransformationConfig#remove `transformations.remove` option}.\n *\n * In order to completely override the supported transformations, use the\n * {@link module:typing/texttransformation~TextTransformationConfig#include `transformations.include` option}.\n *\n * Examples:\n *\n *\t\tconst transformationsConfig = {\n *\t\t\tinclude: [\n *\t\t\t\t// Use only the 'quotes' and 'typography' groups.\n *\t\t\t\t'quotes',\n *\t\t\t\t'typography',\n *\n *\t\t\t\t// Plus, some custom transformation.\n *\t\t\t\t{ from: 'CKE', to: 'CKEditor' }\n *\t\t\t]\n *\t\t};\n *\n *\t\tconst transformationsConfig = {\n *\t\t\t// Remove the 'ellipsis' transformation loaded by the 'typography' group.\n *\t\t\tremove: [ 'ellipsis' ]\n *\t\t}\n *\n * @interface TextTransformationConfig\n */\n\n/* eslint-disable max-len */\n/**\n * The standard list of text transformations supported by the editor. By default it comes pre-configured with a couple dozen of them\n * (see {@link module:typing/texttransformation~TextTransformationConfig} for the full list). You can override this list completely\n * by setting this option or use the other two options\n * ({@link module:typing/texttransformation~TextTransformationConfig#extra `transformations.extra`},\n * {@link module:typing/texttransformation~TextTransformationConfig#remove `transformations.remove`}) to fine-tune the default list.\n *\n * @member {Array.} module:typing/texttransformation~TextTransformationConfig#include\n */\n\n/**\n * Additional text transformations that are added to the transformations defined in\n * {@link module:typing/texttransformation~TextTransformationConfig#include `transformations.include`}.\n *\n *\t\tconst transformationsConfig = {\n *\t\t\textra: [\n *\t\t\t\t{ from: 'CKE', to: 'CKEditor' }\n *\t\t\t]\n *\t\t};\n *\n * @member {Array.} module:typing/texttransformation~TextTransformationConfig#extra\n */\n\n/**\n * The text transformation names that are removed from transformations defined in\n * {@link module:typing/texttransformation~TextTransformationConfig#include `transformations.include`} or\n * {@link module:typing/texttransformation~TextTransformationConfig#extra `transformations.extra`}.\n *\n *\t\tconst transformationsConfig = {\n *\t\t\tremove: [\n *\t\t\t\t'ellipsis', // Remove only 'ellipsis' from the 'typography' group.\n *\t\t\t\t'mathematical' // Remove all transformations from the 'mathematical' group.\n *\t\t\t]\n *\t\t}\n *\n * @member {Array.} module:typing/texttransformation~TextTransformationConfig#remove\n */\n/* eslint-enable max-len */\n","/**\n * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/textwatcher\n */\n\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport getLastTextLine from './utils/getlasttextline';\n\n/**\n * The text watcher feature.\n *\n * Fires the {@link module:typing/textwatcher~TextWatcher#event:matched:data `matched:data`},\n * {@link module:typing/textwatcher~TextWatcher#event:matched:selection `matched:selection`} and\n * {@link module:typing/textwatcher~TextWatcher#event:unmatched `unmatched`} events on typing or selection changes.\n *\n * @private\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class TextWatcher {\n\t/**\n\t * Creates a text watcher instance.\n\t *\n\t * @param {module:engine/model/model~Model} model\n\t * @param {Function} testCallback See {@link module:typing/textwatcher~TextWatcher#testCallback}.\n\t */\n\tconstructor( model, testCallback ) {\n\t\t/**\n\t\t * The editor's model.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/model~Model}\n\t\t */\n\t\tthis.model = model;\n\n\t\t/**\n\t\t * The function used to match the text.\n\t\t *\n\t\t * The test callback can return 3 values:\n\t\t *\n\t\t * * `false` if there is no match,\n\t\t * * `true` if there is a match,\n\t\t * * an object if there is a match and we want to pass some additional information to the {@link #event:matched:data} event.\n\t\t *\n\t\t * @member {Function} #testCallback\n\t\t * @returns {Object} testResult\n\t\t */\n\t\tthis.testCallback = testCallback;\n\n\t\t/**\n\t\t * Whether there is a match currently.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis.hasMatch = false;\n\n\t\t/**\n\t\t * Flag indicating whether the `TextWatcher` instance is enabled or disabled.\n\t\t * A disabled TextWatcher will not evaluate text.\n\t\t *\n\t\t * To disable TextWatcher:\n\t\t *\n\t\t *\t\tconst watcher = new TextWatcher( editor.model, testCallback );\n\t\t *\n\t\t *\t\t// After this a testCallback will not be called.\n\t\t *\t\twatcher.isEnabled = false;\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', true );\n\n\t\t// Toggle text watching on isEnabled state change.\n\t\tthis.on( 'change:isEnabled', () => {\n\t\t\tif ( this.isEnabled ) {\n\t\t\t\tthis._startListening();\n\t\t\t} else {\n\t\t\t\tthis.stopListening( model.document.selection );\n\t\t\t\tthis.stopListening( model.document );\n\t\t\t}\n\t\t} );\n\n\t\tthis._startListening();\n\t}\n\n\t/**\n\t * Starts listening to the editor for typing and selection events.\n\t *\n\t * @private\n\t */\n\t_startListening() {\n\t\tconst model = this.model;\n\t\tconst document = model.document;\n\n\t\tthis.listenTo( document.selection, 'change:range', ( evt, { directChange } ) => {\n\t\t\t// Indirect changes (i.e. when the user types or external changes are applied) are handled in the document's change event.\n\t\t\tif ( !directChange ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Act only on collapsed selection.\n\t\t\tif ( !document.selection.isCollapsed ) {\n\t\t\t\tif ( this.hasMatch ) {\n\t\t\t\t\tthis.fire( 'unmatched' );\n\t\t\t\t\tthis.hasMatch = false;\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._evaluateTextBeforeSelection( 'selection' );\n\t\t} );\n\n\t\tthis.listenTo( document, 'change:data', ( evt, batch ) => {\n\t\t\tif ( batch.type == 'transparent' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._evaluateTextBeforeSelection( 'data', { batch } );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the editor content for matched text.\n\t *\n\t * @fires matched:data\n\t * @fires matched:selection\n\t * @fires unmatched\n\t *\n\t * @private\n\t * @param {'data'|'selection'} suffix A suffix used for generating the event name.\n\t * @param {Object} data Data object for event.\n\t */\n\t_evaluateTextBeforeSelection( suffix, data = {} ) {\n\t\tconst model = this.model;\n\t\tconst document = model.document;\n\t\tconst selection = document.selection;\n\n\t\tconst rangeBeforeSelection = model.createRange( model.createPositionAt( selection.focus.parent, 0 ), selection.focus );\n\n\t\tconst { text, range } = getLastTextLine( rangeBeforeSelection, model );\n\n\t\tconst testResult = this.testCallback( text );\n\n\t\tif ( !testResult && this.hasMatch ) {\n\t\t\tthis.fire( 'unmatched' );\n\t\t}\n\n\t\tthis.hasMatch = !!testResult;\n\n\t\tif ( testResult ) {\n\t\t\tconst eventData = Object.assign( data, { text, range } );\n\n\t\t\t// If the test callback returns an object with additional data, assign the data as well.\n\t\t\tif ( typeof testResult == 'object' ) {\n\t\t\t\tObject.assign( eventData, testResult );\n\t\t\t}\n\n\t\t\tthis.fire( `matched:${ suffix }`, eventData );\n\t\t}\n\t}\n}\n\nmix( TextWatcher, ObservableMixin );\n\n/**\n * Fired whenever the text watcher found a match for data changes.\n *\n * @event matched:data\n * @param {Object} data Event data.\n * @param {String} data.text The full text before selection to which the regexp was applied.\n * @param {module:engine/model/range~Range} data.range The range representing the position of the `data.text`.\n * @param {Object} [data.testResult] The additional data returned from the {@link module:typing/textwatcher~TextWatcher#testCallback}.\n */\n\n/**\n * Fired whenever the text watcher found a match for selection changes.\n *\n * @event matched:selection\n * @param {Object} data Event data.\n * @param {String} data.text The full text before selection.\n * @param {module:engine/model/range~Range} data.range The range representing the position of the `data.text`.\n * @param {Object} [data.testResult] The additional data returned from the {@link module:typing/textwatcher~TextWatcher#testCallback}.\n */\n\n/**\n * Fired whenever the text does not match anymore. Fired only when the text watcher found a match.\n *\n * @event unmatched\n */\n"],"sourceRoot":""}