deface 0.1.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/MIT-LICENSE +20 -0
- data/README.markdown +80 -0
- data/Rakefile +41 -0
- data/VERSION +1 -0
- data/deface.gemspec +56 -0
- data/init.rb +1 -0
- data/lib/deface.rb +5 -0
- data/lib/deface/action_view_extensions.rb +34 -0
- data/lib/deface/override.rb +106 -0
- data/lib/deface/parser.rb +90 -0
- data/spec/deface/override_spec.rb +106 -0
- data/spec/deface/parser_spec.rb +49 -0
- data/spec/deface/template_spec.rb +75 -0
- data/spec/spec_helper.rb +5 -0
- metadata +114 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Brian Quinn
|
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.markdown
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
Deface
|
2
|
+
======
|
3
|
+
|
4
|
+
Deface is a library that allows you to customize ERB views in a Rails application without editing the underlying view.
|
5
|
+
|
6
|
+
It allows you to easily target html & erb elements as the hooks for customization using both CSS and XPath selectors as supported by Nokogiri.
|
7
|
+
|
8
|
+
Deface temporarily converts ERB files into a pseudo HTML markup that can be parsed and queired by Nokogiri, using the following approach:
|
9
|
+
|
10
|
+
<%= some ruby code %>
|
11
|
+
|
12
|
+
becomes
|
13
|
+
|
14
|
+
<erb-loud> some ruby code </erb-loud>
|
15
|
+
|
16
|
+
and
|
17
|
+
|
18
|
+
<% other ruby code %>
|
19
|
+
|
20
|
+
becomes
|
21
|
+
|
22
|
+
<erb-silent> other ruby code </erb-silent>
|
23
|
+
|
24
|
+
Deface overrides have full access to all variables accessible to the view being customized.
|
25
|
+
|
26
|
+
Deface::Override
|
27
|
+
=======
|
28
|
+
|
29
|
+
A new instance of the Deface::Override class is initialized for each customization you wish to define. When initializing a new override you must supply only one Target, Action & Source parameter and any number of Optional parameters. Note, the source parameter is not required when the "remove" action is specified.
|
30
|
+
|
31
|
+
Target
|
32
|
+
------
|
33
|
+
* <tt>:file_path</tt> - The relative file path of the template / partial where the override should take effect eg: *"shared/_person"*, *"admin/posts/new"* this will apply to all controller actions that use the specified template.
|
34
|
+
|
35
|
+
* <tt>:virtual_path</tt> - The controller and action name where the override should take effect eg: *"controller/action"* or *"posts/index"* will apply to all layouts, templates and partials that are used in the rendering of the specified action.
|
36
|
+
|
37
|
+
Action
|
38
|
+
------
|
39
|
+
* <tt>:remove</tt> - Removes all elements that match the supplied selector
|
40
|
+
|
41
|
+
* <tt>:replace</tt> - Replaces all elements that match the supplied selector
|
42
|
+
|
43
|
+
* <tt>:insert_after</tt> - Inserts after all elements that match the supplied selector
|
44
|
+
|
45
|
+
* <tt>:insert_before</tt> - Inserts before all elements that match the supplied selector
|
46
|
+
|
47
|
+
Source
|
48
|
+
------
|
49
|
+
* <tt>:text</tt> - String containing markup
|
50
|
+
|
51
|
+
* <tt>:partial</tt> - Relative path to a partial
|
52
|
+
|
53
|
+
* <tt>:template</tt> - Relative path to a template
|
54
|
+
|
55
|
+
Optional
|
56
|
+
--------
|
57
|
+
* <tt>:name</tt> - Unique name for override so it can be identified and modified later. This needs to be unique within the same `:virtual_path` or `:file_path`
|
58
|
+
|
59
|
+
Examples
|
60
|
+
========
|
61
|
+
|
62
|
+
Replaces all instances of _h1_ in the `posts/_form.html.erb` partial with `<h1>New Post</h1>`
|
63
|
+
|
64
|
+
Deface::Override.new(:file_path => "posts/_form", :name => "example-1", :replace => "h1", :text => "<h1>New Post</h1>")
|
65
|
+
|
66
|
+
Inserts `<%= link_to "List Comments", comments_url(post) %>` before all instances of `p` with css class `comment` in any layout / template / partial used when rendering _PostsController#index_ action:
|
67
|
+
|
68
|
+
Deface::Override.new(:virtual_path => "posts/index", :name => "example-2", :insert_before => "p.comment", :text => "<%= link_to "List Comments", comments_url(post) %>")
|
69
|
+
|
70
|
+
Inserts the contents of `shared/_comment.html.erb` after all instances of `div` with an id of `comment_21` in any layout / template / partial used when rendering _PostsController#show_ action:
|
71
|
+
|
72
|
+
Deface::Override.new(:virtual_path => "posts/show", :name => "example-3", :insert_after => "div#comment_21", :partial => "shared/comment")
|
73
|
+
|
74
|
+
Removes any instance of `<%= helper_method %>` in the `posts/new.html.erb" template:
|
75
|
+
|
76
|
+
Deface::Override.new(:file_path => "posts/new", :name => "example-4", :remove => "erb-loud:contains('helper_method')" )
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
require 'rspec'
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
|
8
|
+
desc 'Default: run specs'
|
9
|
+
task :default => :spec
|
10
|
+
Rspec::Core::RakeTask.new do |t|
|
11
|
+
t.pattern = "spec/**/*_spec.rb"
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
task :default => :spec
|
16
|
+
|
17
|
+
desc 'Generate documentation for the deface plugin.'
|
18
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
19
|
+
rdoc.rdoc_dir = 'rdoc'
|
20
|
+
rdoc.title = 'Spreme'
|
21
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
22
|
+
rdoc.rdoc_files.include('README')
|
23
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
24
|
+
end
|
25
|
+
|
26
|
+
begin
|
27
|
+
require "jeweler"
|
28
|
+
Jeweler::Tasks.new do |gem|
|
29
|
+
gem.name = "deface"
|
30
|
+
gem.summary = "Deface is a library that allows you to customize ERB views in Rails"
|
31
|
+
gem.email = "brian@railsdog.com"
|
32
|
+
gem.authors = ["Brian Quinn"]
|
33
|
+
gem.files = Dir["*", "{lib}/**/*"]
|
34
|
+
gem.add_dependency("nokogiri", "~> 1.4.3")
|
35
|
+
gem.add_dependency("rails", "~> 3.0.0")
|
36
|
+
end
|
37
|
+
|
38
|
+
Jeweler::GemcutterTasks.new
|
39
|
+
rescue LoadError
|
40
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
41
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/deface.gemspec
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{deface}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Brian Quinn"]
|
12
|
+
s.date = %q{2010-08-30}
|
13
|
+
s.email = %q{brian@railsdog.com}
|
14
|
+
s.extra_rdoc_files = [
|
15
|
+
"README.markdown"
|
16
|
+
]
|
17
|
+
s.files = [
|
18
|
+
"MIT-LICENSE",
|
19
|
+
"README.markdown",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION",
|
22
|
+
"deface.gemspec",
|
23
|
+
"init.rb",
|
24
|
+
"lib/deface.rb",
|
25
|
+
"lib/deface/action_view_extensions.rb",
|
26
|
+
"lib/deface/override.rb",
|
27
|
+
"lib/deface/parser.rb"
|
28
|
+
]
|
29
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
30
|
+
s.require_paths = ["lib"]
|
31
|
+
s.rubygems_version = %q{1.3.7}
|
32
|
+
s.summary = %q{Deface is a library that allows you to customize ERB views in Rails}
|
33
|
+
s.test_files = [
|
34
|
+
"spec/deface/override_spec.rb",
|
35
|
+
"spec/deface/parser_spec.rb",
|
36
|
+
"spec/deface/template_spec.rb",
|
37
|
+
"spec/spec_helper.rb"
|
38
|
+
]
|
39
|
+
|
40
|
+
if s.respond_to? :specification_version then
|
41
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
42
|
+
s.specification_version = 3
|
43
|
+
|
44
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
45
|
+
s.add_runtime_dependency(%q<nokogiri>, ["~> 1.4.3"])
|
46
|
+
s.add_runtime_dependency(%q<rails>, ["~> 3.0.0"])
|
47
|
+
else
|
48
|
+
s.add_dependency(%q<nokogiri>, ["~> 1.4.3"])
|
49
|
+
s.add_dependency(%q<rails>, ["~> 3.0.0"])
|
50
|
+
end
|
51
|
+
else
|
52
|
+
s.add_dependency(%q<nokogiri>, ["~> 1.4.3"])
|
53
|
+
s.add_dependency(%q<rails>, ["~> 3.0.0"])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'deface'
|
data/lib/deface.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
ActionView::Template.class_eval do
|
2
|
+
alias_method :rails_initialize, :initialize
|
3
|
+
|
4
|
+
def initialize(source, identifier, handler, details)
|
5
|
+
overrides = Deface::Override.find(details.merge({:file_path => identifier}))
|
6
|
+
|
7
|
+
unless overrides.empty?
|
8
|
+
doc = Deface::Parser.convert_fragment(source)
|
9
|
+
|
10
|
+
overrides.each do |override|
|
11
|
+
doc.css(override.selector).each do |match|
|
12
|
+
|
13
|
+
match.replace case override.action
|
14
|
+
when :remove
|
15
|
+
""
|
16
|
+
when :replace
|
17
|
+
Deface::Parser.convert_fragment(override.source.clone)
|
18
|
+
when :insert_before
|
19
|
+
Deface::Parser.convert_fragment(override.source.clone << match.to_s)
|
20
|
+
when :insert_after
|
21
|
+
Deface::Parser.convert_fragment(match.to_s << override.source.clone)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
source = doc.to_s
|
28
|
+
|
29
|
+
Deface::Parser.undo_erb_markup(source)
|
30
|
+
end
|
31
|
+
|
32
|
+
rails_initialize(source, identifier, handler, details)
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Deface
|
2
|
+
class Override
|
3
|
+
cattr_accessor :virtual, :file, :actions
|
4
|
+
attr_accessor :args
|
5
|
+
|
6
|
+
@@virtual ||= {}
|
7
|
+
@@file ||= {}
|
8
|
+
@@actions = [:remove, :replace, :insert_after, :insert_before]
|
9
|
+
|
10
|
+
# Initializes new override, you must supply only one Target, Action & Source
|
11
|
+
# parameter for each override (and any number of Optional parameters).
|
12
|
+
#
|
13
|
+
# ==== Target
|
14
|
+
#
|
15
|
+
# * <tt>:file_path</tt> - The relative file path of the template / partial where
|
16
|
+
# the override should take effect eg: "shared/_person", "admin/posts/new"
|
17
|
+
# this will apply to all controller actions that use the specified template
|
18
|
+
# * <tt>:virtual_path</tt> - The controller and action name where
|
19
|
+
# the override should take effect eg: "controller/action" or "posts/index"
|
20
|
+
# will apply to all layouts, templates and partials that are used in the
|
21
|
+
# rendering of the specified action.
|
22
|
+
#
|
23
|
+
# ==== Action
|
24
|
+
#
|
25
|
+
# * <tt>:remove</tt> - Removes all elements that match the supplied selector
|
26
|
+
# * <tt>:replace</tt> - Replaces all elements that match the supplied selector
|
27
|
+
# * <tt>:insert_after</tt> - Inserts after all elements that match the supplied selector
|
28
|
+
# * <tt>:insert_before</tt> - Inserts before all elements that match the supplied selector
|
29
|
+
#
|
30
|
+
# ==== Source
|
31
|
+
#
|
32
|
+
# * <tt>:text</tt> - String containing markup
|
33
|
+
# * <tt>:partial</tt> - Relative path to partial
|
34
|
+
# * <tt>:template</tt> - Relative path to template
|
35
|
+
#
|
36
|
+
# ==== Optional
|
37
|
+
#
|
38
|
+
# * <tt>:name</tt> - Unique name for override so it can be identified and modified later.
|
39
|
+
# This needs to be unique within the same :virtual_path or :file_path
|
40
|
+
|
41
|
+
def initialize(args)
|
42
|
+
@args = args
|
43
|
+
|
44
|
+
if args.key?(:virtual_path)
|
45
|
+
key = args[:virtual_path].to_sym
|
46
|
+
|
47
|
+
@@virtual[key] ||= {}
|
48
|
+
@@virtual[key][args[:name].to_s.parameterize] = self
|
49
|
+
elsif args.key?(:file_path)
|
50
|
+
key = args[:file_path]
|
51
|
+
|
52
|
+
@@file[key] ||= {}
|
53
|
+
@@file[key][args[:name].to_s.parameterize] = self
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def selector
|
58
|
+
@args[self.action]
|
59
|
+
end
|
60
|
+
|
61
|
+
def action
|
62
|
+
(@@actions & @args.keys).first
|
63
|
+
end
|
64
|
+
|
65
|
+
def source
|
66
|
+
erb = if @args.key? :partial
|
67
|
+
load_template_source(@args[:partial], true)
|
68
|
+
elsif @args.key? :template
|
69
|
+
load_template_source(@args[:template], false)
|
70
|
+
elsif @args.key? :text
|
71
|
+
@args[:text]
|
72
|
+
end
|
73
|
+
|
74
|
+
Deface::Parser::ERB.compile(erb)
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.find(details)
|
78
|
+
return [] unless self.virtual || self.file
|
79
|
+
|
80
|
+
result = []
|
81
|
+
|
82
|
+
virtual_path = details[:virtual_path]
|
83
|
+
result << @@virtual[virtual_path.to_sym].try(:values) if virtual_path
|
84
|
+
|
85
|
+
file_path = details[:file_path]
|
86
|
+
result << @@file.map { |key,overrides| overrides.try(:values) if file_path =~ /#{key}/ } if file_path
|
87
|
+
|
88
|
+
result.flatten.compact
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
def load_template_source(virtual_path, partial)
|
93
|
+
parts = virtual_path.split("/")
|
94
|
+
|
95
|
+
@lookup_context ||= ActionView::LookupContext.new(ActionController::Base.view_paths, {:formats => [:html]})
|
96
|
+
|
97
|
+
if parts.size == 2
|
98
|
+
return @lookup_context.find(parts[1], parts[0], partial).source
|
99
|
+
else
|
100
|
+
return ""
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'erubis'
|
3
|
+
|
4
|
+
module Deface
|
5
|
+
class Parser
|
6
|
+
# undoes ERB markup generated by Deface::Parser::ERB
|
7
|
+
#
|
8
|
+
def self.undo_erb_markup(source)
|
9
|
+
source.gsub! /(<|<)erb-silent(>|>)/, '<% '
|
10
|
+
source.gsub! /(<|<)erb-loud(>|>)/, '<%= '
|
11
|
+
source.gsub! /(<|<)\/erb-(loud|silent)(>|>)/, ' %>'
|
12
|
+
source.gsub! /(?!=<%=?)>(?=.*%>)/, '>'
|
13
|
+
source
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def self.convert_fragment(source)
|
18
|
+
source = Deface::Parser::ERB.compile(source)
|
19
|
+
Nokogiri::HTML::DocumentFragment.parse(source)
|
20
|
+
end
|
21
|
+
|
22
|
+
# A class for converting ERB code into a format that's easier
|
23
|
+
# for css & xpath querying4
|
24
|
+
|
25
|
+
# the erb tags are converted to html tags in the following way.
|
26
|
+
# `<% ... %>` is converted into `<erb-silent> ... </erb-silent>`.
|
27
|
+
# `<%= ... %>` is converted into `<erb-loud> ... </erb-loud>`.
|
28
|
+
#
|
29
|
+
class ERB < Erubis::Basic::Engine
|
30
|
+
# Compiles an ERB template into a HTML document containing `erb-` tags.
|
31
|
+
# 100% borrowed from HTML2HAML .. thank you team HAML.
|
32
|
+
#
|
33
|
+
# @param template [String] The ERB template
|
34
|
+
# @return [String] The output document
|
35
|
+
def self.compile(template)
|
36
|
+
new(template).src
|
37
|
+
end
|
38
|
+
|
39
|
+
# not supported (yet?)
|
40
|
+
def escaped_expr(code)
|
41
|
+
raise "Not Supported"
|
42
|
+
end
|
43
|
+
|
44
|
+
# The conversion has no preamble.
|
45
|
+
def add_preamble(src); end
|
46
|
+
|
47
|
+
# The conversion has no postamble.
|
48
|
+
def add_postamble(src); end
|
49
|
+
|
50
|
+
# Concatenates the text onto the source buffer.
|
51
|
+
#
|
52
|
+
# @param src [String] The source buffer
|
53
|
+
# @param text [String] The raw text to add to the buffer
|
54
|
+
def add_text(src, text)
|
55
|
+
src << text
|
56
|
+
end
|
57
|
+
|
58
|
+
# Concatenates a silent Ruby statement onto the source buffer.
|
59
|
+
# This uses the `<erb-silent>` tag
|
60
|
+
#
|
61
|
+
# @param src [String] The source buffer
|
62
|
+
# @param code [String] The Ruby statement to add to the buffer
|
63
|
+
def add_stmt(src, code)
|
64
|
+
src << whitespace(code) << "<erb-silent>" << code.strip << "</erb-silent>"
|
65
|
+
end
|
66
|
+
|
67
|
+
# Concatenates a Ruby expression that's printed to the document
|
68
|
+
# onto the source buffer.
|
69
|
+
# This uses the `<erb-silent>` tag
|
70
|
+
#
|
71
|
+
# @param src [String] The source buffer
|
72
|
+
# @param code [String] The Ruby expression to add to the buffer
|
73
|
+
def add_expr_literal(src, code)
|
74
|
+
src << whitespace(code) << "<erb-loud>" << code.strip << "</erb-loud>"
|
75
|
+
end
|
76
|
+
|
77
|
+
# not supported (yet?)
|
78
|
+
def add_expr_debug(src, code)
|
79
|
+
raise "Not Supported"
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
def whitespace(code)
|
84
|
+
arr = code.scan /^(\s*)/
|
85
|
+
res = arr.flatten.first
|
86
|
+
res.length==1 ? "" : res
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Deface
|
4
|
+
describe Override do
|
5
|
+
before(:each) do
|
6
|
+
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "<h1>Argh!</h1>")
|
7
|
+
@override2 = Deface::Override.new(:file_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "<h1>Argh!</h1>")
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should return correct action" do
|
11
|
+
Deface::Override.actions.each do |action|
|
12
|
+
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", action => "h1", :text => "<h1>Argh!</h1>")
|
13
|
+
@override.action.should == action
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return correct selector" do
|
18
|
+
@override.selector.should == "h1"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should find by virtual_path" do
|
22
|
+
Deface::Override.find({:virtual_path => "posts/index"}).size.should == 1
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should find by file_path" do
|
26
|
+
Deface::Override.find({:file_path => "/full/path/to/posts/index.html.erb"}).size.should == 1
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#new" do
|
30
|
+
|
31
|
+
it "should increase virtual#size by 1" do
|
32
|
+
expect {
|
33
|
+
Deface::Override.new(:virtual_path => "posts/new", :name => "Posts#new", :replace => "h1", :text => "<h1>argh!</h1>")
|
34
|
+
}.to change{Deface::Override.virtual.size}.by(1)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should increase file#size by 1" do
|
38
|
+
expect {
|
39
|
+
Deface::Override.new(:file_path => "posts/new", :name => "Posts#new", :replace => "h1", :text => "<h1>argh!</h1>")
|
40
|
+
}.to change{Deface::Override.file.size}.by(1)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "with :text" do
|
45
|
+
|
46
|
+
before(:each) do
|
47
|
+
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "<h1>Argh!</h1>")
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should return text as source" do
|
51
|
+
@override.source.should == "<h1>Argh!</h1>"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "with :partial" do
|
56
|
+
|
57
|
+
before(:each) do
|
58
|
+
#stub view paths to be local spec/assets directory
|
59
|
+
ActionController::Base.stub(:view_paths).and_return([File.join(File.dirname(__FILE__), '..', "assets")])
|
60
|
+
|
61
|
+
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :partial => "shared/post")
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should return partial contents as source" do
|
65
|
+
@override.source.should == "<p>I'm from shared/post partial</p>\n"
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "with :template" do
|
71
|
+
|
72
|
+
before(:each) do
|
73
|
+
#stub view paths to be local spec/assets directory
|
74
|
+
ActionController::Base.stub(:view_paths).and_return([File.join(File.dirname(__FILE__), '..', "assets")])
|
75
|
+
|
76
|
+
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :template => "shared/person")
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should return template contents as source" do
|
80
|
+
@override.source.should == "<p>I'm from shared/person template</p>\n"
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "when redefining an existing virutal_path and name" do
|
86
|
+
before(:each) do
|
87
|
+
@replacement = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "<h1>Arrrr!</h1>")
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should not increase virtual#size by 1" do
|
91
|
+
expect {
|
92
|
+
Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "<h1>Arrrr!</h1>")
|
93
|
+
}.to change{Deface::Override.virtual.size}.by(0)
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should return new source" do
|
98
|
+
@replacement.source.should_not == @override.source
|
99
|
+
@replacement.source.should == "<h1>Arrrr!</h1>"
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Deface
|
4
|
+
describe Parser do
|
5
|
+
|
6
|
+
describe "#convert_fragment" do
|
7
|
+
it "should parse html" do
|
8
|
+
Deface::Parser.convert_fragment("<h1>Hello</h1>").to_s.should == "<h1>Hello</h1>"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should convert <% ... %>" do
|
12
|
+
Deface::Parser.convert_fragment("<% method_name %>").to_s.should == "<erb-silent>method_name</erb-silent>"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should convert <%= ... %>" do
|
16
|
+
Deface::Parser.convert_fragment("<%= method_name %>").to_s.should == "<erb-loud>method_name</erb-loud>"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should convert nested <% ... %>" do
|
20
|
+
Deface::Parser.convert_fragment("<p id=\"<% method_name %>\"></p>").to_s.should == "<p id=\"<erb-silent>method_name</erb-silent>\"></p>"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should convert nested <%= ... %>" do
|
24
|
+
Deface::Parser.convert_fragment("<p id=\"<%= method_name %>\"></p>").to_s.should == "<p id=\"<erb-loud>method_name</erb-loud>\"></p>"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#undo_erb_markup" do
|
29
|
+
it "should revert <erb-silent>" do
|
30
|
+
Deface::Parser.undo_erb_markup("<erb-silent>method_name</erb-silent>").should == "<% method_name %>"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should revert <erb-loud>" do
|
34
|
+
Deface::Parser.undo_erb_markup("<erb-loud>method_name</erb-loud>").should == "<%= method_name %>"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should revert nested <erb-silent>" do
|
38
|
+
Deface::Parser.undo_erb_markup("<tr id=\"<erb-silent>method_name</erb-silent>\"></tr>").should == "<tr id=\"<% method_name %>\"></tr>"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should revert nested <erb-loud>" do
|
42
|
+
Deface::Parser.undo_erb_markup("<tr id=\"<erb-loud>method_name</erb-loud>\"></tr>").should == "<tr id=\"<%= method_name %>\"></tr>"
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ActionView
|
4
|
+
describe Template do
|
5
|
+
describe "#initialize" do
|
6
|
+
|
7
|
+
describe "with no overrides defined" do
|
8
|
+
before(:all) do
|
9
|
+
@template = ActionView::Template.new("<p>test</p>", "/some/path/to/file.erb", ActionView::Template::Handlers::ERB, {:virtual_path=>"posts/index", :format=>:html})
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should initialize new template object" do
|
13
|
+
@template.is_a?(ActionView::Template).should == true
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return unmodified source" do
|
17
|
+
@template.source.should == "<p>test</p>"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "with a single remove override defined" do
|
22
|
+
before(:all) do
|
23
|
+
Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :remove => "p", :text => "<h1>Argh!</h1>")
|
24
|
+
@template = ActionView::Template.new("<p>test</p><%= raw(text) %>", "/some/path/to/file.erb", ActionView::Template::Handlers::ERB, {:virtual_path=>"posts/index", :format=>:html})
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return modified source" do
|
28
|
+
@template.source.should == "<%= raw(text) %>"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "with a single replace override defined" do
|
33
|
+
before(:all) do
|
34
|
+
Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "p", :text => "<h1>Argh!</h1>")
|
35
|
+
@template = ActionView::Template.new("<p>test</p>", "/some/path/to/file.erb", ActionView::Template::Handlers::ERB, {:virtual_path=>"posts/index", :format=>:html})
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should return modified source" do
|
39
|
+
@template.source.should == "<h1>Argh!</h1>"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "with a single insert_after override defined" do
|
44
|
+
before(:all) do
|
45
|
+
Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :insert_after => "img.button", :text => "<% help %>")
|
46
|
+
|
47
|
+
@template = ActionView::Template.new("<div><img class=\"button\" src=\"path/to/button.png\"></div>",
|
48
|
+
"/path/to/file.erb",
|
49
|
+
ActionView::Template::Handlers::ERB,
|
50
|
+
{:virtual_path=>"posts/index", :format=>:html})
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should return modified source" do
|
54
|
+
@template.source.gsub("\n", "").should == "<div><img class=\"button\" src=\"path/to/button.png\"><% help %></div>"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "with a single insert_before override defined" do
|
59
|
+
before(:all) do
|
60
|
+
Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :insert_after => "ul li:last", :text => "<%= help %>")
|
61
|
+
|
62
|
+
@template = ActionView::Template.new("<ul><li>first</li><li>second</li><li>third</li></ul>",
|
63
|
+
"/path/to/file.erb",
|
64
|
+
ActionView::Template::Handlers::ERB,
|
65
|
+
{:virtual_path=>"posts/index", :format=>:html})
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should return modified source" do
|
69
|
+
@template.source.gsub("\n", "").should == "<ul><li>first</li><li>second</li><li>third</li><%= help %></ul>"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: deface
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Brian Quinn
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-30 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: nokogiri
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 1
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 4
|
33
|
+
- 3
|
34
|
+
version: 1.4.3
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rails
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 7
|
46
|
+
segments:
|
47
|
+
- 3
|
48
|
+
- 0
|
49
|
+
- 0
|
50
|
+
version: 3.0.0
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
description:
|
54
|
+
email: brian@railsdog.com
|
55
|
+
executables: []
|
56
|
+
|
57
|
+
extensions: []
|
58
|
+
|
59
|
+
extra_rdoc_files:
|
60
|
+
- README.markdown
|
61
|
+
files:
|
62
|
+
- MIT-LICENSE
|
63
|
+
- README.markdown
|
64
|
+
- Rakefile
|
65
|
+
- VERSION
|
66
|
+
- deface.gemspec
|
67
|
+
- init.rb
|
68
|
+
- lib/deface.rb
|
69
|
+
- lib/deface/action_view_extensions.rb
|
70
|
+
- lib/deface/override.rb
|
71
|
+
- lib/deface/parser.rb
|
72
|
+
- spec/deface/override_spec.rb
|
73
|
+
- spec/deface/parser_spec.rb
|
74
|
+
- spec/deface/template_spec.rb
|
75
|
+
- spec/spec_helper.rb
|
76
|
+
has_rdoc: true
|
77
|
+
homepage:
|
78
|
+
licenses: []
|
79
|
+
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options:
|
82
|
+
- --charset=UTF-8
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
hash: 3
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
version: "0"
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
requirements: []
|
104
|
+
|
105
|
+
rubyforge_project:
|
106
|
+
rubygems_version: 1.3.7
|
107
|
+
signing_key:
|
108
|
+
specification_version: 3
|
109
|
+
summary: Deface is a library that allows you to customize ERB views in Rails
|
110
|
+
test_files:
|
111
|
+
- spec/deface/override_spec.rb
|
112
|
+
- spec/deface/parser_spec.rb
|
113
|
+
- spec/deface/template_spec.rb
|
114
|
+
- spec/spec_helper.rb
|