page_notes.js 21 KB

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