dl dl{padding:0 0 0 15px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAgMTUwIj48ZGVmcz48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNCAzYTI0IDMyIDAgMCAxIDAgMjQgNDAgMjAtMTAgMCAxIDIzLTEyQTQwIDIwIDEwIDAgMSA0IDN6IiBpZD0iYSIvPjwvZGVmcz48ZyBmaWxsPSIjOTNhMWExIiBzdHJva2U9IiM5M2ExYTEiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxnIGZpbGw9IiM1ODZlNzUiIHN0cm9rZT0iIzU4NmU3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAzMCkiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxwYXRoIGQ9Ik02IDEyNmwxOCAxOG0tMTggMGwxOC0xOCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM1ODZlNzUiLz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #586e75}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#268bd2;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#2aa198}.kint-rich dfn{font-style:normal;font-family:monospace;color:#93a1a1}.kint-rich pre{color:#839496;margin:0 0 0 15px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #586e75;background:#002b36;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(131,148,150,.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#002b36;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#839496;background:#002b36}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #586e75;border-top-width:0;border-bottom-width:0;padding:5px;float:right !important;margin:-5px 0;color:#93a1a1;background:#073642;height:26px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#252525;opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#1b1b1b}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#073642;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-popup-trigger{background:rgba(0,0,0,0);color:#839496}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#839496;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#93a1a1;border-bottom:1px dotted #93a1a1}.kint-rich ul{list-style:none;padding-left:15px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #586e75}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 15px;padding-left:0;background:#002b36;border:1px solid #586e75;border-top:0}.kint-rich ul.kint-tabs>li{background:#073642;border:1px solid #586e75;cursor:pointer;display:inline-block;height:30px;margin:3px;padding:0 15px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#268bd2;color:#2aa198}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#002b36;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:25px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#268bd2;color:#2aa198}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #586e75;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#268bd2}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2.5px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #586e75;padding:2.5px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#073642;color:#93a1a1}.kint-rich table td{background:#002b36;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #268bd2 inset}.kint-rich table tr:hover var{color:#2aa198}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:5px;padding-bottom:5px;border-bottom:1px solid #073642}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #268bd2;padding-right:10px;margin-right:10px}.kint-rich pre.kint-source>div.kint-highlight{background:#073642}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #268bd2,0 1px #268bd2,1px 0 #268bd2,0 -1px #268bd2;color:#002b36;font-weight:bold}input.kint-note-input{width:100%}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px #268bd2 inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px}.kint-rich footer li{color:#ddd}
+.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:#073642}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:calc(100vh - 100px);padding-right:10px;overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#268bd2;color:#839496}.kint-rich .kint-focused{box-shadow:0 0 3px 3px #2aa198}.kint-rich .kint-focused.kint-weak-focus{box-shadow:0 0 3px 1px rgba(42,161,152,.5)}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#839496;float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:10px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#002b36;border:1px solid #586e75;color:#839496;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:5px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#268bd2}.kint-rich>dl dl{padding:0 0 0 15px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAgMTUwIj48ZGVmcz48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNCAzYTI0IDMyIDAgMCAxIDAgMjQgNDAgMjAtMTAgMCAxIDIzLTEyQTQwIDIwIDEwIDAgMSA0IDN6IiBpZD0iYSIvPjwvZGVmcz48ZyBmaWxsPSIjOTNhMWExIiBzdHJva2U9IiM5M2ExYTEiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxnIGZpbGw9IiM1ODZlNzUiIHN0cm9rZT0iIzU4NmU3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAzMCkiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxwYXRoIGQ9Ik02IDEyNmwxOCAxOG0tMTggMGwxOC0xOCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM1ODZlNzUiLz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #586e75}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#268bd2;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#2aa198}.kint-rich dfn{font-style:normal;font-family:monospace;color:#93a1a1}.kint-rich pre{color:#839496;margin:0 0 0 15px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #586e75;background:#002b36;display:block;word-break:normal}.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(131,148,150,.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#002b36;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#839496;background:#002b36}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #586e75;border-top-width:0;border-bottom-width:0;padding:5px;float:right !important;margin:-5px 0;color:#93a1a1;background:#073642;height:26px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#252525;opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#1b1b1b}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#073642;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#839496;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#93a1a1;border-bottom:1px dotted #93a1a1}.kint-rich ul{list-style:none;padding-left:15px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #586e75}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 15px;padding-left:0;background:#002b36;border:1px solid #586e75;border-top:0}.kint-rich ul.kint-tabs>li{background:#073642;border:1px solid #586e75;cursor:pointer;display:inline-block;height:30px;margin:3px;padding:0 15px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#268bd2;color:#2aa198}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#002b36;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:25px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#268bd2;color:#2aa198}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #586e75;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#268bd2}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2.5px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #586e75;padding:2.5px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#073642;color:#93a1a1}.kint-rich table td{background:#002b36;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #268bd2 inset}.kint-rich table tr:hover var{color:#2aa198}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:5px;padding-bottom:5px;border-bottom:1px solid #073642}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #268bd2;padding-right:10px;margin-right:10px}.kint-rich pre.kint-source>div.kint-highlight{background:#073642}.kint-rich .kint-microtime-js .kint-microtime-lap{text-shadow:-1px 0 #268bd2,0 1px #268bd2,1px 0 #268bd2,0 -1px #268bd2;color:#002b36;font-weight:bold}input.kint-note-input{width:100%}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px #268bd2 inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px}.kint-rich footer li{color:#ddd}
diff --git a/resources/compiled/solarized.css b/resources/compiled/solarized.css
index 8c1a67f08..12f61b9c0 100644
--- a/resources/compiled/solarized.css
+++ b/resources/compiled/solarized.css
@@ -1 +1 @@
-.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:rgba(255,255,255,.9)}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:calc(100vh - 100px);padding-right:10px;overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#268bd2;color:#657b83}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #2aa198}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#657b83;float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:10px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#fdf6e3;border:1px solid #93a1a1;color:#657b83;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:5px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#268bd2}.kint-rich>dl dl{padding:0 0 0 15px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAgMTUwIj48ZGVmcz48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNCAzYTI0IDMyIDAgMCAxIDAgMjQgNDAgMjAtMTAgMCAxIDIzLTEyQTQwIDIwIDEwIDAgMSA0IDN6IiBpZD0iYSIvPjwvZGVmcz48ZyBmaWxsPSIjOTNhMWExIiBzdHJva2U9IiM5M2ExYTEiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxnIGZpbGw9IiM1ODZlNzUiIHN0cm9rZT0iIzU4NmU3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAzMCkiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxwYXRoIGQ9Ik02IDEyNmwxOCAxOG0tMTggMGwxOC0xOCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM1ODZlNzUiLz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #93a1a1}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#268bd2;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#2aa198}.kint-rich dfn{font-style:normal;font-family:monospace;color:#586e75}.kint-rich pre{color:#657b83;margin:0 0 0 15px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #93a1a1;background:#fdf6e3;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(101,123,131,.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#fdf6e3;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#657b83;background:#fdf6e3}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #93a1a1;border-top-width:0;border-bottom-width:0;padding:5px;float:right !important;margin:-5px 0;color:#586e75;background:#eee8d5;height:26px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#e2e2e2;opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#f0f0f0}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#eee8d5;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer>.kint-popup-trigger{background:rgba(0,0,0,0);color:#657b83}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#657b83;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#586e75;border-bottom:1px dotted #586e75}.kint-rich ul{list-style:none;padding-left:15px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #93a1a1}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 15px;padding-left:0;background:#fdf6e3;border:1px solid #93a1a1;border-top:0}.kint-rich ul.kint-tabs>li{background:#eee8d5;border:1px solid #93a1a1;cursor:pointer;display:inline-block;height:30px;margin:3px;padding:0 15px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#268bd2;color:#2aa198}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#fdf6e3;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:25px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#268bd2;color:#2aa198}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #93a1a1;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#268bd2}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2.5px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #93a1a1;padding:2.5px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#eee8d5;color:#586e75}.kint-rich table td{background:#fdf6e3;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #268bd2 inset}.kint-rich table tr:hover var{color:#2aa198}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:5px;padding-bottom:5px;border-bottom:1px solid #eee8d5}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #268bd2;padding-right:10px;margin-right:10px}.kint-rich pre.kint-source>div.kint-highlight{background:#eee8d5}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #268bd2,0 1px #268bd2,1px 0 #268bd2,0 -1px #268bd2;color:#fdf6e3;font-weight:bold}input.kint-note-input{width:100%}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px #268bd2 inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px}
+.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:rgba(255,255,255,.9)}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:calc(100vh - 100px);padding-right:10px;overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#268bd2;color:#657b83}.kint-rich .kint-focused{box-shadow:0 0 3px 3px #2aa198}.kint-rich .kint-focused.kint-weak-focus{box-shadow:0 0 3px 1px rgba(42,161,152,.5)}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#657b83;float:none !important;font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:10px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#fdf6e3;border:1px solid #93a1a1;color:#657b83;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:5px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#268bd2}.kint-rich>dl dl{padding:0 0 0 15px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAgMTUwIj48ZGVmcz48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNCAzYTI0IDMyIDAgMCAxIDAgMjQgNDAgMjAtMTAgMCAxIDIzLTEyQTQwIDIwIDEwIDAgMSA0IDN6IiBpZD0iYSIvPjwvZGVmcz48ZyBmaWxsPSIjOTNhMWExIiBzdHJva2U9IiM5M2ExYTEiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxnIGZpbGw9IiM1ODZlNzUiIHN0cm9rZT0iIzU4NmU3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAzMCkiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxwYXRoIGQ9Ik02IDEyNmwxOCAxOG0tMTggMGwxOC0xOCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM1ODZlNzUiLz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px rgba(0,0,0,0);cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #93a1a1}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#268bd2;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#2aa198}.kint-rich dfn{font-style:normal;font-family:monospace;color:#586e75}.kint-rich pre{color:#657b83;margin:0 0 0 15px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #93a1a1;background:#fdf6e3;display:block;word-break:normal}.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(101,123,131,.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#fdf6e3;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#657b83;background:#fdf6e3}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #93a1a1;border-top-width:0;border-bottom-width:0;padding:5px;float:right !important;margin:-5px 0;color:#586e75;background:#eee8d5;height:26px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#e2e2e2;opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#f0f0f0}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#eee8d5;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:rgba(0,0,0,0)}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#657b83;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#586e75;border-bottom:1px dotted #586e75}.kint-rich ul{list-style:none;padding-left:15px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #93a1a1}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 15px;padding-left:0;background:#fdf6e3;border:1px solid #93a1a1;border-top:0}.kint-rich ul.kint-tabs>li{background:#eee8d5;border:1px solid #93a1a1;cursor:pointer;display:inline-block;height:30px;margin:3px;padding:0 15px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#268bd2;color:#2aa198}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#fdf6e3;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:25px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#268bd2;color:#2aa198}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #93a1a1;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#268bd2}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2.5px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #93a1a1;padding:2.5px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#eee8d5;color:#586e75}.kint-rich table td{background:#fdf6e3;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #268bd2 inset}.kint-rich table tr:hover var{color:#2aa198}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:5px;padding-bottom:5px;border-bottom:1px solid #eee8d5}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #268bd2;padding-right:10px;margin-right:10px}.kint-rich pre.kint-source>div.kint-highlight{background:#eee8d5}.kint-rich .kint-microtime-js .kint-microtime-lap{text-shadow:-1px 0 #268bd2,0 1px #268bd2,1px 0 #268bd2,0 -1px #268bd2;color:#fdf6e3;font-weight:bold}input.kint-note-input{width:100%}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px #268bd2 inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px}
diff --git a/resources/js/kint.js b/resources/js/kint.js
new file mode 100644
index 000000000..e9ada2d5a
--- /dev/null
+++ b/resources/js/kint.js
@@ -0,0 +1,79 @@
+import { dedupeElement, elementIsInDom, buildClassSelector } from './utils.js';
+import Rich from './rich.js';
+import Plain from './plain.js';
+import Microtime from './microtime.js';
+
+const constructor_key = Symbol();
+
+export default class Kint {
+ static #instance = null;
+
+ #window;
+ #inits = [];
+ #scriptSelectors = new Set();
+
+ static init(window) {
+ Kint.#instance ??= new Kint(window, constructor_key);
+ Kint.#instance.#removeThisScript();
+ Kint.#instance.runOnLoad(Kint.#dispatchInits);
+
+ return Kint.#instance;
+ }
+
+ get window() {
+ return this.#window;
+ }
+
+ constructor(window, key) {
+ if (constructor_key !== key) {
+ throw new Error('Kint constructor is private. Use Kint.init()');
+ }
+
+ if (!(window instanceof Window)) {
+ throw new Error('Invalid argument to Kint.init()');
+ }
+
+ this.#window = window;
+ this.runOnInit(this.#removeAllScripts.bind(this));
+
+ // Do we want to store submodules? That would be a circular reference...
+ new Plain(this);
+ new Rich(this);
+ new Microtime(this);
+ }
+
+ runOnLoad(cb) {
+ if (this.#window.document.readyState === 'complete') {
+ try {
+ cb();
+ } catch {}
+ } else {
+ this.#window.addEventListener('load', cb);
+ }
+ }
+
+ runOnInit(cb) {
+ this.#inits.push(cb);
+ }
+
+ #removeThisScript() {
+ if (this.#window.document.currentScript) {
+ this.#scriptSelectors.add(buildClassSelector(window.document.currentScript));
+ window.document.currentScript.remove();
+ }
+ }
+
+ #removeAllScripts() {
+ for (const selector of this.#scriptSelectors.keys()) {
+ for (const elem of this.#window.document.querySelectorAll(selector)) {
+ elem.remove();
+ }
+ }
+ }
+
+ static #dispatchInits() {
+ for (const init of Kint.#instance.#inits) {
+ init();
+ }
+ }
+}
diff --git a/resources/js/main.js b/resources/js/main.js
new file mode 100644
index 000000000..e24f44674
--- /dev/null
+++ b/resources/js/main.js
@@ -0,0 +1,7 @@
+import Kint from './kint.js';
+
+if (!window.Kint) {
+ window.Kint = Kint;
+}
+
+window.Kint.init(window);
diff --git a/resources/js/microtime.js b/resources/js/microtime.js
index c9cfe5772..abc58fa2c 100644
--- a/resources/js/microtime.js
+++ b/resources/js/microtime.js
@@ -1,66 +1,74 @@
-if (typeof window.kintMicrotimeInitialized === 'undefined') {
- window.kintMicrotimeInitialized = 1;
- window.addEventListener('load', function () {
- 'use strict';
+import Kint from './kint.js';
- var sums = {};
- var microtimes = Array.prototype.slice.call(
- document.querySelectorAll('[data-kint-microtime-group]'),
- 0
- );
+export default class Microtime {
+ constructor(kint) {
+ if (!(kint instanceof Kint)) {
+ throw new Error('Invalid argument to Plain.constructor()');
+ }
- microtimes.forEach(function (el) {
- if (!el.querySelector('.kint-microtime-lap')) {
- return;
- }
+ // If we do microtime stuff for ajax loads the groups
+ // from the runs will conflate and we'll get bad numbers
+ kint.runOnLoad(Microtime.#setupMicrotimes.bind(null, kint.window));
+ }
+
+ static #setupMicrotimes(window) {
+ const sums = {};
- var group = el.getAttribute('data-kint-microtime-group');
- var lap = parseFloat(el.querySelector('.kint-microtime-lap').innerHTML);
- var avg = parseFloat(el.querySelector('.kint-microtime-avg').innerHTML);
+ const elements = window.document.querySelectorAll('[data-kint-microtime-group]');
+ for (const elem of elements) {
+ const el = elem.querySelector('.kint-microtime-lap');
- if (typeof sums[group] === 'undefined') {
- sums[group] = {};
+ if (!el) {
+ continue;
}
- if (typeof sums[group].min === 'undefined' || sums[group].min > lap) {
+
+ const group = elem.getAttribute('data-kint-microtime-group');
+ const lap = parseFloat(el.textContent);
+ const avg = parseFloat(elem.querySelector('.kint-microtime-avg').textContent);
+
+ sums[group] ??= {
+ min: lap,
+ max: lap,
+ avg: avg,
+ };
+
+ if (sums[group].min > lap) {
sums[group].min = lap;
}
- if (typeof sums[group].max === 'undefined' || sums[group].max < lap) {
+ if (sums[group].max < lap) {
sums[group].max = lap;
}
sums[group].avg = avg;
- });
+ }
- microtimes.forEach(function (microtime) {
- var el = microtime.querySelector('.kint-microtime-lap');
+ for (const elem of elements) {
+ const el = elem.querySelector('.kint-microtime-lap');
- if (el === null) {
- return;
+ if (!el) {
+ continue;
}
- var value = parseFloat(el.textContent);
- var group = microtime.dataset.kintMicrotimeGroup;
- var avg = sums[group].avg;
- var max = sums[group].max;
- var min = sums[group].min;
- var ratio;
+ const lap = parseFloat(el.textContent);
+ const group = sums[elem.dataset.kintMicrotimeGroup];
- microtime.querySelector('.kint-microtime-avg').textContent = avg;
+ elem.querySelector('.kint-microtime-avg').textContent = group.avg;
- if (value === avg && value === min && value === max) {
- return; // Only one result, no need to color
+ if (lap === group.min && lap === group.max) {
+ continue; // Only one result, no need to color
}
- if (value > avg) {
- ratio = (value - avg) / (max - avg);
+ elem.classList.add('kint-microtime-js');
+
+ if (lap > group.avg) {
+ const ratio = (lap - group.avg) / (group.max - group.avg);
el.style.background = 'hsl(' + (40 - 40 * ratio) + ', 100%, 65%)';
} else {
- if (avg === min) {
- ratio = 0;
- } else {
- ratio = (avg - value) / (avg - min);
+ let ratio = 0;
+ if (group.avg !== group.min) {
+ ratio = (group.avg - lap) / (group.avg - group.min);
}
el.style.background = 'hsl(' + (40 + 80 * ratio) + ', 100%, 65%)';
}
- });
- });
+ }
+ }
}
diff --git a/resources/js/plain.js b/resources/js/plain.js
index 26e4189aa..5994a450f 100644
--- a/resources/js/plain.js
+++ b/resources/js/plain.js
@@ -1,25 +1,26 @@
-if (typeof window.kintPlain === 'undefined') {
- window.kintPlain = (function () {
- 'use strict';
+import { dedupeElement, elementIsInDom } from './utils.js';
+import Kint from './kint.js';
- var kintPlain = {
- initLoad: function () {
- kintPlain.style = window.kintShared.dedupe(
- 'style.kint-plain-style',
- kintPlain.style
- );
- kintPlain.script = window.kintShared.dedupe(
- 'script.kint-plain-script',
- kintPlain.script
- );
- },
+export default class Plain {
+ #window;
+ #style;
- style: null,
- script: null,
- };
+ constructor(kint) {
+ if (!(kint instanceof Kint)) {
+ throw new Error('Invalid argument to Plain.constructor()');
+ }
- return kintPlain;
- })();
-}
+ this.#window = kint.window;
+ kint.runOnInit(this.#dedupePlainStyle.bind(this));
+ }
+
+ #dedupePlainStyle() {
+ if (!elementIsInDom(this.#style)) {
+ this.#style = this.#window.document.querySelector('style.kint-plain-style');
+ }
-window.kintShared.runOnce(window.kintPlain.initLoad);
+ if (this.#style) {
+ dedupeElement(this.#style);
+ }
+ }
+}
diff --git a/resources/js/rich.js b/resources/js/rich.js
index 9f4d38104..ecce9063d 100644
--- a/resources/js/rich.js
+++ b/resources/js/rich.js
@@ -1,820 +1,656 @@
-if (typeof window.kintRich === 'undefined') {
- window.kintRich = (function () {
- 'use strict';
+import { dedupeElement, elementIsInDom, selectText, offsetTop } from './utils.js';
+import Kint from './kint.js';
+import Search from './search.js';
+import Table from './table.js';
- var kintRich = {
- selectText: function (element) {
- var selection = window.getSelection();
- var range = document.createRange();
+export default class Rich {
+ #kint;
+ #style;
+ #folder;
- range.selectNodeContents(element);
- selection.removeAllRanges();
- selection.addRange(range);
- },
+ constructor(kint) {
+ if (!(kint instanceof Kint)) {
+ throw new Error('Invalid argument to Rich.constructor()');
+ }
- toggle: function (element, show) {
- var parent = kintRich.getChildren(element);
+ this.#kint = kint;
+ this.#kint.runOnInit(this.#dedupeRichStyleAndSetupFolder.bind(this));
- if (!parent) {
- return;
- }
-
- element.classList.toggle('kint-show', show);
-
- if (parent.childNodes.length === 1) {
- parent = parent.childNodes[0].childNodes[0]; // reuse variable cause I can
-
- // Parent is checked for a class list in case of empty
- if (parent && parent.classList && parent.classList.contains('kint-parent')) {
- kintRich.toggle(parent, show);
- }
- }
- },
-
- toggleChildren: function (element, show) {
- var parent = kintRich.getChildren(element);
-
- if (!parent) {
- return;
- }
-
- var nodes = parent.getElementsByClassName('kint-parent');
- var i = nodes.length;
-
- if (typeof show === 'undefined') {
- show = element.classList.contains('kint-show');
- }
-
- while (i--) {
- kintRich.toggle(nodes[i], show);
- }
- },
-
- switchTab: function (target) {
- var lis;
- var el = target.previousSibling;
- var index = 0;
-
- target.parentNode
- .getElementsByClassName('kint-active-tab')[0]
- .classList.remove('kint-active-tab');
- target.classList.add('kint-active-tab');
-
- // take the index of clicked title tab and make the same n-th content tab visible
- while (el) {
- if (el.nodeType === 1) {
- index++;
- }
-
- el = el.previousSibling;
- }
-
- lis = target.parentNode.nextSibling.childNodes;
-
- for (var i = 0; i < lis.length; i++) {
- if (i === index) {
- lis[i].classList.add('kint-show');
-
- if (lis[i].childNodes.length === 1) {
- el = lis[i].childNodes[0].childNodes[0];
-
- if (el && el.classList && el.classList.contains('kint-parent')) {
- kintRich.toggle(el, true);
- }
- }
- } else {
- lis[i].classList.remove('kint-show');
- }
- }
- },
-
- // Shitty people using shitty regex fuck up the JS when they see or
- // so we have to write this obfuscation to make sure it works after minification
- mktag: function (contents) {
- return '<' + contents + '>';
- },
-
- openInNewWindow: function (kintContainer) {
- var newWindow = window.open();
-
- if (newWindow) {
- newWindow.document.open();
- newWindow.document.write(
- kintRich.mktag('html') +
- kintRich.mktag('head') +
- kintRich.mktag('title') +
- 'Kint (' +
- new Date().toISOString() +
- ')' +
- kintRich.mktag('/title') +
- kintRich.mktag('meta charset="utf-8"') +
- /**
- * `tag.getAttribute('nonce')` doesn't work for security reasons.
- * See https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce#accessing_nonces_and_nonce_hiding.
- */
- kintRich.mktag(
- 'script class="kint-rich-script" nonce="' +
- kintRich.script.nonce +
- '"'
- ) +
- kintRich.script.innerHTML +
- kintRich.mktag('/script') +
- /**
- * `tag.getAttribute('nonce')` doesn't work for security reasons.
- * See https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce#accessing_nonces_and_nonce_hiding.
- */
- kintRich.mktag(
- 'style class="kint-rich-style" nonce="' + kintRich.style.nonce + '"'
- ) +
- kintRich.style.innerHTML +
- kintRich.mktag('/style') +
- kintRich.mktag('/head') +
- kintRich.mktag('body') +
- '' +
- '' +
- kintContainer.parentNode.outerHTML +
- '
' +
- kintRich.mktag('/body')
- );
- newWindow.document.close();
- }
- },
-
- sortTable: function (table, column) {
- var tbody = table.tBodies[0];
-
- [].slice
- .call(table.tBodies[0].rows)
- .sort(function (a, b) {
- a = a.cells[column].textContent.trim().toLocaleLowerCase();
- b = b.cells[column].textContent.trim().toLocaleLowerCase();
-
- // In lieu of natsort we just sort all numbers before strings
- if (!isNaN(a) && !isNaN(b)) {
- a = parseFloat(a);
- b = parseFloat(b);
- } else if (isNaN(a) && !isNaN(b)) {
- return 1;
- } else if (isNaN(b) && !isNaN(a)) {
- return -1;
- }
-
- if (a < b) {
- return -1;
- }
- if (a > b) {
- return 1;
- }
-
- return 0;
- })
- .forEach(function (el) {
- tbody.appendChild(el);
- });
- },
-
- showAccessPath: function (target) {
- var nodes = target.childNodes;
-
- for (var i = 0; i < nodes.length; i++) {
- if (nodes[i].classList && nodes[i].classList.contains('access-path')) {
- nodes[i].classList.toggle('kint-show');
- if (nodes[i].classList.contains('kint-show')) {
- kintRich.selectText(nodes[i]);
- }
- return;
- }
- }
- },
-
- showSearchBox: function (target) {
- var input = target.querySelector('.kint-search');
-
- if (!input) {
- return;
- }
-
- input.classList.toggle('kint-show');
- if (input.classList.contains('kint-show')) {
- target.classList.add('kint-show');
- input.focus();
- input.select();
- kintRich.search(target.parentNode, input.value);
- } else {
- target.parentNode.classList.remove('kint-search-root');
- }
- },
-
- search: function (el, input) {
- el.querySelectorAll('.kint-search-match').forEach(function (match) {
- match.classList.remove('kint-search-match');
- });
- el.classList.remove('kint-search-match');
-
- el.classList.toggle('kint-search-root', input.length);
- if (input.length) {
- kintRich.findMatches(el, input);
- }
- },
-
- findMatches: function (el, term) {
- var cleaned = el.cloneNode(true);
- cleaned.querySelectorAll('.access-path').forEach(function (e) {
- e.remove();
- });
+ const ki = new KeyInput(this, kint);
+ new MouseInput(this, kint.window, ki);
+ }
- if (cleaned.textContent.toUpperCase().indexOf(term.toUpperCase()) == -1) {
- return;
- }
-
- el.classList.add('kint-search-match');
-
- var node;
-
- for (var index in el.childNodes) {
- if (el.childNodes[index].tagName == 'DD') {
- node = el.childNodes[index];
- break;
- }
- }
-
- if (!node) {
- return;
- }
+ #dedupeRichStyleAndSetupFolder() {
+ const document = this.#kint.window.document;
- var tabs;
- var tabcontents;
-
- [].forEach.call(node.childNodes, function (node) {
- if (node.tagName == 'DL') {
- kintRich.findMatches(node, term);
- } else if (node.tagName == 'UL') {
- if (node.classList.contains('kint-tabs')) {
- tabs = node.childNodes;
- } else if (node.classList.contains('kint-tab-contents')) {
- tabcontents = node.childNodes;
- }
- }
- });
-
- if (!tabs || !tabcontents || tabs.length != tabcontents.length) {
- return;
- }
-
- for (var index = 0; index < tabs.length; index++) {
- var matched = false;
+ if (!elementIsInDom(this.#style)) {
+ this.#style = document.querySelector('style.kint-rich-style');
+ }
- if (tabs[index].textContent.toUpperCase().indexOf(term.toUpperCase()) != -1) {
- matched = true;
- } else {
- cleaned = tabcontents[index].cloneNode(true);
- cleaned.querySelectorAll('.access-path').forEach(function (e) {
- e.remove();
- });
+ if (this.#style) {
+ dedupeElement(this.#style);
+ }
- if (cleaned.textContent.toUpperCase().indexOf(term.toUpperCase()) != -1) {
- matched = true;
- }
- }
-
- if (matched) {
- tabs[index].classList.add('kint-search-match');
-
- [].forEach.call(tabcontents[index].childNodes, function (node) {
- if (node.tagName == 'DL') {
- kintRich.findMatches(node, term);
- }
- });
- }
- }
- },
-
- getParentByClass: function (el, className) {
- for (;;) {
- el = el.parentNode;
-
- if (!el || !el.classList || el === document) {
- return null;
- }
-
- if (el.classList.contains(className)) {
- return el;
- }
- }
-
- return null;
- },
-
- getParentHeader: function (el, allowChildren) {
- var nodeName = el.nodeName.toLowerCase();
-
- while (
- nodeName !== 'dd' &&
- nodeName !== 'dt' &&
- kintRich.getParentByClass(el, 'kint-rich')
- ) {
- el = el.parentNode;
- nodeName = el.nodeName.toLowerCase();
- }
-
- if (!kintRich.getParentByClass(el, 'kint-rich')) {
- return null;
- }
-
- if (nodeName === 'dd' && allowChildren) {
- el = el.previousElementSibling;
- }
-
- if (
- el &&
- el.nodeName.toLowerCase() === 'dt' &&
- el.classList.contains('kint-parent')
- ) {
- return el;
- }
- },
-
- getChildren: function (element) {
- do {
- element = element.nextElementSibling;
- } while (element && element.nodeName.toLowerCase() !== 'dd');
- return element;
- },
-
- isFolderOpen: function () {
- if (!kintRich.folder || !kintRich.folder.querySelector('dd.kint-foldout')) {
- return undefined;
- }
-
- return kintRich.folder
- .querySelector('dd.kint-foldout')
- .previousSibling.classList.contains('kint-show');
- },
-
- initLoad: function () {
- kintRich.style = window.kintShared.dedupe('style.kint-rich-style', kintRich.style);
- kintRich.script = window.kintShared.dedupe(
- 'script.kint-rich-script',
- kintRich.script
- );
- kintRich.folder = window.kintShared.dedupe(
- '.kint-rich.kint-folder',
- kintRich.folder
- );
-
- var searchboxes = document.querySelectorAll('input.kint-search');
-
- [].forEach.call(searchboxes, function (input) {
- var timeout = null;
- var value = null;
-
- var searchfunc = function (e) {
- window.clearTimeout(timeout);
-
- if (input.value === value) {
- return;
- }
-
- timeout = window.setTimeout(function () {
- value = input.value;
- kintRich.search(input.parentNode.parentNode, value);
- }, 500);
- };
-
- input.removeEventListener('keyup', searchfunc);
- input.addEventListener('keyup', searchfunc);
- });
-
- if (!kintRich.folder) {
- return;
- }
+ if (!elementIsInDom(this.#folder)) {
+ this.#folder = document.querySelector('.kint-rich.kint-folder');
+ }
- var container = kintRich.folder.querySelector('dd');
+ if (this.#folder) {
+ dedupeElement(this.#folder);
- // Add kint dumps to folder
- [].forEach.call(document.querySelectorAll('.kint-rich.kint-file'), function (elem) {
- if (elem.parentNode === kintRich.folder) {
- return;
- }
+ const container = this.#folder.querySelector('dd.kint-foldout');
+ for (const elem of document.querySelectorAll('.kint-rich.kint-file')) {
+ if (elem.parentNode !== container) {
container.appendChild(elem);
- });
-
- document.body.appendChild(kintRich.folder);
-
- kintRich.folder.classList.add('kint-show');
- },
-
- keyboardNav: {
- targets: [], // all visible toggle carets
- target: 0, // currently selected caret
- active: false,
-
- fetchTargets: function () {
- var selected = kintRich.keyboardNav.targets[kintRich.keyboardNav.target];
-
- kintRich.keyboardNav.targets = [];
-
- document
- .querySelectorAll('.kint-rich nav, .kint-tabs>li:not(.kint-active-tab)')
- .forEach(function (el) {
- // Don't add targets outside of folder if folder is open
- if (kintRich.isFolderOpen() && !kintRich.folder.contains(el)) {
- return;
- }
-
- // Don't add hidden targets (Inside tabs, inside folder)
- if (el.offsetWidth !== 0 || el.offsetHeight !== 0) {
- kintRich.keyboardNav.targets.push(el);
- }
- });
-
- if (selected && kintRich.keyboardNav.targets.indexOf(selected) !== -1) {
- kintRich.keyboardNav.target =
- kintRich.keyboardNav.targets.indexOf(selected);
- }
- },
-
- sync: function (noscroll) {
- var prevElement = document.querySelector('.kint-focused');
- if (prevElement) {
- prevElement.classList.remove('kint-focused');
- }
-
- if (kintRich.keyboardNav.active) {
- var el = kintRich.keyboardNav.targets[kintRich.keyboardNav.target];
- el.classList.add('kint-focused');
-
- // Generally speaking keyboard navigation should result
- // in a scroll and mouse navigation shouldn't
- if (!noscroll) {
- kintRich.keyboardNav.scroll(el);
- }
- }
- },
-
- scroll: function (el) {
- if (kintRich.folder && el === kintRich.folder.querySelector('dt > nav')) {
- return;
- }
-
- var offsetTop = function (el) {
- return el.offsetTop + (el.offsetParent ? offsetTop(el.offsetParent) : 0);
- };
-
- var top = offsetTop(el);
-
- if (kintRich.isFolderOpen()) {
- var container = kintRich.folder.querySelector('dd.kint-foldout');
- container.scrollTo(0, top - container.clientHeight / 2);
- } else {
- window.scrollTo(0, top - window.innerHeight / 2);
- }
- },
-
- moveCursor: function (diff) {
- kintRich.keyboardNav.target += diff;
-
- while (kintRich.keyboardNav.target < 0) {
- kintRich.keyboardNav.target += kintRich.keyboardNav.targets.length;
- }
- while (kintRich.keyboardNav.target >= kintRich.keyboardNav.targets.length) {
- kintRich.keyboardNav.target -= kintRich.keyboardNav.targets.length;
- }
-
- kintRich.keyboardNav.sync();
- },
-
- setCursor: function (elem) {
- // Refuse to set cursor outside of folder if folder is open
- if (kintRich.isFolderOpen() && !kintRich.folder.contains(elem)) {
- return false;
- }
-
- kintRich.keyboardNav.fetchTargets();
-
- for (var i = 0; i < kintRich.keyboardNav.targets.length; i++) {
- if (elem === kintRich.keyboardNav.targets[i]) {
- kintRich.keyboardNav.target = i;
- return true;
- }
- }
-
- return false;
- },
- },
-
- mouseNav: {
- lastClickTarget: null,
- lastClickTimer: null,
- lastClickCount: 0,
-
- renewLastClick: function () {
- window.clearTimeout(kintRich.mouseNav.lastClickTimer);
- kintRich.mouseNav.lastClickTimer = window.setTimeout(function () {
- kintRich.mouseNav.lastClickTarget = null;
- kintRich.mouseNav.lastClickTimer = null;
- kintRich.mouseNav.lastClickCount = 0;
- }, 250);
- },
- },
-
- style: null,
- script: null,
- folder: null,
- };
-
- window.addEventListener(
- 'click',
- function (e) {
- var target = e.target;
-
- // Double/triple click to open children/all
- if (
- kintRich.mouseNav.lastClickTarget &&
- kintRich.mouseNav.lastClickTimer &&
- kintRich.mouseNav.lastClickCount
- ) {
- target = kintRich.mouseNav.lastClickTarget;
-
- if (kintRich.mouseNav.lastClickCount === 1) {
- kintRich.toggleChildren(target.parentNode);
- kintRich.keyboardNav.setCursor(target);
- kintRich.keyboardNav.sync(true);
- kintRich.mouseNav.lastClickCount++;
-
- kintRich.mouseNav.renewLastClick();
- } else {
- // Toggle all on page
- var show = target.parentNode.classList.contains('kint-show');
- var elements = document.getElementsByClassName('kint-parent');
- var i = elements.length;
-
- while (i--) {
- kintRich.toggle(elements[i], show);
- }
-
- kintRich.keyboardNav.setCursor(target);
- kintRich.keyboardNav.sync(true);
- kintRich.keyboardNav.scroll(target);
-
- window.clearTimeout(kintRich.mouseNav.lastClickTimer);
- kintRich.mouseNav.lastClickTarget = null;
- kintRich.mouseNav.lastClickTarget = null;
- kintRich.mouseNav.lastClickCount = 0;
- }
-
- return;
- }
-
- // Ignore clicks outside kint
- if (!kintRich.getParentByClass(target, 'kint-rich')) {
- return;
- }
-
- var nodeName = target.nodeName.toLowerCase();
-
- // auto-select name of variable
- if (nodeName === 'dfn') {
- kintRich.selectText(target);
- }
-
- // Sort tables
- if (nodeName === 'th') {
- if (!e.ctrlKey) {
- kintRich.sortTable(
- target.parentNode.parentNode.parentNode,
- target.cellIndex
- );
- }
- return;
- }
-
- // Ensure the nav is selected for keyboard
- target = kintRich.getParentHeader(target);
- if (target) {
- kintRich.keyboardNav.setCursor(target.querySelector('nav'));
- kintRich.keyboardNav.sync(true);
- }
-
- target = e.target;
-
- if (nodeName === 'li' && target.parentNode.className === 'kint-tabs') {
- // switch tabs
- if (target.className !== 'kint-active-tab') {
- kintRich.switchTab(target);
- }
- target = kintRich.getParentHeader(target, true);
- if (target) {
- kintRich.keyboardNav.setCursor(target.querySelector('nav'));
- kintRich.keyboardNav.sync(true);
- }
- } else if (nodeName === 'nav') {
- // handle clicks on the navigation caret
- if (target.parentNode.nodeName.toLowerCase() === 'footer') {
- kintRich.keyboardNav.setCursor(target);
- kintRich.keyboardNav.sync(true);
- target = target.parentNode;
- target.classList.toggle('kint-show');
- } else {
- // ensure double/triple click has different behaviour, see above
- kintRich.toggle(target.parentNode);
- kintRich.keyboardNav.fetchTargets();
- kintRich.mouseNav.lastClickCount = 1;
- kintRich.mouseNav.lastClickTarget = target;
- kintRich.mouseNav.renewLastClick();
- }
- } else if (target.classList.contains('kint-popup-trigger')) {
- // Popup
- var kintContainer = target.parentNode;
- if (kintContainer.nodeName.toLowerCase() === 'footer') {
- kintContainer = kintContainer.previousSibling;
- } else {
- while (kintContainer && !kintContainer.classList.contains('kint-parent')) {
- kintContainer = kintContainer.parentNode;
- }
- }
-
- kintRich.openInNewWindow(kintContainer);
- } else if (target.classList.contains('kint-access-path-trigger')) {
- // Access path
- kintRich.showAccessPath(target.parentNode);
- } else if (target.classList.contains('kint-search-trigger')) {
- // Search box
- kintRich.showSearchBox(target.parentNode);
- } else if (target.classList.contains('kint-search')) {
- // Do nothing if you click the search input
- } else if (nodeName === 'pre' && e.detail === 3) {
- // Triple click pre to select it all
- kintRich.selectText(target);
- } else if (kintRich.getParentByClass(target, 'kint-source') && e.detail === 3) {
- // Tripleclick source code to select it all
- kintRich.selectText(kintRich.getParentByClass(target, 'kint-source'));
- } else if (target.classList.contains('access-path')) {
- // Select the access path
- kintRich.selectText(target);
- } else if (nodeName !== 'a') {
- // If it's not a link at this point, we're probably clicking the bar, so toggle it
- target = kintRich.getParentHeader(target);
- if (target) {
- kintRich.toggle(target);
- kintRich.keyboardNav.fetchTargets();
- }
- }
- },
- true
- );
-
- // keyboard navigation
- window.addEventListener(
- 'keydown',
- function (e) {
- const key_a = 65;
- const key_d = 68;
- const key_h = 72;
- const key_j = 74;
- const key_k = 75;
- const key_l = 76;
- const key_tab = 9;
- const key_enter = 13;
- const key_esc = 27;
- const key_space = 32;
- const key_left = 37;
- const key_up = 38;
- const key_right = 39;
- const key_down = 40;
-
- // do nothing if alt/ctrl key is pressed or if we're actually typing somewhere
- if (e.target !== document.body || e.altKey || e.ctrlKey) {
- return;
}
+ }
+
+ this.#folder.classList.add('kint-show');
+ }
+ }
+
+ get folder() {
+ if (!elementIsInDom(this.#folder)) {
+ this.#folder = this.#kint.window.document.querySelector('.kint-rich.kint-folder');
+
+ if (this.#folder) {
+ dedupeElement(this.#folder);
+ }
+ }
+ return this.#folder;
+ }
+
+ isFolderOpen() {
+ const foldout = this.#folder?.querySelector('dd.kint-foldout');
+
+ if (!foldout) {
+ return undefined;
+ }
+
+ return foldout.previousSibling.classList.contains('kint-show');
+ }
+
+ static getChildContainer(parent) {
+ let element = parent.nextElementSibling;
+ while (element && !element.matches('dd')) {
+ element = element.nextElementSibling;
+ }
+
+ return element;
+ }
+
+ static toggle(parent, show) {
+ const childContainer = Rich.getChildContainer(parent);
+
+ if (!childContainer) {
+ return;
+ }
+
+ show = parent.classList.toggle('kint-show', show);
+ Rich.#toggleCascade(childContainer, show);
+ }
+
+ static switchTab(tab) {
+ tab.parentNode
+ .getElementsByClassName('kint-active-tab')[0]
+ .classList.remove('kint-active-tab');
+ tab.classList.add('kint-active-tab');
+
+ // take the index of clicked title tab and make the same n-th content tab visible
+ let el = tab;
+ let index = 0;
+ while ((el = el.previousElementSibling)) {
+ index++;
+ }
+
+ const tabContents = tab.parentNode.nextSibling.children;
+ for (let i = tabContents.length; i--; ) {
+ if (i === index) {
+ tabContents[i].classList.add('kint-show');
+ Rich.#toggleCascade(tabContents[i], true);
+ } else {
+ tabContents[i].classList.remove('kint-show');
+ }
+ }
+ }
+
+ static toggleChildren(parent, show) {
+ const childContainer = Rich.getChildContainer(parent);
+
+ if (!childContainer) {
+ return;
+ }
+
+ if (show === undefined) {
+ show = parent.classList.contains('kint-show');
+ }
+
+ const nodes = childContainer.getElementsByClassName('kint-parent');
+ for (const node of nodes) {
+ node.classList.toggle('kint-show', show);
+ }
+ }
+
+ static toggleAccessPath(parent, show) {
+ const ap = parent.querySelector('.access-path');
+ if (ap?.classList.toggle('kint-show', show)) {
+ selectText(ap);
+ }
+ }
+
+ static #toggleCascade(childContainer, show) {
+ if (
+ childContainer.children.length === 2 &&
+ childContainer.lastElementChild.matches('ul.kint-tab-contents')
+ ) {
+ for (const li of childContainer.lastElementChild.children) {
+ if (li.matches('li.kint-show')) {
+ childContainer = li;
+ }
+ }
+ }
+
+ if (
+ childContainer.children.length === 1 &&
+ childContainer.firstElementChild.matches('dl')
+ ) {
+ const parent = childContainer?.firstElementChild?.firstElementChild;
+
+ // Parent is checked for a class list in case of empty
+ if (parent?.classList?.contains('kint-parent')) {
+ Rich.toggle(parent, show);
+ }
+ }
+ }
+}
- if (e.keyCode === key_d) {
- // Toggles navigation on/off
- if (kintRich.keyboardNav.active) {
- kintRich.keyboardNav.active = false;
- } else {
- kintRich.keyboardNav.active = true;
- kintRich.keyboardNav.fetchTargets();
-
- if (kintRich.keyboardNav.targets.length === 0) {
- kintRich.keyboardNav.active = false;
- return;
- }
- }
+class MouseInput {
+ #rich;
+ #keyInput;
+ #window;
+ #lastClickTimer = null;
+ #lastClickTarget = null;
+ #lastClickCount = 0;
+
+ constructor(rich, window, keyInput) {
+ this.#rich = rich;
+ this.#keyInput = keyInput;
+ this.#window = window;
+ this.#window.addEventListener('click', this.#clickHandler.bind(this), true);
+ }
+
+ #renewClickTimeout() {
+ clearTimeout(this.#lastClickTimer);
+ this.#lastClickTimer = setTimeout(this.#resetClickTimeout.bind(this), 250);
+ }
+
+ #resetClickTimeout() {
+ clearTimeout(this.#lastClickTimer);
+ this.#lastClickTimer = null;
+ this.#lastClickTarget = null;
+ this.#lastClickCount = 0;
+ }
+
+ #handleMultiClicks() {
+ const target = this.#lastClickTarget;
+
+ if (!target.matches('.kint-parent > nav')) {
+ return;
+ }
+
+ const parent = target.parentNode;
+
+ if (this.#lastClickCount === 1) {
+ Rich.toggleChildren(parent);
+ this.#keyInput.onTreeChanged();
+
+ this.#renewClickTimeout();
+ this.#lastClickCount = 2;
+ } else if (this.#lastClickCount === 2) {
+ this.#resetClickTimeout();
+
+ const show = parent.classList.contains('kint-show');
+
+ const foldout = this.#rich.folder?.querySelector('.kint-parent');
+ const nodes = this.#window.document.getElementsByClassName('kint-parent');
+ for (const node of nodes) {
+ if (node !== foldout) {
+ node.classList.toggle('kint-show', show);
+ }
+ }
+
+ this.#keyInput.onTreeChanged();
+ // When unfolding the entire page you frequently end up somewhere
+ // else. By scrolling to the thing you opened it's much easier to
+ // see where you are
+ this.#keyInput.scrollToFocus();
+ }
+
+ return;
+ }
+
+ #clickHandler(e) {
+ // Double/triple click to open children/all
+ if (this.#lastClickCount) {
+ this.#handleMultiClicks();
+ return;
+ }
+
+ const target = e.target;
+
+ // Ignore clicks outside kint
+ if (!target.closest('.kint-rich')) {
+ return;
+ }
+
+ // auto-select name of variable
+ if (target.tagName === 'DFN') {
+ selectText(target);
+ }
+
+ // Sort tables
+ if (target.tagName === 'TH') {
+ if (!e.ctrlKey) {
+ Table.sort(target.closest('table'), target.cellIndex);
+ }
+ return;
+ }
+
+ const parent = target.closest('.kint-parent');
+
+ if (target.tagName === 'LI' && target.parentNode.className === 'kint-tabs') {
+ // switch tabs
+ if (target.className !== 'kint-active-tab') {
+ const cursor = target.closest('dl')?.querySelector('.kint-parent > nav') ?? target;
+ this.#keyInput.setCursor(cursor);
+ Rich.switchTab(target);
+ this.#keyInput.onTreeChanged();
+ }
+
+ return;
+ }
+
+ if (target.tagName === 'NAV') {
+ // handle clicks on the nav
+ if (target.parentNode.tagName === 'FOOTER') {
+ this.#keyInput.setCursor(target);
+ target.parentNode.classList.toggle('kint-show');
+ } else if (parent) {
+ // ensure double/triple click has different behaviour, see above
+ Rich.toggle(parent);
+ this.#keyInput.setCursor(target);
+ this.#keyInput.onTreeChanged();
+ this.#renewClickTimeout();
+ this.#lastClickCount = 1;
+ this.#lastClickTarget = target;
+ }
+ } else if (target.classList.contains('kint-access-path-trigger')) {
+ // Access path
+ const bar = target.closest('.kint-rich dt');
+ if (bar) {
+ Rich.toggleAccessPath(bar);
+ }
+ } else if (target.classList.contains('kint-search-trigger')) {
+ // Search box
+ if (parent) {
+ Search.toggleSearchBox(parent);
+ }
+ } else if (target.classList.contains('kint-search')) {
+ // Do nothing if you click the search input
+ } else if (target.tagName === 'PRE' && e.detail === 3) {
+ // Triple click pre to select it all
+ selectText(target);
+ } else if (target.closest('.kint-source') && e.detail === 3) {
+ // Tripleclick source code to select it all
+ selectText(target.closest('.kint-source'));
+ } else if (target.classList.contains('access-path')) {
+ // Select the access path
+ selectText(target);
+ } else if (target.tagName !== 'A') {
+ // If it's not a link at this point, we're probably clicking the bar, so toggle it
+ if (parent) {
+ Rich.toggle(parent);
+ this.#keyInput.setCursor(parent.querySelector('nav'));
+ this.#keyInput.onTreeChanged();
+ }
+ }
+ }
+}
- kintRich.keyboardNav.sync();
- e.preventDefault();
- return;
- } else if (!kintRich.keyboardNav.active) {
- return;
- } else if (e.keyCode === key_tab) {
- // Moves up/down depending on shift key
- kintRich.keyboardNav.moveCursor(e.shiftKey ? -1 : 1);
- e.preventDefault();
+const key_a = 65;
+const key_d = 68;
+const key_h = 72;
+const key_j = 74;
+const key_k = 75;
+const key_l = 76;
+const key_s = 83;
+const key_tab = 9;
+const key_enter = 13;
+const key_esc = 27;
+const key_space = 32;
+const key_left = 37;
+const key_up = 38;
+const key_right = 39;
+const key_down = 40;
+
+class KeyInput {
+ #targets = []; // all visible toggle navs
+ #target = 0; // currently selected nav
+ #active = false;
+ #rich;
+ #window;
+
+ constructor(rich, kint) {
+ this.#rich = rich;
+ this.#window = kint.window;
+
+ this.#window.addEventListener('keydown', this.#handlePress.bind(this), true);
+
+ // Recalc tree on init so you don't have to leave
+ // keyboard control to fix the target list
+ kint.runOnInit(this.onTreeChanged.bind(this));
+ }
+
+ scrollToFocus() {
+ const el = this.#targets[this.#target];
+ if (!el) {
+ return;
+ }
+
+ const folder = this.#rich.folder;
+ if (el === folder?.querySelector('.kint-parent > nav')) {
+ return;
+ }
+
+ const top = offsetTop(el);
+ if (this.#rich.isFolderOpen()) {
+ const container = folder.querySelector('dd.kint-foldout');
+ container.scrollTo(0, top - container.clientHeight / 2);
+ } else {
+ this.#window.scrollTo(0, top - this.#window.innerHeight / 2);
+ }
+ }
+
+ onTreeChanged() {
+ const selected = this.#targets[this.#target];
+
+ this.#targets = [];
+
+ const folder = this.#rich.folder;
+ const folderNav = folder?.querySelector('.kint-parent > nav');
+
+ let container = this.#window.document;
+ if (this.#rich.isFolderOpen()) {
+ container = folder;
+ this.#targets.push(folderNav);
+ }
+
+ for (const el of container.querySelectorAll(
+ '.kint-rich nav, .kint-tabs>li:not(.kint-active-tab)'
+ )) {
+ // Don't add hidden targets (Inside tabs, inside folder)
+ //
+ // In my tests using selectors instead of offsetParent makes this
+ // process go much faster, but the reflow still has to happen and
+ // all you're doing is pushing it further down the road. Using
+ // offsetParent forces the reflow to happen here for the first time
+ // but that's ok because it has to happen anyway (And also for
+ // scrollToFocus) so you might as well get it over with now and
+ // simplify the code.
+ if (el.offsetParent !== null && el !== folderNav) {
+ this.#targets.push(el);
+ }
+ }
+
+ if (folderNav && !this.#rich.isFolderOpen()) {
+ this.#targets.push(folderNav);
+ }
+
+ if (this.#targets.length === 0) {
+ this.#active = false;
+ this.#onCursorChanged();
+ return;
+ }
+
+ if (selected && this.#targets.indexOf(selected) !== -1) {
+ this.#target = this.#targets.indexOf(selected);
+ } else {
+ // We leave the index as is if we can't find the element any more
+ // because at this point we're probably looking at a tab and we're
+ // fine with it switching to a neighbor when activated
+ this.#onCursorChanged();
+ }
+ }
+
+ setCursor(target) {
+ // Refuse to set cursor outside of folder if folder is open
+ if (this.#rich.isFolderOpen() && !this.#rich.folder.contains(target)) {
+ return false;
+ }
+
+ let i = this.#targets.indexOf(target);
+
+ // If we're still loading, refresh the tree to ensure the cursor is set
+ if (i === -1 && this.#window.document.readyState !== 'complete') {
+ this.onTreeChanged();
+ i = this.#targets.indexOf(target);
+ }
+
+ if (i !== -1) {
+ if (i !== this.#target) {
+ this.#target = i;
+ this.#onCursorChanged();
+ return true;
+ } else {
+ this.#targets[i]?.classList.remove('kint-weak-focus');
+ }
+ }
+
+ return false;
+ }
+
+ #moveCursor(diff) {
+ if (this.#targets.length === 0) {
+ this.#target = 0;
+ return null;
+ }
+
+ this.#target += diff;
+
+ while (this.#target < 0) {
+ this.#target += this.#targets.length;
+ }
+ while (this.#target >= this.#targets.length) {
+ this.#target -= this.#targets.length;
+ }
+
+ this.#onCursorChanged();
+
+ return this.#target;
+ }
+
+ #onCursorChanged() {
+ const prevElement = this.#window.document.querySelector('.kint-focused');
+ if (prevElement) {
+ prevElement.classList.remove('kint-focused');
+ prevElement.classList.remove('kint-weak-focus');
+ }
+
+ if (this.#active) {
+ this.#targets[this.#target]?.classList.add('kint-focused');
+ }
+ }
+
+ #handlePress(e) {
+ if (this.#active && e.keyCode === key_esc && e.target.matches('.kint-search')) {
+ e.target.blur();
+ this.#onCursorChanged();
+ return;
+ }
+
+ // do nothing if alt/ctrl key is pressed or if we're actually typing somewhere
+ if (e.target !== this.#window.document.body || e.altKey || e.ctrlKey) {
+ return;
+ }
+
+ // Activation logic
+ if (e.keyCode === key_d) {
+ // Toggles navigation on/off
+ if (this.#active) {
+ this.#active = false;
+ } else {
+ this.#active = true;
+ this.onTreeChanged();
+
+ if (this.#targets.length === 0) {
+ this.#active = false;
return;
- } else if (e.keyCode === key_up || e.keyCode === key_k) {
- // Moves up
- kintRich.keyboardNav.moveCursor(-1);
- e.preventDefault();
- return;
- } else if (e.keyCode === key_down || e.keyCode === key_j) {
- // Moves down
- kintRich.keyboardNav.moveCursor(1);
- e.preventDefault();
- return;
- }
-
- var kintNode = kintRich.keyboardNav.targets[kintRich.keyboardNav.target];
- if (kintNode.nodeName.toLowerCase() === 'li') {
- // When we're on a tab
- if (e.keyCode === key_space || e.keyCode === key_enter) {
- // Toggle to it
- kintRich.switchTab(kintNode);
- kintRich.keyboardNav.fetchTargets();
- kintRich.keyboardNav.sync();
- e.preventDefault();
- return;
- } else if (e.keyCode === key_right || e.keyCode === key_l) {
- // Move right
- kintRich.keyboardNav.moveCursor(1);
- e.preventDefault();
- return;
- } else if (e.keyCode === key_left || e.keyCode === key_h) {
- // Move left
- kintRich.keyboardNav.moveCursor(-1);
- e.preventDefault();
- return;
- }
}
- // simple dump
- kintNode = kintNode.parentNode;
-
- if (e.keyCode === key_a) {
- // Toggles access path on/off
- kintRich.showAccessPath(kintNode);
- e.preventDefault();
+ this.scrollToFocus();
+ }
+
+ this.#onCursorChanged();
+ e.preventDefault();
+ return;
+ } else if (e.keyCode === key_esc) {
+ if (this.#active) {
+ this.#active = false;
+ this.#onCursorChanged();
+ e.preventDefault();
+ }
+ return;
+ } else if (!this.#active) {
+ return;
+ }
+
+ e.preventDefault();
+
+ const target = this.#targets[this.#target];
+
+ // If something detaches all the nodes we need to regenerate the tree
+ if (!elementIsInDom(target)) {
+ this.onTreeChanged();
+ }
+
+ // Basic movement logic
+ if ([key_tab, key_up, key_k, key_down, key_j].includes(e.keyCode)) {
+ if (e.keyCode === key_tab) {
+ // Moves up/down depending on shift key
+ this.#moveCursor(e.shiftKey ? -1 : 1);
+ } else if (e.keyCode === key_up || e.keyCode === key_k) {
+ // Moves up
+ this.#moveCursor(-1);
+ } else if (e.keyCode === key_down || e.keyCode === key_j) {
+ // Moves down
+ this.#moveCursor(1);
+ }
+
+ this.scrollToFocus();
+ return;
+ }
+
+ // Tab logic
+ if (
+ target.tagName === 'LI' &&
+ [key_space, key_enter, key_right, key_l, key_left, key_h].includes(e.keyCode)
+ ) {
+ // When we're on a tab
+ if (e.keyCode === key_space || e.keyCode === key_enter) {
+ // Toggle to it
+ Rich.switchTab(target);
+ this.onTreeChanged();
+ } else if (e.keyCode === key_right || e.keyCode === key_l) {
+ // Move right
+ this.#moveCursor(1);
+ } else if (e.keyCode === key_left || e.keyCode === key_h) {
+ // Move left
+ this.#moveCursor(-1);
+ }
+
+ this.scrollToFocus();
+ return;
+ }
+
+ const parent = target.closest('.kint-parent');
+ if (!parent) {
+ return;
+ }
+
+ if (e.keyCode === key_a) {
+ // Toggles access path on/off
+ Rich.toggleAccessPath(parent);
+ return;
+ }
+
+ if (e.keyCode === key_s) {
+ // Enables search
+ const topParent = parent
+ .closest('.kint-rich > dl')
+ ?.querySelector('.kint-search')
+ ?.closest('.kint-parent');
+
+ if (topParent) {
+ target.classList.add('kint-weak-focus');
+ Search.toggleSearchBox(topParent, true);
+ return;
+ }
+ }
+
+ if (target.parentNode.tagName === 'FOOTER' && target.closest('.kint-rich')) {
+ // Minitrace needs special class handling
+ if (e.keyCode === key_space || e.keyCode === key_enter) {
+ target.parentNode.classList.toggle('kint-show');
+ } else if (e.keyCode === key_left || e.keyCode === key_h) {
+ target.parentNode.classList.remove('kint-show');
+ } else if (e.keyCode === key_right || e.keyCode === key_l) {
+ target.parentNode.classList.add('kint-show');
+ }
+ return;
+ }
+
+ if (e.keyCode === key_space || e.keyCode === key_enter) {
+ // Toggle for normal nav
+ Rich.toggle(parent);
+ this.onTreeChanged();
+ return;
+ }
+
+ if ([key_right, key_l, key_left, key_h].includes(e.keyCode)) {
+ // Left hides, right opens
+ const show = e.keyCode === key_right || e.keyCode === key_l;
+ const isOpen = parent.classList.contains('kint-show');
+
+ if (show) {
+ // If the target is open
+ if (isOpen) {
+ // Expand/collapse all children first
+ Rich.toggleChildren(parent, show);
+ }
+ // Otherwise just expand the current one
+ Rich.toggle(parent, show);
+ this.onTreeChanged();
+ return;
+ } else {
+ if (isOpen) {
+ // Close the target and all children
+ Rich.toggleChildren(parent, show);
+ Rich.toggle(parent, show);
+ this.onTreeChanged();
return;
- } else if (
- kintNode.nodeName.toLowerCase() === 'footer' &&
- kintNode.parentNode.classList.contains('kint-rich')
- ) {
- // Minitrace needs special class handling
- if (e.keyCode === key_space || e.keyCode === key_enter) {
- kintNode.classList.toggle('kint-show');
- e.preventDefault();
- } else if (e.keyCode === key_left || e.keyCode === key_h) {
- kintNode.classList.remove('kint-show');
- e.preventDefault();
- } else if (e.keyCode === key_right || e.keyCode === key_l) {
- kintNode.classList.add('kint-show');
- e.preventDefault();
+ } else {
+ // If it's already closed find the next highest parent
+ const highTarget = parent
+ .closest('.kint-rich .kint-parent ~ dd')
+ ?.parentNode.querySelector('.kint-parent > nav');
+ if (highTarget) {
+ this.setCursor(highTarget);
+ this.scrollToFocus();
}
return;
- } else if (e.keyCode === key_space || e.keyCode === key_enter) {
- // Toggle for normal nav
- kintRich.toggle(kintNode);
- kintRich.keyboardNav.fetchTargets();
- e.preventDefault();
- return;
- } else if (
- e.keyCode === key_right ||
- e.keyCode === key_l ||
- e.keyCode === key_left ||
- e.keyCode === key_h
- ) {
- // Left hides, right opens
- var show = e.keyCode === key_right || e.keyCode === key_l;
-
- // If the target is open
- if (kintNode.classList.contains('kint-show')) {
- // Expand/collapse all children first
- kintRich.toggleChildren(kintNode, show);
- } else if (!show) {
- // If the target is already closed and we press left,
- // then traverse to parent and close it instead
- var parent = kintRich.getParentHeader(kintNode.parentNode.parentNode, true);
-
- if (parent) {
- kintNode = parent;
- kintRich.keyboardNav.setCursor(kintNode.querySelector('nav'));
- kintRich.keyboardNav.sync();
- }
- }
-
- kintRich.toggle(kintNode, show);
-
- kintRich.keyboardNav.fetchTargets();
- e.preventDefault();
- return;
}
- },
- true
- );
-
- return kintRich;
- })();
+ }
+ }
+ }
}
-
-window.kintShared.runOnce(window.kintRich.initLoad);
diff --git a/resources/js/search.js b/resources/js/search.js
new file mode 100644
index 000000000..e6045e2fc
--- /dev/null
+++ b/resources/js/search.js
@@ -0,0 +1,140 @@
+import { debounce } from './utils.js';
+import Rich from './rich.js';
+
+export default class Search {
+ static #hookedInputs = new Set();
+
+ static toggleSearchBox(parent, show) {
+ const input = parent.querySelector('.kint-search');
+ const root = parent.parentNode;
+
+ if (!input) {
+ return;
+ }
+
+ if (input.classList.toggle('kint-show', show)) {
+ input.focus();
+ input.select();
+
+ if (!Search.#hookedInputs.has(input)) {
+ // If it's a really big dump (eg. symfony container without
+ // depth limit) up the debounce time or it'll be unworkable
+ const subcount = root.querySelectorAll('dl').length;
+ let time = 200;
+ if (subcount > 10000) {
+ time = 700;
+ }
+
+ input.addEventListener('keyup', debounce(Search.#search.bind(null, input), time));
+ Search.#hookedInputs.add(input);
+ }
+
+ Search.#search(input);
+ } else {
+ root.classList.remove('kint-search-root');
+ }
+ }
+
+ static #search(input) {
+ const root = input.closest('.kint-parent')?.parentNode;
+
+ if (!root) {
+ return;
+ }
+
+ if (input.classList.contains('kint-show') && input.value.length) {
+ const lastSearch = root.dataset.lastSearch;
+ root.classList.add('kint-search-root');
+
+ if (lastSearch !== input.value) {
+ root.dataset.lastSearch = input.value;
+
+ root.classList.remove('kint-search-match');
+ for (const element of root.querySelectorAll('.kint-search-match')) {
+ element.classList.remove('kint-search-match');
+ }
+
+ Search.#findMatches(root, input.value.toUpperCase());
+ }
+ } else {
+ root.classList.remove('kint-search-root');
+ }
+ }
+
+ static #findMatches(container, term) {
+ const cleaned = container.cloneNode(true);
+ for (const ap of cleaned.querySelectorAll('.access-path')) {
+ ap.remove();
+ }
+
+ if (!cleaned.textContent.toUpperCase().includes(term)) {
+ return;
+ }
+
+ container.classList.add('kint-search-match');
+
+ let parent = container.firstElementChild;
+ while (parent && parent.tagName !== 'DT') {
+ parent = parent.nextElementSibling;
+ }
+
+ if (!parent) {
+ return;
+ }
+
+ const childContainer = Rich.getChildContainer(parent);
+ if (!childContainer) {
+ return;
+ }
+
+ let tabs;
+ let tabContents;
+
+ for (const child of childContainer.children) {
+ if (child.tagName === 'DL') {
+ Search.#findMatches(child, term);
+ } else if (child.tagName === 'UL') {
+ if (child.classList.contains('kint-tabs')) {
+ tabs = child.childNodes;
+ } else if (child.classList.contains('kint-tab-contents')) {
+ tabContents = child.childNodes;
+ }
+ }
+ }
+
+ if (!tabs || tabs.length !== tabContents?.length) {
+ return;
+ }
+
+ for (let index = tabs.length; index--; ) {
+ let matchedTab = false;
+ let matchedTabContents = false;
+
+ if (tabs[index].textContent.toUpperCase().includes(term)) {
+ matchedTab = true;
+ }
+
+ const cleaned = tabContents[index].cloneNode(true);
+ for (const ap of cleaned.querySelectorAll('.access-path')) {
+ ap.remove();
+ }
+
+ if (cleaned.textContent.toUpperCase().includes(term)) {
+ matchedTab = true;
+ matchedTabContents = true;
+ }
+
+ if (matchedTab) {
+ tabs[index].classList.add('kint-search-match');
+ }
+
+ if (matchedTabContents) {
+ for (const child of tabContents[index].children) {
+ if (child.tagName === 'DL') {
+ Search.#findMatches(child, term);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/resources/js/shared.js b/resources/js/shared.js
deleted file mode 100644
index 46218683e..000000000
--- a/resources/js/shared.js
+++ /dev/null
@@ -1,43 +0,0 @@
-if (typeof window.kintShared === 'undefined') {
- window.kintShared = (function () {
- 'use strict';
-
- var kintShared = {
- dedupe: function (selector, keep) {
- [].forEach.call(document.querySelectorAll(selector), function (elem) {
- if (!keep || !keep.ownerDocument.contains(keep)) {
- keep = elem;
- }
-
- if (elem !== keep) {
- elem.parentNode.removeChild(elem);
- }
- });
-
- return keep;
- },
-
- runOnce: function (cb) {
- if (document.readyState === 'complete') {
- cb();
- } else {
- window.addEventListener('load', cb);
- }
- },
- };
-
- window.addEventListener('click', function (e) {
- 'use strict';
-
- // add ajax call to contact editor but prevent link default action
- if (e.target.classList.contains('kint-ide-link')) {
- var ajax = new XMLHttpRequest();
- ajax.open('GET', e.target.href);
- ajax.send(null);
- e.preventDefault();
- }
- });
-
- return kintShared;
- })();
-}
diff --git a/resources/js/table.js b/resources/js/table.js
new file mode 100644
index 000000000..fe402a0fd
--- /dev/null
+++ b/resources/js/table.js
@@ -0,0 +1,37 @@
+export default class Table {
+ static sort(table, column) {
+ const curSort = table.dataset.kintTableSort;
+ const order = parseInt(curSort) === column ? -1 : 1;
+ const tbody = table.tBodies[0];
+
+ [...tbody.rows]
+ .sort(function (a, b) {
+ a = a.cells[column].textContent.trim().toLocaleLowerCase();
+ b = b.cells[column].textContent.trim().toLocaleLowerCase();
+
+ let diff = 0;
+
+ // In lieu of natsort we just sort all numbers before strings
+ if (!isNaN(a) && !isNaN(b)) {
+ a = parseFloat(a);
+ b = parseFloat(b);
+ diff = a - b;
+ } else if (isNaN(a) && !isNaN(b)) {
+ diff = 1;
+ } else if (isNaN(b) && !isNaN(a)) {
+ diff = -1;
+ } else {
+ diff = ('' + a).localeCompare('' + b);
+ }
+
+ return diff * order;
+ })
+ .forEach((el) => tbody.appendChild(el));
+
+ if (order < 0) {
+ table.dataset.kintTableSort = null;
+ } else {
+ table.dataset.kintTableSort = column;
+ }
+ }
+}
diff --git a/resources/js/utils.js b/resources/js/utils.js
new file mode 100644
index 000000000..a93aaccfb
--- /dev/null
+++ b/resources/js/utils.js
@@ -0,0 +1,66 @@
+export function dedupeElement(element) {
+ if (!(element instanceof Element)) {
+ throw new Error('Invalid argument to dedupeElement()');
+ }
+
+ const document = element.ownerDocument;
+ const selector = buildClassSelector(element);
+
+ for (const elem of document.querySelectorAll(selector)) {
+ if (element !== elem) {
+ elem.parentNode.removeChild(elem);
+ }
+ }
+}
+
+// Why would we need this? Because if someone naively rewrites the dom
+// with something like `body.innerHTML += x` all our node references
+// will be detached and we'll need to reaquire them somehow
+export function elementIsInDom(element) {
+ if (!(element instanceof Element)) {
+ return false;
+ }
+
+ return element.ownerDocument.contains(element);
+}
+
+export function buildClassSelector(element) {
+ if (!(element instanceof Element)) {
+ throw new Error('Invalid argument to buildClassSelector()');
+ }
+
+ return [element.nodeName, ...element.classList].join('.');
+}
+
+export function selectText(element) {
+ if (!(element instanceof Element)) {
+ throw new Error('Invalid argument to selectText()');
+ }
+
+ const document = element.ownerDocument;
+ const selection = document.getSelection();
+ const range = document.createRange();
+
+ range.selectNodeContents(element);
+ selection.removeAllRanges();
+ selection.addRange(range);
+}
+
+export function debounce(cb, time) {
+ let timeout;
+ return function (...args) {
+ clearTimeout(timeout);
+
+ timeout = setTimeout(function () {
+ cb(...args);
+ }, time);
+ };
+}
+
+export function offsetTop(element) {
+ if (!(element instanceof Element)) {
+ throw new Error('Invalid argument to offsetTop()');
+ }
+
+ return element.offsetTop + (element.offsetParent ? offsetTop(element.offsetParent) : 0);
+}
diff --git a/resources/sass/_base.scss b/resources/sass/_base.scss
index 2f4416b4f..17f2caafc 100644
--- a/resources/sass/_base.scss
+++ b/resources/sass/_base.scss
@@ -58,7 +58,11 @@ $caret-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5
}
.kint-focused {
- box-shadow: 0 0 3px 2px $variable-type-color-hover;
+ box-shadow: 0 0 3px 3px $variable-type-color-hover;
+
+ &.kint-weak-focus {
+ box-shadow: 0 0 3px 1px rgba($variable-type-color-hover, 0.5);
+ }
}
&,
@@ -187,7 +191,6 @@ $caret-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5
word-break: normal;
}
- .kint-popup-trigger,
.kint-access-path-trigger,
.kint-search-trigger {
background: rgba($text-color, 0.8);
@@ -213,12 +216,6 @@ $caret-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5
}
}
- // The ⧉ icon is slightly higher than the ⇆ icon,
- // so increase the line height to make it line out better
- dt.kint-parent > .kint-popup-trigger {
- line-height: $color_size * 1.2 * 1px;
- }
-
// The ⌕ icon is slightly smaller than the ⇆ icon,
// so make it a bit bigger to line it out better
.kint-search-trigger {
@@ -280,11 +277,6 @@ $caret-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5
font-size: 9px;
background: transparent;
- > .kint-popup-trigger {
- background: transparent;
- color: $text-color;
- }
-
nav {
height: 10px;
width: 10px;
@@ -509,7 +501,7 @@ $caret-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5
}
// Microtime representation
- .kint-microtime-lap {
+ .kint-microtime-js .kint-microtime-lap {
text-shadow:
-1px 0 $border-color-hover,
0 1px $border-color-hover,
diff --git a/resources/sass/plain.scss b/resources/sass/plain.scss
index da6dcd49a..574263f77 100644
--- a/resources/sass/plain.scss
+++ b/resources/sass/plain.scss
@@ -16,12 +16,13 @@
font-weight: bold;
}
- .kint-microtime-lap {
- font-weight: bold;
+ .kint-microtime-js .kint-microtime-lap {
text-shadow:
- 1px 0 #fff,
- 0 1px #fff,
- -1px 0 #fff,
- 0 -1px #fff;
+ 1px 0 #d00,
+ 0 1px #d00,
+ -1px 0 #d00,
+ 0 -1px #d00;
+ color: #fff;
+ font-weight: bold;
}
}
diff --git a/src/Renderer/PlainRenderer.php b/src/Renderer/PlainRenderer.php
index 09befebfe..f40441f01 100644
--- a/src/Renderer/PlainRenderer.php
+++ b/src/Renderer/PlainRenderer.php
@@ -28,7 +28,6 @@
namespace Kint\Renderer;
use Kint\Kint;
-use Kint\Renderer\Text\MicrotimePlugin;
use Kint\Zval\BlobValue;
use Kint\Zval\Value;
@@ -37,7 +36,6 @@ class PlainRenderer extends TextRenderer
public static array $pre_render_sources = [
'script' => [
[self::class, 'renderJs'],
- [MicrotimePlugin::class, 'renderJs'],
],
'style' => [
[self::class, 'renderCss'],
@@ -186,13 +184,7 @@ public function ideLink(string $file, int $line): string
return $path;
}
- $class = '';
-
- if (\preg_match('/https?:\\/\\//i', $ideLink)) {
- $class = 'class="kint-ide-link" ';
- }
-
- return 'escape($ideLink).'">'.$path.'';
+ return ''.$path.'';
}
public function escape(string $string, $encoding = false): string
@@ -228,7 +220,7 @@ protected function utf8ToHtmlentity(string $string): string
protected static function renderJs(): string
{
- return \file_get_contents(KINT_DIR.'/resources/compiled/shared.js').\file_get_contents(KINT_DIR.'/resources/compiled/plain.js');
+ return \file_get_contents(KINT_DIR.'/resources/compiled/main.js');
}
protected static function renderCss(): string
diff --git a/src/Renderer/Rich/MicrotimePlugin.php b/src/Renderer/Rich/MicrotimePlugin.php
index 086e81447..66468772a 100644
--- a/src/Renderer/Rich/MicrotimePlugin.php
+++ b/src/Renderer/Rich/MicrotimePlugin.php
@@ -62,13 +62,4 @@ public function renderTab(Representation $r): ?string
return ''.$out.'
';
}
-
- public static function renderJs(): string
- {
- if (\is_string($out = \file_get_contents(KINT_DIR.'/resources/compiled/microtime.js'))) {
- return $out;
- }
-
- return '';
- }
}
diff --git a/src/Renderer/RichRenderer.php b/src/Renderer/RichRenderer.php
index 1113a8147..cb0077ebb 100644
--- a/src/Renderer/RichRenderer.php
+++ b/src/Renderer/RichRenderer.php
@@ -78,7 +78,6 @@ class RichRenderer extends AbstractRenderer
public static array $pre_render_sources = [
'script' => [
[self::class, 'renderJs'],
- [Rich\MicrotimePlugin::class, 'renderJs'],
],
'style' => [
[self::class, 'renderCss'],
@@ -273,8 +272,6 @@ public function renderHeaderWrapper(Value $o, bool $has_children, string $conten
}
if ($has_children) {
- $out .= '';
-
if (0 === $o->depth) {
$out .= '⌕';
$out .= '';
@@ -463,8 +460,6 @@ public function postRender(): string
}
$output = '