You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1314 lines
58 KiB

3 years ago
  1. $axure.internal(function($ax) {
  2. var document = window.document;
  3. var _visibility = {};
  4. $ax.visibility = _visibility;
  5. var _defaultHidden = {};
  6. var _defaultLimbo = {};
  7. // ****************** Visibility and State Functions ****************** //
  8. var _isIdVisible = $ax.visibility.IsIdVisible = function(id) {
  9. return $ax.visibility.IsVisible(window.document.getElementById(id));
  10. };
  11. $ax.visibility.IsVisible = function(element) {
  12. //cannot use css('visibility') because that gets the effective visiblity
  13. //e.g. won't be able to set visibility on panels inside hidden panels
  14. return element.style.visibility != 'hidden';
  15. };
  16. $ax.visibility.SetIdVisible = function(id, visible) {
  17. $ax.visibility.SetVisible(window.document.getElementById(id), visible);
  18. // Hide lightbox if necessary
  19. if(!visible) {
  20. $jobj($ax.repeater.applySuffixToElementId(id, '_lightbox')).remove();
  21. $ax.flyoutManager.unregisterPanel(id, true);
  22. }
  23. };
  24. var _setAllVisible = function(query, visible) {
  25. for(var i = 0; i < query.length; i++) {
  26. _visibility.SetVisible(query[i], visible);
  27. }
  28. }
  29. $ax.visibility.SetVisible = function (element, visible) {
  30. //not setting display to none to optimize measuring
  31. if(visible) {
  32. if($(element).hasClass(HIDDEN_CLASS)) $(element).removeClass(HIDDEN_CLASS);
  33. if($(element).hasClass(UNPLACED_CLASS)) $(element).removeClass(UNPLACED_CLASS);
  34. element.style.display = '';
  35. element.style.visibility = 'inherit';
  36. } else {
  37. element.style.display = 'none';
  38. element.style.visibility = 'hidden';
  39. }
  40. };
  41. var _setWidgetVisibility = $ax.visibility.SetWidgetVisibility = function (elementId, options) {
  42. var visible = $ax.visibility.IsIdVisible(elementId);
  43. // If limboed, just fire the next action then leave.
  44. if(visible == options.value || _limboIds[elementId]) {
  45. if(!_limboIds[elementId]) options.onComplete && options.onComplete();
  46. $ax.action.fireAnimationFromQueue(elementId, $ax.action.queueTypes.fade);
  47. return;
  48. }
  49. options.containInner = true;
  50. var query = $jobj(elementId);
  51. var parentId = query.parent().attr('id');
  52. var axObj = $obj(elementId);
  53. var preserveScroll = false;
  54. var isPanel = $ax.public.fn.IsDynamicPanel(axObj.type);
  55. var isLayer = $ax.public.fn.IsLayer(axObj.type);
  56. if(!options.noContainer && (isPanel || isLayer)) {
  57. //if dp has scrollbar, save its scroll position
  58. if(isPanel && axObj.scrollbars != 'none') {
  59. var shownState = $ax.dynamicPanelManager.getShownState(elementId);
  60. preserveScroll = true;
  61. //before hiding, try to save scroll location
  62. if(!options.value && shownState) {
  63. DPStateAndScroll[elementId] = {
  64. shownId: shownState.attr('id'),
  65. left: shownState.scrollLeft(),
  66. top: shownState.scrollTop()
  67. }
  68. }
  69. }
  70. _pushContainer(elementId, isPanel);
  71. if(isPanel && !options.value) _tryResumeScrollForDP(elementId);
  72. var complete = options.onComplete;
  73. options.onComplete = function () {
  74. if(complete) complete();
  75. _popContainer(elementId, isPanel);
  76. //using containers stops mouseleave from firing on IE/Edge and FireFox
  77. if(!options.value && $ax.event.mouseOverObjectId && (FIREFOX || $axure.browser.isEdge || IE)) {
  78. var mouseOveredElement = $('#' + $ax.event.mouseOverObjectId);
  79. if(mouseOveredElement && !mouseOveredElement.is(":visible")) {
  80. var axObj = $obj($ax.event.mouseOverObjectId);
  81. if(($ax.public.fn.IsDynamicPanel(axObj.type) || $ax.public.fn.IsLayer(axObj.type)) && axObj.propagate) {
  82. mouseOveredElement.trigger('mouseleave');
  83. } else mouseOveredElement.trigger('mouseleave.ixStyle');
  84. }
  85. }
  86. //after showing dp, restore the scoll position
  87. if(isPanel && options.value) _tryResumeScrollForDP(elementId, true);
  88. }
  89. options.containerExists = true;
  90. }
  91. _setVisibility(parentId, elementId, options, preserveScroll);
  92. //set the visibility of the annotation box as well if it exists
  93. var ann = document.getElementById(elementId + "_ann");
  94. if(ann) _visibility.SetVisible(ann, options.value);
  95. //set ref visibility for ref of flow shape, if that exists
  96. var ref = document.getElementById(elementId + '_ref');
  97. if(ref) _visibility.SetVisible(ref, options.value);
  98. if(options.value && !MOBILE_DEVICE && $ax.adaptive.isDeviceMode()) _updateMobileScrollForWidgetShown(axObj);
  99. };
  100. var _updateMobileScrollForWidgetShown = function(widget) {
  101. var isPanel = $ax.public.fn.IsDynamicPanel(widget.type);
  102. var isLayer = $ax.public.fn.IsLayer(widget.type);
  103. if (isPanel) {
  104. var elementId = $id(widget);
  105. var stateId = $ax.repeater.applySuffixToElementId(elementId, '_state0');
  106. $ax.dynamicPanelManager.updateMobileScroll(elementId, stateId, true);
  107. if (!widget.diagrams) return;
  108. for (var i = 0; i < widget.diagrams.length; ++i) {
  109. var diagram = widget.diagrams[i];
  110. if (!diagram.objects) continue;
  111. for (var j = 0; j < diagram.objects.length; ++j) {
  112. _updateMobileScrollForWidgetShown(diagram.objects[j]);
  113. }
  114. }
  115. } else if (isLayer) {
  116. for (var i = 0; i < widget.objs.length; ++i) {
  117. _updateMobileScrollForWidgetShown(widget.objs[i]);
  118. }
  119. }
  120. }
  121. var _setVisibility = function(parentId, childId, options, preserveScroll) {
  122. var wrapped = $jobj(childId);
  123. var completeTotal = 1;
  124. var visible = $ax.visibility.IsIdVisible(childId);
  125. if(visible == options.value) {
  126. options.onComplete && options.onComplete();
  127. $ax.action.fireAnimationFromQueue(childId, $ax.action.queueTypes.fade);
  128. return;
  129. }
  130. var child = $jobj(childId);
  131. var size = options.size || (options.containerExists ? $(child.children()[0]) : child);
  132. var isIdFitToContent = $ax.dynamicPanelManager.isIdFitToContent(parentId);
  133. //fade and resize won't work together when there is a container... but we still needs the container for fit to content DPs
  134. var needContainer = options.easing && options.easing != 'none' && (options.easing != 'fade' || isIdFitToContent);
  135. var cullPosition = options.cull ? options.cull.css('position') : '';
  136. var containerExists = options.containerExists;
  137. var isFullWidth = $ax.dynamicPanelManager.isPercentWidthPanel($obj(childId));
  138. // If fixed fit to content panel, then we must set size on it. It will be size of 0 otherwise, because container in it is absolute position.
  139. var needSetSize = false;
  140. var sizeObj = {};
  141. if(needContainer) {
  142. var sizeId = '';
  143. if($ax.dynamicPanelManager.isIdFitToContent(childId)) sizeId = childId;
  144. else {
  145. var panelId = $ax.repeater.removeSuffixFromElementId(childId);
  146. if($ax.dynamicPanelManager.isIdFitToContent(panelId)) sizeId = panelId;
  147. }
  148. if(sizeId) {
  149. needSetSize = true;
  150. sizeObj = $jobj(sizeId);
  151. var newSize = options.cull || sizeObj;
  152. var newAxSize = $ax('#' + newSize.attr('id'));
  153. sizeObj.width(newAxSize.width());
  154. sizeObj.height(newAxSize.height());
  155. }
  156. }
  157. var wrappedOffset = { left: 0, top: 0 };
  158. var visibleWrapped = wrapped;
  159. if(needContainer) {
  160. var childObj = $obj(childId);
  161. if (options.cull) {
  162. var axCull = $ax('#' + options.cull.attr('id'));
  163. var containerWidth = axCull.width();
  164. var containerHeight = axCull.height();
  165. } else {
  166. if (childObj && ($ax.public.fn.IsLayer(childObj.type))) {// || childObj.generateCompound)) {
  167. var boundingRectangle = $ax('#' + childId).offsetBoundingRect();
  168. //var boundingRectangle = $ax.public.fn.getWidgetBoundingRect(childId);
  169. wrappedOffset.left = boundingRectangle.left;
  170. wrappedOffset.top = boundingRectangle.top;
  171. containerWidth = boundingRectangle.width;
  172. containerHeight = boundingRectangle.height;
  173. } else if (childObj && childObj.generateCompound) {
  174. var image = $jobj(childId + '_img');
  175. containerWidth = $ax.getNumFromPx(image.css('width'));
  176. containerHeight = $ax.getNumFromPx(image.css('height'));
  177. wrappedOffset.left = $ax.getNumFromPx(image.css('left'));
  178. wrappedOffset.top = $ax.getNumFromPx(image.css('top'));
  179. } else {
  180. containerWidth = $ax('#' + childId).width();
  181. containerHeight = $ax('#' + childId).height();
  182. }
  183. }
  184. var containerId = $ax.visibility.applyWidgetContainer(childId);
  185. // var container = _makeContainer(containerId, options.cull || boundingRectangle, isFullWidth, options.easing == 'flip', wrappedOffset, options.containerExists);
  186. var container = _makeContainer(containerId, containerWidth, containerHeight, isFullWidth, options.easing == 'flip', wrappedOffset, options.containerExists);
  187. if(options.containInner) {
  188. wrapped = _wrappedChildren(containerExists ? $(child.children()[0]) : child);
  189. // Filter for visibile wrapped children
  190. visibleWrapped = [];
  191. for (var i = 0; i < wrapped.length; i++) if($ax.visibility.IsVisible(wrapped[i])) visibleWrapped.push(wrapped[i]);
  192. visibleWrapped = $(visibleWrapped);
  193. completeTotal = visibleWrapped.length;
  194. if(!containerExists) container.prependTo(child);
  195. // Offset items if necessary
  196. if(!containerExists && (wrappedOffset.left != 0 || wrappedOffset.top != 0)) {
  197. for(var i = 0; i < wrapped.length; i++) {
  198. var inner = $(wrapped[i]);
  199. inner.css('left', $ax.getNumFromPx(inner.css('left')) - wrappedOffset.left);
  200. inner.css('top', $ax.getNumFromPx(inner.css('top')) - wrappedOffset.top);
  201. // Parent layer is now size 0, so have to have to use conatiner since it's the real size.
  202. // Should we use container all the time? This may make things easier for fit panels too.
  203. size = container;
  204. }
  205. }
  206. } else if(!containerExists) container.insertBefore(child);
  207. if(!containerExists) wrapped.appendTo(container);
  208. if (options.value && options.containInner) {
  209. //has to set children first because flip to show needs children invisible
  210. _setAllVisible(visibleWrapped, false);
  211. //_updateChildAlignment(childId);
  212. _setAllVisible(child, true);
  213. }
  214. }
  215. var completeCount = 0;
  216. var onComplete = function () {
  217. completeCount++;
  218. if (needContainer && completeCount == completeTotal) {
  219. if ($ax.public.fn.isCompoundVectorHtml(container.parent()[0])) {
  220. wrappedOffset.left = $ax.getNumFromPx(container.css('left'));
  221. wrappedOffset.top = $ax.getNumFromPx(container.css('top'));
  222. }
  223. if (options.containInner && !containerExists) {
  224. if (wrappedOffset.left != 0 || wrappedOffset.top != 0) {
  225. for (i = 0; i < wrapped.length; i++) {
  226. inner = $(wrapped[i]);
  227. if (!inner.hasClass('text')) {
  228. inner.css('left', $ax.getNumFromPx(inner.css('left')) + wrappedOffset.left);
  229. inner.css('top', $ax.getNumFromPx(inner.css('top')) + wrappedOffset.top);
  230. }
  231. }
  232. }
  233. wrapped.filter('.text').css({ 'left': '', 'top': '' });
  234. }
  235. if(options.containInner && !options.value) {
  236. _setAllVisible(child, false);
  237. _setAllVisible(visibleWrapped, true);
  238. }
  239. if(containerExists) {
  240. if(!options.settingChild) container.css('position', 'relative;');
  241. } else {
  242. wrapped.insertBefore(container);
  243. container.remove();
  244. }
  245. if(childObj && $ax.public.fn.IsDynamicPanel(childObj.type) && window.modifiedDynamicPanleParentOverflowProp) {
  246. child.css('overflow', 'hidden');
  247. window.modifiedDynamicPanleParentOverflowProp = false;
  248. }
  249. }
  250. //if(options.value) _updateChildAlignment(childId);
  251. if(!needContainer || completeTotal == completeCount) {
  252. if(options.cull) options.cull.css('position', cullPosition);
  253. if(needSetSize) {
  254. sizeObj.css('width', 'auto');
  255. sizeObj.css('height', 'auto');
  256. }
  257. options.onComplete && options.onComplete();
  258. if(options.fire) {
  259. $ax.event.raiseSyntheticEvent(childId, options.value ? 'onShow' : 'onHide');
  260. $ax.action.fireAnimationFromQueue(childId, $ax.action.queueTypes.fade);
  261. }
  262. }
  263. };
  264. // Nothing actually being animated, all wrapped elements invisible
  265. if(!visibleWrapped.length) {
  266. if(!options.easing || options.easing == 'none') {
  267. $ax.visibility.SetIdVisible(childId, options.value);
  268. completeTotal = 1;
  269. onComplete();
  270. } else {
  271. window.setTimeout(function() {
  272. completeCount = completeTotal - 1;
  273. onComplete();
  274. },options.duration);
  275. }
  276. return;
  277. }
  278. if(!options.easing || options.easing == 'none') {
  279. $ax.visibility.SetIdVisible(childId, options.value);
  280. completeTotal = 1;
  281. onComplete();
  282. } else if(options.easing == 'fade') {
  283. if(options.value) {
  284. if(preserveScroll) {
  285. visibleWrapped.css('opacity', 0);
  286. visibleWrapped.css('visibility', 'inherit');
  287. visibleWrapped.css('display', 'block');
  288. //was hoping we could just use fadein here, but need to set display before set scroll position
  289. _tryResumeScrollForDP(childId);
  290. visibleWrapped.animate({ opacity: 1 }, {
  291. duration: options.duration,
  292. easing: 'swing',
  293. queue: false,
  294. complete: function() {
  295. $ax.visibility.SetIdVisible(childId, true);
  296. visibleWrapped.css('opacity', '');
  297. onComplete();
  298. }
  299. });
  300. } else {
  301. // Can't use $ax.visibility.SetIdVisible, because we only want to set visible, we don't want to set display, fadeIn will handle that.
  302. visibleWrapped.css('visibility', 'inherit');
  303. visibleWrapped.fadeIn({
  304. queue: false,
  305. duration: options.duration,
  306. complete: onComplete
  307. });
  308. }
  309. } else {
  310. // Fading here is being strange...
  311. visibleWrapped.animate({ opacity: 0 }, { duration: options.duration, easing: 'swing', queue: false, complete: function() {
  312. $ax.visibility.SetIdVisible(childId, false);
  313. visibleWrapped.css('opacity', '');
  314. onComplete();
  315. }});
  316. }
  317. } else if (options.easing == 'flip') {
  318. //this container will hold
  319. var trapScroll = _trapScrollLoc(childId);
  320. var innerContainer = $('<div></div>');
  321. innerContainer.attr('id', containerId + "_inner");
  322. innerContainer.data('flip', options.direction == 'left' || options.direction == 'right' ? 'y' : 'x');
  323. innerContainer.css({
  324. position: 'relative',
  325. 'width': containerWidth,
  326. 'height': containerHeight,
  327. 'display': 'flex'
  328. });
  329. innerContainer.appendTo(container);
  330. wrapped.appendTo(innerContainer);
  331. if(childObj && $ax.public.fn.IsDynamicPanel(childObj.type)) var containerDiv = child;
  332. else containerDiv = parentId ? $jobj(parentId) : child.parent();
  333. completeTotal = 1;
  334. var flipdegree;
  335. var originForFlip = containerWidth / 2 + 'px ' + containerHeight / 2 + 'px';
  336. if (options.value) {
  337. innerContainer.css({
  338. '-webkit-transform-origin': originForFlip,
  339. '-ms-transform-origin': originForFlip,
  340. 'transform-origin': originForFlip,
  341. });
  342. //options.value == true means in or show, note to get here, the element must be currently hidden to show,
  343. // we need to first flip it +/- 90deg without animation (180 if we want to show the back of the flip)
  344. switch(options.direction) {
  345. case 'right':
  346. case 'left':
  347. _setRotateTransformation(innerContainer, _getRotateString(true, options.direction === 'right', options.showFlipBack));
  348. flipdegree = 'rotateY(0deg)';
  349. break;
  350. case 'up':
  351. case 'down':
  352. _setRotateTransformation(innerContainer, _getRotateString(false, options.direction === 'up', options.showFlipBack));
  353. flipdegree = 'rotateX(0deg)';
  354. break;
  355. }
  356. var onFlipShowComplete = function() {
  357. var trapScroll = _trapScrollLoc(childId);
  358. $ax.visibility.SetIdVisible(childId, true);
  359. wrapped.insertBefore(innerContainer);
  360. innerContainer.remove();
  361. trapScroll();
  362. onComplete();
  363. };
  364. innerContainer.css({
  365. '-webkit-backface-visibility': 'hidden',
  366. 'backface-visibility': 'hidden'
  367. });
  368. child.css({
  369. 'display': '',
  370. 'visibility': 'inherit'
  371. });
  372. visibleWrapped.css({
  373. 'display': '',
  374. 'visibility': 'inherit'
  375. });
  376. innerContainer.css({
  377. '-webkit-transition-duration': options.duration + 'ms',
  378. 'transition-duration': options.duration + 'ms'
  379. });
  380. if(preserveScroll) _tryResumeScrollForDP(childId);
  381. _setRotateTransformation(innerContainer, flipdegree, containerDiv, onFlipShowComplete, options.duration, true);
  382. } else { //hide or out
  383. innerContainer.css({
  384. '-webkit-transform-origin': originForFlip,
  385. '-ms-transform-origin': originForFlip,
  386. 'transform-origin': originForFlip,
  387. });
  388. switch(options.direction) {
  389. case 'right':
  390. case 'left':
  391. flipdegree = _getRotateString(true, options.direction !== 'right', options.showFlipBack);
  392. break;
  393. case 'up':
  394. case 'down':
  395. flipdegree = _getRotateString(false, options.direction !== 'up', options.showFlipBack);
  396. break;
  397. }
  398. var onFlipHideComplete = function() {
  399. var trapScroll = _trapScrollLoc(childId);
  400. wrapped.insertBefore(innerContainer);
  401. $ax.visibility.SetIdVisible(childId, false);
  402. innerContainer.remove();
  403. trapScroll();
  404. onComplete();
  405. };
  406. innerContainer.css({
  407. '-webkit-backface-visibility': 'hidden',
  408. 'backface-visibility': 'hidden',
  409. '-webkit-transition-duration': options.duration + 'ms',
  410. 'transition-duration': options.duration + 'ms'
  411. });
  412. if(preserveScroll) _tryResumeScrollForDP(childId);
  413. _setRotateTransformation(innerContainer, flipdegree, containerDiv, onFlipHideComplete, options.duration, true);
  414. }
  415. trapScroll();
  416. } else {
  417. // Because the move is gonna fire on annotation and ref too, need to update complete total
  418. completeTotal = $addAll(visibleWrapped, childId).length;
  419. if(options.value) {
  420. _slideStateIn(childId, childId, options, size, false, onComplete, visibleWrapped, preserveScroll);
  421. } else {
  422. var tops = [];
  423. var lefts = [];
  424. for(var i = 0; i < visibleWrapped.length; i++) {
  425. var currWrapped = $(visibleWrapped[i]);
  426. tops.push(fixAuto(currWrapped, 'top'));
  427. lefts.push(fixAuto(currWrapped, 'left'));
  428. }
  429. var onOutComplete = function () {
  430. //bring back SetIdVisible on childId for hiding lightbox
  431. $ax.visibility.SetIdVisible(childId, false);
  432. for(i = 0; i < visibleWrapped.length; i++) {
  433. currWrapped = $(visibleWrapped[i]);
  434. $ax.visibility.SetVisible(currWrapped[0], false);
  435. currWrapped.css('top', tops[i]);
  436. currWrapped.css('left', lefts[i]);
  437. }
  438. onComplete();
  439. };
  440. _slideStateOut(size, childId, options, onOutComplete, visibleWrapped);
  441. }
  442. }
  443. // If showing, go through all rich text objects inside you, and try to redo alignment of them
  444. //if(options.value && !options.containInner) {
  445. // _updateChildAlignment(childId);
  446. //}
  447. };
  448. // IE/Safari are giving auto here instead of calculating to for us. May need to calculate this eventually, but for now we can assume auto === 0px for the edge case found
  449. var fixAuto = function (jobj, prop) {
  450. var val = jobj.css(prop);
  451. return val == 'auto' ? '0px' : val;
  452. };
  453. var _getRotateString = function (y, neg, showFlipBack) {
  454. // y means flip on y axis, or left/right, neg means flipping it left/down, and show back is for set panel state
  455. // and will show the back of the widget (transparent) for the first half of a show, or second half of a hide.
  456. return 'rotate' + (y ? 'Y' : 'X') + '(' + (neg ? '-' : '') + (showFlipBack ? 180 : IE ? 91 : 90) + 'deg)';
  457. }
  458. //var _updateChildAlignment = function(childId) {
  459. // var descendants = $jobj(childId).find('.text');
  460. // for(var i = 0; i < descendants.length; i++) $ax.style.updateTextAlignmentForVisibility(descendants[i].id);
  461. //};
  462. var _wrappedChildren = function (child) {
  463. return child.children();
  464. //var children = child.children();
  465. //var valid = [];
  466. //for(var i = 0; i < children.length; i++) if($ax.visibility.IsVisible(children[i])) valid.push(children[i]);
  467. //return $(valid);
  468. };
  469. var requestAnimationFrame = window.requestAnimationFrame ||
  470. window.webkitRequestAnimationFrame ||
  471. window.mozRequestAnimationFrame || window.msRequestAnimationFrame ||
  472. function (callback) {
  473. window.setTimeout(callback, 1000 / 60);
  474. };
  475. var _setRotateTransformation = function(elementsToSet, transformValue, elementParent, flipCompleteCallback, flipDurationMs, useAnimationFrame) {
  476. if(flipCompleteCallback) {
  477. //here we didn't use 'transitionend' event to fire callback
  478. //when show/hide on one element, changing transition property will stop the event from firing
  479. window.setTimeout(flipCompleteCallback, flipDurationMs);
  480. }
  481. var trasformCss = {
  482. '-webkit-transform': transformValue,
  483. '-moz-transform': transformValue,
  484. '-ms-transform': transformValue,
  485. '-o-transform': transformValue,
  486. 'transform': transformValue
  487. };
  488. if(useAnimationFrame) {
  489. if(FIREFOX || CHROME) $('body').hide().show(0); //forces FF to render the animation
  490. requestAnimationFrame(function() {
  491. elementsToSet.css(trasformCss);
  492. });
  493. } else elementsToSet.css(trasformCss);
  494. //when deal with dynamic panel, we need to set it's parent's overflow to visible to have the 3d effect
  495. //NOTE: we need to set this back when both flips finishes in DP, to prevents one animation finished first and set this back
  496. if(elementParent && elementParent.css('overflow') === 'hidden') {
  497. elementParent.css('overflow', 'visible');
  498. window.modifiedDynamicPanleParentOverflowProp = true;
  499. }
  500. };
  501. $ax.visibility.GetPanelState = function(id) {
  502. var children = $ax.visibility.getRealChildren($jobj(id).children());
  503. for(var i = 0; i < children.length; i++) {
  504. if(children[i].style && $ax.visibility.IsVisible(children[i])) return children[i].id;
  505. }
  506. return '';
  507. };
  508. var containerCount = {};
  509. $ax.visibility.SetPanelState = function(id, stateId, easingOut, directionOut, durationOut, easingIn, directionIn, durationIn, showWhenSet) {
  510. var show = !$ax.visibility.IsIdVisible(id) && showWhenSet;
  511. if(show) $ax.visibility.SetIdVisible(id, true);
  512. // Exit here if already at desired state.
  513. if($ax.visibility.IsIdVisible(stateId)) {
  514. if(show) {
  515. $ax.event.raiseSyntheticEvent(id, 'onShow');
  516. // If showing size changes and need to update parent panels
  517. $ax.dynamicPanelManager.fitParentPanel(id);
  518. }
  519. $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.setState);
  520. return;
  521. }
  522. var hasEasing = easingIn != 'none' || easingOut != 'none';
  523. if(hasEasing) _pushContainer(id, true);
  524. var state = $jobj(stateId);
  525. var oldStateId = $ax.visibility.GetPanelState(id);
  526. var oldState = $jobj(oldStateId);
  527. var isFixed = $jobj(id).css('position') == 'fixed';
  528. //pin to browser
  529. if(isFixed) $ax.dynamicPanelManager.adjustFixed(id, oldState.width(), oldState.height(), state.width(), state.height());
  530. _bringPanelStateToFront(id, stateId, oldStateId, easingIn == 'none' || durationIn == '0');
  531. var fitToContent = $ax.dynamicPanelManager.isIdFitToContent(id);
  532. var resized = false;
  533. if(fitToContent) {
  534. // Set resized
  535. //var width = state.width();
  536. //var height = state.height();
  537. var newBoundingRect = $ax('#' + stateId).childrenBoundingRect();
  538. var width = newBoundingRect.right;
  539. var height = newBoundingRect.bottom;
  540. var oldBoundingRect = $ax('#' + id).size();
  541. var oldWidth = oldBoundingRect.right;
  542. var oldHeight = oldBoundingRect.bottom;
  543. resized = width != oldWidth || height != oldHeight;
  544. //resized = width != oldState.width() || height != oldState.height();
  545. $ax.visibility.setResizedSize(id, $obj(id).percentWidth ? oldWidth : width, height);
  546. }
  547. //edge case for sliding
  548. var movement = (directionOut == 'left' || directionOut == 'up' || state.children().length == 0) && oldState.children().length != 0 ? oldState : state;
  549. var onCompleteCount = 0;
  550. var onComplete = function () {
  551. //move this call from _setVisibility() for animate out.
  552. //Because this will make the order of dp divs consistence: the showing panel is always in front after both animation finished
  553. //tested in the cases where one panel is out/show slower/faster/same time/instantly.
  554. _bringPanelStateToFront(id, stateId, oldStateId, false);
  555. if (window.modifiedDynamicPanleParentOverflowProp) {
  556. var parent = id ? $jobj(id) : child.parent();
  557. parent.css('overflow', 'hidden');
  558. window.modifiedDynamicPanleParentOverflowProp = false;
  559. }
  560. $ax.dynamicPanelManager.fitParentPanel(id);
  561. $ax.dynamicPanelManager.updatePanelPercentWidth(id);
  562. $ax.dynamicPanelManager.updatePanelContentPercentWidth(id);
  563. $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.setState);
  564. $ax.event.raiseSyntheticEvent(id, "onPanelStateChange");
  565. $ax.event.leavingState(oldStateId);
  566. if (hasEasing) _popContainer(id, true);
  567. $ax.dynamicPanelManager.updateMobileScroll(id, stateId);
  568. };
  569. // Must do state out first, so if we cull by new state, location is correct
  570. _setVisibility(id, oldStateId, {
  571. value: false,
  572. easing: easingOut,
  573. direction: directionOut,
  574. duration: durationOut,
  575. containerExists: true,
  576. onComplete: function() {
  577. // if(easingIn !== 'flip') _bringPanelStateToFront(id, stateId);
  578. if (++onCompleteCount == 2) onComplete();
  579. },
  580. settingChild: true,
  581. size: movement,
  582. //cull for
  583. cull: easingOut == 'none' || state.children().length == 0 ? oldState : state,
  584. showFlipBack: true
  585. });
  586. _setVisibility(id, stateId, {
  587. value: true,
  588. easing: easingIn,
  589. direction: directionIn,
  590. duration: durationIn,
  591. containerExists: true,
  592. onComplete: function () {
  593. // if (easingIn === 'flip') _bringPanelStateToFront(id, stateId);
  594. if (++onCompleteCount == 2) onComplete();
  595. },
  596. settingChild: true,
  597. //size for offset
  598. size: movement,
  599. showFlipBack: true
  600. });
  601. if(show) $ax.event.raiseSyntheticEvent(id, 'onShow');
  602. if(resized) $ax.event.raiseSyntheticEvent(id, 'onResize');
  603. };
  604. var containedFixed = {};
  605. var _pushContainer = _visibility.pushContainer = function(id, panel) {
  606. var count = containerCount[id];
  607. if(count) containerCount[id] = count + 1;
  608. else {
  609. var trapScroll = _trapScrollLoc(id);
  610. var jobj = $jobj(id);
  611. var children = jobj.children();
  612. var css = {
  613. position: 'relative',
  614. top: 0,
  615. left: 0
  616. };
  617. if(!panel) {
  618. var boundingRect = $ax('#' + id).offsetBoundingRect();
  619. //var boundingRect = $axure.fn.getWidgetBoundingRect(id);
  620. css.top = boundingRect.top;
  621. css.left = boundingRect.left;
  622. }
  623. var container = $('<div></div>');
  624. container.attr('id', ''); // Placeholder id, so we won't try to recurse the container until it is ready
  625. container.css(css);
  626. //container.append(jobj.children());
  627. jobj.append(container);
  628. containerCount[id] = 1;
  629. // Panel needs to wrap children
  630. if(panel) {
  631. for(var i = 0; i < children.length; i++) {
  632. var child = $(children[i]);
  633. var childContainer = $('<div></div>');
  634. childContainer.attr('id', $ax.visibility.applyWidgetContainer(child.attr('id')));
  635. childContainer.css(css);
  636. child.after(childContainer);
  637. childContainer.append(child);
  638. container.append(childContainer);
  639. }
  640. } else {
  641. var focus = _getCurrFocus();
  642. if(focus) $ax.event.addSuppressedEvent($ax.repeater.removeSuffixFromElementId(focus), 'OnLostFocus');
  643. // Layer needs to fix top left
  644. var childIds = $ax('#' + id).getChildren()[0].children;
  645. for(var i = 0; i < childIds.length; i++) {
  646. var childId = childIds[i];
  647. var childObj = $jobj(childId);
  648. var fixedInfo = $ax.dynamicPanelManager.getFixedInfo(childId);
  649. if(fixedInfo.fixed) {
  650. var axObj = $ax('#' + childId);
  651. var viewportLocation = axObj.viewportLocation();
  652. var left = viewportLocation.left;
  653. var top = viewportLocation.top;
  654. //var left = axObj.left();
  655. //var top = axObj.top();
  656. containedFixed[childId] = { left: left, top: top, fixed: fixedInfo };
  657. childObj.css('left', left);
  658. childObj.css('top', top);
  659. childObj.css('margin-left', 0);
  660. childObj.css('margin-top', 0);
  661. childObj.css('right', 'auto');
  662. childObj.css('bottom', 'auto');
  663. childObj.css('position', 'absolute');
  664. }
  665. var cssChange = {
  666. left: '-=' + css.left,
  667. top: '-=' + css.top
  668. };
  669. if($ax.getTypeFromElementId(childId) == $ax.constants.LAYER_TYPE) {
  670. _pushContainer(childId, false);
  671. $ax.visibility.applyWidgetContainer(childId, true).css(cssChange);
  672. } else {
  673. //if ($ax.public.fn.isCompoundVectorHtml(jobj[0])) {
  674. // var grandChildren = jobj[0].children;
  675. // //while (grandChildren.length > 0 && grandChildren[0].id.indexOf('container') >= 0) grandChildren = grandChildren[0].children;
  676. // for (var j = 0; j < grandChildren.length; j++) {
  677. // var grandChildId = grandChildren[j].id;
  678. // if (grandChildId.indexOf(childId + 'p') >= 0 || grandChildId.indexOf('_container') >= 0) $jobj(grandChildId).css(cssChange);
  679. // }
  680. //} else
  681. // Need to include ann and ref in move.
  682. childObj = $addAll(childObj, childId);
  683. childObj.css(cssChange);
  684. }
  685. container.append(childObj);
  686. }
  687. _setCurrFocus(focus);
  688. }
  689. container.attr('id', $ax.visibility.applyWidgetContainer(id)); // Setting the correct final id for the container
  690. trapScroll();
  691. }
  692. };
  693. var _popContainer = _visibility.popContainer = function (id, panel) {
  694. var count = containerCount[id];
  695. if(!count) return;
  696. count--;
  697. containerCount[id] = count;
  698. if(count != 0) return;
  699. var trapScroll = _trapScrollLoc(id);
  700. var jobj = $jobj(id);
  701. var container = $ax.visibility.applyWidgetContainer(id, true);
  702. // If layer is at bottom or right of page, unwrapping could change scroll by temporarily reducting page size.
  703. // To avoid this, we let container persist on page, with the size it is at this point, and don't remove container completely
  704. // until the children are back to their proper locations.
  705. var size = $ax('#' + id).size();
  706. container.css('width', size.width);
  707. container.css('height', size.height);
  708. var focus = _getCurrFocus();
  709. if(focus) $ax.event.addSuppressedEvent($ax.repeater.removeSuffixFromElementId(focus), 'OnLostFocus');
  710. jobj.append(container.children());
  711. _setCurrFocus(focus);
  712. $('body').first().append(container);
  713. // Layer doesn't have children containers to clean up
  714. if(panel) {
  715. var children = jobj.children();
  716. for(var i = 0; i < children.length; i++) {
  717. var childContainer = $(children[i]);
  718. var child = $(childContainer.children()[0]);
  719. childContainer.after(child);
  720. childContainer.remove();
  721. }
  722. } else {
  723. var left = container.css('left');
  724. var top = container.css('top');
  725. var childIds = $ax('#' + id).getChildren()[0].children;
  726. for (var i = 0; i < childIds.length; i++) {
  727. var childId = childIds[i];
  728. var cssChange = {
  729. left: '+=' + left,
  730. top: '+=' + top
  731. };
  732. if($ax.getTypeFromElementId(childId) == $ax.constants.LAYER_TYPE) {
  733. $ax.visibility.applyWidgetContainer(childId, true).css(cssChange);
  734. _popContainer(childId, false);
  735. } else {
  736. var childObj = $jobj(childId);
  737. // if ($ax.public.fn.isCompoundVectorHtml(jobj[0])) {
  738. // var grandChildren = jobj[0].children;
  739. // //while (grandChildren.length > 0 && grandChildren[0].id.indexOf('container') >= 0) grandChildren = grandChildren[0].children;
  740. // for (var j = 0; j < grandChildren.length; j++) {
  741. // var grandChildId = grandChildren[j].id;
  742. // if (grandChildId.indexOf(childId + 'p') >= 0 || grandChildId.indexOf('_container') >= 0) $jobj(grandChildId).css(cssChange);
  743. // }
  744. //} else
  745. var allObjs = $addAll(childObj, childId); // Just include other objects for initial css. Fixed panels need to be dealt with separately.
  746. allObjs.css(cssChange);
  747. var fixedInfo = containedFixed[childId];
  748. if(fixedInfo) {
  749. delete containedFixed[childId];
  750. childObj.css('position', 'fixed');
  751. var deltaX = $ax.getNumFromPx(childObj.css('left')) - fixedInfo.left;
  752. var deltaY = $ax.getNumFromPx(childObj.css('top')) - fixedInfo.top;
  753. fixedInfo = fixedInfo.fixed;
  754. if(fixedInfo.horizontal == 'left') childObj.css('left', fixedInfo.x + deltaX);
  755. else if(fixedInfo.horizontal == 'center') {
  756. childObj.css('left', '50%');
  757. childObj.css('margin-left', fixedInfo.x + deltaX);
  758. } else {
  759. childObj.css('left', 'auto');
  760. childObj.css('right', fixedInfo.x - deltaX);
  761. }
  762. if(fixedInfo.vertical == 'top') childObj.css('top', fixedInfo.y + deltaY);
  763. else if(fixedInfo.vertical == 'middle') {
  764. childObj.css('top', '50%');
  765. childObj.css('margin-top', fixedInfo.y + deltaY);
  766. } else {
  767. childObj.css('top', 'auto');
  768. childObj.css('bottom', fixedInfo.y - deltaY);
  769. }
  770. $ax.dynamicPanelManager.updatePanelPercentWidth(childId);
  771. $ax.dynamicPanelManager.updatePanelContentPercentWidth(childId);
  772. }
  773. }
  774. }
  775. }
  776. container.remove();
  777. trapScroll();
  778. };
  779. var _trapScrollLoc = function(id) {
  780. var locs = {};
  781. var states = $jobj(id).find('.panel_state');
  782. for(var i = 0; i < states.length; i++) {
  783. var state = $(states[i]);
  784. locs[state.attr('id')] = { x: state.scrollLeft(), y: state.scrollTop() };
  785. }
  786. return function() {
  787. for(var key in locs) {
  788. var state = $jobj(key);
  789. state.scrollLeft(locs[key].x);
  790. state.scrollTop(locs[key].y);
  791. }
  792. };
  793. }
  794. var _getCurrFocus = function () {
  795. // Only care about focused a tags and inputs
  796. var id = window.lastFocusedClickable && window.lastFocusedClickable.id;
  797. if(!id) return id;
  798. var jobj = $(window.lastFocusedClickable);
  799. return jobj.is('a') || jobj.is('input') ? id : '';
  800. }
  801. var _setCurrFocus = function(id) {
  802. if(id) {
  803. // This is really just needed for IE, so if this causes issues on other browsers, try adding that check here
  804. var trap = $ax.event.blockEvent($ax.repeater.removeSuffixFromElementId(id), 'OnFocus');
  805. window.setTimeout(function () {
  806. $jobj(id).focus();
  807. trap();
  808. }, 0);
  809. }
  810. }
  811. //use this to save & restore DP's scroll position when show/hide
  812. //key => dp's id (not state's id, because it seems we can change state while hiding)
  813. //value => first state's id & scroll position
  814. //we only need to store one scroll position for one DP, and remove the key after shown.
  815. var DPStateAndScroll = {}
  816. var _tryResumeScrollForDP = function (dpId, deleteId) {
  817. var scrollObj = DPStateAndScroll[dpId];
  818. if(scrollObj) {
  819. var shownState = document.getElementById(scrollObj.shownId);
  820. if(scrollObj.left) shownState.scrollLeft = scrollObj.left;
  821. if(scrollObj.top) shownState.scrollTop = scrollObj.top;
  822. if(deleteId) delete DPStateAndScroll[dpId];
  823. }
  824. };
  825. // var _makeContainer = function (containerId, rect, isFullWidth, isFlip, offset, containerExists) {
  826. var _makeContainer = function (containerId, width, height, isFullWidth, isFlip, offset, containerExists) {
  827. if(containerExists) var container = $jobj(containerId);
  828. else {
  829. container = $('<div></div>');
  830. container.attr('id', containerId);
  831. }
  832. var css = {
  833. position: 'absolute',
  834. width: width,
  835. height: height,
  836. display: 'flex'
  837. };
  838. if(!containerExists) {
  839. // If container exists, may be busy updating location. Will init and update it correctly.
  840. css.top = offset.top;
  841. css.left = offset.left;
  842. }
  843. if(isFlip) {
  844. css.perspective = '800px';
  845. css.webkitPerspective = "800px";
  846. css.mozPerspective = "800px";
  847. //adding this to make Edge happy
  848. css['transform-style'] = 'preserve-3d';
  849. } else css.overflow = 'hidden';
  850. //perspective on container will give us 3d effect when flip
  851. //if(!isFlip) css.overflow = 'hidden';
  852. // Rect should be a jquery not axquery obj
  853. //_getFixedCss(css, rect.$ ? rect.$() : rect, fixedInfo, isFullWidth);
  854. container.css(css);
  855. return container;
  856. };
  857. var CONTAINER_SUFFIX = _visibility.CONTAINER_SUFFIX = '_container';
  858. var CONTAINER_INNER = CONTAINER_SUFFIX + '_inner';
  859. _visibility.getWidgetFromContainer = function(id) {
  860. var containerIndex = id.indexOf(CONTAINER_SUFFIX);
  861. if(containerIndex == -1) return id;
  862. return id.substr(0, containerIndex) + id.substr(containerIndex + CONTAINER_SUFFIX.length);
  863. };
  864. // Apply container to widget id if necessary.
  865. // returnJobj: True if you want the jquery object rather than id returned
  866. // skipCheck: True if you want the query returned reguardless of container existing
  867. // checkInner: True if inner container should be checked
  868. _visibility.applyWidgetContainer = function (id, returnJobj, skipCheck, checkInner) {
  869. // If container exists, just return (return query if requested)
  870. if(id.indexOf(CONTAINER_SUFFIX) != -1) return returnJobj ? $jobj(id) : id;
  871. // Get desired id, and return it if query is not desired
  872. var containerId = $ax.repeater.applySuffixToElementId(id, checkInner ? CONTAINER_INNER : CONTAINER_SUFFIX);
  873. if(!returnJobj) return containerId;
  874. // If skipping check or container exists, just return innermost container requested
  875. var container = $jobj(containerId);
  876. if(skipCheck || container.length) return container;
  877. // If inner container was not checked, then no more to check, return query for widget
  878. if(!checkInner) return $jobj(id);
  879. // If inner container was checked, check for regular container still
  880. container = $jobj($ax.repeater.applySuffixToElementId(id, CONTAINER_SUFFIX));
  881. return container.length ? container : $jobj(id);
  882. };
  883. _visibility.isContainer = function(id) {
  884. return id.indexOf(CONTAINER_SUFFIX) != -1;
  885. };
  886. _visibility.getRealChildren = function(query) {
  887. while(query.length && $(query[0]).attr('id').indexOf(CONTAINER_SUFFIX) != -1) query = query.children();
  888. return query;
  889. };
  890. //var _getFixedCss = function(css, rect, fixedInfo, isFullWidth) {
  891. // // todo: **mas** make sure this is ok
  892. // if(fixedInfo.fixed) {
  893. // css.position = 'fixed';
  894. // if(fixedInfo.horizontal == 'left') css.left = fixedInfo.x;
  895. // else if(fixedInfo.horizontal == 'center') {
  896. // css.left = isFullWidth ? '0px' : '50%';
  897. // css['margin-left'] = fixedInfo.x;
  898. // } else if(fixedInfo.horizontal == 'right') {
  899. // css.left = 'auto';
  900. // css.right = fixedInfo.x;
  901. // }
  902. // if(fixedInfo.vertical == 'top') css.top = fixedInfo.y;
  903. // else if(fixedInfo.vertical == 'middle') {
  904. // css.top = '50%';
  905. // css['margin-top'] = fixedInfo.y;
  906. // } else if(fixedInfo.vertical == 'bottom') {
  907. // css.top = 'auto';
  908. // css.bottom = fixedInfo.y;
  909. // }
  910. // } else {
  911. // css.left = Number(rect.css('left').replace('px', '')) || 0;
  912. // css.top = Number(rect.css('top').replace('px', '')) || 0;
  913. // }
  914. //};
  915. var _slideStateOut = function (container, stateId, options, onComplete, jobj) {
  916. var directionOut = options.direction;
  917. var axObject = $ax('#' + container.attr('id'));
  918. var width = axObject.width();
  919. var height = axObject.height();
  920. _blockSetMoveIds = true;
  921. if(directionOut == "right") {
  922. $ax.move.MoveWidget(stateId, width, 0, options, false, onComplete, false, jobj, true);
  923. } else if(directionOut == "left") {
  924. $ax.move.MoveWidget(stateId, -width, 0, options, false, onComplete, false, jobj, true);
  925. } else if(directionOut == "up") {
  926. $ax.move.MoveWidget(stateId, 0, -height, options, false, onComplete, false, jobj, true);
  927. } else if(directionOut == "down") {
  928. $ax.move.MoveWidget(stateId, 0, height, options, false, onComplete, false, jobj, true);
  929. }
  930. _blockSetMoveIds = false;
  931. };
  932. var _slideStateIn = function (id, stateId, options, container, makePanelVisible, onComplete, jobj, preserveScroll) {
  933. var directionIn = options.direction;
  934. var axObject = $ax('#' +container.attr('id'));
  935. var width = axObject.width();
  936. var height = axObject.height();
  937. if (makePanelVisible) $ax.visibility.SetIdVisible(id, true);
  938. for (i = 0; i < jobj.length; i++) $ax.visibility.SetVisible(jobj[i], true);
  939. for(var i = 0; i < jobj.length; i++) {
  940. var child = $(jobj[i]);
  941. var oldTop = $ax.getNumFromPx(fixAuto(child, 'top'));
  942. var oldLeft = $ax.getNumFromPx(fixAuto(child, 'left'));
  943. if (directionIn == "right") {
  944. child.css('left', oldLeft - width + 'px');
  945. } else if(directionIn == "left") {
  946. child.css('left', oldLeft + width + 'px');
  947. } else if(directionIn == "up") {
  948. child.css('top', oldTop + height + 'px');
  949. } else if(directionIn == "down") {
  950. child.css('top', oldTop - height + 'px');
  951. }
  952. }
  953. if(preserveScroll) _tryResumeScrollForDP(id);
  954. _blockSetMoveIds = true;
  955. if(directionIn == "right") {
  956. $ax.move.MoveWidget(stateId, width, 0, options, false, onComplete, false, jobj, true);
  957. } else if(directionIn == "left") {
  958. $ax.move.MoveWidget(stateId, -width, 0, options, false, onComplete, false, jobj, true);
  959. } else if(directionIn == "up") {
  960. $ax.move.MoveWidget(stateId, 0, -height, options, false, onComplete, false, jobj, true);
  961. } else if(directionIn == "down") {
  962. $ax.move.MoveWidget(stateId, 0, height, options, false, onComplete, false, jobj, true);
  963. }
  964. _blockSetMoveIds = false;
  965. };
  966. $ax.visibility.GetPanelStateId = function(dpId, index) {
  967. var itemNum = $ax.repeater.getItemIdFromElementId(dpId);
  968. var panelStateId = $ax.repeater.getScriptIdFromElementId(dpId) + '_state' + index;
  969. return $ax.repeater.createElementId(panelStateId, itemNum);
  970. };
  971. $ax.visibility.GetPanelStateCount = function(id) {
  972. return $ax.visibility.getRealChildren($jobj(id).children()).filter("[id*='_state']").length;
  973. };
  974. var _bringPanelStateToFront = function (dpId, stateId, oldStateId, oldInFront) {
  975. var panel = $jobj(dpId);
  976. var frontId = oldInFront ? oldStateId : stateId;
  977. if(containerCount[dpId]) {
  978. frontId = $ax.visibility.applyWidgetContainer(frontId);
  979. panel = $ax.visibility.applyWidgetContainer(dpId, true, false, true);
  980. }
  981. $jobj(frontId).appendTo(panel);
  982. //when bring a panel to front, it will be focused, and the previous front panel should fire blur event if it's lastFocusedClickableSelector
  983. //ie(currently 11) and firefox(currently 34) doesn't fire blur event, this is the hack to fire it manually
  984. if((IE || FIREFOX) && window.lastFocusedClickable && $ax.event.getFocusableWidgetOrChildId(window.lastFocusedControl) == window.lastFocusedClickable.id) {
  985. // Only need to do this if the currently focused widget is in the panel state that is being hidden.
  986. if($jobj(oldStateId).find('#' + window.lastFocusedClickable.id.split('_')[0]).length) $(window.lastFocusedClickable).triggerHandler('blur');
  987. }
  988. };
  989. var _limboIds = _visibility.limboIds = {};
  990. // limboId's is a dictionary of id->true, essentially a set.
  991. var _addLimboAndHiddenIds = $ax.visibility.addLimboAndHiddenIds = function(newLimboIds, newHiddenIds, query, skipRepeater) {
  992. var limboedByMaster = {};
  993. for(var key in newLimboIds) {
  994. if (!$ax.public.fn.IsReferenceDiagramObject($ax.getObjectFromElementId(key).type)) continue;
  995. var ids = $ax.model.idsInRdoToHideOrLimbo(key);
  996. for(var i = 0; i < ids.length; i++) limboedByMaster[ids[i]] = true;
  997. }
  998. var hiddenByMaster = {};
  999. for(key in newHiddenIds) {
  1000. if (!$ax.public.fn.IsReferenceDiagramObject($ax.getObjectFromElementId(key).type)) continue;
  1001. ids = $ax.model.idsInRdoToHideOrLimbo(key);
  1002. for(i = 0; i < ids.length; i++) hiddenByMaster[ids[i]] = true;
  1003. }
  1004. // Extend with children of rdos
  1005. newLimboIds = $.extend(newLimboIds, limboedByMaster);
  1006. newHiddenIds = $.extend(newHiddenIds, hiddenByMaster);
  1007. // something is only visible if it's not hidden and limboed
  1008. query.each(function(diagramObject, elementId) {
  1009. // Rdos already handled, contained widgets are limboed by the parent, and sub menus should be ignored
  1010. if(diagramObject.isContained || $ax.public.fn.IsReferenceDiagramObject(diagramObject.type) || $ax.public.fn.IsTableCell(diagramObject.type) || $jobj(elementId).hasClass('sub_menu')) return;
  1011. if(diagramObject.type == 'table' && $jobj(elementId).parent().hasClass('ax_menu')) return;
  1012. if(skipRepeater) {
  1013. // Any item in a repeater should return
  1014. if($ax.getParentRepeaterFromElementIdExcludeSelf(elementId)) return;
  1015. }
  1016. var scriptId = $ax.repeater.getScriptIdFromElementId(elementId);
  1017. var shouldBeVisible = Boolean(!newLimboIds[scriptId] && !newHiddenIds[scriptId]);
  1018. var isVisible = Boolean(_isIdVisible(elementId));
  1019. if(shouldBeVisible != isVisible) {
  1020. _setWidgetVisibility(elementId, { value: shouldBeVisible, noContainer: true });
  1021. }
  1022. });
  1023. _limboIds = _visibility.limboIds = $.extend(_limboIds, newLimboIds);
  1024. };
  1025. var _clearLimboAndHidden = $ax.visibility.clearLimboAndHidden = function(ids) {
  1026. _limboIds = _visibility.limboIds = {};
  1027. };
  1028. $ax.visibility.clearLimboAndHiddenIds = function(ids) {
  1029. for(var i = 0; i < ids.length; i++) {
  1030. var scriptId = $ax.repeater.getScriptIdFromElementId(ids[i]);
  1031. delete _limboIds[scriptId];
  1032. }
  1033. };
  1034. $ax.visibility.resetLimboAndHiddenToDefaults = function (query) {
  1035. if(!query) query = $ax('*');
  1036. _clearLimboAndHidden();
  1037. _addLimboAndHiddenIds(_defaultLimbo, _defaultHidden, query);
  1038. };
  1039. $ax.visibility.isScriptIdLimbo = function(scriptId) {
  1040. if(_limboIds[scriptId]) return true;
  1041. var repeater = $ax.getParentRepeaterFromScriptId(scriptId);
  1042. if(!repeater) return false;
  1043. var itemId = $ax.getItemIdsForRepeater(repeater)[0];
  1044. return _limboIds[$ax.repeater.createElementId(scriptId, itemId)];
  1045. }
  1046. $ax.visibility.isElementIdLimboOrInLimboContainer = function (elementId) {
  1047. var parent = document.getElementById(elementId);
  1048. while(parent) {
  1049. var scriptId = $ax.repeater.getScriptIdFromElementId($(parent).attr('id'));
  1050. if(_limboIds[scriptId]) return true;
  1051. parent = parent.parentElement;
  1052. }
  1053. return false;
  1054. }
  1055. var _blockSetMoveIds = false;
  1056. var _movedIds = _visibility.movedIds = {};
  1057. var _resizedIds = _visibility.resizedIds = {};
  1058. var _rotatedIds = _visibility.rotatedIds = {};
  1059. $ax.visibility.getMovedLocation = function(scriptId) {
  1060. return _movedIds[scriptId];
  1061. //var repeater = $ax.getParentRepeaterFromScriptId(scriptId);
  1062. //if (!repeater) return false;
  1063. //var itemId = $ax.getItemIdsForRepeater(repeater)[0];
  1064. //return _movedIds[$ax.repeater.createElementId(scriptId, itemId)];
  1065. };
  1066. $ax.visibility.setMovedLocation = function (scriptId, left, top) {
  1067. if ($jobj(scriptId).css('position') == 'fixed') return;
  1068. _movedIds[scriptId] = { left: left, top: top };
  1069. };
  1070. $ax.visibility.moveMovedLocation = function (scriptId, deltaLeft, deltaTop) {
  1071. if(_blockSetMoveIds) return false;
  1072. var offsetLocation = $ax('#' + scriptId).offsetLocation();
  1073. $ax.visibility.setMovedLocation(scriptId, offsetLocation.x + deltaLeft, offsetLocation.y + deltaTop);
  1074. if($ax.getTypeFromElementId(scriptId) == $ax.constants.LAYER_TYPE) {
  1075. var childIds = $ax('#' + scriptId).getChildren()[0].children;
  1076. for (var i = 0; i < childIds.length; i++) {
  1077. $ax.visibility.moveMovedLocation(childIds[i], deltaLeft, deltaTop);
  1078. }
  1079. }
  1080. };
  1081. $ax.visibility.getResizedSize = function(scriptId) {
  1082. return _resizedIds[scriptId];
  1083. //var repeater = $ax.getParentRepeaterFromScriptId(scriptId);
  1084. //if (!repeater) return false;
  1085. //var itemId = $ax.getItemIdsForRepeater(repeater)[0];
  1086. //return _resizedIds[$ax.repeater.createElementId(scriptId, itemId)];
  1087. };
  1088. $ax.visibility.setResizedSize = function(scriptId, width, height) {
  1089. _resizedIds[scriptId] = { width: width, height: height };
  1090. };
  1091. $ax.visibility.getRotatedAngle = function (scriptId) {
  1092. return _rotatedIds[scriptId];
  1093. };
  1094. $ax.visibility.setRotatedAngle = function (scriptId, rotation) {
  1095. _rotatedIds[scriptId] = rotation;
  1096. };
  1097. $ax.visibility.clearMovedAndResized = function () {
  1098. _movedIds = _visibility.movedIds = {};
  1099. _resizedIds = _visibility.resizedIds = {};
  1100. _rotatedIds = _visibility.rotatedIds = {};
  1101. };
  1102. $ax.visibility.clearMovedAndResizedIds = function (elementIds) {
  1103. for (var i = 0; i < elementIds.length; i++) {
  1104. var id = elementIds[i];
  1105. delete _movedIds[id];
  1106. delete _resizedIds[id];
  1107. delete _rotatedIds[id];
  1108. }
  1109. };
  1110. $ax.visibility.initialize = function() {
  1111. // initialize initial visible states
  1112. $('.' + HIDDEN_CLASS).each(function (index, diagramObject) {
  1113. _defaultHidden[$ax.repeater.getScriptIdFromElementId(diagramObject.id)] = true;
  1114. });
  1115. $('.' + UNPLACED_CLASS).each(function (index, diagramObject) {
  1116. _defaultLimbo[$ax.repeater.getScriptIdFromElementId(diagramObject.id)] = true;
  1117. });
  1118. _addLimboAndHiddenIds(_defaultLimbo, _defaultHidden, $ax('*'), true);
  1119. };
  1120. _visibility.initRepeater = function(repeaterId) {
  1121. var html = $('<div></div>');
  1122. html.append($jobj(repeaterId + '_script').html());
  1123. html.find('.' + HIDDEN_CLASS).each(function (index, element) {
  1124. _defaultHidden[$ax.repeater.getScriptIdFromElementId(element.id)] = true;
  1125. });
  1126. html.find('.' + UNPLACED_CLASS).each(function (index, element) {
  1127. _defaultLimbo[$ax.repeater.getScriptIdFromElementId(element.id)] = true;
  1128. });
  1129. }
  1130. var HIDDEN_CLASS = _visibility.HIDDEN_CLASS = 'ax_default_hidden';
  1131. var UNPLACED_CLASS = _visibility.UNPLACED_CLASS = 'ax_default_unplaced';
  1132. });