deface 1.0.0.rc2 → 1.0.0.rc3

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/.travis.yml CHANGED
@@ -1,16 +1,12 @@
1
1
  script: "bundle exec rake"
2
2
  rvm:
3
- - 1.8.7
4
- - 1.9.2
5
3
  - 1.9.3
6
4
  - 2.0.0
7
- - jruby-18mode
8
- - jruby-19mode
9
5
  gemfile:
10
6
  - gemfiles/rails3_1.gemfile
11
7
  - gemfiles/rails3_2.gemfile
8
+ - gemfiles/rails4_0.gemfile
12
9
  - gemfiles/haml4_0.gemfile
13
-
14
10
  notifications:
15
11
  email:
16
12
  - brian@spreecommerce.com
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gemspec
3
+ gem 'rails', ENV['RAILS'] || '~> 3.2.13'
4
4
 
5
+ gemspec
data/README.markdown CHANGED
@@ -7,7 +7,7 @@
7
7
  Deface
8
8
  ======
9
9
 
10
- Deface is a library that allows you to customize HTML (ERB and HAML) views in a Rails application without editing the underlying view.
10
+ Deface is a library that allows you to customize HTML (ERB, Haml and Slim) views in a Rails application without editing the underlying view.
11
11
 
12
12
  It allows you to easily target html & erb elements as the hooks for customization using CSS selectors as supported by Nokogiri.
13
13
 
@@ -59,7 +59,7 @@ You should save your overrides in the ````app/overrides````, normally one overri
59
59
 
60
60
  * <tt>:insert_bottom</tt> - Inserts inside all elements that match the supplied selector, as the last child.
61
61
 
62
- * <tt>:set_</tt> - Sets attributes on all elements that match the supplied selector, replacing existing attribute value if present or adding if not. Expects :attributes option to be passed.
62
+ * <tt>:set_attributes</tt> - Sets attributes on all elements that match the supplied selector, replacing existing attribute value if present or adding if not. Expects :attributes option to be passed.
63
63
 
64
64
  * <tt>:add_to_attributes</tt> - Appends value to attributes on all elements that match the supplied selector, adds attribute if not present. Expects :attributes option to be passed.
65
65
 
data/deface.gemspec CHANGED
@@ -1,26 +1,27 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "deface"
3
- s.version = "1.0.0.rc2"
3
+ s.version = "1.0.0.rc3"
4
4
 
5
5
  s.authors = ["Brian D Quinn"]
6
- s.description = "Deface is a library that allows you to customize ERB & HAML views in a Rails application without editing the underlying view."
6
+ s.description = "Deface is a library that allows you to customize ERB, Haml and Slim views in a Rails application without editing the underlying view."
7
7
  s.email = "brian@spreecommerce.com"
8
8
  s.extra_rdoc_files = [
9
9
  "README.markdown"
10
10
  ]
11
11
  s.files = `git ls-files`.split("\n")
12
12
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
13
- s.homepage = "http://github.com/railsdog/deface"
13
+ s.homepage = "https://github.com/spree/deface"
14
14
  s.rdoc_options = ["--charset=UTF-8"]
15
15
  s.require_paths = ["lib"]
16
- s.summary = "Deface is a library that allows you to customize ERB & HAML views in Rails"
16
+ s.summary = "Deface is a library that allows you to customize ERB, Haml and Slim views in Rails"
17
17
 
18
- s.add_dependency('nokogiri', '~> 1.5.9')
19
- s.add_dependency('rails', '~> 3.1')
18
+ s.add_dependency('nokogiri', '~> 1.6.0')
19
+ s.add_dependency('rails', '>= 3.1')
20
20
  s.add_dependency('colorize', '>= 0.5.8')
21
21
 
22
22
  s.add_development_dependency('rspec', '>= 2.11.0')
23
23
  s.add_development_dependency('haml', '>= 3.1.4')
