diff --git a/app/models/code_theme_user_setting.rb b/app/models/code_theme_user_setting.rb new file mode 100644 index 0000000..acc5663 --- /dev/null +++ b/app/models/code_theme_user_setting.rb @@ -0,0 +1,94 @@ + +class CodeThemeUserSetting < ActiveRecord::Base + unloadable + belongs_to :user + validates_presence_of :user + + DEFAULT_CODE_THEME = '__default_code_theme__' + CODE_THEMES = { + 'agate' => 'agate', + 'androidstudio' => 'androidstudio', + 'arta' => 'arta', + 'ascetic' => 'ascetic', + 'atelier cave (light)' => 'atelier-cave.light', + 'atelier cave (dark)' => 'atelier-cave.dark', + 'atelier dune (light)' => 'atelier-dune.light', + 'atelier dune (dark)' => 'atelier-dune.dark', + 'atelier estuary (light)' => 'atelier-estuary.light', + 'atelier estuary (dark)' => 'atelier-estuary.dark', + 'atelier forest (light)' => 'atelier-forest.light', + 'atelier forest (dark)' => 'atelier-forest.dark', + 'atelier heath (light)' => 'atelier-heath.light', + 'atelier heath (dark)' => 'atelier-heath.dark', + 'atelier lakeside (light)' => 'atelier-lakeside.light', + 'atelier lakeside (dark)' => 'atelier-lakeside.dark', + 'atelier plateau (light)' => 'atelier-plateau.light', + 'atelier plateau (dark)' => 'atelier-plateau.dark', + 'atelier savanna (light)' => 'atelier-savanna.light', + 'atelier savanna (dark)' => 'atelier-savanna.dark', + 'atelier seaside (light)' => 'atelier-seaside.light', + 'atelier seaside (dark)' => 'atelier-seaside.dark', + 'atelier sulphurpool (light)' => 'atelier-sulphurpool.light', + 'atelier sulphurpool (dark)' => 'atelier-sulphurpool.dark', + 'brown paper' => 'brown_paper', + 'codepen embed' => 'codepen-embed', + 'color brewer' => 'color-brewer', + 'dark' => 'dark', + 'darkula' => 'darkula', + 'default' => 'default', + 'docco' => 'docco', + 'far' => 'far', + 'foundation' => 'foundation', + 'github' => 'github', + 'github gist' => 'github-gist', + 'googlecode' => 'googlecode', + 'grayscale' => 'grayscale', + 'hopscotch' => 'hopscotch', + 'hybrid' => 'hybrid', + 'idea' => 'idea', + 'ir_black' => 'ir_black', + 'kimbie (light)' => 'kimbie.light', + 'kimbie (dark)' => 'kimbie.dark', + 'magula' => 'magula', + 'mono-blue' => 'mono-blue', + 'monokai' => 'monokai', + 'monokai sublime' => 'monokai_sublime', + 'obsidian' => 'obsidian', + 'paraiso (light)' => 'paraiso.light', + 'paraiso (dark)' => 'paraiso.dark', + 'pojoaque' => 'pojoaque', + 'pojoaque.jpg' => 'pojoaque.jpg', + 'railscasts' => 'railscasts', + 'rainbow' => 'rainbow', + 'school_book' => 'school_book', + 'solarized (light)' => 'solarized_light', + 'solarized (dark)' => 'solarized_dark', + 'sunburst' => 'sunburst', + 'tomorrow night' => 'tomorrow-night', + 'tomorrow night (blue)' => 'tomorrow-night-blue', + 'tomorrow night (bright)' => 'tomorrow-night-bright', + 'tomorrow night (eighties)' => 'tomorrow-night-eighties', + 'tomorrow' => 'tomorrow', + 'vs' => 'vs', + 'xcode' => 'xcode', + 'zenburn' => 'zenburn' + } + + def self.find_code_theme_by_user_id(user_id) + CodeThemeUserSetting.find(:first, :conditions => ['user_id = ?', user_id]) + end + + def self.find_or_create_code_theme_by_user_id(user_id) + code_theme = find_code_theme_by_user_id(user_id) + unless code_theme + code_theme = CodeThemeUserSetting.new + code_theme.user_id = user_id + end + return code_theme + end + + def code_theme_name + return '' if code_theme == DEFAULT_CODE_THEME + code_theme + end +end diff --git a/app/views/settings/_code_theme_form.html.erb b/app/views/settings/_code_theme_form.html.erb new file mode 100644 index 0000000..ec0cecb --- /dev/null +++ b/app/views/settings/_code_theme_form.html.erb @@ -0,0 +1,19 @@ +
+ +<%=h l(:code_theme_title) %> +
+

+ + <%=select_tag("pref[code_theme]", options_for_select( + { + l(:label_default) => CodeThemeUserSetting::DEFAULT_CODE_THEME + }.merge(CodeThemeUserSetting::CODE_THEMES), + user.preference.code_theme)) + %> +

+

+ <%= l(:try_it_link) %> https://highlightjs.org/static/demo/ +

