base.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. /**
  2. java -jar compiler.jar --js $FileName$ --js_output_file ../inc/kint.js --compilation_level ADVANCED_OPTIMIZATIONS --output_wrapper "(function(){%output%})()"
  3. */
  4. if ( typeof kintInitialized === 'undefined' ) {
  5. kintInitialized = 1;
  6. var kint = {
  7. visiblePluses : [], // all visible toggle carets
  8. currentPlus : -1, // currently selected caret
  9. selectText : function( element ) {
  10. var selection = window.getSelection(),
  11. range = document.createRange();
  12. range.selectNodeContents(element);
  13. selection.removeAllRanges();
  14. selection.addRange(range);
  15. },
  16. each : function( selector, callback ) {
  17. Array.prototype.slice.call(document.querySelectorAll(selector), 0).forEach(callback)
  18. },
  19. hasClass : function( target, className ) {
  20. if ( !target.classList ) return false;
  21. if ( typeof className === 'undefined' ) {
  22. className = 'kint-show';
  23. }
  24. return target.classList.contains(className);
  25. },
  26. addClass : function( target, className ) {
  27. if ( typeof className === 'undefined' ) {
  28. className = 'kint-show';
  29. }
  30. target.classList.add(className);
  31. },
  32. removeClass : function( target, className ) {
  33. if ( typeof className === 'undefined' ) {
  34. className = 'kint-show';
  35. }
  36. target.classList.remove(className);
  37. return target;
  38. },
  39. next : function( element ) {
  40. do {
  41. element = element.nextElementSibling;
  42. } while ( element.nodeName.toLowerCase() !== 'dd' );
  43. return element;
  44. },
  45. toggle : function( element, hide ) {
  46. var parent = kint.next(element);
  47. if ( typeof hide === 'undefined' ) {
  48. hide = kint.hasClass(element);
  49. }
  50. if ( hide ) {
  51. kint.removeClass(element);
  52. } else {
  53. kint.addClass(element);
  54. }
  55. if ( parent.childNodes.length === 1 ) {
  56. parent = parent.childNodes[0].childNodes[0]; // reuse variable cause I can
  57. // parent is checked in case of empty <pre> when array("\n") is dumped
  58. if ( parent && kint.hasClass(parent, 'kint-parent') ) {
  59. kint.toggle(parent, hide)
  60. }
  61. }
  62. },
  63. toggleChildren : function( element, hide ) {
  64. var parent = kint.next(element)
  65. , nodes = parent.getElementsByClassName('kint-parent')
  66. , i = nodes.length;
  67. if ( typeof hide === 'undefined' ) {
  68. hide = kint.hasClass(element);
  69. }
  70. while ( i-- ) {
  71. kint.toggle(nodes[i], hide);
  72. }
  73. kint.toggle(element, hide);
  74. },
  75. toggleAll : function( caret ) {
  76. var elements = document.getElementsByClassName('kint-parent')
  77. , i = elements.length
  78. , visible = kint.hasClass(caret.parentNode);
  79. while ( i-- ) {
  80. kint.toggle(elements[i], visible);
  81. }
  82. },
  83. switchTab : function( target ) {
  84. var lis, el = target, index = 0;
  85. target.parentNode.getElementsByClassName('kint-active-tab')[0].className = '';
  86. target.className = 'kint-active-tab';
  87. // take the index of clicked title tab and make the same n-th content tab visible
  88. while ( el = el.previousSibling ) el.nodeType === 1 && index++;
  89. lis = target.parentNode.nextSibling.childNodes;
  90. for ( var i = 0; i < lis.length; i++ ) {
  91. if ( i === index ) {
  92. lis[i].style.display = 'block';
  93. if ( lis[i].childNodes.length === 1 ) {
  94. el = lis[i].childNodes[0].childNodes[0];
  95. if ( kint.hasClass(el, 'kint-parent') ) {
  96. kint.toggle(el, false)
  97. }
  98. }
  99. } else {
  100. lis[i].style.display = 'none';
  101. }
  102. }
  103. },
  104. isSibling : function( el ) {
  105. for ( ; ; ) {
  106. el = el.parentNode;
  107. if ( !el || kint.hasClass(el, 'kint') ) break;
  108. }
  109. return !!el;
  110. },
  111. fetchVisiblePluses : function() {
  112. kint.visiblePluses = [];
  113. kint.each('.kint nav, .kint-tabs>li:not(.kint-active-tab)', function( el ) {
  114. if ( el.offsetWidth !== 0 || el.offsetHeight !== 0 ) {
  115. kint.visiblePluses.push(el)
  116. }
  117. });
  118. },
  119. openInNewWindow : function( kintContainer ) {
  120. var newWindow;
  121. if ( newWindow = window.open() ) {
  122. newWindow.document.open();
  123. newWindow.document.write(
  124. '<html>'
  125. + '<head>'
  126. + '<title>Kint (' + new Date().toISOString() + ')</title>'
  127. + '<meta charset="utf-8">'
  128. + document.getElementsByClassName('-kint-js')[0].outerHTML
  129. + document.getElementsByClassName('-kint-css')[0].outerHTML
  130. + '</head>'
  131. + '<body>'
  132. + '<input style="width: 100%" placeholder="Take some notes!">'
  133. + '<div class="kint">'
  134. + kintContainer.parentNode.outerHTML
  135. + '</div></body>'
  136. );
  137. newWindow.document.close();
  138. }
  139. },
  140. sortTable : function( table, column ) {
  141. var tbody = table.tBodies[0];
  142. var format = function( s ) {
  143. var n = column === 1 ? s.replace(/^#/, '') : s;
  144. if ( isNaN(n) ) {
  145. return s.trim().toLocaleLowerCase();
  146. } else {
  147. n = parseFloat(n);
  148. return isNaN(n) ? s.trim() : n;
  149. }
  150. };
  151. [].slice.call(table.tBodies[0].rows)
  152. .sort(function( a, b ) {
  153. a = format(a.cells[column].textContent);
  154. b = format(b.cells[column].textContent);
  155. if ( a < b ) return -1;
  156. if ( a > b ) return 1;
  157. return 0;
  158. })
  159. .forEach(function( el ) {
  160. tbody.appendChild(el);
  161. });
  162. },
  163. keyCallBacks : {
  164. cleanup : function( i ) {
  165. var focusedClass = 'kint-focused';
  166. var prevElement = document.querySelector('.' + focusedClass);
  167. prevElement && kint.removeClass(prevElement, focusedClass);
  168. if ( i !== -1 ) {
  169. var el = kint.visiblePluses[i];
  170. kint.addClass(el, focusedClass);
  171. var offsetTop = function( el ) {
  172. return el.offsetTop + ( el.offsetParent ? offsetTop(el.offsetParent) : 0 );
  173. };
  174. var top = offsetTop(el) - (window.innerHeight / 2 );
  175. window.scrollTo(0, top);
  176. }
  177. kint.currentPlus = i;
  178. },
  179. moveCursor : function( up, i ) {
  180. // todo make the first VISIBLE plus active
  181. if ( up ) {
  182. if ( --i < 0 ) {
  183. i = kint.visiblePluses.length - 1;
  184. }
  185. } else {
  186. if ( ++i >= kint.visiblePluses.length ) {
  187. i = 0;
  188. }
  189. }
  190. kint.keyCallBacks.cleanup(i);
  191. return false;
  192. }
  193. }
  194. };
  195. window.addEventListener("click", function( e ) {
  196. var target = e.target
  197. , nodeName = target.nodeName.toLowerCase();
  198. if ( !kint.isSibling(target) ) return;
  199. // auto-select name of variable
  200. if ( nodeName === 'dfn' ) {
  201. kint.selectText(target);
  202. target = target.parentNode;
  203. } else if ( nodeName === 'var' ) { // stupid workaround for misc elements
  204. target = target.parentNode; // to not stop event from further propagating
  205. nodeName = target.nodeName.toLowerCase()
  206. } else if ( nodeName === 'th' ) {
  207. if ( !e.ctrlKey ) {
  208. kint.sortTable(target.parentNode.parentNode.parentNode, target.cellIndex)
  209. }
  210. return false;
  211. }
  212. // switch tabs
  213. if ( nodeName === 'li' && target.parentNode.className === 'kint-tabs' ) {
  214. if ( target.className !== 'kint-active-tab' ) {
  215. kint.switchTab(target);
  216. if ( kint.currentPlus !== -1 ) kint.fetchVisiblePluses();
  217. }
  218. return false;
  219. }
  220. // handle clicks on the navigation caret
  221. if ( nodeName === 'nav' ) {
  222. // special case for nav in footer
  223. if ( target.parentNode.nodeName.toLowerCase() === 'footer' ) {
  224. target = target.parentNode;
  225. if ( kint.hasClass(target) ) {
  226. kint.removeClass(target)
  227. } else {
  228. kint.addClass(target)
  229. }
  230. } else {
  231. // ensure doubleclick has different behaviour, see below
  232. setTimeout(function() {
  233. var timer = parseInt(target.kintTimer, 10);
  234. if ( timer > 0 ) {
  235. target.kintTimer--;
  236. } else {
  237. kint.toggleChildren(target.parentNode); // <dt>
  238. if ( kint.currentPlus !== -1 ) kint.fetchVisiblePluses();
  239. }
  240. }, 300);
  241. }
  242. e.stopPropagation();
  243. return false;
  244. } else if ( kint.hasClass(target, 'kint-parent') ) {
  245. kint.toggle(target);
  246. if ( kint.currentPlus !== -1 ) kint.fetchVisiblePluses();
  247. return false;
  248. } else if ( kint.hasClass(target, 'kint-ide-link') ) {
  249. e.preventDefault();
  250. var ajax = new XMLHttpRequest(); // add ajax call to contact editor but prevent link default action
  251. ajax.open('GET', target.href);
  252. ajax.send(null);
  253. return false;
  254. } else if ( kint.hasClass(target, 'kint-popup-trigger') ) {
  255. var kintContainer = target.parentNode;
  256. if ( kintContainer.nodeName.toLowerCase() === 'footer' ) {
  257. kintContainer = kintContainer.previousSibling;
  258. } else {
  259. while ( kintContainer && !kint.hasClass(kintContainer, 'kint-parent') ) {
  260. kintContainer = kintContainer.parentNode;
  261. }
  262. }
  263. kint.openInNewWindow(kintContainer);
  264. } else if ( nodeName === 'pre' && e.detail === 3 ) { // triple click pre to select it all
  265. kint.selectText(target);
  266. }
  267. }, false);
  268. window.addEventListener("dblclick", function( e ) {
  269. var target = e.target;
  270. if ( !kint.isSibling(target) ) return;
  271. if ( target.nodeName.toLowerCase() === 'nav' ) {
  272. target.kintTimer = 2;
  273. kint.toggleAll(target);
  274. if ( kint.currentPlus !== -1 ) kint.fetchVisiblePluses();
  275. e.stopPropagation();
  276. }
  277. }, false);
  278. // keyboard navigation
  279. window.onkeydown = function( e ) { // direct assignment is used to have priority over ex FAYT
  280. // do nothing if alt/ctrl key is pressed or if we're actually typing somewhere
  281. if ( e.target !== document.body || e.altKey || e.ctrlKey ) return;
  282. var keyCode = e.keyCode
  283. , shiftKey = e.shiftKey
  284. , i = kint.currentPlus;
  285. if ( keyCode === 68 ) { // 'd' : toggles navigation on/off
  286. if ( i === -1 ) {
  287. kint.fetchVisiblePluses();
  288. return kint.keyCallBacks.moveCursor(false, i);
  289. } else {
  290. kint.keyCallBacks.cleanup(-1);
  291. return false;
  292. }
  293. } else {
  294. if ( i === -1 ) return;
  295. if ( keyCode === 9 ) { // TAB : moves up/down depending on shift key
  296. return kint.keyCallBacks.moveCursor(shiftKey, i);
  297. } else if ( keyCode === 38 ) { // ARROW UP : moves up
  298. return kint.keyCallBacks.moveCursor(true, i);
  299. } else if ( keyCode === 40 ) { // ARROW DOWN : down
  300. return kint.keyCallBacks.moveCursor(false, i);
  301. }
  302. }
  303. var kintNode = kint.visiblePluses[i];
  304. if ( kintNode.nodeName.toLowerCase() === 'li' ) { // we're on a trace tab
  305. if ( keyCode === 32 || keyCode === 13 ) { // SPACE/ENTER
  306. kint.switchTab(kintNode);
  307. kint.fetchVisiblePluses();
  308. return kint.keyCallBacks.moveCursor(true, i);
  309. } else if ( keyCode === 39 ) { // arrows
  310. return kint.keyCallBacks.moveCursor(false, i);
  311. } else if ( keyCode === 37 ) {
  312. return kint.keyCallBacks.moveCursor(true, i);
  313. }
  314. }
  315. kintNode = kintNode.parentNode; // simple dump
  316. if ( keyCode === 32 || keyCode === 13 ) { // SPACE/ENTER : toggles
  317. kint.toggle(kintNode);
  318. kint.fetchVisiblePluses();
  319. return false;
  320. } else if ( keyCode === 39 || keyCode === 37 ) { // ARROW LEFT/RIGHT : respectively hides/shows and traverses
  321. var visible = kint.hasClass(kintNode);
  322. var hide = keyCode === 37;
  323. if ( visible ) {
  324. kint.toggleChildren(kintNode, hide); // expand/collapse all children if immediate ones are showing
  325. } else {
  326. if ( hide ) { // LEFT
  327. // traverse to parent and THEN hide
  328. do {kintNode = kintNode.parentNode} while ( kintNode && kintNode.nodeName.toLowerCase() !== 'dd' );
  329. if ( kintNode ) {
  330. kintNode = kintNode.previousElementSibling;
  331. i = -1;
  332. var parentPlus = kintNode.querySelector('nav');
  333. while ( parentPlus !== kint.visiblePluses[++i] ) {}
  334. kint.keyCallBacks.cleanup(i)
  335. } else { // we are at root
  336. kintNode = kint.visiblePluses[i].parentNode;
  337. }
  338. }
  339. kint.toggle(kintNode, hide);
  340. }
  341. kint.fetchVisiblePluses();
  342. return false;
  343. }
  344. };
  345. window.addEventListener("load", function( e ) { // colorize microtime results relative to others
  346. var elements = Array.prototype.slice.call(document.querySelectorAll('.kint-microtime'), 0);
  347. elements.forEach(function( el ) {
  348. var value = parseFloat(el.innerHTML)
  349. , min = Infinity
  350. , max = -Infinity
  351. , ratio;
  352. elements.forEach(function( el ) {
  353. var val = parseFloat(el.innerHTML);
  354. if ( min > val ) min = val;
  355. if ( max < val ) max = val;
  356. });
  357. ratio = 1 - (value - min) / (max - min);
  358. el.style.background = 'hsl(' + Math.round(ratio * 120) + ',60%,70%)';
  359. });
  360. });
  361. }
  362. // debug purposes only, removed in minified source
  363. function clg( i ) {
  364. if ( !window.console )return;
  365. var l = arguments.length, o = 0;
  366. while ( o < l )console.log(arguments[o++])
  367. }