page_notes.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. // use this to isolate the scope
  2. (function () {
  3. // No notes shown specified by generation config
  4. if (!$axure.document.configuration.showPageNotes && !$axure.document.configuration.showAnnotationsSidebar && !$axure.document.configuration.showAnnotations) { return; }
  5. $(window.document).ready(function () {
  6. // Load right panel for Page Notes
  7. if ($axure.document.configuration.showPageNotes || $axure.document.configuration.showAnnotationsSidebar) {
  8. $axure.player.createPluginHost({
  9. id: 'pageNotesHost',
  10. context: 'inspect',
  11. title: 'Notes',
  12. gid: 2,
  13. });
  14. }
  15. // Load footnotes on widgets
  16. if ($axure.document.configuration.showAnnotations) {
  17. $('#overflowMenuContainer').prepend('<div id="showNotesOption" class="showOption" style="order: 3"><div class="overflowOptionCheckbox"></div>Show Note Markers</div>');
  18. }
  19. createNotesOverlay();
  20. generatePageNotes();
  21. if ($axure.player.isMobileMode()) {
  22. $('#showNotesOption').hide();
  23. } else {
  24. $('#showNotesOption').click(footnotes_click);
  25. $('#showNotesOption').find('.overflowOptionCheckbox').addClass('selected');
  26. }
  27. function escapeXSS(htmlStr) {
  28. return htmlStr.replace(/&/g, "&amp;")
  29. .replace(/</g, "&lt;")
  30. .replace(/>/g, "&gt;")
  31. .replace(/"/g, "&quot;")
  32. .replace(/'/g, "&#39;");
  33. }
  34. function populateNotes(pageForNotes) {
  35. var hasNotes = false;
  36. if ($axure.document.configuration.showPageNotes) {
  37. var pageNoteUi = '';
  38. function populatePageNotes(pageOrMaster) {
  39. //populate the page notes
  40. var notes = pageOrMaster.notes;
  41. if (notes && !$.isEmptyObject(notes)) {
  42. pageNoteUi += "<div class='notesPageNameHeader'>" + escapeXSS(pageOrMaster.pageName) + "</div>";
  43. var showNames = $axure.document.configuration.showPageNoteNames;
  44. for(var noteName in notes) {
  45. pageNoteUi += "<div class='pageNoteContainer'>";
  46. if(showNames) {
  47. pageNoteUi += "<div class='pageNoteName'>" + noteName + "</div>";
  48. }
  49. pageNoteUi += "<div class='pageNote'>" + linkify(notes[noteName]) + "</div>";
  50. pageNoteUi += "</div>";
  51. //$('#pageNotesContent').append(pageNoteUi);
  52. hasNotes = true;
  53. }
  54. }
  55. }
  56. populatePageNotes(pageForNotes);
  57. if (pageForNotes.masterNotes) {
  58. for (var i = 0; i < pageForNotes.masterNotes.length; i++) {
  59. populatePageNotes(pageForNotes.masterNotes[i]);
  60. }
  61. }
  62. if (pageNoteUi.length > 0) {
  63. pageNoteUi += "<div class='lineDivider'></div>";
  64. var pageNotesHeader = "<div id='pageNotesSectionHeader' class='notesSectionHeader pluginNameHeader'>Page Notes</div>";
  65. $('#pageNotesContent').append(pageNotesHeader + pageNoteUi);
  66. }
  67. }
  68. if ($axure.document.configuration.showAnnotationsSidebar) {
  69. var widgetNoteUi = '';
  70. //var widgetNotes = pageForNotes.widgetNotes;
  71. function populateWidgetNotes(widgetNotes){
  72. if (widgetNotes) {
  73. for (var i = 0; i < widgetNotes.length; i++) {
  74. var widgetNote = widgetNotes[i];
  75. widgetNoteUi += "<div class='widgetNoteContainer' data-id='" + widgetNote["ownerId"] + "'>";
  76. widgetNoteUi += "<div class='widgetNoteFootnote'>" + widgetNote["fn"] + "</div>";
  77. widgetNoteUi += "<div class='widgetNoteLabel'>" + widgetNote["label"] + "</div>";
  78. for (var widgetNoteName in widgetNote) {
  79. if (widgetNoteName != "label" && widgetNoteName != "fn" && widgetNoteName != "ownerId") {
  80. widgetNoteUi += "<div class='pageNoteName'>" + widgetNoteName + "</div>";
  81. widgetNoteUi += "<div class='pageNote'>" + linkify(widgetNote[widgetNoteName]) + "</div>";
  82. //widgetNoteUi += "<div class='nondottedDivider'></div>";
  83. }
  84. }
  85. widgetNoteUi += "</div>";
  86. //widgetNoteUi += "<div class='nondottedDivider'></div>";
  87. //$('#pageNotesContent').append(widgetNoteUi);
  88. hasNotes = true;
  89. }
  90. }
  91. }
  92. populateWidgetNotes(pageForNotes.widgetNotes);
  93. if (pageForNotes.masterNotes) {
  94. for (var i = 0; i < pageForNotes.masterNotes.length; i++) {
  95. populateWidgetNotes(pageForNotes.masterNotes[i].widgetNotes);
  96. }
  97. }
  98. if (widgetNoteUi.length > 0) {
  99. var widgetNotesHeader = "<div id='widgetNotesSectionHeader' class='notesSectionHeader pluginNameHeader'>Widget Notes</div>";
  100. $('#pageNotesContent').append(widgetNotesHeader + widgetNoteUi);
  101. //$('.widgetNoteContainer').children(':last-child').remove();
  102. //$('.widgetNoteFootnote').append("<div class='annnoteline'></div><div class='annnoteline'></div><div class='annnoteline'></div>");
  103. $('.widgetNoteContainer').click(function () {
  104. var wasSelected = $(this).hasClass('widgetNoteContainerSelected');
  105. $('.widgetNoteContainerSelected').removeClass('widgetNoteContainerSelected');
  106. if (!wasSelected) $(this).addClass('widgetNoteContainerSelected');
  107. var dimStr = $('.currentAdaptiveView').attr('data-dim');
  108. var h = dimStr ? dimStr.split('x')[1] : '0';
  109. var $leftPanel = $('.leftPanel:visible');
  110. var leftPanelOffset = (!$axure.player.isMobileMode() && $leftPanel.length > 0) ? $leftPanel.width() : 0;
  111. var $rightPanel = $('.rightPanel:visible');
  112. var rightPanelOffset = (!$axure.player.isMobileMode() && $rightPanel.length > 0) ? $rightPanel.width() : 0;
  113. var viewDimensions = {
  114. h: h != '0' ? h : '',
  115. scaleVal: $('.vpScaleOption').find('.selectedRadioButton').parent().attr('val'),
  116. height: $('.rightPanel').height(),
  117. panelWidthOffset: leftPanelOffset + rightPanelOffset
  118. };
  119. $axure.messageCenter.postMessage('toggleSelectWidgetNote', { id: this.getAttribute('data-id'), value: !wasSelected, view: viewDimensions});
  120. });
  121. }
  122. //if (pageForNotes.masterNotes) {
  123. // for (var i = 0; i < pageForNotes.masterNotes.length; i++) {
  124. // var master = pageForNotes.masterNotes[i];
  125. // hasNotes = populateNotes(master) || hasNotes;
  126. // }
  127. //}
  128. }
  129. return hasNotes;
  130. }
  131. // bind to the page load
  132. $axure.page.bind('load.page_notes', function () {
  133. closeAllDialogs();
  134. var hasNotes = false;
  135. $('#pageNotesContent').html("");
  136. hasNotes = populateNotes($axure.page);
  137. if(hasNotes) $('#pageNotesEmptyState').hide();
  138. else $('#pageNotesEmptyState').show();
  139. //If footnotes enabled for this prototype...
  140. if ($axure.player.isMobileMode()) {
  141. $axure.messageCenter.postMessage('annotationToggle', false);
  142. } else if($axure.document.configuration.showAnnotations == true) {
  143. //If the fn var is defined and set to 0, hide footnotes
  144. //else if hide-footnotes button selected, hide them
  145. var fnVal = $axure.player.getHashStringVar(FOOTNOTES_VAR_NAME);
  146. if(fnVal.length > 0 && fnVal == 0) {
  147. $('#showNotesOption').find('.overflowOptionCheckbox').removeClass('selected');
  148. $axure.messageCenter.postMessage('annotationToggle', false);
  149. } else if(!$('#showNotesOption').find('.overflowOptionCheckbox').hasClass('selected')) {
  150. //If the footnotes button isn't selected, hide them on this loaded page
  151. $axure.messageCenter.postMessage('annotationToggle', false);
  152. }
  153. }
  154. // Get multiple click call if not removing beforehand
  155. $('#notesOverlay').off('click');
  156. $('#notesOverlay').on('click', '.closeNotesDialog', function () {
  157. var ownerId = $(this).attr("data-ownerid");
  158. _toggleAnnDialog(ownerId);
  159. });
  160. $axure.player.updatePlugins();
  161. return false;
  162. });
  163. $axure.messageCenter.addMessageListener(function (message, data) {
  164. //var messageData = { id: elementId, x: event.pageX, y: event.pageY }
  165. if (message == 'toggleAnnDialog') {
  166. _toggleAnnDialog(data.id, data.x, data.y, data.page);
  167. }
  168. });
  169. });
  170. function linkify(text) {
  171. var urlRegex = /(\b(((https?|ftp|file):\/\/)|(www\.))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
  172. return text.replace(urlRegex, function (url, b, c) {
  173. var url2 = (c == 'www.') ? 'http://' + url : url;
  174. return '<a href="' + url2 + '" target="_blank" class="noteLink">' + url + '</a>';
  175. });
  176. }
  177. function getWidgetNotesHtml(ownerId, page) {
  178. var pageForNotes = page || $axure.page;
  179. var widgetNoteUi = '';
  180. widgetNoteUi += "<div data-ownerid='" + ownerId + "' class='closeNotesDialog'></div>";
  181. widgetNoteUi += "<div class='notesDialogScroll'>";
  182. function getNotesForPage(widgetNotes) {
  183. for (var i = 0; i < widgetNotes.length; i++) {
  184. var widgetNote = widgetNotes[i];
  185. if (widgetNote["ownerId"] == ownerId) {
  186. widgetNoteUi += "<div class='widgetNoteContainer' data-id='" + widgetNote["ownerId"] + "'>";
  187. widgetNoteUi += "<div class='widgetNoteFootnote'>" + widgetNote["fn"] + "</div>";
  188. widgetNoteUi += "<div class='widgetNoteLabel'>" + widgetNote["label"] + "</div>";
  189. for (var widgetNoteName in widgetNote) {
  190. if (widgetNoteName != "label" && widgetNoteName != "fn" && widgetNoteName != "ownerId") {
  191. widgetNoteUi += "<div class='pageNoteName'>" + widgetNoteName + "</div>";
  192. widgetNoteUi += "<div class='pageNote'>" + linkify(widgetNote[widgetNoteName]) + "</div>";
  193. }
  194. }
  195. widgetNoteUi += "</div>";
  196. }
  197. }
  198. }
  199. getNotesForPage(pageForNotes.widgetNotes);
  200. if (pageForNotes.masterNotes) {
  201. for (var i = 0; i < pageForNotes.masterNotes.length; i++) {
  202. getNotesForPage(pageForNotes.masterNotes[i].widgetNotes);
  203. }
  204. }
  205. widgetNoteUi += "</div>";
  206. widgetNoteUi += "<div class='resizeNotesDialog'></div>";
  207. return widgetNoteUi;
  208. }
  209. var maxZIndex = 1;
  210. var dialogs = {};
  211. var _toggleAnnDialog = function (id, srcLeft, srcTop, page) {
  212. if(dialogs[id]) {
  213. var $dialog = dialogs[id];
  214. // reset the dialog
  215. dialogs[id] = undefined;
  216. $dialog.find('.notesDialogScroll').getNiceScroll().remove();
  217. $dialog.remove();
  218. return;
  219. }
  220. var bufferH = 10;
  221. var bufferV = 10;
  222. var blnLeft = false;
  223. var blnAbove = false;
  224. var mfPos = $('#mainPanelContainer').position();
  225. var viewablePanelLeftMargin = parseInt($('#mainPanelContainer').css('margin-left'));
  226. var sourceTop = srcTop + mfPos.top;
  227. var sourceLeft = srcLeft + viewablePanelLeftMargin;
  228. var width = 300;
  229. var height = 300;
  230. if(sourceLeft > width + bufferH) {
  231. blnLeft = true;
  232. }
  233. if(sourceTop > height + bufferV) {
  234. blnAbove = true;
  235. }
  236. var top = 0;
  237. var left = 0;
  238. if(blnAbove) top = sourceTop - height - 20;
  239. else top = sourceTop + 10;
  240. if(blnLeft) left = sourceLeft - width - 4;
  241. else left = sourceLeft - 6;
  242. //need to set the zindex
  243. maxZIndex = maxZIndex + 1;
  244. var $dialog = $('<div class="notesDialog"></div>')
  245. .appendTo('#notesOverlay')
  246. .html(getWidgetNotesHtml(id, page));
  247. $dialog.css({ 'left': left, 'top': top, 'z-index': maxZIndex });
  248. $dialog.find('.notesDialogScroll').niceScroll({ cursorcolor: "#8c8c8c", cursorborder: "0px solid #fff" });
  249. $dialog.find('.notesDialogScroll').on($axure.eventNames.mouseDownName, function(event) {
  250. event.stopPropagation();
  251. });
  252. $dialog.find('.closeNotesDialog').on($axure.eventNames.mouseDownName, function (event) {
  253. event.stopPropagation();
  254. });
  255. $dialog.on($axure.eventNames.mouseDownName, startDialogMove);
  256. var startMouseX;
  257. var startMouseY;
  258. var startDialogX;
  259. var startDialogY;
  260. function startDialogMove() {
  261. startMouseX = window.event.pageX;
  262. startMouseY = window.event.pageY;
  263. var position = $dialog.position();
  264. startDialogX = position.left;
  265. startDialogY = position.top;
  266. $dialog.addClass('active');
  267. $('<div class="splitterMask"></div>').insertAfter($('#notesOverlay'));
  268. $(document).bind($axure.eventNames.mouseMoveName, doDialogMove).bind($axure.eventNames.mouseUpName, endDialogMove);
  269. $dialog.find('.notesDialogScroll').getNiceScroll().hide();
  270. }
  271. function doDialogMove() {
  272. var currentX = window.event.pageX;
  273. var currentY = window.event.pageY;
  274. $dialog.css({ 'left': startDialogX + currentX - startMouseX, 'top': startDialogY + currentY - startMouseY });
  275. }
  276. function endDialogMove() {
  277. $('div.splitterMask').remove();
  278. $dialog.removeClass('active');
  279. $(document).unbind($axure.eventNames.mouseMoveName, doDialogMove).unbind($axure.eventNames.mouseUpName, endDialogMove);
  280. $dialog.find('.notesDialogScroll').getNiceScroll().resize();
  281. $dialog.find('.notesDialogScroll').getNiceScroll().show();
  282. }
  283. $dialog.find('.resizeNotesDialog').on($axure.eventNames.mouseDownName, startDialogResize);
  284. var startDialogW;
  285. var startDialogH;
  286. function startDialogResize() {
  287. event.stopPropagation();
  288. startMouseX = window.event.pageX;
  289. startMouseY = window.event.pageY;
  290. startDialogW = Number($dialog.css('width').replace('px',''));
  291. startDialogH = Number($dialog.css('height').replace('px', ''));
  292. $dialog.addClass('active');
  293. $('<div class="splitterMask"></div>').insertAfter($('#notesOverlay'));
  294. $(document).bind($axure.eventNames.mouseMoveName, doDialogResize).bind($axure.eventNames.mouseUpName, endDialogResize);
  295. $dialog.find('.notesDialogScroll').getNiceScroll().hide();
  296. }
  297. function doDialogResize() {
  298. var currentX = window.event.pageX;
  299. var currentY = window.event.pageY;
  300. var newWidth = Math.max(200, startDialogW + currentX - startMouseX);
  301. var newHeight = Math.max(200, startDialogH + currentY - startMouseY);
  302. $dialog.css({ 'width': newWidth, 'height': newHeight });
  303. }
  304. function endDialogResize() {
  305. $('div.splitterMask').remove();
  306. $dialog.removeClass('active');
  307. $(document).unbind($axure.eventNames.mouseMoveName, doDialogResize).unbind($axure.eventNames.mouseUpName, endDialogResize);
  308. $dialog.find('.notesDialogScroll').getNiceScroll().resize();
  309. $dialog.find('.notesDialogScroll').getNiceScroll().show();
  310. }
  311. dialogs[id] = $dialog;
  312. // scroll ... just for IE
  313. //window.scrollTo(scrollX, scrollY);
  314. };
  315. $(document).on('sidebarCollapse', function (event, data) {
  316. clearSelection();
  317. });
  318. $(document).on('pluginShown', function (event, data) {
  319. if(data != 2) {
  320. clearSelection();
  321. }
  322. });
  323. function clearSelection() {
  324. var selectedNote = $('#pageNotesContainer').find('.widgetNoteContainerSelected');
  325. if(selectedNote.length > 0) {
  326. selectedNote.removeClass('widgetNoteContainerSelected');
  327. //var dimStr = $('.currentAdaptiveView').attr('data-dim');
  328. //var h = dimStr ? dimStr.split('x')[1] : '0';
  329. //var $leftPanel = $('.leftPanel:visible');
  330. //var leftPanelOffset = (!$axure.player.isMobileMode() && $leftPanel.length > 0) ? $leftPanel.width() : 0;
  331. //var $rightPanel = $('.rightPanel:visible');
  332. //var rightPanelOffset = (!$axure.player.isMobileMode() && $rightPanel.length > 0) ? $rightPanel.width() : 0;
  333. //var viewDimensions = {
  334. // h: h != '0' ? h : '',
  335. // scaleVal: $('.vpScaleOption').find('.selectedRadioButton').parent().attr('val'),
  336. // scrollLeft: $('#clipFrameScroll').scrollLeft(),
  337. // scrollTop: $('#clipFrameScroll').scrollTop(),
  338. // height: $('.rightPanel').height(),
  339. // panelWidthOffset: leftPanelOffset + rightPanelOffset
  340. //};
  341. //$axure.messageCenter.postMessage('toggleSelectWidgetNote', { id: '', value: false, view: viewDimensions });
  342. $axure.messageCenter.postMessage('toggleSelectWidgetNote', { id: '', value: false });
  343. //$axure.messageCenter.postMessage('toggleSelectWidgetNote', '');
  344. }
  345. }
  346. function closeAllDialogs() {
  347. for (var id in dialogs) {
  348. var $dialog = dialogs[id];
  349. if ($dialog !== undefined) _toggleAnnDialog(id);
  350. }
  351. }
  352. $axure.player.toggleFootnotes = function(val) {
  353. var scaleCheckDiv = $('#showNotesOption').find('.overflowOptionCheckbox');
  354. if (scaleCheckDiv.hasClass('selected')) {
  355. if (!val) $('#showNotesOption').click();
  356. } else {
  357. if (val) $('#showNotesOption').click();
  358. }
  359. }
  360. function footnotes_click(event) {
  361. var scaleCheckDiv = $('#showNotesOption').find('.overflowOptionCheckbox');
  362. if (scaleCheckDiv.hasClass('selected')) {
  363. closeAllDialogs();
  364. scaleCheckDiv.removeClass('selected');
  365. $axure.messageCenter.postMessage('annotationToggle', false);
  366. //Add 'fn' hash string var so that footnotes stay hidden across reloads
  367. $axure.player.setVarInCurrentUrlHash(FOOTNOTES_VAR_NAME, 0);
  368. } else {
  369. scaleCheckDiv.addClass('selected');
  370. $axure.messageCenter.postMessage('annotationToggle', true);
  371. //Delete 'fn' hash string var if it exists since default is visible
  372. $axure.player.deleteVarFromCurrentUrlHash(FOOTNOTES_VAR_NAME);
  373. }
  374. }
  375. function createNotesOverlay() {
  376. var $targetPanel = $('#clippingBounds');
  377. if (!$('#notesOverlay').length) {
  378. var notesOverlay = document.createElement('div');
  379. notesOverlay.setAttribute('id', 'notesOverlay');
  380. $targetPanel.prepend(notesOverlay);
  381. $(notesOverlay).append('&nbsp;');
  382. }
  383. }
  384. function generatePageNotes() {
  385. var pageNotesUi = "<div id='pageNotesHeader'>";
  386. pageNotesUi += "<div id='pageNotesToolbar' style='height: 10px;'>";
  387. pageNotesUi += "</div>";
  388. pageNotesUi += "</div>";
  389. pageNotesUi += "<div id='pageNotesScrollContainer'>";
  390. pageNotesUi += "<div id='pageNotesContainer'>";
  391. pageNotesUi += "<div id='pageNotesEmptyState' class='emptyStateContainer'><div class='emptyStateTitle'>No notes for this page.</div><div class='emptyStateContent'>Notes added in Axure RP will appear here.</div><div class='dottedDivider'></div></div>";
  392. pageNotesUi += "<span id='pageNotesContent'></span>";
  393. pageNotesUi += "</div></div>";
  394. $('#pageNotesHost').append(pageNotesUi);
  395. if(!$axure.document.configuration.showAnnotations) {
  396. $('#pageNotesHost .pageNameHeader').css('padding-right', '55px');
  397. }
  398. }
  399. })();