From 4344b8d2d4367b19c6849c3cab0d02d17ddf2304 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 25 Aug 2015 14:31:33 -0700 Subject: [PATCH 01/10] Add Gitlab::ColorSchemes module Very similar to Gitlab::Theme, this contains all of the definitions for our syntax highlighting schemes. --- app/helpers/preferences_helper.rb | 25 +------- app/views/profiles/preferences/show.html.haml | 8 +-- lib/gitlab/color_schemes.rb | 62 +++++++++++++++++++ spec/lib/gitlab/color_schemes_spec.rb | 45 ++++++++++++++ spec/lib/gitlab/themes_spec.rb | 3 - 5 files changed, 113 insertions(+), 30 deletions(-) create mode 100644 lib/gitlab/color_schemes.rb create mode 100644 spec/lib/gitlab/color_schemes_spec.rb diff --git a/app/helpers/preferences_helper.rb b/app/helpers/preferences_helper.rb index ea774e28ecf..b294ddc9d72 100644 --- a/app/helpers/preferences_helper.rb +++ b/app/helpers/preferences_helper.rb @@ -1,25 +1,5 @@ # Helper methods for per-User preferences module PreferencesHelper - COLOR_SCHEMES = { - 1 => 'white', - 2 => 'dark', - 3 => 'solarized-light', - 4 => 'solarized-dark', - 5 => 'monokai', - } - COLOR_SCHEMES.default = 'white' - - # Helper method to access the COLOR_SCHEMES - # - # The keys are the `color_scheme_ids` - # The values are the `name` of the scheme. - # - # The preview images are `name-scheme-preview.png` - # The stylesheets should use the css class `.name` - def color_schemes - COLOR_SCHEMES.freeze - end - # Maps `dashboard` values to more user-friendly option text DASHBOARD_CHOICES = { projects: 'Your Projects (default)', @@ -50,12 +30,11 @@ module PreferencesHelper end def user_application_theme - theme = Gitlab::Themes.by_id(current_user.try(:theme_id)) - theme.css_class + Gitlab::Themes.by_id(current_user.try(:theme_id)).css_class end def user_color_scheme_class - COLOR_SCHEMES[current_user.try(:color_scheme_id)] if defined?(current_user) + Gitlab::ColorSchemes.by_id(current_user.try(:color_scheme_id)).css_class end def prefer_readme? diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml index 1134317ee06..aa0361a0a1b 100644 --- a/app/views/profiles/preferences/show.html.haml +++ b/app/views/profiles/preferences/show.html.haml @@ -22,11 +22,11 @@ .panel-heading Syntax highlighting theme .panel-body - - color_schemes.each do |color_scheme_id, color_scheme| + - Gitlab::ColorSchemes.each do |scheme| = label_tag do - .preview= image_tag "#{color_scheme}-scheme-preview.png" - = f.radio_button :color_scheme_id, color_scheme_id - = color_scheme.tr('-_', ' ').titleize + .preview= image_tag "#{scheme.css_class}-scheme-preview.png" + = f.radio_button :color_scheme_id, scheme.id + = scheme.name .panel.panel-default .panel-heading diff --git a/lib/gitlab/color_schemes.rb b/lib/gitlab/color_schemes.rb new file mode 100644 index 00000000000..763853ab1cb --- /dev/null +++ b/lib/gitlab/color_schemes.rb @@ -0,0 +1,62 @@ +module Gitlab + # Module containing GitLab's syntax color scheme definitions and helper + # methods for accessing them. + module ColorSchemes + # Struct class representing a single Scheme + Scheme = Struct.new(:id, :name, :css_class) + + SCHEMES = [ + Scheme.new(1, 'White', 'white'), + Scheme.new(2, 'Dark', 'dark'), + Scheme.new(3, 'Solarized Light', 'solarized-light'), + Scheme.new(4, 'Solarized Dark', 'solarized-dark'), + Scheme.new(5, 'Monokai', 'monokai') + ].freeze + + # Convenience method to get a space-separated String of all the color scheme + # classes that might be applied to a code block. + # + # Returns a String + def self.body_classes + SCHEMES.collect(&:css_class).uniq.join(' ') + end + + # Get a Scheme by its ID + # + # If the ID is invalid, returns the default Scheme. + # + # id - Integer ID + # + # Returns a Scheme + def self.by_id(id) + SCHEMES.detect { |s| s.id == id } || default + end + + # Get the default Scheme + # + # Returns a Scheme + def self.default + by_id(1) + end + + # Iterate through each Scheme + # + # Yields the Scheme object + def self.each(&block) + SCHEMES.each(&block) + end + + # Get the Scheme for the specified user, or the default + # + # user - User record + # + # Returns a Scheme + def self.for_user(user) + if user + by_id(user.color_scheme_id) + else + default + end + end + end +end diff --git a/spec/lib/gitlab/color_schemes_spec.rb b/spec/lib/gitlab/color_schemes_spec.rb new file mode 100644 index 00000000000..c7be45dbcd3 --- /dev/null +++ b/spec/lib/gitlab/color_schemes_spec.rb @@ -0,0 +1,45 @@ +require 'spec_helper' + +describe Gitlab::ColorSchemes do + describe '.body_classes' do + it 'returns a space-separated list of class names' do + css = described_class.body_classes + + expect(css).to include('white') + expect(css).to include(' solarized-light ') + expect(css).to include(' monokai') + end + end + + describe '.by_id' do + it 'returns a scheme by its ID' do + expect(described_class.by_id(1).name).to eq 'White' + expect(described_class.by_id(4).name).to eq 'Solarized Dark' + end + end + + describe '.default' do + it 'returns the default scheme' do + expect(described_class.default.id).to eq 1 + end + end + + describe '.each' do + it 'passes the block to the SCHEMES Array' do + ids = [] + described_class.each { |scheme| ids << scheme.id } + expect(ids).not_to be_empty + end + end + + describe '.for_user' do + it 'returns default when user is nil' do + expect(described_class.for_user(nil).id).to eq 1 + end + + it "returns user's preferred color scheme" do + user = double(color_scheme_id: 5) + expect(described_class.for_user(user).id).to eq 5 + end + end +end diff --git a/spec/lib/gitlab/themes_spec.rb b/spec/lib/gitlab/themes_spec.rb index 9c6c3fd8104..e554458e41c 100644 --- a/spec/lib/gitlab/themes_spec.rb +++ b/spec/lib/gitlab/themes_spec.rb @@ -43,9 +43,6 @@ describe Gitlab::Themes do ids = [] described_class.each { |theme| ids << theme.id } expect(ids).not_to be_empty - - # TODO (rspeicher): RSpec 3.x - # expect(described_class.each).to yield_with_arg(described_class::Theme) end end end From 59180c4f5a553938ee79968e7983aee6ce584ff5 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 25 Aug 2015 15:23:41 -0700 Subject: [PATCH 02/10] Add highlight_word style definition to each color scheme Now we don't need to override the user color scheme on search results. They'll look good with any of them. --- app/assets/stylesheets/generic/common.scss | 4 ---- app/assets/stylesheets/highlight/dark.scss | 6 ++++++ app/assets/stylesheets/highlight/monokai.scss | 6 ++++++ app/assets/stylesheets/highlight/solarized_dark.scss | 5 +++++ app/assets/stylesheets/highlight/solarized_light.scss | 5 +++++ app/assets/stylesheets/highlight/white.scss | 5 +++++ 6 files changed, 27 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss index bf5c7a8d75e..7281b26179e 100644 --- a/app/assets/stylesheets/generic/common.scss +++ b/app/assets/stylesheets/generic/common.scss @@ -132,10 +132,6 @@ p.time { text-shadow: none; } -.highlight_word { - background: #fafe3d; -} - .thin_area{ height: 150px; } diff --git a/app/assets/stylesheets/highlight/dark.scss b/app/assets/stylesheets/highlight/dark.scss index c8cb18ec35f..8323a8598ec 100644 --- a/app/assets/stylesheets/highlight/dark.scss +++ b/app/assets/stylesheets/highlight/dark.scss @@ -21,6 +21,12 @@ pre.code.highlight.dark, background-color: #557 !important; } + // Search result highlight + span.highlight_word { + background: #ffe792; + color: #000000; + } + .hll { background-color: #373b41 } .c { color: #969896 } /* Comment */ .err { color: #cc6666 } /* Error */ diff --git a/app/assets/stylesheets/highlight/monokai.scss b/app/assets/stylesheets/highlight/monokai.scss index 001e8b31020..e8381674336 100644 --- a/app/assets/stylesheets/highlight/monokai.scss +++ b/app/assets/stylesheets/highlight/monokai.scss @@ -21,6 +21,12 @@ pre.code.monokai, background-color: #49483e !important; } + // Search result highlight + span.highlight_word { + background: #ffe792; + color: #000000; + } + .hll { background-color: #49483e } .c { color: #75715e } /* Comment */ .err { color: #960050; background-color: #1e0010 } /* Error */ diff --git a/app/assets/stylesheets/highlight/solarized_dark.scss b/app/assets/stylesheets/highlight/solarized_dark.scss index f5b827e7c02..bd41480aefb 100644 --- a/app/assets/stylesheets/highlight/solarized_dark.scss +++ b/app/assets/stylesheets/highlight/solarized_dark.scss @@ -21,6 +21,11 @@ pre.code.highlight.solarized-dark, background-color: #174652 !important; } + // Search result highlight + span.highlight_word { + background: #094554; + } + /* Solarized Dark For use with Jekyll and Pygments diff --git a/app/assets/stylesheets/highlight/solarized_light.scss b/app/assets/stylesheets/highlight/solarized_light.scss index 6b44c00c305..4cc62863870 100644 --- a/app/assets/stylesheets/highlight/solarized_light.scss +++ b/app/assets/stylesheets/highlight/solarized_light.scss @@ -21,6 +21,11 @@ pre.code.highlight.solarized-light, background-color: #ddd8c5 !important; } + // Search result highlight + span.highlight_word { + background: #eee8d5; + } + /* Solarized Light For use with Jekyll and Pygments diff --git a/app/assets/stylesheets/highlight/white.scss b/app/assets/stylesheets/highlight/white.scss index a52ffc971d1..e0edfb80b42 100644 --- a/app/assets/stylesheets/highlight/white.scss +++ b/app/assets/stylesheets/highlight/white.scss @@ -21,6 +21,11 @@ pre.code.highlight.white, background-color: #f8eec7 !important; } + // Search result highlight + span.highlight_word { + background: #fafe3d; + } + .hll { background-color: #f8f8f8 } .c { color: #999988; font-style: italic; } .err { color: #a61717; background-color: #e3d2d2; } From 2c3e42e4a44e2f40e521cbafc8144e5d7c366b76 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 25 Aug 2015 15:24:53 -0700 Subject: [PATCH 03/10] Remove user_color_scheme_class Instead of rendering this value server-side, we use Javascript and Gon to apply the user's color scheme (or the default) to any syntax highlighted code blocks. This will make it easier to cache these blocks in the future because they're no longer state-dependent. --- .../javascripts/syntax_highlight.coffee | 9 ++++++++ app/controllers/application_controller.rb | 9 ++++---- app/helpers/gitlab_markdown_helper.rb | 2 +- app/helpers/preferences_helper.rb | 4 ---- app/views/search/results/_blob.html.haml | 2 +- .../search/results/_snippet_blob.html.haml | 2 +- app/views/search/results/_wiki_blob.html.haml | 2 +- app/views/shared/_file_highlight.html.haml | 2 +- lib/redcarpet/render/gitlab_html.rb | 5 ++--- spec/features/markdown_spec.rb | 4 ---- spec/helpers/preferences_helper_spec.rb | 21 ------------------- 11 files changed, 21 insertions(+), 41 deletions(-) create mode 100644 app/assets/javascripts/syntax_highlight.coffee diff --git a/app/assets/javascripts/syntax_highlight.coffee b/app/assets/javascripts/syntax_highlight.coffee new file mode 100644 index 00000000000..510f15d1b49 --- /dev/null +++ b/app/assets/javascripts/syntax_highlight.coffee @@ -0,0 +1,9 @@ +# Applies a syntax highlighting color scheme CSS class to any element with the +# `js-syntax-highlight` class +# +# ### Example Markup +# +#
+# +$(document).on 'ready page:load', -> + $('.js-syntax-highlight').addClass(gon.user_color_scheme) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 12d439b0b31..b51a9600c18 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -190,11 +190,12 @@ class ApplicationController < ActionController::Base end def add_gon_variables + gon.api_version = API::API.version + gon.default_avatar_url = URI::join(Gitlab.config.gitlab.url, ActionController::Base.helpers.image_path('no_avatar.png')).to_s gon.default_issues_tracker = Project.new.default_issue_tracker.to_param - gon.api_version = API::API.version - gon.relative_url_root = Gitlab.config.gitlab.relative_url_root - gon.default_avatar_url = URI::join(Gitlab.config.gitlab.url, ActionController::Base.helpers.image_path('no_avatar.png')).to_s - gon.max_file_size = current_application_settings.max_attachment_size; + gon.max_file_size = current_application_settings.max_attachment_size + gon.relative_url_root = Gitlab.config.gitlab.relative_url_root + gon.user_color_scheme = Gitlab::ColorSchemes.for_user(current_user).css_class if current_user gon.current_user_id = current_user.id diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb index eb3f72a307d..114730eb948 100644 --- a/app/helpers/gitlab_markdown_helper.rb +++ b/app/helpers/gitlab_markdown_helper.rb @@ -58,7 +58,7 @@ module GitlabMarkdownHelper @options = options # see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch - rend = Redcarpet::Render::GitlabHTML.new(self, user_color_scheme_class, options) + rend = Redcarpet::Render::GitlabHTML.new(self, options) # see https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use @markdown = Redcarpet::Markdown.new(rend, MARKDOWN_OPTIONS) diff --git a/app/helpers/preferences_helper.rb b/app/helpers/preferences_helper.rb index b294ddc9d72..51a6b3fa997 100644 --- a/app/helpers/preferences_helper.rb +++ b/app/helpers/preferences_helper.rb @@ -33,10 +33,6 @@ module PreferencesHelper Gitlab::Themes.by_id(current_user.try(:theme_id)).css_class end - def user_color_scheme_class - Gitlab::ColorSchemes.by_id(current_user.try(:color_scheme_id)).css_class - end - def prefer_readme? !current_user || current_user.project_view == 'readme' diff --git a/app/views/search/results/_blob.html.haml b/app/views/search/results/_blob.html.haml index 58f58eff54d..0fe8a3b490a 100644 --- a/app/views/search/results/_blob.html.haml +++ b/app/views/search/results/_blob.html.haml @@ -7,4 +7,4 @@ %strong = blob.filename .file-content.code.term - = render 'shared/file_highlight', blob: blob, first_line_number: blob.startline, user_color_scheme_class: 'white' + = render 'shared/file_highlight', blob: blob, first_line_number: blob.startline diff --git a/app/views/search/results/_snippet_blob.html.haml b/app/views/search/results/_snippet_blob.html.haml index 95099853918..19a7bfefef5 100644 --- a/app/views/search/results/_snippet_blob.html.haml +++ b/app/views/search/results/_snippet_blob.html.haml @@ -23,7 +23,7 @@ .nothing-here-block Empty file - else .file-content.code - %div.highlighted-data{class: user_color_scheme_class} + %div.highlighted-data.js-syntax-highlight .line-numbers - snippet_blob[:snippet_chunks].each do |snippet| - unless snippet[:data].empty? diff --git a/app/views/search/results/_wiki_blob.html.haml b/app/views/search/results/_wiki_blob.html.haml index c03438eb952..f5859481d46 100644 --- a/app/views/search/results/_wiki_blob.html.haml +++ b/app/views/search/results/_wiki_blob.html.haml @@ -7,4 +7,4 @@ %strong = wiki_blob.filename .file-content.code.term - = render 'shared/file_highlight', blob: wiki_blob, first_line_number: wiki_blob.startline, user_color_scheme_class: 'white' + = render 'shared/file_highlight', blob: wiki_blob, first_line_number: wiki_blob.startline diff --git a/app/views/shared/_file_highlight.html.haml b/app/views/shared/_file_highlight.html.haml index d6a2e177da1..7b1c624d769 100644 --- a/app/views/shared/_file_highlight.html.haml +++ b/app/views/shared/_file_highlight.html.haml @@ -1,4 +1,4 @@ -.file-content.code{class: user_color_scheme_class} +.file-content.code.js-syntax-highlight .line-numbers - if blob.data.present? - blob.data.lines.each_index do |index| diff --git a/lib/redcarpet/render/gitlab_html.rb b/lib/redcarpet/render/gitlab_html.rb index f57b56cbdf0..9cb8e91d6e3 100644 --- a/lib/redcarpet/render/gitlab_html.rb +++ b/lib/redcarpet/render/gitlab_html.rb @@ -4,9 +4,8 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML attr_reader :template alias_method :h, :template - def initialize(template, color_scheme, options = {}) + def initialize(template, options = {}) @template = template - @color_scheme = color_scheme @options = options.dup @options.reverse_merge!( @@ -35,7 +34,7 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML end formatter = Rouge::Formatters::HTMLGitlab.new( - cssclass: "code highlight #{@color_scheme} #{lexer.tag}" + cssclass: "code highlight js-syntax-highlight #{lexer.tag}" ) formatter.format(lexer.lex(code)) end diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index 3da4dfc2b23..d32bd4adb52 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -224,8 +224,4 @@ describe 'GitLab Markdown', feature: true do def current_user @feat.user end - - def user_color_scheme_class - :white - end end diff --git a/spec/helpers/preferences_helper_spec.rb b/spec/helpers/preferences_helper_spec.rb index d814b562113..b4dee272bfd 100644 --- a/spec/helpers/preferences_helper_spec.rb +++ b/spec/helpers/preferences_helper_spec.rb @@ -48,25 +48,4 @@ describe PreferencesHelper do ] end end - - describe 'user_color_scheme_class' do - context 'with current_user is nil' do - it 'should return a string' do - allow(self).to receive(:current_user).and_return(nil) - expect(user_color_scheme_class).to be_kind_of(String) - end - end - - context 'with a current_user' do - (1..5).each do |color_scheme_id| - context "with color_scheme_id == #{color_scheme_id}" do - it 'should return a string' do - current_user = double(color_scheme_id: color_scheme_id) - allow(self).to receive(:current_user).and_return(current_user) - expect(user_color_scheme_class).to be_kind_of(String) - end - end - end - end - end end From c401543d02487888a71966518fa8cb4f17de1397 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 25 Aug 2015 15:57:55 -0700 Subject: [PATCH 04/10] Fix failing spec --- spec/features/markdown_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index d32bd4adb52..4fe019f8342 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -64,8 +64,8 @@ describe 'GitLab Markdown', feature: true do it 'parses fenced code blocks' do aggregate_failures do - expect(doc).to have_selector('pre.code.highlight.white.c') - expect(doc).to have_selector('pre.code.highlight.white.python') + expect(doc).to have_selector('pre.code.highlight.js-syntax-highlight.c') + expect(doc).to have_selector('pre.code.highlight.js-syntax-highlight.python') end end From d6a145d4b0b8d2baa63f2c1699ba44ea203a4ae8 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 25 Aug 2015 16:26:20 -0700 Subject: [PATCH 05/10] Fix two more failing specs --- spec/helpers/events_helper_spec.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spec/helpers/events_helper_spec.rb b/spec/helpers/events_helper_spec.rb index da58ab98462..e68a5ec29ab 100644 --- a/spec/helpers/events_helper_spec.rb +++ b/spec/helpers/events_helper_spec.rb @@ -28,8 +28,7 @@ describe EventsHelper do it 'should display the first line of a code block' do input = "```\nCode block\nwith two lines\n```" - expected = '
' \
-               'Code block...
' + expected = %r{Code block\.\.\.} expect(event_note(input)).to match(expected) end @@ -55,7 +54,7 @@ describe EventsHelper do it 'should preserve code color scheme' do input = "```ruby\ndef test\n 'hello world'\nend\n```" - expected = '
' \
+    expected = '
' \
       "def test\n" \
       "  \'hello world\'\n" \
       "end" \