+
+ +
diff --git a/app/views/settings/_highlightjs_settings.html.erb b/app/views/settings/_highlightjs_settings.html.erb index 3a963fd..4a3c235 100644 --- a/app/views/settings/_highlightjs_settings.html.erb +++ b/app/views/settings/_highlightjs_settings.html.erb @@ -3,77 +3,14 @@ <%= select_tag('settings[theme]', - options_for_select({ - 'agate' => 'agate', - 'androidstudio' => 'androidstudio', - 'arta' => 'arta', - 'ascetic' => 'ascetic', - 'atelier cave (light)' => 'atelier-cave.light', - 'atelier cave (dark)' => 'atelier-cave.dark', - 'atelier dune (light)' => 'atelier-dune.light', - 'atelier dune (dark)' => 'atelier-dune.dark', - 'atelier estuary (light)' => 'atelier-estuary.light', - 'atelier estuary (dark)' => 'atelier-estuary.dark', - 'atelier forest (light)' => 'atelier-forest.light', - 'atelier forest (dark)' => 'atelier-forest.dark', - 'atelier heath (light)' => 'atelier-heath.light', - 'atelier heath (dark)' => 'atelier-heath.dark', - 'atelier lakeside (light)' => 'atelier-lakeside.light', - 'atelier lakeside (dark)' => 'atelier-lakeside.dark', - 'atelier plateau (light)' => 'atelier-plateau.light', - 'atelier plateau (dark)' => 'atelier-plateau.dark', - 'atelier savanna (light)' => 'atelier-savanna.light', - 'atelier savanna (dark)' => 'atelier-savanna.dark', - 'atelier seaside (light)' => 'atelier-seaside.light', - 'atelier seaside (dark)' => 'atelier-seaside.dark', - 'atelier sulphurpool (light)' => 'atelier-sulphurpool.light', - 'atelier sulphurpool (dark)' => 'atelier-sulphurpool.dark', - 'brown paper' => 'brown_paper', - 'codepen embed' => 'codepen-embed', - 'color brewer' => 'color-brewer', - 'dark' => 'dark', - 'darkula' => 'darkula', - 'default' => 'default', - 'docco' => 'docco', - 'far' => 'far', - 'foundation' => 'foundation', - 'github' => 'github', - 'github gist' => 'github-gist', - 'googlecode' => 'googlecode', - 'grayscale' => 'grayscale', - 'hopscotch' => 'hopscotch', - 'hybrid' => 'hybrid', - 'idea' => 'idea', - 'ir_black' => 'ir_black', - 'kimbie (light)' => 'kimbie.light', - 'kimbie (dark)' => 'kimbie.dark', - 'magula' => 'magula', - 'mono-blue' => 'mono-blue', - 'monokai' => 'monokai', - 'monokai sublime' => 'monokai_sublime', - 'obsidian' => 'obsidian', - 'paraiso (light)' => 'paraiso.light', - 'paraiso (dark)' => 'paraiso.dark', - 'pojoaque' => 'pojoaque', - 'pojoaque.jpg' => 'pojoaque.jpg', - 'railscasts' => 'railscasts', - 'rainbow' => 'rainbow', - 'school_book' => 'school_book', - 'solarized (light)' => 'solarized_light', - 'solarized (dark)' => 'solarized_dark', - 'sunburst' => 'sunburst', - 'tomorrow night' => 'tomorrow-night', - 'tomorrow night (blue)' => 'tomorrow-night-blue', - 'tomorrow night (bright)' => 'tomorrow-night-bright', - 'tomorrow night (eighties)' => 'tomorrow-night-eighties', - 'tomorrow' => 'tomorrow', - 'vs' => 'vs', - 'xcode' => 'xcode', - 'zenburn' => 'zenburn' - }, settings['theme'])) %> + options_for_select(CodeThemeUserSetting::CODE_THEMES, settings['theme'])) %> <%= l(:try_it_link) %> https://highlightjs.org/static/demo/ + + + <%=check_box_tag 'settings[allow_redefine]', 'yes', settings['allow_redefine'] == 'yes' %> + diff --git a/assets/stylesheets/fixes.css b/assets/stylesheets/fixes.css index 995e0c7..23da48e 100644 --- a/assets/stylesheets/fixes.css +++ b/assets/stylesheets/fixes.css @@ -79,3 +79,7 @@ pre code.nohighlight { padding: 10px !important; display: block !important; } + +fieldset.hidden { + display: none !important; +} diff --git a/config/locales/en.yml b/config/locales/en.yml index af343a6..784c99b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3,3 +3,7 @@ en: supported_languages: Language Markups supported in this build highlighting_theme: Highlight using theme try_it_link: "Try theme with online demo:" + code_theme: Highlight Code Theme + code_theme_title: Podświetlenie bloków kodu + allow_redefine: Allow to redefine by user + diff --git a/config/locales/pl.yml b/config/locales/pl.yml index c8233d7..7afa840 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -3,4 +3,7 @@ pl: supported_languages: Definicje wspierane w tej wersji biblioteki highlighting_theme: Schemat kolorów try_it_link: "Wybierz korzystając z demo online:" - + code_theme: Schemat podświetlania + code_theme_title: Podświetlenie bloków kodu + allow_redefine: Pozwalaj zmieniać użytkownikom + diff --git a/db/migrate/0002_create_code_theme_user_settings.rb b/db/migrate/0002_create_code_theme_user_settings.rb new file mode 100644 index 0000000..cad7716 --- /dev/null +++ b/db/migrate/0002_create_code_theme_user_settings.rb @@ -0,0 +1,13 @@ +class CreateCodeThemeUserSettings < ActiveRecord::Migration + def self.up + create_table :code_theme_user_settings do |t| + t.column :user_id, :integer + t.column :code_theme, :string + t.column :updated_at, :timestamp + end + end + + def self.down + drop_table :code_theme_user_settings + end +end diff --git a/init.rb b/init.rb index a4eaac5..d53427b 100644 --- a/init.rb +++ b/init.rb @@ -1,4 +1,7 @@ require 'redmine' +require 'code_theme_my_account_hooks' +require 'code_theme_user_patch' +require 'code_theme_themes_patch' require_dependency 'hooks/view_highlighted_hook' @@ -8,11 +11,19 @@ url 'https://github.com/dominch/redmine_highlightjs' author_url 'http://dominik.net.pl/' description 'Adds much better syntax highlighting with autodetection' - version '1.0.1' + version '1.0.2' settings :default => {'theme' => 'monokai_sublime'}, :partial => 'settings/highlightjs_settings' + requires_redmine :version_or_higher => '2.0.0' end ActionDispatch::Callbacks.to_prepare do require_dependency 'highlightjs_highlighting' Redmine::SyntaxHighlighting.highlighter = 'Highlightjs' end + +Rails.configuration.to_prepare do + require_dependency 'user_preference' + unless UserPreference.included_modules.include? CodeThemeUserPreferencePatch + UserPreference.send(:include, CodeThemeUserPreferencePatch) + end +end diff --git a/lib/code_theme_my_account_hooks.rb b/lib/code_theme_my_account_hooks.rb new file mode 100644 index 0000000..82514a7 --- /dev/null +++ b/lib/code_theme_my_account_hooks.rb @@ -0,0 +1,3 @@ +class CodeThemeMyAccountHooks < Redmine::Hook::ViewListener + render_on :view_my_account, :partial => 'settings/code_theme_form', :multipart => true +end diff --git a/lib/code_theme_themes_patch.rb b/lib/code_theme_themes_patch.rb new file mode 100644 index 0000000..ee7e30a --- /dev/null +++ b/lib/code_theme_themes_patch.rb @@ -0,0 +1,8 @@ +module ApplicationHelper + def get_code_theme + setting = CodeThemeUserSetting.find_code_theme_by_user_id(User.current.id) + return Setting.ui_theme unless setting + return Setting.ui_theme if setting.code_theme == CodeThemeUserSetting::DEFAULT_CODE_THEME + return setting.code_theme_name + end +end diff --git a/lib/code_theme_user_patch.rb b/lib/code_theme_user_patch.rb new file mode 100644 index 0000000..b2909a3 --- /dev/null +++ b/lib/code_theme_user_patch.rb @@ -0,0 +1,23 @@ +module CodeThemeUserPreferencePatch + def self.included(base) + base.send(:include, UserPreferenceInstanceMethodsForCodeTheme) + base.class_eval do + unloadable + end + end +end + +module UserPreferenceInstanceMethodsForCodeTheme + + def code_theme + code_theme_setting = CodeThemeUserSetting.find_code_theme_by_user_id(user.id) + return nil unless code_theme_setting + code_theme_setting.code_theme + end + + def code_theme=(name) + code_theme_setting = CodeThemeUserSetting.find_or_create_code_theme_by_user_id(user.id) + code_theme_setting.code_theme = name + code_theme_setting.save! + end +end diff --git a/lib/hooks/view_highlighted_hook.rb b/lib/hooks/view_highlighted_hook.rb index 10fbba6..2cc6ec4 100644 --- a/lib/hooks/view_highlighted_hook.rb +++ b/lib/hooks/view_highlighted_hook.rb @@ -9,7 +9,8 @@ def view_layouts_base_html_head(context={}) if SupportedBrowsers.detect { |browser| user_agent >= browser } Rails.logger.info "redmine_highlightjs2: supported browser: #{user_agent}" Redmine::SyntaxHighlighting.highlighter = 'Highlightjs' - setting = Setting.plugin_redmine_highlightjs[:theme] + setting = User.current.preference.code_theme if !Setting.plugin_redmine_highlightjs[:allow_redefine].nil? + setting = Setting.plugin_redmine_highlightjs[:theme] if setting.nil? || setting.empty? || setting == CodeThemeUserSetting::DEFAULT_CODE_THEME setting = 'monokai_sublime' if setting.nil? || setting.empty? return stylesheet_link_tag("themes/#{setting}.css", :plugin => "redmine_highlightjs", :media => "screen") + stylesheet_link_tag("fixes.css", :plugin => "redmine_highlightjs", :media => "screen") +