24
+ s.add_development_dependency('slim', '>= 2.0.0')
24
25
  s.add_development_dependency('simplecov', '>= 0.6.4')
25
26
  s.add_development_dependency('generator_spec', '~> 0.8.5')
26
27
  end
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem "rails", "~> 4.0.0.rc1"
4
+
5
+ gemspec :path => "../"
data/lib/deface.rb CHANGED
@@ -11,6 +11,7 @@ require "deface/sources/source"
11
11
  require "deface/sources/text"
12
12
  require "deface/sources/erb"
13
13
  require "deface/sources/haml"
14
+ require "deface/sources/slim"
14
15
  require "deface/sources/partial"
15
16
  require "deface/sources/template"
16
17
  require "deface/sources/copy"
@@ -46,5 +47,5 @@ module Deface
46
47
  class DefaceError < StandardError; end
47
48
 
48
49
  class NotSupportedError < DefaceError; end
49
-
50
+
50
51
  end
@@ -2,12 +2,16 @@ ActionView::Template.class_eval do
2
2
  alias_method :initialize_without_deface, :initialize
3
3
 
4
4
  def initialize(source, identifier, handler, details)
5
- if Rails.application.config.deface.enabled && should_be_defaced?(handler)
6
- haml = handler.to_s == "Haml::Plugin"
5
+ syntax = determine_syntax(handler)
7
6
 
8
- processed_source = Deface::Override.apply(source, details, true, haml )
7
+ if Rails.application.config.deface.enabled && should_be_defaced?(syntax)
9
8
 
10
- if haml && processed_source != source
9
+ processed_source = Deface::Override.apply(source, details, true, syntax)
10
+
11
+ # force change in handler before continuing to original Rails method
12
+ # as we've just converted some other template language into ERB!
13
+ #
14
+ if [:slim, :haml].include?(syntax) && processed_source != source
11
15
  handler = ActionView::Template::Handlers::ERB
12
16
  end
13
17
  else
@@ -53,8 +57,20 @@ ActionView::Template.class_eval do
53
57
 
54
58
  private
55
59
 
56
- def should_be_defaced?(handler)
57
- handler.to_s.demodulize == "ERB" || handler.class.to_s.demodulize == "ERB" || handler.to_s == "Haml::Plugin"
60
+ def should_be_defaced?(syntax)
61
+ syntax != :unknown
62
+ end
63
+
64
+ def determine_syntax(handler)
65
+ if handler.to_s == "Haml::Plugin"
66
+ :haml
67
+ elsif handler.class.to_s == "Slim::RailsTemplate"
68
+ :slim
69
+ elsif handler.to_s.demodulize == "ERB" || handler.class.to_s.demodulize == "ERB"
70
+ :erb
71
+ else
72
+ :unknown
73
+ end
58
74
  end
59
75
  end
60
76
 
@@ -3,7 +3,7 @@ module Deface
3
3
  module ClassMethods
4
4
  # applies all applicable overrides to given source
5
5
  #
6
- def apply(source, details, log=true, haml=false)
6
+ def apply(source, details, log=true, syntax=:erb)
7
7
  overrides = find(details)
8
8
 
9
9
  if log && overrides.size > 0
@@ -11,9 +11,12 @@ module Deface
11
11
  end
12
12
 
13
13
  unless overrides.empty?
14
- if haml
14
+ case syntax
15
+ when :haml
15
16
  #convert haml to erb before parsing before
16
17
  source = Deface::HamlConverter.new(source).result
18
+ when :slim
19
+ source = Slim::ERBConverter.new.call(source)
17
20
  end
18
21
 
19
22
  doc = Deface::Parser.convert(source)
@@ -6,8 +6,8 @@ module Deface
6
6
  module DSL
7
7
  class Loader
8
8
  def self.load(filename, options = nil, &block)
