|
3 | 3 | <head> |
4 | 4 | <title><%= exception_type %> at <%= request_path %></title> |
5 | 5 | </head> |
6 | | -<body> |
| 6 | +<body class="better-errors-javascript-not-loaded"> |
7 | 7 | <%# Stylesheets are placed in the <body> for Turbolinks compatibility. %> |
8 | 8 | <style> |
9 | 9 | /* Basic reset */ |
|
107 | 107 | } |
108 | 108 |
|
109 | 109 | .frame_info { |
| 110 | + display: none; |
| 111 | + |
110 | 112 | right: 0; |
111 | 113 | left: 40%; |
112 | 114 |
|
113 | 115 | padding: 20px; |
114 | 116 | padding-left: 10px; |
115 | 117 | margin-left: 30px; |
116 | 118 | } |
| 119 | + .frame_info.current { |
| 120 | + display: block; |
| 121 | + } |
117 | 122 | } |
118 | 123 |
|
119 | 124 | nav.sidebar { |
|
227 | 232 | * Navigation |
228 | 233 | * --------------------------------------------------------------------- */ |
229 | 234 |
|
| 235 | + .better-errors-javascript-not-loaded .backtrace .tabs { |
| 236 | + display: none; |
| 237 | + } |
| 238 | + |
230 | 239 | nav.tabs { |
231 | 240 | border-bottom: solid 1px #ddd; |
232 | 241 |
|
|
411 | 420 | * Display area |
412 | 421 | * --------------------------------------------------------------------- */ |
413 | 422 |
|
| 423 | + p.no-javascript-notice { |
| 424 | + margin-bottom: 1em; |
| 425 | + padding: 1em; |
| 426 | + border: 2px solid #e00; |
| 427 | + } |
| 428 | + .better-errors-javascript-loaded .no-javascript-notice { |
| 429 | + display: none; |
| 430 | + } |
| 431 | + .no-inline-style-notice { |
| 432 | + display: none; |
| 433 | + } |
| 434 | + |
414 | 435 | .trace_info { |
415 | 436 | background: #fff; |
416 | 437 | padding: 6px; |
|
468 | 489 | font-weight: 200; |
469 | 490 | } |
470 | 491 |
|
| 492 | + .better-errors-javascript-not-loaded .be-repl { |
| 493 | + display: none; |
| 494 | + } |
| 495 | + |
471 | 496 | .code, .be-console, .unavailable { |
472 | 497 | background: #fff; |
473 | 498 | padding: 5px; |
|
598 | 623 | .console-has-been-used .live-console-hint { |
599 | 624 | display: none; |
600 | 625 | } |
| 626 | + .better-errors-javascript-not-loaded .live-console-hint { |
| 627 | + display: none; |
| 628 | + } |
601 | 629 |
|
602 | 630 | .hint:before { |
603 | 631 | content: '\25b2'; |
|
701 | 729 | </style> |
702 | 730 |
|
703 | 731 | <%# IE8 compatibility crap %> |
704 | | - <script> |
| 732 | + <script nonce="<%= csp_nonce %>"> |
705 | 733 | (function() { |
706 | 734 | var elements = ["section", "nav", "header", "footer", "audio"]; |
707 | 735 | for (var i = 0; i < elements.length; i++) { |
|
715 | 743 | rendered in the host app's layout. Let's empty out the styles of the |
716 | 744 | host app. |
717 | 745 | %> |
718 | | - <script> |
| 746 | + <script nonce="<%= csp_nonce %>"> |
719 | 747 | if (window.Turbolinks) { |
720 | 748 | for(var i=0; i < document.styleSheets.length; i++) { |
721 | 749 | if(document.styleSheets[i].href) |
|
740 | 768 | } |
741 | 769 | </script> |
742 | 770 |
|
| 771 | + <p class='no-inline-style-notice'> |
| 772 | + <strong> |
| 773 | + Better Errors can't apply inline style<span class='no-javascript-notice'> (or run Javascript)</span>, |
| 774 | + possibly because you have a Content Security Policy along with Turbolinks. |
| 775 | + But you can |
| 776 | + <a href='/__better_errors' target="_blank">open the interactive console in a new tab/window</a>. |
| 777 | + </strong> |
| 778 | + </p> |
| 779 | + |
743 | 780 | <div class='top'> |
744 | 781 | <header class="exception"> |
745 | 782 | <h2><strong><%= exception_type %></strong> <span>at <%= request_path %></span></h2> |
|
786 | 823 | </ul> |
787 | 824 | </nav> |
788 | 825 |
|
789 | | - <% backtrace_frames.each_with_index do |frame, index| %> |
790 | | - <div class="frame_info" id="frame_info_<%= index %>" style="display:none;"></div> |
791 | | - <% end %> |
| 826 | + <div class="frameInfos"> |
| 827 | + <div class="frame_info current" data-frame-idx="0"> |
| 828 | + <p class='no-javascript-notice'> |
| 829 | + Better Errors can't run Javascript here<span class='no-inline-style-notice'> (or apply inline style)</span>, |
| 830 | + possibly because you have a Content Security Policy along with Turbolinks. |
| 831 | + But you can |
| 832 | + <a href='/__better_errors' target="_blank">open the interactive console in a new tab/window</a>. |
| 833 | + </p> |
| 834 | + <!-- this is enough information to show something in case JS doesn't get to load --> |
| 835 | + <%== ErrorPage.render_template('variable_info', first_frame_variable_info) %> |
| 836 | + </div> |
| 837 | + </div> |
792 | 838 | </section> |
793 | 839 | </body> |
794 | | -<script> |
| 840 | +<script nonce="<%= csp_nonce %>"> |
795 | 841 | (function() { |
796 | 842 |
|
797 | 843 | var OID = "<%= id %>"; |
798 | 844 | var csrfToken = "<%= csrf_token %>"; |
799 | 845 |
|
800 | 846 | var previousFrame = null; |
801 | | - var previousFrameInfo = null; |
802 | 847 | var allFrames = document.querySelectorAll("ul.frames li"); |
803 | | - var allFrameInfos = document.querySelectorAll(".frame_info"); |
| 848 | + var frameInfos = document.querySelector(".frameInfos"); |
| 849 | + |
| 850 | + document.querySelector('body').classList.remove("better-errors-javascript-not-loaded"); |
| 851 | + document.querySelector('body').classList.add("better-errors-javascript-loaded"); |
| 852 | + |
| 853 | + var noJSNotices = document.querySelectorAll('.no-javascript-notice'); |
| 854 | + for(var i = 0; i < noJSNotices.length; i++) { |
| 855 | + noJSNotices[i].remove(); |
| 856 | + } |
804 | 857 |
|
805 | 858 | function apiCall(method, opts, cb) { |
806 | 859 | var req = new XMLHttpRequest(); |
|
974 | 1027 | }; |
975 | 1028 |
|
976 | 1029 | function switchTo(el) { |
977 | | - if(previousFrameInfo) previousFrameInfo.style.display = "none"; |
978 | | - previousFrameInfo = el; |
| 1030 | + var currentFrameInfo = document.querySelectorAll('.frame_info.current'); |
| 1031 | + for(var i = 0; i < currentFrameInfo.length; i++) { |
| 1032 | + currentFrameInfo[i].className = "frame_info"; |
| 1033 | + } |
979 | 1034 |
|
980 | | - el.style.display = "block"; |
| 1035 | + el.className = "frame_info current"; |
981 | 1036 |
|
982 | 1037 | var replInput = el.querySelector('.be-console input'); |
983 | 1038 | if (replInput) replInput.focus(); |
984 | 1039 | } |
985 | 1040 |
|
986 | 1041 | function selectFrameInfo(index) { |
987 | | - var el = allFrameInfos[index]; |
| 1042 | + var el = document.querySelector(".frame_info[data-frame-idx='" + index + "']") |
| 1043 | + if (!el) { |
| 1044 | + el = document.createElement("div"); |
| 1045 | + el.className = "frame_info"; |
| 1046 | + el.setAttribute('data-frame-idx', index); |
| 1047 | + frameInfos.appendChild(el); |
| 1048 | + } |
988 | 1049 | if(el) { |
989 | 1050 | if (el.loaded) { |
990 | 1051 | return switchTo(el); |
|
0 commit comments