debugger.html.eex (28730B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title><%= h @title %> at <%= h method(@conn) %> <%= h @conn.request_path %></title> 6 <meta name="viewport" content="width=device-width"> 7 <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> 8 <style> 9 html, body, td, input { 10 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; 11 } 12 13 * { 14 box-sizing: border-box; 15 } 16 17 html { 18 font-size: 15px; 19 line-height: 1.6; 20 background: #fff; 21 color: <%= @style.text_color %>; 22 } 23 24 @media (max-width: 768px) { 25 html { 26 font-size: 14px; 27 } 28 } 29 30 @media (max-width: 480px) { 31 html { 32 font-size: 13px; 33 } 34 } 35 36 button:focus, 37 summary:focus { 38 outline: 0; 39 } 40 41 summary { 42 cursor: pointer; 43 } 44 45 pre { 46 font-family: <%= @style.monospace_font %>; 47 overflow: auto; 48 max-width: 100%; 49 } 50 51 .top-details { 52 padding: 48px; 53 background: #f9f9fa; 54 } 55 56 .top-details, 57 .conn-info { 58 padding: 48px; 59 } 60 61 62 @media (max-width: 768px) { 63 .top-details, 64 .conn-info { 65 padding: 32px; 66 } 67 } 68 69 @media (max-width: 480px) { 70 .top-details, 71 .conn-info { 72 padding: 16px; 73 } 74 } 75 76 /* 77 * Exception logo 78 */ 79 80 <%= if @style.logo do %> 81 .exception-logo { 82 position: absolute; 83 right: 48px; 84 top: 48px; 85 pointer-events: none; 86 width: 100%; 87 } 88 89 .exception-logo:before { 90 content: ''; 91 display: block; 92 height: 64px; 93 width: 100%; 94 background-size: auto 100%; 95 background-image: url("<%= @style.logo %>"); 96 background-position: right 0; 97 background-repeat: no-repeat; 98 margin-bottom: 16px; 99 } 100 101 @media (max-width: 768px) { 102 .exception-logo { 103 position: static; 104 } 105 106 .exception-logo:before { 107 height: 32px; 108 background-position: left 0; 109 } 110 } 111 112 @media (max-width: 480px) { 113 .exception-logo { 114 display: none; 115 } 116 } 117 <% end %> 118 119 /* 120 * Exception info 121 */ 122 123 /* Compensate for logo placement */ 124 @media (min-width: 769px) { 125 .exception-info { 126 max-width: 90%; 127 } 128 } 129 130 .exception-info > .struct, 131 .exception-info > .title, 132 .exception-info > .detail { 133 margin: 0; 134 padding: 0; 135 } 136 137 .exception-info > .struct { 138 font-size: 1em; 139 font-weight: 700; 140 color: <%= @style.primary %>; 141 } 142 143 .exception-info > .struct > small { 144 font-size: 1em; 145 color: <%= @style.accent %>; 146 font-weight: 400; 147 } 148 149 .exception-info > .title { 150 font-size: <%= :math.pow(1.2, 4) %>em; 151 line-height: 1.4; 152 font-weight: 300; 153 color: <%= @style.primary %>; 154 } 155 156 @media (max-width: 768px) { 157 .exception-info > .title { 158 font-size: <%= :math.pow(1.15, 4) %>em; 159 } 160 } 161 162 @media (max-width: 480px) { 163 .exception-info > .title { 164 font-size: <%= :math.pow(1.1, 4) %>em; 165 } 166 } 167 168 .exception-info > .detail { 169 margin-top: 1.3em; 170 white-space: pre-wrap; 171 } 172 173 /* 174 * Code explorer 175 */ 176 177 .code-explorer { 178 margin: 32px 0 0 0; 179 } 180 181 @media (max-width: 768px) { 182 .code-explorer { 183 margin-top: 16px; 184 } 185 } 186 187 .code-explorer:after { 188 content: ''; 189 display: table; 190 clear: both; 191 zoom: 1; 192 } 193 194 .code-explorer > .code-snippets { 195 float: left; 196 width: 45%; 197 } 198 199 .code-explorer > .stack-trace { 200 float: right; 201 width: 55%; 202 padding-left: 32px; 203 } 204 205 .code-explorer .hidden-contents { 206 position: absolute; 207 left: -999em; 208 } 209 210 /* Collapse to single-column */ 211 @media (max-width: 960px) { 212 .code-explorer > .code-snippets { 213 float: none; 214 width: auto; 215 margin-bottom: 16px; 216 } 217 218 .code-explorer > .stack-trace { 219 float: none; 220 width: auto; 221 padding-left: 0; 222 } 223 } 224 225 /* 226 * Frame info: 227 * Holds the code (code-block) and more 228 */ 229 230 .frame-info { 231 background: white; 232 border-radius: 4px; 233 box-shadow: 234 0 1px 3px rgba(80, 100, 140, .1), 235 0 8px 15px rgba(80, 100, 140, .05); 236 } 237 238 .frame-info > .meta, 239 .frame-info > .file { 240 padding: 12px 16px; 241 overflow: hidden; 242 text-overflow: ellipsis; 243 white-space: nowrap; 244 font-size: <%= :math.pow(1.2, -1) %>em; 245 } 246 247 @media (max-width: 480px) { 248 .frame-info > .meta, 249 .frame-info > .file { 250 padding: 6px 16px; 251 font-size: <%= :math.pow(1.1, -1) %>em; 252 } 253 } 254 255 .frame-info > .file > a { 256 text-decoration: none; 257 color: <%= @style.text_color %>; 258 font-weight: 700; 259 } 260 261 .frame-info > .code { 262 border-top: solid 1px <%= @style.line_color %>; 263 border-bottom: solid 1px <%= @style.line_color %>; 264 font-size: 0.8em; 265 } 266 267 /* Hiding */ 268 .frame-info { 269 display: none; 270 } 271 272 .frame-info.-active { 273 display: block; 274 } 275 276 .frame-info > details.meta { 277 border-top: solid 1px <%= @style.line_color %>; 278 padding: 0; 279 } 280 281 .frame-info > details.meta > summary { 282 padding: 12px 16px; 283 } 284 285 .frame-info > details.meta > pre { 286 line-height: 16px; 287 padding: 6px 0 24px 30px; 288 } 289 290 .frame-info > details.meta > ol { 291 counter-reset: item; 292 padding: 6px 0 24px 46px; 293 list-style: none; 294 } 295 296 .frame-info > details.meta > ol > li { 297 counter-increment: item; 298 } 299 300 .frame-info > details.meta > ol > li:before { 301 content: counter(item) ". "; 302 color: <%= @style.accent %>; 303 } 304 305 /* 306 * Frame details 307 */ 308 309 .frame-mfa { 310 color: <%= @style.accent %>; 311 } 312 313 .frame-mfa > .app { 314 color: <%= @style.accent %>; 315 } 316 317 .frame-mfa > .docs { 318 color: <%= @style.primary %>; 319 text-decoration: none; 320 } 321 322 .frame-mfa .docs:hover { 323 text-decoration: underline; 324 } 325 326 .frame-mfa > .right { 327 float: right; 328 padding-left: 5px; 329 } 330 331 .frame-mfa > .right:after { 332 content: '·'; 333 margin-left: .2em; 334 padding-left: .2em; 335 } 336 337 .frame-mfa > .right:first-child:after { 338 content: ''; 339 } 340 341 /* 342 * Code block: 343 * The `pre` that holds the code 344 */ 345 346 .code-block { 347 margin: 0; 348 padding: 12px 0; 349 font-size: <%= :math.pow(1.2, -1) %>em; 350 line-height: 1.4; 351 white-space: normal; 352 } 353 354 .code-block > .line { 355 white-space: pre; 356 display: block; 357 padding: 0 16px; 358 } 359 360 /* Line highlight */ 361 .code-block > .line.-highlight { 362 background-color: <%= @style.highlight %>; 363 -webkit-animation: line-highlight 750ms linear; 364 animation: line-highlight 750ms linear; 365 } 366 367 @-webkit-keyframes line-highlight { 368 0% { background-color: <%= @style.highlight %>; } 369 25% { background-color: <%= @style.red_highlight %>; } 370 50% { background-color: <%= @style.highlight %>; } 371 75% { background-color: <%= @style.red_highlight %>; } 372 } 373 374 @keyframes line-highlight { 375 0% { background-color: <%= @style.highlight %>; } 376 25% { background-color: <%= @style.red_highlight %>; } 377 50% { background-color: <%= @style.highlight %>; } 378 75% { background-color: <%= @style.red_highlight %>; } 379 } 380 381 .code-block > .line > .ln { 382 color: <%= @style.accent %>; 383 margin-right: 1.5em; 384 -webkit-user-select: none; 385 -moz-user-select: none; 386 -ms-user-select: none; 387 user-select: none; 388 } 389 390 .code-block > .line > .code { 391 font-family: <%= @style.monospace_font %>; 392 } 393 394 /* 395 * Empty code 396 */ 397 398 .code-block-empty { 399 text-align: center; 400 color: <%= @style.accent %>; 401 padding-top: 48px; 402 padding-bottom: 48px; 403 } 404 405 /* 406 * Stack trace heading 407 */ 408 409 .stack-trace-heading { 410 display: flex; 411 align-items: center; 412 justify-content: space-between; 413 padding-top: 8px; 414 } 415 416 .stack-trace-heading > h3 { 417 display: none; 418 } 419 420 .stack-trace-heading > label { 421 display: inline-block; 422 padding-left: 5px; 423 line-height: 1.9; 424 font-size: <%= :math.pow(1.2, -1) %>em; 425 -webkit-user-select: none; 426 -moz-user-select: none; 427 -ms-user-select: none; 428 user-select: none; 429 } 430 431 .stack-trace-heading > label > input { 432 margin: -0.2em 0.5em 0 0; 433 vertical-align: middle; 434 } 435 436 .stack-trace-heading .copy-markdown { 437 color: <%= @style.text_color %>; 438 background-color: transparent; 439 display: inline-flex; 440 align-items: center; 441 font-size: <%= :math.pow(1.2, -1) %>em; 442 line-height: 1.9; 443 border-width: 0; 444 } 445 446 .stack-trace-heading .copy-markdown:active { 447 cursor: pointer; 448 } 449 450 .stack-trace-heading .copy-markdown:hover { 451 cursor: pointer; 452 } 453 454 .stack-trace-heading .copy-markdown-icon { 455 height: 1rem; 456 width: 1rem; 457 margin: 0.1em 0.3rem 0; 458 } 459 460 @media (max-width: 480px) { 461 .stack-trace-heading > label { 462 font-size: <%= :math.pow(1.1, -1) %>em; 463 } 464 } 465 466 /* 467 * Stack trace 468 */ 469 470 .stack-trace-list, 471 .stack-trace-list > li { 472 margin: 0; 473 padding: 0; 474 list-style-type: none; 475 } 476 477 .stack-trace-list > li > .stack-trace-item.-all { 478 display: none; 479 } 480 481 .stack-trace-list.-show-all > li > .stack-trace-item.-all { 482 display: block; 483 } 484 485 /* 486 * Stack trace item: 487 * The clickable line to inspect a stack trace 488 */ 489 490 .stack-trace-item { 491 font-size: <%= :math.pow(1.2, -1) %>em; 492 display: block; 493 width: 100%; 494 border: 0; 495 margin: 0; 496 padding: 4px 8px; 497 background: transparent; 498 cursor: pointer; 499 text-align: left; 500 overflow: hidden; 501 white-space: nowrap; 502 } 503 504 .stack-trace-item:hover, 505 .stack-trace-item:focus { 506 background-color: rgba(80, 100, 140, 0.05); 507 border-radius: 4px; 508 } 509 510 .stack-trace-item, 511 .stack-trace-item:active { 512 color: <%= @style.text_color %>; 513 } 514 515 .stack-trace-item:active { 516 background-color: rgba(80, 100, 140, 0.1); 517 } 518 519 .stack-trace-item.-active { 520 background-color: rgba(80, 100, 140, 0.1); 521 border-radius: 4px; 522 } 523 524 /* Circle */ 525 .stack-trace-item > .left:before { 526 content: ''; 527 display: inline-block; 528 width: 8px; 529 height: 8px; 530 background: #a0b0c0; 531 border-radius: 50%; 532 margin-right: 8px; 533 opacity: 0.5; 534 } 535 536 .stack-trace-item.-active > .left:before { 537 opacity: 1; 538 } 539 540 .stack-trace-item.-app > .left:before { 541 background: <%= @style.primary %>; 542 } 543 544 .stack-trace-item.-app > .left > .app { 545 display: none; 546 } 547 548 .stack-trace-item > .left { 549 float: left; 550 max-width: 55%; 551 } 552 553 .stack-trace-item > .info { 554 color: <%= @style.accent %>; 555 float: right; 556 max-width: 45%; 557 } 558 559 .stack-trace-item > .left, 560 .stack-trace-item > .info { 561 white-space: nowrap; 562 overflow: hidden; 563 text-overflow: ellipsis; 564 } 565 566 .stack-trace-item > .left > .filename > .line { 567 color: <%= @style.accent %>; 568 } 569 570 /* App name */ 571 .stack-trace-item > .left > .app { 572 color: <%= @style.accent %>; 573 } 574 575 .stack-trace-item > .left > .app:after { 576 content: '·'; 577 margin: 0 .2em; 578 } 579 580 /* 581 * Code as a blockquote: 582 * Like `pre` but with wrapping 583 */ 584 585 .code-quote { 586 font-family: <%= @style.monospace_font %>; 587 font-size: <%= :math.pow(1.2, -1) %>em; 588 margin: 0; 589 overflow: auto; 590 max-width: 100%; 591 word-wrap: break-word; 592 white-space: normal; 593 } 594 595 .code-quote > pre { 596 margin: 0; 597 } 598 599 .code.-padded { 600 padding: 0 16px 16px 16px; 601 } 602 603 .code i.red { 604 color: #CC0000; 605 font-style: normal; 606 } 607 608 .code i.green { 609 font-style: normal; 610 } 611 612 .banner { 613 padding: 24px 48px 24px 48px; 614 border-top: solid 1px <%= @style.line_color %>; 615 } 616 617 /* 618 * Conn info 619 */ 620 621 .conn-info { 622 border-top: solid 1px <%= @style.line_color %>; 623 } 624 625 /* 626 * Conn details 627 */ 628 629 .conn-details { 630 } 631 632 .conn-details + .conn-details { 633 margin-top: 16px; 634 } 635 636 .conn-details > summary { 637 } 638 639 .conn-details > dl { 640 display: block; 641 overflow: hidden; 642 margin: 0; 643 padding: 4px 0; 644 border-bottom: solid 1px <%= @style.line_color %>; 645 white-space: nowrap; 646 text-overflow: ellipsis; 647 } 648 649 .conn-details > dl:first-of-type { 650 margin-top: 16px; 651 border-top: solid 1px <%= @style.line_color %>; 652 } 653 654 /* Term */ 655 .conn-details > dl > dt { 656 width: 20%; 657 float: left; 658 font-size: <%= :math.pow(1.2, -1) %>em; 659 color: <%= @style.accent %>; 660 overflow: hidden; 661 text-overflow: ellipsis; 662 position: relative; 663 top: -1px; /* Compensate for font metrics */ 664 } 665 666 /* Definition */ 667 .conn-details > dl > dd { 668 width: 80%; 669 float: left; 670 } 671 672 @media (max-width: 480px) { 673 .conn-details > dl > dt { 674 font-size: <%= :math.pow(1.1, -1) %>em; 675 } 676 } 677 678 .action-form { 679 display: inline-block; 680 margin: 20px 10px 5px 0; 681 } 682 683 .action-button:hover { 684 background-color: #f9f9fa; 685 cursor: pointer; 686 } 687 688 .action-button { 689 background-color: white; 690 border: 1px solid <%= @style.primary %>; 691 border-radius: 3px; 692 color: <%= @style.primary %>; 693 padding: 0 20px; 694 } 695 696 .action-button:active { 697 background-color: inherit; 698 background-color: #f2f2f4; 699 } 700 701 </style> 702 </head> 703 <body> 704 <div class="top-details"> 705 <%= if @style.logo do %> 706 <aside class="exception-logo"></aside> 707 <% end %> 708 709 <header class="exception-info"> 710 <% [headline | details] = String.split(@message, "\n\n") %> 711 <h5 class="struct"> 712 <%= h @title %> 713 <small>at <%= h method(@conn) %></small> 714 <small class="path"><%= h @conn.request_path %></small> 715 </h5> 716 <h1 class="title"><%= h headline %></h1> 717 <%= for detail <- details do %> 718 <p class="detail"><%= h detail %></p> 719 <% end %> 720 </header> 721 722 <%= for %{label: label, encoded_handler: encoded_handler} <- @actions do %> 723 <form class="action-form" action="/__plug__/debugger/action" method="POST"> 724 <input type="hidden" name="encoded_handler" value="<%= encoded_handler %>"> 725 <input type="hidden" name="last_path" value="<%= @last_path %>"> 726 <button class="action-button" type="submit"> <%= label %> </button> 727 </form> 728 <% end %> 729 730 <%= if @banner do %> 731 </div> 732 <div class="banner"><%= @banner %></div> 733 <div class="top-details"> 734 <% end %> 735 736 <div class="code-explorer"> 737 <textarea class="hidden-contents" role="copy-contents"><%= @markdown %></textarea> 738 <div class="code-snippets"> 739 <%= for frame <- @frames do %> 740 <div class="frame-info" data-index="<%= frame.index %>" role="stack-trace-details"> 741 <div class="file"> 742 <a href="<%= frame.link %>"><%= h frame.file %></a> 743 </div> 744 745 <%= if (snippet = frame.snippet) && snippet != [] do %> 746 <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> 747 <% end %></pre> 748 <% else %> 749 <div class="code code-block-empty">No code available.</div> 750 <% end %> 751 752 <div class="meta"> 753 <div class="frame-mfa"> 754 <%= h frame.info %> 755 <%= if doc = frame.doc do %> 756 <a class="docs right" href="<%= h doc %>">Docs</a> 757 <% end %> 758 <%= if app = frame.app do %> 759 <span class="app right"><%= h app %></span> 760 <% end %> 761 </div> 762 </div> 763 764 <%= if frame.args do %> 765 <details class="meta" open> 766 <summary>Called with <%= length(frame.args) %> arguments</summary> 767 <ol class="code code-quote -padded"> 768 <%= for arg <- frame.args do %> 769 <li><%= h inspect arg %></li> 770 <% end %> 771 </ol> 772 </details> 773 <% end %> 774 775 <%= if frame.clauses do %> 776 <% {min, max, clauses} = frame.clauses %> 777 <details class="meta" open> 778 <summary>Attempted function clauses (showing <%= min %> out of <%= max %>)</summary> 779 <pre class="code code-block -padded"> 780 <%= for clause <- clauses do %> 781 <span class="line"><%= clause %></span> 782 <% end %> 783 </pre> 784 </details> 785 <% end %> 786 </div> 787 <% end %> 788 </div> 789 790 <div class="stack-trace"> 791 <div class="stack-trace-heading"> 792 <label><input type="checkbox" role="show-all-toggle">Show only app frames</label> 793 <button class="copy-markdown" role="copy-to-markdown" type="button"> 794 <span role="copy-to-markdown-text">Copy markdown</span> 795 <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> 796 </button> 797 </div> 798 799 <ul class="stack-trace-list -show-all" role="stack-trace-list"> 800 <%= for frame <- @frames do %> 801 <li> 802 <button class="stack-trace-item -<%= frame.context %>" role="stack-trace-item" data-index="<%= frame.index %>"> 803 <span class="left"> 804 <%= if app = frame.app do %> 805 <span class="app"><%= h app %></span> 806 <% end %> 807 808 <span class="filename"> 809 <%= h frame.file %><%= if frame.line do %><span class="line">:<%= h frame.line %></span><% end %> 810 </span> 811 </span> 812 813 <span class="info"><%= h frame.info %></span> 814 </button> 815 </li> 816 <% end %> 817 </ul> 818 </div> 819 </div> 820 </div> 821 822 <div class="conn-info"> 823 <%= if @params && @params != %{} do %> 824 <details class="conn-details" open> 825 <summary>Params</summary> 826 <%= for {key, value} <- @params do %> 827 <dl> 828 <dt><%= h key %></dt> 829 <dd><pre><%= h inspect(value) %></pre></dd> 830 </dl> 831 <% end %> 832 </details> 833 <% end %> 834 835 <details class="conn-details"> 836 <summary>Request info</summary> 837 838 <dl> 839 <dt>URI:</dt> 840 <dd class="code-quote"><%= h url(@conn) %></dd> 841 </dl> 842 843 <dl> 844 <dt>Query string:</dt> 845 <dd class="code-quote"><%= h @conn.query_string %></dd> 846 </dl> 847 </details> 848 849 <details class="conn-details"> 850 <summary>Headers</summary> 851 <%= for {key, value} <- Enum.sort(@conn.req_headers) do %> 852 <dl> 853 <dt><%= h key %></dt> 854 <dd class="code-quote"><%= h value %></dd> 855 </dl> 856 <% end %> 857 </details> 858 859 <%= if @session && @session != %{} do %> 860 <details class="conn-details"> 861 <summary>Session</summary> 862 <%= for {key, value} <- @session do %> 863 <dl> 864 <dt><%= h key %></dt> 865 <dd class="code-quote"><pre><%= h inspect(value) %></pre></dd> 866 </dl> 867 <% end %> 868 </details> 869 <% end %> 870 </div> 871 872 <script>(function () { 873 var $items = document.querySelectorAll('[role~="stack-trace-item"]') 874 var $toggle = document.querySelector('[role~="show-all-toggle"]') 875 var $list = document.querySelector('[role~="stack-trace-list"]') 876 var $copyBtn = document.querySelector('[role~="copy-to-markdown"]') 877 var $copyBtnText = document.querySelector('[role~="copy-to-markdown-text"]') 878 var $copy = document.querySelector('[role~="copy-contents"]') 879 880 each($items, function ($item) { 881 on($item, 'click', itemOnclick) 882 }) 883 884 on($toggle, 'click', toggleOnclick) 885 on($copyBtn, 'click', copyToClipboard) 886 887 function copyToClipboard () { 888 if(navigator.clipboard) { 889 // For those working on localhost or HTTPS 890 navigator.clipboard.writeText($copy.innerHTML).then(copiedClipboard).catch(() => {}) 891 } else { 892 // For those working on HTTP 893 $copy.select() 894 if (document.execCommand("copy")) copiedClipboard() 895 } 896 } 897 898 function copiedClipboard () { 899 $copyBtnText.innerText = "Copied!" 900 setTimeout(function () { 901 $copyBtnText.innerText = "Copy markdown" 902 }, 5000) 903 } 904 905 function toggleOnclick () { 906 if (this.checked) { 907 var $first = document.querySelector('[role~="stack-trace-item"].-app:first-of-type') 908 if ($first) itemOnclick.call($first) 909 removeClass($list, '-show-all') 910 } else { 911 addClass($list, '-show-all') 912 } 913 } 914 915 function itemOnclick () { 916 var idx = this.getAttribute('data-index') 917 918 var $detail = document.querySelector('[role~="stack-trace-details"].-active') 919 if ($detail) removeClass($detail, '-active') 920 921 $detail = document.querySelector('[role~="stack-trace-details"][data-index="' + idx + '"]') 922 if ($detail) addClass($detail, '-active') 923 924 var $item = document.querySelector('[role~="stack-trace-item"].-active') 925 if ($item) removeClass($item, '-active') 926 927 $item = document.querySelector('[role~="stack-trace-item"][data-index="' + idx + '"]') 928 if ($item) addClass($item, '-active') 929 } 930 931 var $first = document.querySelector('[role~="stack-trace-item"]:first-of-type') 932 if ($first) itemOnclick.call($first) 933 934 /* 935 * Helpers 936 */ 937 938 function each (list, fn) { 939 for (var i = 0, len = list.length; i < len; i++) { 940 var item = list[i] 941 fn(item) 942 } 943 } 944 945 function addClass (el, className) { 946 if (el.classList) { 947 el.classList.add(className) 948 } else { 949 el.className += ' ' + className 950 } 951 } 952 953 function removeClass (el, className) { 954 if (el.classList) { 955 el.classList.remove(className) 956 } else { 957 var expr = new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi') 958 el.className = el.className.replace(expr, ' ') 959 } 960 } 961 962 function on (el, event, handler) { 963 if (el.addEventListener) { 964 el.addEventListener(event, handler) 965 } else { 966 el.attachEvent('on' + event, function () { 967 handler.call(el) 968 }) 969 } 970 } 971 }())</script> 972 </body> 973 </html>