9
- unless File.basename(filename) =~ /^[^\.]+(.html.(erb|haml)){0,1}.deface$/
10
- raise "Deface::DSL does not know how to read '#{filename}'. Override files should end with just .deface, .html.erb.deface, or .html.haml.deface"
9
+ unless File.basename(filename) =~ /^[^\.]+(.html.(erb|haml|slim)){0,1}.deface$/
10
+ raise "Deface::DSL does not know how to read '#{filename}'. Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface"
11
11
  end
12
12
 
13
13
  unless file_in_dir_below_overrides?(filename)
@@ -37,6 +37,15 @@ module Deface
37
37
  context.instance_eval(dsl_commands)
38
38
  context.haml(the_rest)
39
39
  context.create_override
40
+ elsif context_name.end_with?('.html.slim')
41
+ dsl_commands, the_rest = extract_dsl_commands_from_slim(file_contents)
42
+
43
+ context_name = context_name.gsub('.html.slim', '')
44
+ context = Context.new(context_name)
45
+ context.virtual_path(determine_virtual_path(filename))
46
+ context.instance_eval(dsl_commands)
47
+ context.slim(the_rest)
48
+ context.create_override
40
49
  else
41
50
  context = Context.new(context_name)
42
51
  context.virtual_path(determine_virtual_path(filename))
@@ -99,7 +108,12 @@ module Deface
99
108
  [dsl_commands, file_contents]
100
109
  end
101
110
 
102
- private
111
+ class << self
112
+ alias_method :extract_dsl_commands_from_slim, :extract_dsl_commands_from_haml
113
+ end
114
+
115
+
116
+ private
103
117
 
104
118
  def self.starts_with_html_comment?(line)
105
119
  line.lstrip.index('<!--') == 0
@@ -126,4 +140,4 @@ module Deface
126
140
  end
127
141
  end
128
142
  end
129
- end
143
+ end
@@ -3,14 +3,15 @@ module Deface
3
3
  Actions::SurroundContents, Actions::InsertBefore, Actions::InsertAfter, Actions::InsertTop,
4
4
  Actions::InsertBottom, Actions::SetAttributes, Actions::AddToAttributes, Actions::RemoveFromAttributes ]
5
5
 
6
- DEFAULT_SOURCES = [ Sources::Text, Sources::Erb, Sources::Haml, Sources::Partial, Sources::Template, Sources::Cut, Sources::Copy]
6
+ DEFAULT_SOURCES = [ Sources::Text, Sources::Erb, Sources::Haml, Sources::Slim, Sources::Partial, Sources::Template, Sources::Cut, Sources::Copy]
7
7
 
8
8
  class Environment
9
- attr_accessor :overrides, :enabled, :haml_support, :namespaced
9
+ attr_accessor :overrides, :enabled, :haml_support, :namespaced, :slim_support
10
10
  def initialize
11
11
  @overrides = Overrides.new
12
12
  @enabled = true
13
13
  @haml_support = false
14
+ @slim_support = false
14
15
  @actions = []
15
16
  @sources = []
16
17
  @namespaced = false
@@ -51,16 +52,21 @@ module Deface
51
52
  end
52
53
 
53
54
  def load_all(app)
54
- #clear overrides before reloading them
55
+ # clear overrides before reloading them
55
56
  app.config.deface.overrides.all.clear
56
57
  Deface::DSL::Loader.register
57
58
 
58
59
  # check all railties / engines / extensions / application for overrides
59
- app.railties.all.dup.push(app).each do |railtie|
60
+ railties = if Rails.version >= "4.0"
61
+ app.railties._all
62
+ else
63
+ app.railties.all
64
+ end
65
+
66
+ railties.dup.push(app).each do |railtie|
60
67
  next unless railtie.respond_to? :root
61
68
  load_overrides(railtie)
62
69
  end
63
-
64
70
  end
65
71
 
66
72
  def early_check
data/lib/deface/parser.rb CHANGED
@@ -71,23 +71,29 @@ module Deface
71
71
  source.gsub!("#{match[0]}#{match[1]}#{match[2]}") { |m| m = "#{match[0]}#{ CGI.unescapeHTML match[1] }#{match[2]}" }