From 6d43308b5a5ff7663e1782fd6f5493f48c0f7e2a Mon Sep 17 00:00:00 2001
From: Robert Speicher 
Date: Wed, 26 Aug 2015 11:30:11 -0700
Subject: [PATCH 06/10] Add `Gitlab::Themes.for_user`

---
 lib/gitlab/themes.rb | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/lib/gitlab/themes.rb b/lib/gitlab/themes.rb
index 5209df92795..37a36b9599b 100644
--- a/lib/gitlab/themes.rb
+++ b/lib/gitlab/themes.rb
@@ -51,6 +51,19 @@ module Gitlab
       THEMES.each(&block)
     end
 
+    # Get the Theme for the specified user, or the default
+    #
+    # user - User record
+    #
+    # Returns a Theme
+    def self.for_user(user)
+      if user
+        by_id(user.theme_id)
+      else
+        default
+      end
+    end
+
     private
 
     def self.default_id

From 2d72efcd9fb63f4bb0c6aed5a472a2eca2d6abac Mon Sep 17 00:00:00 2001
From: Robert Speicher 
Date: Wed, 26 Aug 2015 11:30:38 -0700
Subject: [PATCH 07/10] Add `count` to Themes and ColorSchemes

---
 lib/gitlab/color_schemes.rb | 5 +++++
 lib/gitlab/themes.rb        | 5 +++++
 2 files changed, 10 insertions(+)

