sitemap.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. var currentNodeUrl = '';
  2. var allNodeUrls = [];
  3. function openNextPage() {
  4. var index = allNodeUrls.indexOf(currentNodeUrl) + 1;
  5. if(index >= allNodeUrls.length) return;
  6. var nextNodeUrl = allNodeUrls[index];
  7. $('.sitemapPageLink[nodeUrl="' + nextNodeUrl + '"]').click();
  8. }
  9. function openPreviousPage() {
  10. var index = allNodeUrls.indexOf(currentNodeUrl) - 1;
  11. if(index < 0) return;
  12. var nextNodeUrl = allNodeUrls[index];
  13. $('.sitemapPageLink[nodeUrl="' + nextNodeUrl + '"]').click();
  14. }
  15. // use this to isolate the scope
  16. (function() {
  17. var SHOW_HIDE_ANIMATION_DURATION = 0;
  18. var HIGHLIGHT_INTERACTIVE_VAR_NAME = 'hi';
  19. var currentPageLoc = '';
  20. var currentPlayerLoc = '';
  21. var currentPageHashString = '';
  22. $(window.document).ready(function() {
  23. $axure.player.createPluginHost({
  24. id: 'sitemapHost',
  25. context: 'interface',
  26. title: 'PAGES',
  27. gid: 1
  28. });
  29. generateSitemap();
  30. $('.sitemapPlusMinusLink').toggle(collapse_click, expand_click);
  31. $('.sitemapPageLink').click(node_click);
  32. $('#sitemapLinksContainer').hide();
  33. $('#linksButton').click(links_click);
  34. $('#adaptiveButton').click(adaptive_click);
  35. $('#adaptiveViewsContainer').hide();
  36. $('#highlightInteractiveButton').click(highlight_interactive);
  37. $('#searchButton').click(search_click);
  38. $('#searchBox').keyup(search_input_keyup);
  39. $('.sitemapLinkField').click(function() { this.select(); });
  40. $('input[value="withoutmap"]').click(withoutSitemapRadio_click);
  41. $('input[value="withmap"]').click(withSitemapRadio_click);
  42. $('#minimizeBox, #collapseBox, #footnotesBox, #highlightBox').change(sitemapUrlOptions_change);
  43. $('#viewSelect').change(sitemapUrlViewSelect_change);
  44. $(document).on('ContainerHeightChange', function() {
  45. updateContainerHeight();
  46. });
  47. // bind to the page load
  48. $axure.page.bind('load.sitemap', function() {
  49. currentPageLoc = $axure.page.location.split("#")[0];
  50. var decodedPageLoc = decodeURI(currentPageLoc);
  51. currentNodeUrl = decodedPageLoc.substr(decodedPageLoc.lastIndexOf('/') ? decodedPageLoc.lastIndexOf('/') + 1 : 0);
  52. currentPlayerLoc = $(location).attr('href').split("#")[0].split("?")[0];
  53. currentPageHashString = '#p=' + currentNodeUrl.substr(0, currentNodeUrl.lastIndexOf('.'));
  54. setVarInCurrentUrlHash('p', currentNodeUrl.substring(0, currentNodeUrl.lastIndexOf('.html')));
  55. $('.sitemapPageLink').parent().parent().removeClass('sitemapHighlight');
  56. $('.sitemapPageLink[nodeUrl="' + currentNodeUrl + '"]').parent().parent().addClass('sitemapHighlight');
  57. var pageName = $axure.page.pageName;
  58. $('.pageNameHeader').html(pageName);
  59. $('#sitemapLinksPageName').html($('.sitemapHighlight > .sitemapPageLinkContainer > .sitemapPageLink > .sitemapPageName').html());
  60. //Click the "Without sitemap" radio button so that it's selected by default
  61. $('input[value="withoutmap"]').click();
  62. //If highlight var is present and set to 1 or else if
  63. //sitemap highlight button is selected then highlight interactive elements
  64. var hiVal = getHashStringVar(HIGHLIGHT_INTERACTIVE_VAR_NAME);
  65. if(hiVal.length > 0 && hiVal == 1) {
  66. $('#highlightInteractiveButton').addClass('sitemapToolbarButtonSelected');
  67. $axure.messageCenter.postMessage('highlightInteractive', true);
  68. } else if($('#highlightInteractiveButton').is('.sitemapToolbarButtonSelected')) {
  69. $axure.messageCenter.postMessage('highlightInteractive', true);
  70. }
  71. //Set the current view if it is defined in the hash string
  72. //If the view is invalid, set it to 'auto' in the string
  73. //ELSE set the view based on the currently selected view in the toolbar menu
  74. var viewStr = getHashStringVar(ADAPTIVE_VIEW_VAR_NAME);
  75. if(viewStr.length > 0) {
  76. var $view = $('.adaptiveViewOption[val="' + viewStr + '"]');
  77. if($view.length > 0) $view.click();
  78. else $('.adaptiveViewOption[val="auto"]').click();
  79. } else if($('.checkedAdaptive').length > 0) {
  80. var $viewOption = $('.checkedAdaptive').parents('.adaptiveViewOption');
  81. if($viewOption.attr('val') != 'auto') $viewOption.click();
  82. }
  83. $axure.messageCenter.postMessage('finishInit');
  84. return false;
  85. });
  86. var $adaptiveViewsContainer = $('#adaptiveViewsContainer');
  87. var $viewSelect = $('#viewSelect');
  88. //Fill out adaptive view container with prototype's defined adaptive views, as well as the default, and Auto
  89. $adaptiveViewsContainer.append('<div class="adaptiveViewOption" val="auto"><div class="adaptiveCheckboxDiv checkedAdaptive"></div>Auto</div>');
  90. $viewSelect.append('<option value="auto">Auto</option>');
  91. if(typeof $axure.document.defaultAdaptiveView.name != 'undefined') {
  92. //If the name is a blank string, make the view name the width if non-zero, else 'any'
  93. var defaultViewName = $axure.document.defaultAdaptiveView.name;
  94. $adaptiveViewsContainer.append('<div class="adaptiveViewOption currentAdaptiveView" val="default"><div class="adaptiveCheckboxDiv"></div>' + defaultViewName + '</div>');
  95. $viewSelect.append('<option value="default">' + defaultViewName + '</option>');
  96. }
  97. var enabledViewIds = $axure.document.configuration.enabledViewIds;
  98. for(var viewIndex = 0; viewIndex < $axure.document.adaptiveViews.length; viewIndex++) {
  99. var currView = $axure.document.adaptiveViews[viewIndex];
  100. if(enabledViewIds.indexOf(currView.id) < 0) continue;
  101. var widthString = currView.size.width == 0 ? 'any' : currView.size.width;
  102. var heightString = currView.size.height == 0 ? 'any' : currView.size.height;
  103. var conditionString = '';
  104. if(currView.condition == '>' || currView.condition == '>=') {
  105. conditionString = ' and above';
  106. } else if(currView.condition == '<' || currView.condition == '<=') {
  107. conditionString = ' and below';
  108. }
  109. var viewString = currView.name + ' (' + widthString + ' x ' + heightString + conditionString + ')';
  110. $adaptiveViewsContainer.append('<div class="adaptiveViewOption" val="' + currView.id + '"><div class="adaptiveCheckboxDiv"></div>' + viewString + '</div>');
  111. $viewSelect.append('<option value="' + currView.id + '">' + viewString + '</option>');
  112. }
  113. $('.adaptiveViewOption').click(adaptiveViewOption_click);
  114. $('.adaptiveViewOption').mouseup(function(event) {
  115. event.stopPropagation();
  116. });
  117. $('#searchBox').focusin(function() {
  118. if($(this).is('.searchBoxHint')) {
  119. $(this).val('');
  120. $(this).removeClass('searchBoxHint');
  121. }
  122. }).focusout(function() {
  123. if($(this).val() == '') {
  124. $(this).addClass('searchBoxHint');
  125. $(this).val('Search');
  126. }
  127. });
  128. $('#searchBox').focusout();
  129. });
  130. function updateContainerHeight() {
  131. $('#sitemapTreeContainer').height($('#sitemapHost').height() - $('#sitemapHeader').outerHeight());
  132. }
  133. function hideAllContainersExcept(exceptContainer) {
  134. //1 - adaptive container, 3 - links container
  135. if(exceptContainer != 1) {
  136. $('#adaptiveViewsContainer').hide();
  137. $('#adaptiveButton').removeClass('sitemapToolbarButtonSelected');
  138. }
  139. if(exceptContainer != 3) {
  140. $('#sitemapLinksContainer').hide();
  141. $('#linksButton').removeClass('sitemapToolbarButtonSelected');
  142. }
  143. }
  144. function collapse_click(event) {
  145. $(this)
  146. .children('.sitemapMinus').removeClass('sitemapMinus').addClass('sitemapPlus').end()
  147. .closest('li').children('ul').hide(SHOW_HIDE_ANIMATION_DURATION);
  148. $(this).next('.sitemapFolderOpenIcon').removeClass('sitemapFolderOpenIcon').addClass('sitemapFolderIcon');
  149. }
  150. function expand_click(event) {
  151. $(this)
  152. .children('.sitemapPlus').removeClass('sitemapPlus').addClass('sitemapMinus').end()
  153. .closest('li').children('ul').show(SHOW_HIDE_ANIMATION_DURATION);
  154. $(this).next('.sitemapFolderIcon').removeClass('sitemapFolderIcon').addClass('sitemapFolderOpenIcon');
  155. }
  156. function node_click(event) {
  157. $axure.page.navigate(this.getAttribute('nodeUrl'), true);
  158. }
  159. function links_click(event) {
  160. hideAllContainersExcept(3);
  161. $('#sitemapLinksContainer').toggle();
  162. updateContainerHeight();
  163. if($('#sitemapLinksContainer').is(":visible")) {
  164. $('#linksButton').addClass('sitemapToolbarButtonSelected');
  165. } else {
  166. $('#linksButton').removeClass('sitemapToolbarButtonSelected');
  167. }
  168. }
  169. $axure.messageCenter.addMessageListener(function(message, data) {
  170. if(message == 'adaptiveViewChange') {
  171. $('.adaptiveViewOption').removeClass('currentAdaptiveView');
  172. if(data.viewId) {$('div[val="' + data.viewId + '"]').addClass('currentAdaptiveView');}
  173. else $('div[val="default"]').addClass('currentAdaptiveView');
  174. //when we set adaptive view through user event, we want to update the checkmark on sitemap
  175. if(data.forceSwitchTo) {
  176. $('.checkedAdaptive').removeClass('checkedAdaptive');
  177. $('div[val="' + data.forceSwitchTo + '"]').find('.adaptiveCheckboxDiv').addClass('checkedAdaptive');
  178. }
  179. }
  180. });
  181. $(document).on('pluginShown', function (event, data) {
  182. if(data == 1) {
  183. hideAllContainersExcept(1);
  184. updateContainerHeight();
  185. }
  186. });
  187. $(document).on('sidebarExpanded', function (event, data) {
  188. hideAllContainersExcept(1);
  189. updateContainerHeight();
  190. });
  191. function highlight_interactive(event) {
  192. if($('#highlightInteractiveButton').is('.sitemapToolbarButtonSelected')) {
  193. $('#highlightInteractiveButton').removeClass('sitemapToolbarButtonSelected');
  194. $axure.messageCenter.postMessage('highlightInteractive', false);
  195. //Delete 'hi' hash string var if it exists since default is unselected
  196. deleteVarFromCurrentUrlHash(HIGHLIGHT_INTERACTIVE_VAR_NAME);
  197. } else {
  198. $('#highlightInteractiveButton').addClass('sitemapToolbarButtonSelected');
  199. $axure.messageCenter.postMessage('highlightInteractive', true);
  200. //Add 'hi' hash string var so that stay highlighted across reloads
  201. setVarInCurrentUrlHash(HIGHLIGHT_INTERACTIVE_VAR_NAME, 1);
  202. }
  203. }
  204. function adaptive_click(event) {
  205. hideAllContainersExcept(1);
  206. $('#adaptiveViewsContainer').toggle();
  207. updateContainerHeight();
  208. if(!$('#adaptiveViewsContainer').is(":visible")) {
  209. $('#adaptiveButton').removeClass('sitemapToolbarButtonSelected');
  210. } else {
  211. $('#adaptiveButton').addClass('sitemapToolbarButtonSelected');
  212. }
  213. }
  214. function adaptiveViewOption_click(event) {
  215. var currVal = $(this).attr('val');
  216. $('.checkedAdaptive').removeClass('checkedAdaptive');
  217. $(this).find('.adaptiveCheckboxDiv').addClass('checkedAdaptive');
  218. currentPageLoc = $axure.page.location.split("#")[0];
  219. var decodedPageLoc = decodeURI(currentPageLoc);
  220. var nodeUrl = decodedPageLoc.substr(decodedPageLoc.lastIndexOf('/') ? decodedPageLoc.lastIndexOf('/') + 1 : 0);
  221. var adaptiveData = {
  222. src: nodeUrl
  223. };
  224. adaptiveData.view = currVal;
  225. $axure.messageCenter.postMessage('switchAdaptiveView', adaptiveData);
  226. if(currVal == 'auto') {
  227. //Remove view in hash string if one is set
  228. deleteVarFromCurrentUrlHash(ADAPTIVE_VIEW_VAR_NAME);
  229. } else {
  230. //Set current view in hash string so that it can be maintained across reloads
  231. setVarInCurrentUrlHash(ADAPTIVE_VIEW_VAR_NAME, currVal);
  232. }
  233. }
  234. function search_click(event) {
  235. $('#searchDiv').toggle();
  236. if(!$('#searchDiv').is(":visible")) {
  237. $('#searchButton').removeClass('sitemapToolbarButtonSelected');
  238. $('#searchBox').val('');
  239. $('#searchBox').keyup();
  240. //$('#sitemapToolbar').css('height', '22px');
  241. $('#sitemapTreeContainer').css('top', '31px');
  242. } else {
  243. $('#searchButton').addClass('sitemapToolbarButtonSelected');
  244. $('#searchBox').focus();
  245. //$('#sitemapToolbar').css('height', '50px');
  246. $('#sitemapTreeContainer').css('top', '63px');
  247. }
  248. }
  249. function search_input_keyup(event) {
  250. var searchVal = $(this).val().toLowerCase();
  251. //If empty search field, show all nodes, else grey+hide all nodes and
  252. //ungrey+unhide all matching nodes, as well as unhide their parent nodes
  253. if(searchVal == '') {
  254. $('.sitemapPageName').removeClass('sitemapGreyedName');
  255. $('.sitemapNode').show();
  256. } else {
  257. $('.sitemapNode').hide();
  258. $('.sitemapPageName').addClass('sitemapGreyedName').each(function() {
  259. var nodeName = $(this).text().toLowerCase();
  260. if(nodeName.indexOf(searchVal) != -1) {
  261. $(this).removeClass('sitemapGreyedName').parents('.sitemapNode:first').show().parents('.sitemapExpandableNode').show();
  262. }
  263. });
  264. }
  265. }
  266. function withoutSitemapRadio_click() {
  267. $('#sitemapLinkWithPlayer').val(currentPageLoc);
  268. $('#sitemapOptionsDiv').hide();
  269. $('#minimizeBox').attr('disabled', 'disabled');
  270. $('#collapseBox').attr('disabled', 'disabled');
  271. $('#footnotesBox').attr('disabled', 'disabled');
  272. $('#highlightBox').attr('disabled', 'disabled');
  273. $('#viewSelect').attr('disabled', 'disabled');
  274. $('input[value="withmap"]').parent().removeClass('sitemapRadioSelected');
  275. updateContainerHeight();
  276. }
  277. function withSitemapRadio_click() {
  278. $('#sitemapLinkWithPlayer').val(currentPlayerLoc + currentPageHashString);
  279. $('#minimizeBox').removeAttr('disabled').change();
  280. $('#collapseBox').removeAttr('disabled').change();
  281. $('#footnotesBox').removeAttr('disabled').change();
  282. $('#highlightBox').removeAttr('disabled').change();
  283. $('#viewSelect').removeAttr('disabled').change();
  284. $('#sitemapOptionsDiv').show();
  285. $('input[value="withmap"]').parent().addClass('sitemapRadioSelected');
  286. updateContainerHeight();
  287. }
  288. function sitemapUrlOptions_change() {
  289. var currLinkHash = '#' + $('#sitemapLinkWithPlayer').val().split("#")[1];
  290. var newHash = null;
  291. var varName = '';
  292. var defVal = 1;
  293. if($(this).is('#minimizeBox')) {
  294. varName = SITEMAP_COLLAPSE_VAR_NAME;
  295. } else if($(this).is('#collapseBox')) {
  296. varName = PLUGIN_VAR_NAME;
  297. defVal = 0;
  298. } else if($(this).is('#footnotesBox')) {
  299. varName = FOOTNOTES_VAR_NAME;
  300. defVal = 0;
  301. } else if($(this).is('#highlightBox')) {
  302. varName = HIGHLIGHT_INTERACTIVE_VAR_NAME;
  303. }
  304. newHash = $(this).is(':checked') ? setHashStringVar(currLinkHash, varName, defVal) : deleteHashStringVar(currLinkHash, varName);
  305. if(newHash != null) {
  306. $('#sitemapLinkWithPlayer').val(currentPlayerLoc + newHash);
  307. }
  308. }
  309. function sitemapUrlViewSelect_change() {
  310. var currLinkHash = '#' + $('#sitemapLinkWithPlayer').val().split("#")[1];
  311. var newHash = null;
  312. var $selectedOption = $(this).find('option:selected');
  313. if($selectedOption.length == 0) return;
  314. var selectedVal = $selectedOption.attr('value');
  315. newHash = selectedVal == 'auto' ? deleteHashStringVar(currLinkHash, ADAPTIVE_VIEW_VAR_NAME) : setHashStringVar(currLinkHash, ADAPTIVE_VIEW_VAR_NAME, selectedVal);
  316. if(newHash != null) {
  317. $('#sitemapLinkWithPlayer').val(currentPlayerLoc + newHash);
  318. }
  319. }
  320. function generateSitemap() {
  321. var treeUl = "<div id='sitemapHeader'' class='sitemapHeader'>";
  322. treeUl += "<div id='sitemapToolbar' class='sitemapToolbar'>";
  323. treeUl += "<div class='pluginNameHeader'>PAGES</div>";
  324. treeUl += "<div class='pageNameHeader'></div>";
  325. treeUl += "<div class='pageButtonHeader'>";
  326. if($axure.document.configuration.enabledViewIds.length > 0) {
  327. treeUl += "<a id='adaptiveButton' title='Select Adaptive View' class='sitemapToolbarButton'></a>";
  328. }
  329. treeUl += "<a id='linksButton' title='Get Links' class='sitemapToolbarButton'></a>";
  330. treeUl += "<a id='highlightInteractiveButton' title='Highlight interactive elements' class='sitemapToolbarButton'></a>";
  331. treeUl += "</div>";
  332. treeUl += "</div>";
  333. if($axure.document.adaptiveViews.length > 0) {
  334. treeUl += "<div id='adaptiveViewsContainer'><div style='margin-bottom:10px;'>Adaptive Views</div></div>";
  335. }
  336. //linkcontainer
  337. treeUl += "<div id='sitemapLinksContainer' class='sitemapLinkContainer'>";
  338. treeUl += "<div style='margin-bottom:10px;'>Generate sharable URLs</div>";
  339. treeUl += "<input id='sitemapLinkWithPlayer' type='text' class='sitemapLinkField'/>";
  340. treeUl += "<div class='sitemapOptionContainer'>";
  341. treeUl += "<div><label><input type='radio' name='sitemapToggle' value='withoutmap'/>Without Sidebar</label></div>";
  342. treeUl += "<div style='margin-top:10px;'><label><input type='radio' name='sitemapToggle' value='withmap'/>With Sidebar</label>";
  343. treeUl += "<div id='sitemapOptionsDiv'>";
  344. treeUl += "<div class='sitemapUrlOption'><label><input type='checkbox' id='minimizeBox' />Minimize sidebar</label></div>";
  345. treeUl += "<div class='sitemapUrlOption'><label><input type='checkbox' id='collapseBox' />Pages closed</label></div>";
  346. if($axure.document.configuration.showAnnotations == true) {
  347. treeUl += "<div class='sitemapUrlOption'><label><input type='checkbox' id='footnotesBox' />Hide footnotes</label></div>";
  348. }
  349. treeUl += "<div class='sitemapUrlOption'><label><input type='checkbox' id='highlightBox' />Highlight interactive elements</label></div>";
  350. if($axure.document.configuration.enabledViewIds.length > 0) {
  351. treeUl += "<div id='viewSelectDiv' class='sitemapUrlOption'><label>View: <select id='viewSelect'></select></label></div>";
  352. }
  353. treeUl += "</div></div></div></div>";
  354. /////////////////
  355. treeUl += "</div>";
  356. treeUl += "<div id='sitemapTreeContainer'>";
  357. treeUl += '<div id="searchDiv" style=""><input id="searchBox" style="" type="text"/></div>';
  358. treeUl += "<ul class='sitemapTree' style='clear:both;'>";
  359. var rootNodes = $axure.document.sitemap.rootNodes;
  360. for(var i = 0; i < rootNodes.length; i++) {
  361. treeUl += generateNode(rootNodes[i], 0);
  362. }
  363. treeUl += "</ul></div>";
  364. $('#sitemapHost').html(treeUl);
  365. if($axure.document.adaptiveViews.length <= 0) {
  366. $('#sitemapHost .pageNameHeader').css('padding-right', '55px');
  367. }
  368. }
  369. function generateNode(node, level) {
  370. var hasChildren = (node.children && node.children.length > 0);
  371. var margin, returnVal;
  372. if(hasChildren) {
  373. margin = (9 + level * 17);
  374. returnVal = "<li class='sitemapNode sitemapExpandableNode'><div><div class='sitemapPageLinkContainer' style='margin-left:" + margin + "px'><a class='sitemapPlusMinusLink'><span class='sitemapMinus'></span></a>";
  375. } else {
  376. margin = (21 + level * 17);
  377. returnVal = "<li class='sitemapNode sitemapLeafNode'><div><div class='sitemapPageLinkContainer' style='margin-left:" + margin + "px'>";
  378. }
  379. var isFolder = node.type == "Folder";
  380. if(!isFolder) {
  381. returnVal += "<a class='sitemapPageLink' nodeUrl='" + node.url + "'>";
  382. allNodeUrls.push(node.url);
  383. }
  384. returnVal += "<span class='sitemapPageIcon";
  385. if(node.type == "Flow") { returnVal += " sitemapFlowIcon"; }
  386. if(isFolder) {
  387. if(hasChildren) returnVal += " sitemapFolderOpenIcon";
  388. else returnVal += " sitemapFolderIcon";
  389. }
  390. returnVal += "'></span><span class='sitemapPageName'>";
  391. returnVal += $('<div/>').text(node.pageName).html();
  392. returnVal += "</span>";
  393. if(!isFolder) returnVal += "</a>";
  394. returnVal += "</div></div>";
  395. if(hasChildren) {
  396. returnVal += "<ul>";
  397. for(var i = 0; i < node.children.length; i++) {
  398. var child = node.children[i];
  399. returnVal += generateNode(child, level + 1);
  400. }
  401. returnVal += "</ul>";
  402. }
  403. returnVal += "</li>";
  404. return returnVal;
  405. }
  406. })();