coder_app.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. /* Copyright 2013-2018 The MathWorks, Inc. */
  2. function queryByClassName(className, elem) {
  3. if (!elem) elem = document.body;
  4. if (typeof elem.querySelectorAll === "function") {
  5. return elem.querySelectorAll("."+className);
  6. } else {
  7. return elem.getElementsByClass(className);
  8. }
  9. }
  10. function nav_token_usage_details(direction) {
  11. var els = queryByClassName("token_usage_details_tabrow");
  12. var selectedIdx = 0;
  13. var selectedClassName = "selected";
  14. for (selectedIdx; selectedIdx < els.length; selectedIdx++) {
  15. if (els[selectedIdx].classList.contains(selectedClassName)) {
  16. break;
  17. }
  18. }
  19. var nextIdx = selectedIdx;
  20. if (direction === -1 && selectedIdx > 0) {
  21. nextIdx = selectedIdx-1;
  22. } else if (direction === 1 && selectedIdx < els.length - 1) {
  23. nextIdx = selectedIdx + 1;
  24. }
  25. if (nextIdx !== selectedIdx) {
  26. els[selectedIdx].classList.remove(selectedClassName);
  27. els[nextIdx].classList.add(selectedClassName);
  28. els[nextIdx].scrollIntoView(alignWithTop=false);
  29. }
  30. return false;
  31. }
  32. function tabrowClicked(event) {
  33. }
  34. function popupOnload() {
  35. var els = queryByClassName("token_usage_details_tabrow");
  36. for (var i=0; i<els.length; i++) {
  37. els[i].onclick= tabrowClicked;
  38. }
  39. };
  40. function tokenOnRightclick(event) {
  41. var filename = location.pathname.split(/\//);
  42. filename = filename[filename.length-1];
  43. top.inspectToken(filename, location.pathname, event);
  44. top.hiliteClickedToken(event.currentTarget);
  45. return false;
  46. }
  47. function tokenOnclick(event) {
  48. tokenOnRightclick(event);
  49. if (event.currentTarget.href.length !== 0 && event.currentTarget.href.protocol !== "matlab:") {
  50. top.tokenLinkOnClick(event);
  51. return true;
  52. }
  53. return false;
  54. };
  55. function tokenOnMouseOver(event) {
  56. var filename = location.pathname.split(/\//);
  57. filename = filename[filename.length-1];
  58. createPopup(filename, event);
  59. };
  60. function tokenOnMouseOut(event) {
  61. destroyPopup(event.currentTarget);
  62. };
  63. function blkLinkOnClick(event) {
  64. top.hiliteClickedToken(event.currentTarget);
  65. return true;
  66. }
  67. function clearTokenLink(id) {
  68. var codeElement = document.getElementById(id);
  69. var els = queryByClassName("tk", codeElement);
  70. var elem;
  71. if (top.CodeDefine && top.CodeDefine.instance) {
  72. for (var i=0; i<els.length; i++) {
  73. var re = new RegExp('active', 'g');
  74. els[i].className = els[i].className.replace(re, '');
  75. re = new RegExp('traceable_token', 'g');
  76. els[i].className = els[i].className.replace(re, '');
  77. }
  78. }
  79. }
  80. function updateTokenLink(id) {
  81. var codeElement = document.getElementById(id);
  82. var filename = location.pathname.split(/\//);
  83. filename = filename[filename.length-1];
  84. var srcFilename;
  85. if (top.RTW_TraceInfo) {
  86. srcFilename = top.RTW_TraceInfo.toSrcFileName(filename);
  87. }
  88. var els = queryByClassName("tk", codeElement);
  89. var elem;
  90. var hasTraceFlag = null;
  91. if (top.TraceInfoFlag && top.TraceInfoFlag.instance)
  92. hasTraceFlag = top.TraceInfoFlag.instance.traceFlag;
  93. else
  94. hasTraceFlag = false;
  95. var defObj;
  96. var traceObj;
  97. var codeDef = (top.CodeDefine && top.CodeDefine.instance) ? top.CodeDefine.instance : null;
  98. var aLink = top.document.createElement("a");
  99. if (hasTraceFlag || (top.CodeDefine && top.CodeDefine.instance)) {
  100. for (var i=0; i<els.length; i++) {
  101. defObj = null;
  102. if (codeDef) {
  103. if (codeDef.def.hasOwnProperty(srcFilename + ":" + els[i].text)) {
  104. defObj = codeDef.def[srcFilename + ":" + els[i].text];
  105. } else if (codeDef.def.hasOwnProperty(els[i].text)) {
  106. defObj = codeDef.def[els[i].text];
  107. }
  108. }
  109. traceObj = hasTraceFlag && hasTraceFlag[srcFilename+":"+els[i].id];
  110. if (traceObj || defObj) {
  111. els[i].onclick= tokenOnclick;
  112. els[i].oncontextmenu= tokenOnRightclick;
  113. els[i].onmouseover = tokenOnMouseOver;
  114. els[i].onmouseout = tokenOnMouseOut;
  115. els[i].className += " active";
  116. els[i].target = "rtwreport_document_frame";
  117. if (traceObj && top.reportModel) {
  118. if (top.testHarnessInfo && top.testHarnessInfo.IsTestHarness==="1") {
  119. els[i].href = "matlab:rtw.report.code2model('" + top.reportModel
  120. + "','" + location.pathname + "','" + els[i].id
  121. + "','" + top.testHarnessInfo.HarnessName
  122. + "','" + top.testHarnessInfo.HarnessOwner
  123. + "','" + top.testHarnessInfo.OwnerFileName + "')";
  124. } else {
  125. els[i].href = "matlab:rtw.report.code2model(\'" + top.reportModel
  126. + "\',\'" + location.pathname + "\',\'" + els[i].id + "')";
  127. }
  128. } else {
  129. aLink.href = defObj.file;
  130. els[i].href = aLink.pathname + "#" + defObj.line;
  131. }
  132. }
  133. }
  134. }
  135. }
  136. // remove the code table; insert back
  137. function updateToken(codeElement) {
  138. var filename = location.pathname.split(/\//);
  139. filename = filename[filename.length-1];
  140. var srcFilename;
  141. if (top.RTW_TraceInfo) {
  142. srcFilename = top.RTW_TraceInfo.toSrcFileName(filename);
  143. }
  144. // update block path link in comments
  145. els = queryByClassName("blk", codeElement);
  146. var lineSid = null;
  147. if (top.RTW_rtwnameSIDMap && top.RTW_rtwnameSIDMap.instance) {
  148. for (var i=0; i<els.length; i++) {
  149. lineSid = top.RTW_rtwnameSIDMap.instance.getSID(els[i].text);
  150. if (lineSid) {
  151. if (top.testHarnessInfo && top.testHarnessInfo.IsTestHarness==="1") {
  152. els[i].href = "matlab:coder.internal.code2model('" + lineSid.sid + "','" +
  153. top.testHarnessInfo.HarnessName+ "','" +
  154. top.testHarnessInfo.HarnessOwner+ "','" +
  155. top.testHarnessInfo.OwnerFileName + "');";
  156. } else {
  157. els[i].href = "matlab:coder.internal.code2model('" + lineSid.sid + "');";
  158. }
  159. els[i].id = "blkLink_" + i;
  160. els[i].onclick = blkLinkOnClick;
  161. els[i].className += " blk_active";
  162. }
  163. }
  164. }
  165. // update lib block path link in comments
  166. els = queryByClassName("libblk", codeElement);
  167. var lineSid = null;
  168. for (var i=0; i<els.length; i++) {
  169. lineSid = els[i].text;
  170. if (lineSid) {
  171. if (top.testHarnessInfo && top.testHarnessInfo.IsTestHarness==="1") {
  172. els[i].href = "matlab:coder.internal.code2model('" + lineSid + "','" +
  173. top.testHarnessInfo.HarnessName+ "','" +
  174. top.testHarnessInfo.HarnessOwner+ "','" +
  175. top.testHarnessInfo.OwnerFileName + "');";
  176. } else {
  177. els[i].href = "matlab:coder.internal.code2model('" + lineSid + "');";
  178. }
  179. els[i].id = "blkLink_" + i;
  180. els[i].onclick = blkLinkOnClick;
  181. els[i].className += " blk_active";
  182. }
  183. }
  184. // update requirement link in comments
  185. els = queryByClassName("req", codeElement);
  186. var req_block;
  187. if (top.RTW_rtwnameSIDMap && top.RTW_rtwnameSIDMap.instance) {
  188. for (var i=0; i<els.length; i++) {
  189. lineSid = top.RTW_rtwnameSIDMap.instance.getSID(els[i].getAttribute("blockpath"));
  190. if (lineSid) {
  191. req_block = lineSid.sid;
  192. } else {
  193. req_block = els[i].getAttribute("blockpath");
  194. }
  195. var req_id = els[i].getAttribute("req_id");
  196. els[i].href = "matlab:rtw.report.code2req('" + req_block + "'," + req_id + ");";
  197. els[i].id = "req_" + i;
  198. els[i].onclick = top.reqOnClick;
  199. els[i].className += " req_active";
  200. }
  201. }
  202. // add link to source file
  203. if (top.Html2SrcLink && top.Html2SrcLink.instance) {
  204. filename = top.rtwGetFileName(location.href);
  205. var link2Src = top.Html2SrcLink.instance.getLink2Src(filename);
  206. var link = document.createElement("h4");
  207. link.innerHTML = "File: <a href=\"" + link2Src +
  208. "\" target = \"rtwreport_document_frame\" id=\"linkToText_plain\">" +
  209. top.rtwGetFileName(link2Src) + "</a>";
  210. var bodyNode = document.body;
  211. bodyNode.insertBefore(link, bodyNode.firstElementChild);
  212. }
  213. top.updateHyperlinks();
  214. // update fileSelector frame
  215. if (top.fileSelector) {
  216. var o = top.fileSelector.document.getElementById('fileSelector');
  217. if (o) {
  218. o.value = filename;
  219. }
  220. }
  221. // add links to line numbers
  222. var hasLineFlag = null;
  223. if (top.TraceInfoLineFlag && top.TraceInfoLineFlag.instance) {
  224. hasLineFlag = true;
  225. } else {
  226. hasLineFlag = false;
  227. }
  228. if(hasLineFlag) {
  229. var lines = queryByClassName("ln", codeElement);
  230. var lineTraceFlag = top.TraceInfoLineFlag.instance.lineTraceFlag;
  231. var lineNo = null;
  232. for (var i=0; i<lines.length; i++) {
  233. lineNo = lines[i].id.substring(1)
  234. if(lineTraceFlag[srcFilename+":"+ lineNo]) {
  235. lines[i].className += " active";
  236. if (top.testHarnessInfo && top.testHarnessInfo.IsTestHarness==="1") {
  237. lines[i].href = "matlab:rtw.report.code2model('" + top.reportModel
  238. + "','" + srcFilename
  239. + "','" + lineNo
  240. + "','" + top.testHarnessInfo.HarnessName
  241. + "','" + top.testHarnessInfo.HarnessOwner
  242. + "','" + top.testHarnessInfo.OwnerFileName + "')";
  243. } else {
  244. lines[i].href = "matlab:rtw.report.code2model('" + top.reportModel
  245. + "','" + srcFilename + "','" + lineNo + "')";
  246. }
  247. }
  248. }
  249. }
  250. }
  251. function getInsertFunction(element) {
  252. var parentNode = element.parentNode;
  253. var nextSibling = element.nextSibling;
  254. parentNode.removeChild(element);
  255. var spinner = document.createElement("img");
  256. spinner.src = "spinner.gif";
  257. parentNode.appendChild(spinner);
  258. return function() {
  259. if (spinner) {
  260. parentNode.removeChild(spinner);
  261. }
  262. if (nextSibling) {
  263. parentNode.insertBefore(element, nextSibling);
  264. } else {
  265. parentNode.appendChild(element);
  266. }
  267. };
  268. }
  269. var hovered_line = '';
  270. var lineOnMouseIn = function (id) {
  271. if (hovered_line !== id) {
  272. hovered_line = id;
  273. updateTokenLink(id);
  274. }
  275. }
  276. var lineOnMouseOut = function (id) {
  277. clearTokenLink(id);
  278. hovered_line = '';
  279. }
  280. function registerDelayedOnMouseOver(elm, onMouseIn, onMouseOut) {
  281. var delay = function (elem, onMouseIn, onMouseOut) {
  282. var timeout = null;
  283. elem.onmouseover = function(e) {
  284. timeout = setTimeout(onMouseIn, 200, e.currentTarget.id);
  285. };
  286. elem.onmouseout = function(e) {
  287. clearTimeout(timeout);
  288. if (hovered_line !== '') {
  289. onMouseOut(e.currentTarget.id);
  290. }
  291. }
  292. };
  293. delay(elm, onMouseIn, onMouseOut);
  294. }
  295. // Returns true if obj has all the fields in criteria and obj's values (as strings)
  296. // are present in criteria's values
  297. function matchCriteria(obj, criteria) {
  298. for (var prop in criteria) {
  299. if (!obj.hasOwnProperty(prop) || String(obj[prop]).toUpperCase().indexOf(String(criteria[prop]).toUpperCase()) === -1) {
  300. return false;
  301. }
  302. }
  303. return true;
  304. }
  305. function findParent(node, criteria) {
  306. if (!node) {
  307. return null;
  308. }
  309. else if (matchCriteria(node, criteria)) {
  310. return node;
  311. }
  312. else {
  313. return findParent(node.parentNode, criteria);
  314. }
  315. }
  316. function getLastTableCellContents(trNode) {
  317. for (var i = trNode.childNodes.length - 1; i >= 0; --i) {
  318. var childNode = trNode.childNodes[i];
  319. if (childNode.tagName.toUpperCase() === "TD") {
  320. return childNode.childNodes;
  321. }
  322. }
  323. return null;
  324. }
  325. // see g1225075
  326. function fixBoxStyleFnHeaderLineWidths() {
  327. // Match strings like "/**********/" which is the top line of
  328. // a box-style function comment header
  329. var reBoxHeader = /\/\*+\//;
  330. // Match strings like "' */" which is the contents of the text
  331. // element originally generated in the report to pad the width of
  332. // the line.
  333. var rePadding = /'\s*\*\//;
  334. // All block identifier elements in the report page
  335. blkLineElts = queryByClassName("blk");
  336. for (var i = 0; i < blkLineElts.length; ++i) {
  337. var origPadding = blkLineElts[i].nextSibling;
  338. if (origPadding.textContent.match(rePadding)) {
  339. var spanElt = findParent(blkLineElts[i], { tagName: "span", className: "ct" });
  340. if (!spanElt) {
  341. continue;
  342. }
  343. // The numbered line in the report containing block identifier "i"
  344. var tableRowElt = findParent(spanElt, { tagName: "tr" });
  345. if (!tableRowElt) {
  346. continue;
  347. }
  348. // Loop backward through table rows (i.e., report lines) looking
  349. // for the "/***************/" start of the header. When found save
  350. // its pixel width. Not actually the width of the <tr> itself but
  351. // the span inside its last <td>. This is will determine the real
  352. // padding that is needed for proper alignment regardless of font
  353. // or CKJ characters.
  354. var targetWidth = 0;
  355. var sanity = Number.MAX_VALUE;
  356. var node = tableRowElt.previousSibling;
  357. while (node && (sanity-- > 0)) {
  358. var lastCellContents = getLastTableCellContents(node);
  359. if (lastCellContents) {
  360. if (lastCellContents.length === 0) {
  361. break;
  362. }
  363. if (lastCellContents[0].textContent.match(reBoxHeader)) {
  364. targetWidth = lastCellContents[0].offsetWidth;
  365. break;
  366. }
  367. }
  368. node = node.previousSibling;
  369. }
  370. // If applying a new padding (i.e., targetWidth > 0), replace
  371. // the original padding "' */' (a single text element) with
  372. // two text elements and a span in between. The span will be the
  373. // new pixel-accurate padding.
  374. if (targetWidth > 0) {
  375. var singleQuoteNode = document.createTextNode("'");
  376. var spacerNode = document.createElement('span');
  377. origPadding.textContent = "*/";
  378. origPadding.parentNode.insertBefore(spacerNode, origPadding);
  379. origPadding.parentNode.insertBefore(singleQuoteNode, spacerNode);
  380. var padWidth = targetWidth - spanElt.offsetWidth;
  381. spacerNode.style.display = 'inline-block';
  382. spacerNode.style.width = String(padWidth) + "px";
  383. spacerNode.style.height = '1em'; // cursor won't work w/o some height
  384. spacerNode.style.cursor = 'text';
  385. }
  386. }
  387. }
  388. }
  389. // the onload function for source file
  390. function srcFileOnload() {
  391. var codeElement = document.getElementById("codeTbl");
  392. var insertFunction = getInsertFunction(codeElement);
  393. try {
  394. var els = codeElement.getElementsByTagName("tr");
  395. for (var i = 0; i < els.length; i++) {
  396. registerDelayedOnMouseOver(els[i], lineOnMouseIn, lineOnMouseOut);
  397. }
  398. updateToken(codeElement);
  399. } catch (err) {};
  400. insertFunction();
  401. // add code to model hyperlinks for all tokens
  402. var filename = location.pathname.split(/\//);
  403. filename = filename[filename.length-1];
  404. // highlight the filename in the TOC frame
  405. if (top.rtwreport_contents_frame && top.hiliteByFileName(top.rtwreport_document_frame.document.location.href)) {
  406. // remove the highlights in the TOC frame if filename is hilite successfully
  407. top.removeHiliteTOC(top.rtwreport_contents_frame);
  408. }
  409. // annotate code with code coverage data
  410. if (typeof rtwannotate === 'function') {
  411. rtwannotate(filename.replace(/.html$/,"_cov.xml"));
  412. }
  413. fixBoxStyleFnHeaderLineWidths();
  414. // highlight token and row
  415. if (top.RTW_TraceInfo.instance && top.RTW_TraceArgs.instance) {
  416. var i;
  417. // find the highlight file name
  418. var fileIdx = top.RTW_TraceArgs.instance.getFileIdx(filename);
  419. var ids=[], rows=[];
  420. if (typeof fileIdx !== "undefined") {
  421. ids = top.RTW_TraceArgs.instance.getIDs(fileIdx);
  422. rows = top.RTW_TraceArgs.instance.getRows(fileIdx);
  423. // highlight rows in file
  424. for (i=0; i<rows.length;i++) {
  425. elem = top.rtwreport_document_frame.document.getElementById(rows[i]);
  426. if (elem) elem.className += " hilite";
  427. }
  428. // highlight tokens in file
  429. if (top.GlobalConfig.hiliteToken) {
  430. for (i=0; i<ids.length;i++) {
  431. elem = top.rtwreport_document_frame.document.getElementById(ids[i]);
  432. if (elem) elem.className += " hilite";
  433. }
  434. }
  435. } // end of if current file has highlighted lines
  436. // if the loaded file is not currFile, call setInitLocation
  437. var currFileIdx = top.RTW_TraceInfo.instance.getCurrFileIdx();
  438. var myFileIdx = top.RTW_TraceInfo.instance.getFileIdx(filename);
  439. // update navigation status if the file is loaded first time
  440. if (currFileIdx !== myFileIdx && document.location.hash === "") {
  441. if (rows.length > 0)
  442. top.RTW_TraceInfo.instance.setInitLocation(filename,rows[0]);
  443. else {
  444. top.toggleNavSideBar("off");
  445. return;
  446. }
  447. }
  448. // display navigation side bar
  449. if (top.rtwreport_nav_frame) top.rtwreport_nav_frame.location.reload();
  450. if (rows.length>0) {
  451. top.toggleNavSideBar("on");
  452. top.toggleNavToolBar("on");
  453. } else {
  454. top.toggleNavSideBar("off");
  455. }
  456. }
  457. top.scrollToLineBasedOnHash(document.location.hash);
  458. function getHash() {
  459. var loc;
  460. var aHash="";
  461. var topDocObj = top.window.document;
  462. // get the hash value from location.
  463. loc = topDocObj.location;
  464. loc = loc.search || loc.hash;
  465. aHash = loc.substring(1);
  466. aHash = decodeURI(aHash);
  467. return aHash;
  468. }
  469. }
  470. function createPopup(filename, evt) {
  471. var anchorObj = evt.currentTarget;
  472. if (anchorObj.children.length > 0)
  473. return;
  474. var filename = location.pathname.split(/\//);
  475. filename = filename[filename.length-1];
  476. var windowObj = top.getInspectWindow();
  477. var propObj = top.getInspectData(filename, anchorObj);
  478. var navObj = top.getInspectLink(filename, location.pathname, anchorObj);
  479. if (propObj) {
  480. windowObj.appendChild(propObj);
  481. windowObj.style.left = "0px";
  482. if (anchorObj.parentElement.nodeName === "TD" &&
  483. anchorObj.parentElement.parentElement.nodeName === "TR") {
  484. anchorObj.parentElement.parentElement.lastChild.insertBefore(windowObj,
  485. anchorObj.parentElement.parentElement.lastChild.lastChild.nextSibling);
  486. var left = Math.min(evt.clientX , window.innerWidth - windowObj.scrollWidth - 30);
  487. left = Math.max(0, left);
  488. windowObj.style.left = "" + left + "px";
  489. }
  490. }
  491. };
  492. function destroyPopup(anchorObj) {
  493. var popWindow = document.getElementById("popup_window");
  494. if (popWindow) {
  495. popWindow.parentElement.removeChild(popWindow);
  496. }
  497. };