PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/AutoHotkey.docset/Contents/Resources/Documents/static/source/main.js

https://gitlab.com/ahkscript/Autohotkey.docset
JavaScript | 424 lines | 381 code | 24 blank | 19 comment | 7 complexity | 5276de446e52879682b3d4ab101550d7 MD5 | raw file
  1. if (!IsInsideCHM() && !IsSearchBot())
  2. {
  3. BuildStructure();
  4. AddContent();
  5. }
  6. $(document).ready(AddChmAndOnlineFeatures);
  7. function GetWorkingDir()
  8. {
  9. var wDir = '';
  10. var pathArray = GetScriptDir().split('/');
  11. for (i = 0; i < pathArray.length - 1; i++)
  12. wDir += pathArray[i] + "/";
  13. return wDir.substr(0, wDir.lastIndexOf('/'));
  14. }
  15. function GetScriptDir()
  16. {
  17. var scriptPath = '';
  18. var scriptEls = document.getElementsByTagName('script');
  19. for (i = 0; i < scriptEls.length; i++)
  20. if (scriptEls[i].src)
  21. scriptPath = scriptEls[i].src;
  22. return scriptPath.substr(0, scriptPath.lastIndexOf('/'));
  23. }
  24. function BuildStructure()
  25. {
  26. var wDir = GetWorkingDir();
  27. var header = '<div class="header"><table class="hdr-table"><tr><td class="hdr-image"><a href="' + wDir + '/"><img src="' + wDir + '/static/ahk_logo_no_text.png" width="217" height="70" alt="AutoHotkey"></a></td><td class="hdr-search"><form id="search-form"><input id="q" size="30" type="text" placeholder="' + translate.hdSearchTxt + '"></form><div id="search-btn">' + translate.hdSearchBtn + '</div></td><td class="hdr-language"><ul><li>Language<ul class="second"><li id="lng-btn-en">English</li><li id="lng-btn-de">Deutsch</li><li id="lng-btn-cn">&#20013;&#25991;</li></ul></li></ul></td></tr></table></div>';
  28. var main_1 = '<div class="main-content"><div id="app-body"><div id="headerbar"></div><div class="left-col"><ul class="nav"><li id="sb_content" class="selected"><span>' + translate.sbContent + '</span></li><li id="sb_index"><span>' + translate.sbIndex + '</span></li></ul><div id="sidebar"></div><div id="keywords" style="display: none;"><input id="IndexEntry" type="text"><select id="indexcontainer" name="IndexListbox" class="docstyle" size="20"></select></div></div><div class="right-col"><div id="main-content">';
  29. var main_2 = '</div></div><div class="float-clear"></div></div></div>';
  30. var footer = '<div class="footer"><b>Copyright</b> &copy; 2003-' + new Date().getFullYear() + ' ' + location.host + ' - <span id="ftLicense">' + translate.ftLicense + '</span> <a href="' + wDir + '/license.htm">GNU General Public License</a><span id="ftExtra">' + translate.ftExtra + '</span></div>';
  31. document.write(header + main_1);
  32. $(document).ready(function() { $('body').append(main_2 + footer); });
  33. }
  34. function AddContent()
  35. {
  36. $(window).unload(function () { $(window).unbind('unload'); }); // disable firefox's bfcache
  37. $(document).ready(function() {
  38. var wDir = GetWorkingDir();
  39. var relPath = location.href.replace(wDir + '/', '');
  40. //
  41. // set last used state of sidebar
  42. //
  43. (window.name == 2) ? ShowIndex() : ShowTOC();
  44. //
  45. // on events for sidebar buttons
  46. //
  47. $('#sb_content').on('click', function() { ShowTOC(); });
  48. $('#sb_index').on('click', function() { ShowIndex(); });
  49. //
  50. // on events for search field + button
  51. //
  52. $('.header #search-btn').on('click', function() {
  53. var query = $(".header #q").val();
  54. document.location = translate.hdSearchLnk.format(query);
  55. });
  56. $('.header #search-form').on('submit', function(event) {
  57. event.preventDefault();
  58. var query = $(".header #q").val();
  59. document.location = translate.hdSearchLnk.format(query);
  60. });
  61. //
  62. // Hide logo
  63. //
  64. $('#ahklogo').hide();
  65. //
  66. // Headings
  67. //
  68. // Change display of h1 header
  69. $('h1').attr("class", "navh1");
  70. // Provide anchor link
  71. $('h1, h2, h3, h4, h5, h6').each(function(index) {
  72. // Show paragraph sign on mouseover
  73. $(this).hover(
  74. function() {
  75. $(this).append("<span style='color:#888;font-size:smaller;'> &para;</span>");
  76. }, function() {
  77. $(this).find("span:last").remove();
  78. }
  79. );
  80. // Add anchor
  81. if(!$(this).attr('id')) // if id anchor not exist, create one
  82. {
  83. var str = $(this).text().replace(/\s/g, '_'); // replace spaces with _
  84. var str = str.replace(/[():.,;'#\[\]\/{}&="|?!]/g, ''); // remove special chars
  85. if($('#' + str).length) // if new id anchor exist already, set it to a unique one
  86. $(this).attr('id', str + '_' + index);
  87. else
  88. $(this).attr('id', str);
  89. }
  90. $(this).wrap('<a href="#' + $(this).attr('id') + '" style="text-decoration:none;color:#000"></a>');
  91. });
  92. //
  93. // language button
  94. //
  95. var en = 'http://ahkscript.org/docs/';
  96. var de = 'http://ragnar-f.github.io/docs/';
  97. var cn = 'http://ahkcn.sourceforge.net/docs/';
  98. $('#lng-btn-en').on('click', function() { document.location = en + relPath; } );
  99. $('#lng-btn-de').on('click', function() { document.location = de + relPath; } );
  100. $('#lng-btn-cn').on('click', function() { document.location = cn + relPath; } );
  101. $('.hdr-table .hdr-language').find('li').mouseenter(function() {
  102. $(this).children('ul').show();
  103. $(this).addClass('selected');
  104. $(this).mouseleave(function() {
  105. $(this).children('ul').hide();
  106. $(this).removeClass('selected');
  107. });
  108. });
  109. //
  110. // Create toc sidebar
  111. //
  112. var node_matched = [];
  113. $('#sidebar').tree({
  114. data: toc,
  115. useContextMenu: false,
  116. keyboardSupport: false,
  117. saveState: false,
  118. onCanSelectNode: function(node) {
  119. if ((node.children.length) && (!node.path))
  120. return false;
  121. else
  122. return true;
  123. },
  124. onCreateLi: function(node, $li) {
  125. if (node.path == relPath)
  126. {
  127. node_matched.push(node);
  128. }
  129. }
  130. });
  131. $('#sidebar').bind('tree.click', function(event) {
  132. var node = event.node;
  133. $(this).tree('toggle', node);
  134. if (node.path)
  135. window.location = wDir + "/" + node.path;
  136. });
  137. //
  138. // pre-select toc sidebar item
  139. //
  140. for (var i = 0, len = node_matched.length; i < len; i++)
  141. {
  142. $('#sidebar').tree('addToSelection', node_matched[i]);
  143. $('#sidebar').tree('openNode', node_matched[i]);
  144. $('#sidebar').tree('openNode', node_matched[i].parent);
  145. }
  146. //
  147. // Create keyword list sidebar
  148. //
  149. var newContent = '';
  150. index.sort(function(a, b) {
  151. var textA = a[0].toLowerCase(), textB = b[0].toLowerCase()
  152. return textA.localeCompare(textB);
  153. });
  154. for (var i = 0, len = index.length; i < len; i++)
  155. {
  156. newContent += '<option value="' + index[i][1] + '">' + index[i][0] + '</option>';
  157. };
  158. $("#indexcontainer").html(newContent);
  159. //
  160. // Make keyword list fill and follow the viewport
  161. //
  162. var nav = $('ul.nav')[0];
  163. (function(top) {
  164. var wasFixed, margin;
  165. function scrolled() {
  166. var fixed = $(window).scrollTop() > top;
  167. if (fixed != wasFixed) {
  168. if (wasFixed = fixed) {
  169. $('#keywords').css({position: 'fixed', top: '8px'});
  170. $('#IndexEntry').css('display', 'block');
  171. margin = 8 + 20 + 44;
  172. } else {
  173. $('#keywords').css({position: '', top: ''});
  174. $('#IndexEntry').css('display', '');
  175. margin = top + 20 + 8;
  176. }
  177. resized();
  178. }
  179. }
  180. function resized() {
  181. var ic = $('#indexcontainer');
  182. // Child height seems to always return 0 on IE, so calculate it this way:
  183. var itemHeight = ic.height() / (ic.attr('size') || 1);
  184. ic.attr('size', ~~(($(window).height() - margin) / itemHeight));
  185. }
  186. $(window).on({scroll: scrolled, resize: resized});
  187. scrolled();
  188. })(nav.offsetTop + nav.offsetHeight);
  189. //
  190. // pre-select keyword list sidebar item
  191. //
  192. var sb_index_lastselected = $('[value="' + relPath + '"]').index() + 1;
  193. var sb_index_item_last = $('#indexcontainer :nth-child(' + sb_index_lastselected + ')');
  194. sb_index_item_last.prop('selected', true);
  195. //
  196. // select closest listbox entry while typing
  197. //
  198. $("#IndexEntry").on('keyup', function() {
  199. var oList = $('#indexcontainer')[0];
  200. var ListLen = oList.length;
  201. var iCurSel = oList.selectedIndex;
  202. var text = $("#IndexEntry").val().toLowerCase();
  203. var TextLen = text.length;
  204. if (!text) return
  205. for (var i = 0; i < ListLen; i++) {
  206. var listitem = oList.item(i).text.substr(0, TextLen).toLowerCase();
  207. if (listitem == text) {
  208. if (i != iCurSel) {
  209. var iPos = i + oList.size - 1;
  210. if(ListLen > iPos)
  211. oList.selectedIndex = iPos;
  212. else
  213. oList.selectedIndex = ListLen-1;
  214. oList.selectedIndex = i;
  215. }
  216. break;
  217. }
  218. }
  219. });
  220. //
  221. // open document when pressing enter or select item
  222. //
  223. $("#indexcontainer, #IndexEntry").on('keydown dblclick', function(event) {
  224. if ((event.which && event.which==13) || (event.keyCode && event.keyCode==13) || (event.type == 'dblclick')) {
  225. var iSelect = document.getElementById("indexcontainer").selectedIndex;
  226. if (iSelect >= 0) {
  227. var URL = document.getElementById("indexcontainer").item(iSelect).value;
  228. if (URL.length > 0) {
  229. window.location = wDir + '/' + URL;
  230. }
  231. }
  232. }
  233. });
  234. });
  235. };
  236. function AddChmAndOnlineFeatures()
  237. {
  238. // Make all external links open a new tab/window.
  239. $("a[href^='http']").attr('target', '_blank');
  240. (function() {
  241. var templ = $('<a class="ver"></a>');
  242. $('span.ver').each(function(idx, el) {
  243. // Give each version annotation a link to the changelog.
  244. var jel = $(el);
  245. var m, title, href, text = jel.text();
  246. if (m = /AHK_L (\d+)\+/.exec(text)) {
  247. title = translate.verToolTipAHK_L.format(m[1]);
  248. href = '/AHKL_ChangeLog.htm#L' + m[1];
  249. text = text.replace(m[0], 'v1.0.90+'); // For users who don't know what AHK_L was.
  250. } else if (m = /v\d\.\d\.(\d+\.)?\d+/.exec(text)) {
  251. title = translate.verToolTipDefault.format(m[0]);
  252. if (!m[1])
  253. m[0] = m[0] + '.00';
  254. if (m[0] <= 'v1.0.48.05')
  255. href = '/ChangeLogHelp.htm#' + m[0];
  256. else
  257. href = '/AHKL_ChangeLog.htm#' + m[0];
  258. } else return;
  259. jel.replaceWith(templ.clone(true)
  260. .attr('title', title)
  261. .attr('href', GetWorkingDir() + href)
  262. .text(text)
  263. );
  264. });
  265. })();
  266. //
  267. // Add useful features for code boxes
  268. //
  269. // Show select and download buttons in lower right corner of a pre box
  270. var divStyle = {fontSize: "11px", float: "right"};
  271. var aStyle = {cursor: "pointer", color: $("a:not([href=])").css("color")};
  272. var selectLink = $('<a id="selectCode">').text(translate.cdSelectBtn).css(aStyle);
  273. var downloadLink = $('<a id="downloadCode">').text(translate.cdDownloadBtn).css(aStyle);
  274. $('pre').each(function(index) {
  275. if ($(this).is(".Syntax")) {
  276. $.extend(divStyle, {marginTop: "-32px", marginRight: "7px"});
  277. $(this).after($('<div>').css(divStyle).prepend(selectLink.clone()));
  278. }
  279. else {
  280. $.extend(divStyle, {marginTop: "-28px", marginRight: "28px"});
  281. $(this).after($('<div>').css(divStyle).prepend(selectLink.clone(), [' | ', downloadLink.clone()]));
  282. }
  283. });
  284. // Select complete code when clicking
  285. $('a#selectCode').each(function(index) {
  286. $(this).on('click', function(e) {
  287. var doc = document
  288. , text = $(this).parent().prev('pre')[0]
  289. , range, selection
  290. ;
  291. if (doc.body.createTextRange) {
  292. range = document.body.createTextRange();
  293. range.moveToElementText(text);
  294. range.select();
  295. } else if (window.getSelection) {
  296. selection = window.getSelection();
  297. range = document.createRange();
  298. range.selectNodeContents(text);
  299. selection.removeAllRanges();
  300. selection.addRange(range);
  301. }
  302. });
  303. });
  304. // Download complete code when clicking
  305. $('a#downloadCode').each(function(index) {
  306. $(this).on('click', function(e) {
  307. var textToWrite = '\ufeff' + $(this).parent().prev('pre').text().replace(/\n/g, "\r\n");
  308. var textFileAsBlob = new Blob([textToWrite], {type:'text/csv'});
  309. var fileNameToSaveAs = location.pathname.match(/([^\/]+)(?=\.\w+$)/)[0] + "-Script.ahk";
  310. var downloadLink = document.createElement("a");
  311. downloadLink.download = fileNameToSaveAs;
  312. downloadLink.innerHTML = "Download File";
  313. if (window.webkitURL != null) {
  314. // Chrome
  315. downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
  316. downloadLink.click();
  317. }
  318. else if (navigator.userAgent.indexOf("Trident")>-1) {
  319. // IE 10+
  320. navigator.msSaveBlob(textFileAsBlob, fileNameToSaveAs)
  321. }
  322. else {
  323. // Firefox
  324. downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
  325. downloadLink.style.display = "none";
  326. document.body.appendChild(downloadLink);
  327. downloadLink.click();
  328. }
  329. });
  330. });
  331. }
  332. function ShowTOC()
  333. {
  334. window.name = 1;
  335. $('#sb_content').attr('class', 'selected');
  336. $('#sb_index').removeAttr('class');
  337. $('#keywords').hide();
  338. $('#sidebar').fadeIn();
  339. }
  340. function ShowIndex()
  341. {
  342. window.name = 2;
  343. $('#sb_index').attr('class', 'selected');
  344. $('#sb_content').removeAttr('class');
  345. $('#sidebar').hide();
  346. $('#keywords').fadeIn();
  347. $(window).trigger('resize');
  348. }
  349. function IsInsideCHM()
  350. {
  351. return (location.href.search(/::/) > 0) ? 1 : 0;
  352. }
  353. function IsSearchBot()
  354. {
  355. return navigator.userAgent.match(/googlebot|bingbot|slurp/i);
  356. }
  357. String.prototype.format = function() {
  358. var args = arguments;
  359. return this.replace(/\{(\d+)\}/g, function(m, n) { return args[n]; });
  360. };