web-console 2.1.3 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +45 -0
- data/README.markdown +26 -6
- data/Rakefile +37 -0
- data/lib/web_console/extensions.rb +2 -1
- data/lib/web_console/integration/cruby.rb +2 -1
- data/lib/web_console/integration/rubinius.rb +2 -1
- data/lib/web_console/railtie.rb +19 -1
- data/lib/web_console/session.rb +4 -3
- data/lib/web_console/templates/_inner_console_markup.html.erb +8 -3
- data/lib/web_console/templates/console.js.erb +169 -46
- data/lib/web_console/templates/error_page.js.erb +2 -15
- data/lib/web_console/templates/main.js.erb +1 -24
- data/lib/web_console/templates/style.css.erb +22 -9
- data/lib/web_console/tracer.rb +11 -0
- data/lib/web_console/version.rb +1 -1
- metadata +5 -155
- data/test/dummy/README.rdoc +0 -28
- data/test/dummy/Rakefile +0 -6
- data/test/dummy/app/assets/javascripts/application.js +0 -13
- data/test/dummy/app/assets/stylesheets/application.css +0 -13
- data/test/dummy/app/controllers/application_controller.rb +0 -5
- data/test/dummy/app/controllers/controller_helper_test_controller.rb +0 -7
- data/test/dummy/app/controllers/exception_test_controller.rb +0 -15
- data/test/dummy/app/controllers/helper_error_controller.rb +0 -4
- data/test/dummy/app/controllers/helper_test_controller.rb +0 -5
- data/test/dummy/app/controllers/tests_controller.rb +0 -16
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/views/controller_helper_test/index.html.erb +0 -1
- data/test/dummy/app/views/exception_test/xhr.html.erb +0 -1
- data/test/dummy/app/views/helper_error/index.html.erb +0 -2
- data/test/dummy/app/views/helper_test/index.html.erb +0 -220
- data/test/dummy/app/views/layouts/application.html.erb +0 -16
- data/test/dummy/bin/bundle +0 -3
- data/test/dummy/bin/rails +0 -4
- data/test/dummy/bin/rake +0 -4
- data/test/dummy/config.ru +0 -4
- data/test/dummy/config/application.rb +0 -19
- data/test/dummy/config/boot.rb +0 -5
- data/test/dummy/config/database.yml +0 -25
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -29
- data/test/dummy/config/environments/production.rb +0 -80
- data/test/dummy/config/environments/test.rb +0 -34
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
- data/test/dummy/config/initializers/inflections.rb +0 -16
- data/test/dummy/config/initializers/mime_types.rb +0 -5
- data/test/dummy/config/initializers/secret_token.rb +0 -12
- data/test/dummy/config/initializers/session_store.rb +0 -3
- data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy/config/locales/en.yml +0 -23
- data/test/dummy/config/routes.rb +0 -15
- data/test/dummy/db/schema.rb +0 -16
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +0 -808
- data/test/dummy/public/404.html +0 -58
- data/test/dummy/public/422.html +0 -58
- data/test/dummy/public/500.html +0 -57
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/0c9b99b1b975b36a5b686845ae729db3 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/12e9f58adcf819cf65fd68b6859a438f +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/1fd6abead3df36a4e4a2cb042a551b39 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/33b5eb81b5aaaa1e6dd5dcb6517792b4 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/3e460b2e021085f88b5597b38d194932 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/52f04b2ea6e461f4661b6d0be393fa94 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/688c344c2919f882338f06c5daaea209 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/7f079298e19bbef40a5d6a37dc03033a +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/91aa709f89e465f58056fabe5f75eef4 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/95f4e4e5217aec9f71b2c1a65a9a9231 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/9c41be9b6625756fbb6d05b7665dd911 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/a95f64d41fcf8244b8f5b84a55f07822 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/c5e6bf1efd5929bee63e28ad7c9f6f83 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/d863259e9eeca657a1624135cfe24446 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/e1d2fc4601b6423ec8a42415ee05dd14 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/e82616536a759c2e87d703adc77d65da +0 -0
- data/test/support/scenarios/bad_custom_error_scenario.rb +0 -17
- data/test/support/scenarios/basic_nested_scenario.rb +0 -15
- data/test/support/scenarios/custom_error_scenario.rb +0 -11
- data/test/support/scenarios/eval_nested_scenario.rb +0 -15
- data/test/support/scenarios/flat_scenario.rb +0 -9
- data/test/support/scenarios/reraised_scenario.rb +0 -21
- data/test/test_helper.rb +0 -78
- data/test/web_console/evaluator_test.rb +0 -73
- data/test/web_console/extensions_test.rb +0 -28
- data/test/web_console/helper_test.rb +0 -76
- data/test/web_console/integration_test.rb +0 -47
- data/test/web_console/middleware_test.rb +0 -116
- data/test/web_console/railtie_test.rb +0 -99
- data/test/web_console/request_test.rb +0 -82
- data/test/web_console/session_test.rb +0 -59
- data/test/web_console/whiny_request_test.rb +0 -33
- data/test/web_console/whitelist_test.rb +0 -43
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bde2832a1ef7a0ace010d61011afb4c74a116a93
|
|
4
|
+
data.tar.gz: c0e5de96dab453f1a3e233d969bf5ada72ba848a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eb74d0994835ccc223df24cb3a5ee1e034ca2456580f99962724864994438f04a14c67aa05f9425263f1c36773623969abdc7bca5a2b255535e90449b6394ac3
|
|
7
|
+
data.tar.gz: 31f90bb5c32ed53a95f43cb1a0f25cf89765847c92010255a9df5c0235423203711be37e09eda9af4f435616772d247502b682a2ef367f5409cbbbcc23cca963
|
data/CHANGELOG.markdown
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# CHANGELOG
|
|
2
|
+
|
|
3
|
+
## master (unreleased)
|
|
4
|
+
|
|
5
|
+
## 2.2.0
|
|
6
|
+
|
|
7
|
+
* [#140](https://github.com/rails/web-console/pull/140) Add the ability to close the console on each page ([@sh19910711])
|
|
8
|
+
* [#135](https://github.com/rails/web-console/pull/135) Run the console only in development mode and raise warning in tests ([@frenesim])
|
|
9
|
+
|
|
10
|
+
## 2.1.3
|
|
11
|
+
|
|
12
|
+
* Fix remote code execution vulnerability in Web Console. CVE-2015-3224.
|
|
13
|
+
* [#123](https://github.com/rails/web-console/pull/123) Replace deprecated `alias_method_chain` with `alias_method` ([@jonatack])
|
|
14
|
+
|
|
15
|
+
## 2.1.2
|
|
16
|
+
|
|
17
|
+
* [#115](https://github.com/rails/web-console/pull/115) Show proper binding when raising an error in a template ([@gsamokovarov])
|
|
18
|
+
* [#114](https://github.com/rails/web-console/pull/114) Fix templates non rendering, because of missing template suffix ([@gsamokovarov])
|
|
19
|
+
|
|
20
|
+
## 2.1.1
|
|
21
|
+
|
|
22
|
+
* [#112](https://github.com/rails/web-console/pull/112) Always allow application/x-www-form-urlencoded content type ([@gsamokovarov])
|
|
23
|
+
|
|
24
|
+
## 2.1.0
|
|
25
|
+
|
|
26
|
+
* [#109](https://github.com/rails/web-console/pull/109) Revamp unavailable session response message ([@gsamokovarov])
|
|
27
|
+
* [#107](https://github.com/rails/web-console/pull/107) Fix pasting regression for all browsers ([@parterburn])
|
|
28
|
+
* [#105](https://github.com/rails/web-console/pull/105) Lock scroll bottom on console window resize ([@noahpatterson])
|
|
29
|
+
* [#104](https://github.com/rails/web-console/pull/104) Always whitelist localhost and inform users why no console is displayed ([@gsamokovarov])
|
|
30
|
+
* [#100](https://github.com/rails/web-console/pull/100) Accept text/plain as acceptable content type for Puma ([@gsamokovarov])
|
|
31
|
+
* [#98](https://github.com/rails/web-console/pull/98) Add arbitrary big z-index to the console ([@bglbruno])
|
|
32
|
+
* [#88](https://github.com/rails/web-console/pull/88) Spelling fixes ([@jeffnv])
|
|
33
|
+
* [#86](https://github.com/rails/web-console/pull/86) Disable autofocus when initializing the console ([@ryandao])
|
|
34
|
+
* [#84](https://github.com/rails/web-console/pull/84) Allow Rails 5 as dependency in gemspec ([@jonatack])
|
|
35
|
+
* [#69](https://github.com/rails/web-console/pull/69) Introduce middleware for request dispatch and console rendering ([@gsamokovarov])
|
|
36
|
+
|
|
37
|
+
[@jonatack]: https://github.com/jonatack
|
|
38
|
+
[@ryandao]: https://github.com/ryandao
|
|
39
|
+
[@jeffnv]: https://github.com/jeffnv
|
|
40
|
+
[@gsamokovarov]: https://github.com/gsamokovarov
|
|
41
|
+
[@bglbruno]: https://github.com/bglbruno
|
|
42
|
+
[@noahpatterson]: https://github.com/noahpatterson
|
|
43
|
+
[@parterburn]: https://github.com/parterburn
|
|
44
|
+
[@sh19910711]: https://github.com/sh19910711
|
|
45
|
+
[@frenesim]: https://github.com/frenesim
|
data/README.markdown
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
<p align=right>
|
|
2
2
|
Documentation for:
|
|
3
3
|
<a href=https://github.com/rails/web-console/tree/v2.0.0>v2.0.0</a>
|
|
4
|
+
<a href=https://github.com/rails/web-console/tree/v2.1.0>v2.1.0</a>
|
|
5
|
+
<a href=https://github.com/rails/web-console/tree/v2.1.1>v2.1.1</a>
|
|
6
|
+
<a href=https://github.com/rails/web-console/tree/v2.1.2>v2.1.2</a>
|
|
7
|
+
<a href=https://github.com/rails/web-console/tree/v2.1.3>v2.1.3</a>
|
|
4
8
|
</p>
|
|
5
9
|
|
|
6
10
|
# Web Console [](https://travis-ci.org/rails/web-console)
|
|
@@ -119,7 +123,7 @@ end
|
|
|
119
123
|
If you want to whitelist the whole private network, you can do:
|
|
120
124
|
|
|
121
125
|
```ruby
|
|
122
|
-
|
|
126
|
+
Rails.application.configure do
|
|
123
127
|
config.web_console.whitelisted_ips = '192.168.0.0/16'
|
|
124
128
|
end
|
|
125
129
|
```
|
|
@@ -138,19 +142,19 @@ messages like the following is printed in the server logs:
|
|
|
138
142
|
If you don't wanna see this message anymore, set this option to `false`:
|
|
139
143
|
|
|
140
144
|
```ruby
|
|
141
|
-
|
|
145
|
+
Rails.application.configure do
|
|
142
146
|
config.web_console.whiny_requests = false
|
|
143
147
|
end
|
|
144
148
|
```
|
|
145
149
|
|
|
146
|
-
### config.web_console.
|
|
150
|
+
### config.web_console.template_paths
|
|
147
151
|
|
|
148
152
|
If you wanna style the console yourself, you can place `style.css` at a
|
|
149
|
-
directory pointed by `config.web_console.
|
|
153
|
+
directory pointed by `config.web_console.template_paths`:
|
|
150
154
|
|
|
151
155
|
```ruby
|
|
152
|
-
|
|
153
|
-
config.web_console.
|
|
156
|
+
Rails.application.configure do
|
|
157
|
+
config.web_console.template_paths = 'app/views/web_console'
|
|
154
158
|
end
|
|
155
159
|
```
|
|
156
160
|
|
|
@@ -181,6 +185,22 @@ server requests only out of one process.
|
|
|
181
185
|
The interactive console executes Ruby code. Invoking `instance_variables` and
|
|
182
186
|
`local_variables` will give you what you want.
|
|
183
187
|
|
|
188
|
+
### Why does console only appear on error pages but not when I call it?
|
|
189
|
+
|
|
190
|
+
This can be happening if you are using `Rack::Deflater`. Be sure that
|
|
191
|
+
`WebConsole::Middleware` is used after `Rack::Deflater`. The easiest way to do
|
|
192
|
+
this is to insert `Rack::Deflater` as early as possible
|
|
193
|
+
|
|
194
|
+
```ruby
|
|
195
|
+
Rails.application.configure do
|
|
196
|
+
config.middleware.insert(0, Rack::Deflater)
|
|
197
|
+
end
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Why I'm getting an undefined method `web_console`?
|
|
201
|
+
|
|
202
|
+
Make sure you configuration lives in `config/environments/development.rb`.
|
|
203
|
+
|
|
184
204
|
## Credits
|
|
185
205
|
|
|
186
206
|
* Shoutout to [Charlie Somerville] for [better_errors] and [this] code.
|
data/Rakefile
CHANGED
|
@@ -6,6 +6,8 @@ end
|
|
|
6
6
|
|
|
7
7
|
require 'socket'
|
|
8
8
|
require 'rake/testtask'
|
|
9
|
+
require 'tmpdir'
|
|
10
|
+
require 'securerandom'
|
|
9
11
|
|
|
10
12
|
EXPANDED_CWD = File.expand_path(File.dirname(__FILE__))
|
|
11
13
|
|
|
@@ -16,6 +18,41 @@ Rake::TestTask.new(:test) do |t|
|
|
|
16
18
|
t.verbose = false
|
|
17
19
|
end
|
|
18
20
|
|
|
21
|
+
namespace :test do
|
|
22
|
+
desc "Run tests for templates"
|
|
23
|
+
task :templates => "templates:all"
|
|
24
|
+
|
|
25
|
+
namespace :templates do
|
|
26
|
+
task :all => [:daemonize, :npm, :rackup, :mocha, :kill]
|
|
27
|
+
task :serve => [:npm, :rackup]
|
|
28
|
+
|
|
29
|
+
work_dir = Pathname(__FILE__).dirname.join("test/templates")
|
|
30
|
+
pid_file = Pathname(Dir.tmpdir).join("web_console.#{SecureRandom.uuid}.pid")
|
|
31
|
+
server_port = 29292
|
|
32
|
+
rackup_opts = "-p #{server_port}"
|
|
33
|
+
|
|
34
|
+
task :daemonize do
|
|
35
|
+
rackup_opts += " -D -P #{pid_file}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
task :npm do
|
|
39
|
+
Dir.chdir(work_dir) { system "npm install --silent" }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
task :rackup do
|
|
43
|
+
Dir.chdir(work_dir) { system "bundle exec rackup #{rackup_opts}" }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
task :mocha do
|
|
47
|
+
Dir.chdir(work_dir) { system "$(npm bin)/mocha-phantomjs http://localhost:#{server_port}/html/spec_runner.html" }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
task :kill do
|
|
51
|
+
system "kill #{File.read pid_file}"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
19
56
|
Bundler::GemHelper.install_tasks
|
|
20
57
|
|
|
21
58
|
task default: :test
|
|
@@ -15,5 +15,6 @@ ActionDispatch::DebugExceptions.class_eval do
|
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
alias_method :render_exception_without_web_console, :render_exception
|
|
19
|
+
alias_method :render_exception, :render_exception_with_web_console
|
|
19
20
|
end
|
|
@@ -34,6 +34,7 @@ class Exception
|
|
|
34
34
|
set_backtrace_without_binding_of_caller(*args)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
alias_method :set_backtrace_without_binding_of_caller, :set_backtrace
|
|
38
|
+
alias_method :set_backtrace, :set_backtrace_with_binding_of_caller
|
|
38
39
|
end
|
|
39
40
|
end
|
|
@@ -62,5 +62,6 @@ end
|
|
|
62
62
|
raise_exception_without_current_bindings(exc)
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
alias_method :raise_exception_without_current_bindings, :raise_exception
|
|
66
|
+
alias_method :raise_exception, :raise_exception_with_current_bindings
|
|
66
67
|
end
|
data/lib/web_console/railtie.rb
CHANGED
|
@@ -17,11 +17,29 @@ module WebConsole
|
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
initializer 'web_console.development_only' do
|
|
21
|
+
unless (config.web_console.development_only == false) || Rails.env.development?
|
|
22
|
+
abort <<-END.strip_heredoc
|
|
23
|
+
Web Console is activated in the #{Rails.env} environment, which is
|
|
24
|
+
usually a mistake. To ensure it's only activated in development
|
|
25
|
+
mode, move it to the development group of your Gemfile:
|
|
26
|
+
|
|
27
|
+
gem 'web-console', group: :development
|
|
28
|
+
|
|
29
|
+
If you still want to run it the #{Rails.env} environment (and know
|
|
30
|
+
what you are doing), put this in your Rails application
|
|
31
|
+
configuration:
|
|
32
|
+
|
|
33
|
+
config.web_console.development_only = false
|
|
34
|
+
END
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
20
38
|
initializer 'web_console.insert_middleware' do |app|
|
|
21
39
|
app.middleware.insert_before ActionDispatch::DebugExceptions, Middleware
|
|
22
40
|
end
|
|
23
41
|
|
|
24
|
-
initializer 'web_console.
|
|
42
|
+
initializer 'web_console.template_paths' do
|
|
25
43
|
if template_paths = config.web_console.template_paths
|
|
26
44
|
Template.template_paths.unshift(*Array(template_paths))
|
|
27
45
|
end
|
data/lib/web_console/session.rb
CHANGED
|
@@ -9,7 +9,8 @@ module WebConsole
|
|
|
9
9
|
# error pages only, as currently, this is the only client that needs to do
|
|
10
10
|
# that.
|
|
11
11
|
class Session
|
|
12
|
-
|
|
12
|
+
cattr_reader :inmemory_storage
|
|
13
|
+
@@inmemory_storage = {}
|
|
13
14
|
|
|
14
15
|
class << self
|
|
15
16
|
# Finds a persisted session in memory by its id.
|
|
@@ -17,7 +18,7 @@ module WebConsole
|
|
|
17
18
|
# Returns a persisted session if found in memory.
|
|
18
19
|
# Raises NotFound error unless found in memory.
|
|
19
20
|
def find(id)
|
|
20
|
-
|
|
21
|
+
inmemory_storage[id]
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
# Create a Session from an exception.
|
|
@@ -59,7 +60,7 @@ module WebConsole
|
|
|
59
60
|
private
|
|
60
61
|
|
|
61
62
|
def store_into_memory
|
|
62
|
-
|
|
63
|
+
inmemory_storage[id] = self
|
|
63
64
|
end
|
|
64
65
|
end
|
|
65
66
|
end
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
<div
|
|
2
|
-
<div class='console-
|
|
3
|
-
<
|
|
1
|
+
<div class='resizer layer'></div>
|
|
2
|
+
<div class='console-outer layer'>
|
|
3
|
+
<div class='console-actions'>
|
|
4
|
+
<div class='close-button button' title='close'>x</div>
|
|
5
|
+
</div>
|
|
6
|
+
<div class='console-inner'></div>
|
|
7
|
+
</div>
|
|
8
|
+
<input class='clipboard' type='text'>
|
|
@@ -1,40 +1,3 @@
|
|
|
1
|
-
// DOM helpers
|
|
2
|
-
function hasClass(el, className) {
|
|
3
|
-
var regex = new RegExp('(?:^|\\s)' + className + '(?!\\S)', 'g');
|
|
4
|
-
return el.className.match(regex);
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
function addClass(el, className) {
|
|
8
|
-
el.className += " " + className;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function removeClass(el, className) {
|
|
12
|
-
var regex = new RegExp('(?:^|\\s)' + className + '(?!\\S)', 'g');
|
|
13
|
-
el.className = el.className.replace(regex, '');
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function removeAllChildren(el) {
|
|
17
|
-
while (el.firstChild) {
|
|
18
|
-
el.removeChild(el.firstChild);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function escapeHTML(html) {
|
|
23
|
-
return html
|
|
24
|
-
.replace(/&/g, '&')
|
|
25
|
-
.replace(/</g, '<')
|
|
26
|
-
.replace(/>/g, '>')
|
|
27
|
-
.replace(/"/g, '"')
|
|
28
|
-
.replace(/'/g, ''')
|
|
29
|
-
.replace(/`/g, '`');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Add CSS styles dynamically. This probably doesnt work for IE <8.
|
|
33
|
-
var style = document.createElement('style');
|
|
34
|
-
style.type = 'text/css';
|
|
35
|
-
style.innerHTML = <%= render_inlined_string 'style.css' %>;
|
|
36
|
-
document.getElementsByTagName('head')[0].appendChild(style);
|
|
37
|
-
|
|
38
1
|
/**
|
|
39
2
|
* Constructor for command storage.
|
|
40
3
|
* It uses localStorage if available. Otherwise fallback to normal JS array.
|
|
@@ -84,6 +47,10 @@ function CommandStorage() {
|
|
|
84
47
|
// HTML strings for dynamic elements.
|
|
85
48
|
var consoleInnerHtml = <%= render_inlined_string '_inner_console_markup.html' %>;
|
|
86
49
|
var promptBoxHtml = <%= render_inlined_string '_prompt_box_markup.html' %>;
|
|
50
|
+
// CSS
|
|
51
|
+
var consoleStyleCss = <%= render_inlined_string 'style.css' %>;
|
|
52
|
+
// Insert a style element with the unique ID
|
|
53
|
+
var styleElementId = 'sr02459pvbvrmhco';
|
|
87
54
|
|
|
88
55
|
// REPLConsole Constructor
|
|
89
56
|
function REPLConsole(config) {
|
|
@@ -122,17 +89,25 @@ REPLConsole.prototype.install = function(container) {
|
|
|
122
89
|
// Render the console.
|
|
123
90
|
container.innerHTML = consoleInnerHtml;
|
|
124
91
|
|
|
92
|
+
var consoleOuter = findChild(container, 'console-outer');
|
|
93
|
+
var consoleActions = findChild(consoleOuter, 'console-actions');
|
|
94
|
+
|
|
95
|
+
addClass(container, 'console');
|
|
96
|
+
addClass(container.getElementsByClassName('layer'), 'pos-absolute border-box');
|
|
97
|
+
addClass(container.getElementsByClassName('button'), 'border-box');
|
|
98
|
+
addClass(consoleActions, 'pos-fixed pos-right');
|
|
99
|
+
|
|
125
100
|
// Make the console resizable.
|
|
126
|
-
|
|
101
|
+
function resizeContainer(ev) {
|
|
127
102
|
var startY = ev.clientY;
|
|
128
103
|
var startHeight = parseInt(document.defaultView.getComputedStyle(container).height, 10);
|
|
129
|
-
var
|
|
130
|
-
var
|
|
131
|
-
var innerClientHeightStart = consoleInner.clientHeight;
|
|
104
|
+
var scrollTopStart = consoleOuter.scrollTop;
|
|
105
|
+
var clientHeightStart = consoleOuter.clientHeight;
|
|
132
106
|
|
|
133
107
|
var doDrag = function(e) {
|
|
134
108
|
container.style.height = (startHeight + startY - e.clientY) + 'px';
|
|
135
|
-
|
|
109
|
+
consoleOuter.scrollTop = scrollTopStart + (clientHeightStart - consoleOuter.clientHeight);
|
|
110
|
+
shiftConsoleActions();
|
|
136
111
|
};
|
|
137
112
|
|
|
138
113
|
var stopDrag = function(e) {
|
|
@@ -142,12 +117,50 @@ REPLConsole.prototype.install = function(container) {
|
|
|
142
117
|
|
|
143
118
|
document.documentElement.addEventListener('mousemove', doDrag, false);
|
|
144
119
|
document.documentElement.addEventListener('mouseup', stopDrag, false);
|
|
145
|
-
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function closeContainer(ev) {
|
|
123
|
+
container.parentNode.removeChild(container);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
var shifted = false;
|
|
127
|
+
function shiftConsoleActions() {
|
|
128
|
+
if (consoleOuter.scrollHeight > consoleOuter.clientHeight) {
|
|
129
|
+
var widthDiff = document.documentElement.clientWidth - consoleOuter.clientWidth;
|
|
130
|
+
if (shifted || ! widthDiff) return;
|
|
131
|
+
shifted = true;
|
|
132
|
+
consoleActions.style.marginRight = widthDiff + 'px';
|
|
133
|
+
} else if (shifted) {
|
|
134
|
+
shifted = false;
|
|
135
|
+
consoleActions.style.marginRight = '0px';
|
|
136
|
+
}
|
|
137
|
+
}
|
|
146
138
|
|
|
147
139
|
// Initialize
|
|
148
|
-
this.
|
|
149
|
-
this.
|
|
140
|
+
this.outer = consoleOuter;
|
|
141
|
+
this.inner = findChild(this.outer, 'console-inner');
|
|
142
|
+
this.clipboard = findChild(container, 'clipboard');
|
|
143
|
+
this.remotePath = container.dataset.remotePath;
|
|
150
144
|
this.newPromptBox();
|
|
145
|
+
this.insertCss();
|
|
146
|
+
|
|
147
|
+
findChild(container, 'resizer').addEventListener('mousedown', resizeContainer);
|
|
148
|
+
findChild(consoleActions, 'close-button').addEventListener('click', closeContainer);
|
|
149
|
+
consoleOuter.addEventListener('DOMNodeInserted', shiftConsoleActions);
|
|
150
|
+
|
|
151
|
+
REPLConsole.currentSession = this;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
// Add CSS styles dynamically. This probably doesnt work for IE <8.
|
|
155
|
+
REPLConsole.prototype.insertCss = function() {
|
|
156
|
+
if (document.getElementById(styleElementId)) {
|
|
157
|
+
return; // already inserted
|
|
158
|
+
}
|
|
159
|
+
var style = document.createElement('style');
|
|
160
|
+
style.type = 'text/css';
|
|
161
|
+
style.innerHTML = consoleStyleCss;
|
|
162
|
+
style.id = styleElementId;
|
|
163
|
+
document.getElementsByTagName('head')[0].appendChild(style);
|
|
151
164
|
};
|
|
152
165
|
|
|
153
166
|
REPLConsole.prototype.focus = function() {
|
|
@@ -367,7 +380,117 @@ REPLConsole.prototype.insertAtCurrent = function(char) {
|
|
|
367
380
|
};
|
|
368
381
|
|
|
369
382
|
REPLConsole.prototype.scrollToBottom = function() {
|
|
370
|
-
this.
|
|
383
|
+
this.outer.scrollTop = this.outer.scrollHeight;
|
|
371
384
|
};
|
|
372
385
|
|
|
386
|
+
// Change the binding of the console
|
|
387
|
+
REPLConsole.prototype.switchBindingTo = function(frameId, callback) {
|
|
388
|
+
var url = this.remotePath + "/trace";
|
|
389
|
+
var params = "frame_id=" + encodeURIComponent(frameId);
|
|
390
|
+
postRequest(url, params, callback);
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Install the console into the element with a specific ID.
|
|
395
|
+
* Example: REPLConsole.installInto("target-id")
|
|
396
|
+
*/
|
|
397
|
+
REPLConsole.installInto = function(id) {
|
|
398
|
+
var consoleElement = document.getElementById(id);
|
|
399
|
+
var remotePath = consoleElement.dataset.remotePath;
|
|
400
|
+
var replConsole = new REPLConsole({
|
|
401
|
+
promptLabel: consoleElement.dataset.initialPrompt,
|
|
402
|
+
commandHandle: function(line) {
|
|
403
|
+
var _this = this;
|
|
404
|
+
var url = remotePath;
|
|
405
|
+
var params = "input=" + encodeURIComponent(line);
|
|
406
|
+
putRequest(url, params, function(xhr) {
|
|
407
|
+
var response = JSON.parse(xhr.responseText);
|
|
408
|
+
_this.writeOutput(response.output);
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
replConsole.install(consoleElement);
|
|
414
|
+
return replConsole;
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
// This is to store the latest single session, and the stored session
|
|
418
|
+
// is updated by the REPLConsole#install() method.
|
|
419
|
+
// It allows to operate the current session from the other scripts.
|
|
420
|
+
REPLConsole.currentSession = null;
|
|
421
|
+
|
|
422
|
+
// DOM helpers
|
|
423
|
+
function hasClass(el, className) {
|
|
424
|
+
var regex = new RegExp('(?:^|\\s)' + className + '(?!\\S)', 'g');
|
|
425
|
+
return el.className && el.className.match(regex);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
function isNodeList(el) {
|
|
429
|
+
return typeof el.length === 'number' &&
|
|
430
|
+
typeof el.item === 'function';
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
function addClass(el, className) {
|
|
434
|
+
if (isNodeList(el)) {
|
|
435
|
+
for (var i = 0; i < el.length; ++ i) {
|
|
436
|
+
addClass(el[i], className);
|
|
437
|
+
}
|
|
438
|
+
} else {
|
|
439
|
+
el.className += " " + className;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function removeClass(el, className) {
|
|
444
|
+
var regex = new RegExp('(?:^|\\s)' + className + '(?!\\S)', 'g');
|
|
445
|
+
el.className = el.className.replace(regex, '');
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function removeAllChildren(el) {
|
|
449
|
+
while (el.firstChild) {
|
|
450
|
+
el.removeChild(el.firstChild);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
function findChild(el, className) {
|
|
455
|
+
for (var i = 0; i < el.childNodes.length; ++ i) {
|
|
456
|
+
if (hasClass(el.childNodes[i], className)) {
|
|
457
|
+
return el.childNodes[i];
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
function escapeHTML(html) {
|
|
463
|
+
return html
|
|
464
|
+
.replace(/&/g, '&')
|
|
465
|
+
.replace(/</g, '<')
|
|
466
|
+
.replace(/>/g, '>')
|
|
467
|
+
.replace(/"/g, '"')
|
|
468
|
+
.replace(/'/g, ''')
|
|
469
|
+
.replace(/`/g, '`');
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// XHR helpers
|
|
473
|
+
function request(method, url, params, callback) {
|
|
474
|
+
var xhr = new XMLHttpRequest();
|
|
475
|
+
|
|
476
|
+
xhr.open(method, url, true);
|
|
477
|
+
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
|
478
|
+
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
|
479
|
+
xhr.send(params);
|
|
480
|
+
|
|
481
|
+
xhr.onreadystatechange = function() {
|
|
482
|
+
if (xhr.readyState === 4) {
|
|
483
|
+
callback(xhr);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
function postRequest(url, params, callback) {
|
|
489
|
+
request("POST", url, params, callback);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
function putRequest(url, params, callback) {
|
|
493
|
+
request("PUT", url, params, callback);
|
|
494
|
+
}
|
|
495
|
+
|
|
373
496
|
window.REPLConsole = REPLConsole;
|