72
72
  end
73
73
 
74
+ if RUBY_PLATFORM == 'java'
75
+ #un-escapes changes from Nokogiri under Java, where " are converted to %22 when in an attribute of an element
76
+ #
77
+ source.scan(/(<%.*?)((?:(?!%>)[\s\S])*)(%>)/).each do |match|
78
+ source.gsub!("#{match[0]}#{match[1]}#{match[2]}") { |m| m = "#{match[0]}#{ match[1].gsub('%22', '"') }#{match[2]}" }
79
+ end
80
+ end
81
+
74
82
  source
75
83
  end
76
84
 
77
85
  def self.convert(source)
78
- if source.encoding_aware?
79
- # Look for # encoding: *. If we find one, we'll encode the
80
- # String in that encoding, otherwise, we'll use the
81
- # default external encoding.
82
- encoding = source.scan(/#{ActionView::Template::Handlers::ERB.const_get(:ENCODING_TAG)}/).first.try(:last) || Encoding.default_external
83
-
84
- # Tag the source with the default external encoding
85
- # or the encoding specified in the file
86
- source.force_encoding(encoding)
87
-
88
- unless source.valid_encoding?
89
- raise ActionView::WrongEncodingError.new(source, encoding)
90
- end
86
+ # Look for # encoding: *. If we find one, we'll encode the
87
+ # String in that encoding, otherwise, we'll use the
88
+ # default external encoding.
89
+ encoding = source.scan(/#{ActionView::Template::Handlers::ERB.const_get(:ENCODING_TAG)}/).first.try(:last) || Encoding.default_external
90
+
91
+ # Tag the source with the default external encoding
92
+ # or the encoding specified in the file
93
+ source.force_encoding(encoding)
94
+
95
+ unless source.valid_encoding?
96
+ raise ActionView::WrongEncodingError.new(source, encoding)
91
97
  end
92
98
 
93
99
  erb_markup!(source)
@@ -100,6 +106,5 @@ module Deface
100
106
  Nokogiri::HTML::DocumentFragment.parse(source)
101
107
  end
102
108
  end
103
-
104
109
  end
105
110
  end
@@ -39,9 +39,14 @@ module Deface
39
39
  app.config.eager_load_paths.reject! {|path| path =~ /app\/overrides\z/ }
40
40
 
41
41
  # railites / engines / extensions
42
- app.railties.all.each do |railtie|
43
- next unless railtie.respond_to? :root
42
+ railties = if Rails.version >= "4.0"
43
+ app.railties._all
44
+ else
45
+ app.railties.all
46
+ end
44
47
 
48
+ railties.each do |railtie|
49
+ next unless railtie.respond_to? :root
45
50
  railtie.config.eager_load_paths.reject! {|path| path =~ /app\/overrides\z/ }
46
51
  end
47
52
  end
@@ -63,6 +68,11 @@ module Deface
63
68
  require 'deface/haml_converter'
64
69
  end
65
70
 
71
+ if defined?(Slim)
72
+ app.config.deface.slim_support = true
73
+ require 'slim/erb_converter'
74
+ end
75
+
66
76
  # catchs any overrides that we required manually
67
77
  app.config.deface.overrides.early_check
68
78
 
@@ -0,0 +1,13 @@
1
+ module Deface
2
+ module Sources
3
+ class Slim < Source
4
+ def self.execute(override)
5
+ if Rails.application.config.deface.slim_support
6
+ ::Slim::ERBConverter.new.call(override.args[:slim])
7
+ else
8
+ raise Deface::NotSupportedError, "`#{override.name}` supplies :slim source, but slim_support is not detected."
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -22,6 +22,8 @@ module Deface
22
22
 
23
23
  if view.handler.to_s == "Haml::Plugin"
24
24
  Deface::HamlConverter.new(view.source).result
25
+ elsif view.handler.class.to_s == "Slim::RailsTemplate"
26
+ Slim::ERBConverter.new.call(view.source)
25
27
  else
26
28
  view.source
27
29
  end
@@ -0,0 +1,3 @@
1
+ /
2
+ insert_after 'h1'
3
+ h2 These robots are awesome.
@@ -0,0 +1 @@
1
+ div class="some" id="message"= "Hi, World!"
@@ -0,0 +1,5 @@
1
+ #content
2
+ .left
3
+ p= print_information
4
+ .right(id=@right)
5
+ = render :partial => "sidebar"
@@ -86,7 +86,8 @@ module ActionView
86
86
  expectations.each do |handler, expected|
87
87
  @template = ActionView::Template.new("xml.post => :blah", "/some/path/to/file.erb", handler, {:virtual_path=>"posts/index", :format=>:xml, :updated_at => (Time.now - 100)})
88
88
  @template.is_a?(ActionView::Template).should == true
89
- @template.send(:should_be_defaced?, handler).should eq(expected), "unexpected result for handler "+handler.to_s
89
+ syntax = @template.send(:determine_syntax, handler)
90
+ @template.send(:should_be_defaced?, syntax).should eq(expected), "unexpected result for handler "+handler.to_s
90
91
  end
91
92
  end
92
93
  end
@@ -10,7 +10,7 @@ describe Deface::DSL::Loader do
10
10
  filename = 'app/overrides/example_name.deface'
11
11
 
12
12
  lambda { Deface::DSL::Loader.load(filename) }.should_not raise_error(
13
- "Deface::DSL does not know how to read 'app/overrides/example_name.deface'. Override files should end with just .deface, .html.erb.deface, or .html.haml.deface")
13
+ "Deface::DSL does not know how to read 'app/overrides/example_name.deface'. Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface")
14
14
  end
15
15
 
16
16
  it 'should succeed if file ends with .html.erb.deface' do
@@ -18,7 +18,7 @@ describe Deface::DSL::Loader do
18
18
  filename = 'app/overrides/example_name.html.erb.deface'
19
19
 
20
20
  lambda { Deface::DSL::Loader.load(filename) }.should_not raise_error(
21
- "Deface::DSL does not know how to read 'app/overrides/example_name.html.erb.deface'. Override files should end with just .deface, .html.erb.deface, or .html.haml.deface")
21
+ "Deface::DSL does not know how to read 'app/overrides/example_name.html.erb.deface'. Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface")
22
22
  end
23
23
 
24
24
  it 'should succeed if file ends with .html.haml.deface' do
@@ -26,7 +26,15 @@ describe Deface::DSL::Loader do
26
26
  filename = 'app/overrides/example_name.html.haml.deface'
27
27
 
28
28
  lambda { Deface::DSL::Loader.load(filename) }.should_not raise_error(
29
- "Deface::DSL does not know how to read 'app/overrides/example_name.html.haml.deface'. Override files should end with just .deface, .html.erb.deface, or .html.haml.deface")
29
+ "Deface::DSL does not know how to read 'app/overrides/example_name.html.haml.deface'. Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface")
30
+ end
31
+
32
+ it 'should succeed if file ends with .html.slim.deface' do
33
+ file = mock('deface file')
34
+ filename = 'app/overrides/example_name.html.slim.deface'
35
+
36
+ lambda { Deface::DSL::Loader.load(filename) }.should_not raise_error(
37
+ "Deface::DSL does not know how to read 'app/overrides/example_name.html.slim.deface'. Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface")
30
38
  end
