deface 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,5 @@
1
+ require "action_view"
2
+ require "action_controller"
3
+ require "deface/action_view_extensions"
4
+ require "deface/override"
5
+ require "deface/parser"
@@ -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! /(<|&lt;)erb-silent(&gt;|>)/, '<% '
10
+ source.gsub! /(<|&lt;)erb-loud(&gt;|>)/, '<%= '
11
+ source.gsub! /(<|&lt;)\/erb-(loud|silent)(&gt;|>)/, ' %>'
12
+ source.gsub! /(?!=<%=?)&gt;(?=.*%>)/, '>'
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=\"&lt;erb-silent&gt;method_name&lt;/erb-silent&gt;\"></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=\"&lt;erb-loud&gt;method_name&lt;/erb-loud&gt;\"></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=\"&lt;erb-silent&gt;method_name&lt;/erb-silent&gt;\"></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=\"&lt;erb-loud&gt;method_name&lt;/erb-loud&gt;\"></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
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'action_view'
4
+ require 'action_controller'
5
+ require 'deface'
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