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 - dims...@opensuse.org
+
+- 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 - co...@suse.com
+
+- 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:
 - char...@charliesomerville.com
@@ -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:
   - - ">="


Reply via email to