diff --git a/Rakefile b/Rakefile index cdc19a8f..0eac245d 100644 --- a/Rakefile +++ b/Rakefile @@ -41,7 +41,7 @@ end namespace :style do desc "Build main.css from the SASS sources" task :build do - css = BetterErrors::ErrorPageStyle.compiled_style(true) + css = BetterErrors::ErrorPageStyle.compiled_css(true) File.open(File.expand_path("lib/better_errors/templates/main.css", File.dirname(__FILE__)), "w") do |f| f.write(css) end diff --git a/lib/better_errors/code_formatter.rb b/lib/better_errors/code_formatter.rb index 4c6824d1..a0e0245c 100644 --- a/lib/better_errors/code_formatter.rb +++ b/lib/better_errors/code_formatter.rb @@ -42,7 +42,7 @@ def each_line_of(lines, &blk) end def highlighted_lines - CodeRay.scan(context_lines.join, coderay_scanner).div(wrap: nil).lines + CodeRay.scan(context_lines.join, coderay_scanner).html(css: :class).lines end def context_lines diff --git a/lib/better_errors/code_formatter/html.rb b/lib/better_errors/code_formatter/html.rb index ec96a214..c20b3aa8 100644 --- a/lib/better_errors/code_formatter/html.rb +++ b/lib/better_errors/code_formatter/html.rb @@ -8,7 +8,7 @@ def source_unavailable def formatted_lines each_line_of(highlighted_lines) { |highlight, current_line, str| class_name = highlight ? "highlight" : "" - sprintf '
%s', class_name, str + sprintf '
%s', class_name, str } end diff --git a/lib/better_errors/error_page_style.rb b/lib/better_errors/error_page_style.rb index 3a7377d0..2d14fde5 100644 --- a/lib/better_errors/error_page_style.rb +++ b/lib/better_errors/error_page_style.rb @@ -3,7 +3,7 @@ module BetterErrors # @private module ErrorPageStyle - def self.compiled_style(for_deployment = false) + def self.compiled_css(for_deployment = false) style_dir = File.expand_path("style", File.dirname(__FILE__)) style_file = "#{style_dir}/main.scss" @@ -17,14 +17,14 @@ def self.compiled_style(for_deployment = false) engine.render end - def self.style_tag + def self.style_tag(csp_nonce) style_file = File.expand_path("templates/main.css", File.dirname(__FILE__)) css = if File.exist?(style_file) File.open(style_file).read else - compiled_style(false) + compiled_css(false) end - "" + "" end end end diff --git a/lib/better_errors/middleware.rb b/lib/better_errors/middleware.rb index 7a2ebbeb..34b5efa7 100644 --- a/lib/better_errors/middleware.rb +++ b/lib/better_errors/middleware.rb @@ -119,8 +119,8 @@ def show_error_page(env, exception=nil) # for older browsers without nonce support. # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src "script-src 'self' 'nonce-#{csp_nonce}' 'unsafe-inline'", - # Inline style is required by the syntax highlighter. - "style-src 'self' 'unsafe-inline'", + "style-src 'self' 'nonce-#{csp_nonce}' 'unsafe-inline'", + "img-src data:", "connect-src 'self'", "navigate-to 'self' #{BetterErrors.editor.scheme}", ].join('; '), diff --git a/lib/better_errors/style/main.scss b/lib/better_errors/style/main.scss index 2e906d50..41eb9fb4 100644 --- a/lib/better_errors/style/main.scss +++ b/lib/better_errors/style/main.scss @@ -719,3 +719,5 @@ nav.sidebar:hover::-webkit-scrollbar-thumb { .code:hover::-webkit-scrollbar-thumb { background: #888; } + +@import "syntax_highlighting"; diff --git a/lib/better_errors/style/syntax_highlighting.scss b/lib/better_errors/style/syntax_highlighting.scss new file mode 100644 index 00000000..e24e9be8 --- /dev/null +++ b/lib/better_errors/style/syntax_highlighting.scss @@ -0,0 +1,139 @@ +.CodeRay { +// background-color: #FFF; +// border: 1px solid #CCC; +// font-family: Monaco, "Courier New", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace; + color: #000; +// padding: 1em 0px 1em 1em; + + &span { white-space: pre; border: 0px; padding: 2px } + + &table { + border-collapse: collapse; + width: 100%; + padding: 2px + td { + padding: 1em 0.5em; + vertical-align: top; + } + } + + pre { + margin: 0px; + } + + .line-numbers, .no { + background-color: #ECECEC; + color: #AAA; + text-align: right; + } + + .line-numbers a { + color: #AAA; + } + + .line-numbers tt { font-weight: bold } + .line-numbers .highlighted { color: red } + .line { display: block; float: left; width: 100%; } + span.line-numbers { padding: 0px 4px } + .code { width: 100% } + + &ol { + font-size: 10pt; + li { + white-space: pre + } + } + + .code pre { overflow: auto } + .debug { color:white ! important; background:blue ! important; } + + .annotation { color:#007 } + .attribute-name { color:#f08 } + .attribute-value { color:#700 } + .binary { color:#509; font-weight:bold } + .comment { color:#998; font-style: italic;} + .char { color:#04D } + .char .content { color:#04D } + .char .delimiter { color:#039 } + .class { color:#458; font-weight:bold } + .complex { color:#A08; font-weight:bold } + .constant { color:teal; } + .color { color:#0A0 } + .class-variable { color:#369 } + .decorator { color:#B0B; } + .definition { color:#099; font-weight:bold } + .directive { color:#088; font-weight:bold } + .delimiter { color:black } + .doc { color:#970 } + .doctype { color:#34b } + .doc-string { color:#D42; font-weight:bold } + .escape { color:#666; font-weight:bold } + .entity { color:#800; font-weight:bold } + .error { color:#F00; background-color:#FAA } + .exception { color:#C00; font-weight:bold } + .filename { color:#099; } + .function { color:#900; font-weight:bold } + .global-variable { color:teal; font-weight:bold } + .hex { color:#058; font-weight:bold } + .integer { color:#099; } + .include { color:#B44; font-weight:bold } + .inline { color: black } + .inline .inline { background: #ccc } + .inline .inline .inline { background: #bbb } + .inline .inline-delimiter { color: #D14; } + .inline-delimiter { color: #D14; } + .important { color:#f00; } + .interpreted { color:#B2B; font-weight:bold } + .instance-variable { color:teal } + .label { color:#970; font-weight:bold } + .local-variable { color:#963 } + .octal { color:#40E; font-weight:bold } + .operator { } + .predefined-constant { font-weight:bold } + .predefined { color:#369; font-weight:bold } + .preprocessor { color:#579; } + .pseudo-class { color:#00C; font-weight:bold } + .predefined-type { color:#074; font-weight:bold } + .reserved, .keyword { color:#000; font-weight:bold } + + .key { color: #808; } + .key .delimiter { color: #606; } + .key .char { color: #80f; } + .value { color: #088; } + + .regexp { background-color:#fff0ff } + .regexp .content { color:#808 } + .regexp .delimiter { color:#404 } + .regexp .modifier { color:#C2C } + .regexp .function { color:#404; font-weight: bold } + + .string { color: #D20; } + .string .string { } + .string .string .string { background-color:#ffd0d0 } + .string .content { color: #D14; } + .string .char { color: #D14; } + .string .delimiter { color: #D14; } + + .shell { color:#D14 } + .shell .content { } + .shell .delimiter { color:#D14 } + + .symbol { color:#990073 } + .symbol .content { color:#A60 } + .symbol .delimiter { color:#630 } + + .tag { color:#070 } + .tag-special { color:#D70; font-weight:bold } + .type { color:#339; font-weight:bold } + .variable { color:#036 } + + .insert { background: #afa; } + .delete { background: #faa; } + .change { color: #aaf; background: #007; } + .head { color: #f8f; background: #505 } + + .insert .insert { color: #080; font-weight:bold } + .delete .delete { color: #800; font-weight:bold } + .change .change { color: #66f; } + .head .head { color: #f4f; } +} diff --git a/lib/better_errors/templates/main.erb b/lib/better_errors/templates/main.erb index 60821322..7829c568 100644 --- a/lib/better_errors/templates/main.erb +++ b/lib/better_errors/templates/main.erb @@ -2,10 +2,11 @@