diff --git a/lib/gitlab/color_schemes.rb b/lib/gitlab/color_schemes.rb
index 763853ab1cb..9c4664df903 100644
--- a/lib/gitlab/color_schemes.rb
+++ b/lib/gitlab/color_schemes.rb
@@ -32,6 +32,11 @@ module Gitlab
       SCHEMES.detect { |s| s.id == id } || default
     end
 
+    # Returns the number of defined Schemes
+    def self.count
+      SCHEMES.size
+    end
+
     # Get the default Scheme
     #
     # Returns a Scheme
diff --git a/lib/gitlab/themes.rb b/lib/gitlab/themes.rb
index 37a36b9599b..83f91de810c 100644
--- a/lib/gitlab/themes.rb
+++ b/lib/gitlab/themes.rb
@@ -37,6 +37,11 @@ module Gitlab
       THEMES.detect { |t| t.id == id } || default
     end
 
+    # Returns the number of defined Themes
+    def self.count
+      THEMES.size
+    end
+
     # Get the default Theme
     #
     # Returns a Theme

From 7a81dc65d9013dff4d8bf36cf78e027693703990 Mon Sep 17 00:00:00 2001
From: Robert Speicher 
Date: Wed, 26 Aug 2015 11:33:44 -0700
Subject: [PATCH 08/10] Re-add user_color_scheme helper

