Hello community,
here is the log from the commit of package rubygem-web-console for
openSUSE:Factory checked in at 2016-03-17 16:36:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-web-console (Old)
and /work/SRC/openSUSE:Factory/.rubygem-web-console.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-web-console"
Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-web-console/rubygem-web-console.changes
2015-08-05 06:49:52.000000000 +0200
+++
/work/SRC/openSUSE:Factory/.rubygem-web-console.new/rubygem-web-console.changes
2016-03-17 16:49:24.000000000 +0100
@@ -1,0 +2,20 @@
+Wed Mar 2 22:46:02 UTC 2016 - [email protected]
+
+- Fix spec: this rubygem is only compatible with ruby 2.2. Add:
+ + %%define rb_build_versions ruby22
+ + %%define rb_default_ruby_abi ruby:2.2.0
+
+-------------------------------------------------------------------
+Mon Jan 25 05:55:49 UTC 2016 - [email protected]
+
+- updated to version 3.0.0
+ see installed CHANGELOG.markdown
+
+ ## 3.0.0
+
+ * [#173](https://github.com/rails/web-console/pull/173) Revert "Change
config.development_only default until 4.2.4 is released" ([@gsamokovarov])
+ * [#171](https://github.com/rails/web-console/pull/171) Fixed blocked IP
logging ([@gsamokovarov])
+ * [#162](https://github.com/rails/web-console/pull/162) Render the console
inside the body tag ([@gsamokovarov])
+ * [#165](https://github.com/rails/web-console/pull/165) Revamped
integrations for CRuby and Rubinius ([@gsamokovarov])
+
+-------------------------------------------------------------------
Old:
----
web-console-2.2.1.gem
New:
----
web-console-3.0.0.gem
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ rubygem-web-console.spec ++++++
--- /var/tmp/diff_new_pack.rZPino/_old 2016-03-17 16:49:25.000000000 +0100
+++ /var/tmp/diff_new_pack.rZPino/_new 2016-03-17 16:49:25.000000000 +0100
@@ -1,7 +1,7 @@
#
# spec file for package rubygem-web-console
#
-# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -24,13 +24,17 @@
#
Name: rubygem-web-console
-Version: 2.2.1
+Version: 3.0.0
Release: 0
%define mod_name web-console
%define mod_full_name %{mod_name}-%{version}
+# MANUAL
+%define rb_build_versions ruby22
+%define rb_default_ruby_abi ruby:2.2.0
+# /MANUAL
BuildRoot: %{_tmppath}/%{name}-%{version}-build
+BuildRequires: %{ruby >= 2.2.2}
BuildRequires: %{rubygem gem2rpm}
-BuildRequires: %{ruby}
BuildRequires: ruby-macros >= 5
Url: https://github.com/rails/web-console
Source: http://rubygems.org/gems/%{mod_full_name}.gem
@@ -48,7 +52,7 @@
%install
%gem_install \
- --doc-files="CHANGELOG.markdown MIT-LICENSE README.markdown" \
+ --doc-files="MIT-LICENSE" \
-f
%gem_packages
++++++ gem2rpm.yml ++++++
--- /var/tmp/diff_new_pack.rZPino/_old 2016-03-17 16:49:25.000000000 +0100
+++ /var/tmp/diff_new_pack.rZPino/_new 2016-03-17 16:49:25.000000000 +0100
@@ -68,3 +68,6 @@
# :post: |-
# /bin/echo foo
#
+:preamble: |-
+ %define rb_build_versions ruby22
+ %define rb_default_ruby_abi ruby:2.2.0
++++++ web-console-2.2.1.gem -> web-console-3.0.0.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/CHANGELOG.markdown new/CHANGELOG.markdown
--- old/CHANGELOG.markdown 2015-07-10 22:13:19.000000000 +0200
+++ new/CHANGELOG.markdown 2015-12-13 17:58:49.000000000 +0100
@@ -2,9 +2,16 @@
## master (unreleased)
+## 3.0.0
+
+* [#173](https://github.com/rails/web-console/pull/173) Revert "Change
config.development_only default until 4.2.4 is released" ([@gsamokovarov])
+* [#171](https://github.com/rails/web-console/pull/171) Fixed blocked IP
logging ([@gsamokovarov])
+* [#162](https://github.com/rails/web-console/pull/162) Render the console
inside the body tag ([@gsamokovarov])
+* [#165](https://github.com/rails/web-console/pull/165) Revamped integrations
for CRuby and Rubinius ([@gsamokovarov])
+
## 2.2.1
-* [#150](https://github.com/rails/web-console/pull/150) Change
config.development_only default until 4.2.4 is released.
+* [#150](https://github.com/rails/web-console/pull/150) Change
config.development_only default until 4.2.4 is released ([@gsamokovarov])
## 2.2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/README.markdown new/README.markdown
--- old/README.markdown 2015-07-10 22:13:19.000000000 +0200
+++ new/README.markdown 2015-12-13 17:58:49.000000000 +0100
@@ -1,9 +1,6 @@
<p align=right>
Documentation for:
- <a href=https://github.com/rails/web-console/tree/v2.0.0>v2.0.0</a>
- <a href=https://github.com/rails/web-console/tree/v2.1.0>v2.1.0</a>
- <a href=https://github.com/rails/web-console/tree/v2.1.1>v2.1.1</a>
- <a href=https://github.com/rails/web-console/tree/v2.1.2>v2.1.2</a>
+ <a href=https://github.com/rails/web-console/tree/v1.0.4>v1.0.4</a>
<a href=https://github.com/rails/web-console/tree/v2.1.3>v2.1.3</a>
</p>
@@ -28,7 +25,7 @@
```ruby
group :development do
- gem 'web-console', '~> 2.0'
+ gem 'web-console', '~> 3.0'
end
```
@@ -37,35 +34,9 @@
## Runtime
-_Web Console_ uses [John Mair]'s [binding_of_caller] to spawn a console in a
-specific binding. This comes at the price of limited Ruby runtime support.
-
### CRuby
-CRuby 1.9.2 and below is **not** supported.
-
-### JRuby
-
-JRuby needs to run in interpreted mode. You can enable it by:
-
-```bash
-export JRUBY_OPTS=-J-Djruby.compile.mode=OFF
-
-# If you run JRuby 1.7.12 and above, you can use:
-export JRUBY_OPTS=--dev
-```
-
-An unstable version of [binding_of_caller] is needed as the latest stable one
-won't compile on _JRuby_. To install it, put the following in your application
-`Gemfile`:
-
-```ruby
-group :development do
- gem 'binding_of_caller', '0.7.3.pre1'
-end
-```
-
-Only _JRuby_ 1.7, is supported (no JRuby 9K support at the moment).
+CRuby 2.2 and below is **not** supported.
### Rubinius
@@ -75,7 +46,7 @@
The web console allows you to create an interactive Ruby session in your
browser. Those sessions are launched automatically in case on an error, but
-they can also be launched manually in in any page.
+they can also be launched manually in any page.
For example, calling `console` in a view will display a console in the current
page in the context of the view binding.
@@ -161,6 +132,18 @@
You may wanna check the [templates] folder at the source tree for the files you
may override.
+### config.web_console.mount_point
+
+Usually the middleware of _Web Console_ is mounted at `/__web_console`.
+If you wanna change the path for some reasons, you can specify it
+by `config.web_console.mount_point`:
+
+```ruby
+Rails.application.configure do
+ config.web_console.mount_point = '/path/to/web_console'
+end
+```
+
## FAQ
### Where did /console go?
@@ -203,17 +186,16 @@
## Credits
-* Shoutout to [Charlie Somerville] for [better_errors] and [this] code.
-* Kudos to [John Mair] for [binding_of_caller].
+* Shoutout to [Charlie Somerville] for [better_errors].
+* Kudos to [John Mair] for [debug_inspector].
* Thanks to [Charles Oliver Nutter] for all the _JRuby_ feedback.
-* Hugs and kisses to all of our [contributors].
+* Hugs and kisses to all of our [contributors]!
[better_errors]: https://github.com/charliesome/better_errors
-[binding_of_caller]: https://github.com/banister/binding_of_caller
+[debug_inspector]: https://github.com/banister/debug_inspector
[Charlie Somerville]: https://github.com/charliesome
[John Mair]: https://github.com/banister
[Charles Oliver Nutter]: https://github.com/headius
[templates]:
https://github.com/rails/web-console/tree/master/lib/web_console/templates
-[this]:
https://github.com/rails/web-console/blob/master/lib/web_console/integration/cruby.rb#L20-L32
[rvt]: https://github.com/gsamokovarov/rvt
[contributors]: https://github.com/rails/web-console/graphs/contributors
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Rakefile new/Rakefile
--- old/Rakefile 2015-07-10 22:13:19.000000000 +0200
+++ new/Rakefile 2015-12-13 17:58:49.000000000 +0100
@@ -8,6 +8,8 @@
require 'rake/testtask'
require 'tmpdir'
require 'securerandom'
+require 'json'
+require 'web_console/testing/erb_precompiler'
EXPANDED_CWD = File.expand_path(File.dirname(__FILE__))
@@ -18,40 +20,7 @@
t.verbose = false
end
-namespace :test do
- desc "Run tests for templates"
- task :templates => "templates:all"
-
- namespace :templates do
- task :all => [:daemonize, :npm, :rackup, :mocha, :kill]
- task :serve => [:npm, :rackup]
-
- work_dir = Pathname(__FILE__).dirname.join("test/templates")
- pid_file =
Pathname(Dir.tmpdir).join("web_console.#{SecureRandom.uuid}.pid")
- server_port = 29292
- rackup_opts = "-p #{server_port}"
-
- task :daemonize do
- rackup_opts += " -D -P #{pid_file}"
- end
-
- task :npm do
- Dir.chdir(work_dir) { system "npm install --silent" }
- end
-
- task :rackup do
- Dir.chdir(work_dir) { system "bundle exec rackup #{rackup_opts}" }
- end
-
- task :mocha do
- Dir.chdir(work_dir) { system "$(npm bin)/mocha-phantomjs
http://localhost:#{server_port}/html/spec_runner.html" }
- end
-
- task :kill do
- system "kill #{File.read pid_file}"
- end
- end
-end
+Dir['lib/web_console/tasks/**/*.rake'].each { |task| load task }
Bundler::GemHelper.install_tasks
Files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/extensions.rb
new/lib/web_console/extensions.rb
--- old/lib/web_console/extensions.rb 2015-07-10 22:13:19.000000000 +0200
+++ new/lib/web_console/extensions.rb 2015-12-13 17:58:49.000000000 +0100
@@ -1,7 +1,11 @@
ActionDispatch::DebugExceptions.class_eval do
- def render_exception_with_web_console(env, exception)
- render_exception_without_web_console(env, exception).tap do
- error = ActionDispatch::ExceptionWrapper.new(env, exception).exception
+ def render_exception_with_web_console(request, exception)
+ render_exception_without_web_console(request, exception).tap do
+ # Retain superficial Rails 4.2 compatibility.
+ env = Hash === request ? request : request.env
+
+ backtrace_cleaner = env['action_dispatch.backtrace_cleaner']
+ error = ActionDispatch::ExceptionWrapper.new(backtrace_cleaner,
exception).exception
# Get the original exception if ExceptionWrapper decides to follow it.
env['web_console.exception'] = error
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/helper.rb
new/lib/web_console/helper.rb
--- old/lib/web_console/helper.rb 2015-07-10 22:13:19.000000000 +0200
+++ new/lib/web_console/helper.rb 2015-12-13 17:58:49.000000000 +0100
@@ -11,7 +11,7 @@
def console(binding = nil)
raise DoubleRenderError if request.env['web_console.binding']
- request.env['web_console.binding'] = binding ||
::Kernel.binding.of_caller(1)
+ request.env['web_console.binding'] = binding ||
::WebConsole.caller_bindings.first
# Make sure nothing is rendered from the view helper. Otherwise
# you're gonna see unexpected #<Binding:0x007fee4302b078> in the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/integration/cruby.rb
new/lib/web_console/integration/cruby.rb
--- old/lib/web_console/integration/cruby.rb 2015-07-10 22:13:19.000000000
+0200
+++ new/lib/web_console/integration/cruby.rb 2015-12-13 17:58:49.000000000
+0100
@@ -1,40 +1,23 @@
-class Exception
- begin
- # We share the same exception binding extraction mechanism as
better_errors,
- # so try to use it if it is already available. It also solves problems like
- # charliesome/better_errors#272, caused by an infinite recursion.
- require 'better_errors'
+require 'debug_inspector'
- # The bindings in which the exception originated in.
- def bindings
- @bindings || __better_errors_bindings_stack
- end
- rescue LoadError
- # The bindings in which the exception originated in.
- def bindings
- @bindings || []
- end
-
- # CRuby calls #set_backtrace every time it raises an exception. Overriding
- # it to assign the #bindings.
- def set_backtrace_with_binding_of_caller(*args)
- # Thanks to @charliesome who wrote this bit for better_errors.
- unless Thread.current[:__web_console_exception_lock]
- Thread.current[:__web_console_exception_lock] = true
- begin
- # Raising an exception here will cause all of the rubies to go into a
- # stack overflow. Some rubies may even segfault. See
- # https://bugs.ruby-lang.org/issues/10164 for details.
- @bindings = binding.callers.drop(1)
- ensure
- Thread.current[:__web_console_exception_lock] = false
- end
- end
+def WebConsole.caller_bindings
+ bindings = RubyVM::DebugInspector.open do |context|
+ context.backtrace_locations.each_index.map { |i| context.frame_binding(i) }
+ end
- set_backtrace_without_binding_of_caller(*args)
- end
+ # For C functions, we can't extract a binding. In this case,
+ # DebugInspector#frame_binding would have returned us nil. That's why we need
+ # to compact the bindings.
+ #
+ # Dropping two bindings, removes the current Ruby one in this exact method,
+ # and the one in the caller method. The caller method binding can be obtained
+ # by Kernel#binding, if needed.
+ bindings.compact.drop(2)
+end
- alias_method :set_backtrace_without_binding_of_caller, :set_backtrace
- alias_method :set_backtrace, :set_backtrace_with_binding_of_caller
+TracePoint.trace(:raise) do |context|
+ exc = context.raised_exception
+ if exc.bindings.empty?
+ exc.instance_variable_set(:@bindings, WebConsole.caller_bindings)
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/integration/jruby.rb
new/lib/web_console/integration/jruby.rb
--- old/lib/web_console/integration/jruby.rb 2015-07-10 22:13:19.000000000
+0200
+++ new/lib/web_console/integration/jruby.rb 1970-01-01 01:00:00.000000000
+0100
@@ -1,111 +0,0 @@
-require 'English'
-require 'active_support/core_ext/string/strip'
-
-java_import org.jruby.RubyInstanceConfig
-
-module WebConsole
- module JRuby
- class << self
- # Returns whether JRuby is ran in interpreted mode.
- def interpreted_mode?
- compile_mode = ::JRuby.runtime.instance_config.compile_mode
- interpreted_mode = RubyInstanceConfig::CompileMode::OFF
-
- compile_mode == interpreted_mode
- end
-
- # A proc to be used in Kernel#set_trace_func.
- #
- # It sets Exception#bindings for an error with all the bindings the
- # current ThreadContext contains.
- def set_exception_bindings_trace_func
- proc do |event, file, line, id, binding, classname|
- case event
- when 'raise'
- if $ERROR_INFO.bindings.empty?
- # binding_of_caller will generate an improperly built binding at
- # caller[1]. Every call to a non existent method, constant or a
- # local variable will result in a Java NullPointerException.
- #
- # The binding that Kernel#set_trace_func is giving us is properly
- # built, so we can use in place of the broken one.
- bindings = ::Kernel.binding.callers.drop(2).unshift(binding)
- $ERROR_INFO.instance_variable_set(:@bindings, bindings)
- end
- end
- end
- end
- end
-
- # A fake binding for JRuby in non interpreted mode.
- #
- # It won't actually evaluate any code, rather it will tell the user how to
- # enable interpreted mode.
- class FakeJRubyBinding
- TURN_ON_INTERPRETED_MODE_TEXT = <<-END.strip_heredoc
- JRuby needs to run in interpreted mode for introspection support.
-
- To turn on interpreted mode, put -J-Djruby.compile.mode=OFF in the
- JRUBY_OPTS environment variable.
- END
-
- def TURN_ON_INTERPRETED_MODE_TEXT.inspect
- self
- end
-
- TURN_ON_INTERPRETED_MODE_TEXT.freeze
-
- def eval(*)
- TURN_ON_INTERPRETED_MODE_TEXT
- end
- end
-
- # A fake array of FakeJRubyBinding objects.
- #
- # It is used in Exception#bindings to make sure that when users switch
- # bindings on the UI, they get a FakeJRubyBinding notifying them what to do
- # if they want introspection.
- class FakeJRubyBindingsArray < Array
- def [](*)
- FakeJRubyBinding.new
- end
-
- # For Kernel#Array and other implicit conversion API. JRuby expects it to
- # return an object that is_a? an Array. This is the reasoning of
- # FakeJRubyBindingsArray being a subclass of Array.
- def to_ary
- self
- end
- end
- end
-end
-
-if WebConsole::JRuby.interpreted_mode?
- ::Exception.class_eval do
- def bindings
- @bindings || []
- end
- end
-
- # Kernel#set_trace_func will complain about not being able to capture all the
- # events without the JRuby --debug flag.
- silence_warnings do
- set_trace_func WebConsole::JRuby.set_exception_bindings_trace_func
- end
-else
- ::Exception.class_eval do
- def bindings
- WebConsole::JRuby::FakeJRubyBindingsArray.new
- end
- end
-
- ::Binding.class_eval do
- def of_caller(*)
- WebConsole::JRuby::FakeJRubyBinding.new
- end
-
- def callers
- WebConsole::JRuby::FakeJRubyBindingsArray.new
- end
- end
-end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/integration/rubinius.rb
new/lib/web_console/integration/rubinius.rb
--- old/lib/web_console/integration/rubinius.rb 2015-07-10 22:13:19.000000000
+0200
+++ new/lib/web_console/integration/rubinius.rb 2015-12-13 17:58:49.000000000
+0100
@@ -1,62 +1,34 @@
-module WebConsole
- module Rubinius
- # Filters internal Rubinius locations.
- #
- # There are a couple of reasons why we wanna filter out the locations.
- #
- # * ::Kernel.raise, is implemented in Ruby for Rubinius. We don't wanna
- # have the frame for it to align with the CRuby and JRuby
implementations.
- #
- # * For internal methods location variables can be nil. We can't create a
- # bindings for them.
- #
- # * Bindings from the current file are considered internal and ignored.
- #
- # We do that all that so we can align the bindings with the backtraces
- # entries.
- class InternalLocationFilter
- def initialize(locations)
- @locations = locations
- end
+def WebConsole.caller_bindings
+ locations = ::Rubinius::VM.backtrace(1, true)
- def filter
- @locations.reject do |location|
- location.file.start_with?('kernel/delta/kernel.rb') ||
- location.file == __FILE__ ||
- location.variables.nil?
- end
- end
- end
-
- # Gets the current bindings for all available Ruby frames.
- #
- # Filters the internal Rubinius and WebConsole frames.
- def self.current_bindings
- locations = ::Rubinius::VM.backtrace(1, true)
-
- InternalLocationFilter.new(locations).filter.map do |location|
- Binding.setup(
- location.variables,
- location.variables.method,
- location.constant_scope,
- location.variables.self,
- location
- )
- end
- end
+ # Kernel.raise, is implemented in Ruby for Rubinius. We don't wanna have
+ # the frame for it to align with the CRuby and JRuby implementations.
+ #
+ # For internal methods location variables can be nil. We can't create a
+ # bindings for them.
+ locations.reject! do |location|
+ location.file.start_with?('kernel/delta/kernel.rb') ||
location.variables.nil?
end
-end
-::Exception.class_eval do
- def bindings
- @bindings || []
+ bindings = locations.map do |location|
+ Binding.setup(
+ location.variables,
+ location.variables.method,
+ location.constant_scope,
+ location.variables.self,
+ location
+ )
end
+
+ # Drop the binding of the direct caller. That one can be created by
+ # Kernel#binding.
+ bindings.drop(1)
end
::Rubinius.singleton_class.class_eval do
def raise_exception_with_current_bindings(exc)
if exc.bindings.empty?
- exc.instance_variable_set(:@bindings,
WebConsole::Rubinius.current_bindings)
+ exc.instance_variable_set(:@bindings, WebConsole.caller_bindings)
end
raise_exception_without_current_bindings(exc)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/integration.rb
new/lib/web_console/integration.rb
--- old/lib/web_console/integration.rb 2015-07-10 22:13:19.000000000 +0200
+++ new/lib/web_console/integration.rb 2015-12-13 17:58:49.000000000 +0100
@@ -1,8 +1,31 @@
+module WebConsole
+ # Returns the Ruby bindings of Kernel#callers locations.
+ #
+ # The list of bindings here doesn't map 1 to 1 with Kernel#callers, as we
+ # can't build Ruby bindings for C functions or the equivalent native
+ # implementations in JRuby and Rubinius.
+ #
+ # This method needs to be overridden by every integration.
+ def self.caller_bindings
+ raise NotImplementedError
+ end
+end
+
+class Exception
+ # Returns an array of the exception backtrace locations bindings.
+ #
+ # The list won't map to the traces in #backtrace 1 to 1, because we can't
+ # build bindings for every trace (C functions, for example).
+ #
+ # Every integration should the instance variable.
+ def bindings
+ @bindings || []
+ end
+end
+
case RUBY_ENGINE
when 'rbx'
require 'web_console/integration/rubinius'
-when 'jruby'
- require 'web_console/integration/jruby'
when 'ruby'
require 'web_console/integration/cruby'
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/locales/en.yml
new/lib/web_console/locales/en.yml
--- old/lib/web_console/locales/en.yml 1970-01-01 01:00:00.000000000 +0100
+++ new/lib/web_console/locales/en.yml 2015-12-13 17:58:49.000000000 +0100
@@ -0,0 +1,15 @@
+en:
+ errors:
+ unavailable_session: |
+ Session %{id} is is no longer available in memory.
+
+ If you happen to run on a multi-process server (like Unicorn or Puma)
the process
+ this request hit doesn't store %{id} in memory. Consider turning the
number of
+ processes/workers to one (1) or using a different server in development.
+
+ unacceptable_request: |
+ A supported version is expected in the Accept header.
+
+ connection_refused: |
+ Oops! Failed to connect to the Web Console middleware.
+ Please make sure a rails development server is running.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/middleware.rb
new/lib/web_console/middleware.rb
--- old/lib/web_console/middleware.rb 2015-07-10 22:13:19.000000000 +0200
+++ new/lib/web_console/middleware.rb 2015-12-13 17:58:49.000000000 +0100
@@ -4,31 +4,19 @@
class Middleware
TEMPLATES_PATH = File.expand_path('../templates', __FILE__)
- DEFAULT_OPTIONS = {
- update_re: %r{/repl_sessions/(?<id>.+?)\z},
- binding_change_re: %r{/repl_sessions/(?<id>.+?)/trace\z}
- }
-
- UNAVAILABLE_SESSION_MESSAGE = <<-END.strip_heredoc
- Session %{id} is is no longer available in memory.
-
- If you happen to run on a multi-process server (like Unicorn) the process
- this request hit doesn't store %{id} in memory.
- END
-
- UNACCEPTABLE_REQUEST_MESSAGE = "A supported version is expected in the
Accept header."
+ cattr_accessor :mount_point
+ @@mount_point = '/__web_console'
cattr_accessor :whiny_requests
@@whiny_requests = true
- def initialize(app, options = {})
- @app = app
- @options = DEFAULT_OPTIONS.merge(options)
+ def initialize(app)
+ @app = app
end
def call(env)
request = create_regular_or_whiny_request(env)
- return @app.call(env) unless request.from_whitelited_ip?
+ return @app.call(env) unless request.from_whitelisted_ip?
if id = id_for_repl_session_update(request)
return update_repl_session(id, request)
@@ -44,11 +32,12 @@
session = Session.from_binding(binding)
end
- if session && request.acceptable_content_type?
- headers["X-Web-Console-Session-Id"] = session.id
- response = Rack::Response.new(body, status, headers)
+ if session && acceptable_content_type?(headers)
+ response = Response.new(body, status, headers)
template = Template.new(env, session)
+ response.headers["X-Web-Console-Session-Id"] = session.id
+ response.headers["X-Web-Console-Mount-Point"] = mount_point
response.write(template.render('index'))
response.finish
else
@@ -58,6 +47,10 @@
private
+ def acceptable_content_type?(headers)
+ Mime::Type.parse(headers['Content-Type']).first == Mime[:html]
+ end
+
def json_response(opts = {})
status = opts.fetch(:status, 200)
headers = { 'Content-Type' => 'application/json; charset = utf-8' }
@@ -67,17 +60,10 @@
end
def json_response_with_session(id, request, opts = {})
- json_response(opts) do
- unless request.acceptable?
- return respond_with_unacceptable_request
- end
-
- unless session = Session.find(id)
- return respond_with_unavailable_session(id)
- end
+ return respond_with_unacceptable_request unless request.acceptable?
+ return respond_with_unavailable_session(id) unless session =
Session.find(id)
- yield session
- end
+ json_response(opts) { yield session }
end
def create_regular_or_whiny_request(env)
@@ -85,23 +71,27 @@
whiny_requests ? WhinyRequest.new(request) : request
end
+ def repl_sessions_re
+ @_repl_sessions_re ||= %r{#{mount_point}/repl_sessions/(?<id>[^/]+)}
+ end
+
def update_re
- @options[:update_re]
+ @_update_re ||= %r{#{repl_sessions_re}\z}
end
def binding_change_re
- @options[:binding_change_re]
+ @_binding_change_re ||= %r{#{repl_sessions_re}/trace\z}
end
def id_for_repl_session_update(request)
if request.xhr? && request.put?
- update_re.match(request.path_info) { |m| m[:id] }
+ update_re.match(request.path) { |m| m[:id] }
end
end
def id_for_repl_session_stack_frame_change(request)
if request.xhr? && request.post?
- binding_change_re.match(request.path_info) { |m| m[:id] }
+ binding_change_re.match(request.path) { |m| m[:id] }
end
end
@@ -121,13 +111,13 @@
def respond_with_unavailable_session(id)
json_response(status: 404) do
- { output: format(UNAVAILABLE_SESSION_MESSAGE, id: id)}
+ { output: format(I18n.t('errors.unavailable_session'), id: id)}
end
end
def respond_with_unacceptable_request
json_response(status: 406) do
- { error: UNACCEPTABLE_REQUEST_MESSAGE }
+ { output: I18n.t('errors.unacceptable_request') }
end
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/railtie.rb
new/lib/web_console/railtie.rb
--- old/lib/web_console/railtie.rb 2015-07-10 22:13:19.000000000 +0200
+++ new/lib/web_console/railtie.rb 2015-12-13 17:58:49.000000000 +0100
@@ -5,10 +5,6 @@
config.web_console = ActiveSupport::OrderedOptions.new
config.web_console.whitelisted_ips = %w( 127.0.0.1 ::1 )
- # See rails/web-console#150 and rails/rails#20319. Revert when Ruby on
- # Rails 4.2.4 is released.
- config.web_console.development_only = false
-
initializer 'web_console.initialize' do
require 'web_console/extensions'
@@ -24,7 +20,7 @@
initializer 'web_console.development_only' do
unless (config.web_console.development_only == false) ||
Rails.env.development?
abort <<-END.strip_heredoc
- Web Console is activated in the #{Rails.env} environment, which is
+ Web Console is activated in the #{Rails.env} environment. This is
usually a mistake. To ensure it's only activated in development
mode, move it to the development group of your Gemfile:
@@ -43,6 +39,12 @@
app.middleware.insert_before ActionDispatch::DebugExceptions, Middleware
end
+ initializer 'web_console.mount_point' do
+ if mount_point = config.web_console.mount_point
+ Middleware.mount_point = mount_point.chomp('/')
+ end
+ end
+
initializer 'web_console.template_paths' do
if template_paths = config.web_console.template_paths
Template.template_paths.unshift(*Array(template_paths))
@@ -61,12 +63,8 @@
end
end
- # Leave this undocumented so we treat such content type misses as bugs,
- # while still being able to help the affected users in the meantime.
- initializer 'web_console.acceptable_content_types' do
- if acceptable_content_types = config.web_console.acceptable_content_types
-
Request.acceptable_content_types.concat(Array(acceptable_content_types))
- end
+ initializer 'i18n.load_path' do
+ config.i18n.load_path.concat(Dir[File.expand_path('../locales/*.yml',
__FILE__)])
end
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/request.rb
new/lib/web_console/request.rb
--- old/lib/web_console/request.rb 2015-07-10 22:13:19.000000000 +0200
+++ new/lib/web_console/request.rb 2015-12-13 17:58:49.000000000 +0100
@@ -1,57 +1,50 @@
module WebConsole
# Web Console tailored request object.
class Request < ActionDispatch::Request
- # While most of the servers will return blank content type if none given,
- # Puma will return text/plain.
- cattr_accessor :acceptable_content_types
- @@acceptable_content_types = [Mime::HTML, Mime::TEXT,
Mime::URL_ENCODED_FORM]
-
# Configurable set of whitelisted networks.
cattr_accessor :whitelisted_ips
@@whitelisted_ips = Whitelist.new
- # Define a vendor MIME type. We can call it using Mime::WEB_CONSOLE_V2
constant.
+ # Define a vendor MIME type. We can call it using Mime[:web_console_v2].
Mime::Type.register 'application/vnd.web-console.v2', :web_console_v2
# Returns whether a request came from a whitelisted IP.
#
# For a request to hit Web Console features, it needs to come from a white
# listed IP.
- def from_whitelited_ip?
+ def from_whitelisted_ip?
whitelisted_ips.include?(strict_remote_ip)
end
# Determines the remote IP using our much stricter whitelist.
def strict_remote_ip
- GetSecureIp.new(env, whitelisted_ips).to_s
- end
-
- # Returns whether the request is from an acceptable content type.
- #
- # We can render a console for HTML and TEXT by default. If a client didn't
- # specified any content type and the server returned it as blank, we'll
- # render it as well.
- def acceptable_content_type?
- content_type.blank? || content_type.in?(acceptable_content_types)
+ GetSecureIp.new(self, whitelisted_ips).to_s
end
# Returns whether the request is acceptable.
def acceptable?
- xhr? && accepts.any? { |mime| Mime::WEB_CONSOLE_V2 == mime }
+ xhr? && accepts.any? { |mime| Mime[:web_console_v2] == mime }
end
- class GetSecureIp < ActionDispatch::RemoteIp::GetIp
- def initialize(env, proxies)
- @env = env
- @check_ip = true
- @proxies = proxies
- end
+ private
+
+ class GetSecureIp < ActionDispatch::RemoteIp::GetIp
+ def initialize(req, proxies)
+ # After rails/rails@07b2ff0 ActionDispatch::RemoteIp::GetIp
initializes
+ # with a ActionDispatch::Request object instead of plain Rack
+ # environment hash. Keep both @req and @env here, so we don't if/else
+ # on Rails versions.
+ @req = req
+ @env = req.env
+ @check_ip = true
+ @proxies = proxies
+ end
- def filter_proxies(ips)
- ips.reject do |ip|
- @proxies.include?(ip)
+ def filter_proxies(ips)
+ ips.reject do |ip|
+ @proxies.include?(ip)
+ end
end
end
- end
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/response.rb
new/lib/web_console/response.rb
--- old/lib/web_console/response.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/lib/web_console/response.rb 2015-12-13 17:58:49.000000000 +0100
@@ -0,0 +1,23 @@
+module WebConsole
+ # A response object that writes content before the closing </body> tag, if
+ # possible.
+ #
+ # The object quacks like Rack::Response.
+ class Response < Struct.new(:body, :status, :headers)
+ def write(content)
+ raw_body = Array(body).first.to_s
+
+ if position = raw_body.rindex('</body>')
+ raw_body.insert(position, content)
+ else
+ raw_body << content
+ end
+
+ self.body = raw_body
+ end
+
+ def finish
+ Rack::Response.new(body, status, headers).finish
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/tasks/extensions.rake
new/lib/web_console/tasks/extensions.rake
--- old/lib/web_console/tasks/extensions.rake 1970-01-01 01:00:00.000000000
+0100
+++ new/lib/web_console/tasks/extensions.rake 2015-12-13 17:58:49.000000000
+0100
@@ -0,0 +1,60 @@
+namespace :ext do
+ rootdir = Pathname('extensions')
+
+ desc 'Build Chrome Extension'
+ task chrome: 'chrome:build'
+
+ namespace :chrome do
+ dist = Pathname('dist/crx')
+ extdir = rootdir.join(dist)
+ manifest_json = rootdir.join('chrome/manifest.json')
+
+ directory extdir
+
+ task build: [ extdir, 'lib:templates' ] do
+ cd rootdir do
+ cp_r [ 'img/', 'tmp/lib/' ], dist
+ `cd chrome && git ls-files`.split("\n").each do |src|
+ dest = dist.join(src)
+ mkdir_p dest.dirname
+ cp Pathname('chrome').join(src), dest
+ end
+ end
+ end
+
+ # Generate a .crx file.
+ task crx: [ :build, :npm ] do
+ out =
"crx-web-console-#{JSON.parse(File.read(manifest_json))["version"]}.crx"
+ cd(extdir) { sh "node \"$(npm bin)/crx\" pack ./ -p
../crx-web-console.pem -o ../#{out}" }
+ end
+
+ # Generate a .zip file for Chrome Web Store.
+ task zip: [ :build ] do
+ version = JSON.parse(File.read(manifest_json))["version"]
+ cd(extdir) { sh "zip -r ../crx-web-console-#{version}.zip ./" }
+ end
+
+ desc 'Launch a browser with the chrome extension.'
+ task run: [ :build ] do
+ cd(rootdir) { sh "sh ./script/run_chrome.sh --load-extension=#{dist}" }
+ end
+ end
+
+ task :npm do
+ cd(rootdir) { sh "npm install --silent" }
+ end
+
+ namespace :lib do
+ templates = Pathname('lib/web_console/templates')
+ tmplib = rootdir.join('tmp/lib/')
+ js_erb = FileList.new(templates.join('**/*.js.erb'))
+ dirs = js_erb.pathmap("%{^#{templates},#{tmplib}}d")
+
+ task templates: dirs + js_erb.pathmap("%{^#{templates},#{tmplib}}X")
+
+ dirs.each { |d| directory d }
+ rule '.js' => [ "%{^#{tmplib},#{templates}}X.js.erb" ] do |t|
+ File.write(t.name,
WebConsole::Testing::ERBPrecompiler.new(t.source).build)
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/tasks/test_templates.rake
new/lib/web_console/tasks/test_templates.rake
--- old/lib/web_console/tasks/test_templates.rake 1970-01-01
01:00:00.000000000 +0100
+++ new/lib/web_console/tasks/test_templates.rake 2015-12-13
17:58:49.000000000 +0100
@@ -0,0 +1,50 @@
+namespace :test do
+ desc "Run tests for templates"
+ task templates: "templates:all"
+
+ namespace :templates do
+ task all: [ :daemonize, :npm, :rackup, :wait, :mocha, :kill, :exit ]
+ task serve: [ :npm, :rackup ]
+
+ work_dir = Pathname(EXPANDED_CWD).join("test/templates")
+ pid_file =
Pathname(Dir.tmpdir).join("web_console.#{SecureRandom.uuid}.pid")
+ runner_uri = URI.parse("http://localhost:29292/html/spec_runner.html")
+ rackup_opts = "-p #{runner_uri.port}"
+ test_result = nil
+
+ def need_to_wait?(uri)
+ Net::HTTP.start(uri.host, uri.port) { |http| http.get(uri.path) }
+ rescue Errno::ECONNREFUSED
+ retry if yield
+ end
+
+ task :daemonize do
+ rackup_opts += " -D -P #{pid_file}"
+ end
+
+ task :npm do
+ Dir.chdir(work_dir) { system "npm install --silent" }
+ end
+
+ task :rackup do
+ Dir.chdir(work_dir) { system "bundle exec rackup #{rackup_opts}" }
+ end
+
+ task :wait do
+ cnt = 0
+ need_to_wait?(runner_uri) { sleep 1; cnt += 1; cnt < 5 }
+ end
+
+ task :mocha do
+ Dir.chdir(work_dir) { test_result = system("$(npm bin)/mocha-phantomjs
#{runner_uri}") }
+ end
+
+ task :kill do
+ system "kill #{File.read pid_file}"
+ end
+
+ task :exit do
+ exit test_result
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/template.rb
new/lib/web_console/template.rb
--- old/lib/web_console/template.rb 2015-07-10 22:13:19.000000000 +0200
+++ new/lib/web_console/template.rb 2015-12-13 17:58:49.000000000 +0100
@@ -4,33 +4,6 @@
# It introduces template helpers to ease the inclusion of scripts only on
# Rails error pages.
class Template
- class Context < ActionView::Base
- # Execute a block only on error pages.
- #
- # The error pages are special, because they are the only pages that
- # currently require multiple bindings. We get those from exceptions.
- def only_on_error_page(*args)
- yield if @env['web_console.exception'].present?
- end
-
- # Render JavaScript inside a script tag and a closure.
- #
- # This one lets write JavaScript that will automatically get wrapped in a
- # script tag and enclosed in a closure, so you don't have to worry for
- # leaking globals, unless you explicitly want to.
- def render_javascript(template)
- render(template: template, layout: 'layouts/javascript')
- end
-
- # Render inlined string to be used inside of JavaScript code.
- #
- # The inlined string is returned as an actual JavaScript string. You
- # don't need to wrap the result yourself.
- def render_inlined_string(template)
- render(template: template, layout: 'layouts/inlined_string')
- end
- end
-
# Lets you customize the default templates folder location.
cattr_accessor :template_paths
@@template_paths = [ File.expand_path('../templates', __FILE__) ]
@@ -38,12 +11,13 @@
def initialize(env, session)
@env = env
@session = session
+ @mount_point = Middleware.mount_point
end
# Render a template (inferred from +template_paths+) as a plain string.
def render(template)
- context = Context.new(template_paths, instance_values)
- context.render(template: template, layout: false)
+ view = View.new(template_paths, instance_values)
+ view.render(template: template, layout: false)
end
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/templates/_markup.html.erb
new/lib/web_console/templates/_markup.html.erb
--- old/lib/web_console/templates/_markup.html.erb 2015-07-10
22:13:19.000000000 +0200
+++ new/lib/web_console/templates/_markup.html.erb 2015-12-13
17:58:49.000000000 +0100
@@ -1,4 +1,5 @@
<div id="console"
- data-remote-path='<%= "console/repl_sessions/#{@session.id}" %>'
- data-initial-prompt='>> '>
+ data-mount-point='<%= @mount_point %>'
+ data-session-id='<%= @session.id %>'
+ data-prompt-label='>> '>
</div>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/templates/console.js.erb
new/lib/web_console/templates/console.js.erb
--- old/lib/web_console/templates/console.js.erb 2015-07-10
22:13:19.000000000 +0200
+++ new/lib/web_console/templates/console.js.erb 2015-12-13
17:58:49.000000000 +0100
@@ -54,11 +54,69 @@
// REPLConsole Constructor
function REPLConsole(config) {
+ function getConfig(key, defaultValue) {
+ return config && config[key] || defaultValue;
+ }
+
this.commandStorage = new CommandStorage();
- this.prompt = config && config.promptLabel ? config.promptLabel : ' >>';
- this.commandHandle = config && config.commandHandle ? config.commandHandle :
function() { return this; }
+ this.prompt = getConfig('promptLabel', ' >>');
+ this.mountPoint = getConfig('mountPoint');
+ this.sessionId = getConfig('sessionId');
}
+REPLConsole.prototype.getSessionUrl = function(path) {
+ var parts = [ this.mountPoint, 'repl_sessions', this.sessionId ];
+ if (path) {
+ parts.push(path);
+ }
+ // Join and remove duplicate slashes.
+ return parts.join('/').replace(/([^:]\/)\/+/g, '$1');
+};
+
+REPLConsole.prototype.commandHandle = function(line, callback) {
+ var self = this;
+ var params = 'input=' + encodeURIComponent(line);
+ callback = callback || function() {};
+
+ function isSuccess(status) {
+ return status >= 200 && status < 300 || status === 304;
+ }
+
+ function parseJSON(text) {
+ try {
+ return JSON.parse(text);
+ } catch (e) {
+ return null;
+ }
+ }
+
+ function getErrorText(xhr) {
+ if (!xhr.status) {
+ return "<%= t 'errors.connection_refused' %>";
+ } else {
+ return xhr.status + ' ' + xhr.statusText;
+ }
+ }
+
+ putRequest(self.getSessionUrl(), params, function(xhr) {
+ var response = parseJSON(xhr.responseText);
+ var result = isSuccess(xhr.status);
+ if (result) {
+ self.writeOutput(response.output);
+ } else {
+ if (response && response.output) {
+ self.writeError(response.output);
+ } else {
+ self.writeError(getErrorText(xhr));
+ }
+ }
+ callback(result, response);
+ });
+};
+
+REPLConsole.prototype.uninstall = function() {
+ this.container.parentNode.removeChild(this.container);
+};
REPLConsole.prototype.install = function(container) {
var _this = this;
@@ -99,8 +157,8 @@
// Make the console resizable.
function resizeContainer(ev) {
- var startY = ev.clientY;
- var startHeight =
parseInt(document.defaultView.getComputedStyle(container).height, 10);
+ var startY = ev.clientY;
+ var startHeight =
parseInt(document.defaultView.getComputedStyle(container).height, 10);
var scrollTopStart = consoleOuter.scrollTop;
var clientHeightStart = consoleOuter.clientHeight;
@@ -137,10 +195,10 @@
}
// Initialize
+ this.container = container;
this.outer = consoleOuter;
this.inner = findChild(this.outer, 'console-inner');
this.clipboard = findChild(container, 'clipboard');
- this.remotePath = container.dataset.remotePath;
this.newPromptBox();
this.insertCss();
@@ -263,6 +321,13 @@
consoleMessage.innerHTML = escapeHTML(output);
this.inner.appendChild(consoleMessage);
this.newPromptBox();
+ return consoleMessage;
+};
+
+REPLConsole.prototype.writeError = function(output) {
+ var consoleMessage = this.writeOutput(output);
+ addClass(consoleMessage, "error-message");
+ return consoleMessage;
};
REPLConsole.prototype.onEnterKey = function() {
@@ -385,7 +450,7 @@
// Change the binding of the console
REPLConsole.prototype.switchBindingTo = function(frameId, callback) {
- var url = this.remotePath + "/trace";
+ var url = this.getSessionUrl('trace');
var params = "frame_id=" + encodeURIComponent(frameId);
postRequest(url, params, callback);
};
@@ -394,22 +459,16 @@
* Install the console into the element with a specific ID.
* Example: REPLConsole.installInto("target-id")
*/
-REPLConsole.installInto = function(id) {
+REPLConsole.installInto = function(id, options) {
var consoleElement = document.getElementById(id);
- var remotePath = consoleElement.dataset.remotePath;
- var replConsole = new REPLConsole({
- promptLabel: consoleElement.dataset.initialPrompt,
- commandHandle: function(line) {
- var _this = this;
- var url = remotePath;
- var params = "input=" + encodeURIComponent(line);
- putRequest(url, params, function(xhr) {
- var response = JSON.parse(xhr.responseText);
- _this.writeOutput(response.output);
- });
- }
- });
+ options = options || {};
+
+ for (var prop in consoleElement.dataset) {
+ options[prop] = options[prop] || consoleElement.dataset[prop];
+ }
+
+ var replConsole = new REPLConsole(options);
replConsole.install(consoleElement);
return replConsole;
};
@@ -419,6 +478,26 @@
// It allows to operate the current session from the other scripts.
REPLConsole.currentSession = null;
+// This line is for the Firefox Add-on, because it doesn't have XMLHttpRequest
as default.
+// And so we need to require a module compatible with XMLHttpRequest from SDK.
+REPLConsole.XMLHttpRequest = typeof XMLHttpRequest === 'undefined' ? null :
XMLHttpRequest;
+
+REPLConsole.request = function request(method, url, params, callback) {
+ var xhr = new REPLConsole.XMLHttpRequest();
+
+ xhr.open(method, url, true);
+ xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ xhr.setRequestHeader("Accept", "<%= Mime[:web_console_v2] %>");
+ xhr.send(params);
+
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState === 4) {
+ callback(xhr);
+ }
+ };
+};
+
// DOM helpers
function hasClass(el, className) {
var regex = new RegExp('(?:^|\\s)' + className + '(?!\\S)', 'g');
@@ -470,28 +549,16 @@
}
// XHR helpers
-function request(method, url, params, callback) {
- var xhr = new XMLHttpRequest();
-
- xhr.open(method, url, true);
- xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
- xhr.setRequestHeader("Accept", "<%= Mime::WEB_CONSOLE_V2 %>");
- xhr.send(params);
-
- xhr.onreadystatechange = function() {
- if (xhr.readyState === 4) {
- callback(xhr);
- }
- }
+function postRequest() {
+ REPLConsole.request.apply(this, ["POST"].concat([].slice.call(arguments)));
}
-function postRequest(url, params, callback) {
- request("POST", url, params, callback);
+function putRequest() {
+ REPLConsole.request.apply(this, ["PUT"].concat([].slice.call(arguments)));
}
-function putRequest(url, params, callback) {
- request("PUT", url, params, callback);
+if (typeof exports === 'object') {
+ exports.REPLConsole = REPLConsole;
+} else {
+ window.REPLConsole = REPLConsole;
}
-
-window.REPLConsole = REPLConsole;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/templates/style.css.erb
new/lib/web_console/templates/style.css.erb
--- old/lib/web_console/templates/style.css.erb 2015-07-10 22:13:19.000000000
+0200
+++ new/lib/web_console/templates/style.css.erb 2015-12-13 17:58:49.000000000
+0100
@@ -10,6 +10,7 @@
.console .console-inner { font-family: monospace; font-size: 11px; width:
100%; height: 100%; overflow: none; background: #333; }
.console .console-prompt-box { color: #FFF; }
.console .console-message { color: #1AD027; margin: 0; border: 0; white-space:
pre-wrap; background-color: #333; padding: 0; }
+.console .console-message.error-message { color: #fc9; }
.console .console-focus .console-cursor { background: #FEFEFE; color: #333;
font-weight: bold; }
.console .resizer { background: #333; width: 100%; height: 4px; cursor:
ns-resize; }
.console .console-actions { padding-right: 3px; }
@@ -20,3 +21,7 @@
.console .clipboard { height: 0px; padding: 0px; margin: 0px; width: 0px;
margin-left: -1000px; }
.console .console-prompt-label { display: inline; color: #FFF; background:
none repeat scroll 0% 0% #333; border: 0; padding: 0; }
.console .console-prompt-display { display: inline; color: #FFF; background:
none repeat scroll 0% 0% #333; border: 0; padding: 0; }
+.console.full-screen { height: 100%; }
+.console.full-screen .console-outer { padding-top: 3px; }
+.console.full-screen .resizer { display: none; }
+.console.full-screen .close-button { display: none; }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/testing/erb_precompiler.rb
new/lib/web_console/testing/erb_precompiler.rb
--- old/lib/web_console/testing/erb_precompiler.rb 1970-01-01
01:00:00.000000000 +0100
+++ new/lib/web_console/testing/erb_precompiler.rb 2015-12-13
17:58:49.000000000 +0100
@@ -0,0 +1,25 @@
+require 'web_console/testing/helper'
+require 'web_console/testing/fake_middleware'
+
+module WebConsole
+ module Testing
+ # This class is to pre-compile 'templates/*.erb'.
+ class ERBPrecompiler
+ def initialize(path)
+ @erb = ERB.new(File.read(path))
+ @view = FakeMiddleware.new(
+ view_path: Helper.gem_root.join('lib/web_console/templates'),
+ ).view
+ end
+
+ def build
+ @erb.result(binding)
+ end
+
+ def method_missing(name, *args, &block)
+ return super unless @view.respond_to?(name)
+ @view.send(name, *args, &block)
+ end
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/testing/fake_middleware.rb
new/lib/web_console/testing/fake_middleware.rb
--- old/lib/web_console/testing/fake_middleware.rb 1970-01-01
01:00:00.000000000 +0100
+++ new/lib/web_console/testing/fake_middleware.rb 2015-12-13
17:58:49.000000000 +0100
@@ -0,0 +1,43 @@
+require 'action_view'
+require 'action_dispatch'
+require 'active_support/core_ext/string/access'
+require 'json'
+require 'web_console/whitelist'
+require 'web_console/request'
+require 'web_console/view'
+require 'web_console/testing/helper'
+
+module WebConsole
+ module Testing
+ class FakeMiddleware
+
I18n.load_path.concat(Dir[Helper.gem_root.join('lib/web_console/locales/*.yml')])
+
+ DEFAULT_HEADERS = { "Content-Type" => "application/javascript" }
+
+ def initialize(opts)
+ @headers = opts.fetch(:headers, DEFAULT_HEADERS)
+ @req_path_regex = opts[:req_path_regex]
+ @view_path = opts[:view_path]
+ end
+
+ def call(env)
+ [ 200, @headers, [ render(req_path(env)) ] ]
+ end
+
+ def view
+ @view ||= View.new(@view_path)
+ end
+
+ private
+
+ # extract target path from REQUEST_PATH
+ def req_path(env)
+ env["REQUEST_PATH"].match(@req_path_regex)[1]
+ end
+
+ def render(template)
+ view.render(template: template, layout: nil)
+ end
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/testing/helper.rb
new/lib/web_console/testing/helper.rb
--- old/lib/web_console/testing/helper.rb 1970-01-01 01:00:00.000000000
+0100
+++ new/lib/web_console/testing/helper.rb 2015-12-13 17:58:49.000000000
+0100
@@ -0,0 +1,9 @@
+module WebConsole
+ module Testing
+ module Helper
+ def self.gem_root
+ Pathname(File.expand_path('../../../../', __FILE__))
+ end
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/version.rb
new/lib/web_console/version.rb
--- old/lib/web_console/version.rb 2015-07-10 22:13:19.000000000 +0200
+++ new/lib/web_console/version.rb 2015-12-13 17:58:49.000000000 +0100
@@ -1,3 +1,3 @@
module WebConsole
- VERSION = '2.2.1'
+ VERSION = '3.0.0'
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/view.rb new/lib/web_console/view.rb
--- old/lib/web_console/view.rb 1970-01-01 01:00:00.000000000 +0100
+++ new/lib/web_console/view.rb 2015-12-13 17:58:49.000000000 +0100
@@ -0,0 +1,37 @@
+module WebConsole
+ class View < ActionView::Base
+ # Execute a block only on error pages.
+ #
+ # The error pages are special, because they are the only pages that
+ # currently require multiple bindings. We get those from exceptions.
+ def only_on_error_page(*args)
+ yield if @env['web_console.exception'].present?
+ end
+
+ # Render JavaScript inside a script tag and a closure.
+ #
+ # This one lets write JavaScript that will automatically get wrapped in a
+ # script tag and enclosed in a closure, so you don't have to worry for
+ # leaking globals, unless you explicitly want to.
+ def render_javascript(template)
+ render(template: template, layout: 'layouts/javascript')
+ end
+
+ # Render inlined string to be used inside of JavaScript code.
+ #
+ # The inlined string is returned as an actual JavaScript string. You
+ # don't need to wrap the result yourself.
+ def render_inlined_string(template)
+ render(template: template, layout: 'layouts/inlined_string')
+ end
+
+ # Override method for ActionView::Helpers::TranslationHelper#t.
+ #
+ # This method escapes the original return value for JavaScript, since the
+ # method returns a HTML tag with some attributes when the key is not found,
+ # so it could cause a syntax error if we use the value in the string
literals.
+ def t(key, options = {})
+ j super
+ end
+ end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console/whiny_request.rb
new/lib/web_console/whiny_request.rb
--- old/lib/web_console/whiny_request.rb 2015-07-10 22:13:19.000000000
+0200
+++ new/lib/web_console/whiny_request.rb 2015-12-13 17:58:49.000000000
+0100
@@ -4,20 +4,13 @@
# If any calls to +from_whitelisted_ip?+ and +acceptable_content_type?+
# return false, an info log message will be displayed in users' logs.
class WhinyRequest < SimpleDelegator
- def from_whitelited_ip?
- whine_unless request.from_whitelited_ip? do
- "Cannot render console from #{request.remote_ip}! " \
+ def from_whitelisted_ip?
+ whine_unless request.from_whitelisted_ip? do
+ "Cannot render console from #{request.strict_remote_ip}! " \
"Allowed networks: #{request.whitelisted_ips}"
end
end
- def acceptable_content_type?
- whine_unless request.acceptable_content_type? do
- "Cannot render console with content type #{request.content_type}" \
- "Allowed content types: #{request.acceptable_content_types}"
- end
- end
-
private
def whine_unless(condition)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/web_console.rb new/lib/web_console.rb
--- old/lib/web_console.rb 2015-07-10 22:13:19.000000000 +0200
+++ new/lib/web_console.rb 2015-12-13 17:58:49.000000000 +0100
@@ -1,5 +1,3 @@
-require 'binding_of_caller'
-
require 'active_support/lazy_load_hooks'
require 'active_support/logger'
@@ -13,6 +11,8 @@
require 'web_console/middleware'
require 'web_console/whitelist'
require 'web_console/request'
+require 'web_console/response'
+require 'web_console/view'
require 'web_console/whiny_request'
module WebConsole
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata 2015-07-10 22:13:19.000000000 +0200
+++ new/metadata 2015-12-13 17:58:49.000000000 +0100
@@ -1,7 +1,7 @@
--- !ruby/object:Gem::Specification
name: web-console
version: !ruby/object:Gem::Version
- version: 2.2.1
+ version: 3.0.0
platform: ruby
authors:
- Charlie Somerville
@@ -11,7 +11,7 @@
autorequire:
bindir: bin
cert_chain: []
-date: 2015-07-10 00:00:00.000000000 Z
+date: 2015-12-13 00:00:00.000000000 Z
dependencies:
- !ruby/object:Gem::Dependency
name: railties
@@ -19,90 +19,42 @@
requirements:
- - ">="
- !ruby/object:Gem::Version
- version: '4.0'
+ version: '4.2'
type: :runtime
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
- version: '4.0'
+ version: '4.2'
- !ruby/object:Gem::Dependency
name: activemodel
requirement: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
- version: '4.0'
+ version: '4.2'
type: :runtime
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
- version: '4.0'
+ version: '4.2'
- !ruby/object:Gem::Dependency
- name: sprockets-rails
+ name: debug_inspector
requirement: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
- version: '2.0'
- - - "<"
- - !ruby/object:Gem::Version
- version: '4.0'
+ version: '0'
type: :runtime
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
- version: '2.0'
- - - "<"
- - !ruby/object:Gem::Version
- version: '4.0'
-- !ruby/object:Gem::Dependency
- name: binding_of_caller
- requirement: !ruby/object:Gem::Requirement
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- version: 0.7.2
- type: :runtime
- prerelease: false
- version_requirements: !ruby/object:Gem::Requirement
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- version: 0.7.2
-- !ruby/object:Gem::Dependency
- name: actionmailer
- requirement: !ruby/object:Gem::Requirement
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- version: '4.0'
- type: :development
- prerelease: false
- version_requirements: !ruby/object:Gem::Requirement
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- version: '4.0'
-- !ruby/object:Gem::Dependency
- name: activerecord
- requirement: !ruby/object:Gem::Requirement
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- version: '4.0'
- type: :development
- prerelease: false
- version_requirements: !ruby/object:Gem::Requirement
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- version: '4.0'
+ version: '0'
description:
email:
- [email protected]
@@ -125,12 +77,15 @@
- lib/web_console/helper.rb
- lib/web_console/integration.rb
- lib/web_console/integration/cruby.rb
-- lib/web_console/integration/jruby.rb
- lib/web_console/integration/rubinius.rb
+- lib/web_console/locales/en.yml
- lib/web_console/middleware.rb
- lib/web_console/railtie.rb
- lib/web_console/request.rb
+- lib/web_console/response.rb
- lib/web_console/session.rb
+- lib/web_console/tasks/extensions.rake
+- lib/web_console/tasks/test_templates.rake
- lib/web_console/template.rb
- lib/web_console/templates/_inner_console_markup.html.erb
- lib/web_console/templates/_markup.html.erb
@@ -142,8 +97,12 @@
- lib/web_console/templates/layouts/javascript.erb
- lib/web_console/templates/main.js.erb
- lib/web_console/templates/style.css.erb
+- lib/web_console/testing/erb_precompiler.rb
+- lib/web_console/testing/fake_middleware.rb
+- lib/web_console/testing/helper.rb
- lib/web_console/tracer.rb
- lib/web_console/version.rb
+- lib/web_console/view.rb
- lib/web_console/whiny_request.rb
- lib/web_console/whitelist.rb
homepage: https://github.com/rails/web-console
@@ -158,7 +117,7 @@
requirements:
- - ">="
- !ruby/object:Gem::Version
- version: '0'
+ version: 2.2.2
required_rubygems_version: !ruby/object:Gem::Requirement
requirements:
- - ">="