condensation 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +12 -0
- data/condensation.gemspec +22 -0
- data/lib/condensation/filters/default.rb +10 -0
- data/lib/condensation/filters/hyperlink.rb +12 -0
- data/lib/condensation/filters/replace_inner_html.rb +12 -0
- data/lib/condensation/filters.rb +3 -0
- data/lib/condensation/sanitizer.rb +13 -0
- data/lib/condensation/version.rb +3 -0
- data/lib/condensation.rb +17 -0
- data/spec/condensation/filters/default_spec.rb +45 -0
- data/spec/condensation/filters/hyperlink_spec.rb +52 -0
- data/spec/condensation/filters/replace_inner_html_spec.rb +43 -0
- data/spec/condensation/sanitizer_spec.rb +11 -0
- data/spec/condensation_spec.rb +7 -0
- data/spec/spec_helper.rb +6 -0
- metadata +103 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Derrick Reimer
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Condensation
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'condensation'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install condensation
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'condensation/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "condensation"
|
8
|
+
gem.version = Condensation::VERSION
|
9
|
+
gem.authors = ["Derrick Reimer"]
|
10
|
+
gem.email = ["derrickreimer@gmail.com"]
|
11
|
+
gem.description = %q{A collection of handy extensions to the Liquid templating language}
|
12
|
+
gem.summary = %q{Condensation is a collection of handy extensions to the Liquid templating language}
|
13
|
+
gem.homepage = "https://github.com/djreimer/condensation"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency "liquid", "~> 2.0"
|
21
|
+
gem.add_development_dependency "shoulda-context", "~> 1.0"
|
22
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Condensation
|
2
|
+
module Filters
|
3
|
+
module Hyperlink
|
4
|
+
def hyperlink(input, text = nil)
|
5
|
+
return if input.nil?
|
6
|
+
input = Sanitizer.new(input.to_s).escape_html
|
7
|
+
text = text ? Sanitizer.new(text).escape_html : input
|
8
|
+
"<a href='#{input}'>#{text}</a>"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/condensation.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "liquid"
|
2
|
+
require "condensation/sanitizer"
|
3
|
+
require "condensation/filters"
|
4
|
+
require "condensation/version"
|
5
|
+
|
6
|
+
module Condensation
|
7
|
+
FILTERS = [
|
8
|
+
Filters::Default,
|
9
|
+
Filters::ReplaceInnerHTML
|
10
|
+
]
|
11
|
+
|
12
|
+
def register_filters
|
13
|
+
FILTERS.each do |filter|
|
14
|
+
Liquid::Template.register_filter(filter)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
2
|
+
|
3
|
+
describe Condensation::Filters::Default do
|
4
|
+
def render_with_filter(template, context)
|
5
|
+
template.render(context, :filters => [Condensation::Filters::Default])
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "#default" do
|
9
|
+
it "should return input if it is not blank" do
|
10
|
+
template = Liquid::Template.parse("{{ name | default: 'Bar' }}")
|
11
|
+
result = render_with_filter(template, { "name" => "Foo" })
|
12
|
+
result.must_equal "Foo"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return default value if input is nil" do
|
16
|
+
template = Liquid::Template.parse("{{ name | default: 'Bar' }}")
|
17
|
+
result = render_with_filter(template, { "name" => nil })
|
18
|
+
result.must_equal "Bar"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return default value if input is an empty string" do
|
22
|
+
template = Liquid::Template.parse("{{ name | default: 'Bar' }}")
|
23
|
+
result = render_with_filter(template, { "name" => "" })
|
24
|
+
result.must_equal "Bar"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return default value if input is an empty hash" do
|
28
|
+
template = Liquid::Template.parse("{{ name | default: 'Bar' }}")
|
29
|
+
result = render_with_filter(template, { "name" => {} })
|
30
|
+
result.must_equal "Bar"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return default value if input is an empty array" do
|
34
|
+
template = Liquid::Template.parse("{{ name | default: 'Bar' }}")
|
35
|
+
result = render_with_filter(template, { "name" => [] })
|
36
|
+
result.must_equal "Bar"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should return default value if input is false" do
|
40
|
+
template = Liquid::Template.parse("{{ name | default: 'Bar' }}")
|
41
|
+
result = render_with_filter(template, { "name" => false })
|
42
|
+
result.must_equal "Bar"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
2
|
+
|
3
|
+
describe Condensation::Filters::Hyperlink do
|
4
|
+
def render_with_filter(template, context)
|
5
|
+
template.render(context, :filters => [Condensation::Filters::Hyperlink])
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "#hyperlink" do
|
9
|
+
it "should use the URL as the anchor text if none provided" do
|
10
|
+
url = "http://www.example.com"
|
11
|
+
template = Liquid::Template.parse("{{ url | hyperlink }}")
|
12
|
+
result = render_with_filter(template, { "url" => url })
|
13
|
+
result.must_equal "<a href='#{url}'>#{url}</a>"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should use the provided anchor text" do
|
17
|
+
url = "http://www.example.com"
|
18
|
+
template = Liquid::Template.parse("{{ url | hyperlink: 'Click here!' }}")
|
19
|
+
result = render_with_filter(template, { "url" => url })
|
20
|
+
result.must_equal "<a href='#{url}'>Click here!</a>"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should escape HTML in the URL" do
|
24
|
+
url = "<script>attack.me()</script>"
|
25
|
+
escaped = "<script>attack.me()</script>"
|
26
|
+
template = Liquid::Template.parse("{{ url | hyperlink }}")
|
27
|
+
result = render_with_filter(template, { "url" => url })
|
28
|
+
result.must_equal "<a href='#{escaped}'>#{escaped}</a>"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should escape HTML in the anchor text" do
|
32
|
+
url = "http://www.example.com"
|
33
|
+
text = "<script>attack.me()</script>"
|
34
|
+
escaped = "<script>attack.me()</script>"
|
35
|
+
template = Liquid::Template.parse("{{ url | hyperlink: '#{text}' }}")
|
36
|
+
result = render_with_filter(template, { "url" => url })
|
37
|
+
result.must_equal "<a href='#{url}'>#{escaped}</a>"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return empty string if input is nil" do
|
41
|
+
template = Liquid::Template.parse("{{ url | hyperlink }}")
|
42
|
+
result = render_with_filter(template, {})
|
43
|
+
result.must_equal ""
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should handle numeric input" do
|
47
|
+
template = Liquid::Template.parse("{{ url | hyperlink: 'Bar' }}")
|
48
|
+
result = render_with_filter(template, { "url" => 1 })
|
49
|
+
result.must_equal "<a href='1'>Bar</a>"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
2
|
+
|
3
|
+
describe Condensation::Filters::ReplaceInnerHTML do
|
4
|
+
def render_with_filter(template, context)
|
5
|
+
template.render(context, :filters => [Condensation::Filters::ReplaceInnerHTML])
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "#replace_inner_html" do
|
9
|
+
it "should replace the inner content of a given HTML tag" do
|
10
|
+
tag = "<a href='http://www.example.com'>Foo</a>"
|
11
|
+
template = Liquid::Template.parse("{{ example_link | replace_inner_html: 'Bar' }}")
|
12
|
+
result = render_with_filter(template, { "example_link" => tag })
|
13
|
+
result.must_equal "<a href='http://www.example.com'>Bar</a>"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should not alter malformed input" do
|
17
|
+
tags = [
|
18
|
+
"< a href='http://www.example.com'>Foo</a>",
|
19
|
+
"<a href='http://www.example.com'>Foo< /a>",
|
20
|
+
"<a href='http://www.example.com'>Foo",
|
21
|
+
" <a href='http://www.example.com'>Foo</a> "
|
22
|
+
]
|
23
|
+
|
24
|
+
tags.each do |tag|
|
25
|
+
template = Liquid::Template.parse("{{ example_link | replace_inner_html: 'Bar' }}")
|
26
|
+
result = render_with_filter(template, { "example_link" => tag })
|
27
|
+
result.must_equal tag
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should return empty string if input is nil" do
|
32
|
+
template = Liquid::Template.parse("{{ example_link | replace_inner_html: 'Bar' }}")
|
33
|
+
result = render_with_filter(template, {})
|
34
|
+
result.must_equal ""
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should handle numeric input" do
|
38
|
+
template = Liquid::Template.parse("{{ example_link | replace_inner_html: 'Bar' }}")
|
39
|
+
result = render_with_filter(template, { "example_link" => 1 })
|
40
|
+
result.must_equal "1"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
describe Condensation::Sanitizer do
|
4
|
+
describe "#escape_html" do
|
5
|
+
it "should escape HTML entities" do
|
6
|
+
html = "<div><a href='http://foo.bar/?x=r%20b&y=z'>Baz</a></div>"
|
7
|
+
escaped = "<div><a href='http://foo.bar/?x=r%20b&y=z'>Baz</a></div>"
|
8
|
+
Condensation::Sanitizer.new(html).escape_html.must_equal(escaped)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: condensation
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Derrick Reimer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-10-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: liquid
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: shoulda-context
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.0'
|
46
|
+
description: A collection of handy extensions to the Liquid templating language
|
47
|
+
email:
|
48
|
+
- derrickreimer@gmail.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- Gemfile
|
55
|
+
- LICENSE.txt
|
56
|
+
- README.md
|
57
|
+
- Rakefile
|
58
|
+
- condensation.gemspec
|
59
|
+
- lib/condensation.rb
|
60
|
+
- lib/condensation/filters.rb
|
61
|
+
- lib/condensation/filters/default.rb
|
62
|
+
- lib/condensation/filters/hyperlink.rb
|
63
|
+
- lib/condensation/filters/replace_inner_html.rb
|
64
|
+
- lib/condensation/sanitizer.rb
|
65
|
+
- lib/condensation/version.rb
|
66
|
+
- spec/condensation/filters/default_spec.rb
|
67
|
+
- spec/condensation/filters/hyperlink_spec.rb
|
68
|
+
- spec/condensation/filters/replace_inner_html_spec.rb
|
69
|
+
- spec/condensation/sanitizer_spec.rb
|
70
|
+
- spec/condensation_spec.rb
|
71
|
+
- spec/spec_helper.rb
|
72
|
+
homepage: https://github.com/djreimer/condensation
|
73
|
+
licenses: []
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 1.8.23
|
93
|
+
signing_key:
|
94
|
+
specification_version: 3
|
95
|
+
summary: Condensation is a collection of handy extensions to the Liquid templating
|
96
|
+
language
|
97
|
+
test_files:
|
98
|
+
- spec/condensation/filters/default_spec.rb
|
99
|
+
- spec/condensation/filters/hyperlink_spec.rb
|
100
|
+
- spec/condensation/filters/replace_inner_html_spec.rb
|
101
|
+
- spec/condensation/sanitizer_spec.rb
|
102
|
+
- spec/condensation_spec.rb
|
103
|
+
- spec/spec_helper.rb
|