Update PreferencesHelper specs
---
 app/helpers/preferences_helper.rb       |  6 +-
 spec/helpers/preferences_helper_spec.rb | 95 ++++++++++++++++---------
 2 files changed, 68 insertions(+), 33 deletions(-)

diff --git a/app/helpers/preferences_helper.rb b/app/helpers/preferences_helper.rb
index 51a6b3fa997..7f1b6a69926 100644
--- a/app/helpers/preferences_helper.rb
+++ b/app/helpers/preferences_helper.rb
@@ -30,7 +30,11 @@ module PreferencesHelper
   end
 
   def user_application_theme
-    Gitlab::Themes.by_id(current_user.try(:theme_id)).css_class
+    Gitlab::Themes.for_user(current_user).css_class
+  end
+
+  def user_color_scheme
+    Gitlab::ColorSchemes.for_user(current_user).css_class
   end
 
   def prefer_readme?
diff --git a/spec/helpers/preferences_helper_spec.rb b/spec/helpers/preferences_helper_spec.rb
index b4dee272bfd..06f69262b71 100644
--- a/spec/helpers/preferences_helper_spec.rb
+++ b/spec/helpers/preferences_helper_spec.rb
@@ -1,51 +1,82 @@
 require 'spec_helper'
 
 describe PreferencesHelper do
