{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/selection.js"],"names":["Selection","selectable","arguments","length","undefined","placeOrOffset","options","Object","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_classCallCheck_js__WEBPACK_IMPORTED_MODULE_8__","this","_ranges","_lastRangeBackward","_isFake","_fakeSelectionLabel","setTo","range","anchor","end","start","clone","focus","rangeCount","isCollapsed","editableElement","getRanges","_iterator","_step","regeneratorRuntime","wrap","_context","prev","next","_createForOfIteratorHelper","s","n","done","value","t0","e","f","finish","stop","_step2","first","_iterator2","isBefore","err","_step3","last","_iterator3","isAfter","firstRange","getFirstRange","lastRange","getLastRange","otherSelection","isFake","fakeSelectionLabel","isEqual","_step4","_iterator4","_step5","thisRange","found","_iterator5","otherRange","isBackward","numOfRangesA","count","numOfRangesB","_step6","_iterator6","rangeA","getTrimmed","_step7","_iterator7","rangeB","getContainedElement","_setRanges","_setFakeOptions","DocumentSelection","fake","label","Range","backward","Position","Node","CKEditorError","_createIn","_createOn","_createAt","isIterable","fire","itemOrPosition","offset","newFocus","compareWith","pop","_addRange","type","newRanges","isLastBackward","Array","from","_step8","_iterator8","_pushRange","_step9","_iterator9","storedRange","isIntersecting","addedRange","intersectingRange","push","mix","EmitterMixin"],"mappings":"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","file":"js/chunk-2d0e1f70.cdfdee35.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 engine/view/selection\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport Range from './range';\nimport Position from './position';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport Node from './node';\nimport count from '@ckeditor/ckeditor5-utils/src/count';\nimport isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';\nimport DocumentSelection from './documentselection';\n\n/**\n * Class representing an arbirtary selection in the view.\n * See also {@link module:engine/view/documentselection~DocumentSelection}.\n *\n * New selection instances can be created via the constructor or one these methods:\n *\n * * {@link module:engine/view/view~View#createSelection `View#createSelection()`},\n * * {@link module:engine/view/upcastwriter~UpcastWriter#createSelection `UpcastWriter#createSelection()`}.\n *\n * A selection can consist of {@link module:engine/view/range~Range ranges} that can be set by using\n * the {@link module:engine/view/selection~Selection#setTo `Selection#setTo()`} method.\n */\nexport default class Selection {\n\t/**\n\t * Creates new selection instance.\n\t *\n\t * **Note**: The selection constructor is available as a factory method:\n\t *\n\t * * {@link module:engine/view/view~View#createSelection `View#createSelection()`},\n\t * * {@link module:engine/view/upcastwriter~UpcastWriter#createSelection `UpcastWriter#createSelection()`}.\n\t *\n\t * \t\t// Creates empty selection without ranges.\n\t *\t\tconst selection = writer.createSelection();\n\t *\n\t *\t\t// Creates selection at the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\tconst selection = writer.createSelection( range );\n\t *\n\t *\t\t// Creates selection at the given ranges\n\t * \t\tconst ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t *\t\tconst selection = writer.createSelection( ranges );\n\t *\n\t *\t\t// Creates selection from the other selection.\n\t *\t\tconst otherSelection = writer.createSelection();\n\t *\t\tconst selection = writer.createSelection( otherSelection );\n\t *\n\t *\t\t// Creates selection from the document selection.\n\t *\t\tconst selection = writer.createSelection( editor.editing.view.document.selection );\n\t *\n\t * \t\t// Creates selection at the given position.\n\t *\t\tconst position = writer.createPositionFromPath( root, path );\n\t *\t\tconst selection = writer.createSelection( position );\n\t *\n\t *\t\t// Creates collapsed selection at the position of given item and offset.\n\t *\t\tconst paragraph = writer.createContainerElement( 'paragraph' );\n\t *\t\tconst selection = writer.createSelection( paragraph, offset );\n\t *\n\t *\t\t// Creates a range inside an {@link module:engine/view/element~Element element} which starts before the\n\t *\t\t// first child of that element and ends after the last child of that element.\n\t *\t\tconst selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t *\t\t// Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends\n\t *\t\t// just after the item.\n\t *\t\tconst selection = writer.createSelection( paragraph, 'on' );\n\t *\n\t * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t *\t\t// Creates backward selection.\n\t *\t\tconst selection = writer.createSelection( range, { backward: true } );\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be properly handled by screen readers).\n\t *\n\t *\t\t// Creates fake selection with label.\n\t *\t\tconst selection = writer.createSelection( range, { fake: true, label: 'foo' } );\n\t *\n\t * @param {module:engine/view/selection~Selectable} [selectable=null]\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Offset or place when selectable is an `Item`.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.\n\t * @param {String} [options.label] Label for the fake selection.\n\t */\n\tconstructor( selectable = null, placeOrOffset, options ) {\n\t\t/**\n\t\t * Stores all ranges that are selected.\n\t\t *\n\t\t * @protected\n\t\t * @member {Array.}\n\t\t */\n\t\tthis._ranges = [];\n\n\t\t/**\n\t\t * Specifies whether the last added range was added as a backward or forward range.\n\t\t *\n\t\t * @protected\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis._lastRangeBackward = false;\n\n\t\t/**\n\t\t * Specifies whether selection instance is fake.\n\t\t *\n\t\t * @private\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis._isFake = false;\n\n\t\t/**\n\t\t * Fake selection's label.\n\t\t *\n\t\t * @private\n\t\t * @member {String}\n\t\t */\n\t\tthis._fakeSelectionLabel = '';\n\n\t\tthis.setTo( selectable, placeOrOffset, options );\n\t}\n\n\t/**\n\t * Returns true if selection instance is marked as `fake`.\n\t *\n\t * @see #setTo\n\t * @type {Boolean}\n\t */\n\tget isFake() {\n\t\treturn this._isFake;\n\t}\n\n\t/**\n\t * Returns fake selection label.\n\t *\n\t * @see #setTo\n\t * @type {String}\n\t */\n\tget fakeSelectionLabel() {\n\t\treturn this._fakeSelectionLabel;\n\t}\n\n\t/**\n\t * Selection anchor. Anchor may be described as a position where the selection starts. Together with\n\t * {@link #focus focus} they define the direction of selection, which is important\n\t * when expanding/shrinking selection. Anchor is always the start or end of the most recent added range.\n\t * It may be a bit unintuitive when there are multiple ranges in selection.\n\t *\n\t * @see #focus\n\t * @type {module:engine/view/position~Position}\n\t */\n\tget anchor() {\n\t\tif ( !this._ranges.length ) {\n\t\t\treturn null;\n\t\t}\n\t\tconst range = this._ranges[ this._ranges.length - 1 ];\n\t\tconst anchor = this._lastRangeBackward ? range.end : range.start;\n\n\t\treturn anchor.clone();\n\t}\n\n\t/**\n\t * Selection focus. Focus is a position where the selection ends.\n\t *\n\t * @see #anchor\n\t * @type {module:engine/view/position~Position}\n\t */\n\tget focus() {\n\t\tif ( !this._ranges.length ) {\n\t\t\treturn null;\n\t\t}\n\t\tconst range = this._ranges[ this._ranges.length - 1 ];\n\t\tconst focus = this._lastRangeBackward ? range.start : range.end;\n\n\t\treturn focus.clone();\n\t}\n\n\t/**\n\t * Returns whether the selection is collapsed. Selection is collapsed when there is exactly one range which is\n\t * collapsed.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isCollapsed() {\n\t\treturn this.rangeCount === 1 && this._ranges[ 0 ].isCollapsed;\n\t}\n\n\t/**\n\t * Returns number of ranges in selection.\n\t *\n\t * @type {Number}\n\t */\n\tget rangeCount() {\n\t\treturn this._ranges.length;\n\t}\n\n\t/**\n\t * Specifies whether the {@link #focus} precedes {@link #anchor}.\n\t *\n\t * @type {Boolean}\n\t */\n\tget isBackward() {\n\t\treturn !this.isCollapsed && this._lastRangeBackward;\n\t}\n\n\t/**\n\t * {@link module:engine/view/editableelement~EditableElement EditableElement} instance that contains this selection, or `null`\n\t * if the selection is not inside an editable element.\n\t *\n\t * @type {module:engine/view/editableelement~EditableElement|null}\n\t */\n\tget editableElement() {\n\t\tif ( this.anchor ) {\n\t\t\treturn this.anchor.editableElement;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns an iterable that contains copies of all ranges added to the selection.\n\t *\n\t * @returns {Iterable.}\n\t */\n\t* getRanges() {\n\t\tfor ( const range of this._ranges ) {\n\t\t\tyield range.clone();\n\t\t}\n\t}\n\n\t/**\n\t * Returns copy of the first range in the selection. First range is the one which\n\t * {@link module:engine/view/range~Range#start start} position {@link module:engine/view/position~Position#isBefore is before} start\n\t * position of all other ranges (not to confuse with the first range added to the selection).\n\t * Returns `null` if no ranges are added to selection.\n\t *\n\t * @returns {module:engine/view/range~Range|null}\n\t */\n\tgetFirstRange() {\n\t\tlet first = null;\n\n\t\tfor ( const range of this._ranges ) {\n\t\t\tif ( !first || range.start.isBefore( first.start ) ) {\n\t\t\t\tfirst = range;\n\t\t\t}\n\t\t}\n\n\t\treturn first ? first.clone() : null;\n\t}\n\n\t/**\n\t * Returns copy of the last range in the selection. Last range is the one which {@link module:engine/view/range~Range#end end}\n\t * position {@link module:engine/view/position~Position#isAfter is after} end position of all other ranges (not to confuse\n\t * with the last range added to the selection). Returns `null` if no ranges are added to selection.\n\t *\n\t * @returns {module:engine/view/range~Range|null}\n\t */\n\tgetLastRange() {\n\t\tlet last = null;\n\n\t\tfor ( const range of this._ranges ) {\n\t\t\tif ( !last || range.end.isAfter( last.end ) ) {\n\t\t\t\tlast = range;\n\t\t\t}\n\t\t}\n\n\t\treturn last ? last.clone() : null;\n\t}\n\n\t/**\n\t * Returns copy of the first position in the selection. First position is the position that\n\t * {@link module:engine/view/position~Position#isBefore is before} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t *\n\t * @returns {module:engine/view/position~Position|null}\n\t */\n\tgetFirstPosition() {\n\t\tconst firstRange = this.getFirstRange();\n\n\t\treturn firstRange ? firstRange.start.clone() : null;\n\t}\n\n\t/**\n\t * Returns copy of the last position in the selection. Last position is the position that\n\t * {@link module:engine/view/position~Position#isAfter is after} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t *\n\t * @returns {module:engine/view/position~Position|null}\n\t */\n\tgetLastPosition() {\n\t\tconst lastRange = this.getLastRange();\n\n\t\treturn lastRange ? lastRange.end.clone() : null;\n\t}\n\n\t/**\n\t * Checks whether, this selection is equal to given selection. Selections are equal if they have same directions,\n\t * same number of ranges and all ranges from one selection equal to a range from other selection.\n\t *\n\t * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} otherSelection\n\t * Selection to compare with.\n\t * @returns {Boolean} `true` if selections are equal, `false` otherwise.\n\t */\n\tisEqual( otherSelection ) {\n\t\tif ( this.isFake != otherSelection.isFake ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this.isFake && this.fakeSelectionLabel != otherSelection.fakeSelectionLabel ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this.rangeCount != otherSelection.rangeCount ) {\n\t\t\treturn false;\n\t\t} else if ( this.rangeCount === 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( !this.anchor.isEqual( otherSelection.anchor ) || !this.focus.isEqual( otherSelection.focus ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const thisRange of this._ranges ) {\n\t\t\tlet found = false;\n\n\t\t\tfor ( const otherRange of otherSelection._ranges ) {\n\t\t\t\tif ( thisRange.isEqual( otherRange ) ) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !found ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks whether this selection is similar to given selection. Selections are similar if they have same directions, same\n\t * number of ranges, and all {@link module:engine/view/range~Range#getTrimmed trimmed} ranges from one selection are\n\t * equal to any trimmed range from other selection.\n\t *\n\t * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} otherSelection\n\t * Selection to compare with.\n\t * @returns {Boolean} `true` if selections are similar, `false` otherwise.\n\t */\n\tisSimilar( otherSelection ) {\n\t\tif ( this.isBackward != otherSelection.isBackward ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst numOfRangesA = count( this.getRanges() );\n\t\tconst numOfRangesB = count( otherSelection.getRanges() );\n\n\t\t// If selections have different number of ranges, they cannot be similar.\n\t\tif ( numOfRangesA != numOfRangesB ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If both selections have no ranges, they are similar.\n\t\tif ( numOfRangesA == 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check if each range in one selection has a similar range in other selection.\n\t\tfor ( let rangeA of this.getRanges() ) {\n\t\t\trangeA = rangeA.getTrimmed();\n\n\t\t\tlet found = false;\n\n\t\t\tfor ( let rangeB of otherSelection.getRanges() ) {\n\t\t\t\trangeB = rangeB.getTrimmed();\n\n\t\t\t\tif ( rangeA.start.isEqual( rangeB.start ) && rangeA.end.isEqual( rangeB.end ) ) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// For `rangeA`, neither range in `otherSelection` was similar. So selections are not similar.\n\t\t\tif ( !found ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// There were no ranges that weren't matched. Selections are similar.\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns the selected element. {@link module:engine/view/element~Element Element} is considered as selected if there is only\n\t * one range in the selection, and that range contains exactly one element.\n\t * Returns `null` if there is no selected element.\n\t *\n\t * @returns {module:engine/view/element~Element|null}\n\t */\n\tgetSelectedElement() {\n\t\tif ( this.rangeCount !== 1 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.getFirstRange().getContainedElement();\n\t}\n\n\t/**\n\t * Sets this selection's ranges and direction to the specified location based on the given\n\t * {@link module:engine/view/selection~Selectable selectable}.\n\t *\n\t *\t\t// Sets selection to the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\tselection.setTo( range );\n\t *\n\t *\t\t// Sets selection to given ranges.\n\t * \t\tconst ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t *\t\tselection.setTo( range );\n\t *\n\t *\t\t// Sets selection to the other selection.\n\t *\t\tconst otherSelection = writer.createSelection();\n\t *\t\tselection.setTo( otherSelection );\n\t *\n\t *\t \t// Sets selection to contents of DocumentSelection.\n\t *\t\tselection.setTo( editor.editing.view.document.selection );\n\t *\n\t * \t\t// Sets collapsed selection at the given position.\n\t *\t\tconst position = writer.createPositionAt( root, path );\n\t *\t\tselection.setTo( position );\n\t *\n\t * \t\t// Sets collapsed selection at the position of given item and offset.\n\t *\t\tselection.setTo( paragraph, offset );\n\t *\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t *\t\tselection.setTo( paragraph, 'in' );\n\t *\n\t * Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends just after the item.\n\t *\n\t *\t\tselection.setTo( paragraph, 'on' );\n\t *\n\t * \t\t// Clears selection. Removes all ranges.\n\t *\t\tselection.setTo( null );\n\t *\n\t * `Selection#setTo()` method allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t *\t\t// Sets selection as backward.\n\t *\t\tselection.setTo( range, { backward: true } );\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be properly handled by screen readers).\n\t *\n\t *\t\t// Creates fake selection with label.\n\t *\t\tselection.setTo( range, { fake: true, label: 'foo' } );\n\t *\n\t * @fires change\n\t * @param {module:engine/view/selection~Selectable} selectable\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.\n\t * @param {String} [options.label] Label for the fake selection.\n\t */\n\tsetTo( selectable, placeOrOffset, options ) {\n\t\tif ( selectable === null ) {\n\t\t\tthis._setRanges( [] );\n\t\t\tthis._setFakeOptions( placeOrOffset );\n\t\t} else if ( selectable instanceof Selection || selectable instanceof DocumentSelection ) {\n\t\t\tthis._setRanges( selectable.getRanges(), selectable.isBackward );\n\t\t\tthis._setFakeOptions( { fake: selectable.isFake, label: selectable.fakeSelectionLabel } );\n\t\t} else if ( selectable instanceof Range ) {\n\t\t\tthis._setRanges( [ selectable ], placeOrOffset && placeOrOffset.backward );\n\t\t\tthis._setFakeOptions( placeOrOffset );\n\t\t} else if ( selectable instanceof Position ) {\n\t\t\tthis._setRanges( [ new Range( selectable ) ] );\n\t\t\tthis._setFakeOptions( placeOrOffset );\n\t\t} else if ( selectable instanceof Node ) {\n\t\t\tconst backward = !!options && !!options.backward;\n\t\t\tlet range;\n\n\t\t\tif ( placeOrOffset === undefined ) {\n\t\t\t\t/**\n\t\t\t\t * selection.setTo requires the second parameter when the first parameter is a node.\n\t\t\t\t *\n\t\t\t\t * @error view-selection-setto-required-second-parameter\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'view-selection-setto-required-second-parameter', this );\n\t\t\t} else if ( placeOrOffset == 'in' ) {\n\t\t\t\trange = Range._createIn( selectable );\n\t\t\t} else if ( placeOrOffset == 'on' ) {\n\t\t\t\trange = Range._createOn( selectable );\n\t\t\t} else {\n\t\t\t\trange = new Range( Position._createAt( selectable, placeOrOffset ) );\n\t\t\t}\n\n\t\t\tthis._setRanges( [ range ], backward );\n\t\t\tthis._setFakeOptions( options );\n\t\t} else if ( isIterable( selectable ) ) {\n\t\t\t// We assume that the selectable is an iterable of ranges.\n\t\t\t// Array.from() is used to prevent setting ranges to the old iterable\n\t\t\tthis._setRanges( selectable, placeOrOffset && placeOrOffset.backward );\n\t\t\tthis._setFakeOptions( placeOrOffset );\n\t\t} else {\n\t\t\t/**\n\t\t\t * Cannot set selection to given place.\n\t\t\t *\n\t\t\t * @error view-selection-setto-not-selectable\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-selection-setto-not-selectable', this );\n\t\t}\n\n\t\tthis.fire( 'change' );\n\t}\n\n\t/**\n\t * Moves {@link #focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as {@link module:engine/view/view~View#createPositionAt view.createPositionAt()}\n\t * parameters.\n\t *\n\t * @fires change\n\t * @param {module:engine/view/item~Item|module:engine/view/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tsetFocus( itemOrPosition, offset ) {\n\t\tif ( this.anchor === null ) {\n\t\t\t/**\n\t\t\t * Cannot set selection focus if there are no ranges in selection.\n\t\t\t *\n\t\t\t * @error view-selection-setfocus-no-ranges\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-selection-setfocus-no-ranges', this );\n\t\t}\n\n\t\tconst newFocus = Position._createAt( itemOrPosition, offset );\n\n\t\tif ( newFocus.compareWith( this.focus ) == 'same' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst anchor = this.anchor;\n\n\t\tthis._ranges.pop();\n\n\t\tif ( newFocus.compareWith( anchor ) == 'before' ) {\n\t\t\tthis._addRange( new Range( newFocus, anchor ), true );\n\t\t} else {\n\t\t\tthis._addRange( new Range( anchor, newFocus ) );\n\t\t}\n\n\t\tthis.fire( 'change' );\n\t}\n\n\t/**\n\t * Checks whether this object is of the given type.\n\t *\n\t *\t\tselection.is( 'selection' ); // -> true\n\t *\t\tselection.is( 'view:selection' ); // -> true\n\t *\n\t *\t\tselection.is( 'model:selection' ); // -> false\n\t *\t\tselection.is( 'element' ); // -> false\n\t *\t\tselection.is( 'range' ); // -> false\n\t *\n\t * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.\n\t *\n\t * @param {String} type\n\t * @returns {Boolean}\n\t */\n\tis( type ) {\n\t\treturn type === 'selection' || type === 'view:selection';\n\t}\n\n\t/**\n\t * Replaces all ranges that were added to the selection with given array of ranges. Last range of the array\n\t * is treated like the last added range and is used to set {@link #anchor anchor} and {@link #focus focus}.\n\t * Accepts a flag describing in which way the selection is made.\n\t *\n\t * @private\n\t * @param {Iterable.} newRanges Iterable object of ranges to set.\n\t * @param {Boolean} [isLastBackward=false] Flag describing if last added range was selected forward - from start to end\n\t * (`false`) or backward - from end to start (`true`). Defaults to `false`.\n\t */\n\t_setRanges( newRanges, isLastBackward = false ) {\n\t\t// New ranges should be copied to prevent removing them by setting them to `[]` first.\n\t\t// Only applies to situations when selection is set to the same selection or same selection's ranges.\n\t\tnewRanges = Array.from( newRanges );\n\n\t\tthis._ranges = [];\n\n\t\tfor ( const range of newRanges ) {\n\t\t\tthis._addRange( range );\n\t\t}\n\n\t\tthis._lastRangeBackward = !!isLastBackward;\n\t}\n\n\t/**\n\t * Sets this selection instance to be marked as `fake`. A fake selection does not render as browser native selection\n\t * over selected elements and is hidden to the user. This way, no native selection UI artifacts are displayed to\n\t * the user and selection over elements can be represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM (and be\n\t * properly handled by screen readers).\n\t *\n\t * @private\n\t * @param {Object} [options] Options.\n\t * @param {Boolean} [options.fake] If set to true selection will be marked as `fake`.\n\t * @param {String} [options.label=''] Fake selection label.\n\t */\n\t_setFakeOptions( options = {} ) {\n\t\tthis._isFake = !!options.fake;\n\t\tthis._fakeSelectionLabel = options.fake ? options.label || '' : '';\n\t}\n\n\t/**\n\t * Adds a range to the selection. Added range is copied. This means that passed range is not saved in the\n\t * selection instance and you can safely operate on it.\n\t *\n\t * Accepts a flag describing in which way the selection is made - passed range might be selected from\n\t * {@link module:engine/view/range~Range#start start} to {@link module:engine/view/range~Range#end end}\n\t * or from {@link module:engine/view/range~Range#end end} to {@link module:engine/view/range~Range#start start}.\n\t * The flag is used to set {@link #anchor anchor} and {@link #focus focus} properties.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-selection-range-intersects` if added range intersects\n\t * with ranges already stored in Selection instance.\n\t *\n\t * @private\n\t * @fires change\n\t * @param {module:engine/view/range~Range} range\n\t * @param {Boolean} [isBackward]\n\t */\n\t_addRange( range, isBackward = false ) {\n\t\tif ( !( range instanceof Range ) ) {\n\t\t\t/**\n\t\t\t * Selection range set to an object that is not an instance of {@link module:engine/view/range~Range}.\n\t\t\t *\n\t\t\t * @error view-selection-add-range-not-range\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-selection-add-range-not-range',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\tthis._pushRange( range );\n\t\tthis._lastRangeBackward = !!isBackward;\n\t}\n\n\t/**\n\t * Adds range to selection - creates copy of given range so it can be safely used and modified.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-selection-range-intersects` if added range intersects\n\t * with ranges already stored in selection instance.\n\t *\n\t * @private\n\t * @param {module:engine/view/range~Range} range\n\t */\n\t_pushRange( range ) {\n\t\tfor ( const storedRange of this._ranges ) {\n\t\t\tif ( range.isIntersecting( storedRange ) ) {\n\t\t\t\t/**\n\t\t\t\t * Trying to add a range that intersects with another range from selection.\n\t\t\t\t *\n\t\t\t\t * @error view-selection-range-intersects\n\t\t\t\t * @param {module:engine/view/range~Range} addedRange Range that was added to the selection.\n\t\t\t\t * @param {module:engine/view/range~Range} intersectingRange Range from selection that intersects with `addedRange`.\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'view-selection-range-intersects',\n\t\t\t\t\tthis,\n\t\t\t\t\t{ addedRange: range, intersectingRange: storedRange }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tthis._ranges.push( new Range( range.start, range.end ) );\n\t}\n\n\t/**\n\t * Fired whenever selection ranges are changed through {@link ~Selection Selection API}.\n\t *\n\t * @event change\n\t */\n}\n\nmix( Selection, EmitterMixin );\n\n/**\n * An entity that is used to set selection.\n *\n * See also {@link module:engine/view/selection~Selection#setTo}\n *\n * @typedef {\n * module:engine/view/selection~Selection|\n * module:engine/view/documentselection~DocumentSelection|\n * module:engine/view/position~Position|\n * Iterable.|\n * module:engine/view/range~Range|\n * module:engine/view/item~Item|\n * null\n * } module:engine/view/selection~Selectable\n */\n"],"sourceRoot":""}