tuttle 0.0.6 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +17 -0
- data/Rakefile +0 -1
- data/app/controllers/tuttle/active_job_controller.rb +1 -0
- data/app/controllers/tuttle/active_model_serializers_controller.rb +1 -0
- data/app/controllers/tuttle/active_support_controller.rb +1 -0
- data/app/controllers/tuttle/application_controller.rb +19 -2
- data/app/controllers/tuttle/cancancan_controller.rb +2 -0
- data/app/controllers/tuttle/devise_controller.rb +1 -0
- data/app/controllers/tuttle/execjs_controller.rb +12 -0
- data/app/controllers/tuttle/gems_controller.rb +3 -2
- data/app/controllers/tuttle/home_controller.rb +1 -0
- data/app/controllers/tuttle/i18n_controller.rb +27 -0
- data/app/controllers/tuttle/paperclip_controller.rb +1 -0
- data/app/controllers/tuttle/rack_attack_controller.rb +26 -0
- data/app/controllers/tuttle/rack_mini_profiler_controller.rb +1 -0
- data/app/controllers/tuttle/rails_controller.rb +19 -5
- data/app/controllers/tuttle/request_controller.rb +1 -0
- data/app/controllers/tuttle/ruby_controller.rb +15 -2
- data/app/helpers/tuttle/application_helper.rb +64 -2
- data/app/models/tuttle/configuration_registry.rb +1 -0
- data/app/models/tuttle/version_detector.rb +1 -0
- data/app/views/layouts/tuttle/application.html.erb +22 -6
- data/app/views/tuttle/active_support/dependencies.html.erb +7 -7
- data/app/views/tuttle/active_support/inflectors.html.erb +1 -1
- data/app/views/tuttle/cancancan/index.html.erb +1 -1
- data/app/views/tuttle/cancancan/rule_tester.html.erb +3 -3
- data/app/views/tuttle/execjs/index.html.erb +87 -0
- data/app/views/tuttle/gems/http_clients.html.erb +13 -12
- data/app/views/tuttle/gems/index.html.erb +4 -4
- data/app/views/tuttle/gems/json.html.erb +10 -10
- data/app/views/tuttle/home/index.html.erb +6 -6
- data/app/views/tuttle/i18n/_translation_entry.html.erb +10 -0
- data/app/views/tuttle/i18n/index.html.erb +111 -0
- data/app/views/tuttle/i18n/localize.html.erb +53 -0
- data/app/views/tuttle/i18n/translations.html.erb +12 -0
- data/app/views/tuttle/rack_attack/index.html.erb +227 -0
- data/app/views/tuttle/rails/assets.html.erb +4 -4
- data/app/views/tuttle/rails/cache.html.erb +4 -8
- data/app/views/tuttle/rails/controllers.html.erb +54 -7
- data/app/views/tuttle/rails/database.html.erb +14 -1
- data/app/views/tuttle/rails/engines.html.erb +1 -1
- data/app/views/tuttle/rails/helpers.html.erb +1 -1
- data/app/views/tuttle/rails/index.html.erb +72 -19
- data/app/views/tuttle/rails/models.html.erb +150 -73
- data/app/views/tuttle/rails/routes.html.erb +10 -8
- data/app/views/tuttle/rails/schema_cache.html.erb +2 -2
- data/app/views/tuttle/ruby/constants.html.erb +29 -0
- data/app/views/tuttle/ruby/extensions.html.erb +24 -0
- data/app/views/tuttle/ruby/index.html.erb +21 -15
- data/app/views/tuttle/ruby/tuning.html.erb +6 -9
- data/config/routes.rb +15 -1
- data/lib/tuttle.rb +1 -0
- data/lib/tuttle/engine.rb +3 -4
- data/lib/tuttle/instrumenter.rb +3 -1
- data/lib/tuttle/middleware/request_profiler.rb +11 -11
- data/lib/tuttle/presenters/action_dispatch/routing/route_wrapper.rb +34 -2
- data/lib/tuttle/presenters/active_record/reflection_presenter.rb +54 -0
- data/lib/tuttle/presenters/active_support/callbacks.rb +26 -0
- data/lib/tuttle/presenters/base_presenter.rb +19 -0
- data/lib/tuttle/presenters/rack_mini_profiler/client_settings.rb +1 -0
- data/lib/tuttle/ruby_prof/fast_call_stack_printer.rb +2 -1
- data/lib/tuttle/version.rb +2 -1
- metadata +27 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9a62a3da7ea3c2565f1f91d6b9a446b95a951dbc2b3ac140102f27fc7f49c1bb
|
4
|
+
data.tar.gz: bcad3944fdbf4fc00790142e0de00318a8bbc52fae9bf3e8ad1811cfdace59e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e0f1e91acf1a8775c379136e09b84749b6e29af8a1728209236867764ed78c07c606ab059d6781137961070771b6ec343df5e8fbb6de513e8d1d9876b846961
|
7
|
+
data.tar.gz: 56aa10ea1db3241284ca712a867c8752554fcfeb34e1a23c15f664fedfed1d9e796cf2b79010a5004a31b4479a10f4109008bff9be708a4cd02d10c0b71b8ff2
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
### 0.0.8
|
2
|
+
|
3
|
+
* Features
|
4
|
+
* New ExecJS inspector
|
5
|
+
* New Rack::Attack inspector
|
6
|
+
* Improved ActiveRecord models inspector with associations and validations
|
7
|
+
* Improved Rails Controllers link to matched routes (excluding wildcards and implicit renders)
|
8
|
+
|
9
|
+
### 0.0.7
|
10
|
+
|
11
|
+
* Features
|
12
|
+
* Rails 5.1 support (drops Rails 4.0)
|
13
|
+
* New I18n inspector
|
14
|
+
* New Constants and Object extensions inspector
|
15
|
+
* Improved Rails routes inspector to show route validity
|
16
|
+
* Improved listing display formatting
|
17
|
+
|
1
18
|
### 0.0.6
|
2
19
|
|
3
20
|
* Features
|
data/Rakefile
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Tuttle
|
2
3
|
class ApplicationController < ActionController::Base
|
3
4
|
abstract!
|
4
5
|
protect_from_forgery with: :exception
|
5
6
|
|
6
7
|
before_action :check_reload_status
|
8
|
+
around_action :set_locale
|
7
9
|
|
8
10
|
private
|
9
11
|
|
@@ -11,8 +13,23 @@ module Tuttle
|
|
11
13
|
return unless Tuttle::Engine.reload_needed && !Rails.configuration.eager_load
|
12
14
|
Tuttle::Engine.logger.warn('Eager-loading application')
|
13
15
|
ActiveSupport::Notifications.instrument 'tuttle.perform_eager_load' do
|
14
|
-
|
15
|
-
|
16
|
+
begin
|
17
|
+
Rails.application.eager_load!
|
18
|
+
rescue
|
19
|
+
Tuttle::Engine.logger.warn('Failed to eager-load application')
|
20
|
+
ensure
|
21
|
+
Tuttle::Engine.reload_needed = false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_locale
|
27
|
+
if params[:hl] && I18n.locale_available?(params[:hl])
|
28
|
+
I18n.with_locale(params[:hl]) do
|
29
|
+
yield
|
30
|
+
end
|
31
|
+
else
|
32
|
+
yield
|
16
33
|
end
|
17
34
|
end
|
18
35
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require_dependency 'tuttle/application_controller'
|
2
3
|
|
3
4
|
module Tuttle
|
@@ -6,6 +7,7 @@ module Tuttle
|
|
6
7
|
def index
|
7
8
|
@cancan_user = current_user || User.new
|
8
9
|
@ability = Ability.new(@cancan_user)
|
10
|
+
@rules = @ability.instance_variable_get('@rules')
|
9
11
|
end
|
10
12
|
|
11
13
|
def rule_tester
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require_dependency 'tuttle/application_controller'
|
2
3
|
|
3
4
|
module Tuttle
|
4
5
|
class GemsController < ApplicationController
|
5
6
|
|
6
7
|
def index
|
8
|
+
@gemspecs = Bundler.rubygems.all_specs.sort_by(&:name)
|
7
9
|
end
|
8
10
|
|
9
11
|
def http_clients
|
@@ -12,8 +14,7 @@ module Tuttle
|
|
12
14
|
def json
|
13
15
|
end
|
14
16
|
|
15
|
-
# rubocop:disable
|
16
|
-
def get_process_mem
|
17
|
+
def get_process_mem # rubocop:disable Naming/AccessorMethodName
|
17
18
|
require 'get_process_mem'
|
18
19
|
require 'get_process_mem/version'
|
19
20
|
@memory_self = GetProcessMem.new
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_dependency 'tuttle/application_controller'
|
3
|
+
|
4
|
+
module Tuttle
|
5
|
+
class I18nController < ApplicationController
|
6
|
+
|
7
|
+
before_action :set_sorted_locales
|
8
|
+
|
9
|
+
def index
|
10
|
+
end
|
11
|
+
|
12
|
+
def localize
|
13
|
+
end
|
14
|
+
|
15
|
+
def translations
|
16
|
+
@translations = I18n.backend.send(:translations)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def set_sorted_locales
|
22
|
+
@sorted_locales = [I18n.default_locale] +
|
23
|
+
(I18n.available_locales.map(&:to_s).sort.map(&:to_sym) - [I18n.default_locale])
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_dependency 'tuttle/application_controller'
|
3
|
+
|
4
|
+
module Tuttle
|
5
|
+
class RackAttackController < ApplicationController
|
6
|
+
|
7
|
+
def index
|
8
|
+
require 'rack/attack/version'
|
9
|
+
if ::Rack::Attack::VERSION < '5'
|
10
|
+
render plain: 'Tuttle Rack::Attack support requires version 5.x' && return
|
11
|
+
end
|
12
|
+
|
13
|
+
default_keys = %w[rack.attack.matched rack.attack.match_discriminator rack.attack.match_type rack.attack.match_data]
|
14
|
+
rack_attack_env_vars = request.env.select { |k, _v| k.to_s.start_with?('rack.attack') }
|
15
|
+
@rack_attack_env_settings = (rack_attack_env_vars.keys + default_keys).uniq
|
16
|
+
|
17
|
+
@throttles = Rack::Attack.throttles
|
18
|
+
@safelists = Rack::Attack.safelists
|
19
|
+
@blocklists = Rack::Attack.blocklists
|
20
|
+
@tracks = Rack::Attack.tracks
|
21
|
+
|
22
|
+
@asn_listeners = ActiveSupport::Notifications.notifier.listeners_for("rack.attack")
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'rails/generators'
|
2
3
|
require_dependency 'tuttle/application_controller'
|
3
4
|
require_dependency 'tuttle/presenters/action_dispatch/routing/route_wrapper'
|
5
|
+
require_dependency 'tuttle/presenters/active_support/callbacks'
|
6
|
+
require_dependency 'tuttle/presenters/active_record/reflection_presenter'
|
4
7
|
|
5
8
|
module Tuttle
|
6
9
|
class RailsController < ApplicationController
|
@@ -10,12 +13,23 @@ module Tuttle
|
|
10
13
|
end
|
11
14
|
|
12
15
|
def controllers
|
13
|
-
|
16
|
+
@routes = Rails.application.routes.routes.collect do |route|
|
17
|
+
Tuttle::Presenters::ActionDispatch::Routing::RouteWrapper.new(route)
|
18
|
+
end
|
19
|
+
|
14
20
|
# It seems likely that .descendants will work best when Tuttle and Rails classes are not modified
|
15
21
|
# but both approaches also require eager_load to be true
|
16
22
|
# @controllers = ObjectSpace.each_object(::Class).select {|klass| klass < ActionController::Base }
|
17
23
|
@controllers = ActionController::Base.descendants
|
18
|
-
@controllers.reject!
|
24
|
+
@controllers.reject! do |controller|
|
25
|
+
controller.abstract? || controller <= Tuttle::ApplicationController
|
26
|
+
end
|
27
|
+
|
28
|
+
# Rails 5.1 introduced Rails::ApplicationController which really should be abstract
|
29
|
+
if defined?(Rails::ApplicationController)
|
30
|
+
@controllers.reject! { |controller| controller == Rails::ApplicationController }
|
31
|
+
end
|
32
|
+
|
19
33
|
@controllers.sort_by!(&:name)
|
20
34
|
end
|
21
35
|
|
@@ -24,12 +38,12 @@ module Tuttle
|
|
24
38
|
end
|
25
39
|
|
26
40
|
def generators
|
27
|
-
Rails::Generators.lookup! if
|
41
|
+
Rails::Generators.lookup! if params[:load_all_generators] == 'true'
|
28
42
|
@generators = Rails::Generators.subclasses.group_by(&:base_name)
|
29
43
|
end
|
30
44
|
|
31
45
|
def models
|
32
|
-
@models = ActiveRecord::Base.descendants
|
46
|
+
@models = ActiveRecord::Base.descendants.reject { |model| model.abstract_class? || !model.table_exists? }
|
33
47
|
@models.sort_by!(&:name)
|
34
48
|
end
|
35
49
|
|
@@ -101,7 +115,7 @@ module Tuttle
|
|
101
115
|
|
102
116
|
def recognize_paths(path)
|
103
117
|
results = {}
|
104
|
-
[
|
118
|
+
%i[get post put delete patch].each {|method| results[method] = recognize_path(path, method: method)}
|
105
119
|
results
|
106
120
|
end
|
107
121
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_dependency 'tuttle/application_controller'
|
4
4
|
|
@@ -18,7 +18,6 @@ module Tuttle
|
|
18
18
|
@gc_enabled = (GC.disable ? false : GC.enable)
|
19
19
|
|
20
20
|
# taken verbatim from the ruby 2.2 man page
|
21
|
-
# rubocop:disable Metrics/LineLength
|
22
21
|
@gc_params = {
|
23
22
|
'RUBY_GC_HEAP_INIT_SLOTS' => 'Initial allocation slots. Introduced in Ruby 2.1, default: 10000.',
|
24
23
|
'RUBY_GC_HEAP_FREE_SLOTS' => 'Prepare at least this amount of slots after GC. Allocate this number slots if there are not enough slots. Introduced in Ruby 2.1, default: 4096',
|
@@ -37,5 +36,19 @@ module Tuttle
|
|
37
36
|
def miscellaneous
|
38
37
|
end
|
39
38
|
|
39
|
+
def constants
|
40
|
+
# Global constants minus a few deprecated constants (to prevent warnings)
|
41
|
+
@constants = (Object.constants - %i[Bignum Fixnum NIL TRUE FALSE TimeoutError Data]).
|
42
|
+
sort.
|
43
|
+
map { |sym| [sym, Object.const_get(sym).class, Object.const_get(sym)] }.
|
44
|
+
reject { |_sym, klass, _val| klass == Class || klass == Module }
|
45
|
+
end
|
46
|
+
|
47
|
+
def extensions
|
48
|
+
@obj_extensions = Object.methods.select { |meth| Object.method(meth).source_location }.
|
49
|
+
sort.
|
50
|
+
map { |meth| [meth, *Object.method(meth).source_location] }
|
51
|
+
end
|
52
|
+
|
40
53
|
end
|
41
54
|
end
|
@@ -1,12 +1,19 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
3
2
|
module Tuttle
|
4
3
|
module ApplicationHelper
|
4
|
+
BUNDLER_GEM_PATHS_REGEX = %r{(#{Bundler.rubygems.gem_dir}|#{File.realpath(Bundler.rubygems.gem_dir)})+(/bundler)*/gems}
|
5
|
+
|
6
|
+
# Display true/false label with text overrides
|
5
7
|
def truth_label(is_true, true_label = 'true', false_label = 'false')
|
6
8
|
content_tag(:span, is_true ? true_label : false_label,
|
7
9
|
class: ['label', is_true ? 'label-success' : 'label-danger'])
|
8
10
|
end
|
9
11
|
|
12
|
+
# Display label if condition is true
|
13
|
+
def true_label(is_true, true_label = 'true')
|
14
|
+
content_tag(:span, true_label, class: %w[label label-success]) if is_true
|
15
|
+
end
|
16
|
+
|
10
17
|
def tuttle_redacted(enumarator)
|
11
18
|
enumarator.collect do |key, value|
|
12
19
|
yield key, redact_by_key(key, value)
|
@@ -21,10 +28,65 @@ module Tuttle
|
|
21
28
|
main_app.respond_to?(:root_url) ? main_app.root_url : '/'
|
22
29
|
end
|
23
30
|
|
31
|
+
def link_to_rails_guide(file, title)
|
32
|
+
content_tag(:a, title, :href => rails_guides_versioned_url(file + '.html'))
|
33
|
+
end
|
34
|
+
|
24
35
|
def rails_guides_versioned_url(path)
|
25
36
|
"http://guides.rubyonrails.org/v#{Tuttle::VersionDetector.rails_major_minor}/#{path}"
|
26
37
|
end
|
27
38
|
|
39
|
+
def display_path(path)
|
40
|
+
return if path.blank?
|
41
|
+
display_location =
|
42
|
+
if path.start_with?(Rails.root.to_s)
|
43
|
+
path.sub(Rails.root.to_s, "$RAILS_ROOT")
|
44
|
+
elsif File.realpath(path).start_with?(File.realpath(Bundler.rubygems.gem_dir))
|
45
|
+
File.realpath(path).sub(BUNDLER_GEM_PATHS_REGEX, "$GEMS")
|
46
|
+
else
|
47
|
+
path
|
48
|
+
end
|
49
|
+
expanded_path = File.expand_path(path)
|
50
|
+
content_tag(:span, display_location, :class => 'tuttle-path', :data => { :initial => path, :expanded => expanded_path })
|
51
|
+
end
|
52
|
+
|
53
|
+
def display_source_locaction(path, line)
|
54
|
+
return content_tag(:span, "Unknown", :class => 'tuttle-path') if path.nil?
|
55
|
+
|
56
|
+
display_location = file_location(path)
|
57
|
+
expanded_path = File.expand_path(path)
|
58
|
+
content_tag(:span, :class => 'tuttle-path', :data => { :initial => path, :expanded => expanded_path }) do
|
59
|
+
"#{display_location}##{line}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def file_location(path)
|
64
|
+
if path.start_with?(Rails.root.to_s)
|
65
|
+
path.gsub(Rails.root.to_s, "$RAILS_ROOT")
|
66
|
+
elsif path.start_with?(RbConfig::CONFIG['rubylibdir'])
|
67
|
+
path.gsub(RbConfig::CONFIG['rubylibdir'], "$RUBY_LIB_DIR")
|
68
|
+
elsif path == "<internal:prelude>"
|
69
|
+
path
|
70
|
+
elsif File.realpath(path).start_with?(File.realpath(Bundler.rubygems.gem_dir))
|
71
|
+
File.realpath(path).gsub(BUNDLER_GEM_PATHS_REGEX, "$GEMS")
|
72
|
+
else
|
73
|
+
path
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def value_inspect(val, hide_nil: false)
|
78
|
+
case val
|
79
|
+
when NilClass
|
80
|
+
content_tag(:code, val.inspect) unless hide_nil
|
81
|
+
when String
|
82
|
+
content_tag(:code, val.inspect)
|
83
|
+
when Symbol
|
84
|
+
content_tag(:code, val.inspect)
|
85
|
+
else
|
86
|
+
val.inspect
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
28
90
|
private
|
29
91
|
|
30
92
|
def redact_by_key(key, value)
|
@@ -2,28 +2,30 @@
|
|
2
2
|
<html lang="en">
|
3
3
|
<head>
|
4
4
|
<meta charset="utf-8">
|
5
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
6
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
7
6
|
<title>Tuttle</title>
|
8
7
|
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
9
8
|
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
|
10
|
-
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.
|
11
|
-
|
9
|
+
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
|
10
|
+
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" integrity="sha256-3YM6A3pH4QFCl9WbSU8oXF5N6W/2ylvW0o2g+Z6TmLQ=" crossorigin="anonymous" />
|
12
11
|
<%= content_for(:stylesheets) -%>
|
13
12
|
<link rel="icon" href="//s3.amazonaws.com/tuttle-assets/images/favicon.ico">
|
14
13
|
<style>
|
15
14
|
html { overflow: -moz-scrollbars-vertical; overflow-y: scroll; }
|
16
15
|
body { padding-top: 50px; }
|
17
16
|
table.not-wide { width: auto; }
|
18
|
-
|
17
|
+
table code { color: black; background-color: inherit; padding: 0; }
|
18
|
+
table.table-condensed tbody tr td:first-child { padding-left: 0; }
|
19
|
+
table .nowrap { white-space: nowrap; }
|
19
20
|
a[href*="github.com"] { white-space: nowrap; }
|
20
21
|
a[href*="github.com"]:after { font-family: FontAwesome; content: "\f09b"; display: inline-block; color: initial; padding-left: 3px; }
|
22
|
+
details :focus { outline: none; }
|
21
23
|
</style>
|
22
24
|
<%= csrf_meta_tags %>
|
23
25
|
</head>
|
24
26
|
<body>
|
25
27
|
|
26
|
-
<nav class="navbar
|
28
|
+
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
27
29
|
<div class="container">
|
28
30
|
<div class="navbar-header">
|
29
31
|
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
|
@@ -50,6 +52,12 @@
|
|
50
52
|
<li><%= link_to 'Asset Pipeline', rails_assets_path %></li>
|
51
53
|
<li><%= link_to 'Caching', rails_cache_path %></li>
|
52
54
|
<li role="separator" class="divider"></li>
|
55
|
+
<%- if defined?(::I18n) %>
|
56
|
+
<li><%= link_to 'Internationalization', i18n_path %></li>
|
57
|
+
<li><%= link_to 'Localization', i18n_localize_path %></li>
|
58
|
+
<li><%= link_to 'Translations', i18n_translations_path %></li>
|
59
|
+
<li role="separator" class="divider"></li>
|
60
|
+
<% end %>
|
53
61
|
<li><%= link_to 'Database', rails_database_path %></li>
|
54
62
|
<li><%= link_to 'Schema Cache', rails_schema_cache_path %></li>
|
55
63
|
<li role="separator" class="divider"></li>
|
@@ -88,6 +96,12 @@
|
|
88
96
|
<%- if defined?(::GetProcessMem) %>
|
89
97
|
<li><%= link_to 'GetProcessMem', gems_get_process_mem_path %></li>
|
90
98
|
<%- end %>
|
99
|
+
<%- if defined?(::ExecJS) %>
|
100
|
+
<li><%= link_to 'ExecJS', execjs_path %></li>
|
101
|
+
<%- end %>
|
102
|
+
<%- if defined?(::Rack::Attack) %>
|
103
|
+
<li><%= link_to 'Rack::Attack', rack_attack_path %></li>
|
104
|
+
<%- end %>
|
91
105
|
<li><%= link_to 'HTTP Clients', gems_http_clients_path %></li>
|
92
106
|
<li><%= link_to 'JSON', gems_json_path %></li>
|
93
107
|
<li><%= link_to 'Other', gems_other_path %></li>
|
@@ -99,6 +113,8 @@
|
|
99
113
|
<li><%= link_to 'Overview', ruby_path %></li>
|
100
114
|
<li class="divider"></li>
|
101
115
|
<li><%= link_to 'Tuning', ruby_tuning_path %></li>
|
116
|
+
<li><%= link_to 'Extensions', ruby_extensions_path %></li>
|
117
|
+
<li><%= link_to 'Constants', ruby_constants_path %></li>
|
102
118
|
<li><%= link_to 'Miscellaneous', ruby_miscellaneous_path %></li>
|
103
119
|
</ul>
|
104
120
|
</li>
|
@@ -115,7 +131,7 @@
|
|
115
131
|
|
116
132
|
<script src="//code.jquery.com/jquery-2.2.4.min.js" integrity="sha384-rY/jv8mMhqDabXSo+UCggqKtdmBfd3qC2/KvyTDNQ6PcUJXaxK1tMepoQda4g5vB" crossorigin="anonymous"></script>
|
117
133
|
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
118
|
-
|
134
|
+
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js" integrity="sha256-/BfiIkHlHoVihZdc6TFuj7MmJ0TWcWsMXkeDFwhi0zw=" crossorigin="anonymous"></script>
|
119
135
|
<%= content_for(:javascripts) -%>
|
120
136
|
<script>hljs.initHighlightingOnLoad();</script>
|
121
137
|
</body>
|