Inject js code only into valid html head tags

This commit is contained in:
Nathan Hoel 2014-12-05 11:23:31 -05:00
parent 952ea670dd
commit 2ddc4296dd
6 changed files with 28 additions and 34 deletions

View File

@ -4,7 +4,6 @@ module Rack
class LiveReload class LiveReload
class BodyProcessor class BodyProcessor
LIVERELOAD_JS_PATH = '/__rack/livereload.js' LIVERELOAD_JS_PATH = '/__rack/livereload.js'
HEAD_TAG_REGEX = /<head>|<head[^(er)][^<]*>/
LIVERELOAD_PORT = 35729 LIVERELOAD_PORT = 35729
attr_reader :content_length, :new_body, :livereload_added attr_reader :content_length, :new_body, :livereload_added
@ -63,22 +62,20 @@ module Rack
def process!(env) def process!(env)
@env = env @env = env
@body.close if @body.respond_to?(:close) @body.close if @body.respond_to?(:close)
@string_body = '' ; @body.each { |line| @string_body += line.to_s }
@new_body = [] ; @body.each { |line| @new_body << line.to_s } xmlfragment = Nokogiri::XML.fragment(@string_body)
head_elements = xmlfragment.xpath('./html/head|./head')
@content_length = 0 head_elements.each do |head|
@livereload_added = false head.inner_html = "#{template.result(binding)}\n #{head.inner_html}"
@new_body.each do |line|
if !@livereload_added && line['<head']
line.gsub!(HEAD_TAG_REGEX) { |match| %{#{match}#{template.result(binding)}} }
@livereload_added = true
end
@content_length += line.bytesize
@processed = true
end end
@string_body = xmlfragment.to_s
@content_length = @string_body.bytesize()
@livereload_added = true if head_elements.length > 0
@processed = true
@new_body = [@string_body]
end end
def app_root def app_root

View File

@ -21,6 +21,7 @@ Gem::Specification.new do |s|
# specify any dependencies here; for example: # specify any dependencies here; for example:
s.add_development_dependency "rspec" s.add_development_dependency "rspec"
s.add_development_dependency "rspec-its"
s.add_development_dependency "cucumber" s.add_development_dependency "cucumber"
s.add_development_dependency "httparty" s.add_development_dependency "httparty"
s.add_development_dependency "sinatra" s.add_development_dependency "sinatra"

View File

@ -2,23 +2,6 @@ require 'spec_helper'
require 'nokogiri' require 'nokogiri'
describe Rack::LiveReload::BodyProcessor do describe Rack::LiveReload::BodyProcessor do
describe 'head tag regex' do
let(:regex) { described_class::HEAD_TAG_REGEX }
subject { regex }
it { should be_kind_of(Regexp) }
it 'only picks a valid <head> tag' do
regex.match("<head></head>").to_s.should eq('<head>')
regex.match("<head><title></title></head>").to_s.should eq('<head>')
regex.match("<head attribute='something'><title></title></head>").to_s.should eq("<head attribute='something'>")
end
it 'responds false when no head tag' do
regex.match("<header></header>").should be_false
end
end
let(:processor) { described_class.new(body, options) } let(:processor) { described_class.new(body, options) }
let(:body) { [ page_html ] } let(:body) { [ page_html ] }
let(:options) { {} } let(:options) { {} }
@ -143,6 +126,14 @@ describe Rack::LiveReload::BodyProcessor do
end end
end end
context 'in html content areas' do
let(:page_html) { "<script type='text/template'><head></head></script> <!-- <head></head> --> <xmp><head></head></xmp>" }
it 'should not add the livereload js' do
processed_body.should == "<script type=\"text/template\">\n <head/>\n</script> <!-- <head></head> --> <xmp>\n <head/>\n</xmp>"
end
end
context 'not vendored' do context 'not vendored' do
before do before do
processor.stubs(:use_vendored?).returns(false) processor.stubs(:use_vendored?).returns(false)

View File

@ -14,7 +14,7 @@ describe Rack::LiveReload::ProcessingSkipAnalyzer do
describe '#skip_processing?' do describe '#skip_processing?' do
it "should skip processing" do it "should skip processing" do
subject.skip_processing?.should be_true subject.skip_processing?.should be_truthy
end end
end end

View File

@ -20,7 +20,7 @@ describe Rack::LiveReload do
end end
it 'should return the js file' do it 'should return the js file' do
middleware._call(env).should be_true middleware._call(env).should be_truthy
end end
end end
end end

View File

@ -1,9 +1,14 @@
require 'mocha/api' require 'mocha/api'
require 'webmock/rspec' require 'webmock/rspec'
require 'rspec/its'
require 'rack-livereload' require 'rack-livereload'
RSpec.configure do |c| RSpec.configure do |c|
c.expect_with :rspec do |config|
config.syntax = :should
end
c.mock_with :mocha c.mock_with :mocha
end end