31
39
 
32
40
  it 'should fail if file ends with .blargh.deface' do
@@ -34,7 +42,7 @@ describe Deface::DSL::Loader do
34
42
  filename = 'app/overrides/example_name.blargh.deface'
35
43
 
36
44
  lambda { Deface::DSL::Loader.load(filename) }.should raise_error(
37
- "Deface::DSL does not know how to read 'app/overrides/example_name.blargh.deface'. Override files should end with just .deface, .html.erb.deface, or .html.haml.deface")
45
+ "Deface::DSL does not know how to read 'app/overrides/example_name.blargh.deface'. Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface")
38
46
  end
39
47
 
40
48
  it "should suceed if parent directory has a dot(.) in it's name" do
@@ -42,7 +50,7 @@ describe Deface::DSL::Loader do
42
50
  filename = 'app/overrides/parent.dir.with.dot/example_name.html.haml.deface'
43
51
 
44
52
  lambda { Deface::DSL::Loader.load(filename) }.should_not raise_error(
45
- "Deface::DSL does not know how to read 'app/overrides/parent.dir.with.dot/example_name.html.haml.deface'. Override files should end with just .deface, .html.erb.deface, or .html.haml.deface")
53
+ "Deface::DSL does not know how to read 'app/overrides/parent.dir.with.dot/example_name.html.haml.deface'. Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface")
46
54
  end
