rack-unscripted 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +76 -0
- data/Rakefile +2 -0
- data/lib/rack-unscripted.rb +1 -0
- data/lib/rack/unscripted.rb +78 -0
- data/lib/version.rb +5 -0
- data/rack-unscripted.gemspec +40 -0
- data/test/unscripted_test.rb +69 -0
- metadata +109 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2011 Casey Dreier.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
= Rack::Unscripted
|
2
|
+
|
3
|
+
This is a small piece of Rack middleware that will append a message to your HTML warning a user that they need to enable JavaScript in order to properly view your site.
|
4
|
+
|
5
|
+
The Rack middleware will append a <tt><div></tt> right after the opening body tag, but hide it via a CSS directive that is written by JavaScript in the <tt><head></tt> section. This prevents any flashing that can happen by merely hiding the element via JS directly. We don't use the <tt><noscript></tt> tag since it has spotty support and doesn't work when a user is using a browser plugin to whitelist JS on certain sites.
|
6
|
+
|
7
|
+
The div that is created can be referenced in CSS the the id, <tt>rack-unscripted-no-javascript-warning</tt>, so you can style this warning (when it does get displayed) to your heart's content.
|
8
|
+
|
9
|
+
== Example
|
10
|
+
|
11
|
+
Original HTML:
|
12
|
+
|
13
|
+
<html>
|
14
|
+
<head>
|
15
|
+
<title>The Bucket of Truth</title>
|
16
|
+
</head>
|
17
|
+
<body>
|
18
|
+
...stuff!...
|
19
|
+
</body>
|
20
|
+
</html>
|
21
|
+
|
22
|
+
HTML with Rack::Unscripted enabled:
|
23
|
+
|
24
|
+
<html>
|
25
|
+
<head>
|
26
|
+
<title>The Bucket of Truth</title>
|
27
|
+
<script type="text/javascript">
|
28
|
+
document.write('<style>.rack-unscripted-no-javascript-warning { display:none }</style>');
|
29
|
+
</script>
|
30
|
+
</head>
|
31
|
+
<body>
|
32
|
+
<div id='rack-unscripted-no-javascript-warning'>
|
33
|
+
Warning, this site requires JavaScript to function properly. Please enable it.
|
34
|
+
</div>
|
35
|
+
...stuff!...
|
36
|
+
</body>
|
37
|
+
</html>
|
38
|
+
|
39
|
+
== Installation
|
40
|
+
|
41
|
+
Make sure to install this gem:
|
42
|
+
|
43
|
+
gem install rack-unscripted
|
44
|
+
|
45
|
+
or, add the following to your Gemfile:
|
46
|
+
|
47
|
+
gem 'rack-unscripted'
|
48
|
+
|
49
|
+
Then you need to configure your middleware stack to use this library.
|
50
|
+
|
51
|
+
== Usage
|
52
|
+
|
53
|
+
use Rack::Unscripted
|
54
|
+
|
55
|
+
or
|
56
|
+
|
57
|
+
use Rack::Unscripted, "Custom warning message to users without JavaScript enabled."
|
58
|
+
|
59
|
+
== Example Configuration
|
60
|
+
|
61
|
+
=== Rails 3.x
|
62
|
+
|
63
|
+
In config/initializers/rack_unscripted.rb
|
64
|
+
|
65
|
+
MyApplicationName::Application.config.middleware use "Rack::Unscripted"
|
66
|
+
|
67
|
+
=== Rails 2.3.x
|
68
|
+
|
69
|
+
In config/environment.rb
|
70
|
+
|
71
|
+
config.middleware.use "Rack::Unscripted"
|
72
|
+
|
73
|
+
=== Sinatra
|
74
|
+
|
75
|
+
require 'rack/unscripted'
|
76
|
+
use Rack::Unscripted
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'rack/unscripted'
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Rack
|
2
|
+
class Unscripted
|
3
|
+
def initialize(app, warning_message = nil)
|
4
|
+
self.warning_message = warning_message if warning_message
|
5
|
+
@app = app
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
@status, @headers, @response = @app.call(env)
|
10
|
+
if valid_content_type?(@headers['Content-Type']) && valid_status?(@status)
|
11
|
+
@response.each do |response_line|
|
12
|
+
insert_js(response_line) if response_line =~ head_regex
|
13
|
+
insert_html(response_line) if response_line =~ body_regex
|
14
|
+
end
|
15
|
+
end
|
16
|
+
[@status, @headers, @response]
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
attr_writer :warning_message
|
22
|
+
|
23
|
+
def insert_js(response_line)
|
24
|
+
add_to_content_length(inline_code.length)
|
25
|
+
response_line.sub!(head_regex, inline_code + '\1')
|
26
|
+
end
|
27
|
+
|
28
|
+
# Inserts HTML of javascript warning after the opening body tag.
|
29
|
+
def insert_html(response_line)
|
30
|
+
add_to_content_length(no_javascript_warning.length)
|
31
|
+
response_line.sub!(body_regex, '\1'+ no_javascript_warning)
|
32
|
+
end
|
33
|
+
|
34
|
+
def no_javascript_warning
|
35
|
+
"<div id='rack-unscripted-no-javascript-warning'>#{warning_message}</div>"
|
36
|
+
end
|
37
|
+
|
38
|
+
def inline_code
|
39
|
+
<<-END
|
40
|
+
<script type="text/javascript">document.write('<style>#rack-unscripted-no-javascript-warning{display:none;}</style>');</script>
|
41
|
+
END
|
42
|
+
end
|
43
|
+
|
44
|
+
# Regular Expression to find the opening body tag.
|
45
|
+
def body_regex
|
46
|
+
/(<\s*body[^>]*>)/i
|
47
|
+
end
|
48
|
+
|
49
|
+
# Regular expression to find the closing </head> tag in a document.
|
50
|
+
def head_regex
|
51
|
+
/(<\s*\/head[^>]*>)/i
|
52
|
+
end
|
53
|
+
|
54
|
+
# Appends the given number to the current content length in the headers.
|
55
|
+
def add_to_content_length(number)
|
56
|
+
if @headers['Content-Length']
|
57
|
+
@headers['Content-Length'] = (@headers['Content-Length'].to_i + number.to_i).to_s
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns +true+ if the content type is text/html. No need to add this message
|
62
|
+
# to any other types of content.
|
63
|
+
def valid_content_type?(content_type)
|
64
|
+
content_type.respond_to?(:include?) && content_type.include?("text/html")
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns +true+ if the HTTP response code is such that we should append this warning message.
|
68
|
+
def valid_status?(response_code)
|
69
|
+
[200, 404].include? response_code.to_i
|
70
|
+
end
|
71
|
+
|
72
|
+
# Attribute reader for the warning message. Sets a default value.
|
73
|
+
def warning_message
|
74
|
+
@warning_message ||= 'Warning, this site requires javascript to function properly. Please enable it.'
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
data/lib/version.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# $:.push File.expand_path("lib", __FILE__)
|
3
|
+
require File.expand_path('../lib/version.rb', __FILE__)
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "rack-unscripted"
|
6
|
+
s.version = Rack::Unscripted::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Casey Dreier"]
|
9
|
+
s.email = ["casey.dreier@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/daphonz/rack-unscripted"
|
11
|
+
s.summary = %q{Rack middleware to add a textual warning to your site for users who have Javascript disabled.}
|
12
|
+
s.description = %q{Many sites these days absolutely require a user to have Javascript enabled in order to function properly. You may have one yourself. Users that either have JS disabled or only allow trusted sites to execute JS should be given a textual warning that their user experience may be hampered.
|
13
|
+
|
14
|
+
This Rack middleware will append a div with a customizable message to the HTTP response body, right after the opening <body> tag. This warning message is then hidden via a CSS command that is written by Javascript.
|
15
|
+
}
|
16
|
+
|
17
|
+
s.rubyforge_project = "rack-unscripted"
|
18
|
+
s.extra_rdoc_files = ['README.rdoc']
|
19
|
+
s.license = 'MIT'
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test}/*`.split("\n")
|
22
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
|
25
|
+
s.add_development_dependency('rack-test')
|
26
|
+
|
27
|
+
if s.respond_to? :specification_version then
|
28
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
29
|
+
s.specification_version = 3
|
30
|
+
|
31
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
32
|
+
s.add_runtime_dependency(%q<rack>, [">= 1.0"])
|
33
|
+
else
|
34
|
+
s.add_dependency(%q<rack>, [">= 1.0"])
|
35
|
+
end
|
36
|
+
else
|
37
|
+
s.add_dependency(%q<rack>, [">= 1.0"])
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rack/test'
|
3
|
+
require 'test/unit'
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/rack/unscripted')
|
5
|
+
|
6
|
+
class Rack::UnscriptedTest < Test::Unit::TestCase
|
7
|
+
include Rack::Test::Methods
|
8
|
+
|
9
|
+
def app
|
10
|
+
@other_app ||= other_app
|
11
|
+
@custom_warning_message ||= nil
|
12
|
+
Rack::Unscripted.new(@other_app, @custom_warning_message)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_inline_js_added
|
16
|
+
get '/'
|
17
|
+
assert last_response.body.include?(app.send(:inline_code) + '</head>')
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_default_warning_message_added_to_response_body
|
21
|
+
get '/'
|
22
|
+
assert last_response.body.include?("<body class=\"such-and-such\">" + app.send(:no_javascript_warning))
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_custom_message_added_to_response_body
|
26
|
+
@custom_warning_message = "¡Se necissita activar JavaScript!"
|
27
|
+
get '/'
|
28
|
+
assert last_response.body.include?(@custom_warning_message)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_content_length_is_increased
|
32
|
+
get '/'
|
33
|
+
expected = app.send(:inline_code).length + app.send(:no_javascript_warning).length + test_page_html.length
|
34
|
+
assert_equal expected, last_response.headers['Content-Length'].to_i
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_takes_no_action_on_non_html_content_type
|
38
|
+
json = "{\"success\":\"success\"}"
|
39
|
+
@other_app = other_app(200, {'Content-Type' => 'application/json', 'Content-Length' => json.length.to_s}, Rack::Response.new(json))
|
40
|
+
get '/'
|
41
|
+
assert_equal json.length, last_response.headers['Content-Length'].to_i
|
42
|
+
assert_equal json, last_response.body
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_takes_no_action_on_non_200_or_404_status_responses
|
46
|
+
# Obviously, this isn't all possible responses, but you get the idea.
|
47
|
+
[204, 302, 406, 500].each do |status|
|
48
|
+
@other_app = other_app(status)
|
49
|
+
get '/'
|
50
|
+
assert_equal test_page_html.length, last_response.headers['Content-Length'].to_i
|
51
|
+
assert_equal test_page_html, last_response.body
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def other_app(status = 200, headers = nil, response = nil)
|
58
|
+
headers = {'Content-Type' => 'text/html', 'Content-Length' => test_page_html.length.to_s} unless headers
|
59
|
+
response = Rack::Response.new(test_page_html) unless response
|
60
|
+
Proc.new do |env|
|
61
|
+
[status, headers, response]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_page_html
|
66
|
+
'<html><head></head><body class="such-and-such"><p>The Bucket of Truth</p></body></html>'
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-unscripted
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Casey Dreier
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-05-07 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rack-test
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rack
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 15
|
44
|
+
segments:
|
45
|
+
- 1
|
46
|
+
- 0
|
47
|
+
version: "1.0"
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id002
|
50
|
+
description: |
|
51
|
+
Many sites these days absolutely require a user to have Javascript enabled in order to function properly. You may have one yourself. Users that either have JS disabled or only allow trusted sites to execute JS should be given a textual warning that their user experience may be hampered.
|
52
|
+
|
53
|
+
This Rack middleware will append a div with a customizable message to the HTTP response body, right after the opening <body> tag. This warning message is then hidden via a CSS command that is written by Javascript.
|
54
|
+
|
55
|
+
email:
|
56
|
+
- casey.dreier@gmail.com
|
57
|
+
executables: []
|
58
|
+
|
59
|
+
extensions: []
|
60
|
+
|
61
|
+
extra_rdoc_files:
|
62
|
+
- README.rdoc
|
63
|
+
files:
|
64
|
+
- .gitignore
|
65
|
+
- Gemfile
|
66
|
+
- MIT-LICENSE
|
67
|
+
- README.rdoc
|
68
|
+
- Rakefile
|
69
|
+
- lib/rack-unscripted.rb
|
70
|
+
- lib/rack/unscripted.rb
|
71
|
+
- lib/version.rb
|
72
|
+
- rack-unscripted.gemspec
|
73
|
+
- test/unscripted_test.rb
|
74
|
+
has_rdoc: true
|
75
|
+
homepage: https://github.com/daphonz/rack-unscripted
|
76
|
+
licenses:
|
77
|
+
- MIT
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
hash: 3
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
version: "0"
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
hash: 3
|
98
|
+
segments:
|
99
|
+
- 0
|
100
|
+
version: "0"
|
101
|
+
requirements: []
|
102
|
+
|
103
|
+
rubyforge_project: rack-unscripted
|
104
|
+
rubygems_version: 1.6.2
|
105
|
+
signing_key:
|
106
|
+
specification_version: 3
|
107
|
+
summary: Rack middleware to add a textual warning to your site for users who have Javascript disabled.
|
108
|
+
test_files: []
|
109
|
+
|