ref.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  1. var $hilighted,
  2. $hilightedMenuItem,
  3. optionDictionary = {},
  4. names = [],
  5. buildApiOffline,
  6. initOffline,
  7. offline = {},
  8. API = {},
  9. buildPage;
  10. function loadScript(url, callback) {
  11. //http://www.nczonline.net/blog/2009/07/28/the-best-way-to-load-external-javascript/
  12. var script = document.createElement("script");
  13. script.type = "text/javascript";
  14. if (script.readyState){ //IE
  15. script.onreadystatechange = function(){
  16. if (script.readyState == "loaded" ||
  17. script.readyState == "complete"){
  18. script.onreadystatechange = null;
  19. callback();
  20. }
  21. };
  22. } else { //Others
  23. script.onload = function() {
  24. callback();
  25. };
  26. }
  27. script.src = url;
  28. document.getElementsByTagName("head")[0].appendChild(script);
  29. }
  30. function toDot (id){
  31. return id.replace(/[-]+/g,'.');
  32. };
  33. function escapeHTML(html) {
  34. if (typeof html === 'string') {
  35. html = html
  36. .replace('\u25CF', '\\u25CF')
  37. .replace(/</g, '&lt;')
  38. .replace(/>/g, '&gt;');
  39. }
  40. return html;
  41. }
  42. function escapeSelector (name) {
  43. return name.replace('<', '\\<').replace('>', '\\>');
  44. }
  45. function activateInternalLinks($parent) {
  46. $('a[href^="#"]', $parent).each(function (i, anchor) {
  47. $(anchor).click(function () {
  48. gotoSection(anchor.href.split('#')[1], true);
  49. return false;
  50. });
  51. });
  52. }
  53. /**
  54. * Highligth a specific option by coloring it in the menu view and section view
  55. */
  56. function hilight (id) {
  57. var linkId, $el, $detailsWrap = $('#details-wrap');
  58. $el = $('div.member#' + escapeSelector(id));
  59. // clear old
  60. if ($hilighted) {
  61. $hilighted.removeClass('hilighted');
  62. }
  63. if ($hilightedMenuItem) {
  64. $hilightedMenuItem.removeClass('hilighted');
  65. }
  66. if ($el.length === 0) {
  67. $detailsWrap.scrollTop(0);
  68. } else {
  69. // hilight new
  70. $hilighted = $el;
  71. $hilighted.addClass('hilighted');
  72. $detailsWrap.scrollTop($hilighted.offset().top + $detailsWrap.scrollTop() - 160);
  73. }
  74. linkId = id.replace(/[^a-z0-9<>\\]+/gi,'.');
  75. $hilightedMenuItem = $('a[href="#'+ linkId +'"]').not('.plus');
  76. $hilightedMenuItem.addClass('hilighted');
  77. }
  78. /**
  79. * Expand and load children when necessary of current level
  80. */
  81. function toggleExpand($elem, callback) {
  82. var $_menu = $elem.find('div[id$="-menu"]').first(),
  83. _id = $_menu.attr('id').replace("-menu",""),
  84. displayChildrenCallback = function () {
  85. $('.dots', $elem).removeClass('loading');
  86. $elem.removeClass("collapsed");
  87. $elem.addClass("expanded");
  88. $_menu.slideDown();
  89. // show relevant section
  90. if (/[A-Z]/.test(_id[0])) {
  91. _id = 'object-' + _id;
  92. }
  93. toggleSection(_id);
  94. if (callback) {
  95. callback();
  96. }
  97. };
  98. if ($elem.hasClass('collapsed')) {
  99. /* if not loaded, load children, standard we have three children */
  100. if ($_menu.children().size() == 1) {
  101. $('.dots', $elem).addClass('loading');
  102. loadChildren(_id, false, displayChildrenCallback);
  103. } else {
  104. displayChildrenCallback();
  105. }
  106. } else {
  107. // hide children
  108. $_menu.slideUp('normal',function(){
  109. $elem.removeClass("expanded");
  110. $elem.addClass("collapsed");
  111. });
  112. }
  113. };
  114. function toggleSection(sectionId) {
  115. $section = $("#details > div.section:visible");
  116. // hide current section
  117. if($section){
  118. $section.hide();
  119. }
  120. if (/[^\\]</.test(sectionId)) {
  121. sectionId = sectionId.replace('<', '\\<').replace('>', '\\>');
  122. }
  123. $('#details > div.section#' + sectionId).show();
  124. }
  125. function addSectionOption(val){
  126. $section = $('<div class="section" id="' + val.name + '" style="display:none;"></div>').appendTo('#details');
  127. $('<h1>' + val.fullname.replace('<', '&lt;').replace('>', '&gt;') + '</h1>'
  128. + (val.description ? '<div class="section-description">' + val.description + '</div>': '')
  129. + (val.demo ? '<div class="demo"><h4>Try it:</h4> ' + val.demo + '</div>': '' )).appendTo($section);
  130. activateInternalLinks($section);
  131. $(document).triggerHandler({ type:"xtra.btn.section.event",id: optionDictionary[val.fullname], table: 'option' });
  132. }
  133. function addSectionObject(val){
  134. $section = $('<div class="section" id="object-' + val.name + '" style="display:none;"></div>').appendTo('#details');
  135. $('<h1>' + val.title + '</h1>').appendTo($section);
  136. $('<div class="section-description">' + val.description + '</div>').appendTo($section);
  137. activateInternalLinks($section);
  138. $(document).triggerHandler({ type:"xtra.btn.section.event",id: 'object-'+ val.name, table: 'object'});
  139. }
  140. function markupReturnType(s) {
  141. s = s.replace(/[<>]/g, function (a) {
  142. return {
  143. '<': '&lt;',
  144. '>': '&gt;'
  145. }[a];
  146. });
  147. s = s.replace(/(Axis|Chart|Element|Highcharts|Point|Renderer|Series)/g, '<a href="#$1">$1</a>');
  148. return s;
  149. }
  150. function loadOptionMemberInSection(obj, isParent){
  151. //add member to section in div#details
  152. var $_section = $('div#' + obj.parent.replace('<', '\\<').replace('>', '\\>') + '.section'),
  153. $_inheritedLink,
  154. $memberDiv,
  155. contextClass = obj.description && obj.description.indexOf('<p>') > -1 ? '' : ' context';
  156. $memberDiv = $('<div class="member" id="' + obj.name + '"><span class="title">' + obj.title + '</span>'
  157. + (obj.returnType ? '<span class="returnType">: ' + markupReturnType(obj.returnType) + '</span>' : '')
  158. + (obj.deprecated ? '<div class="deprecated"><p>Deprecated</p></div>' : '' )
  159. + (obj.since ? '<div class="since">Since ' + obj.since + '</div>' : '' )
  160. + (obj.description ? '<div class="description">' + obj.description
  161. + (obj.defaults ? ' Defaults to <code>' + escapeHTML(obj.defaults) + '</code>.' : '')
  162. + '</div>' : '')
  163. + (obj.context ? '<div class="description' + contextClass + '">The <code>this</code> keyword refers to the '+ markupReturnType(obj.context) +' object.</div>' : '')
  164. + (obj.demo ? '<div class="demo"><h4>Try it:</h4> ' + obj.demo + '</div>': '' )
  165. + (obj.seeAlso ? '<div class="seeAlso">See also: ' + obj.seeAlso + '</div>': '' )
  166. + '</div>').appendTo($_section);
  167. activateInternalLinks($memberDiv);
  168. if (isParent) {
  169. $('div#' + escapeSelector(obj.name) + '.member span.title').html(function() {
  170. var title = $.trim($(this).text());
  171. return $('<a href="#' + obj.fullname + '">' + title + '</a>').click(function(){
  172. gotoSection(obj.fullname, true);
  173. });
  174. });
  175. }
  176. }
  177. function loadObjectMemberInSection(obj) {
  178. $memberDiv = $('<div class="member" id="' + obj.name + '">'
  179. + '<span class="title">' + obj.title + '</span> '
  180. + (obj.params ? '<span class="parameters">' + obj.params + '</span>' : '')
  181. + (obj.since ? '<div class="since">Since ' + obj.since + '</div>' : '' )
  182. + (obj.deprecated ? '<div class="deprecated"><p>Deprecated</p></div>' : '' )
  183. + '<div class="description"><p>' + obj.description + '</p>'
  184. + (obj.paramsDescription ? '<h4>Parameters</h4><ul id="paramdesc"><li>' +
  185. obj.paramsDescription.replace(/\|\|/g,'</li><li>') + '</li></ul>' : '')
  186. + (obj.returnType ? '<h4>Returns</h4><ul id="returns"><li>' + markupReturnType(obj.returnType) + '</li></ul>' : '')
  187. + '</div>'
  188. + (obj.demo ? '<div class="demo"><h4>Try it:</h4> ' + obj.demo + '</div>': '' )
  189. + '</div>').appendTo('div#object-' + obj.parent + '.section');
  190. activateInternalLinks($memberDiv);
  191. }
  192. function loadChildren(name, silent, callback) {
  193. var isObject = /[A-Z]/.test(name[0]),
  194. url = isObject ?
  195. 'object/'+ PRODUCTNAME + '-obj/child/' + name :
  196. 'option/'+ PRODUCTNAME + '/child/' + name;
  197. $.ajax({
  198. type: "GET",
  199. url: url,
  200. dataType: "json",
  201. error: function () {
  202. var $menu;
  203. $menu = $('div#' + escapeSelector(name) + '-menu');
  204. $('.dots', $menu.parent()).removeClass('loading').addClass('error').html('Error');
  205. },
  206. success: function (data) {
  207. var display = 'block',
  208. display, $menu, $menuItem;
  209. if (silent){
  210. display = 'none';
  211. }
  212. name = name.replace('<', '\\<').replace('>', '\\>');
  213. $menu = $('div#' + name + '-menu');
  214. $.each(data, function (key, val) {
  215. var $div = $('<div></div>').appendTo($menu), $plus, $menuLink, parts,
  216. tie, dottedName, internalName,
  217. name,
  218. title,
  219. defaults,
  220. cls;
  221. /*if (val.type === 'method') {
  222. name = val.name.replace('--', '.') + '()';
  223. } else if (val.type === 'property') {
  224. name = val.name.replace('--', '.');
  225. } else {
  226. name = val.fullname;
  227. }*/
  228. name = val.fullname;
  229. if (val.isParent) {
  230. var preBracket = '{',
  231. postBracket = '}';
  232. if (val.returnType && val.returnType.indexOf('Array') === 0 ) {
  233. preBracket = '[{';
  234. postBracket = '}]';
  235. }
  236. $menuItem = $('<div class="menuitem collapsed"></div>');
  237. $menuLink = $('<a href="#' + name + '">' + val.title + '</a>').appendTo($menuItem);
  238. $menuLink.click(function(){
  239. gotoSection(val.fullname, true);
  240. });
  241. $plus = $('<a href="#' + name + '" class="plus"></a>').appendTo($menuItem);
  242. $plus.click(function () {
  243. toggleExpand($plus.parent());
  244. });
  245. $menuItem.append(':&nbsp;'+ preBracket +'<span class="dots"><span>…</span></span>');
  246. // add empty submenu
  247. $subMenu = $('<div id="' + val.name + '-menu" style="display:none"><div>').appendTo($menuItem);
  248. $menuItem.append(postBracket);
  249. $menuItem.appendTo($menu);
  250. addSectionOption(val);
  251. } else {
  252. if (val.type === 'method') {
  253. title = val.title + '()';
  254. } else {
  255. title = val.title;
  256. }
  257. $menuLink = $('<a href="#' + name + '">' + title + '</a>').appendTo($div);
  258. $menuLink.click(function() {
  259. gotoSection(name, true);
  260. });
  261. if (val.type === 'method') {
  262. defaults = '[function]';
  263. } else if (val.type === 'property') {
  264. defaults = '[' + val.returnType + ']';
  265. } else if (val.defaults === 'null' || val.defaults === 'undefined' || val.defaults === '' || val.defaults === undefined) {
  266. defaults = val.defaults;
  267. } else if (val.returnType === 'String' || val.returnType === 'Color') {
  268. defaults = '"' + val.defaults + '"';
  269. } else {
  270. defaults = val.defaults;
  271. }
  272. if (val.returnType) {
  273. cls = val.returnType.toLowerCase();
  274. } else {
  275. cls = '';
  276. console.warn('Missing returnType for ' + val.fullname);
  277. }
  278. $('<span class="value value-' + cls + '">: ' + escapeHTML(defaults) + '</span>').appendTo($div);
  279. }
  280. if (isObject) {
  281. loadObjectMemberInSection(val);
  282. } else {
  283. loadOptionMemberInSection(val, val.isParent);
  284. }
  285. });
  286. $(document).triggerHandler({
  287. type:"xtra.btn.member.event",
  288. id: isObject ? 'object-' + name : name,
  289. table: isObject ? 'object' : 'option'
  290. });
  291. if (callback) {
  292. callback();
  293. }
  294. }
  295. });
  296. };
  297. function loadObjectMembers(name){
  298. $.ajax({
  299. type: "GET",
  300. url: 'object/'+ PRODUCTNAME + '-obj/child/' + name,
  301. async: false,
  302. dataType: "json",
  303. success: function (data) {
  304. $.each(data, function (key, val) {
  305. loadObjectMemberInSection(val);
  306. });
  307. }
  308. });
  309. $(document).triggerHandler({ type:"xtra.btn.member.event", id: 'object-' + name,table:'object'});
  310. };
  311. function gotoSection(anchor, hilighted) {
  312. var name, levels, member, isObjectArr, isObject, parts, $_parent, $_parentparent, $_menu,
  313. sectionId, parent,
  314. i,
  315. callbackStack = [];
  316. // is it an option-section or an object-section?
  317. parts = anchor.split("-");
  318. // Handle typed parent item, like series<line>
  319. name = anchor.split('.');
  320. if (name.length > 1) {
  321. name[name.length - 1] = '-' + name[name.length - 1];
  322. }
  323. name = name.join('-');
  324. levels = name.split(/[-]{1,2}/);
  325. isObject = (parts.length > 1 && parts[0] == 'object' || /[A-Z]/.test(name[0]));
  326. // Asyncronously expand parent elements of selected item
  327. $.each(levels, function(i) {
  328. callbackStack.push(function () {
  329. var proceed = true,
  330. level,
  331. $_menu,
  332. $_parent;
  333. if (levels[i]) {
  334. level = levels.slice(0, i + 1).join('-');
  335. if (level.indexOf('<') > -1) {
  336. $_parentparent = $('#' + level.split('<')[0] + '-menu').parent();
  337. level = escapeSelector(level);
  338. }
  339. $_menu = $('#' + level + '-menu');
  340. $_parent = $_menu.parent();
  341. if ($_menu && $_parent.hasClass('collapsed')) {
  342. if ($_parentparent && $_parentparent.hasClass('collapsed')) {
  343. toggleExpand($_parentparent);
  344. }
  345. // Do the toggle, and pass the next level as the callback argument
  346. toggleExpand($_parent, callbackStack[i + 1]);
  347. proceed = false;
  348. }
  349. }
  350. // For the last path item, show the section etc
  351. if (/[A-Z]/.test(level[0])) {
  352. level = 'object-' + level;
  353. }
  354. if ($('#details > div.section#' + level).length) {
  355. toggleSection(level);
  356. // empty search
  357. $("#search").val("");
  358. window.location.hash = anchor;
  359. }
  360. if (proceed && callbackStack[i + 1]) {
  361. callbackStack[i + 1]();
  362. }
  363. });
  364. });
  365. // Hilighting is the last operation in the async stack
  366. if (hilighted) {
  367. callbackStack.push(function () {
  368. hilight(name);
  369. });
  370. }
  371. // Start the recursive iteration
  372. callbackStack[0]();
  373. }
  374. /*
  375. function addToSelectBox(key, val, type) {
  376. var $menuItem = $('<div class="menuitem collapsed"></div>').appendTo('#' + type + 's'),
  377. splut = val.fullname.split('<'),
  378. commonName = splut[0],
  379. templateName = splut[1].split('>')[0],
  380. $menuLink = $('#' + commonName + '-menulink'),
  381. $selectbox = $('#' + commonName + '-selectbox');
  382. // The first time we encounter the series, generate the menu item for it.
  383. if ($menuLink.length === 0) {
  384. $menuLink = $('<a href="#' + commonName + '" id="' + commonName + '-menulink">' + commonName + '</a>')
  385. .appendTo($menuItem);
  386. $menuItem.append(': { type: ');
  387. $selectbox = $('<select id="'+ commonName +'-selectbox">')
  388. .bind('change', function () {
  389. console.log(this.value);
  390. })
  391. .appendTo($menuItem);
  392. $menuItem.append(' }');
  393. }
  394. $selectbox.append('<option>' + templateName + '</option>')
  395. .attr({
  396. name: templateName
  397. });
  398. }
  399. */
  400. /**
  401. * Add the first level menu items on page load
  402. */
  403. function addFirstLevelMenuItem(key, val, type) {
  404. var $menuItem = $('<div class="menuitem collapsed"></div>').appendTo('#' + type + 's'),
  405. $plus, anchor, $menu, levels, level, member, $menuLink,
  406. sectionId = val.fullname || val.name,
  407. title = escapeHTML(val.title),
  408. mainSection,
  409. name = val.name,
  410. recurseToType = false,
  411. menuItemPrefix = '';
  412. prefix = ': {',
  413. suffix = '}';
  414. if (val.returnType && val.returnType.indexOf('Array') === 0) {
  415. if (val.returnType === 'Array<Object>') {
  416. prefix = ': [{';
  417. suffix = '}]';
  418. } else {
  419. prefix = ': [';
  420. suffix = ']';
  421. }
  422. }
  423. // Global options
  424. if ($.inArray(val.name, ['global', 'lang']) !== -1) {
  425. $menuItem = $('<div class="menuitem collapsed"></div>').appendTo('#global-options');
  426. }
  427. // Handle the series<line> syntax
  428. if (sectionId.indexOf('<') > -1) {
  429. mainSection = sectionId.split('<')[0];
  430. // The first time we encounter a menu item on the syntax series<line>, add the series menu item
  431. if ($('#' + mainSection + '-menu').length === 0) {
  432. sectionId = title = name = mainSection;
  433. prefix = ': [';
  434. suffix = ']';
  435. recurseToType = true; // run this method again, but now for the { type: "line" } menu item
  436. } else {
  437. $menuItem.appendTo($('#' + mainSection + '-menu'));
  438. menuItemPrefix = '{<br class="typed"/>';
  439. title = '<span class="typed">type: "' + sectionId.split('<')[1].split('>')[0] + '"</span>';
  440. prefix = ', ';
  441. }
  442. }
  443. if (menuItemPrefix) {
  444. $menuItem.append(menuItemPrefix);
  445. }
  446. $menuLink = $('<a href="#' + sectionId + '">' + title + '</a>')
  447. .appendTo($menuItem)
  448. .click(function(){
  449. gotoSection(sectionId, true);
  450. return false;
  451. });
  452. if (val.isParent) {
  453. $plus = $('<a href="#' + sectionId + '" class="plus"></a>')
  454. .appendTo($menuItem)
  455. .click(function () {
  456. toggleExpand($plus.parent());
  457. });
  458. }
  459. $menuItem.append(prefix);
  460. $('<span class="dots"><span>…</span></span>').appendTo($menuItem);
  461. if(val.isParent) {
  462. $subMenu = $('<div id="' + name + '-menu" style="display:none"><div>').appendTo($menuItem);
  463. }
  464. $menuItem.append(suffix);
  465. // create sections in div#details
  466. if (type === 'option') {
  467. addSectionOption(val);
  468. } else {
  469. addSectionObject(val);
  470. }
  471. if (recurseToType) {
  472. addFirstLevelMenuItem.apply(null, arguments);
  473. }
  474. }
  475. prepareOffline = function(callback) {
  476. offline = {highcharts: {}, highstock: {}, highmaps: {}};
  477. // now we have the data loaded we rewrite $.ajax for offline use
  478. $.ajax = function(obj) {
  479. var result,
  480. type,
  481. splitted;
  482. if (obj.url === PRODUCTNAME + '/names') {
  483. result = API[PRODUCTNAME].names;
  484. }
  485. var type = obj.url.split('/');
  486. if (obj.url === 'option/'+ PRODUCTNAME + '/main') {
  487. result = API[PRODUCTNAME].main.option;
  488. }
  489. if (obj.url === 'object/'+ PRODUCTNAME + '-obj/main') {
  490. result = API[PRODUCTNAME].main.object;
  491. }
  492. splitted = obj.url.split('object/' + PRODUCTNAME + '-obj/child/');
  493. if (splitted.length > 1) {
  494. result = API[PRODUCTNAME].object[splitted[1]].children;
  495. }
  496. splitted = obj.url.split('option/' + PRODUCTNAME + '/child/');
  497. if (splitted.length > 1) {
  498. result = API[PRODUCTNAME].option[splitted[1]].children;
  499. }
  500. // result to handler
  501. obj.success(result);
  502. };
  503. callback();
  504. }
  505. // build dictionary for offline use
  506. buildApiOffline = function(data, callback) {
  507. var option,
  508. main,
  509. names,
  510. type,
  511. i = 0;
  512. API[PRODUCTNAME] = { option: [], object: [], main: {}, names: [] };
  513. names = API[PRODUCTNAME].names;
  514. function fillWithType(type) {
  515. var idx,
  516. slot = API[PRODUCTNAME][type],
  517. main = API[PRODUCTNAME].main[type] = [];
  518. name,
  519. parent;
  520. // Loop over options in dump file
  521. for (idx = 0; idx < data[type].length; idx++) {
  522. option = data[type][idx];
  523. name = option.name;
  524. names.push(name);
  525. if (option.isParent) {
  526. // Store main options separately
  527. if (!/-/.test(name)) {
  528. main.push(option);
  529. }
  530. if (slot[name] == undefined) {
  531. slot[name] = {details: option, children: []};
  532. } else {
  533. /* In case the parent option was already
  534. * deducted from a child option
  535. */
  536. slot[name].details = option;
  537. }
  538. }
  539. // we have a child!
  540. if (slot.hasOwnProperty(option.parent)) {
  541. slot[option.parent].children.push(option);
  542. } else {
  543. slot[option.parent] = {details: null, children: [option]};
  544. }
  545. }
  546. }
  547. while(i < 2) {
  548. type = ['option', 'object'][i];
  549. fillWithType(type);
  550. i++
  551. }
  552. callback();
  553. };
  554. buildPage = function() {
  555. // autocomplete
  556. $.ajax({
  557. type: "GET",
  558. url: PRODUCTNAME + '/names',
  559. async: false,
  560. dataType: "json",
  561. success: function (data) {
  562. $.each(data, function (key, val) {
  563. var dotted = toDot(val);
  564. names.push(dotted);
  565. optionDictionary[dotted] = val;
  566. });
  567. $("#search" ).autocomplete({
  568. source: names,
  569. autoFocus: true,
  570. minLength: 2,
  571. select: function( event, ui ) {
  572. gotoSection(ui.item.value, true);
  573. },
  574. position: {
  575. my: 'left top',
  576. of: '#search-wrap'
  577. }
  578. });
  579. }
  580. });
  581. // load main options and build folded menu tree
  582. $.ajax({
  583. type: "GET",
  584. url: 'option/' + PRODUCTNAME + '/main',
  585. async: false,
  586. dataType: "json",
  587. success: function (data) {
  588. $.each(data, function (key, val) {
  589. addFirstLevelMenuItem(key, val, 'option');
  590. });
  591. }
  592. });
  593. // load objects of product
  594. $.ajax({
  595. type: "GET",
  596. url: 'object/' + PRODUCTNAME + '-obj/main',
  597. async: false,
  598. dataType: "json",
  599. success: function (data) {
  600. $.each(data, function (key, val) {
  601. addFirstLevelMenuItem(key, val, 'object');
  602. });
  603. }
  604. });
  605. // check url for anchor, remove also '()' from old links for object.method().
  606. anchor = window.location.hash.replace('#', '').replace('()','');
  607. if (anchor) {
  608. gotoSection(anchor, true);
  609. }
  610. if (/\?object_not_found=true/.test(window.location.search)) {
  611. dottedName = window.location.hash.split('#').pop();
  612. internalName = optionDictionary[dottedName];
  613. $('div#' + internalName).append('<div class="error">The object/option wasn\'t found in the database, maybe iẗ́\'s inherited??</div>');
  614. }
  615. // focus search
  616. $("#search")[0].focus();
  617. }
  618. // Startup
  619. $(document).ready( function () {
  620. if (runDB) {
  621. buildPage();
  622. } else {
  623. // prepare dump object
  624. prepareOffline(function () {
  625. // load offline data
  626. loadScript('./js/' + PRODUCTNAME + '.json', function() {
  627. buildApiOffline(offline[PRODUCTNAME], buildPage);
  628. });
  629. });
  630. // hide elements that don't make sence in offline mode
  631. $('.hidden-offline').hide();
  632. };
  633. // convert hash from redirected dash syntax to new dot syntax
  634. if (/-/.test(location.hash)) {
  635. location.hash = location.hash.replace(/(--|-)/g, '.');
  636. }
  637. // Add scrollanimation to button
  638. $("a[href='#top']").click(function() {
  639. $("html, body").animate({ scrollTop: 0 }, "slow");
  640. return false;
  641. });
  642. $(window).on('scroll', function() {
  643. button = $("#scrollTop");
  644. if (!$("#top").isOnScreen()) {
  645. if (button.css('display') == 'none') {
  646. button.fadeIn("slow");
  647. }
  648. } else {
  649. if (button.css('display') == 'block') {
  650. button.fadeOut("slow");
  651. }
  652. }
  653. });
  654. $.fn.isOnScreen = function(){
  655. var win = $(window),
  656. viewport = {
  657. top : win.scrollTop(),
  658. left : win.scrollLeft()
  659. };
  660. viewport.right = viewport.left + win.width();
  661. viewport.bottom = viewport.top + win.height();
  662. var bounds = this.offset();
  663. bounds.right = bounds.left + this.outerWidth();
  664. bounds.bottom = bounds.top + this.outerHeight();
  665. return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
  666. };
  667. function updateHeight() {
  668. if (jQuery(window).width() >= 768) {
  669. // Disable
  670. var padding,
  671. height = $(window).height() - $('#top').height() - $('#footer').height();
  672. $("#wrapper").height(height);
  673. padding = $("#wrapper .container").innerHeight() - $("#wrapper .container").height();
  674. height = $("#wrapper").height() - padding;
  675. $("#wrapper-inner").height(height);
  676. $("#nav-wrap").height(height);
  677. $("#details-wrap").height(height);
  678. } else {
  679. // no height defined on the element for mobile devices
  680. $('#nav-wrap').removeAttr('style');
  681. }
  682. };
  683. updateHeight();
  684. $(window).resize(updateHeight);
  685. // Make the Highcharts/Highstock links dynamic
  686. $('#highstock-link, #highcharts-link').click(function () {
  687. this.href += location.hash;
  688. });
  689. // Login shortcut (hot corner)
  690. $("<div>")
  691. .css({
  692. position: 'absolute',
  693. display: 'block',
  694. width: '10px',
  695. height: '10px',
  696. right: 0,
  697. cursor: 'pointer'
  698. })
  699. .click(function () {
  700. $('<iframe src="auth/login">').dialog({
  701. height: 300
  702. });
  703. })
  704. .prependTo('#top .container');
  705. });