{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-widget/src/widget.js"],"names":["Widget","_this","this","editor","view","editing","viewDocument","document","_previouslySelected","Set","downcastDispatcher","on","evt","data","conversionApi","viewWriter","writer","modelSelection","selection","isCollapsed","selectedModelElement","getSelectedElement","selectedViewElement","mapper","toViewElement","isWidget","consumable","consume","setSelection","createRangeOn","fake","label","getLabel","_clearPreviouslySelectedWidgets","_step","viewSelection","lastMarked","_iterator","_createForOfIteratorHelper","getRanges","s","n","done","_step2","range","value","_iterator2","node","item","isChild","addClass","WIDGET_SELECTED_CLASS_NAME","add","err","e","f","priority","addObserver","MouseObserver","listenTo","_onMousedown","apply","arguments","_handleSelectionChangeOnArrowKeyPress","context","_preventDefaultOnArrowKeyPress","verticalNavigationHandler","_handleDelete","direction","preventDefault","stop","eventInfo","domEventData","element","target","isInsideNestedEditable","env","isSafari","isGecko","domEvent","detail","viewElement","is","findAncestor","modelElement","toModelElement","model","change","isAndroid","isFocused","focus","_setSelectionOverElement","keyCode","schema","objectElement","isForward","isForwardArrowKeyCode","locale","contentLanguageDirection","isObject","position","getLastPosition","getFirstPosition","newRange","getNearestSelectionRange","objectElementNextToSelection","_getObjectElementNextToSelection","_this2","isReadOnly","modelDocument","previousNode","anchor","parent","isEmpty","nodeToRemove","remove","forward","probe","createSelection","modifySelection","nodeBefore","nodeAfter","_step3","_iterator3","widget","removeClass","clear","WidgetTypeAround","Delete","Plugin","Array","from","getAncestors","includes"],"mappings":"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","file":"js/chunk-2d21b2d5.d6a4ca5d.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/widget\n */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport MouseObserver from '@ckeditor/ckeditor5-engine/src/view/observer/mouseobserver';\nimport WidgetTypeAround from './widgettypearound/widgettypearound';\nimport Delete from '@ckeditor/ckeditor5-typing/src/delete';\nimport { getLabel, isWidget, WIDGET_SELECTED_CLASS_NAME } from './utils';\nimport { isForwardArrowKeyCode } from '@ckeditor/ckeditor5-utils/src/keyboard';\nimport env from '@ckeditor/ckeditor5-utils/src/env';\n\nimport '../theme/widget.css';\nimport verticalNavigationHandler from './verticalnavigation';\n\n/**\n * The widget plugin. It enables base support for widgets.\n *\n * See {@glink api/widget package page} for more details and documentation.\n *\n * This plugin enables multiple behaviors required by widgets:\n *\n * * The model to view selection converter for the editing pipeline (it handles widget custom selection rendering).\n * If a converted selection wraps around a widget element, that selection is marked as\n * {@link module:engine/view/selection~Selection#isFake fake}. Additionally, the `ck-widget_selected` CSS class\n * is added to indicate that widget has been selected.\n * * The mouse and keyboard events handling on and around widget elements.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Widget extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Widget';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ WidgetTypeAround, Delete ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\t/**\n\t\t * Holds previously selected widgets.\n\t\t *\n\t\t * @private\n\t\t * @type {Set.}\n\t\t */\n\t\tthis._previouslySelected = new Set();\n\n\t\t// Model to view selection converter.\n\t\t// Converts selection placed over widget element to fake selection.\n\t\t//\n\t\t// By default, the selection is downcasted by the engine to surround the attribute element, even though its only\n\t\t// child is an inline widget. A similar thing also happens when a collapsed marker is rendered as a UI element\n\t\t// next to an inline widget: the view selection contains both the widget and the marker.\n\t\t//\n\t\t// This prevents creating a correct fake selection when this inline widget is selected. Normalize the selection\n\t\t// in these cases based on the model:\n\t\t//\n\t\t//\t\t[] -> []\n\t\t//\t\t[] -> []\n\t\t//\n\t\t// Thanks to this:\n\t\t//\n\t\t// * fake selection can be set correctly,\n\t\t// * any logic depending on (View)Selection#getSelectedElement() also works OK.\n\t\t//\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/9524.\n\t\tthis.editor.editing.downcastDispatcher.on( 'selection', ( evt, data, conversionApi ) => {\n\t\t\tconst viewWriter = conversionApi.writer;\n\t\t\tconst modelSelection = data.selection;\n\n\t\t\t// The collapsed selection can't contain any widget.\n\t\t\tif ( modelSelection.isCollapsed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selectedModelElement = modelSelection.getSelectedElement();\n\n\t\t\tif ( !selectedModelElement ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selectedViewElement = editor.editing.mapper.toViewElement( selectedModelElement );\n\n\t\t\tif ( !isWidget( selectedViewElement ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !conversionApi.consumable.consume( modelSelection, 'selection' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tviewWriter.setSelection( viewWriter.createRangeOn( selectedViewElement ), {\n\t\t\t\tfake: true,\n\t\t\t\tlabel: getLabel( selectedViewElement )\n\t\t\t} );\n\t\t} );\n\n\t\t// Mark all widgets inside the selection with the css class.\n\t\t// This handler is registered at the 'low' priority so it's triggered after the real selection conversion.\n\t\tthis.editor.editing.downcastDispatcher.on( 'selection', ( evt, data, conversionApi ) => {\n\t\t\t// Remove selected class from previously selected widgets.\n\t\t\tthis._clearPreviouslySelectedWidgets( conversionApi.writer );\n\n\t\t\tconst viewWriter = conversionApi.writer;\n\t\t\tconst viewSelection = viewWriter.document.selection;\n\n\t\t\tlet lastMarked = null;\n\n\t\t\tfor ( const range of viewSelection.getRanges() ) {\n\t\t\t\t// Note: There could be multiple selected widgets in a range but no fake selection.\n\t\t\t\t// All of them must be marked as selected, for instance []\n\t\t\t\tfor ( const value of range ) {\n\t\t\t\t\tconst node = value.item;\n\n\t\t\t\t\t// Do not mark nested widgets in selected one. See: #57.\n\t\t\t\t\tif ( isWidget( node ) && !isChild( node, lastMarked ) ) {\n\t\t\t\t\t\tviewWriter.addClass( WIDGET_SELECTED_CLASS_NAME, node );\n\n\t\t\t\t\t\tthis._previouslySelected.add( node );\n\t\t\t\t\t\tlastMarked = node;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\t// If mouse down is pressed on widget - create selection over whole widget.\n\t\tview.addObserver( MouseObserver );\n\t\tthis.listenTo( viewDocument, 'mousedown', ( ...args ) => this._onMousedown( ...args ) );\n\n\t\t// There are two keydown listeners working on different priorities. This allows other\n\t\t// features such as WidgetTypeAround or TableKeyboard to attach their listeners in between\n\t\t// and customize the behavior even further in different content/selection scenarios.\n\t\t//\n\t\t// * The first listener handles changing the selection on arrow key press\n\t\t// if the widget is selected or if the selection is next to a widget and the widget\n\t\t// should become selected upon the arrow key press.\n\t\t//\n\t\t// * The second (late) listener makes sure the default browser action on arrow key press is\n\t\t// prevented when a widget is selected. This prevents the selection from being moved\n\t\t// from a fake selection container.\n\t\tthis.listenTo( viewDocument, 'arrowKey', ( ...args ) => {\n\t\t\tthis._handleSelectionChangeOnArrowKeyPress( ...args );\n\t\t}, { context: [ isWidget, '$text' ] } );\n\n\t\tthis.listenTo( viewDocument, 'arrowKey', ( ...args ) => {\n\t\t\tthis._preventDefaultOnArrowKeyPress( ...args );\n\t\t}, { context: '$root' } );\n\n\t\tthis.listenTo( viewDocument, 'arrowKey', verticalNavigationHandler( this.editor.editing ), { context: '$text' } );\n\n\t\t// Handle custom delete behaviour.\n\t\tthis.listenTo( viewDocument, 'delete', ( evt, data ) => {\n\t\t\tif ( this._handleDelete( data.direction == 'forward' ) ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: '$root' } );\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:mousedown mousedown} events on widget elements.\n\t *\n\t * @private\n\t * @param {module:utils/eventinfo~EventInfo} eventInfo\n\t * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData\n\t */\n\t_onMousedown( eventInfo, domEventData ) {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\t\tlet element = domEventData.target;\n\n\t\t// Do nothing for single or double click inside nested editable.\n\t\tif ( isInsideNestedEditable( element ) ) {\n\t\t\t// But at least triple click inside nested editable causes broken selection in Safari.\n\t\t\t// For such event, we select the entire nested editable element.\n\t\t\t// See: https://github.com/ckeditor/ckeditor5/issues/1463.\n\t\t\tif ( ( env.isSafari || env.isGecko ) && domEventData.domEvent.detail >= 3 ) {\n\t\t\t\tconst mapper = editor.editing.mapper;\n\t\t\t\tconst viewElement = element.is( 'attributeElement' ) ?\n\t\t\t\t\telement.findAncestor( element => !element.is( 'attributeElement' ) ) : element;\n\t\t\t\tconst modelElement = mapper.toModelElement( viewElement );\n\n\t\t\t\tdomEventData.preventDefault();\n\n\t\t\t\tthis.editor.model.change( writer => {\n\t\t\t\t\twriter.setSelection( modelElement, 'in' );\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// If target is not a widget element - check if one of the ancestors is.\n\t\tif ( !isWidget( element ) ) {\n\t\t\telement = element.findAncestor( isWidget );\n\n\t\t\tif ( !element ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// On Android selection would jump to the first table cell, on other devices\n\t\t// we can't block it (and don't need to) because of drag and drop support.\n\t\tif ( env.isAndroid ) {\n\t\t\tdomEventData.preventDefault();\n\t\t}\n\n\t\t// Focus editor if is not focused already.\n\t\tif ( !viewDocument.isFocused ) {\n\t\t\tview.focus();\n\t\t}\n\n\t\t// Create model selection over widget.\n\t\tconst modelElement = editor.editing.mapper.toModelElement( element );\n\n\t\tthis._setSelectionOverElement( modelElement );\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:keydown keydown} events and changes\n\t * the model selection when:\n\t *\n\t * * arrow key is pressed when the widget is selected,\n\t * * the selection is next to a widget and the widget should become selected upon the arrow key press.\n\t *\n\t * See {@link #_preventDefaultOnArrowKeyPress}.\n\t *\n\t * @private\n\t * @param {module:utils/eventinfo~EventInfo} eventInfo\n\t * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData\n\t */\n\t_handleSelectionChangeOnArrowKeyPress( eventInfo, domEventData ) {\n\t\tconst keyCode = domEventData.keyCode;\n\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst modelSelection = model.document.selection;\n\t\tconst objectElement = modelSelection.getSelectedElement();\n\t\tconst isForward = isForwardArrowKeyCode( keyCode, this.editor.locale.contentLanguageDirection );\n\n\t\t// If object element is selected.\n\t\tif ( objectElement && schema.isObject( objectElement ) ) {\n\t\t\tconst position = isForward ? modelSelection.getLastPosition() : modelSelection.getFirstPosition();\n\t\t\tconst newRange = schema.getNearestSelectionRange( position, isForward ? 'forward' : 'backward' );\n\n\t\t\tif ( newRange ) {\n\t\t\t\tmodel.change( writer => {\n\t\t\t\t\twriter.setSelection( newRange );\n\t\t\t\t} );\n\n\t\t\t\tdomEventData.preventDefault();\n\t\t\t\teventInfo.stop();\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// If selection is next to object element.\n\t\t// Return if not collapsed.\n\t\tif ( !modelSelection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst objectElementNextToSelection = this._getObjectElementNextToSelection( isForward );\n\n\t\tif ( objectElementNextToSelection && schema.isObject( objectElementNextToSelection ) ) {\n\t\t\tthis._setSelectionOverElement( objectElementNextToSelection );\n\n\t\t\tdomEventData.preventDefault();\n\t\t\teventInfo.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:keydown keydown} events and prevents\n\t * the default browser behavior to make sure the fake selection is not being moved from a fake selection\n\t * container.\n\t *\n\t * See {@link #_handleSelectionChangeOnArrowKeyPress}.\n\t *\n\t * @private\n\t * @param {module:utils/eventinfo~EventInfo} eventInfo\n\t * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData\n\t */\n\t_preventDefaultOnArrowKeyPress( eventInfo, domEventData ) {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst objectElement = model.document.selection.getSelectedElement();\n\n\t\t// If object element is selected.\n\t\tif ( objectElement && schema.isObject( objectElement ) ) {\n\t\t\tdomEventData.preventDefault();\n\t\t\teventInfo.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Handles delete keys: backspace and delete.\n\t *\n\t * @private\n\t * @param {Boolean} isForward Set to true if delete was performed in forward direction.\n\t * @returns {Boolean|undefined} Returns `true` if keys were handled correctly.\n\t */\n\t_handleDelete( isForward ) {\n\t\t// Do nothing when the read only mode is enabled.\n\t\tif ( this.editor.isReadOnly ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelDocument = this.editor.model.document;\n\t\tconst modelSelection = modelDocument.selection;\n\n\t\t// Do nothing on non-collapsed selection.\n\t\tif ( !modelSelection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst objectElement = this._getObjectElementNextToSelection( isForward );\n\n\t\tif ( objectElement ) {\n\t\t\tthis.editor.model.change( writer => {\n\t\t\t\tlet previousNode = modelSelection.anchor.parent;\n\n\t\t\t\t// Remove previous element if empty.\n\t\t\t\twhile ( previousNode.isEmpty ) {\n\t\t\t\t\tconst nodeToRemove = previousNode;\n\t\t\t\t\tpreviousNode = nodeToRemove.parent;\n\n\t\t\t\t\twriter.remove( nodeToRemove );\n\t\t\t\t}\n\n\t\t\t\tthis._setSelectionOverElement( objectElement );\n\t\t\t} );\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t/**\n\t * Sets {@link module:engine/model/selection~Selection document's selection} over given element.\n\t *\n\t * @protected\n\t * @param {module:engine/model/element~Element} element\n\t */\n\t_setSelectionOverElement( element ) {\n\t\tthis.editor.model.change( writer => {\n\t\t\twriter.setSelection( writer.createRangeOn( element ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks if {@link module:engine/model/element~Element element} placed next to the current\n\t * {@link module:engine/model/selection~Selection model selection} exists and is marked in\n\t * {@link module:engine/model/schema~Schema schema} as `object`.\n\t *\n\t * @protected\n\t * @param {Boolean} forward Direction of checking.\n\t * @returns {module:engine/model/element~Element|null}\n\t */\n\t_getObjectElementNextToSelection( forward ) {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst modelSelection = model.document.selection;\n\n\t\t// Clone current selection to use it as a probe. We must leave default selection as it is so it can return\n\t\t// to its current state after undo.\n\t\tconst probe = model.createSelection( modelSelection );\n\t\tmodel.modifySelection( probe, { direction: forward ? 'forward' : 'backward' } );\n\t\tconst objectElement = forward ? probe.focus.nodeBefore : probe.focus.nodeAfter;\n\n\t\tif ( !!objectElement && schema.isObject( objectElement ) ) {\n\t\t\treturn objectElement;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Removes CSS class from previously selected widgets.\n\t *\n\t * @private\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer\n\t */\n\t_clearPreviouslySelectedWidgets( writer ) {\n\t\tfor ( const widget of this._previouslySelected ) {\n\t\t\twriter.removeClass( WIDGET_SELECTED_CLASS_NAME, widget );\n\t\t}\n\n\t\tthis._previouslySelected.clear();\n\t}\n}\n\n// Returns `true` when element is a nested editable or is placed inside one.\n//\n// @param {module:engine/view/element~Element}\n// @returns {Boolean}\nfunction isInsideNestedEditable( element ) {\n\twhile ( element ) {\n\t\tif ( element.is( 'editableElement' ) && !element.is( 'rootElement' ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Click on nested widget should select it.\n\t\tif ( isWidget( element ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\telement = element.parent;\n\t}\n\n\treturn false;\n}\n\n// Checks whether the specified `element` is a child of the `parent` element.\n//\n// @param {module:engine/view/element~Element} element An element to check.\n// @param {module:engine/view/element~Element|null} parent A parent for the element.\n// @returns {Boolean}\nfunction isChild( element, parent ) {\n\tif ( !parent ) {\n\t\treturn false;\n\t}\n\n\treturn Array.from( element.getAncestors() ).includes( parent );\n}\n"],"sourceRoot":""}