visibility.js 60 KB

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