deface 0.9.1 → 1.0.0.rc1
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 +1 -0
- data/.rspec +3 -0
- data/.travis.yml +1 -0
- data/README.markdown +139 -59
- data/deface.gemspec +4 -2
- data/gemfiles/haml3_2.gemfile +5 -0
- data/lib/deface.rb +28 -1
- data/lib/deface/action_view_extensions.rb +7 -1
- data/lib/deface/actions/action.rb +19 -0
- data/lib/deface/actions/add_to_attributes.rb +15 -0
- data/lib/deface/actions/attribute_action.rb +33 -0
- data/lib/deface/actions/element_action.rb +13 -0
- data/lib/deface/actions/insert_after.rb +9 -0
- data/lib/deface/actions/insert_before.rb +9 -0
- data/lib/deface/actions/insert_bottom.rb +14 -0
- data/lib/deface/actions/insert_top.rb +14 -0
- data/lib/deface/actions/remove.rb +13 -0
- data/lib/deface/actions/remove_from_attributes.rb +13 -0
- data/lib/deface/actions/replace.rb +14 -0
- data/lib/deface/actions/replace_contents.rb +19 -0
- data/lib/deface/actions/set_attributes.rb +12 -0
- data/lib/deface/actions/surround.rb +24 -0
- data/lib/deface/actions/surround_action.rb +15 -0
- data/lib/deface/actions/surround_contents.rb +33 -0
- data/lib/deface/applicator.rb +35 -191
- data/lib/deface/dsl/context.rb +7 -3
- data/lib/deface/dsl/loader.rb +5 -2
- data/lib/deface/environment.rb +31 -1
- data/lib/deface/haml_converter.rb +33 -5
- data/lib/deface/matchers/element.rb +13 -0
- data/lib/deface/matchers/range.rb +52 -0
- data/lib/deface/override.rb +28 -57
- data/lib/deface/sources/copy.rb +15 -0
- data/lib/deface/sources/cut.rb +25 -0
- data/lib/deface/sources/erb.rb +9 -0
- data/lib/deface/sources/haml.rb +14 -0
- data/lib/deface/sources/partial.rb +13 -0
- data/lib/deface/sources/source.rb +11 -0
- data/lib/deface/sources/template.rb +13 -0
- data/lib/deface/sources/text.rb +9 -0
- data/lib/deface/utils/failure_finder.rb +41 -0
- data/spec/deface/action_view_template_spec.rb +28 -2
- data/spec/deface/actions/add_to_attributes_spec.rb +62 -0
- data/spec/deface/actions/insert_after_spec.rb +19 -0
- data/spec/deface/actions/insert_before_spec.rb +19 -0
- data/spec/deface/actions/insert_bottom_spec.rb +28 -0
- data/spec/deface/actions/insert_top_spec.rb +28 -0
- data/spec/deface/actions/remove_from_attributes_spec.rb +81 -0
- data/spec/deface/actions/remove_spec.rb +30 -0
- data/spec/deface/actions/replace_contents_spec.rb +29 -0
- data/spec/deface/actions/replace_spec.rb +52 -0
- data/spec/deface/actions/set_attributes_spec.rb +62 -0
- data/spec/deface/actions/surround_contents_spec.rb +57 -0
- data/spec/deface/actions/surround_spec.rb +57 -0
- data/spec/deface/applicator_spec.rb +0 -354
- data/spec/deface/dsl/context_spec.rb +14 -7
- data/spec/deface/dsl/loader_spec.rb +12 -4
- data/spec/deface/override_spec.rb +26 -3
- data/spec/deface/template_helper_spec.rb +11 -0
- data/spec/deface/utils/failure_finder_spec.rb +76 -0
- data/spec/spec_helper.rb +21 -2
- data/tasks/utils.rake +24 -0
- metadata +91 -14
data/lib/deface/dsl/context.rb
CHANGED
@@ -19,7 +19,7 @@ module Deface
|
|
19
19
|
@virtual_path = name
|
20
20
|
end
|
21
21
|
|
22
|
-
|
22
|
+
def self.define_action_method(action_name)
|
23
23
|
define_method(action_name) do |selector|
|
24
24
|
if @action.present?
|
25
25
|
Rails.logger.error "\e[1;32mDeface: [WARNING]\e[0m Multiple action methods have been called. The last one will be used."
|
@@ -29,7 +29,7 @@ module Deface
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
|
32
|
+
def self.define_source_method(source_name)
|
33
33
|
define_method(source_name) do |value|
|
34
34
|
if @source.present?
|
35
35
|
Rails.logger.error "\e[1;32mDeface: [WARNING]\e[0m Multiple source methods have been called. The last one will be used."
|
@@ -62,6 +62,10 @@ module Deface
|
|
62
62
|
def disabled
|
63
63
|
@options[:disabled] = true
|
64
64
|
end
|
65
|
+
|
66
|
+
def namespaced
|
67
|
+
@options[:namespaced] = true
|
68
|
+
end
|
65
69
|
end
|
66
70
|
end
|
67
|
-
end
|
71
|
+
end
|
data/lib/deface/dsl/loader.rb
CHANGED
@@ -36,7 +36,7 @@ module Deface
|
|
36
36
|
context.virtual_path(determine_virtual_path(filename))
|
37
37
|
context.instance_eval(dsl_commands)
|
38
38
|
context.haml(the_rest)
|
39
|
-
context.create_override
|
39
|
+
context.create_override
|
40
40
|
else
|
41
41
|
context = Context.new(context_name)
|
42
42
|
context.virtual_path(determine_virtual_path(filename))
|
@@ -61,7 +61,10 @@ module Deface
|
|
61
61
|
comment = html_file_contents[first_open_comment_index..first_close_comment_index+2]
|
62
62
|
end
|
63
63
|
|
64
|
-
|
64
|
+
comment.gsub('<!--', '').gsub('-->', '').strip.scan(/[^\s"']+|"[^"]*"|'[^']*'/).each do |part|
|
65
|
+
dsl_commands =~ /('|")\z/ || part =~ /\w\z/ ? dsl_commands << "\n" : dsl_commands << ' '
|
66
|
+
dsl_commands << part
|
67
|
+
end
|
65
68
|
|
66
69
|
html_file_contents = html_file_contents.gsub(comment, '')
|
67
70
|
end
|
data/lib/deface/environment.rb
CHANGED
@@ -1,12 +1,42 @@
|
|
1
1
|
module Deface
|
2
|
+
DEFAULT_ACTIONS = [ Actions::Remove, Actions::Replace, Actions::ReplaceContents, Actions::Surround,
|
3
|
+
Actions::SurroundContents, Actions::InsertBefore, Actions::InsertAfter, Actions::InsertTop,
|
4
|
+
Actions::InsertBottom, Actions::SetAttributes, Actions::AddToAttributes, Actions::RemoveFromAttributes ]
|
5
|
+
|
6
|
+
DEFAULT_SOURCES = [ Sources::Text, Sources::Erb, Sources::Haml, Sources::Partial, Sources::Template, Sources::Cut, Sources::Copy]
|
2
7
|
|
3
8
|
class Environment
|
4
|
-
attr_accessor :overrides, :enabled, :haml_support
|
9
|
+
attr_accessor :overrides, :enabled, :haml_support, :namespaced
|
5
10
|
def initialize
|
6
11
|
@overrides = Overrides.new
|
7
12
|
@enabled = true
|
8
13
|
@haml_support = false
|
14
|
+
@actions = []
|
15
|
+
@sources = []
|
16
|
+
@namespaced = false
|
17
|
+
|
18
|
+
Deface::DEFAULT_ACTIONS.each { |action| register_action(action) }
|
19
|
+
Deface::DEFAULT_SOURCES.each { |source| register_source(source) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def register_action(action)
|
23
|
+
@actions << action
|
24
|
+
Deface::DSL::Context.define_action_method(action.to_sym)
|
25
|
+
end
|
26
|
+
|
27
|
+
def actions
|
28
|
+
@actions.dup
|
9
29
|
end
|
30
|
+
|
31
|
+
def register_source(source)
|
32
|
+
@sources << source
|
33
|
+
Deface::DSL::Context.define_source_method(source.to_sym)
|
34
|
+
end
|
35
|
+
|
36
|
+
def sources
|
37
|
+
@sources.dup
|
38
|
+
end
|
39
|
+
|
10
40
|
end
|
11
41
|
|
12
42
|
class Environment::Overrides
|
@@ -1,9 +1,6 @@
|
|
1
1
|
module Deface
|
2
|
-
class HamlConverter < Haml::Engine
|
3
|
-
def result
|
4
|
-
Deface::Parser.undo_erb_markup! String.new(render)
|
5
|
-
end
|
6
2
|
|
3
|
+
module HamlCompilerMethods
|
7
4
|
def push_script(text, preserve_script, in_tag = false, preserve_tag = false,
|
8
5
|
escape_html = false, nuke_inner_whitespace = false)
|
9
6
|
push_text "<%= #{text.strip} %>"
|
@@ -17,7 +14,9 @@ module Deface
|
|
17
14
|
def push_silent(text, can_suppress = false)
|
18
15
|
push_text "<% #{text.strip} %>"
|
19
16
|
end
|
17
|
+
end
|
20
18
|
|
19
|
+
module HamlParserMethods
|
21
20
|
def parse_old_attributes(line)
|
22
21
|
attributes_hash, rest, last_line = super(line)
|
23
22
|
|
@@ -34,7 +33,6 @@ module Deface
|
|
34
33
|
|
35
34
|
return attributes, rest, last_line
|
36
35
|
end
|
37
|
-
|
38
36
|
private
|
39
37
|
|
40
38
|
# coverts { attributes into deface compatibily attributes
|
@@ -72,6 +70,36 @@ module Deface
|
|
72
70
|
|
73
71
|
attrs.join(', ')
|
74
72
|
end
|
73
|
+
end
|
75
74
|
|
75
|
+
class HamlConverter < Haml::Engine
|
76
|
+
|
77
|
+
# spec coverage will always be bad on one-side
|
78
|
+
# or the other of this if, travis-ci gemfile takes
|
79
|
+
# care of 3.2 haml side for now (until 3.2 is relased)
|
80
|
+
# then we should reverse to test 3.1 with gemfile
|
81
|
+
#
|
82
|
+
if Haml::VERSION >= "3.2"
|
83
|
+
class Compiler < Haml::Compiler
|
84
|
+
include HamlCompilerMethods
|
85
|
+
end
|
86
|
+
|
87
|
+
class Parser < Haml::Parser
|
88
|
+
include HamlParserMethods
|
89
|
+
end
|
90
|
+
|
91
|
+
def initialize(template, options = {})
|
92
|
+
options[:compiler_class] = Compiler
|
93
|
+
options[:parser_class] = Parser
|
94
|
+
super(template, options)
|
95
|
+
end
|
96
|
+
else
|
97
|
+
include HamlParserMethods
|
98
|
+
include HamlCompilerMethods
|
99
|
+
end
|
100
|
+
|
101
|
+
def result
|
102
|
+
Deface::Parser.undo_erb_markup! String.new(render)
|
103
|
+
end
|
76
104
|
end
|
77
105
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Deface
|
2
|
+
module Matchers
|
3
|
+
class Range
|
4
|
+
def initialize(name, selector, end_selector)
|
5
|
+
@name = name
|
6
|
+
@selector = selector
|
7
|
+
@end_selector = end_selector
|
8
|
+
end
|
9
|
+
|
10
|
+
def matches(document, log=true)
|
11
|
+
starting, ending = select_endpoints(document, @selector, @end_selector)
|
12
|
+
|
13
|
+
if starting && ending
|
14
|
+
if log
|
15
|
+
Rails.logger.info("\e[1;32mDeface:\e[0m '#{@name}' matched starting with '#{@selector}' and ending with '#{@end_selector}'")
|
16
|
+
end
|
17
|
+
|
18
|
+
return [select_range(starting, ending)]
|
19
|
+
else
|
20
|
+
if starting.nil?
|
21
|
+
Rails.logger.info("\e[1;32mDeface:\e[0m '#{@name}' failed to match with starting selector '#{@selector}'")
|
22
|
+
else
|
23
|
+
Rails.logger.info("\e[1;32mDeface:\e[0m '#{@name}' failed to match with end selector '#{@end_selector}'")
|
24
|
+
end
|
25
|
+
return []
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def select_endpoints(doc, start, finish)
|
30
|
+
# targeting range of elements as end_selector is present
|
31
|
+
#
|
32
|
+
finish = "#{start} ~ #{finish}"
|
33
|
+
starting = doc.css(start).first
|
34
|
+
|
35
|
+
ending = if starting && starting.parent
|
36
|
+
starting.parent.css(finish).first
|
37
|
+
else
|
38
|
+
doc.css(finish).first
|
39
|
+
end
|
40
|
+
|
41
|
+
return starting, ending
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
# finds all elements upto closing sibling in nokgiri document
|
46
|
+
#
|
47
|
+
def select_range(first, last)
|
48
|
+
first == last ? [first] : [first, *select_range(first.next, last)]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/deface/override.rb
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
module Deface
|
2
2
|
class Override
|
3
|
-
include TemplateHelper
|
4
3
|
include OriginalValidator
|
4
|
+
include Applicator
|
5
5
|
extend Applicator::ClassMethods
|
6
6
|
extend Search::ClassMethods
|
7
7
|
|
8
|
-
cattr_accessor :
|
9
|
-
attr_accessor :args, :parsed_document
|
8
|
+
cattr_accessor :_early, :current_railtie
|
9
|
+
attr_accessor :args, :parsed_document, :failure
|
10
10
|
|
11
11
|
@@_early = []
|
12
|
-
@@actions = [:remove, :replace, :replace_contents, :surround, :surround_contents, :insert_after, :insert_before, :insert_top, :insert_bottom, :set_attributes, :add_to_attributes, :remove_from_attributes]
|
13
|
-
@@sources = [:text, :erb, :haml, :partial, :template, :cut, :copy]
|
14
12
|
|
15
13
|
# Initializes new override, you must supply only one Target, Action & Source
|
16
14
|
# parameter for each override (and any number of Optional parameters).
|
@@ -32,6 +30,7 @@ module Deface
|
|
32
30
|
raise(ArgumentError, ":virtual_path must be defined") if args[:virtual_path].blank?
|
33
31
|
|
34
32
|
args[:text] = content.call if block_given?
|
33
|
+
args[:name] = "#{current_railtie.underscore}_#{args[:name]}" if Rails.application.try(:config).try(:deface).try(:namespaced) || args.delete(:namespaced)
|
35
34
|
|
36
35
|
virtual_key = args[:virtual_path].to_sym
|
37
36
|
name_key = args[:name].to_s.parameterize
|
@@ -44,13 +43,13 @@ module Deface
|
|
44
43
|
@args = self.class.all[virtual_key][name_key].args
|
45
44
|
|
46
45
|
#check if the action is being redefined, and reject old action
|
47
|
-
if (
|
48
|
-
@args.reject!{|key, value| (
|
46
|
+
if (self.class.actions & args.keys).present?
|
47
|
+
@args.reject!{|key, value| (self.class.actions & @args.keys).include? key }
|
49
48
|
end
|
50
49
|
|
51
50
|
#check if the source is being redefined, and reject old action
|
52
|
-
if (
|
53
|
-
@args.reject!{|key, value| (
|
51
|
+
if (Deface::DEFAULT_SOURCES.map(&:to_sym) & args.keys).present?
|
52
|
+
@args.reject!{|key, value| (Deface::DEFAULT_SOURCES.map(&:to_sym) & @args.keys).include? key }
|
54
53
|
end
|
55
54
|
|
56
55
|
@args.merge!(args)
|
@@ -122,69 +121,34 @@ module Deface
|
|
122
121
|
end
|
123
122
|
|
124
123
|
def action
|
125
|
-
(
|
124
|
+
(self.class.actions & @args.keys).first
|
126
125
|
end
|
127
126
|
|
127
|
+
# Returns the markup to be inserted / used
|
128
|
+
#
|
128
129
|
def source
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
when :template
|
133
|
-
load_template_source(@args[:template], false)
|
134
|
-
when :text
|
135
|
-
@args[:text]
|
136
|
-
when :erb
|
137
|
-
@args[:erb]
|
138
|
-
when :cut
|
139
|
-
cut = @args[:cut]
|
140
|
-
|
141
|
-
if cut.is_a? Hash
|
142
|
-
starting, ending = self.class.select_endpoints(self.parsed_document, cut[:start], cut[:end])
|
143
|
-
|
144
|
-
range = self.class.select_range(starting, ending)
|
145
|
-
range.map &:remove
|
146
|
-
|
147
|
-
Deface::Parser.undo_erb_markup! range.map(&:to_s).join
|
148
|
-
|
149
|
-
else
|
150
|
-
Deface::Parser.undo_erb_markup! self.parsed_document.css(cut).first.remove.to_s.clone
|
151
|
-
end
|
152
|
-
|
153
|
-
when :copy
|
154
|
-
copy = @args[:copy]
|
155
|
-
|
156
|
-
if copy.is_a? Hash
|
157
|
-
starting, ending = self.class.select_endpoints(self.parsed_document, copy[:start], copy[:end])
|
158
|
-
|
159
|
-
range = self.class.select_range(starting, ending)
|
160
|
-
|
161
|
-
Deface::Parser.undo_erb_markup! range.map(&:to_s).join
|
162
|
-
else
|
163
|
-
Deface::Parser.undo_erb_markup! parsed_document.css(copy).first.to_s.clone
|
164
|
-
end
|
130
|
+
sources = Rails.application.config.deface.sources
|
131
|
+
source = sources.find { |source| source.to_sym == source_argument }
|
132
|
+
raise(DefaceError, "Source #{source} not found.") unless source
|
165
133
|
|
166
|
-
|
167
|
-
if Rails.application.config.deface.haml_support
|
168
|
-
haml_engine = Deface::HamlConverter.new(@args[:haml])
|
169
|
-
haml_engine.render
|
170
|
-
else
|
171
|
-
raise Deface::NotSupportedError, "`#{self.name}` supplies :haml source, but haml_support is not detected."
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
erb
|
134
|
+
source.execute(self) || ''
|
176
135
|
end
|
177
136
|
|
178
137
|
# Returns a :symbol for the source argument present
|
179
138
|
#
|
180
139
|
def source_argument
|
181
|
-
|
140
|
+
Deface::DEFAULT_SOURCES.detect { |source| @args.key? source.to_sym }.try :to_sym
|
182
141
|
end
|
183
142
|
|
184
143
|
def source_element
|
185
144
|
Deface::Parser.convert(source.clone)
|
186
145
|
end
|
187
146
|
|
147
|
+
def safe_source_element
|
148
|
+
return unless source_argument
|
149
|
+
source_element
|
150
|
+
end
|
151
|
+
|
188
152
|
def disabled?
|
189
153
|
@args.key?(:disabled) ? @args[:disabled] : false
|
190
154
|
end
|
@@ -194,6 +158,8 @@ module Deface
|
|
194
158
|
@args[:closing_selector]
|
195
159
|
end
|
196
160
|
|
161
|
+
# returns attributes hash for attribute related actions
|
162
|
+
#
|
197
163
|
def attributes
|
198
164
|
@args[:attributes] || []
|
199
165
|
end
|
@@ -227,6 +193,11 @@ module Deface
|
|
227
193
|
Rails.application.config.deface.overrides.all
|
228
194
|
end
|
229
195
|
|
196
|
+
def self.actions
|
197
|
+
Rails.application.config.deface.actions.map &:to_sym
|
198
|
+
end
|
199
|
+
|
200
|
+
|
230
201
|
private
|
231
202
|
|
232
203
|
# check if method is compiled for the current virtual path
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Deface
|
2
|
+
module Sources
|
3
|
+
class Copy < Source
|
4
|
+
def self.execute(override)
|
5
|
+
copy = override.args[:copy]
|
6
|
+
if copy.is_a? Hash
|
7
|
+
range = Deface::Matchers::Range.new('Copy', copy[:start], copy[:end]).matches(override.parsed_document).first
|
8
|
+
Deface::Parser.undo_erb_markup! range.map(&:to_s).join
|
9
|
+
else
|
10
|
+
Deface::Parser.undo_erb_markup! override.parsed_document.css(copy).first.to_s.clone
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Deface
|
2
|
+
module Sources
|
3
|
+
class Cut < Source
|
4
|
+
def self.execute(override)
|
5
|
+
cut = override.args[:cut]
|
6
|
+
if cut.is_a? Hash
|
7
|
+
range = Deface::Matchers::Range.new('Cut', cut[:start], cut[:end]).matches(override.parsed_document).first
|
8
|
+
range.map &:remove
|
9
|
+
|
10
|
+
Deface::Parser.undo_erb_markup! range.map(&:to_s).join
|
11
|
+
|
12
|
+
else
|
13
|
+
element = override.parsed_document.css(cut).first
|
14
|
+
|
15
|
+
if element.nil?
|
16
|
+
override.failure = "failed to match :cut selector '#{cut}'"
|
17
|
+
nil
|
18
|
+
else
|
19
|
+
Deface::Parser.undo_erb_markup! element.remove.to_s.clone
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Deface
|
2
|
+
module Sources
|
3
|
+
class Haml < Source
|
4
|
+
def self.execute(override)
|
5
|
+
if Rails.application.config.deface.haml_support
|
6
|
+
haml_engine = Deface::HamlConverter.new(override.args[:haml])
|
7
|
+
haml_engine.render
|
8
|
+
else
|
9
|
+
raise Deface::NotSupportedError, "`#{override.name}` supplies :haml source, but haml_support is not detected."
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|