-  describe 'user_application_theme' do
-    context 'with a user' do
-      it "returns user's theme's css_class" do
-        user = double('user', theme_id: 3)
-        allow(self).to receive(:current_user).and_return(user)
-        expect(user_application_theme).to eq 'ui_green'
-      end
-
-      it 'returns the default when id is invalid' do
-        user = double('user', theme_id: Gitlab::Themes::THEMES.size + 5)
-
-        allow(Gitlab.config.gitlab).to receive(:default_theme).and_return(2)
-        allow(self).to receive(:current_user).and_return(user)
-
-        expect(user_application_theme).to eq 'ui_charcoal'
-      end
-    end
-
-    context 'without a user' do
-      before do
-        allow(self).to receive(:current_user).and_return(nil)
-      end
-
-      it 'returns the default theme' do
-        expect(user_application_theme).to eq Gitlab::Themes.default.css_class
-      end
-    end
-  end
-
   describe 'dashboard_choices' do
     it 'raises an exception when defined choices may be missing' do
       expect(User).to receive(:dashboards).and_return(foo: 'foo')
-      expect { dashboard_choices }.to raise_error(RuntimeError)
+      expect { helper.dashboard_choices }.to raise_error(RuntimeError)
     end
 
     it 'raises an exception when defined choices may be using the wrong key' do
       expect(User).to receive(:dashboards).and_return(foo: 'foo', bar: 'bar')
