{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-widget/src/highlightstack.js","webpack:///./node_modules/@ckeditor/ckeditor5-widget/src/utils.js","webpack:///./node_modules/@ckeditor/ckeditor5-widget/src/index.js"],"names":["HighlightStack","Object","classCallCheck","this","_stack","descriptor","writer","stack","oldTop","_insertDescriptor","newTop","compareDescriptors","fire","oldDescriptor","newDescriptor","id","_removeDescriptor","index","findIndex","item","splice","i","shouldABeBeforeB","a","b","priority","classesToString","classes","Array","isArray","sort","join","mix","EmitterMixin","WIDGET_CLASS_NAME","WIDGET_SELECTED_CLASS_NAME","isWidget","node","is","getCustomProperty","toWidget","element","options","arguments","length","undefined","CKEditorError","setAttribute","addClass","setCustomProperty","getFillerOffset","label","setLabel","hasSelectionHandle","addSelectionHandle","setHighlightHandling","addHighlight","removeHighlight","toArray","attributes","key","removeClass","removeAttribute","add","remove","on","evt","data","labelOrCreator","getLabel","labelCreator","toWidgetEditable","editable","isReadOnly","property","findOptimalInsertionRange","selection","model","selectedElement","getSelectedElement","typeAroundFakeCaretPosition","getTypeAroundFakeCaretPosition","createRange","createPositionAt","schema","isObject","isInline","createRangeOn","firstBlock","getSelectedBlocks","next","value","isEmpty","positionAfter","createPositionAfter","focus","isTouching","createPositionBefore","centeredBalloonPositionForLongWidgets","widgetRect","balloonRect","viewportRect","Rect","global","window","viewportWidgetInsersectionRect","getIntersection","balloonTotalHeight","height","BalloonPanelView","arrowVerticalOffset","top","bottom","targetRect","left","width","Math","max","name","widgetElement","selectionHandle","createUIElement","class","domDocument","domElement","toDomElement","icon","IconView","set","dragHandleIcon","render","appendChild","insert","_widget__WEBPACK_IMPORTED_MODULE_0__","__webpack_require__","d","__webpack_exports__","_widgettoolbarrepository__WEBPACK_IMPORTED_MODULE_1__","_utils__WEBPACK_IMPORTED_MODULE_4__"],"mappings":"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","file":"js/chunk-0d1b57b4.6c74b28e.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 widget/highlightstack\n */\n\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * Class used to handle correct order of highlights on elements.\n *\n * When different highlights are applied to same element correct order should be preserved:\n *\n * * highlight with highest priority should be applied,\n * * if two highlights have same priority - sort by CSS class provided in\n * {@link module:engine/conversion/downcasthelpers~HighlightDescriptor}.\n *\n * This way, highlight will be applied with the same rules it is applied on texts.\n */\nexport default class HighlightStack {\n\t/**\n\t * Creates class instance.\n\t */\n\tconstructor() {\n\t\tthis._stack = [];\n\t}\n\n\t/**\n\t * Adds highlight descriptor to the stack.\n\t *\n\t * @fires change:top\n\t * @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} descriptor\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n\t */\n\tadd( descriptor, writer ) {\n\t\tconst stack = this._stack;\n\n\t\t// Save top descriptor and insert new one. If top is changed - fire event.\n\t\tconst oldTop = stack[ 0 ];\n\t\tthis._insertDescriptor( descriptor );\n\t\tconst newTop = stack[ 0 ];\n\n\t\t// When new object is at the top and stores different information.\n\t\tif ( oldTop !== newTop && !compareDescriptors( oldTop, newTop ) ) {\n\t\t\tthis.fire( 'change:top', {\n\t\t\t\toldDescriptor: oldTop,\n\t\t\t\tnewDescriptor: newTop,\n\t\t\t\twriter\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Removes highlight descriptor from the stack.\n\t *\n\t * @fires change:top\n\t * @param {String} id Id of the descriptor to remove.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n\t */\n\tremove( id, writer ) {\n\t\tconst stack = this._stack;\n\n\t\tconst oldTop = stack[ 0 ];\n\t\tthis._removeDescriptor( id );\n\t\tconst newTop = stack[ 0 ];\n\n\t\t// When new object is at the top and stores different information.\n\t\tif ( oldTop !== newTop && !compareDescriptors( oldTop, newTop ) ) {\n\t\t\tthis.fire( 'change:top', {\n\t\t\t\toldDescriptor: oldTop,\n\t\t\t\tnewDescriptor: newTop,\n\t\t\t\twriter\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Inserts given descriptor in correct place in the stack. It also takes care about updating information when\n\t * descriptor with same id is already present.\n\t *\n\t * @private\n\t * @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} descriptor\n\t */\n\t_insertDescriptor( descriptor ) {\n\t\tconst stack = this._stack;\n\t\tconst index = stack.findIndex( item => item.id === descriptor.id );\n\n\t\t// Inserting exact same descriptor - do nothing.\n\t\tif ( compareDescriptors( descriptor, stack[ index ] ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If descriptor with same id but with different information is on the stack - remove it.\n\t\tif ( index > -1 ) {\n\t\t\tstack.splice( index, 1 );\n\t\t}\n\n\t\t// Find correct place to insert descriptor in the stack.\n\t\t// It have different information (for example priority) so it must be re-inserted in correct place.\n\t\tlet i = 0;\n\n\t\twhile ( stack[ i ] && shouldABeBeforeB( stack[ i ], descriptor ) ) {\n\t\t\ti++;\n\t\t}\n\n\t\tstack.splice( i, 0, descriptor );\n\t}\n\n\t/**\n\t * Removes descriptor with given id from the stack.\n\t *\n\t * @private\n\t * @param {String} id Descriptor's id.\n\t */\n\t_removeDescriptor( id ) {\n\t\tconst stack = this._stack;\n\t\tconst index = stack.findIndex( item => item.id === id );\n\n\t\t// If descriptor with same id is on the list - remove it.\n\t\tif ( index > -1 ) {\n\t\t\tstack.splice( index, 1 );\n\t\t}\n\t}\n}\n\nmix( HighlightStack, EmitterMixin );\n\n// Compares two descriptors by checking their priority and class list.\n//\n// @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} a\n// @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} b\n// @returns {Boolean} Returns true if both descriptors are defined and have same priority and classes.\nfunction compareDescriptors( a, b ) {\n\treturn a && b && a.priority == b.priority && classesToString( a.classes ) == classesToString( b.classes );\n}\n\n// Checks whenever first descriptor should be placed in the stack before second one.\n//\n// @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} a\n// @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} b\n// @returns {Boolean}\nfunction shouldABeBeforeB( a, b ) {\n\tif ( a.priority > b.priority ) {\n\t\treturn true;\n\t} else if ( a.priority < b.priority ) {\n\t\treturn false;\n\t}\n\n\t// When priorities are equal and names are different - use classes to compare.\n\treturn classesToString( a.classes ) > classesToString( b.classes );\n}\n\n// Converts CSS classes passed with {@link module:engine/conversion/downcasthelpers~HighlightDescriptor} to\n// sorted string.\n//\n// @param {String|Array} descriptor\n// @returns {String}\nfunction classesToString( classes ) {\n\treturn Array.isArray( classes ) ? classes.sort().join( ',' ) : classes;\n}\n\n/**\n * Fired when top element on {@link module:widget/highlightstack~HighlightStack} has been changed\n *\n * @event change:top\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} [data.newDescriptor] New highlight\n * descriptor. It will be `undefined` when last descriptor is removed from the stack.\n * @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} [data.oldDescriptor] Old highlight\n * descriptor. It will be `undefined` when first descriptor is added to the stack.\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that can be used to modify element.\n */\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 widget/utils\n */\n\nimport BalloonPanelView from '@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview';\n\nimport global from '@ckeditor/ckeditor5-utils/src/dom/global';\nimport Rect from '@ckeditor/ckeditor5-utils/src/dom/rect';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport toArray from '@ckeditor/ckeditor5-utils/src/toarray';\n\nimport HighlightStack from './highlightstack';\nimport { getTypeAroundFakeCaretPosition } from './widgettypearound/utils';\n\nimport IconView from '@ckeditor/ckeditor5-ui/src/icon/iconview';\nimport dragHandleIcon from '../theme/icons/drag-handle.svg';\n\n/**\n * CSS class added to each widget element.\n *\n * @const {String}\n */\nexport const WIDGET_CLASS_NAME = 'ck-widget';\n\n/**\n * CSS class added to currently selected widget element.\n *\n * @const {String}\n */\nexport const WIDGET_SELECTED_CLASS_NAME = 'ck-widget_selected';\n\n/**\n * Returns `true` if given {@link module:engine/view/node~Node} is an {@link module:engine/view/element~Element} and a widget.\n *\n * @param {module:engine/view/node~Node} node\n * @returns {Boolean}\n */\nexport function isWidget( node ) {\n\tif ( !node.is( 'element' ) ) {\n\t\treturn false;\n\t}\n\n\treturn !!node.getCustomProperty( 'widget' );\n}\n\n/**\n * Converts the given {@link module:engine/view/element~Element} to a widget in the following way:\n *\n * * sets the `contenteditable` attribute to `\"false\"`,\n * * adds the `ck-widget` CSS class,\n * * adds a custom {@link module:engine/view/element~Element#getFillerOffset `getFillerOffset()`} method returning `null`,\n * * adds a custom property allowing to recognize widget elements by using {@link ~isWidget `isWidget()`},\n * * implements the {@link ~setHighlightHandling view highlight on widgets}.\n *\n * This function needs to be used in conjunction with\n * {@link module:engine/conversion/downcasthelpers~DowncastHelpers downcast conversion helpers}\n * like {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`}.\n * Moreover, typically you will want to use `toWidget()` only for `editingDowncast`, while keeping the `dataDowncast` clean.\n *\n * For example, in order to convert a `` model element to `
` in the view, you can define\n * such converters:\n *\n *\t\teditor.conversion.for( 'editingDowncast' )\n *\t\t\t.elementToElement( {\n *\t\t\t\tmodel: 'widget',\n *\t\t\t\tview: ( modelItem, { writer } ) => {\n *\t\t\t\t\tconst div = writer.createContainerElement( 'div', { class: 'widget' } );\n *\n *\t\t\t\t\treturn toWidget( div, writer, { label: 'some widget' } );\n *\t\t\t\t}\n *\t\t\t} );\n *\n *\t\teditor.conversion.for( 'dataDowncast' )\n *\t\t\t.elementToElement( {\n *\t\t\t\tmodel: 'widget',\n *\t\t\t\tview: ( modelItem, { writer } ) => {\n *\t\t\t\t\treturn writer.createContainerElement( 'div', { class: 'widget' } );\n *\t\t\t\t}\n *\t\t\t} );\n *\n * See the full source code of the widget (with a nested editable) schema definition and converters in\n * [this sample](https://github.com/ckeditor/ckeditor5-widget/blob/master/tests/manual/widget-with-nestededitable.js).\n *\n * @param {module:engine/view/element~Element} element\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n * @param {Object} [options={}]\n * @param {String|Function} [options.label] Element's label provided to the {@link ~setLabel} function. It can be passed as\n * a plain string or a function returning a string. It represents the widget for assistive technologies (like screen readers).\n * @param {Boolean} [options.hasSelectionHandle=false] If `true`, the widget will have a selection handle added.\n * @returns {module:engine/view/element~Element} Returns the same element.\n */\nexport function toWidget( element, writer, options = {} ) {\n\tif ( !element.is( 'containerElement' ) ) {\n\t\t/**\n\t\t * The element passed to `toWidget()` must be a {@link module:engine/view/containerelement~ContainerElement}\n\t\t * instance.\n\t\t *\n\t\t * @error widget-to-widget-wrong-element-type\n\t\t * @param {String} element The view element passed to `toWidget()`.\n\t\t */\n\t\tthrow new CKEditorError(\n\t\t\t'widget-to-widget-wrong-element-type',\n\t\t\tnull,\n\t\t\t{ element }\n\t\t);\n\t}\n\n\twriter.setAttribute( 'contenteditable', 'false', element );\n\n\twriter.addClass( WIDGET_CLASS_NAME, element );\n\twriter.setCustomProperty( 'widget', true, element );\n\telement.getFillerOffset = getFillerOffset;\n\n\tif ( options.label ) {\n\t\tsetLabel( element, options.label, writer );\n\t}\n\n\tif ( options.hasSelectionHandle ) {\n\t\taddSelectionHandle( element, writer );\n\t}\n\n\tsetHighlightHandling( element, writer, addHighlight, removeHighlight );\n\n\treturn element;\n}\n\n// Default handler for adding a highlight on a widget.\n// It adds CSS class and attributes basing on the given highlight descriptor.\n//\n// @param {module:engine/view/element~Element} element\n// @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} descriptor\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\nfunction addHighlight( element, descriptor, writer ) {\n\tif ( descriptor.classes ) {\n\t\twriter.addClass( toArray( descriptor.classes ), element );\n\t}\n\n\tif ( descriptor.attributes ) {\n\t\tfor ( const key in descriptor.attributes ) {\n\t\t\twriter.setAttribute( key, descriptor.attributes[ key ], element );\n\t\t}\n\t}\n}\n\n// Default handler for removing a highlight from a widget.\n// It removes CSS class and attributes basing on the given highlight descriptor.\n//\n// @param {module:engine/view/element~Element} element\n// @param {module:engine/conversion/downcasthelpers~HighlightDescriptor} descriptor\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\nfunction removeHighlight( element, descriptor, writer ) {\n\tif ( descriptor.classes ) {\n\t\twriter.removeClass( toArray( descriptor.classes ), element );\n\t}\n\n\tif ( descriptor.attributes ) {\n\t\tfor ( const key in descriptor.attributes ) {\n\t\t\twriter.removeAttribute( key, element );\n\t\t}\n\t}\n}\n\n/**\n * Sets highlight handling methods. Uses {@link module:widget/highlightstack~HighlightStack} to\n * properly determine which highlight descriptor should be used at given time.\n *\n * @param {module:engine/view/element~Element} element\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n * @param {Function} add\n * @param {Function} remove\n */\nexport function setHighlightHandling( element, writer, add, remove ) {\n\tconst stack = new HighlightStack();\n\n\tstack.on( 'change:top', ( evt, data ) => {\n\t\tif ( data.oldDescriptor ) {\n\t\t\tremove( element, data.oldDescriptor, data.writer );\n\t\t}\n\n\t\tif ( data.newDescriptor ) {\n\t\t\tadd( element, data.newDescriptor, data.writer );\n\t\t}\n\t} );\n\n\twriter.setCustomProperty( 'addHighlight', ( element, descriptor, writer ) => stack.add( descriptor, writer ), element );\n\twriter.setCustomProperty( 'removeHighlight', ( element, id, writer ) => stack.remove( id, writer ), element );\n}\n\n/**\n * Sets label for given element.\n * It can be passed as a plain string or a function returning a string. Function will be called each time label is retrieved by\n * {@link ~getLabel `getLabel()`}.\n *\n * @param {module:engine/view/element~Element} element\n * @param {String|Function} labelOrCreator\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n */\nexport function setLabel( element, labelOrCreator, writer ) {\n\twriter.setCustomProperty( 'widgetLabel', labelOrCreator, element );\n}\n\n/**\n * Returns the label of the provided element.\n *\n * @param {module:engine/view/element~Element} element\n * @returns {String}\n */\nexport function getLabel( element ) {\n\tconst labelCreator = element.getCustomProperty( 'widgetLabel' );\n\n\tif ( !labelCreator ) {\n\t\treturn '';\n\t}\n\n\treturn typeof labelCreator == 'function' ? labelCreator() : labelCreator;\n}\n\n/**\n * Adds functionality to the provided {@link module:engine/view/editableelement~EditableElement} to act as a widget's editable:\n *\n * * sets the `contenteditable` attribute to `true` when {@link module:engine/view/editableelement~EditableElement#isReadOnly} is `false`,\n * otherwise sets it to `false`,\n * * adds the `ck-editor__editable` and `ck-editor__nested-editable` CSS classes,\n * * adds the `ck-editor__nested-editable_focused` CSS class when the editable is focused and removes it when it is blurred.\n *\n * Similarly to {@link ~toWidget `toWidget()`} this function should be used in `editingDowncast` only and it is usually\n * used together with {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`}.\n *\n * For example, in order to convert a `` model element to `
` in the view, you can define\n * such converters:\n *\n *\t\teditor.conversion.for( 'editingDowncast' )\n *\t\t\t.elementToElement( {\n *\t\t\t\tmodel: 'nested',\n *\t\t\t\tview: ( modelItem, { writer } ) => {\n *\t\t\t\t\tconst div = writer.createEditableElement( 'div', { class: 'nested' } );\n *\n *\t\t\t\t\treturn toWidgetEditable( nested, writer );\n *\t\t\t\t}\n *\t\t\t} );\n *\n *\t\teditor.conversion.for( 'dataDowncast' )\n *\t\t\t.elementToElement( {\n *\t\t\t\tmodel: 'nested',\n *\t\t\t\tview: ( modelItem, { writer } ) => {\n *\t\t\t\t\treturn writer.createContainerElement( 'div', { class: 'nested' } );\n *\t\t\t\t}\n *\t\t\t} );\n *\n * See the full source code of the widget (with nested editable) schema definition and converters in\n * [this sample](https://github.com/ckeditor/ckeditor5-widget/blob/master/tests/manual/widget-with-nestededitable.js).\n *\n * @param {module:engine/view/editableelement~EditableElement} editable\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n * @returns {module:engine/view/editableelement~EditableElement} Returns the same element that was provided in the `editable` parameter\n */\nexport function toWidgetEditable( editable, writer ) {\n\twriter.addClass( [ 'ck-editor__editable', 'ck-editor__nested-editable' ], editable );\n\n\t// Set initial contenteditable value.\n\twriter.setAttribute( 'contenteditable', editable.isReadOnly ? 'false' : 'true', editable );\n\n\t// Bind the contenteditable property to element#isReadOnly.\n\teditable.on( 'change:isReadOnly', ( evt, property, is ) => {\n\t\twriter.setAttribute( 'contenteditable', is ? 'false' : 'true', editable );\n\t} );\n\n\teditable.on( 'change:isFocused', ( evt, property, is ) => {\n\t\tif ( is ) {\n\t\t\twriter.addClass( 'ck-editor__nested-editable_focused', editable );\n\t\t} else {\n\t\t\twriter.removeClass( 'ck-editor__nested-editable_focused', editable );\n\t\t}\n\t} );\n\n\treturn editable;\n}\n\n/**\n * Returns a model range which is optimal (in terms of UX) for inserting a widget block.\n *\n * For instance, if a selection is in the middle of a paragraph, the collapsed range before this paragraph\n * will be returned so that it is not split. If the selection is at the end of a paragraph,\n * the collapsed range after this paragraph will be returned.\n *\n * Note: If the selection is placed in an empty block, the range in that block will be returned. If that range\n * is then passed to {@link module:engine/model/model~Model#insertContent}, the block will be fully replaced\n * by the inserted widget block.\n *\n * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection\n * The selection based on which the insertion position should be calculated.\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {module:engine/model/range~Range} The optimal range.\n */\nexport function findOptimalInsertionRange( selection, model ) {\n\tconst selectedElement = selection.getSelectedElement();\n\n\tif ( selectedElement ) {\n\t\tconst typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition( selection );\n\n\t\t// If the WidgetTypeAround \"fake caret\" is displayed, use its position for the insertion\n\t\t// to provide the most predictable UX (https://github.com/ckeditor/ckeditor5/issues/7438).\n\t\tif ( typeAroundFakeCaretPosition ) {\n\t\t\treturn model.createRange( model.createPositionAt( selectedElement, typeAroundFakeCaretPosition ) );\n\t\t}\n\n\t\tif ( model.schema.isObject( selectedElement ) && !model.schema.isInline( selectedElement ) ) {\n\t\t\treturn model.createRangeOn( selectedElement );\n\t\t}\n\t}\n\n\tconst firstBlock = selection.getSelectedBlocks().next().value;\n\n\tif ( firstBlock ) {\n\t\t// If inserting into an empty block – return position in that block. It will get\n\t\t// replaced with the image by insertContent(). #42.\n\t\tif ( firstBlock.isEmpty ) {\n\t\t\treturn model.createRange( model.createPositionAt( firstBlock, 0 ) );\n\t\t}\n\n\t\tconst positionAfter = model.createPositionAfter( firstBlock );\n\n\t\t// If selection is at the end of the block - return position after the block.\n\t\tif ( selection.focus.isTouching( positionAfter ) ) {\n\t\t\treturn model.createRange( positionAfter );\n\t\t}\n\n\t\t// Otherwise return position before the block.\n\t\treturn model.createRange( model.createPositionBefore( firstBlock ) );\n\t}\n\n\treturn model.createRange( selection.focus );\n}\n\n/**\n * A util to be used in order to map view positions to correct model positions when implementing a widget\n * which renders non-empty view element for an empty model element.\n *\n * For example:\n *\n *\t\t// Model:\n *\t\t\n *\n *\t\t// View:\n *\t\tname\n *\n * In such case, view positions inside `` cannot be correct mapped to the model (because the model element is empty).\n * To handle mapping positions inside `` to the model use this util as follows:\n *\n *\t\teditor.editing.mapper.on(\n *\t\t\t'viewToModelPosition',\n *\t\t\tviewToModelPositionOutsideModelElement( model, viewElement => viewElement.hasClass( 'placeholder' ) )\n *\t\t);\n *\n * The callback will try to map the view offset of selection to an expected model position.\n *\n * 1. When the position is at the end (or in the middle) of the inline widget:\n *\n *\t\t// View:\n *\t\t

foo name| bar

\n *\n *\t\t// Model:\n *\t\tfoo | bar\n *\n * 2. When the position is at the beginning of the inline widget:\n *\n *\t\t// View:\n *\t\t

foo |name bar

\n *\n *\t\t// Model:\n *\t\tfoo | bar\n *\n * @param {module:engine/model/model~Model} model Model instance on which the callback operates.\n * @param {Function} viewElementMatcher Function that is passed a view element and should return `true` if the custom mapping\n * should be applied to the given view element.\n * @return {Function}\n */\nexport function viewToModelPositionOutsideModelElement( model, viewElementMatcher ) {\n\treturn ( evt, data ) => {\n\t\tconst { mapper, viewPosition } = data;\n\n\t\tconst viewParent = mapper.findMappedViewAncestor( viewPosition );\n\n\t\tif ( !viewElementMatcher( viewParent ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelParent = mapper.toModelElement( viewParent );\n\n\t\tdata.modelPosition = model.createPositionAt( modelParent, viewPosition.isAtStart ? 'before' : 'after' );\n\t};\n}\n\n/**\n * A positioning function passed to the {@link module:utils/dom/position~getOptimalPosition} helper as a last resort\n * when attaching {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView balloon UI} to widgets.\n * It comes in handy when a widget is longer than the visual viewport of the web browser and/or upper/lower boundaries\n * of a widget are off screen because of the web page scroll.\n *\n *\t ┌─┄┄┄┄┄┄┄┄┄Widget┄┄┄┄┄┄┄┄┄┐\n *\t ┊ ┊\n *\t┌────────────Viewport───────────┐ ┌──╁─────────Viewport────────╁──┐\n *\t│ ┏━━━━━━━━━━Widget━━━━━━━━━┓ │ │ ┃ ^ ┃ │\n *\t│ ┃ ^ ┃ │ │ ┃ ╭───────/ \\───────╮ ┃ │\n *\t│ ┃ ╭───────/ \\───────╮ ┃ │ │ ┃ │ Balloon │ ┃ │\n *\t│ ┃ │ Balloon │ ┃ │ │ ┃ ╰─────────────────╯ ┃ │\n *\t│ ┃ ╰─────────────────╯ ┃ │ │ ┃ ┃ │\n *\t│ ┃ ┃ │ │ ┃ ┃ │\n *\t│ ┃ ┃ │ │ ┃ ┃ │\n *\t│ ┃ ┃ │ │ ┃ ┃ │\n *\t│ ┃ ┃ │ │ ┃ ┃ │\n *\t│ ┃ ┃ │ │ ┃ ┃ │\n *\t│ ┃ ┃ │ │ ┃ ┃ │\n *\t└──╀─────────────────────────╀──┘ └──╀─────────────────────────╀──┘\n *\t ┊ ┊ ┊ ┊\n *\t ┊ ┊ └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘\n *\t ┊ ┊\n *\t └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘\n *\n * **Note**: Works best if used together with\n * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions default `BalloonPanelView` positions}\n * like `northArrowSouth` and `southArrowNorth`; the transition between these two and this position is smooth.\n *\n * @param {module:utils/dom/rect~Rect} widgetRect A rect of the widget.\n * @param {module:utils/dom/rect~Rect} balloonRect A rect of the balloon.\n * @returns {module:utils/dom/position~Position|null}\n */\nexport function centeredBalloonPositionForLongWidgets( widgetRect, balloonRect ) {\n\tconst viewportRect = new Rect( global.window );\n\tconst viewportWidgetInsersectionRect = viewportRect.getIntersection( widgetRect );\n\n\tconst balloonTotalHeight = balloonRect.height + BalloonPanelView.arrowVerticalOffset;\n\n\t// If there is enough space above or below the widget then this position should not be used.\n\tif ( widgetRect.top - balloonTotalHeight > viewportRect.top || widgetRect.bottom + balloonTotalHeight < viewportRect.bottom ) {\n\t\treturn null;\n\t}\n\n\t// Because this is a last resort positioning, to keep things simple we're not playing with positions of the arrow\n\t// like, for instance, \"south west\" or whatever. Just try to keep the balloon in the middle of the visible area of\n\t// the widget for as long as it is possible. If the widgets becomes invisible (because cropped by the viewport),\n\t// just... place the balloon in the middle of it (because why not?).\n\tconst targetRect = viewportWidgetInsersectionRect || widgetRect;\n\tconst left = targetRect.left + targetRect.width / 2 - balloonRect.width / 2;\n\n\treturn {\n\t\ttop: Math.max( widgetRect.top, 0 ) + BalloonPanelView.arrowVerticalOffset,\n\t\tleft,\n\t\tname: 'arrow_n'\n\t};\n}\n\n// Default filler offset function applied to all widget elements.\n//\n// @returns {null}\nfunction getFillerOffset() {\n\treturn null;\n}\n\n// Adds a drag handle to the widget.\n//\n// @param {module:engine/view/containerelement~ContainerElement}\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer\nfunction addSelectionHandle( widgetElement, writer ) {\n\tconst selectionHandle = writer.createUIElement( 'div', { class: 'ck ck-widget__selection-handle' }, function( domDocument ) {\n\t\tconst domElement = this.toDomElement( domDocument );\n\n\t\t// Use the IconView from the ui library.\n\t\tconst icon = new IconView();\n\t\ticon.set( 'content', dragHandleIcon );\n\n\t\t// Render the icon view right away to append its #element to the selectionHandle DOM element.\n\t\ticon.render();\n\n\t\tdomElement.appendChild( icon.element );\n\n\t\treturn domElement;\n\t} );\n\n\t// Append the selection handle into the widget wrapper.\n\twriter.insert( writer.createPositionAt( widgetElement, 0 ), selectionHandle );\n\twriter.addClass( [ 'ck-widget_with-selection-handle' ], widgetElement );\n}\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\nexport { default as Widget } from './widget';\nexport { default as WidgetToolbarRepository } from './widgettoolbarrepository';\nexport { default as WidgetResize } from './widgetresize';\nexport { default as WidgetTypeAround } from './widgettypearound/widgettypearound';\nexport * from './utils';\n"],"sourceRoot":""}