47
55
  end
48
56
 
@@ -124,6 +132,31 @@ describe Deface::DSL::Loader do
124
132
  Deface::DSL::Loader.load(filename)
125
133
  end
126
134
 
135
+ it 'should set the virtual_path for a .html.slim.deface file in a directory below overrides' do
136
+ file = mock('html/slim/deface file')
137
+ filename = 'app/overrides/path/to/view/example_name.html.slim.deface'
138
+ File.should_receive(:open).with(filename).and_yield(file)
139
+
140
+ override_name = 'example_name'
141
+ context = mock('dsl context')
142
+ Deface::DSL::Context.should_receive(:new).with(override_name).
143
+ and_return(context)
144
+
145
+ file_contents = mock('file contents')
146
+ file.should_receive(:read).and_return(file_contents)
147
+
148
+ Deface::DSL::Loader.should_receive(:extract_dsl_commands_from_slim).
149
+ with(file_contents).
150
+ and_return(['dsl commands', 'slim'])
151
+
152
+ context.should_receive(:virtual_path).with('path/to/view').ordered
153
+ context.should_receive(:instance_eval).with('dsl commands').ordered
154
+ context.should_receive(:slim).with('slim').ordered
155
+ context.should_receive(:create_override).ordered
156
+
157
+ Deface::DSL::Loader.load(filename)
158
+ end
159
+
127
160
  end
128
161
 
129
162
  context '.register' do
@@ -220,6 +253,28 @@ describe Deface::DSL::Loader do
220
253
  dsl_commands.should == ""
221
254
  the_rest.should == example
222
255
  end
256
+ end
257
+
258
+ context '.extract_dsl_commands_from_slim' do
259
+ it 'should work in the simplest case' do
260
+ example = "/ test 'command'\n/ another 'command'\nh1 Wow!"
261
+ dsl_commands, the_rest = Deface::DSL::Loader.extract_dsl_commands_from_slim(example)
262
+ dsl_commands.should == "test 'command'\nanother 'command'\n"
263
+ the_rest.should == "h1 Wow!"
264
+ end
223
265
 
266
+ it 'should work with a block style comment using spaces' do
267
+ example = "/\n test 'command'\n another 'command'\nh1 Wow!"
268
+ dsl_commands, the_rest = Deface::DSL::Loader.extract_dsl_commands_from_slim(example)
269
+ dsl_commands.should == "\ntest 'command'\nanother 'command'\n"
270
+ the_rest.should == "h1 Wow!"
271
+ end
272
+
273
+ it 'should leave internal comments alone' do
274
+ example = "br\n/ test 'command'\n/ another 'command'\nh1 Wow!"
275
+ dsl_commands, the_rest = Deface::DSL::Loader.extract_dsl_commands_from_erb(example)
276
+ dsl_commands.should == ""
277
+ the_rest.should == example
278
+ end
224
279
  end
225
280
  end