{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon.js"],"names":["toPx","toUnit","ContextualBalloon","editor","_this","Object","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_classCallCheck_js__WEBPACK_IMPORTED_MODULE_9__","this","_super","call","positionLimiter","view","editing","viewDocument","document","editableElement","selection","domConverter","mapViewToDom","root","set","BalloonPanelView","locale","ui","body","add","focusTracker","element","_viewToStack","Map","_idToStack","_rotatorView","_createRotatorView","_fakePanelsView","_createFakePanelsView","Array","from","keys","includes","data","hasView","CKEditorError","stackId","has","get","_numberOfStacks","size","_visibleStack","singleViewMode","showStack","stack","_showView","_singleViewMode","visibleView","_showNextStack","hide","hideView","values","delete","_getStackId","position","pin","_getBalloonPosition","updatePosition","id","visibleStack","pop","entry","entries","find","stacks","nextIndex","indexOf","length","_this2","RotatorView","t","content","bind","to","value","isSingleViewMode","on","priority","numberOfStacks","current","buttonNextView","isFocused","focus","buttonPrevView","_showPrevStack","FakePanelsView","number","showPanels","Math","min","listenTo","_ref","_ref$balloonClassName","balloonClassName","_ref$withArrow","withArrow","_ref$singleViewMode","class","showView","limiter","assign","Plugin","_this3","_super2","bindTemplate","FocusTracker","_createButtonView","prevIcon","nextIcon","createCollection","setTemplate","tag","attributes","z-index","children","text","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_get_js__WEBPACK_IMPORTED_MODULE_1__","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_getPrototypeOf_js__WEBPACK_IMPORTED_MODULE_13__","prototype","clear","label","icon","ButtonView","tooltip","View","balloonPanelView","_this4","_super3","_balloonPanelView","style","top","left","width","height","evt","name","next","prev","_addPanels","_removePanels","registerChild","last","remove","deregisterChild","destroy","numberOfPanels","_this$_balloonPanelVi","_Rect","Rect"],"mappings":";;;;GAwBA,IAAMA,EAAOC,eAAQ,MAsCAC,6CAWpB,SAAAA,EAAaC,GAAS,IAAAC,EAAA,OAAAC,OAAAC,EAAA,KAAAD,CAAAE,KAAAL,GACrBE,EAAAI,EAAAC,KAAAF,KAAOJ,GAaPC,EAAKM,gBAAkB,WACtB,IAAMC,EAAOP,EAAKD,OAAOS,QAAQD,KAC3BE,EAAeF,EAAKG,SACpBC,EAAkBF,EAAaG,UAAUD,gBAE/C,OAAKA,EACGJ,EAAKM,aAAaC,aAAcH,EAAgBI,MAGjD,MAURf,EAAKgB,IAAK,cAAe,MAQzBhB,EAAKO,KAAO,IAAIU,OAAkBlB,EAAOmB,QACzCnB,EAAOoB,GAAGZ,KAAKa,KAAKC,IAAKrB,EAAKO,MAC9BR,EAAOoB,GAAGG,aAAaD,IAAKrB,EAAKO,KAAKgB,SAQtCvB,EAAKwB,aAAe,IAAIC,IAQxBzB,EAAK0B,WAAa,IAAID,IAUtBzB,EAAKgB,IAAK,kBAAmB,GAU7BhB,EAAKgB,IAAK,mBAAmB,GAS7BhB,EAAK2B,aAAe3B,EAAK4B,qBAQzB5B,EAAK6B,gBAAkB7B,EAAK8B,wBAhGP9B,gDAyGtB,SAASO,GACR,OAAOwB,MAAMC,KAAM7B,KAAKqB,aAAaS,QAASC,SAAU3B,sBAezD,SAAK4B,GACJ,GAAKhC,KAAKiC,QAASD,EAAK5B,MAMvB,MAAM,IAAI8B,OACT,oCACElC,KAAMgC,IAIV,IAAMG,EAAUH,EAAKG,SAAW,OAGhC,IAAMnC,KAAKuB,WAAWa,IAAKD,GAS1B,OARAnC,KAAKuB,WAAWV,IAAKsB,EAAS,IAAIb,MAASU,EAAK5B,KAAM4B,MACtDhC,KAAKqB,aAAaR,IAAKmB,EAAK5B,KAAMJ,KAAKuB,WAAWc,IAAKF,IACvDnC,KAAKsC,gBAAkBtC,KAAKuB,WAAWgB,UAEjCvC,KAAKwC,gBAAiBR,EAAKS,gBAChCzC,KAAK0C,UAAWP,IAMlB,IAAMQ,EAAQ3C,KAAKuB,WAAWc,IAAKF,GAE9BH,EAAKS,gBACTzC,KAAK0C,UAAWP,GAIjBQ,EAAM9B,IAAKmB,EAAK5B,KAAM4B,GACtBhC,KAAKqB,aAAaR,IAAKmB,EAAK5B,KAAMuC,GAG7BA,IAAU3C,KAAKwC,eACnBxC,KAAK4C,UAAWZ,yBAYlB,SAAQ5B,GACP,IAAMJ,KAAKiC,QAAS7B,GAMnB,MAAM,IAAI8B,OACT,2CACElC,KAAMI,IAIV,IAAMuC,EAAQ3C,KAAKqB,aAAagB,IAAKjC,GAEhCJ,KAAK6C,iBAAmB7C,KAAK8C,cAAgB1C,IACjDJ,KAAK6C,iBAAkB,GAKnB7C,KAAK8C,cAAgB1C,IACL,IAAfuC,EAAMJ,KACLvC,KAAKuB,WAAWgB,KAAO,EAC3BvC,KAAK+C,kBAEL/C,KAAKI,KAAK4C,OACVhD,KAAK8C,YAAc,KACnB9C,KAAKwB,aAAayB,YAGnBjD,KAAK4C,UAAWhB,MAAMC,KAAMc,EAAMO,UAAYP,EAAMJ,KAAO,KAIzC,IAAfI,EAAMJ,MACVvC,KAAKuB,WAAW4B,OAAQnD,KAAKoD,YAAaT,IAC1C3C,KAAKsC,gBAAkBtC,KAAKuB,WAAWgB,MAEvCI,EAAMQ,OAAQ/C,GAGfJ,KAAKqB,aAAa8B,OAAQ/C,iCAS3B,SAAgBiD,GACVA,IACJrD,KAAKwC,cAAcH,IAAKrC,KAAK8C,aAAcO,SAAWA,GAGvDrD,KAAKI,KAAKkD,IAAKtD,KAAKuD,uBACpBvD,KAAK0B,gBAAgB8B,0CAQtB,SAAWC,GACVzD,KAAK0D,aAAeD,EACpB,IAAMd,EAAQ3C,KAAKuB,WAAWc,IAAKoB,GAEnC,IAAMd,EAML,MAAM,IAAIT,OACT,8CACAlC,MAIGA,KAAKwC,gBAAkBG,GAI5B3C,KAAK4C,UAAWhB,MAAMC,KAAMc,EAAMO,UAAWS,kCAS9C,WACC,OAAO3D,KAAKqB,aAAagB,IAAKrC,KAAK8C,wCAUpC,SAAaH,GACZ,IAAMiB,EAAQhC,MAAMC,KAAM7B,KAAKuB,WAAWsC,WAAYC,KAAM,SAAAF,GAAK,OAAIA,EAAO,KAAQjB,IAEpF,OAAOiB,EAAO,iCAQf,WACC,IAAMG,EAASnC,MAAMC,KAAM7B,KAAKuB,WAAW2B,UAEvCc,EAAYD,EAAOE,QAASjE,KAAKwC,eAAkB,EAEjDuB,EAAQC,KACbA,EAAY,GAGbhE,KAAK0C,UAAW1C,KAAKoD,YAAaW,EAAQC,mCAQ3C,WACC,IAAMD,EAASnC,MAAMC,KAAM7B,KAAKuB,WAAW2B,UAEvCc,EAAYD,EAAOE,QAASjE,KAAKwC,eAAkB,EAEjDuB,EAAQC,KACbA,EAAYD,EAAOG,OAAS,GAG7BlE,KAAK0C,UAAW1C,KAAKoD,YAAaW,EAAQC,uCAS3C,WAAqB,IAAAG,EAAAnE,KACdI,EAAO,IAAIgE,EAAapE,KAAKJ,OAAOmB,QACpCsD,EAAIrE,KAAKJ,OAAOmB,OAAOsD,EA2C7B,OAzCArE,KAAKI,KAAKkE,QAAQpD,IAAKd,GAGvBA,EAAKmE,KAAM,uBAAwBC,GAAIxE,KAAM,kBAAmBA,KAAM,kBAAmB,SAAEyE,EAAOC,GACjG,OAAQA,GAAoBD,EAAQ,IAIrCrE,EAAKuE,GAAI,6BAA8B,kBAAQR,EAAKX,mBAAsBoB,SAAU,QAGpFxE,EAAKmE,KAAM,WAAYC,GAAIxE,KAAM,cAAeA,KAAM,kBAAmB,SAAE8C,EAAa+B,GACvF,GAAKA,EAAiB,EACrB,MAAO,GAGR,IAAMC,EAAUlD,MAAMC,KAAMsC,EAAK5C,WAAW2B,UAAWe,QAASE,EAAK3B,eAAkB,EAEvF,OAAO6B,EAAG,YAAcS,EAASD,MAGlCzE,EAAK2E,eAAeJ,GAAI,UAAW,WAG7BvE,EAAKe,aAAa6D,WACtBb,EAAKvE,OAAOS,QAAQD,KAAK6E,QAG1Bd,EAAKpB,mBAGN3C,EAAK8E,eAAeP,GAAI,UAAW,WAG7BvE,EAAKe,aAAa6D,WACtBb,EAAKvE,OAAOS,QAAQD,KAAK6E,QAG1Bd,EAAKgB,mBAGC/E,uCAOR,WACC,IAAMA,EAAO,IAAIgF,EAAgBpF,KAAKJ,OAAOmB,OAAQf,KAAKI,MAa1D,OAXAA,EAAKmE,KAAM,kBAAmBC,GAAIxE,KAAM,kBAAmBA,KAAM,kBAAmB,SAAEqF,EAAQX,GAC7F,IAAMY,GAAcZ,GAAoBW,GAAU,EAElD,OAAOC,EAAaC,KAAKC,IAAKH,EAAS,EAAG,GAAM,IAGjDjF,EAAKqF,SAAUzF,KAAKI,KAAM,aAAc,kBAAMA,EAAKoD,mBACnDpD,EAAKqF,SAAUzF,KAAKI,KAAM,cAAe,kBAAMA,EAAKoD,mBAEpDxD,KAAKJ,OAAOoB,GAAGZ,KAAKa,KAAKC,IAAKd,GAEvBA,2BAaR,SAAAsF,GAAuF,IAA1EtF,EAA0EsF,EAA1EtF,KAA0EuF,EAAAD,EAApEE,wBAAoE,IAAAD,EAAjD,GAAiDA,EAAAE,EAAAH,EAA7CI,iBAA6C,IAAAD,KAAAE,EAAAL,EAA3BjD,sBAA2B,IAAAsD,KACtF/F,KAAKI,KAAK4F,MAAQJ,EAClB5F,KAAKI,KAAK0F,UAAYA,EAEtB9F,KAAKwB,aAAayE,SAAU7F,GAC5BJ,KAAK8C,YAAc1C,EACnBJ,KAAKI,KAAKkD,IAAKtD,KAAKuD,uBACpBvD,KAAK0B,gBAAgB8B,iBAEhBf,IACJzC,KAAK6C,iBAAkB,sCAWzB,WACC,IAAIQ,EAAWzB,MAAMC,KAAM7B,KAAKwC,cAAcU,UAAWS,MAAMN,SAU/D,OAPKA,IAAaA,EAAS6C,UAE1B7C,EAAWvD,OAAOqG,UAAY9C,GAC7B6C,QAASlG,KAAKG,mBAITkD,4BA1bR,WACC,MAAO,2BALsC+C,QAyczChC,6CAIL,SAAAA,EAAarD,GAAS,IAAAsF,EAAAvG,OAAAC,EAAA,KAAAD,CAAAE,KAAAoE,GACrBiC,EAAAC,EAAApG,KAAAF,KAAOe,GAEP,IAAMsD,EAAItD,EAAOsD,EACXE,EAAO8B,EAAKE,aAJG,OAWrBF,EAAKxF,IAAK,uBAAuB,GAOjCwF,EAAKlF,aAAe,IAAIqF,OAOxBH,EAAKnB,eAAiBmB,EAAKI,kBAAmBpC,EAAG,YAAcqC,KAO/DL,EAAKtB,eAAiBsB,EAAKI,kBAAmBpC,EAAG,QAAUsC,KAQ3DN,EAAK/B,QAAU+B,EAAKO,mBAEpBP,EAAKQ,aACJC,IAAK,MACLC,YACCf,OACC,KACA,sBAEDgB,UAAW,MAEZC,WAEEH,IAAK,MACLC,YACCf,OACC,iCACAzB,EAAKC,GAAI,sBAAuB,SAAAC,GAAK,OAAIA,EAAQ,GAAK,gBAGxDwC,UACCZ,EAAKnB,gBAEJ4B,IAAK,OAELC,YACCf,OACC,gCAIFiB,WAEEC,KAAM3C,EAAKC,GAAI,cAIlB6B,EAAKtB,kBAIN+B,IAAK,MACLC,YACCf,MAAO,+BAERiB,SAAUZ,EAAK/B,YArFG+B,+CA8FtB,WACCvG,OAAAqH,EAAA,KAAArH,QAAAsH,EAAA,KAAAtH,CAAAsE,EAAAiD,WAAA,SAAArH,MAAAE,KAAAF,MAEAA,KAAKmB,aAAaD,IAAKlB,KAAKoB,iCAQ7B,SAAUhB,GACTJ,KAAKiD,WACLjD,KAAKsE,QAAQpD,IAAKd,2BAMnB,WACCJ,KAAKsE,QAAQgD,yCAWd,SAAmBC,EAAOC,GACzB,IAAMpH,EAAO,IAAIqH,OAAYzH,KAAKe,QAQlC,OANAX,EAAKS,KACJ0G,QACAC,OACAE,SAAS,IAGHtH,SA1IiBuH,QAkJpBvC,6CAEL,SAAAA,EAAarE,EAAQ6G,GAAmB,IAAAC,EAAA/H,OAAAC,EAAA,KAAAD,CAAAE,KAAAoF,GACvCyC,EAAAC,EAAA5H,KAAAF,KAAOe,GAEP,IAAMwD,EAAOsD,EAAKtB,aAHqB,OASvCsB,EAAKhH,IAAK,MAAO,GAMjBgH,EAAKhH,IAAK,OAAQ,GAMlBgH,EAAKhH,IAAK,SAAU,GAMpBgH,EAAKhH,IAAK,QAAS,GAMnBgH,EAAKhH,IAAK,iBAAkB,GAM5BgH,EAAKvD,QAAUuD,EAAKjB,mBAMpBiB,EAAKE,kBAAoBH,EAEzBC,EAAKhB,aACJC,IAAK,MACLC,YACCf,OACC,gBACAzB,EAAKC,GAAI,iBAAkB,SAAAa,GAAM,OAAIA,EAAS,GAAK,eAEpD2C,OACCC,IAAK1D,EAAKC,GAAI,MAAO/E,GACrByI,KAAM3D,EAAKC,GAAI,OAAQ/E,GACvB0I,MAAO5D,EAAKC,GAAI,QAAS/E,GACzB2I,OAAQ7D,EAAKC,GAAI,SAAU/E,KAG7BwH,SAAUY,EAAKvD,UAGhBuD,EAAKlD,GAAI,wBAAyB,SAAE0D,EAAKC,EAAMC,EAAMC,GAC/CD,EAAOC,EACXX,EAAKY,WAAYF,EAAOC,GAExBX,EAAKa,cAAeF,EAAOD,GAG5BV,EAAKrE,mBAvEiCqE,mDA6ExC,SAAYxC,GACX,MAAQA,IAAW,CAClB,IAAMjF,EAAO,IAAIuH,OAEjBvH,EAAKyG,aAAeC,IAAK,QAEzB9G,KAAKsE,QAAQpD,IAAKd,GAClBJ,KAAK2I,cAAevI,iCAMtB,SAAeiF,GACd,MAAQA,IAAW,CAClB,IAAMjF,EAAOJ,KAAKsE,QAAQsE,KAE1B5I,KAAKsE,QAAQuE,OAAQzI,GACrBJ,KAAK8I,gBAAiB1I,GACtBA,EAAK2I,yCAKP,WACC,GAAK/I,KAAKgJ,eAAiB,CAC1B,IAAAC,EAAsBjJ,KAAK+H,kBAAnBE,EAARgB,EAAQhB,IAAKC,EAAbe,EAAaf,KACbgB,EAA0B,IAAIC,OAAMnJ,KAAK+H,kBAAkB3G,SAAnD+G,EAARe,EAAQf,MAAOC,EAAfc,EAAed,OAEftI,OAAOqG,OAAQnG,MAAQiI,MAAKC,OAAMC,QAAOC,mBA5GfT","file":"js/chunk-2d0ab88d.ed4831e8.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 ui/panel/balloon/contextualballoon\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport BalloonPanelView from './balloonpanelview';\nimport View from '../../view';\nimport ButtonView from '../../button/buttonview';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';\nimport toUnit from '@ckeditor/ckeditor5-utils/src/dom/tounit';\nimport Rect from '@ckeditor/ckeditor5-utils/src/dom/rect';\n\nimport prevIcon from '../../../theme/icons/previous-arrow.svg';\nimport nextIcon from '../../../theme/icons/next-arrow.svg';\n\nimport '../../../theme/components/panel/balloonrotator.css';\nimport '../../../theme/components/panel/fakepanel.css';\n\nconst toPx = toUnit( 'px' );\n\n/**\n * Provides the common contextual balloon for the editor.\n *\n * The role of this plugin is to unify the contextual balloons logic, simplify views management and help\n * avoid the unnecessary complexity of handling multiple {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView}\n * instances in the editor.\n *\n * This plugin allows for creating single or multiple panel stacks.\n *\n * Each stack may have multiple views, with the one on the top being visible. When the visible view is removed from the stack,\n * the previous view becomes visible.\n *\n * It might be useful to implement nested navigation in a balloon. For instance, a toolbar view may contain a link button.\n * When you click it, a link view (which lets you set the URL) is created and put on top of the toolbar view, so the link panel\n * is displayed. When you finish editing the link and close (remove) the link view, the toolbar view is visible again.\n *\n * However, there are cases when there are multiple independent balloons to be displayed, for instance, if the selection\n * is inside two inline comments at the same time. For such cases, you can create two independent panel stacks.\n * The contextual balloon plugin will create a navigation bar to let the users switch between these panel stacks using the \"Next\"\n * and \"Previous\" buttons.\n *\n * If there are no views in the current stack, the balloon panel will try to switch to the next stack. If there are no\n * panels in any stack, the balloon panel will be hidden.\n *\n * **Note**: To force the balloon panel to show only one view, even if there are other stacks, use the `singleViewMode=true` option\n * when {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon#add adding} a view to a panel.\n *\n * From the implementation point of view, the contextual ballon plugin is reusing a single\n * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView} instance to display multiple contextual balloon\n * panels in the editor. It also creates a special {@link module:ui/panel/balloon/contextualballoon~RotatorView rotator view},\n * used to manage multiple panel stacks. Rotator view is a child of the balloon panel view and the parent of the specific\n * view you want to display. If there is more than one panel stack to be displayed, the rotator view will add a\n * navigation bar. If there is only one stack, the rotator view is transparent (it does not add any UI elements).\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ContextualBalloon extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ContextualBalloon';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The {@link module:utils/dom/position~Options#limiter position limiter}\n\t\t * for the {@link #view balloon}, used when no `limiter` has been passed into {@link #add}\n\t\t * or {@link #updatePosition}.\n\t\t *\n\t\t * By default, a function that obtains the farthest DOM\n\t\t * {@link module:engine/view/rooteditableelement~RootEditableElement}\n\t\t * of the {@link module:engine/view/document~Document#selection}.\n\t\t *\n\t\t * @member {module:utils/dom/position~Options#limiter} #positionLimiter\n\t\t */\n\t\tthis.positionLimiter = () => {\n\t\t\tconst view = this.editor.editing.view;\n\t\t\tconst viewDocument = view.document;\n\t\t\tconst editableElement = viewDocument.selection.editableElement;\n\n\t\t\tif ( editableElement ) {\n\t\t\t\treturn view.domConverter.mapViewToDom( editableElement.root );\n\t\t\t}\n\n\t\t\treturn null;\n\t\t};\n\n\t\t/**\n\t\t * The currently visible view or `null` when there are no views in any stack.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {module:ui/view~View|null} #visibleView\n\t\t */\n\t\tthis.set( 'visibleView', null );\n\n\t\t/**\n\t\t * The common balloon panel view.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/panel/balloon/balloonpanelview~BalloonPanelView} #view\n\t\t */\n\t\tthis.view = new BalloonPanelView( editor.locale );\n\t\teditor.ui.view.body.add( this.view );\n\t\teditor.ui.focusTracker.add( this.view.element );\n\n\t\t/**\n\t\t * The map of views and their stacks.\n\t\t *\n\t\t * @private\n\t\t * @type {Map.}\n\t\t */\n\t\tthis._viewToStack = new Map();\n\n\t\t/**\n\t\t * The map of IDs and stacks.\n\t\t *\n\t\t * @private\n\t\t * @type {Map.}\n\t\t */\n\t\tthis._idToStack = new Map();\n\n\t\t/**\n\t\t * A total number of all stacks in the balloon.\n\t\t *\n\t\t * @private\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Number} #_numberOfStacks\n\t\t */\n\t\tthis.set( '_numberOfStacks', 0 );\n\n\t\t/**\n\t\t * A flag that controls the single view mode.\n\t\t *\n\t\t * @private\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} #_singleViewMode\n\t\t */\n\t\tthis.set( '_singleViewMode', false );\n\n\t\t/**\n\t\t * Rotator view embedded in the contextual balloon.\n\t\t * Displays the currently visible view in the balloon and provides navigation for switching stacks.\n\t\t *\n\t\t * @private\n\t\t * @type {module:ui/panel/balloon/contextualballoon~RotatorView}\n\t\t */\n\t\tthis._rotatorView = this._createRotatorView();\n\n\t\t/**\n\t\t * Displays fake panels under the balloon panel view when multiple stacks are added to the balloon.\n\t\t *\n\t\t * @private\n\t\t * @type {module:ui/view~View}\n\t\t */\n\t\tthis._fakePanelsView = this._createFakePanelsView();\n\t}\n\n\t/**\n\t * Returns `true` when the given view is in one of the stacks. Otherwise returns `false`.\n\t *\n\t * @param {module:ui/view~View} view\n\t * @returns {Boolean}\n\t */\n\thasView( view ) {\n\t\treturn Array.from( this._viewToStack.keys() ).includes( view );\n\t}\n\n\t/**\n\t * Adds a new view to the stack and makes it visible if the current stack is visible\n\t * or it is the first view in the balloon.\n\t *\n\t * @param {Object} data The configuration of the view.\n\t * @param {String} [data.stackId='main'] The ID of the stack that the view is added to.\n\t * @param {module:ui/view~View} [data.view] The content of the balloon.\n\t * @param {module:utils/dom/position~Options} [data.position] Positioning options.\n\t * @param {String} [data.balloonClassName] An additional CSS class added to the {@link #view balloon} when visible.\n\t * @param {Boolean} [data.withArrow=true] Whether the {@link #view balloon} should be rendered with an arrow.\n\t * @param {Boolean} [data.singleViewMode=false] Whether the view should be the only visible view even if other stacks were added.\n\t */\n\tadd( data ) {\n\t\tif ( this.hasView( data.view ) ) {\n\t\t\t/**\n\t\t\t * Trying to add configuration of the same view more than once.\n\t\t\t *\n\t\t\t * @error contextualballoon-add-view-exist\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'contextualballoon-add-view-exist',\n\t\t\t\t[ this, data ]\n\t\t\t);\n\t\t}\n\n\t\tconst stackId = data.stackId || 'main';\n\n\t\t// If new stack is added, creates it and show view from this stack.\n\t\tif ( !this._idToStack.has( stackId ) ) {\n\t\t\tthis._idToStack.set( stackId, new Map( [ [ data.view, data ] ] ) );\n\t\t\tthis._viewToStack.set( data.view, this._idToStack.get( stackId ) );\n\t\t\tthis._numberOfStacks = this._idToStack.size;\n\n\t\t\tif ( !this._visibleStack || data.singleViewMode ) {\n\t\t\t\tthis.showStack( stackId );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst stack = this._idToStack.get( stackId );\n\n\t\tif ( data.singleViewMode ) {\n\t\t\tthis.showStack( stackId );\n\t\t}\n\n\t\t// Add new view to the stack.\n\t\tstack.set( data.view, data );\n\t\tthis._viewToStack.set( data.view, stack );\n\n\t\t// And display it if is added to the currently visible stack.\n\t\tif ( stack === this._visibleStack ) {\n\t\t\tthis._showView( data );\n\t\t}\n\t}\n\n\t/**\n\t * Removes the given view from the stack. If the removed view was visible,\n\t * the view preceding it in the stack will become visible instead.\n\t * When there is no view in the stack, the next stack will be displayed.\n\t * When there are no more stacks, the balloon will hide.\n\t *\n\t * @param {module:ui/view~View} view A view to be removed from the balloon.\n\t */\n\tremove( view ) {\n\t\tif ( !this.hasView( view ) ) {\n\t\t\t/**\n\t\t\t * Trying to remove the configuration of the view not defined in the stack.\n\t\t\t *\n\t\t\t * @error contextualballoon-remove-view-not-exist\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'contextualballoon-remove-view-not-exist',\n\t\t\t\t[ this, view ]\n\t\t\t);\n\t\t}\n\n\t\tconst stack = this._viewToStack.get( view );\n\n\t\tif ( this._singleViewMode && this.visibleView === view ) {\n\t\t\tthis._singleViewMode = false;\n\t\t}\n\n\t\t// When visible view will be removed we need to show a preceding view or next stack\n\t\t// if a view is the only view in the stack.\n\t\tif ( this.visibleView === view ) {\n\t\t\tif ( stack.size === 1 ) {\n\t\t\t\tif ( this._idToStack.size > 1 ) {\n\t\t\t\t\tthis._showNextStack();\n\t\t\t\t} else {\n\t\t\t\t\tthis.view.hide();\n\t\t\t\t\tthis.visibleView = null;\n\t\t\t\t\tthis._rotatorView.hideView();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._showView( Array.from( stack.values() )[ stack.size - 2 ] );\n\t\t\t}\n\t\t}\n\n\t\tif ( stack.size === 1 ) {\n\t\t\tthis._idToStack.delete( this._getStackId( stack ) );\n\t\t\tthis._numberOfStacks = this._idToStack.size;\n\t\t} else {\n\t\t\tstack.delete( view );\n\t\t}\n\n\t\tthis._viewToStack.delete( view );\n\t}\n\n\t/**\n\t * Updates the position of the balloon using the position data of the first visible view in the stack.\n\t * When new position data is given, the position data of the currently visible view will be updated.\n\t *\n\t * @param {module:utils/dom/position~Options} [position] position options.\n\t */\n\tupdatePosition( position ) {\n\t\tif ( position ) {\n\t\t\tthis._visibleStack.get( this.visibleView ).position = position;\n\t\t}\n\n\t\tthis.view.pin( this._getBalloonPosition() );\n\t\tthis._fakePanelsView.updatePosition();\n\t}\n\n\t/**\n\t * Shows the last view from the stack of a given ID.\n\t *\n\t * @param {String} id\n\t */\n\tshowStack( id ) {\n\t\tthis.visibleStack = id;\n\t\tconst stack = this._idToStack.get( id );\n\n\t\tif ( !stack ) {\n\t\t\t/**\n\t\t\t * Trying to show a stack that does not exist.\n\t\t\t *\n\t\t\t * @error contextualballoon-showstack-stack-not-exist\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'contextualballoon-showstack-stack-not-exist',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\tif ( this._visibleStack === stack ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._showView( Array.from( stack.values() ).pop() );\n\t}\n\n\t/**\n\t * Returns the stack of the currently visible view.\n\t *\n\t * @private\n\t * @type {Set}\n\t */\n\tget _visibleStack() {\n\t\treturn this._viewToStack.get( this.visibleView );\n\t}\n\n\t/**\n\t * Returns the ID of the given stack.\n\t *\n\t * @private\n\t * @param {Set} stack\n\t * @returns {String}\n\t */\n\t_getStackId( stack ) {\n\t\tconst entry = Array.from( this._idToStack.entries() ).find( entry => entry[ 1 ] === stack );\n\n\t\treturn entry[ 0 ];\n\t}\n\n\t/**\n\t * Shows the last view from the next stack.\n\t *\n\t * @private\n\t */\n\t_showNextStack() {\n\t\tconst stacks = Array.from( this._idToStack.values() );\n\n\t\tlet nextIndex = stacks.indexOf( this._visibleStack ) + 1;\n\n\t\tif ( !stacks[ nextIndex ] ) {\n\t\t\tnextIndex = 0;\n\t\t}\n\n\t\tthis.showStack( this._getStackId( stacks[ nextIndex ] ) );\n\t}\n\n\t/**\n\t * Shows the last view from the previous stack.\n\t *\n\t * @private\n\t */\n\t_showPrevStack() {\n\t\tconst stacks = Array.from( this._idToStack.values() );\n\n\t\tlet nextIndex = stacks.indexOf( this._visibleStack ) - 1;\n\n\t\tif ( !stacks[ nextIndex ] ) {\n\t\t\tnextIndex = stacks.length - 1;\n\t\t}\n\n\t\tthis.showStack( this._getStackId( stacks[ nextIndex ] ) );\n\t}\n\n\t/**\n\t * Creates a rotator view.\n\t *\n\t * @private\n\t * @returns {module:ui/panel/balloon/contextualballoon~RotatorView}\n\t */\n\t_createRotatorView() {\n\t\tconst view = new RotatorView( this.editor.locale );\n\t\tconst t = this.editor.locale.t;\n\n\t\tthis.view.content.add( view );\n\n\t\t// Hide navigation when there is only a one stack & not in single view mode.\n\t\tview.bind( 'isNavigationVisible' ).to( this, '_numberOfStacks', this, '_singleViewMode', ( value, isSingleViewMode ) => {\n\t\t\treturn !isSingleViewMode && value > 1;\n\t\t} );\n\n\t\t// Update balloon position after toggling navigation.\n\t\tview.on( 'change:isNavigationVisible', () => ( this.updatePosition() ), { priority: 'low' } );\n\n\t\t// Update stacks counter value.\n\t\tview.bind( 'counter' ).to( this, 'visibleView', this, '_numberOfStacks', ( visibleView, numberOfStacks ) => {\n\t\t\tif ( numberOfStacks < 2 ) {\n\t\t\t\treturn '';\n\t\t\t}\n\n\t\t\tconst current = Array.from( this._idToStack.values() ).indexOf( this._visibleStack ) + 1;\n\n\t\t\treturn t( '%0 of %1', [ current, numberOfStacks ] );\n\t\t} );\n\n\t\tview.buttonNextView.on( 'execute', () => {\n\t\t\t// When current view has a focus then move focus to the editable before removing it,\n\t\t\t// otherwise editor will lost focus.\n\t\t\tif ( view.focusTracker.isFocused ) {\n\t\t\t\tthis.editor.editing.view.focus();\n\t\t\t}\n\n\t\t\tthis._showNextStack();\n\t\t} );\n\n\t\tview.buttonPrevView.on( 'execute', () => {\n\t\t\t// When current view has a focus then move focus to the editable before removing it,\n\t\t\t// otherwise editor will lost focus.\n\t\t\tif ( view.focusTracker.isFocused ) {\n\t\t\t\tthis.editor.editing.view.focus();\n\t\t\t}\n\n\t\t\tthis._showPrevStack();\n\t\t} );\n\n\t\treturn view;\n\t}\n\n\t/**\n\t * @private\n\t * @returns {module:ui/view~View}\n\t */\n\t_createFakePanelsView() {\n\t\tconst view = new FakePanelsView( this.editor.locale, this.view );\n\n\t\tview.bind( 'numberOfPanels' ).to( this, '_numberOfStacks', this, '_singleViewMode', ( number, isSingleViewMode ) => {\n\t\t\tconst showPanels = !isSingleViewMode && number >= 2;\n\n\t\t\treturn showPanels ? Math.min( number - 1, 2 ) : 0;\n\t\t} );\n\n\t\tview.listenTo( this.view, 'change:top', () => view.updatePosition() );\n\t\tview.listenTo( this.view, 'change:left', () => view.updatePosition() );\n\n\t\tthis.editor.ui.view.body.add( view );\n\n\t\treturn view;\n\t}\n\n\t/**\n\t * Sets the view as the content of the balloon and attaches the balloon using position\n\t * options of the first view.\n\t *\n\t * @private\n\t * @param {Object} data Configuration.\n\t * @param {module:ui/view~View} [data.view] The view to show in the balloon.\n\t * @param {String} [data.balloonClassName=''] Additional class name which will be added to the {@link #view balloon}.\n\t * @param {Boolean} [data.withArrow=true] Whether the {@link #view balloon} should be rendered with an arrow.\n\t */\n\t_showView( { view, balloonClassName = '', withArrow = true, singleViewMode = false } ) {\n\t\tthis.view.class = balloonClassName;\n\t\tthis.view.withArrow = withArrow;\n\n\t\tthis._rotatorView.showView( view );\n\t\tthis.visibleView = view;\n\t\tthis.view.pin( this._getBalloonPosition() );\n\t\tthis._fakePanelsView.updatePosition();\n\n\t\tif ( singleViewMode ) {\n\t\t\tthis._singleViewMode = true;\n\t\t}\n\t}\n\n\t/**\n\t * Returns position options of the last view in the stack.\n\t * This keeps the balloon in the same position when the view is changed.\n\t *\n\t * @private\n\t * @returns {module:utils/dom/position~Options}\n\t */\n\t_getBalloonPosition() {\n\t\tlet position = Array.from( this._visibleStack.values() ).pop().position;\n\n\t\t// Use the default limiter if none has been specified.\n\t\tif ( position && !position.limiter ) {\n\t\t\t// Don't modify the original options object.\n\t\t\tposition = Object.assign( {}, position, {\n\t\t\t\tlimiter: this.positionLimiter\n\t\t\t} );\n\t\t}\n\n\t\treturn position;\n\t}\n}\n\n/**\n * Rotator view is a helper class for the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon ContextualBalloon}.\n * It is used for displaying the last view from the current stack and providing navigation buttons for switching stacks.\n * See the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon ContextualBalloon} documentation to learn more.\n *\n * @extends module:ui/view~View\n */\nclass RotatorView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tconst t = locale.t;\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * Defines whether navigation is visible or not.\n\t\t *\n\t\t * @member {Boolean} #isNavigationVisible\n\t\t */\n\t\tthis.set( 'isNavigationVisible', true );\n\n\t\t/**\n\t\t * Used for checking if a view is focused or not.\n\t\t *\n\t\t * @type {module:utils/focustracker~FocusTracker}\n\t\t */\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\t/**\n\t\t * Navigation button for switching the stack to the previous one.\n\t\t *\n\t\t * @type {module:ui/button/buttonview~ButtonView}\n\t\t */\n\t\tthis.buttonPrevView = this._createButtonView( t( 'Previous' ), prevIcon );\n\n\t\t/**\n\t\t * Navigation button for switching the stack to the next one.\n\t\t *\n\t\t * @type {module:ui/button/buttonview~ButtonView}\n\t\t */\n\t\tthis.buttonNextView = this._createButtonView( t( 'Next' ), nextIcon );\n\n\t\t/**\n\t\t * A collection of the child views that creates the rotator content.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.content = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-balloon-rotator'\n\t\t\t\t],\n\t\t\t\t'z-index': '-1'\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck-balloon-rotator__navigation',\n\t\t\t\t\t\t\tbind.to( 'isNavigationVisible', value => value ? '' : 'ck-hidden' )\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\tthis.buttonPrevView,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttag: 'span',\n\n\t\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t\t\t'ck-balloon-rotator__counter'\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttext: bind.to( 'counter' )\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\tthis.buttonNextView\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: 'ck-balloon-rotator__content'\n\t\t\t\t\t},\n\t\t\t\t\tchildren: this.content\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tthis.focusTracker.add( this.element );\n\t}\n\n\t/**\n\t * Shows a given view.\n\t *\n\t * @param {module:ui/view~View} view The view to show.\n\t */\n\tshowView( view ) {\n\t\tthis.hideView();\n\t\tthis.content.add( view );\n\t}\n\n\t/**\n\t * Hides the currently displayed view.\n\t */\n\thideView() {\n\t\tthis.content.clear();\n\t}\n\n\t/**\n\t * Creates a navigation button view.\n\t *\n\t * @private\n\t * @param {String} label The button label.\n\t * @param {String} icon The button icon.\n\t * @returns {module:ui/button/buttonview~ButtonView}\n\t */\n\t_createButtonView( label, icon ) {\n\t\tconst view = new ButtonView( this.locale );\n\n\t\tview.set( {\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ttooltip: true\n\t\t} );\n\n\t\treturn view;\n\t}\n}\n\n// Displays additional layers under the balloon when multiple stacks are added to the balloon.\n//\n// @private\n// @extends module:ui/view~View\nclass FakePanelsView extends View {\n\t// @inheritDoc\n\tconstructor( locale, balloonPanelView ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t// Fake panels top offset.\n\t\t//\n\t\t// @observable\n\t\t// @member {Number} #top\n\t\tthis.set( 'top', 0 );\n\n\t\t// Fake panels left offset.\n\t\t//\n\t\t// @observable\n\t\t// @member {Number} #left\n\t\tthis.set( 'left', 0 );\n\n\t\t// Fake panels height.\n\t\t//\n\t\t// @observable\n\t\t// @member {Number} #height\n\t\tthis.set( 'height', 0 );\n\n\t\t// Fake panels width.\n\t\t//\n\t\t// @observable\n\t\t// @member {Number} #width\n\t\tthis.set( 'width', 0 );\n\n\t\t// Number of rendered fake panels.\n\t\t//\n\t\t// @observable\n\t\t// @member {Number} #numberOfPanels\n\t\tthis.set( 'numberOfPanels', 0 );\n\n\t\t// Collection of the child views which creates fake panel content.\n\t\t//\n\t\t// @readonly\n\t\t// @type {module:ui/viewcollection~ViewCollection}\n\t\tthis.content = this.createCollection();\n\n\t\t// Context.\n\t\t//\n\t\t// @private\n\t\t// @type {module:ui/panel/balloon/balloonpanelview~BalloonPanelView}\n\t\tthis._balloonPanelView = balloonPanelView;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-fake-panel',\n\t\t\t\t\tbind.to( 'numberOfPanels', number => number ? '' : 'ck-hidden' )\n\t\t\t\t],\n\t\t\t\tstyle: {\n\t\t\t\t\ttop: bind.to( 'top', toPx ),\n\t\t\t\t\tleft: bind.to( 'left', toPx ),\n\t\t\t\t\twidth: bind.to( 'width', toPx ),\n\t\t\t\t\theight: bind.to( 'height', toPx )\n\t\t\t\t}\n\t\t\t},\n\t\t\tchildren: this.content\n\t\t} );\n\n\t\tthis.on( 'change:numberOfPanels', ( evt, name, next, prev ) => {\n\t\t\tif ( next > prev ) {\n\t\t\t\tthis._addPanels( next - prev );\n\t\t\t} else {\n\t\t\t\tthis._removePanels( prev - next );\n\t\t\t}\n\n\t\t\tthis.updatePosition();\n\t\t} );\n\t}\n\n\t// @private\n\t// @param {Number} number\n\t_addPanels( number ) {\n\t\twhile ( number-- ) {\n\t\t\tconst view = new View();\n\n\t\t\tview.setTemplate( { tag: 'div' } );\n\n\t\t\tthis.content.add( view );\n\t\t\tthis.registerChild( view );\n\t\t}\n\t}\n\n\t// @private\n\t// @param {Number} number\n\t_removePanels( number ) {\n\t\twhile ( number-- ) {\n\t\t\tconst view = this.content.last;\n\n\t\t\tthis.content.remove( view );\n\t\t\tthis.deregisterChild( view );\n\t\t\tview.destroy();\n\t\t}\n\t}\n\n\t// Updates coordinates of fake panels.\n\tupdatePosition() {\n\t\tif ( this.numberOfPanels ) {\n\t\t\tconst { top, left } = this._balloonPanelView;\n\t\t\tconst { width, height } = new Rect( this._balloonPanelView.element );\n\n\t\t\tObject.assign( this, { top, left, width, height } );\n\t\t}\n\t}\n}\n"],"sourceRoot":""}