Packages
plug
1.15.2
1.20.3
1.20.2
1.20.1
retired
1.20.0
retired
1.19.5
1.19.4
1.19.3
1.19.2
1.19.1
1.19.0
1.18.5
1.18.4
1.18.3
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.6
1.16.5
1.16.4
1.16.3
1.16.2
1.16.1
1.16.0
1.15.6
1.15.5
1.15.4
1.15.3
1.15.2
1.15.1
1.15.0
1.14.2
1.14.1
1.14.0
1.13.6
1.13.5
1.13.4
1.13.3
1.13.2
1.13.1
retired
1.13.0
retired
1.12.1
1.12.0
1.11.1
1.11.0
1.10.4
1.10.3
1.10.2
1.10.1
1.10.0
1.9.0
1.8.3
1.8.2
1.8.1
1.8.0
1.7.2
1.7.1
1.7.0
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.1
1.5.0
1.5.0-rc.2
1.5.0-rc.1
1.5.0-rc.0
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.4.0-rc.0
1.3.6
1.3.5
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.2.0-rc.0
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.14.0
0.13.1
0.13.0
0.12.2
0.12.1
0.12.0
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.0
0.5.3
0.5.2
0.5.1
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
Compose web applications with functions
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/plug/templates/debugger.html.eex
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%= h @title %> at <%= h method(@conn) %> <%= h @conn.request_path %></title>
<meta name="viewport" content="width=device-width">
<style>/*! normalize.css v4.2.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,optgroup,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input{overflow:visible}button,select{text-transform:none}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:0.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}</style>
<style>
html, body, td, input {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
}
* {
box-sizing: border-box;
}
html {
font-size: 15px;
line-height: 1.6;
background: #fff;
color: <%= @style.text_color %>;
}
@media (max-width: 768px) {
html {
font-size: 14px;
}
}
@media (max-width: 480px) {
html {
font-size: 13px;
}
}
button:focus,
summary:focus {
outline: 0;
}
summary {
cursor: pointer;
}
pre {
font-family: <%= @style.monospace_font %>;
overflow: auto;
max-width: 100%;
}
.top-details {
padding: 48px;
background: #f9f9fa;
}
.top-details,
.conn-info {
padding: 48px;
}
@media (max-width: 768px) {
.top-details,
.conn-info {
padding: 32px;
}
}
@media (max-width: 480px) {
.top-details,
.conn-info {
padding: 16px;
}
}
/*
* Exception logo
*/
<%= if @style.logo do %>
.exception-logo {
position: absolute;
right: 48px;
top: 48px;
pointer-events: none;
width: 100%;
}
.exception-logo:before {
content: '';
display: block;
height: 64px;
width: 100%;
background-size: auto 100%;
background-image: url("<%= @style.logo %>");
background-position: right 0;
background-repeat: no-repeat;
margin-bottom: 16px;
}
@media (max-width: 768px) {
.exception-logo {
position: static;
}
.exception-logo:before {
height: 32px;
background-position: left 0;
}
}
@media (max-width: 480px) {
.exception-logo {
display: none;
}
}
<% end %>
/*
* Exception info
*/
/* Compensate for logo placement */
@media (min-width: 769px) {
.exception-info {
max-width: 90%;
}
}
.exception-info > .struct {
margin: 0;
padding: 0;
}
.exception-info > .struct {
font-size: 1em;
font-weight: 700;
color: <%= @style.primary %>;
}
.exception-info > .struct > small {
font-size: 1em;
color: <%= @style.accent %>;
font-weight: 400;
}
.exception-info > code {
line-height: 1.5;
}
/*
* Code explorer
*/
.code-explorer {
margin: 32px 0 0 0;
}
@media (max-width: 768px) {
.code-explorer {
margin-top: 16px;
}
}
.code-explorer:after {
content: '';
display: table;
clear: both;
zoom: 1;
}
.code-explorer > .code-snippets {
float: left;
width: 45%;
}
.code-explorer > .stack-trace {
float: right;
width: 55%;
padding-left: 32px;
}
.code-explorer .hidden-contents {
position: absolute;
left: -999em;
}
/* Collapse to single-column */
@media (max-width: 960px) {
.code-explorer > .code-snippets {
float: none;
width: auto;
margin-bottom: 16px;
}
.code-explorer > .stack-trace {
float: none;
width: auto;
padding-left: 0;
}
}
/*
* Frame info:
* Holds the code (code-block) and more
*/
.frame-info {
background: white;
border-radius: 4px;
box-shadow:
0 1px 3px rgba(80, 100, 140, .1),
0 8px 15px rgba(80, 100, 140, .05);
}
.frame-info > .meta,
.frame-info > .file {
padding: 12px 16px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: <%= :math.pow(1.2, -1) %>em;
}
@media (max-width: 480px) {
.frame-info > .meta,
.frame-info > .file {
padding: 6px 16px;
font-size: <%= :math.pow(1.1, -1) %>em;
}
}
.frame-info > .file > a {
text-decoration: none;
color: <%= @style.text_color %>;
font-weight: 700;
}
.frame-info > .code {
border-top: solid 1px <%= @style.line_color %>;
border-bottom: solid 1px <%= @style.line_color %>;
font-size: 0.8em;
}
/* Hiding */
.frame-info {
display: none;
}
.frame-info.-active {
display: block;
}
.frame-info > details.meta {
border-top: solid 1px <%= @style.line_color %>;
padding: 0;
}
.frame-info > details.meta > summary {
padding: 12px 16px;
}
.frame-info > details.meta > pre {
line-height: 16px;
padding: 6px 0 24px 30px;
}
.frame-info > details.meta > ol {
counter-reset: item;
padding: 6px 0 24px 46px;
list-style: none;
}
.frame-info > details.meta > ol > li {
counter-increment: item;
}
.frame-info > details.meta > ol > li:before {
content: counter(item) ". ";
color: <%= @style.accent %>;
}
/*
* Frame details
*/
.frame-mfa {
color: <%= @style.accent %>;
}
.frame-mfa > .app {
color: <%= @style.accent %>;
}
.frame-mfa > .docs {
color: <%= @style.primary %>;
text-decoration: none;
}
.frame-mfa .docs:hover {
text-decoration: underline;
}
.frame-mfa > .right {
float: right;
padding-left: 5px;
}
.frame-mfa > .right:after {
content: '·';
margin-left: .2em;
padding-left: .2em;
}
.frame-mfa > .right:first-child:after {
content: '';
}
/*
* Code block:
* The `pre` that holds the code
*/
.code-block {
margin: 0;
padding: 12px 0;
font-size: <%= :math.pow(1.2, -1) %>em;
line-height: 1.4;
white-space: normal;
}
.code-block > .line {
white-space: pre;
display: block;
padding: 0 16px;
}
/* Line highlight */
.code-block > .line.-highlight {
background-color: <%= @style.highlight %>;
-webkit-animation: line-highlight 750ms linear;
animation: line-highlight 750ms linear;
}
@-webkit-keyframes line-highlight {
0% { background-color: <%= @style.highlight %>; }
25% { background-color: <%= @style.red_highlight %>; }
50% { background-color: <%= @style.highlight %>; }
75% { background-color: <%= @style.red_highlight %>; }
}
@keyframes line-highlight {
0% { background-color: <%= @style.highlight %>; }
25% { background-color: <%= @style.red_highlight %>; }
50% { background-color: <%= @style.highlight %>; }
75% { background-color: <%= @style.red_highlight %>; }
}
.code-block > .line > .ln {
color: <%= @style.accent %>;
margin-right: 1.5em;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.code-block > .line > .code {
font-family: <%= @style.monospace_font %>;
}
/*
* Empty code
*/
.code-block-empty {
text-align: center;
color: <%= @style.accent %>;
padding-top: 48px;
padding-bottom: 48px;
}
/*
* Stack trace heading
*/
.stack-trace-heading {
display: flex;
align-items: center;
justify-content: space-between;
padding-top: 8px;
}
.stack-trace-heading > h3 {
display: none;
}
.stack-trace-heading > label {
display: inline-block;
padding-left: 5px;
line-height: 1.9;
font-size: <%= :math.pow(1.2, -1) %>em;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.stack-trace-heading > label > input {
margin: -0.2em 0.5em 0 0;
vertical-align: middle;
}
.stack-trace-heading .copy-markdown {
color: <%= @style.text_color %>;
background-color: transparent;
display: inline-flex;
align-items: center;
font-size: <%= :math.pow(1.2, -1) %>em;
line-height: 1.9;
border-width: 0;
}
.stack-trace-heading .copy-markdown:active {
cursor: pointer;
}
.stack-trace-heading .copy-markdown:hover {
cursor: pointer;
}
.stack-trace-heading .copy-markdown-icon {
height: 1rem;
width: 1rem;
margin: 0.1em 0.3rem 0;
}
@media (max-width: 480px) {
.stack-trace-heading > label {
font-size: <%= :math.pow(1.1, -1) %>em;
}
}
/*
* Stack trace
*/
.stack-trace-list,
.stack-trace-list > li {
margin: 0;
padding: 0;
list-style-type: none;
}
.stack-trace-list > li > .stack-trace-item.-all {
display: none;
}
.stack-trace-list.-show-all > li > .stack-trace-item.-all {
display: block;
}
/*
* Stack trace item:
* The clickable line to inspect a stack trace
*/
.stack-trace-item {
font-size: <%= :math.pow(1.2, -1) %>em;
display: block;
width: 100%;
border: 0;
margin: 0;
padding: 4px 8px;
background: transparent;
cursor: pointer;
text-align: left;
overflow: hidden;
white-space: nowrap;
}
.stack-trace-item:hover,
.stack-trace-item:focus {
background-color: rgba(80, 100, 140, 0.05);
border-radius: 4px;
}
.stack-trace-item,
.stack-trace-item:active {
color: <%= @style.text_color %>;
}
.stack-trace-item:active {
background-color: rgba(80, 100, 140, 0.1);
}
.stack-trace-item.-active {
background-color: rgba(80, 100, 140, 0.1);
border-radius: 4px;
}
/* Circle */
.stack-trace-item > .left:before {
content: '';
display: inline-block;
width: 8px;
height: 8px;
background: #a0b0c0;
border-radius: 50%;
margin-right: 8px;
opacity: 0.5;
}
.stack-trace-item.-active > .left:before {
opacity: 1;
}
.stack-trace-item.-app > .left:before {
background: <%= @style.primary %>;
}
.stack-trace-item.-app > .left > .app {
display: none;
}
.stack-trace-item > .left {
float: left;
max-width: 55%;
}
.stack-trace-item > .info {
color: <%= @style.accent %>;
float: right;
max-width: 45%;
}
.stack-trace-item > .left,
.stack-trace-item > .info {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.stack-trace-item > .left > .filename > .line {
color: <%= @style.accent %>;
}
/* App name */
.stack-trace-item > .left > .app {
color: <%= @style.accent %>;
}
.stack-trace-item > .left > .app:after {
content: '·';
margin: 0 .2em;
}
/*
* Code as a blockquote:
* Like `pre` but with wrapping
*/
.code-quote {
font-family: <%= @style.monospace_font %>;
font-size: <%= :math.pow(1.2, -1) %>em;
margin: 0;
overflow: auto;
max-width: 100%;
word-wrap: break-word;
white-space: normal;
}
.code-quote > pre {
margin: 0;
}
.code.-padded {
padding: 0 16px 16px 16px;
}
.code i.red {
color: #CC0000;
font-style: normal;
}
.code i.green {
font-style: normal;
}
.banner {
padding: 24px 48px 24px 48px;
border-top: solid 1px <%= @style.line_color %>;
}
/*
* Conn info
*/
.conn-info {
border-top: solid 1px <%= @style.line_color %>;
}
/*
* Conn details
*/
.conn-details {
}
.conn-details + .conn-details {
margin-top: 16px;
}
.conn-details > summary {
}
.conn-details > dl {
display: block;
overflow: hidden;
margin: 0;
padding: 4px 0;
border-bottom: solid 1px <%= @style.line_color %>;
white-space: nowrap;
text-overflow: ellipsis;
}
.conn-details > dl:first-of-type {
margin-top: 16px;
border-top: solid 1px <%= @style.line_color %>;
}
/* Term */
.conn-details > dl > dt {
width: 20%;
float: left;
font-size: <%= :math.pow(1.2, -1) %>em;
color: <%= @style.accent %>;
overflow: hidden;
text-overflow: ellipsis;
position: relative;
top: -1px; /* Compensate for font metrics */
}
/* Definition */
.conn-details > dl > dd {
width: 80%;
float: left;
}
@media (max-width: 480px) {
.conn-details > dl > dt {
font-size: <%= :math.pow(1.1, -1) %>em;
}
}
.action-form {
display: inline-block;
margin: 20px 10px 5px 0;
}
.action-button {
padding: 0 10px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="top-details">
<%= if @style.logo do %>
<aside class="exception-logo"></aside>
<% end %>
<header class="exception-info">
<h5 class="struct">
<%= h @title %>
<small>at <%= h method(@conn) %></small>
<small class="path"><%= h @conn.request_path %></small>
</h5>
<code><pre><%= h @message %></pre></code>
</header>
<%= for %{label: label, encoded_handler: encoded_handler} <- @actions do %>
<form class="action-form" action="/__plug__/debugger/action" method="POST">
<input type="hidden" name="encoded_handler" value="<%= encoded_handler %>">
<input type="hidden" name="last_path" value="<%= @last_path %>">
<button class="action-button" type="submit"> <%= label %> </button>
</form>
<% end %>
<%= if @banner do %>
</div>
<div class="banner"><%= @banner %></div>
<div class="top-details">
<% end %>
<div class="code-explorer">
<textarea class="hidden-contents" role="copy-contents"><%= @markdown %></textarea>
<div class="code-snippets">
<%= for frame <- @frames do %>
<div class="frame-info" data-index="<%= frame.index %>" role="stack-trace-details">
<div class="file">
<a href="<%= frame.link %>"><%= h frame.file %></a>
</div>
<%= if (snippet = frame.snippet) && snippet != [] do %>
<pre class="code code-block"><%= for {index, line, highlight} <- snippet do %><span class="line <%= if highlight, do: "-highlight" %>"><span class="ln"><%= h index %></span><span class="code"><%= h String.trim_trailing(line) %></span></span>
<% end %></pre>
<% else %>
<div class="code code-block-empty">No code available.</div>
<% end %>
<div class="meta">
<div class="frame-mfa">
<%= h frame.info %>
<%= if doc = frame.doc do %>
<a class="docs right" href="<%= h doc %>">Docs</a>
<% end %>
<%= if app = frame.app do %>
<span class="app right"><%= h app %></span>
<% end %>
</div>
</div>
<%= if frame.args do %>
<details class="meta" open>
<summary>Called with <%= length(frame.args) %> arguments</summary>
<ol class="code code-quote -padded">
<%= for arg <- frame.args do %>
<li><%= h inspect arg %></li>
<% end %>
</ol>
</details>
<% end %>
<%= if frame.clauses do %>
<% {min, max, clauses} = frame.clauses %>
<details class="meta" open>
<summary>Attempted function clauses (showing <%= min %> out of <%= max %>)</summary>
<pre class="code code-block -padded">
<%= for clause <- clauses do %>
<span class="line"><%= clause %></span>
<% end %>
</pre>
</details>
<% end %>
</div>
<% end %>
</div>
<div class="stack-trace">
<div class="stack-trace-heading">
<label><input type="checkbox" role="show-all-toggle">Show only app frames</label>
<button class="copy-markdown" role="copy-to-markdown" type="button">
<span role="copy-to-markdown-text">Copy markdown</span>
<svg xmlns="http://www.w3.org/2000/svg" class="copy-markdown-icon" viewBox="0 0 115.77 122.88"><g><path d="M89.62,13.96v7.73h12.19h0.01v0.02c3.85,0.01,7.34,1.57,9.86,4.1c2.5,2.51,4.06,5.98,4.07,9.82h0.02v0.02 v73.27v0.01h-0.02c-0.01,3.84-1.57,7.33-4.1,9.86c-2.51,2.5-5.98,4.06-9.82,4.07v0.02h-0.02h-61.7H40.1v-0.02 c-3.84-0.01-7.34-1.57-9.86-4.1c-2.5-2.51-4.06-5.98-4.07-9.82h-0.02v-0.02V92.51H13.96h-0.01v-0.02c-3.84-0.01-7.34-1.57-9.86-4.1 c-2.5-2.51-4.06-5.98-4.07-9.82H0v-0.02V13.96v-0.01h0.02c0.01-3.85,1.58-7.34,4.1-9.86c2.51-2.5,5.98-4.06,9.82-4.07V0h0.02h61.7 h0.01v0.02c3.85,0.01,7.34,1.57,9.86,4.1c2.5,2.51,4.06,5.98,4.07,9.82h0.02V13.96L89.62,13.96z M79.04,21.69v-7.73v-0.02h0.02 c0-0.91-0.39-1.75-1.01-2.37c-0.61-0.61-1.46-1-2.37-1v0.02h-0.01h-61.7h-0.02v-0.02c-0.91,0-1.75,0.39-2.37,1.01 c-0.61,0.61-1,1.46-1,2.37h0.02v0.01v64.59v0.02h-0.02c0,0.91,0.39,1.75,1.01,2.37c0.61,0.61,1.46,1,2.37,1v-0.02h0.01h12.19V35.65 v-0.01h0.02c0.01-3.85,1.58-7.34,4.1-9.86c2.51-2.5,5.98-4.06,9.82-4.07v-0.02h0.02H79.04L79.04,21.69z M105.18,108.92V35.65v-0.02 h0.02c0-0.91-0.39-1.75-1.01-2.37c-0.61-0.61-1.46-1-2.37-1v0.02h-0.01h-61.7h-0.02v-0.02c-0.91,0-1.75,0.39-2.37,1.01 c-0.61,0.61-1,1.46-1,2.37h0.02v0.01v73.27v0.02h-0.02c0,0.91,0.39,1.75,1.01,2.37c0.61,0.61,1.46,1,2.37,1v-0.02h0.01h61.7h0.02 v0.02c0.91,0,1.75-0.39,2.37-1.01c0.61-0.61,1-1.46,1-2.37h-0.02V108.92L105.18,108.92z"/></g></svg>
</button>
</div>
<ul class="stack-trace-list -show-all" role="stack-trace-list">
<%= for frame <- @frames do %>
<li>
<button class="stack-trace-item -<%= frame.context %>" role="stack-trace-item" data-index="<%= frame.index %>">
<span class="left">
<%= if app = frame.app do %>
<span class="app"><%= h app %></span>
<% end %>
<span class="filename">
<%= h frame.file %><%= if frame.line do %><span class="line">:<%= h frame.line %></span><% end %>
</span>
</span>
<span class="info"><%= h frame.info %></span>
</button>
</li>
<% end %>
</ul>
</div>
</div>
</div>
<div class="conn-info">
<%= if @params && @params != %{} do %>
<details class="conn-details" open>
<summary>Params</summary>
<%= for {key, value} <- @params do %>
<dl>
<dt><%= h key %></dt>
<dd><pre><%= h inspect(value) %></pre></dd>
</dl>
<% end %>
</details>
<% end %>
<details class="conn-details">
<summary>Request info</summary>
<dl>
<dt>URI:</dt>
<dd class="code-quote"><%= h url(@conn) %></dd>
</dl>
<dl>
<dt>Query string:</dt>
<dd class="code-quote"><%= h @conn.query_string %></dd>
</dl>
</details>
<details class="conn-details">
<summary>Headers</summary>
<%= for {key, value} <- Enum.sort(@conn.req_headers) do %>
<dl>
<dt><%= h key %></dt>
<dd class="code-quote"><%= h value %></dd>
</dl>
<% end %>
</details>
<%= if @session && @session != %{} do %>
<details class="conn-details">
<summary>Session</summary>
<%= for {key, value} <- @session do %>
<dl>
<dt><%= h key %></dt>
<dd class="code-quote"><pre><%= h inspect(value) %></pre></dd>
</dl>
<% end %>
</details>
<% end %>
</div>
<script>(function () {
var $items = document.querySelectorAll('[role~="stack-trace-item"]')
var $toggle = document.querySelector('[role~="show-all-toggle"]')
var $list = document.querySelector('[role~="stack-trace-list"]')
var $copyBtn = document.querySelector('[role~="copy-to-markdown"]')
var $copyBtnText = document.querySelector('[role~="copy-to-markdown-text"]')
var $copy = document.querySelector('[role~="copy-contents"]')
each($items, function ($item) {
on($item, 'click', itemOnclick)
})
on($toggle, 'click', toggleOnclick)
on($copyBtn, 'click', copyToClipboard)
function copyToClipboard () {
if(navigator.clipboard) {
// For those working on localhost or HTTPS
navigator.clipboard.writeText($copy.innerHTML).then(copiedClipboard).catch(() => {})
} else {
// For those working on HTTP
$copy.select()
if (document.execCommand("copy")) copiedClipboard()
}
}
function copiedClipboard () {
$copyBtnText.innerText = "Copied!"
setTimeout(function () {
$copyBtnText.innerText = "Copy markdown"
}, 5000)
}
function toggleOnclick () {
if (this.checked) {
var $first = document.querySelector('[role~="stack-trace-item"].-app:first-of-type')
if ($first) itemOnclick.call($first)
removeClass($list, '-show-all')
} else {
addClass($list, '-show-all')
}
}
function itemOnclick () {
var idx = this.getAttribute('data-index')
var $detail = document.querySelector('[role~="stack-trace-details"].-active')
if ($detail) removeClass($detail, '-active')
$detail = document.querySelector('[role~="stack-trace-details"][data-index="' + idx + '"]')
if ($detail) addClass($detail, '-active')
var $item = document.querySelector('[role~="stack-trace-item"].-active')
if ($item) removeClass($item, '-active')
$item = document.querySelector('[role~="stack-trace-item"][data-index="' + idx + '"]')
if ($item) addClass($item, '-active')
}
var $first = document.querySelector('[role~="stack-trace-item"]:first-of-type')
if ($first) itemOnclick.call($first)
/*
* Helpers
*/
function each (list, fn) {
for (var i = 0, len = list.length; i < len; i++) {
var item = list[i]
fn(item)
}
}
function addClass (el, className) {
if (el.classList) {
el.classList.add(className)
} else {
el.className += ' ' + className
}
}
function removeClass (el, className) {
if (el.classList) {
el.classList.remove(className)
} else {
var expr = new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi')
el.className = el.className.replace(expr, ' ')
}
}
function on (el, event, handler) {
if (el.addEventListener) {
el.addEventListener(event, handler)
} else {
el.attachEvent('on' + event, function () {
handler.call(el)
})
}
}
}())</script>
</body>
</html>