detection and use of local livereload if available
This commit is contained in:
parent
38a3396cf2
commit
92479fdaff
11
README.md
11
README.md
@ -41,11 +41,20 @@ use Rack::LiveReload, :min_delay => 500, ...
|
|||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
The necessary `script` tag to bring in a vendored copy of [livereload.js](https://github.com/livereload/livereload-js) is
|
The necessary `script` tag to bring in a copy of [livereload.js](https://github.com/livereload/livereload-js) is
|
||||||
injected right before the closing `head` tag in any `text/html` pages that come through. The `script` tag is built in
|
injected right before the closing `head` tag in any `text/html` pages that come through. The `script` tag is built in
|
||||||
such a way that the `HTTP_HOST` is used as the LiveReload host, so you can connect from external machines (say, to
|
such a way that the `HTTP_HOST` is used as the LiveReload host, so you can connect from external machines (say, to
|
||||||
`mycomputer:3000` instead of `localhost:3000`) and as long as the LiveReload port is accessible from the external machine,
|
`mycomputer:3000` instead of `localhost:3000`) and as long as the LiveReload port is accessible from the external machine,
|
||||||
you'll connect and be LiveReloading away!
|
you'll connect and be LiveReloading away!
|
||||||
|
|
||||||
|
### Which LiveReload script does it use?
|
||||||
|
|
||||||
|
* If you've got a LiveReload watcher running on the same machine as the app that responds
|
||||||
|
to `http://localhost:35729/livereload.js`, that gets used, with the hostname being changed when
|
||||||
|
injected into the HTML page.
|
||||||
|
* If you don't, the copy vendored with rack-livereload is used.
|
||||||
|
* You can force the use of either one (and save on the cost of checking to see if that file
|
||||||
|
is available) with the middleware option `:source => :vendored` or `:source => :livereload`.
|
||||||
|
|
||||||
As usual, super-alpha!
|
As usual, super-alpha!
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
module Rack
|
module Rack
|
||||||
class LiveReload
|
class LiveReload
|
||||||
LIVERELOAD_JS_PATH = '/__rack/livereload.js'
|
LIVERELOAD_JS_PATH = '/__rack/livereload.js'
|
||||||
|
LIVERELOAD_LOCAL_URI = 'http://localhost:35729/livereload.js'
|
||||||
|
|
||||||
attr_reader :app
|
attr_reader :app
|
||||||
|
|
||||||
@ -9,6 +10,31 @@ module Rack
|
|||||||
@options = options
|
@options = options
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def use_vendored?
|
||||||
|
return @use_vendored if @use_vendored
|
||||||
|
|
||||||
|
if @options[:source]
|
||||||
|
@use_vendored = (@options[:source] == :vendored)
|
||||||
|
else
|
||||||
|
require 'net/http'
|
||||||
|
require 'uri'
|
||||||
|
|
||||||
|
uri = URI.parse(LIVERELOAD_LOCAL_URI)
|
||||||
|
|
||||||
|
http = Net::HTTP.new(uri.host, uri.port)
|
||||||
|
http.read_timeout = 1
|
||||||
|
|
||||||
|
begin
|
||||||
|
http.send_request('GET', uri.path)
|
||||||
|
@use_vendored = false
|
||||||
|
rescue Timeout::Error, Errno::ECONNREFUSED
|
||||||
|
@use_vendored = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@use_vendored
|
||||||
|
end
|
||||||
|
|
||||||
def call(env)
|
def call(env)
|
||||||
if env['PATH_INFO'] == LIVERELOAD_JS_PATH
|
if env['PATH_INFO'] == LIVERELOAD_JS_PATH
|
||||||
deliver_file(::File.expand_path('../../../js/livereload.js', __FILE__))
|
deliver_file(::File.expand_path('../../../js/livereload.js', __FILE__))
|
||||||
@ -21,12 +47,14 @@ module Rack
|
|||||||
|
|
||||||
body.each do |line|
|
body.each do |line|
|
||||||
if !headers['X-Rack-LiveReload'] && line['</head>']
|
if !headers['X-Rack-LiveReload'] && line['</head>']
|
||||||
src = LIVERELOAD_JS_PATH.dup
|
host_to_use = @options[:host] || env['HTTP_HOST'].gsub(%r{:.*}, '')
|
||||||
if @options[:host]
|
|
||||||
src << "?host=#{@options[:host]}"
|
if use_vendored?
|
||||||
|
src = LIVERELOAD_JS_PATH.dup + "?host=#{host_to_use}"
|
||||||
else
|
else
|
||||||
src << "?host=#{env['HTTP_HOST'].gsub(%r{:.*}, '')}" if env['HTTP_HOST']
|
src = LIVERELOAD_LOCAL_URI.dup.gsub('localhost', host_to_use) + '?'
|
||||||
end
|
end
|
||||||
|
|
||||||
src << "&mindelay=#{@options[:min_delay]}" if @options[:min_delay]
|
src << "&mindelay=#{@options[:min_delay]}" if @options[:min_delay]
|
||||||
src << "&maxdelay=#{@options[:max_delay]}" if @options[:max_delay]
|
src << "&maxdelay=#{@options[:max_delay]}" if @options[:max_delay]
|
||||||
src << "&port=#{@options[:port]}" if @options[:port]
|
src << "&port=#{@options[:port]}" if @options[:port]
|
||||||
|
@ -28,6 +28,7 @@ Gem::Specification.new do |s|
|
|||||||
s.add_development_dependency "mocha"
|
s.add_development_dependency "mocha"
|
||||||
s.add_development_dependency "guard"
|
s.add_development_dependency "guard"
|
||||||
s.add_development_dependency "guard-rspec"
|
s.add_development_dependency "guard-rspec"
|
||||||
|
s.add_development_dependency "webmock"
|
||||||
|
|
||||||
s.add_runtime_dependency "rack"
|
s.add_runtime_dependency "rack"
|
||||||
end
|
end
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Rack::LiveReload do
|
describe Rack::LiveReload do
|
||||||
let(:middleware) { described_class.new(app) }
|
let(:middleware) { described_class.new(app, options) }
|
||||||
let(:app) { stub }
|
let(:app) { stub }
|
||||||
|
|
||||||
subject { middleware }
|
subject { middleware }
|
||||||
@ -9,6 +9,37 @@ describe Rack::LiveReload do
|
|||||||
its(:app) { should == app }
|
its(:app) { should == app }
|
||||||
|
|
||||||
let(:env) { {} }
|
let(:env) { {} }
|
||||||
|
let(:options) { {} }
|
||||||
|
|
||||||
|
describe described_class::LIVERELOAD_LOCAL_URI do
|
||||||
|
context 'does not exist' do
|
||||||
|
before do
|
||||||
|
stub_request(:any, 'localhost:35729/livereload.js').to_timeout
|
||||||
|
end
|
||||||
|
|
||||||
|
it { should use_vendored }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'exists' do
|
||||||
|
before do
|
||||||
|
stub_request(:any, 'localhost:35729/livereload.js')
|
||||||
|
end
|
||||||
|
|
||||||
|
it { should_not use_vendored }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'specify vendored' do
|
||||||
|
let(:options) { { :source => :vendored } }
|
||||||
|
|
||||||
|
it { should use_vendored }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'specify LR' do
|
||||||
|
let(:options) { { :source => :livereload } }
|
||||||
|
|
||||||
|
it { should_not use_vendored }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'not text/html' do
|
context 'not text/html' do
|
||||||
let(:ret) { [ 200, { 'Content-Type' => 'image/png' }, [ '<head></head>' ] ] }
|
let(:ret) { [ 200, { 'Content-Type' => 'image/png' }, [ '<head></head>' ] ] }
|
||||||
@ -25,6 +56,7 @@ describe Rack::LiveReload do
|
|||||||
context 'text/html' do
|
context 'text/html' do
|
||||||
before do
|
before do
|
||||||
app.stubs(:call).with(env).returns([ 200, { 'Content-Type' => 'text/html', 'Content-Length' => 0 }, [ '<head></head>' ] ])
|
app.stubs(:call).with(env).returns([ 200, { 'Content-Type' => 'text/html', 'Content-Length' => 0 }, [ '<head></head>' ] ])
|
||||||
|
middleware.stubs(:use_vendored?).returns(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:host) { 'host' }
|
let(:host) { 'host' }
|
||||||
@ -34,13 +66,26 @@ describe Rack::LiveReload do
|
|||||||
let(:body) { ret.last.join }
|
let(:body) { ret.last.join }
|
||||||
let(:length) { ret[1]['Content-Length'] }
|
let(:length) { ret[1]['Content-Length'] }
|
||||||
|
|
||||||
it 'should add the livereload js script tag' do
|
context 'vendored' do
|
||||||
body.should include("script")
|
it 'should add the vendored livereload js script tag' do
|
||||||
body.should include(described_class::LIVERELOAD_JS_PATH)
|
body.should include("script")
|
||||||
|
body.should include(described_class::LIVERELOAD_JS_PATH)
|
||||||
|
|
||||||
length.should == body.length.to_s
|
length.should == body.length.to_s
|
||||||
|
|
||||||
described_class::LIVERELOAD_JS_PATH.should_not include(host)
|
described_class::LIVERELOAD_JS_PATH.should_not include(host)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'not vendored' do
|
||||||
|
before do
|
||||||
|
middleware.stubs(:use_vendored?).returns(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should add the LR livereload js script tag' do
|
||||||
|
body.should include("script")
|
||||||
|
body.should include(described_class::LIVERELOAD_LOCAL_URI.gsub('localhost', 'host'))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'set options' do
|
context 'set options' do
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
require 'mocha'
|
require 'mocha'
|
||||||
|
require 'webmock/rspec'
|
||||||
|
|
||||||
require 'rack-livereload'
|
require 'rack-livereload'
|
||||||
|
|
||||||
RSpec.configure do |c|
|
RSpec.configure do |c|
|
||||||
c.mock_with :mocha
|
c.mock_with :mocha
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module RSpec::Matchers
|
||||||
|
define :use_vendored do
|
||||||
|
match do |subject|
|
||||||
|
subject.use_vendored?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user