compass-core 1.0.0.alpha.13

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.
Files changed (141) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/VERSION +1 -0
  4. data/data/caniuse.json +1 -0
  5. data/data/caniuse_extras/css-placeholder.json +171 -0
  6. data/lib/compass-core.rb +1 -0
  7. data/lib/compass/browser_support.rb +62 -0
  8. data/lib/compass/configuration.rb +168 -0
  9. data/lib/compass/configuration/data.rb +178 -0
  10. data/lib/compass/configuration/defaults.rb +197 -0
  11. data/lib/compass/configuration/inheritance.rb +304 -0
  12. data/lib/compass/configuration/paths.rb +19 -0
  13. data/lib/compass/core.rb +64 -0
  14. data/lib/compass/core/caniuse.rb +282 -0
  15. data/lib/compass/core/sass_extensions.rb +10 -0
  16. data/lib/compass/core/sass_extensions/functions.rb +39 -0
  17. data/lib/compass/core/sass_extensions/functions/colors.rb +67 -0
  18. data/lib/compass/core/sass_extensions/functions/configuration.rb +162 -0
  19. data/lib/compass/core/sass_extensions/functions/constants.rb +74 -0
  20. data/lib/compass/core/sass_extensions/functions/cross_browser_support.rb +269 -0
  21. data/lib/compass/core/sass_extensions/functions/display.rb +32 -0
  22. data/lib/compass/core/sass_extensions/functions/enumerate.rb +7 -0
  23. data/lib/compass/core/sass_extensions/functions/env.rb +60 -0
  24. data/lib/compass/core/sass_extensions/functions/font_files.rb +41 -0
  25. data/lib/compass/core/sass_extensions/functions/gradient_support.rb +616 -0
  26. data/lib/compass/core/sass_extensions/functions/image_size.rb +117 -0
  27. data/lib/compass/core/sass_extensions/functions/inline_image.rb +64 -0
  28. data/lib/compass/core/sass_extensions/functions/lists.rb +101 -0
  29. data/lib/compass/core/sass_extensions/functions/math.rb +92 -0
  30. data/lib/compass/core/sass_extensions/functions/selectors.rb +64 -0
  31. data/lib/compass/core/sass_extensions/functions/urls.rb +297 -0
  32. data/lib/compass/core/sass_extensions/monkey_patches.rb +3 -0
  33. data/lib/compass/core/sass_extensions/monkey_patches/browser_support.rb +118 -0
  34. data/lib/compass/core/sass_extensions/monkey_patches/traversal.rb +23 -0
  35. data/lib/compass/core/version.rb +5 -0
  36. data/lib/compass/error.rb +5 -0
  37. data/stylesheets/_compass.scss +3 -0
  38. data/stylesheets/_lemonade.scss +38 -0
  39. data/stylesheets/compass/_configuration.scss +54 -0
  40. data/stylesheets/compass/_css3.scss +21 -0
  41. data/stylesheets/compass/_layout.scss +3 -0
  42. data/stylesheets/compass/_reset-legacy.scss +3 -0
  43. data/stylesheets/compass/_reset.scss +3 -0
  44. data/stylesheets/compass/_support.scss +441 -0
  45. data/stylesheets/compass/_typography.scss +4 -0
  46. data/stylesheets/compass/_utilities.scss +9 -0
  47. data/stylesheets/compass/css3/_animation.scss +122 -0
  48. data/stylesheets/compass/css3/_appearance.scss +17 -0
  49. data/stylesheets/compass/css3/_background-clip.scss +35 -0
  50. data/stylesheets/compass/css3/_background-origin.scss +37 -0
  51. data/stylesheets/compass/css3/_background-size.scss +19 -0
  52. data/stylesheets/compass/css3/_border-radius.scss +107 -0
  53. data/stylesheets/compass/css3/_box-shadow.scss +88 -0
  54. data/stylesheets/compass/css3/_box-sizing.scss +15 -0
  55. data/stylesheets/compass/css3/_box.scss +85 -0
  56. data/stylesheets/compass/css3/_columns.scss +210 -0
  57. data/stylesheets/compass/css3/_deprecated-support.scss +272 -0
  58. data/stylesheets/compass/css3/_filter.scss +50 -0
  59. data/stylesheets/compass/css3/_flexbox.scss +156 -0
  60. data/stylesheets/compass/css3/_font-face.scss +48 -0
  61. data/stylesheets/compass/css3/_hyphenation.scss +71 -0
  62. data/stylesheets/compass/css3/_images.scss +139 -0
  63. data/stylesheets/compass/css3/_inline-block.scss +31 -0
  64. data/stylesheets/compass/css3/_opacity.scss +23 -0
  65. data/stylesheets/compass/css3/_pie.scss +1 -0
  66. data/stylesheets/compass/css3/_regions.scss +27 -0
  67. data/stylesheets/compass/css3/_selection.scss +59 -0
  68. data/stylesheets/compass/css3/_shared.scss +5 -0
  69. data/stylesheets/compass/css3/_text-shadow.scss +82 -0
  70. data/stylesheets/compass/css3/_transform.scss +590 -0
  71. data/stylesheets/compass/css3/_transition.scss +171 -0
  72. data/stylesheets/compass/css3/_user-interface.scss +71 -0
  73. data/stylesheets/compass/layout/_grid-background.scss +178 -0
  74. data/stylesheets/compass/layout/_sticky-footer.scss +23 -0
  75. data/stylesheets/compass/layout/_stretching.scss +24 -0
  76. data/stylesheets/compass/reset/_utilities-legacy.scss +135 -0
  77. data/stylesheets/compass/reset/_utilities.scss +142 -0
  78. data/stylesheets/compass/typography/_links.scss +3 -0
  79. data/stylesheets/compass/typography/_lists.scss +4 -0
  80. data/stylesheets/compass/typography/_text.scss +4 -0
  81. data/stylesheets/compass/typography/_units.scss +152 -0
  82. data/stylesheets/compass/typography/_vertical_rhythm.scss +300 -0
  83. data/stylesheets/compass/typography/links/_hover-link.scss +5 -0
  84. data/stylesheets/compass/typography/links/_link-colors.scss +28 -0
  85. data/stylesheets/compass/typography/links/_unstyled-link.scss +7 -0
  86. data/stylesheets/compass/typography/lists/_bullets.scss +34 -0
  87. data/stylesheets/compass/typography/lists/_horizontal-list.scss +63 -0
  88. data/stylesheets/compass/typography/lists/_inline-block-list.scss +50 -0
  89. data/stylesheets/compass/typography/lists/_inline-list.scss +47 -0
  90. data/stylesheets/compass/typography/text/_ellipsis.scss +25 -0
  91. data/stylesheets/compass/typography/text/_force-wrap.scss +12 -0
  92. data/stylesheets/compass/typography/text/_nowrap.scss +2 -0
  93. data/stylesheets/compass/typography/text/_replacement.scss +68 -0
  94. data/stylesheets/compass/utilities/_color.scss +1 -0
  95. data/stylesheets/compass/utilities/_general.scss +6 -0
  96. data/stylesheets/compass/utilities/_links.scss +5 -0
  97. data/stylesheets/compass/utilities/_lists.scss +6 -0
  98. data/stylesheets/compass/utilities/_print.scss +17 -0
  99. data/stylesheets/compass/utilities/_sass.scss +2 -0
  100. data/stylesheets/compass/utilities/_sprites.scss +2 -0
  101. data/stylesheets/compass/utilities/_tables.scss +3 -0
  102. data/stylesheets/compass/utilities/_text.scss +5 -0
  103. data/stylesheets/compass/utilities/color/_brightness.scss +12 -0
  104. data/stylesheets/compass/utilities/color/_contrast.scss +52 -0
  105. data/stylesheets/compass/utilities/general/_clearfix.scss +44 -0
  106. data/stylesheets/compass/utilities/general/_float.scss +38 -0
  107. data/stylesheets/compass/utilities/general/_hacks.scss +65 -0
  108. data/stylesheets/compass/utilities/general/_min.scss +16 -0
  109. data/stylesheets/compass/utilities/general/_reset.scss +2 -0
  110. data/stylesheets/compass/utilities/general/_tabs.scss +1 -0
  111. data/stylesheets/compass/utilities/general/_tag-cloud.scss +18 -0
  112. data/stylesheets/compass/utilities/links/_hover-link.scss +3 -0
  113. data/stylesheets/compass/utilities/links/_link-colors.scss +3 -0
  114. data/stylesheets/compass/utilities/links/_unstyled-link.scss +3 -0
  115. data/stylesheets/compass/utilities/lists/_bullets.scss +3 -0
  116. data/stylesheets/compass/utilities/lists/_horizontal-list.scss +3 -0
  117. data/stylesheets/compass/utilities/lists/_inline-block-list.scss +3 -0
  118. data/stylesheets/compass/utilities/lists/_inline-list.scss +3 -0
  119. data/stylesheets/compass/utilities/sass/_lists.scss +16 -0
  120. data/stylesheets/compass/utilities/sass/_maps.scss +19 -0
  121. data/stylesheets/compass/utilities/sprites/_base.scss +92 -0
  122. data/stylesheets/compass/utilities/sprites/_sprite-img.scss +81 -0
  123. data/stylesheets/compass/utilities/tables/_alternating-rows-and-columns.scss +22 -0
  124. data/stylesheets/compass/utilities/tables/_borders.scss +38 -0
  125. data/stylesheets/compass/utilities/tables/_scaffolding.scss +9 -0
  126. data/stylesheets/compass/utilities/text/_ellipsis.scss +3 -0
  127. data/stylesheets/compass/utilities/text/_nowrap.scss +3 -0
  128. data/stylesheets/compass/utilities/text/_replacement.scss +3 -0
  129. data/templates/ellipsis/ellipsis.sass +9 -0
  130. data/templates/ellipsis/manifest.rb +27 -0
  131. data/templates/ellipsis/xml/ellipsis.xml +14 -0
  132. data/templates/extension/manifest.rb +26 -0
  133. data/templates/extension/stylesheets/main.sass +1 -0
  134. data/templates/extension/templates/project/manifest.rb +2 -0
  135. data/templates/extension/templates/project/screen.sass +2 -0
  136. data/templates/project/USAGE.markdown +32 -0
  137. data/templates/project/ie.sass +6 -0
  138. data/templates/project/manifest.rb +4 -0
  139. data/templates/project/print.sass +6 -0
  140. data/templates/project/screen.sass +7 -0
  141. metadata +241 -0