-      expect { dashboard_choices }.to raise_error(KeyError)
+      expect { helper.dashboard_choices }.to raise_error(KeyError)
     end
 
     it 'provides better option descriptions' do
-      expect(dashboard_choices).to match_array [
+      expect(helper.dashboard_choices).to match_array [
         ['Your Projects (default)', 'projects'],
         ['Starred Projects',        'stars']
       ]
     end
   end
+
+  describe 'user_application_theme' do
+    context 'with a user' do
+      it "returns user's theme's css_class" do
+        stub_user(theme_id: 3)
+
+        expect(helper.user_application_theme).to eq 'ui_green'
+      end
+
+      it 'returns the default when id is invalid' do
+        stub_user(theme_id: Gitlab::Themes.count + 5)
+
+        allow(Gitlab.config.gitlab).to receive(:default_theme).and_return(2)
+
+        expect(helper.user_application_theme).to eq 'ui_charcoal'
+      end
+    end
+
+    context 'without a user' do
+      it 'returns the default theme' do
+        stub_user
+
+        expect(helper.user_application_theme).to eq Gitlab::Themes.default.css_class
+      end
+    end
+  end
+
+  describe 'user_color_scheme' do
+    context 'with a user' do
+      it "returns user's scheme's css_class" do
+        allow(helper).to receive(:current_user).
+          and_return(double(color_scheme_id: 3))
+
+        expect(helper.user_color_scheme).to eq 'solarized-light'
+      end
+
+      it 'returns the default when id is invalid' do
+        allow(helper).to receive(:current_user).
+          and_return(double(color_scheme_id: Gitlab::ColorSchemes.count + 5))
+      end
+    end
+
+    context 'without a user' do
+      it 'returns the default theme' do
+        stub_user
+
+        expect(helper.user_color_scheme).
+          to eq Gitlab::ColorSchemes.default.css_class
+      end
+    end
+  end
+
+  def stub_user(messages = {})
+    if messages.empty?
+      allow(helper).to receive(:current_user).and_return(nil)
+    else
+      allow(helper).to receive(:current_user).
+        and_return(double('user', messages))
+    end
+  end
 end

From 54771100eb8693c7fa06ea31041b0bd15f78dcc7 Mon Sep 17 00:00:00 2001
From: Robert Speicher 
Date: Wed, 26 Aug 2015 11:34:28 -0700
Subject: [PATCH 09/10] Add user_color_scheme class to file_highlight

Prevents an unstyled flash that occurs when we were only applying the
syntax highlighting class in Javascript. Now for these uncached blobs
the server can add the syntax class, and for (possibly) cached fenced
code blocks, the Javascript will add it as needed.
---
 app/views/shared/_file_highlight.html.haml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/views/shared/_file_highlight.html.haml b/app/views/shared/_file_highlight.html.haml
index 7b1c624d769..57c3aff3e18 100644
--- a/app/views/shared/_file_highlight.html.haml
+++ b/app/views/shared/_file_highlight.html.haml
@@ -1,4 +1,4 @@
-.file-content.code.js-syntax-highlight
+.file-content.code.js-syntax-highlight{ class: user_color_scheme }
   .line-numbers
     - if blob.data.present?
       - blob.data.lines.each_index do |index|

From ce0a0feff45b47b6c03b9ab01d815b651840a7b2 Mon Sep 17 00:00:00 2001
From: Robert Speicher 
Date: Wed, 26 Aug 2015 11:43:25 -0700
Subject: [PATCH 10/10] Make snippet_blob highlight server-side as well

---
 app/views/search/results/_snippet_blob.html.haml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/views/search/results/_snippet_blob.html.haml b/app/views/search/results/_snippet_blob.html.haml
index 19a7bfefef5..9a4f9fb9485 100644
--- a/app/views/search/results/_snippet_blob.html.haml
+++ b/app/views/search/results/_snippet_blob.html.haml
@@ -23,7 +23,7 @@
                 .nothing-here-block Empty file
       - else
         .file-content.code
-          %div.highlighted-data.js-syntax-highlight
+          %div.highlighted-data{ class: user_color_scheme }
             .line-numbers
               - snippet_blob[:snippet_chunks].each do |snippet|
                 - unless snippet[:data].empty?