Controller.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. 'use strict';
  2. /**
  3. * Licensed Materials - Property of IBM
  4. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2013, 2019
  5. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  6. */
  7. define(['../../../../lib/@waca/core-client/js/core-client/ui/core/Class', 'underscore', '../../../../lib/@waca/dashboard-common/dist/ui/AuthoringToolbar', '../../../../lib/@waca/dashboard-common/dist/utils/ActionTypes', './Selection', '../../../../app/util/EventChainLocal', 'jquery'], function (Class, _, Toolbar, ActionTypes, Selection, EventChainLocal, $) {
  8. /**
  9. * Base interaction controller. This class only handles node selection.
  10. */
  11. var Controller = Class.extend({
  12. init: function init(options) {
  13. this.$el = options.$el;
  14. this.glassContext = options.glassContext;
  15. // TODO: clean this - This is only here because of other code referencing the dashboard Api off the controller.
  16. this.dashboardApi = options.dashboardAPI;
  17. this.transaction = options.transaction;
  18. this.toolbarConfig = options.toolbarConfig;
  19. this.canvas = options.canvas;
  20. this.appSettings = options.appSettings || {};
  21. this.layoutController = options.layoutController;
  22. this.eventRouter = options.eventRouter;
  23. this.boardModel = options.boardModel;
  24. this.layout = this.boardModel && this.boardModel.layout;
  25. this._glass = options.glass ? options.glass : window.glass;
  26. this.services = options.services;
  27. this.config = this.appSettings.options && this.appSettings.options.config || {};
  28. this.gatewayUrl = options.gatewayUrl;
  29. this.toolbarItems = [];
  30. this.dynamicToolbarItems = []; //toolbarItems that are non-default (associated with a selection context)
  31. this._toolbarDock = this.dashboardApi.getFeature('ToolbarDock');
  32. this._contentActions = this.dashboardApi.getFeature('ContentActions');
  33. this.toolbar = new Toolbar({
  34. calculateBoundingRect: true,
  35. container: $('body'),
  36. reactToolbar: true
  37. });
  38. this.defaultToolbarOptions = {
  39. textOnly: false,
  40. iconOnly: false
  41. };
  42. this.toolbarMidShow = false;
  43. this.selectedNodes = null;
  44. if (this.eventRouter) {
  45. this.eventRouter.on('widget:availableActions', this.onUpdateAvailableActions, this);
  46. this.eventRouter.on('widget:maximize', this._hideToolbar, this);
  47. this.eventRouter.on('widget:hideToolbar', this._hideToolbar, this);
  48. this.eventRouter.on('widget:deleteItem', this._deleteItem, this);
  49. this.toolbar.on('toolbar:show:before', this._toolbarShowBefore, this);
  50. this.toolbar.on('toolbar:show', this._toolbarShowAfter, this);
  51. this.toolbar.on('toolbar:hide', this._toolbarHideAfter, this);
  52. }
  53. var _ref = options.selectionOptions || {},
  54. deselectionSelector = _ref.deselectionSelector;
  55. this.selectionHandler = new Selection({
  56. controller: this,
  57. canvas: this.canvas,
  58. transaction: this.transaction,
  59. deselectionSelector: deselectionSelector ? deselectionSelector.bind(null, this.layoutController) : null
  60. });
  61. this.selectionHandler.on('selection:nodeSelected', this.onNodeSelected, this);
  62. this.selectionHandler.on('selection:nodeDeselected', this.onNodeDeselected, this);
  63. this.selectionHandler.on('selection:ready', this.onSelectionDone, this);
  64. // re-enable the toolbar when the user reselect widgets
  65. this.selectionHandler.on('selection:reselect', this.onWidgetReselect, this);
  66. // add keydown handler to set focus on the toolbar
  67. this.$el.on('keydown.InteractionController', this.onKeydown.bind(this));
  68. },
  69. /**
  70. * Check the app setting to see whether the toolbar is enabled or not
  71. *
  72. * @return {boolean} TRUE if enabled and FALSE if not
  73. */
  74. isToolbarEnabled: function isToolbarEnabled() {
  75. var toolbar = this.toolbarConfig;
  76. return toolbar === undefined || toolbar === true || toolbar === 'true';
  77. },
  78. applyInteractions: function applyInteractions(interactions) {
  79. this.destroyInteractions();
  80. this.toolbarItems = [];
  81. this.dynamicToolbarItems = []; //toolbarItems that are non-default (associated with a selection context)
  82. this.interactions = interactions;
  83. return this._attachInteractions();
  84. },
  85. finishMoveSelection: function finishMoveSelection(e) {
  86. this.selectionHandler.finishMoveSelection(e);
  87. },
  88. /**
  89. * Handle keydown event
  90. */
  91. onKeydown: function onKeydown(event) {
  92. // trap the F10 keydown event and focus the toolbar if visible
  93. if (event.keyCode === 121 && this.toolbar.focus()) {
  94. // stop propagation so that the ApplicationBar dosen't get focus
  95. event.stopPropagation();
  96. // must return false to prevent browser F10 interaction
  97. return false;
  98. }
  99. },
  100. /*
  101. * Handle scroll event
  102. * closes any open toolbar flyouts when the page is scrolled
  103. */
  104. onPageScroll: function onPageScroll(event) {
  105. //scroll events belonging to children are propagated, make sure the scroll happened on the page, and that we aren't mid-show of a toolbar.
  106. //(This last condition has been added due to bug 250981. If you are scrolled to the very bottom of the canvas, the bootstrap popover display can briefly render the tooltip partially off screen causing this scroll event to fire for some reason. This does not happen if the canvas is not scrolled to the very bottom, but to avoid this, don't hide the toolbar if we get a scroll event fired during the show process)
  107. if (event.target.className.indexOf('page') > -1 && (event.target.className.indexOf('pageabsolute') > -1 || event.target.className.indexOf('pagecontainer') > -1) && !this.toolbarMidShow) {
  108. this._hideToolbar();
  109. }
  110. },
  111. getInteraction: function getInteraction(name) {
  112. var interaction = null;
  113. this.interactions.find(function (interactionStrategy) {
  114. interaction = interactionStrategy.getInteraction(name);
  115. return interaction;
  116. });
  117. return interaction;
  118. },
  119. _attachInteractions: function _attachInteractions() {
  120. var _this = this;
  121. var promise = Promise.resolve();
  122. this.interactions && this.interactions.forEach(function (interaction) {
  123. promise = promise.then(function () {
  124. return interaction.attachInteractions(_this);
  125. });
  126. });
  127. return promise;
  128. },
  129. addActionForSelector: function addActionForSelector(handler, selector, disableUserSelection) {
  130. this.selectionHandler.addActionForSelector(handler, selector, disableUserSelection);
  131. },
  132. /**
  133. * Called when the selection gesture is complete. Here we handle the widget contextual toolbar.
  134. * @param param
  135. */
  136. onSelectionDone: function onSelectionDone(param) {
  137. this.selectedNodes = param.selectedNodes;
  138. // Add widget specific actions to the toolbar if we have we a single widget selected
  139. this.removeDynamicToolbarAndRestoreWidgetToolbar(param);
  140. if (this.eventRouter) {
  141. this.eventRouter.trigger('selection:ready', param);
  142. }
  143. },
  144. getSelectedNodes: function getSelectedNodes() {
  145. return this.selectedNodes ? this.selectedNodes : [];
  146. },
  147. getInteractionProperties: function getInteractionProperties() {
  148. return this.selectionHandler.getInteractionProperties();
  149. },
  150. onNodeSelected: function onNodeSelected(param) {
  151. if (param && param.node) {
  152. if (param.node._layout) {
  153. param.node._layout.onSelect();
  154. }
  155. }
  156. },
  157. onNodeDeselected: function onNodeDeselected(param) {
  158. if (param && param.node) {
  159. if (param.node._layout) {
  160. param.node._layout.onDeselect();
  161. }
  162. }
  163. },
  164. addContextualToolbar: function addContextualToolbar(item) {
  165. this.addContextualToolbarToArray(item, this.toolbarItems);
  166. },
  167. addContextualToolbarToArray: function addContextualToolbarToArray(item, itemArray) {
  168. var existingItem = _.find(itemArray, function (f) {
  169. return f.name === item.name;
  170. });
  171. if (!existingItem) {
  172. itemArray.push(item);
  173. }
  174. },
  175. removeContextualToolbar: function removeContextualToolbar(item) {
  176. if (item) {
  177. this.toolbarItems = this._removeToolbarItem(item, this.toolbarItems);
  178. }
  179. },
  180. _removeToolbarItem: function _removeToolbarItem(item, toolbarItems) {
  181. return _.reject(toolbarItems, function (f) {
  182. return f.name === item.name;
  183. });
  184. },
  185. /**
  186. * Remove any dynamic toolbar items received by the widget iteself
  187. */
  188. removeDynamicToolbarItems: function removeDynamicToolbarItems() {
  189. _.each(this.dynamicToolbarItems, function (item) {
  190. this.removeContextualToolbar(item);
  191. }.bind(this));
  192. },
  193. /**
  194. * Remove any widget specific item from the toolbar
  195. */
  196. removeWidgetContextToolbarItems: function removeWidgetContextToolbarItems() {
  197. if (this.widgetContextItems) {
  198. if (this.widgetContextItems.onBlur) {
  199. this.widgetContextItems.onBlur();
  200. }
  201. var items = this.widgetContextItems.items;
  202. for (var i = 0; i < items.length; i++) {
  203. this.removeContextualToolbar(items[i]);
  204. }
  205. this.widgetContextItems = null;
  206. }
  207. },
  208. onSelectionMoveOrResize: function onSelectionMoveOrResize() {
  209. this.toolbar.hide();
  210. this.eventRouter.trigger('widget:hideToolbar');
  211. },
  212. onSelectionDelete: function onSelectionDelete() {
  213. return this._hideToolbar();
  214. },
  215. removeDynamicToolbarAndRestoreWidgetToolbar: function removeDynamicToolbarAndRestoreWidgetToolbar(param) {
  216. var isEventPrevented = param.event && new EventChainLocal(param.event).getProperty('preventDefaultContextBar');
  217. if (!isEventPrevented) {
  218. this._removeDynamicToolbarAndRestoreWidgetToolbar(param.event);
  219. this.eventRouter.trigger('widget:toolbarItems:changed');
  220. }
  221. },
  222. _updateToolbarDock: function _updateToolbarDock(nodes) {
  223. var _this2 = this;
  224. var idList = nodes.map(function (node) {
  225. return node.id;
  226. });
  227. return this.toolbar.setSelectionContext(nodes).then(function () {
  228. _this2._toolbarDock.updateODTState(_this2._contentActions.getContentActionList(idList), idList);
  229. return;
  230. });
  231. },
  232. _removeDynamicToolbarAndRestoreWidgetToolbar: function _removeDynamicToolbarAndRestoreWidgetToolbar(event) {
  233. var options = event && event.options || {
  234. flyout: true
  235. };
  236. var showToolbar = this.isToolbarEnabled() && !!options.flyout;
  237. // Generate the toolbar items even if we don't render the toolbar. This is used in Explore where a different toolbar
  238. // and a slightly different flow is used.
  239. //
  240. // YES - this has to be refactored...
  241. this.removeDynamicToolbarItems();
  242. if (showToolbar) {
  243. this._updateToolbar({
  244. nodes: this.selectedNodes,
  245. options: {
  246. isWidgetOdt: true,
  247. addClass: ['odtWidget']
  248. }
  249. }, this.toolbarItems, true, event);
  250. }
  251. },
  252. /**
  253. * update the toolbar with the specified set of availableActions
  254. * (actions which are relevant to a particular selection within the widget).
  255. * @param availableActions a set of actions to update the toolbar with.
  256. */
  257. onUpdateAvailableActions: function onUpdateAvailableActions(availableActions) {
  258. this.dynamicToolbarItems = [];
  259. if (availableActions.toolbarOptions) {
  260. //New options for the toolbar created
  261. _.extend(this.toolbar.options, this.defaultToolbarOptions, availableActions.toolbarOptions);
  262. } else {
  263. _.extend(this.toolbar.options, this.defaultToolbarOptions);
  264. }
  265. _.each(availableActions.actions, function (availableAction) {
  266. this.addContextualToolbarToArray(availableAction, this.dynamicToolbarItems);
  267. }.bind(this));
  268. var options = {
  269. nodes: availableActions.targetNode ? [availableActions.targetNode] : this.selectedNodes
  270. };
  271. return this._updateToolbar(_.extend(options, availableActions), this.dynamicToolbarItems, true);
  272. },
  273. /**
  274. * Update the toolbar. If there is no content or selected content, then we hide the toolbar, otherwise we update it and show it.
  275. * This function will show the toolbar using a setTimeout and supports canceling previous timers if they are still pending.
  276. * This is used to avoid showing different toolbars quickly one after the other.
  277. *
  278. * @param selectionContext
  279. * @param toolbarItems
  280. * @param overridePendingRequest - if true, and there is a pending toolbar.show and a new toolbar update occurs, then we cancel the pending toolbar.
  281. * @returns
  282. */
  283. _updateToolbar: function _updateToolbar(selectionContext, toolbarItems, overridePendingRequest, event) {
  284. var nodes = selectionContext.nodes;
  285. var idList = _.map(nodes, function (node) {
  286. return node.id;
  287. });
  288. var isWidgetOdt = selectionContext && selectionContext.options && selectionContext.options.isWidgetOdt;
  289. var widgetActionList = isWidgetOdt && this.canvas.getContentActionList(idList);
  290. var updatedToolBarItems = widgetActionList ? toolbarItems.concat(widgetActionList) : toolbarItems;
  291. var labels = selectionContext.labels;
  292. var hasContext = nodes && nodes.length > 0 || selectionContext.targetBounds;
  293. var hasContent = updatedToolBarItems.length > 0 || labels && labels.length > 0 || selectionContext.title && selectionContext.title.length > 0;
  294. var result = void 0;
  295. if (hasContext && hasContent) {
  296. result = this._createToolbarShowTimer(selectionContext, updatedToolBarItems, overridePendingRequest, event);
  297. } else {
  298. result = this._hideToolbar();
  299. }
  300. return result;
  301. },
  302. _createToolbarShowTimer: function _createToolbarShowTimer(selectionContext, toolbarItems, overridePendingRequest, event) {
  303. var _this3 = this;
  304. var updateToolbar;
  305. if (event && event.target) {
  306. updateToolbar = this._shouldUpdateToolbar(event);
  307. } else {
  308. updateToolbar = true;
  309. }
  310. var result = void 0;
  311. if (updateToolbar) {
  312. if (overridePendingRequest) {
  313. this._clearToolbarUpdateTimer();
  314. }
  315. if (!this.toolbarUpdateTimer) {
  316. this.shownToolbarItems = toolbarItems;
  317. result = new Promise(function (resolve, reject) {
  318. try {
  319. var isWidgetOdt = selectionContext && selectionContext.options && selectionContext.options.isWidgetOdt;
  320. if (_this3._toolbarDock && _this3._toolbarDock.isContentToolbarDocked() && toolbarItems.length && isWidgetOdt) {
  321. _this3.toolbarUpdateTimer = setTimeout(function () {
  322. this._updateToolbarDock(selectionContext.nodes).then(resolve, reject);
  323. }.bind(_this3), 100);
  324. } else {
  325. _this3.toolbarUpdateTimer = setTimeout(function () {
  326. this._showContextualToolbar(selectionContext, toolbarItems).then(resolve, reject);
  327. }.bind(_this3), 100);
  328. }
  329. } catch (error) {
  330. reject(error);
  331. }
  332. });
  333. }
  334. } else {
  335. result = Promise.resolve();
  336. }
  337. return result;
  338. },
  339. _shouldUpdateToolbar: function _shouldUpdateToolbar(event) {
  340. // When default is prevented, don't show the toolbar.
  341. if (!this.isToolbarEnabled()) {
  342. return false;
  343. }
  344. return !event.target.isContentEditable && !$(event.target).data('isContentEditable') && !event.target.tagName.toLowerCase().match(/input|textarea|select/img);
  345. },
  346. _clearToolbarUpdateTimer: function _clearToolbarUpdateTimer() {
  347. if (this.toolbarUpdateTimer) {
  348. clearTimeout(this.toolbarUpdateTimer);
  349. this.toolbarUpdateTimer = null;
  350. }
  351. },
  352. /**
  353. * Utility for hiding the odt/tooltip flyout
  354. * @param {Object} eventListener - custom event listener details for unbinding
  355. * @key classList @val {string} list of classes to find and apply the unbind to
  356. * @key event @val {string} event to unbind
  357. */
  358. _hideToolbar: function _hideToolbar(eventListener) {
  359. var _this4 = this;
  360. this.shownToolbarItems = null;
  361. this._clearToolbarUpdateTimer();
  362. //remove event listener when the toolbar is hidden - allow custom event details
  363. if (eventListener && eventListener.node && eventListener.eventName && eventListener.func) {
  364. eventListener.node.off(eventListener.eventName, eventListener.func);
  365. } else {
  366. this.$el.find('.page.pageabsolute, .page.pagecontainer').off('scroll.BaseController');
  367. }
  368. var hideToolbarPromise = this.toolbar.hide();
  369. hideToolbarPromise.then(function () {
  370. _this4.eventRouter.trigger('widget:hideToolbar:done');
  371. });
  372. return hideToolbarPromise;
  373. },
  374. _deleteItem: function _deleteItem(options) {
  375. this.boardModel.removeLayouts([options.widgetId]);
  376. },
  377. _toolbarShowBefore: function _toolbarShowBefore(payload) {
  378. this.toolbarMidShow = true;
  379. this.eventRouter.trigger('widget:toolbar:show:before', payload);
  380. },
  381. _toolbarShowAfter: function _toolbarShowAfter(payload) {
  382. this.toolbarMidShow = false;
  383. this.eventRouter.trigger('widget:toolbar:show:after', payload);
  384. },
  385. _toolbarHideAfter: function _toolbarHideAfter(payload) {
  386. this.toolbarMidShow = false;
  387. this.eventRouter.trigger('widget:toolbar:hide:after', payload);
  388. },
  389. /**
  390. * Helper for handling scroll on a grid widget and hiding the tooltip on scroll. binds an event to the virtual scroll area
  391. * @param {Object} selectionContext - selectionContext passed from visEventHandler:_showSelectionInfo -> visActionHelper:showDataPointActions -> this._showContextualToolbar
  392. */
  393. handleScrollForGridWidgets: function handleScrollForGridWidgets(selectionContext) {
  394. var _this5 = this;
  395. var gridViewClassName = 'grid-view';
  396. var eventName = 'scroll.virtualScroll';
  397. if (selectionContext && selectionContext.targetNode && selectionContext.targetNode.classList && selectionContext.targetNode.classList.contains) {
  398. if (selectionContext.targetNode.classList.contains(gridViewClassName)) {
  399. var scrollableArea = this._findScrollableArea(selectionContext.targetNode);
  400. if (!scrollableArea) {
  401. return;
  402. }
  403. var $scrollableAreaElement = $(scrollableArea);
  404. var options = {
  405. node: $scrollableAreaElement,
  406. eventName: eventName,
  407. func: this._hideToolbarForGridWidgets
  408. };
  409. $scrollableAreaElement.on(eventName, function () {
  410. _this5._hideToolbarForGridWidgets(options);
  411. });
  412. }
  413. }
  414. },
  415. /**
  416. * Recursively walks down the children tree of a DOM node till it finds the right element
  417. * For this specific case its 3 children down
  418. * @param {DOM Element} ele - Dom element with children
  419. * @return if id matches 'scrollableArea' a DOM element, else undefined.
  420. */
  421. _findScrollableArea: function _findScrollableArea() {
  422. var ele = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  423. if (ele.id && ele.id.match && ele.id.match('scrollableArea')) {
  424. return ele;
  425. } else if (ele.children && ele.children.length) {
  426. return this._findScrollableArea(ele.children[0]);
  427. } else {
  428. return false;
  429. }
  430. },
  431. /**
  432. * Helper for hiding the toolbar when we scroll on a grid widget
  433. * @param {Object} opts
  434. * @param {DOM element} opts.node - node to bind/unbind listener to
  435. * @param {String} opts.eventName - DOM/node event to listen to/ bind/unbind from
  436. * @param {Function} opts.func - function we bind/unbind
  437. */
  438. _hideToolbarForGridWidgets: function _hideToolbarForGridWidgets(opts) {
  439. this._hideToolbar(opts);
  440. },
  441. /**
  442. * Update the contextual toolbar content and show it
  443. *
  444. * @param selectionContext
  445. * @param toolbarItems
  446. * @returns
  447. */
  448. _showContextualToolbar: function _showContextualToolbar(selectionContext, toolbarItems) {
  449. this.toolbarUpdateTimer = null;
  450. var nodes = selectionContext.nodes;
  451. var labels = selectionContext.labels;
  452. this.eventRouter.trigger('textToolbar:hide');
  453. var updateToolbar = function () {
  454. delete this.toolbar.options.placement;
  455. if (selectionContext.placement) {
  456. this.toolbar.options.placement = selectionContext.placement;
  457. }
  458. this.toolbar.setName(selectionContext.toolbarName);
  459. this.toolbar.setLabels({
  460. title: selectionContext.title,
  461. labels: labels,
  462. tooltipContext: selectionContext.tooltipContext,
  463. tooltipRenderer: this.dashboardApi.getFeature('TooltipRenderer.react')
  464. });
  465. // Add listener to close the toolbar when the user scrolls the page
  466. this.$el.find('.page.pageabsolute, .page.pagecontainer').on('scroll.BaseController', this.onPageScroll.bind(this));
  467. // [250580] Remove the label hover tooltip on scroll in grid widgets
  468. if ((selectionContext.title || labels) && !selectionContext.options.isWidgetOdt) {
  469. this.handleScrollForGridWidgets(selectionContext);
  470. }
  471. if (selectionContext.options && selectionContext.options.hasOwnProperty('isHover') && selectionContext.options.isHover === true) {
  472. this.toolbar.options.hideOnMouseLeave = true;
  473. } else {
  474. this.toolbar.options.hideOnMouseLeave = false;
  475. }
  476. return this.toolbar.show();
  477. }.bind(this);
  478. this.toolbar.clearHistory();
  479. this.toolbar.clearItems();
  480. toolbarItems.forEach(function (item) {
  481. if (item.order === undefined) {
  482. item.order = ActionTypes[item.name];
  483. }
  484. });
  485. this.toolbar.addItems(toolbarItems.sort(function (a, b) {
  486. if (a.order && b.order || !a.order && !b.order) {
  487. return a.order - b.order;
  488. }
  489. // defined order should be before undefined order
  490. if (a.order && !b.order) {
  491. // a before b
  492. return -1;
  493. }
  494. if (!a.order && b.order) {
  495. // b before a
  496. return 1;
  497. }
  498. }));
  499. this.toolbar.setOptions(selectionContext.options);
  500. if (selectionContext.targetBounds) {
  501. this.toolbar.options.preferredVertical = false;
  502. return this.toolbar.setSelectionBounds(selectionContext.targetBounds).then(function () {
  503. return updateToolbar();
  504. });
  505. }
  506. var isWidgetOrPagegroup = $(nodes).is('.widget, .pagegroup');
  507. this.toolbar.options.iconOnly = isWidgetOrPagegroup;
  508. this.toolbar.options.preferredVertical = isWidgetOrPagegroup;
  509. return this.toolbar.setSelectionContext(nodes).then(function () {
  510. return updateToolbar();
  511. });
  512. },
  513. onWidgetReselect: function onWidgetReselect(param) {
  514. // toggle the contextual toolbar - watch for dynamic toolbar
  515. if (this.toolbar.isOpened) {
  516. if (this.toolbar._viewStack.length === 0) {
  517. return this.toolbar.hide();
  518. }
  519. } else {
  520. // Clear dynamic toolbar and show the widget contextual toolbar.
  521. this.removeDynamicToolbarAndRestoreWidgetToolbar(param);
  522. }
  523. },
  524. destroyInteractions: function destroyInteractions() {
  525. // Cleanup and remove event handlers
  526. if (this.selectionHandler) {
  527. this.selectionHandler.disableInteraction();
  528. }
  529. if (this.interactions) {
  530. this.interactions.forEach(function (interaction) {
  531. if (interaction.destroy) {
  532. interaction.destroy();
  533. }
  534. });
  535. this.interactions = null;
  536. }
  537. },
  538. destroy: function destroy() {
  539. // Before disabling the interaction,
  540. // let us clear the selection handler events so that we don't trigger useless code on derstruction.
  541. if (this.selectionHandler) {
  542. this.selectionHandler.off();
  543. this.destroyInteractions();
  544. this.selectionHandler = null;
  545. }
  546. if (this.eventRouter) {
  547. this.eventRouter.off('widget:availableActions', this.onUpdateAvailableActions, this);
  548. this.eventRouter.off('widget:maximize', this._hideToolbar, this);
  549. this.eventRouter.off('widget:hideToolbar', this._hideToolbar, this);
  550. this.toolbar.off('toolbar:show:before', this._toolbarShowBefore, this);
  551. this.toolbar.off('toolbar:show', this._toolbarShowAfter, this);
  552. this.toolbar.off('toolbar:hide', this._toolbarHideAfter, this);
  553. }
  554. // remove event listener
  555. this.$el.off('keydown.InteractionController');
  556. this.toolbar.remove();
  557. }
  558. });
  559. return Controller;
  560. });
  561. //# sourceMappingURL=Controller.js.map