@@ -0,0 +1,197 @@
1
+ module Compass
2
+ module Configuration
3
+ module Defaults
4
+ def default_project_path
5
+ "."
6
+ end
7
+
8
+ def default_project_type
9
+ :stand_alone
10
+ end
11
+
12
+ def default_http_path
13
+ "/"
14
+ end
15
+
16
+ def default_extensions_dir
17
+ "extensions"
18
+ end
19
+
20
+ def default_css_dir
21
+ "stylesheets"
22
+ end
23
+
24
+ def default_sass_dir
25
+ "sass"
26
+ end
27
+
28
+ def default_fonts_dir
29
+ "fonts"
30
+ end
31
+
32
+ def default_images_dir
33
+ "images"
34
+ end
35
+
36
+ def default_environment
37
+ :development
38
+ end
39
+
40
+ def default_output_style
41
+ if top_level.environment == :development
42
+ :expanded
43
+ else
44
+ :compressed
45
+ end
46
+ end
47
+
48
+ def default_line_comments
49
+ top_level.environment == :development
50
+ end
51
+
52
+ def default_color_output
53
+ true
54
+ end
55
+
56
+ def default_sass_path
57
+ if (pp = top_level.project_path) && (dir = top_level.sass_dir)
58
+ Compass.projectize(dir, pp)
59
+ end
60
+ end
61
+
62
+ def default_css_path
63
+ if (pp = top_level.project_path) && (dir = top_level.css_dir)
64
+ Compass.projectize(dir, pp)
65
+ end
66
+ end
67
+
68
+ def default_images_path
69
+ if (pp = top_level.project_path) && (dir = top_level.images_dir)
70
+ Compass.projectize(dir, pp)
71
+ end
72
+ end
73
+
74
+ def default_generated_images_path
75
+ if (pp = top_level.project_path) && (dir = top_level.generated_images_dir)
76
+ Compass.projectize(dir, pp)
77
+ else
78
+ top_level.images_path
79
+ end
80
+ end
81
+
82
+ def default_javascripts_path
83
+ if (pp = top_level.project_path) && (dir = top_level.javascripts_dir)
84
+ Compass.projectize(dir, pp)
85
+ end
86
+ end
87
+
88
+ def default_extensions_path
89
+ if (pp = top_level.project_path) && (dir = top_level.extensions_dir)
90
+ Compass.projectize(dir, pp)
91
+ end
92
+ end
93
+
94
+ def default_fonts_path
95
+ if (pp = top_level.project_path) && (dir = top_level.fonts_dir)
96
+ Compass.projectize(dir, pp)
97
+ end
98
+ end
99
+
100
+ def default_cache_path
101
+ if (pp = top_level.project_path) && (dir = top_level.cache_dir)
102
+ Compass.projectize(dir, pp)
103
+ end
104
+ end
105
+
106
+ def default_generated_images_dir
107
+ top_level.images_dir
108
+ end
109
+
110
+ def default_http_generated_images_dir
111
+ top_level.http_images_dir
112
+ end
113
+
114
+ def default_http_images_dir
115
+ top_level.images_dir
116
+ end
117
+
118
+ def default_sprite_load_path
119
+ [top_level.images_path]
120
+ end
121
+
122
+ def default_http_images_path
123
+ http_root_relative top_level.http_images_dir
124
+ end
125
+
126
+ def default_http_stylesheets_dir
127
+ top_level.css_dir
128
+ end
129
+
130
+ def default_http_stylesheets_path
131
+ http_root_relative top_level.http_stylesheets_dir
132
+ end
133
+
134
+ def default_http_generated_images_path
135
+ http_root_relative top_level.http_generated_images_dir
136
+ end
137
+
138
+ def default_http_fonts_dir
139
+ top_level.fonts_dir
140
+ end
141
+
142
+ def default_http_fonts_path
143
+ http_root_relative top_level.http_fonts_dir
144
+ end
145
+
146
+ def default_http_javascripts_dir
147
+ top_level.javascripts_dir
148
+ end
149
+
150
+ def default_http_javascripts_path
151
+ http_root_relative top_level.http_javascripts_dir
152
+ end
153
+
154
+ def default_cache
155
+ true
156
+ end
157
+
158
+ def default_preferred_syntax
159
+ :scss
160
+ end
161
+
162
+ def default_sprite_engine
163
+ :chunky_png
164
+ end
165
+
166
+ def default_chunky_png_options
167
+ if defined?(::Zlib)
168
+ {:compression => Zlib::BEST_COMPRESSION}
169
+ else
170
+ {}
171
+ end
172
+ end
173
+
174
+ # helper functions
175
+
176
+ def http_join(*segments)
177
+ segments.map do |segment|
178
+ next unless segment
179
+ segment = http_pathify(segment)
180
+ segment[-1..-1] == "/" ? segment[0..-2] : segment
181
+ end.join("/")
182
+ end
183
+
184
+ def http_pathify(path)
185
+ if File::SEPARATOR == "/"
186
+ path
187
+ else
188
+ path.gsub(File::SEPARATOR, "/")
189
+ end
190
+ end
191
+
192
+ def http_root_relative(path)
193
+ http_join top_level.http_path, path
194
+ end
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,304 @@
1
+ module Compass
2
+ module Configuration
3
+ # The inheritance module makes it easy for configuration data to inherit from
4
+ # other instances of configuration data. This makes it easier for external code to layer
5
+ # bits of configuration from various sources.
6
+ module Inheritance
7
+
8
+ def self.included(base)
9
+ # inherited_data stores configuration data that this configuration object will
10
+ # inherit if not provided explicitly.
11
+ base.send :attr_accessor, :inherited_data, :set_attributes, :top_level
12
+
13
+ base.send(:include, InstanceMethods)
14
+ base.extend(ClassMethods)
15
+ end
16
+
17
+ module ClassMethods
18
+ def inherited_writer(*attributes)
19
+ attributes.each do |attribute|
20
+ line = __LINE__ + 1
21
+ class_eval %Q{
22
+ def #{attribute}=(value) # def css_dir=(value)
23
+ @set_attributes ||= {} # @set_attributes ||= {}
24
+ @set_attributes[#{attribute.inspect}] = true # @set_attributes[:css_dir] = true
25
+ @#{attribute} = value # @css_dir = value
26
+ end # end
27
+
28
+ def unset_#{attribute}! # def unset_css_dir!
29
+ unset!(#{attribute.inspect}) # unset!(:css_dir)
30
+ end # end
31
+
32
+ def #{attribute}_set? # def css_dir_set?
33
+ set?(#{attribute.inspect}) # set?(:css_dir)
34
+ end # end
35
+ }, __FILE__, line
36
+ end
37
+ end
38
+
39
+ # Defines the default reader to be an inherited_reader that will look at the inherited_data for its
40
+ # value when not set. The inherited reader calls to a raw reader that acts like a normal attribute
41
+ # reader but prefixes the attribute name with "raw_".
42
+ def inherited_reader(*attributes)
43
+ attributes.each do |attribute|
44
+ line = __LINE__ + 1
45
+ class_eval %Q{
46
+ def raw_#{attribute} # def raw_css_dir
47
+ @#{attribute} # @css_dir
48
+ end # end
49
+ def #{attribute}_without_default # def css_dir_without_default
50
+ read_without_default(#{attribute.inspect}) # read_without_default(:css_dir)
51
+ end # end
52
+ def #{attribute} # def css_dir
53
+ read(#{attribute.inspect}) # read(:css_dir)
54
+ end # end
55
+ }, __FILE__, line
56
+ end
57
+ end
58
+
59
+ def inherited_accessor(*attributes)
60
+ inherited_reader(*attributes)
61
+ inherited_writer(*attributes)
62
+ end
63
+
64
+ class ArrayProxy
65
+ def initialize(data, attr)
66
+ @data, @attr = data, attr
67
+ end
68
+ def to_ary
69
+ @data.send(:"read_inherited_#{@attr}_array")
70
+ end
71
+ def to_a
72
+ to_ary
73
+ end
74
+ def <<(v)
75
+ @data.send(:"add_to_#{@attr}", v)
76
+ end
77
+ def >>(v)
78
+ @data.send(:"remove_from_#{@attr}", v)
79
+ end
80
+ def serialize_to_config(prop)
81
+ if v = @data.raw(prop)
82
+ "#{prop} = #{v.inspect}"
83
+ else
84
+ s = ""
85
+ if added = @data.instance_variable_get("@added_to_#{@attr}")
86
+ added.each do |a|
87
+ s << "#{prop} << #{a.inspect}\n"
88
+ end
89
+ end
90
+ if removed = @data.instance_variable_get("@removed_from_#{@attr}")
91
+ removed.each do |r|
92
+ s << "#{prop} >> #{r.inspect}\n"
93
+ end
94
+ end
95
+ if s[-1..-1] == "\n"
96
+ s[0..-2]
97
+ else
98
+ s
99
+ end
100
+ end
101
+ end
102
+ def method_missing(m, *args, &block)
103
+ a = to_ary
104
+ if a.respond_to?(m)
105
+ a.send(m,*args, &block)
106
+ else
107
+ super
108
+ end
109
+ end
110
+ end
111
+
112
+ def inherited_array(*attributes)
113
+ inherited_reader(*attributes)
114
+ inherited_writer(*attributes)
115
+ attributes.each do |attr|
116
+ line = __LINE__ + 1
117
+ class_eval %Q{
118
+ def #{attr} # def sprite_load_paths
119
+ ArrayProxy.new(self, #{attr.inspect}) # ArrayProxy.new(self, :sprite_load_paths)
120
+ end # end
121
+ def #{attr}=(value) # def sprite_load_paths=(value)
122
+ @set_attributes ||= {} # @set_attributes ||= {}
123
+ @set_attributes[#{attr.inspect}] = true # @set_attributes[:sprite_load_paths] = true
124
+ @#{attr} = Array(value) # @sprite_load_paths = Array(value)
125
+ @added_to_#{attr} = [] # @added_to_sprite_load_paths = []
126
+ @removed_from_#{attr} = [] # @removed_from_sprite_load_paths = []
127
+ end # end
128
+ def read_inherited_#{attr}_array # def read_inherited_sprite_load_paths_array
129
+ if #{attr}_set? # if sprite_load_paths_set?
130
+ @#{attr} # Array(@#{attr})
131
+ else # else
132
+ value = if inherited_data # value = Array(read(:sprite_load_paths))
133
+ Array(inherited_data.#{attr})
134
+ else
135
+ Array(read(#{attr.inspect}))
136
+ end
137
+ value -= Array(@removed_from_#{attr}) # value -= Array(@removed_from_sprite_load_paths)
138
+ Array(@added_to_#{attr}) + value # Array(@added_to_sprite_load_paths) + value
139
+ end # end
140
+ end # end
141
+ def add_to_#{attr}(v) # def add_to_sprite_load_paths(v)
142
+ if #{attr}_set? # if sprite_load_paths_set?
143
+ raw_#{attr} << v # raw_sprite_load_paths << v
144
+ else # else
145
+ (@added_to_#{attr} ||= []) << v # (@added_to_sprite_load_paths ||= []) << v
146
+ end # end
147
+ end # end
148
+ def remove_from_#{attr}(v) # def remove_from_sprite_load_paths(v)
149
+ if #{attr}_set? # if sprite_load_paths_set?
150
+ raw_#{attr}.reject!{|e| e == v} # raw_sprite_load_path.reject!{|e| e == v}s
151
+ else # else
152
+ (@removed_from_#{attr} ||= []) << v # (@removed_from_sprite_load_paths ||= []) << v
153
+ end # end
154
+ end # end
155
+ }, __FILE__, line
156
+ end
157
+ end
158
+
159
+ def chained_method(method)
160
+ line = __LINE__ + 1
161
+ class_eval %Q{
162
+ alias_method :_chained_#{method}, method
163
+ def #{method}(*args, &block)
164
+ _chained_#{method}(*args, &block)
165
+ if inherited_data
166
+ inherited_data.#{method}(*args, &block)
167
+ end
168
+ end
169
+ }, __FILE__, line
170
+ end
171
+
172
+
173
+ end
174
+
175
+ module InstanceMethods
176
+
177
+ def on_top!
178
+ self.set_top_level(self)
179
+ end
180
+
181
+ def set_top_level(new_top)
182
+ self.top_level = new_top
183
+ if self.inherited_data.respond_to?(:set_top_level)
184
+ self.inherited_data.set_top_level(new_top)
185
+ end
186
+ end
187
+
188
+
189
+ def inherit_from!(data)
190
+ if self.inherited_data
191
+ self.inherited_data.inherit_from!(data)
192
+ else
193
+ self.inherited_data = data
194
+ end
195
+ self
196
+ end
197
+
198
+ def reset_inheritance!
199
+ self.inherited_data = nil
200
+ end
201
+
202
+ def with_defaults(data)
203
+ inherit_from!(data)
204
+ yield
205
+ reset_inheritance!
206
+ end
207
+
208
+ def unset!(attribute)
209
+ @set_attributes ||= {}
210
+ send("#{attribute}=", nil)
211
+ @set_attributes.delete(attribute)
212
+ nil
213
+ end
214
+
215
+ def set?(attribute)
216
+ @set_attributes ||= {}
217
+ @set_attributes[attribute]
218
+ end
219
+
220
+ def any_attributes_set?
221
+ @set_attributes && @set_attributes.size > 0
222
+ end
223
+
224
+ def default_for(attribute)
225
+ method = "default_#{attribute}".to_sym
226
+ if respond_to?(method)
227
+ send(method)
228
+ end
229
+ end
230
+
231
+ # Read an explicitly set value that is either inherited or set on this instance
232
+ def read_without_default(attribute)
233
+ if set?(attribute)
234
+ send("raw_#{attribute}")
235
+ elsif inherited_data.nil?
236
+ nil
237
+ elsif inherited_data.respond_to?("#{attribute}_without_default")
238
+ inherited_data.send("#{attribute}_without_default")
239
+ elsif inherited_data.respond_to?(attribute)
240
+ inherited_data.send(attribute)
241
+ end
242
+ end
243
+
244
+ # Reads the raw value that was set on this object.
245
+ # you generally should call raw_<attribute>() instead.
246
+ def raw(attribute)
247
+ instance_variable_get("@#{attribute}")
248
+ end
249
+
250
+ # Read a value that is either inherited or set on this instance, if we get to the bottom-most configuration instance,
251
+ # we ask for the default starting at the top level.
252
+ def read(attribute)
253
+ if !(v = send("#{attribute}_without_default")).nil?
254
+ v
255
+ else
256
+ top_level.default_for(attribute)
257
+ end
258
+ end
259
+
260
+ def method_missing(meth, *args, &block)
261
+ if inherited_data
262
+ inherited_data.send(meth, *args, &block)
263
+ else
264
+ raise NoMethodError, meth.to_s
265
+ end
266
+ end
267
+
268
+ def respond_to?(meth)
269
+ if super
270
+ true
271
+ elsif inherited_data
272
+ inherited_data.respond_to?(meth)
273
+ else
274
+ false
275
+ end
276
+ end
277
+
278
+ def chain
279
+ instances = [self]
280
+ instances << instances.last.inherited_data while instances.last.inherited_data
281
+ instances
282
+ end
283
+
284
+ def debug
285
+ normalized_attrs = {}
286
+ ATTRIBUTES.each do |prop|
287
+ values = []
288
+ chain.each do |instance|
289
+ values << {
290
+ :raw => (instance.send("raw_#{prop}") rescue nil),
291
+ :value => (instance.send("#{prop}_without_default") rescue nil),
292
+ :default => (instance.send("default_#{prop}") rescue nil),
293
+ :resolved => instance.send(prop)
294
+ }
295
+ end
296
+ normalized_attrs[prop] = values
297
+ end
298
+ normalized_attrs
299
+ end
300
+
301
+ end
302
+ end
303
+ end
304
+ end