AnimationDirector.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. 'use strict';
  2. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3. /**
  4. * Licensed Materials - Property of IBM
  5. * IBM Cognos Products: Storytelling
  6. * (C) Copyright IBM Corp. 2017, 2019
  7. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  8. */
  9. define(['baglass/core-client/js/core-client/utils/BrowserUtils'], function (BrowserUtils) {
  10. var AnimationDirector = function () {
  11. function AnimationDirector(options) {
  12. _classCallCheck(this, AnimationDirector);
  13. this.pageContextAPI = options.pageContextAPI;
  14. this.widgetHelper = options.widgetHelper;
  15. this._inProgressCssAnimations = {};
  16. this._inProgressWidgetsAnimation = {};
  17. this._scrollBarsStateLockCount = 0;
  18. }
  19. /**
  20. * animates a widget
  21. * @param payload {object}
  22. * {
  23. * target: {string} target widget id"
  24. * duration: {integer} in ms
  25. * animation: {string} animation type
  26. * payload: {object} animation specific information
  27. * }
  28. */
  29. AnimationDirector.prototype.animate = function animate(payload) {
  30. var _this = this;
  31. var widgetId = payload.target;
  32. var node = this.widgetHelper.getContentNode(widgetId);
  33. if (!node) {
  34. return;
  35. }
  36. var transform = this._getLayoutNodeTransform(widgetId);
  37. transform = transform ? ' rotate(' + transform + 'deg)' : transform;
  38. this._finishInProgressCssAnimation(node);
  39. if (payload.duration === 0) {
  40. this._immediateAnimate(node, transform, payload);
  41. return Promise.resolve();
  42. }
  43. if (payload.reveal) {
  44. return this._reveal(payload.target).finally(function () {
  45. return _this._animate(node, transform, payload);
  46. });
  47. } else {
  48. return this._animate(node, transform, payload);
  49. }
  50. };
  51. AnimationDirector.prototype._animate = function _animate(node, transform, payload) {
  52. var _this2 = this;
  53. var width = parseInt(this._getNodeWidth(node), 10);
  54. var height = parseInt(this._getNodeHeight(node), 10);
  55. var bounds = node.getBoundingClientRect();
  56. var left = parseInt(bounds.left, 10);
  57. var top = parseInt(bounds.top, 10);
  58. var docWidth = this._getDocumentWidth();
  59. var docHeight = this._getDocumentHeight();
  60. var duration = payload.duration;
  61. var opacity = node.style.opacity;
  62. var endVal = void 0;
  63. if (payload.animation === 'scaleIn') {
  64. this._lockScrollBarsState(node);
  65. return this._animation(node, {
  66. 'transition': 'transform ' + duration + 'ms',
  67. 'transform': transform
  68. }, function () {
  69. _this2._restoreScrollBarsState(node);
  70. });
  71. } else if (payload.animation === 'scaleOut') {
  72. this._lockScrollBarsState(node);
  73. return this._animation(node, {
  74. 'transition': 'transform ' + duration + 'ms',
  75. 'transform': 'scale(0,0) translate(0,0) rotate(0)' + transform
  76. }, function () {
  77. node.style.transition = 'all 0s';
  78. _this2._restoreScrollBarsState(node);
  79. });
  80. } else if (payload.animation === 'shrinkIn') {
  81. this._lockScrollBarsState(node);
  82. this._forceCssWrite(node, {
  83. 'opacity': '0',
  84. 'transition': 'all 0s',
  85. 'transform': 'scale(5,5) translate(0,0) rotate(0)' + transform
  86. });
  87. return this._animation(node, {
  88. 'opacity': opacity,
  89. 'transition': 'transform ' + duration + 'ms, opacity ' + duration + 'ms',
  90. 'transform': transform
  91. }, function () {
  92. _this2._restoreScrollBarsState(node);
  93. }, 2);
  94. } else if (payload.animation === 'expandOut') {
  95. this._lockScrollBarsState(node);
  96. return this._animation(node, {
  97. 'opacity': '0',
  98. 'transition': 'transform ' + duration + 'ms, opacity ' + duration + 'ms',
  99. 'transform': 'scale(5,5) translate(0,0) rotate(0)' + transform
  100. }, function () {
  101. node.style.opacity = opacity;
  102. node.style.transition = 'all 0s';
  103. node.style.transform = 'scale(0,0) translate(0,0) rotate(0)' + transform;
  104. _this2._restoreScrollBarsState(node);
  105. }, 2);
  106. } else if (payload.animation === 'pivotIn') {
  107. this._lockScrollBarsState(node);
  108. this._forceCssWrite(node, {
  109. 'opacity': '0',
  110. 'transition': 'all 0s',
  111. 'transform': 'scale(1,1) translate(-50%,50%) rotate(-45deg) translate(50%,-50%)' + transform
  112. });
  113. return this._animation(node, {
  114. 'opacity': opacity,
  115. 'transition': 'transform ' + duration + 'ms, opacity ' + duration + 'ms',
  116. 'transform': transform
  117. }, function () {
  118. _this2._restoreScrollBarsState(node);
  119. }, 2);
  120. } else if (payload.animation === 'pivotOut') {
  121. this._lockScrollBarsState(node);
  122. return this._animation(node, {
  123. 'opacity': '0',
  124. 'transition': 'transform ' + duration + 'ms, opacity ' + duration + 'ms',
  125. 'transform': 'scale(1,1) translate(50%,50%) rotate(45deg) translate(-50%,-50%)' + transform
  126. }, function () {
  127. node.style.opacity = opacity;
  128. node.style.transition = 'all 0s';
  129. node.style.transform = 'scale(0,0) translate(0,0) rotate(0)' + transform;
  130. _this2._restoreScrollBarsState(node);
  131. }, 2);
  132. } else if (payload.animation === 'slideInLeft') {
  133. endVal = left + width;
  134. if (node.parentElement && node.parentElement.offsetLeft) {
  135. endVal += node.parentElement.offsetLeft;
  136. }
  137. // Make sure node is: 1) to scale; 2) at the proper opacity level; 3) at its correct starting position
  138. this._forceCssWrite(node, {
  139. 'transition': 'all 0s',
  140. 'transform': 'scale(1,1) translateX(' + -endVal + 'px) rotate(0)' + transform
  141. });
  142. return this._animation(node, {
  143. 'transition': 'transform ' + duration + 'ms',
  144. 'transform': transform
  145. });
  146. } else if (payload.animation === 'slideOutLeft') {
  147. /*
  148. * Use parentElement.offsetLeft here so that the animation works for objects in a group
  149. * because height could be a small value and will be applied relative to the group.
  150. * We use the parent's offset so that two objects sliding out, with one in a group
  151. * and the other not, slide at the same speed (because they travel the same distance).
  152. */
  153. endVal = left + width;
  154. if (node.parentElement && node.parentElement.offsetLeft) {
  155. endVal += node.parentElement.offsetLeft;
  156. }
  157. return this._animation(node, {
  158. 'transition': 'transform ' + duration + 'ms',
  159. 'transform': 'translateX(' + -endVal + 'px)' + transform
  160. }, function () {
  161. node.style.transition = 'all 0s';
  162. node.style.transform = 'scale(0,0) translate(0,0) rotate(0)' + transform;
  163. });
  164. } else if (payload.animation === 'slideInRight') {
  165. this._lockScrollBarsState(node);
  166. this._forceCssWrite(node, {
  167. 'transition': 'all 0s',
  168. 'transform': 'scale(1,1) translateX(' + docWidth + 'px)' + transform
  169. });
  170. // Make sure node is to scale, at the proper opacity level, and at its correct starting position
  171. return this._animation(node, {
  172. 'transition': 'transform ' + duration + 'ms',
  173. 'transform': transform
  174. }, function () {
  175. _this2._restoreScrollBarsState(node);
  176. });
  177. } else if (payload.animation === 'slideOutRight') {
  178. this._lockScrollBarsState(node);
  179. return this._animation(node, {
  180. 'transition': 'transform ' + duration + 'ms',
  181. 'transform': 'translateX(' + docWidth + 'px)' + transform
  182. }, function () {
  183. node.style.transition = 'all 0s';
  184. node.style.transform = 'scale(0,0) translate(0,0) rotate(0)' + transform;
  185. _this2._restoreScrollBarsState(node);
  186. });
  187. } else if (payload.animation === 'slideInTop') {
  188. endVal = top + height;
  189. if (node.parentElement && node.parentElement.offsetTop) {
  190. endVal += node.parentElement.offsetTop;
  191. }
  192. // Make sure node is to scale, at the proper opacity level, and at its correct starting position
  193. this._forceCssWrite(node, {
  194. 'transition': 'all 0s',
  195. 'transform': 'scale(1,1) translateY(' + -endVal + 'px)' + transform
  196. });
  197. return this._animation(node, {
  198. 'transition': 'transform ' + duration + 'ms',
  199. 'transform': transform
  200. });
  201. } else if (payload.animation === 'slideOutTop') {
  202. /*
  203. * Use parentElement.offsetTop here so that the animation works for objects in a group
  204. * because height could be a small value and will be applied relative to the group.
  205. * We use the parent's offset so that two objects sliding out, with one in a group
  206. * and the other not, slide at the same speed (because they travel the same distance).
  207. */
  208. endVal = top + height;
  209. if (node.parentElement && node.parentElement.offsetTop) {
  210. endVal += node.parentElement.offsetTop;
  211. }
  212. return this._animation(node, {
  213. 'transition': 'transform ' + duration + 'ms',
  214. 'transform': 'translateY(' + -endVal + 'px)' + transform
  215. }, function () {
  216. node.style.transition = 'all 0s';
  217. node.style.transform = 'scale(0,0) translate(0,0) rotate(0)' + transform;
  218. });
  219. } else if (payload.animation === 'slideInBottom') {
  220. this._lockScrollBarsState(node);
  221. // Make sure node is to scale, at the proper opacity level, and at its correct starting position
  222. this._forceCssWrite(node, {
  223. 'transition': 'all 0s',
  224. 'transform': 'scale(1,1) translateY(' + docHeight + 'px)' + transform
  225. });
  226. return this._animation(node, {
  227. 'transition': 'transform ' + duration + 'ms',
  228. 'transform': transform
  229. }, function () {
  230. _this2._restoreScrollBarsState(node);
  231. });
  232. } else if (payload.animation === 'slideOutBottom') {
  233. this._lockScrollBarsState(node);
  234. return this._animation(node, {
  235. 'transition': 'transform ' + duration + 'ms',
  236. 'transform': 'translateY(' + docHeight + 'px)' + transform
  237. }, function () {
  238. node.style.transition = 'all 0s';
  239. node.style.transform = 'scale(0,0) translate(0,0) rotate(0)' + transform;
  240. _this2._restoreScrollBarsState(node);
  241. });
  242. } else if (payload.animation === 'show') {
  243. this._forceCssWrite(node, {
  244. 'opacity': '0',
  245. 'transition': 'all 0s'
  246. });
  247. return this._animation(node, {
  248. 'transition': 'opacity ' + duration + 'ms',
  249. 'transform': transform,
  250. 'opacity': opacity
  251. });
  252. } else if (payload.animation === 'hide') {
  253. return this._animation(node, {
  254. 'transition': 'opacity ' + duration + 'ms',
  255. 'opacity': '0'
  256. }, function () {
  257. node.style.transition = 'all 0s';
  258. node.style.transform = 'scale(0,0) translate(0,0) rotate(0)' + transform;
  259. node.style.opacity = opacity;
  260. });
  261. } else if (payload.animation === 'highlight') {
  262. return this._highlightWidget(payload);
  263. } else if (payload.animation === 'clearHighlight') {
  264. return this._clearHighlightWidget(payload);
  265. }
  266. return Promise.resolve();
  267. };
  268. AnimationDirector.prototype._reveal = function _reveal(widgetId) {
  269. var _this3 = this;
  270. this._finishInProgressWidgetAnimation(widgetId);
  271. var widget = this.widgetHelper.getWidget(widgetId);
  272. return Promise.resolve(widget && widget.getVisApi && widget.getVisApi().ownerWidget.reveal ? widget.getVisApi().ownerWidget.reveal() : null).then(function (info) {
  273. if (info && info.renderControlApi) {
  274. _this3._inProgressWidgetsAnimation[widgetId] = info.renderControlApi;
  275. }
  276. });
  277. };
  278. AnimationDirector.prototype.pauseWidgetsAnimation = function pauseWidgetsAnimation() {
  279. var _this4 = this;
  280. Object.keys(this._inProgressWidgetsAnimation).map(function (key) {
  281. return _this4._inProgressWidgetsAnimation[key];
  282. }).forEach(function (api) {
  283. api.pause && api.pause();
  284. });
  285. };
  286. AnimationDirector.prototype.resumeWidgetsAnimation = function resumeWidgetsAnimation() {
  287. var _this5 = this;
  288. Object.keys(this._inProgressWidgetsAnimation).map(function (key) {
  289. return _this5._inProgressWidgetsAnimation[key];
  290. }).forEach(function (api) {
  291. api.resume && api.resume();
  292. });
  293. };
  294. AnimationDirector.prototype.finishWidgetsAnimation = function finishWidgetsAnimation() {
  295. var apisMap = this._inProgressWidgetsAnimation;
  296. this._inProgressWidgetsAnimation = {};
  297. Object.keys(apisMap).map(function (key) {
  298. return apisMap[key];
  299. }).forEach(function (api) {
  300. api.complete && api.complete();
  301. });
  302. };
  303. AnimationDirector.prototype._finishInProgressWidgetAnimation = function _finishInProgressWidgetAnimation(widgetId) {
  304. var api = this._inProgressWidgetsAnimation[widgetId];
  305. delete this._inProgressWidgetsAnimation[widgetId];
  306. if (api) {
  307. api.complete && api.complete();
  308. }
  309. };
  310. /**
  311. * finishes any pending animation on a widget immediately
  312. * @param {object} payload
  313. * @param {string} payload.target id if target widget
  314. * {
  315. * target: {string} target widget id
  316. * }
  317. */
  318. AnimationDirector.prototype.finishInProgressAnimation = function finishInProgressAnimation(payload) {
  319. var node = this.widgetHelper.getContentNode(payload.target);
  320. if (!node) {
  321. return;
  322. }
  323. this._finishInProgressCssAnimation(node);
  324. this._finishInProgressWidgetAnimation(payload.target);
  325. };
  326. /* This method only exists as a performance optimization.
  327. *
  328. * In the case of an immediate animation we only want to show or hide the widget.
  329. * The multi step code in animate is overkill for that and overwhelms firefox in some cases.
  330. */
  331. AnimationDirector.prototype._immediateAnimate = function _immediateAnimate(node, transform, payload) {
  332. // use scale3d(0,0,0) to force a repaint in firefox [defect 184181]. It also accelerates css paint by using GPU.
  333. // Note: the matrix computed in scale(0,0) equals scale3d(0,0,1) but is not equal to scale3d(0,0,0). We are now setting the scale z to 0 for a repaint.
  334. //
  335. // multiple browsers now have this repaint problem (IE, chrome and Firefox I'm looking at you)
  336. // We do the double set to force a repaint.
  337. // In theory this should be GPU accelerated and not called as often as before because of optimization in TimeQueue.
  338. // I.e the total number of _immediateAnimate calls should be less in total on a seek
  339. switch (payload.animation) {
  340. case 'show':
  341. case 'slideInLeft':
  342. case 'slideInRight':
  343. case 'slideInTop':
  344. case 'slideInBottom':
  345. case 'scaleIn':
  346. case 'shrinkIn':
  347. case 'pivotIn':
  348. node.style.transition = 'all 0s';
  349. node.style.transform = transform;
  350. break;
  351. case 'hide':
  352. case 'slideOutLeft':
  353. case 'slideOutRight':
  354. case 'slideOutTop':
  355. case 'slideOutBottom':
  356. case 'scaleOut':
  357. case 'expandOut':
  358. case 'pivotOut':
  359. this._forceCssWrite(node, {
  360. 'transition': 'all 0s',
  361. 'transform': 'scale(0) translate(0,0) rotate(0)' + transform
  362. });
  363. if (!BrowserUtils.isSafari()) {
  364. this._forceCssWrite(node, {
  365. 'transform': 'scale3d(0,0,0) translate(0,0) rotate(0)' + transform
  366. });
  367. }
  368. // From Defect 272532: Forcing IE to remove the inner visualizations that are not hidden when necessary
  369. if (BrowserUtils.isIE()) {
  370. var old_display = node.style.display;
  371. node.style.display = 'none';
  372. this._forceRepaint(node);
  373. node.style.display = old_display;
  374. }
  375. break;
  376. case 'highlight':
  377. this._highlightWidget(payload);
  378. break;
  379. case 'clearHighlight':
  380. this._clearHighlightWidget(payload);
  381. break;
  382. default:
  383. break;
  384. }
  385. };
  386. /**
  387. * Helping method to get this widget's layout information
  388. *
  389. * @param contentId - id of the content
  390. */
  391. AnimationDirector.prototype._getLayoutNodeTransform = function _getLayoutNodeTransform(contentId) {
  392. var content = this.widgetHelper.getContent(contentId);
  393. var transform = content && content.getPropertyValue('rotateAngle');
  394. if (!transform) {
  395. transform = '';
  396. }
  397. return transform;
  398. };
  399. /**
  400. * Private method to perform css animations on a provided DOM node
  401. *
  402. * @param node - DOM object
  403. * @param animationStyleProperties - object - The CSS properties that will be used for the animation
  404. * @param immediate - A boolean variable indicating if the animation should happen right away
  405. * @param callback - function - A callback function to execute after the transition time of the animation
  406. */
  407. AnimationDirector.prototype._animation = function _animation(node, animationStyleProperties, transitionEndCallback) {
  408. var _this6 = this;
  409. var numAnimatedProperties = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
  410. return new Promise(function (resolve) {
  411. var inProgressCssAnimation = _this6._inProgressCssAnimations[node.id];
  412. if (inProgressCssAnimation) {
  413. _this6._finishInProgressCssAnimation(node);
  414. }
  415. inProgressCssAnimation = _this6._inProgressCssAnimations[node.id] = {};
  416. node.classList.add('animating');
  417. var callback = function callback() {
  418. if (transitionEndCallback) {
  419. transitionEndCallback();
  420. }
  421. node.classList.remove('animating');
  422. resolve();
  423. };
  424. _this6._forceCssWrite(node, animationStyleProperties);
  425. inProgressCssAnimation.css = Object.assign({}, animationStyleProperties, { transition: 'none' });
  426. inProgressCssAnimation.onTransitionEnd = _this6._onTransitionEnd.bind(_this6, node);
  427. inProgressCssAnimation.onTransitionEndCallback = callback;
  428. inProgressCssAnimation.numAnimatedProperties = numAnimatedProperties;
  429. inProgressCssAnimation.transitionEndCount = 0;
  430. node.addEventListener('transitionend', inProgressCssAnimation.onTransitionEnd);
  431. });
  432. };
  433. AnimationDirector.prototype._finishInProgressCssAnimation = function _finishInProgressCssAnimation(node) {
  434. var inProgressCssAnimation = this._inProgressCssAnimations[node.id];
  435. if (inProgressCssAnimation) {
  436. this._forceCssWrite(node, inProgressCssAnimation.css);
  437. node.removeEventListener('transitionend', inProgressCssAnimation.onTransitionEnd);
  438. inProgressCssAnimation.onTransitionEndCallback();
  439. delete this._inProgressCssAnimations[node.id];
  440. }
  441. };
  442. /**
  443. * Private method used in conjunction with performing CSS animations.
  444. * This gets called when the 'transitionend' event for a DOM node is fired.
  445. *
  446. * @param callback - function - A callback function to execute when this method is fired
  447. * @param event - el - The DOM element from the 'transitionend' event being fired
  448. */
  449. AnimationDirector.prototype._onTransitionEnd = function _onTransitionEnd(node) {
  450. var inProgressCssAnimation = this._inProgressCssAnimations[node.id];
  451. if (inProgressCssAnimation && ++inProgressCssAnimation.transitionEndCount === inProgressCssAnimation.numAnimatedProperties) {
  452. node.removeEventListener('transitionend', inProgressCssAnimation.onTransitionEnd);
  453. inProgressCssAnimation.onTransitionEndCallback();
  454. delete this._inProgressCssAnimations[node.id];
  455. }
  456. };
  457. /**
  458. * Private method used to force a write of the CSS
  459. * This method allows multiple writes to actually be applied. (see comment in method)
  460. *
  461. * @param node - the widget node
  462. * @param cssPayload - object - css data
  463. */
  464. AnimationDirector.prototype._forceCssWrite = function _forceCssWrite(node, cssPayload) {
  465. var _this7 = this;
  466. Object.keys(cssPayload).forEach(function (key) {
  467. _this7._applyPrefixStyling(node, key, cssPayload[key]);
  468. });
  469. // we are setting multiple conflicting css properties in a row and we want them to be all executed.
  470. // the browser does not always do this so we add the read to force a 'repaint'.
  471. this._forceRepaint(node);
  472. };
  473. AnimationDirector.prototype._applyPrefixStyling = function _applyPrefixStyling(node, property, value) {
  474. var prefixList = ['webkit', 'Webkit', 'moz', 'Moz', 'ms', 'o'];
  475. prefixList.forEach(function (prefix) {
  476. var propertyPrefix = prefix + property.charAt(0).toUpperCase() + property.slice(1);
  477. node.style[propertyPrefix] = value;
  478. });
  479. node.style[property] = value;
  480. };
  481. AnimationDirector.prototype._forceRepaint = function _forceRepaint(node) {
  482. void node.offsetHeight;
  483. };
  484. AnimationDirector.prototype._getDocumentWidth = function _getDocumentWidth() {
  485. return Math.max(document.body.scrollWidth, document.body.offsetWidth, document.documentElement.clientWidth, document.documentElement.scrollWidth, document.documentElement.offsetWidth);
  486. };
  487. AnimationDirector.prototype._getDocumentHeight = function _getDocumentHeight() {
  488. return Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
  489. };
  490. AnimationDirector.prototype._getNodeWidth = function _getNodeWidth(node) {
  491. return Math.max(node.clientWidth, node.offsetWidth, node.scrollWidth);
  492. };
  493. AnimationDirector.prototype._getNodeHeight = function _getNodeHeight(node) {
  494. return Math.max(node.clientHeight, node.offsetHeight, node.scrollHeight);
  495. };
  496. AnimationDirector.prototype._lockScrollBarsState = function _lockScrollBarsState(element) {
  497. var pageContainer = element.closest('.pagecontainer');
  498. if (!pageContainer) {
  499. return;
  500. }
  501. // overflow is set to 'visible' in pan and zoom (see panAndZoom.scss)
  502. var computedStyles = window.getComputedStyle(pageContainer);
  503. if (computedStyles.overflow === 'visible') {
  504. return;
  505. }
  506. // if the scrollbars are already locked, we leave them alone
  507. if (this._scrollBarsStateLockCount++ > 0) {
  508. return;
  509. }
  510. var vscroll = pageContainer.scrollHeight > pageContainer.clientHeight;
  511. var hscroll = pageContainer.scrollWidth > pageContainer.clientWidth;
  512. pageContainer.style.overflowX = hscroll ? 'scroll' : 'hidden';
  513. pageContainer.style.overflowY = vscroll ? 'scroll' : 'hidden';
  514. };
  515. AnimationDirector.prototype._restoreScrollBarsState = function _restoreScrollBarsState(element) {
  516. var pageContainer = element.closest('.pagecontainer');
  517. if (!pageContainer) {
  518. return;
  519. }
  520. // overflow is set to 'visible' in pan and zoom (see panAndZoom.scss)
  521. var computedStyles = window.getComputedStyle(pageContainer);
  522. if (computedStyles.overflow === 'visible') {
  523. return;
  524. }
  525. // if someone else locked the scrollbars we leave them alone
  526. if (--this._scrollBarsStateLockCount > 0) {
  527. return;
  528. }
  529. // in the _lockScrollBarsState we set these values on the element itself to scroll/hidden
  530. // We need to remove them complete to allow for css to take back control
  531. pageContainer.style.overflowX = '';
  532. pageContainer.style.overflowY = '';
  533. };
  534. AnimationDirector.prototype._clearHighlightWidget = function _clearHighlightWidget(event) {
  535. var content = this.widgetHelper.getContent(event.target);
  536. var visualization = content && content.getFeature('Visualization');
  537. if (!visualization) {
  538. return;
  539. }
  540. var options = {
  541. payloadData: {
  542. runtimeOnly: true
  543. }
  544. };
  545. var dataSource = visualization.getDataSource();
  546. // only clear highlight when there is a data source associated with one widget
  547. if (dataSource) {
  548. this.pageContextAPI.resetToPersistedValues({
  549. origin: 'visualization',
  550. scope: this.widgetHelper.getPageContent(content).getId(),
  551. eventSourceId: event.target,
  552. sourceId: dataSource.getId(),
  553. eventGroupId: this.widgetHelper.getEventGroupId(content.getId())
  554. }, options);
  555. }
  556. return Promise.resolve();
  557. };
  558. AnimationDirector.prototype._highlightWidget = function _highlightWidget(event) {
  559. var _this8 = this;
  560. var content = this.widgetHelper.getContent(event.target);
  561. var visualization = content && content.getFeature('Visualization');
  562. if (!visualization) {
  563. return Promise.resolve();
  564. }
  565. var highlights = event.payload || [];
  566. var dataSource = visualization.getDataSource();
  567. highlights.forEach(function (highlight) {
  568. var pageContent = _this8.widgetHelper.getPageContent(content);
  569. var selector = {
  570. origin: 'visualization',
  571. scope: pageContent && pageContent.getId(),
  572. eventSourceId: event.target,
  573. sourceId: dataSource.getId(),
  574. itemId: highlight.columnId,
  575. eventGroupId: _this8.widgetHelper.getEventGroupId(content.getId()),
  576. hierarchies: [{
  577. 'hierarchyUniqueName': highlight.columnId
  578. }]
  579. };
  580. var options = {
  581. payloadData: {
  582. runtimeOnly: true
  583. }
  584. };
  585. var command = {
  586. command: 'replace',
  587. values: highlight.values
  588. };
  589. _this8.pageContextAPI.updateFilterContext(selector, command, options);
  590. });
  591. return Promise.resolve();
  592. };
  593. return AnimationDirector;
  594. }();
  595. return AnimationDirector;
  596. });
  597. //# sourceMappingURL=AnimationDirector.js.map