masterview 0.2.2 → 0.2.3

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 (41) hide show
  1. data/CHANGELOG +14 -0
  2. data/RELEASE_NOTES +12 -0
  3. data/TODO +16 -1
  4. data/doc/configuration.html +19 -8
  5. data/doc/directives.html +173 -4
  6. data/doc/guide.html +2 -2
  7. data/doc/index.html +2 -2
  8. data/doc/stylesheets/masterview.css +13 -0
  9. data/examples/rails_app_config/masterview/environment/development.rb +2 -2
  10. data/lib/masterview/attr_string_parser.rb +105 -0
  11. data/lib/masterview/directive_base.rb +146 -14
  12. data/lib/masterview/directive_helpers.rb +22 -8
  13. data/lib/masterview/directive_registry.rb +169 -0
  14. data/lib/masterview/directives/check_box.rb +31 -0
  15. data/lib/masterview/directives/collection_select.rb +44 -0
  16. data/lib/masterview/directives/hidden_field.rb +2 -2
  17. data/lib/masterview/directives/image_tag.rb +4 -1
  18. data/lib/masterview/directives/insert_generated_comment.rb +7 -6
  19. data/lib/masterview/directives/javascript_include.rb +4 -1
  20. data/lib/masterview/directives/password_field.rb +2 -2
  21. data/lib/masterview/directives/radio_button.rb +35 -0
  22. data/lib/masterview/directives/select.rb +38 -0
  23. data/lib/masterview/directives/stylesheet_link.rb +4 -1
  24. data/lib/masterview/directives/text_area.rb +2 -2
  25. data/lib/masterview/directives/text_field.rb +2 -2
  26. data/lib/masterview/extras/app/controllers/masterview_controller.rb +46 -59
  27. data/lib/masterview/extras/app/views/layouts/masterview_admin.rhtml +73 -0
  28. data/lib/masterview/extras/app/views/masterview/admin/configuration.rhtml +1 -0
  29. data/lib/masterview/extras/app/views/masterview/admin/list.rhtml +1 -1
  30. data/lib/masterview/initializer.rb +73 -20
  31. data/lib/masterview/masterview_info.rb +117 -0
  32. data/lib/masterview/masterview_version.rb +1 -1
  33. data/lib/masterview/parser.rb +22 -35
  34. data/lib/masterview/plugin_load_tracking.rb +17 -8
  35. data/lib/masterview.rb +3 -0
  36. data/test/fixtures/configs/fake_rails_app_with_config/config/masterview/environments/production.rb +5 -1
  37. data/test/unit/config_settings_test.rb +16 -4
  38. data/test/unit/directive_base_test.rb +29 -0
  39. data/test/unit/directive_helpers_parse_test.rb +324 -0
  40. data/test/unit/template_test.rb +242 -0
  41. metadata +14 -2
data/CHANGELOG CHANGED
@@ -1,3 +1,17 @@
1
+ 0.2.3 - July 5th, 2006
2
+ Change default development settings for enable_admin_pages = true and enable_view_rhtml = true, remains false in production.
3
+ Change generated message in files to indicate that list.html controls layout and _messages, while new.html controls _form...
4
+ Added check_box directive
5
+ Added radio_button directive
6
+ Refactored attr_value option parser
7
+ Added select directive
8
+ Added config setting template_asset_base_ref_pattern, index by asset type, for extracting asset refs from template design-time refs for rails helpers.
9
+ Internal rework of directive handling to provide infrastructure for enable alt directive name spaces (separate from builtin mv: namespace).
10
+ Std app directives dir at rails app/masterview/directives will be automatically added to load path along with builtin mv: directives if present.
11
+ Added quote_if method to directive_base and refactored directives to utilize so logic is consolidated.
12
+ Added collection_select directive
13
+
14
+
1
15
  0.2.2 - June 30th, 2006 - Fix bug when not generating rhtml that rails template error could not find source and thus would fail to generate rhtml error page
2
16
 
3
17
  0.2.1 - June 28th, 2006
data/RELEASE_NOTES CHANGED
@@ -1,5 +1,17 @@
1
1
  = MasterView - Rails-optimized (x)html friendly template engine
2
2
 
3
+ == Recent changes (Release 0.2.3)
4
+
5
+ Changed default development settings for enable_admin_pages and
6
+ enable_view_rhtml = true (false in production) to make it easy
7
+ for new users to get up and running. Added check_box, radio_button,
8
+ select, collection_select directives. Refactor attr_value parsing
9
+ to be more robust taking into account nested objects. Internal rework
10
+ of directive handling to support alternate namespaces for directives.
11
+ Std app directives dir at rails app/masterview/directives will be
12
+ automatically added to MasterView load path if exists.
13
+
14
+
3
15
  == Recent changes (Release 0.2.2)
4
16
 
5
17
  Fixes problem when rails encounters exception in either compiling or
data/TODO CHANGED
@@ -31,4 +31,19 @@
31
31
  ??? can we tweak the admin controller for gem plugin so it puts its empty.rhtml in, say, config/masterview/admin??
32
32
  => better loc than vendor/plugins/masterview/........ if users are going to customize that guy
33
33
 
34
- --####################
34
+ --####################
35
+
36
+ DSL for creating directives
37
+ maybe something like
38
+
39
+ event :etag => [:object, :method, :options, :html_options] do
40
+ # creates @dcs, @args, @object, @method, @options, @html_options, and we already have attr_value and attrs
41
+ # the array of symbols is used for string args found in attr_value
42
+ # here we build up the response
43
+ outargs = []
44
+ outargs << quote_if_simple_word(@object)
45
+ outargs << quote_if_simple_word(@method)
46
+ outargs << @options unless @options.to_s.empty?
47
+ outargs << @html_options unless @html_options.to_s.empty?
48
+ erb_output( 'test '+outargs.join(', ') )
49
+ end
@@ -69,8 +69,13 @@ and start using the template engine facilities in its views.
69
69
  <h2>Using MasterView in a Rails Application</h2>
70
70
 
71
71
  <p>The standard configuration of <span class="productName">MasterView</span> in
72
- a Rails application is to generate rhtml into the <code>RAILS_ROOT/app/views</code>
73
- directory from template files in <code>RAILS_ROOT/app/views/masterview</code>.
72
+ a Rails application is to search for MasterView templates (*.html) in the normal
73
+ <code>RAILS_ROOT/app/views</code> directory and for rails to load the generated
74
+ rhtml directly from <span class="productName">MasterView</span> internally. If config.generate_rhtml is set to true
75
+ (default is false) then <span class="productName">MasterView</span> will generate its intermediate rhtml to the standard
76
+ <code>RAILS_ROOT/app/views</code> directory and Rails will pick it up from there
77
+ as normal.
78
+
74
79
  The <code>mv:</code> attribute markup in the masterview templates determines
75
80
  the content of the generated rhtml view templates, which are then used by the Rails controller/view dispatching mechanisms in the usual fashion.
76
81
  </p>
@@ -97,7 +102,7 @@ Options are set by assigning values to the <code>config</code> instance
97
102
  that will be used to initialize <span class="productName">MasterView</span>.
98
103
  </p>
99
104
 
100
- <p>Just as with with your Rails configuration settings, you can optionally provide
105
+ <p>Just as with your Rails configuration settings, you can optionally provide
101
106
  environment-specific settings to override or augment your standard application settings.
102
107
  To specify environment-dependent configuration settings, provide
103
108
  additional config files in an <code>environments</code> subdirectory
@@ -440,16 +445,22 @@ with the pathname of the source template file.
440
445
  </tr>
441
446
  <tr>
442
447
  <td class="setting">enable_admin_pages</td>
443
- <td class="default">false</td>
444
- <td class="description">Enable MasterView admin pages in the rails application. If config/masterview/environments/production.rb was created during installation then the default is false in production mode.
448
+ <td class="default">true for development, otherwise false</td>
449
+ <td class="description">Enable MasterView admin pages in the rails application.
450
+ <!--Too clever, just set the default and be done with it:
451
+ If config/masterview/environments/development.rb was created during installation then the default is true in development mode (false by default in production unless changed in settings.rb).
452
+ -->
445
453
  <div class="explanation">Enables the masterview admin controller at <code>http://yourappdomain/masterview</code>.</div>
446
454
  </td>
447
455
  </tr>
448
456
  <tr>
449
457
  <td class="setting">enable_view_rhtml</td>
450
- <td class="default">false</td>
451
- <td class="description">Enable MasterView admin pages in a rails application to be able to view the generated rhtml. When enabled it creates links on the list page to click to view the rhtml source. Requires that enable_admin_pages is true. If config/masterview/environments/production.rb was created during installation then the default is false in production mode.
452
- <div class="explanation">This functionality is useful for understanding how your templates are being interpretted (ie. what rhtml is being generated by them) and for debugging. For security reasons you would probably disable this feature in production (or disable admin pages altogether).</div>
458
+ <td class="default">true for development, otherwise false</td>
459
+ <td class="description">Enable MasterView admin pages in a rails application to be able to view the generated rhtml. When enabled it creates links on the list page to click to view the rhtml source. Requires that enable_admin_pages is true.
460
+ <!--Too clever, just set the default and be done with it:
461
+ If config/masterview/environments/development.rb was created during installation then the default is true in development mode (false by default in production unless changed in settings.rb).
462
+ -->
463
+ <div class="explanation">This functionality is useful for understanding how your templates are being interpreted (i.e. what rhtml is being generated by them) and for debugging. For security reasons you would probably disable this feature in production (or disable admin pages altogether).</div>
453
464
  </td>
454
465
  </tr>
455
466
  <tr>
data/doc/directives.html CHANGED
@@ -214,6 +214,18 @@ Used on stylesheet <code>&lt;link&gt;</code> elements in html header section
214
214
  <td colspan="2"><a href="#form_directives">Rails Form Helper Directives</a></td>
215
215
  </tr>
216
216
  <tr>
217
+ <td class="directive"><a href="#mv_check_box">mv:check_box</a></td>
218
+ <td>Replaces this element with a Rails <code>check_box</code> helper</td>
219
+ </tr>
220
+ <tr>
221
+ <td class="directive"><a href="#mv_collection_select">mv:collection_select</a></td>
222
+ <td>Replaces this element with a Rails <code>collection_select</code> helper.
223
+ <span class="explanation">(
224
+ Used on <code>&lt;select&gt;</code> form elements
225
+ )</span>
226
+ </td>
227
+ </tr>
228
+ <tr>
217
229
  <td class="directive"><a href="#mv_form">mv:form</a></td>
218
230
  <td>Replaces the start and end tags of this element using the Rails <code>form_tag</code> and <code>form_tag</code> helpers</td>
219
231
  </tr>
@@ -233,6 +245,23 @@ Used on <code>&lt;input&gt;</code> form elements
233
245
  )</span>
234
246
  </td>
235
247
  </tr>
248
+ <tr>
249
+ <td class="directive"><a href="#mv_radio_button">mv:radio_button</a></td>
250
+ <td>Replaces this element with a Rails <code>radio_button</code> helper.
251
+ <span class="explanation">(
252
+ Used on <code>&lt;input&gt;</code> form elements
253
+ )</span>
254
+ </td>
255
+ </tr>
256
+ <tr>
257
+ <td class="directive"><a href="#mv_select">mv:select</a></td>
258
+ <td>Replaces this element with a Rails <code>select</code> helper.
259
+ <span class="explanation">(
260
+ Used on <code>&lt;select&gt;</code> form elements
261
+ )</span>
262
+ </td>
263
+ </tr>
264
+
236
265
  <tr>
237
266
  <td class="directive"><a href="#mv_submit">mv:submit</a></td>
238
267
  <td>Replaces this element with a <code>submit</code> input element using the Rails <code>submit_tag</code> helper.
@@ -379,7 +408,6 @@ mv:import_render=&quot;partial =&gt; &#8216;product/form&#8217;&quot;
379
408
  generates the appropriate render partial helper, but doesn't generate any additional output, it is only used for
380
409
  design time editing and can be easily sync'd up if it ever gets out of sync with the original code.
381
410
  </pre>
382
- <p>
383
411
 
384
412
  <a name="mv_gen_replace"></a>
385
413
  <h4>mv:gen_replace</h4>
@@ -816,6 +844,66 @@ mv:stylesheet_link=&quot;style&quot;
816
844
  <a name="form_directives"></a>
817
845
  <h3>Rails Form Helper Directives</h3>
818
846
 
847
+ <a name="mv_check_box"></a>
848
+ <h4>mv:check_box</h4>
849
+ <p>
850
+ mv:check_box=&quot;product, name&quot;
851
+ </p>
852
+ <pre>
853
+ Replaces this element with the check_box helper. It quotes the object and name if necessary, and merges any
854
+ html attributes into options if supplied
855
+
856
+ &lt;input type="checkbox" mv:check_box=&quot;product, name&quot;/&gt;
857
+
858
+ becomes
859
+
860
+ &lt;% check_box 'product', 'name' %&gt;
861
+
862
+ and
863
+
864
+ &lt;input type="checkbox" class=&quot;green&quot; id=&quot;cb1&quot; mv:check_box=&quot;product, name, {:readonly =&gt; true}, &apos;yes,&apos;, &apos;no&apos;&quot;/&gt;
865
+
866
+ becomes
867
+
868
+ &lt;% check_box 'product', 'name', {:readonly =&gt; true, :class =&gt; &quot;green&quot;, :id =&gt; &quot;cb1&quot;}, &apos;yes,&apos;, &apos;no&apos;&quot;%&gt;
869
+
870
+ </pre>
871
+
872
+ <a name="mv_collection_select"></a>
873
+ <h4>mv:collection_select</h4>
874
+ <p>
875
+ mv:collection_select=&quot;product, category, Category.find_all, id, name&quot;
876
+ </p>
877
+ <pre>
878
+ Replaces the tag with a select helper, it quotes the object and method if necessary, and
879
+ merges any html attributes into the html_options
880
+
881
+
882
+ &lt;select mv:collection_select=&quot;product, category, Category.find_all, id, name&quot;&gt;
883
+ &lt;option&&gt;One&lt;/option&gt;
884
+ &lt;option&&gt;One&lt;/option&gt;
885
+ &lt;/select&gt;
886
+
887
+ becomes
888
+
889
+ &lt;%= collection_select &apos;product&apos;, &apos;category&apos;, Category.find_all, &apos;id&apos;, &apos;name&apos; %&gt;
890
+
891
+ and
892
+
893
+
894
+ &lt;select size=&quot;3&quot; mv:collection_select=&quot;product, category, Category.find_all, id, name, {}, :readonly => true &quot;&gt;
895
+ &lt;option&&gt;One&lt;/option&gt;
896
+ &lt;option&&gt;One&lt;/option&gt;
897
+ &lt;/select&gt;
898
+
899
+
900
+ becomes
901
+
902
+ &lt;%= collection_select &apos;product&apos;, &apos;category&apos;, Category.find_all, &apos;id&apos;, &apos;name&apos;, {}, :readonly => true, :size => 3 %&gt;
903
+
904
+
905
+ </pre>
906
+
819
907
  <a name="mv_form"></a>
820
908
  <h4>mv:form</h4>
821
909
  <p>
@@ -882,6 +970,67 @@ mv:password_field=&quot;user, password&quot;
882
970
  &lt;%= password_field, user, password, :class =&gt; 'pwdStyle', :maxlength = 15, :size =&gt; 10 %&gt;
883
971
  </pre>
884
972
 
973
+ <a name="mv_radio_button"></a>
974
+ <h4>mv:radio_button</h4>
975
+ <p>
976
+ mv:radio_button=&quot;product, category, 'clothing'&quot;
977
+ </p>
978
+ <pre>
979
+ Replaces the tag with a radio_button helper, it quotes the object and method if necessary, and
980
+ merges any html attributes into the options
981
+
982
+
983
+ &lt;input type=&quot;radio&quot; mv:radio_button=&quot;product, category, 'clothing'&quot;/&gt;
984
+
985
+ becomes
986
+
987
+ &lt;%= radio_button &apos;product&apos;,&apos;category&apos;,&apos;clothing&apos; %&gt;
988
+
989
+ and
990
+
991
+ &lt;input type=&quot;radio&quot; class=&quot;green&quot; mv:radio_button=&quot;product, category, 'clothing', :readonly => true&quot;/&gt;
992
+
993
+ becomes
994
+
995
+ &lt;%= radio_button &apos;product&apos;,&apos;category&apos;,&apos;clothing&apos;, :readonly =&gt; true, :class =&gt; &apos;green&apos; %&gt;
996
+
997
+ </pre>
998
+
999
+ <a name="mv_select"></a>
1000
+ <h4>mv:select</h4>
1001
+ <p>
1002
+ mv:select=&quot;product, category, Category.find_all.collect{|c| [c.name, c.id]}&quot;
1003
+ </p>
1004
+ <pre>
1005
+ Replaces the tag with a select helper, it quotes the object and method if necessary, and
1006
+ merges any html attributes into the html_options
1007
+
1008
+
1009
+ &lt;select mv:select=&quot;product, category, Category.find_all.collect{|c| [c.name, c.id]}&quot;&gt;
1010
+ &lt;option&&gt;One&lt;/option&gt;
1011
+ &lt;option&&gt;One&lt;/option&gt;
1012
+ &lt;/select&gt;
1013
+
1014
+ becomes
1015
+
1016
+ &lt;%= select &apos;product&apos;, &apos;category&apos;, Category.find_all.collect{|c| [c.name, c.id]} %&gt;
1017
+
1018
+ and
1019
+
1020
+
1021
+ &lt;select size=&quot;3&quot; mv:select=&quot;product, category, Category.find_all.collect{|c| [c.name, c.id]}, {}, :readonly => true &quot;&gt;
1022
+ &lt;option&&gt;One&lt;/option&gt;
1023
+ &lt;option&&gt;One&lt;/option&gt;
1024
+ &lt;/select&gt;
1025
+
1026
+
1027
+ becomes
1028
+
1029
+ &lt;%= select &apos;product&apos;, &apos;category&apos;, Category.find_all.collect{|c| [c.name, c.id]}, {}, :readonly => true, :size => 3 %&gt;
1030
+
1031
+
1032
+ </pre>
1033
+
885
1034
  <a name="mv_submit"></a>
886
1035
  <h4>mv:submit</h4>
887
1036
  <p>
@@ -981,6 +1130,10 @@ mv:text_field=&quot;object, method&quot;
981
1130
 
982
1131
  <!-- c -->
983
1132
  <tr>
1133
+ <td class="directive"><a href="#mv_check_box">mv:check_box</a></td>
1134
+ <td>Replaces this element with a Rails <code>check_box</code> helper</td>
1135
+ </tr>
1136
+ <tr>
984
1137
  <td class="directive"><a href="#mv_content">mv:content</a></td>
985
1138
  <td>Replaces the content of this element with the value of the expression</td>
986
1139
  </tr>
@@ -990,6 +1143,10 @@ mv:text_field=&quot;object, method&quot;
990
1143
  <td class="directive"><a href="#mv_else">mv:else</a></td>
991
1144
  <td>Used in conjunction with the <span class="directiveName">mv:if</span> and <span class="directiveName">mv:elsif</span> directives to allow you to create <code>if... elsif... else... end</code> blocks</td>
992
1145
  </tr>
1146
+ <tr>
1147
+ <td class="directive"><a href="#mv_elsif">mv:elsif</a></td>
1148
+ <td>Used in conjunction with the <span class="directiveName">mv:if</span> directive to allow you to create <code>if... elsif... end</code> blocks</td>
1149
+ </tr>
993
1150
 
994
1151
  <!-- f -->
995
1152
  <tr>
@@ -1027,8 +1184,12 @@ Used on <code>&lt;input&gt;</code> form elements
1027
1184
  <td>Wraps this element with an <code>if... end</code> block using the attribute contents for the condition</td>
1028
1185
  </tr>
1029
1186
  <tr>
1030
- <td class="directive"><a href="#mv_elsif">mv:elsif</a></td>
1031
- <td>Used in conjunction with the <span class="directiveName">mv:if</span> directive to allow you to create <code>if... elsif... end</code> blocks</td>
1187
+ <td class="directive"><a href="#mv_image_tag">mv:image_tag</a></td>
1188
+ <td>Replaces this element using the Rails <code>image_tag</code> helper.
1189
+ <span class="explanation">(
1190
+ Used on <code>&lt;img&gt;</code> elements
1191
+ )</span>
1192
+ </td>
1032
1193
  </tr>
1033
1194
  <tr>
1034
1195
  <td class="directive"><a href="#mv_import">mv:import</a></td>
@@ -1097,6 +1258,14 @@ Used on <code>&lt;input&gt;</code> form elements
1097
1258
 
1098
1259
  <!-- r -->
1099
1260
  <tr>
1261
+ <td class="directive"><a href="#mv_radio_button">mv:radio_button</a></td>
1262
+ <td>Replaces this element with a Rails <code>radio_button</code> helper.
1263
+ <span class="explanation">(
1264
+ Used on <code>&lt;input&gt;</code> form elements
1265
+ )</span>
1266
+ </td>
1267
+ </tr>
1268
+ <tr>
1100
1269
  <td class="directive"><a href="#mv_replace">mv:replace</a></td>
1101
1270
  <td>Replaces this element and its content with the value of the expression</td>
1102
1271
  </tr>
@@ -1163,7 +1332,7 @@ Used on <code>&lt;input&gt;</code> form elements
1163
1332
  <tr>
1164
1333
  <td class="copyright">&copy;&nbsp;Copyright MasterView 2006</td>
1165
1334
  <td class="validators">
1166
- <a href="http://validator.w3.org/check/referer">[Valid XHTML]</a>
1335
+ <a href="http://validator.w3.org/check/referer"><img src="http://www.w3.org/Icons/valid-xhtml10" title="Valid XHTML 1.0!" alt="Valid XHTML 1.0!" /></a>
1167
1336
  </td>
1168
1337
  </tr>
1169
1338
  </tbody>
data/doc/guide.html CHANGED
@@ -109,7 +109,7 @@ list]
109
109
  <p>
110
110
  The generator by default will generate five masterview template files, one
111
111
  for each distinct page, list, new, edit, show, and destroy. They exist in
112
- the app/views/masterview directory with the filename
112
+ the app/views directory with the filename
113
113
  controller_action.html. The layout and message partial are defined in the
114
114
  list template file and imported into the others. Similarly the new template
115
115
  defines the form partial which is imported into edit, and finally the show
@@ -183,7 +183,7 @@ with different stylesheets each will be used.
183
183
  </p>
184
184
  <p>
185
185
  Once it is done generating, the generated MasterView template file will be
186
- created in app/views/masterview/controller.html. This file is html and can
186
+ created in app/views/CONTROLLER directory. This file is html and can
187
187
  be edited with any standard html editor. The rails specific logic is
188
188
  contained in simple attributes which are ignored by html editors. The
189
189
  syntax for these attributes is heavily derived from the rails helper tags
data/doc/index.html CHANGED
@@ -161,7 +161,7 @@ of the re-work necessary to build out real-world views.
161
161
 
162
162
  </li>
163
163
  <li>Reduce the numbers of files, simplifying editing. Define partials and
164
- layouts naturallyl right in the template, no need to go to another file.
164
+ layouts naturally right in the template, no need to go to another file.
165
165
 
166
166
  </li>
167
167
  <li>Preview in browser without running an app. Allow for dummy data in the
@@ -238,7 +238,7 @@ editors and developers would have the full power of Ruby and Rails without
238
238
  having to jump through extra hoops to use them. I looked at the available
239
239
  html template engines to see if anything fit with my style. I was
240
240
  disappointed with each of them, mainly because they all made it harder than
241
- straigt ERb (rhtml) and were not able to use layouts and partials easily.
241
+ straight ERb (rhtml) and were not able to use layouts and partials easily.
242
242
  </p>
243
243
  <p>
244
244
  After all the hard work so many people have put into Ruby and Rails, I
@@ -85,6 +85,13 @@ div#pageHeader div {
85
85
  text-align: center;
86
86
  }
87
87
 
88
+ div#headerNav {
89
+ width: 800px;
90
+ }
91
+ div#headerNav div {
92
+ text-align: center;
93
+ }
94
+
88
95
  div#pageBody {
89
96
  padding: 15px 20px;
90
97
  }
@@ -153,12 +160,18 @@ div#pageFooter td.copyright {
153
160
  padding-left: 20px;
154
161
  font-size: smaller;
155
162
  font-style: italic;
163
+ vertical-align: middle;
156
164
  }
157
165
  div#pageFooter td.validators {
158
166
  text-align: right;
159
167
  padding-right: 20px;
160
168
  }
161
169
 
170
+ img.w3c_validator {
171
+ width: 88px;
172
+ height: 31px;
173
+ }
174
+
162
175
  /* === Page content style elements ======================================== */
163
176
 
164
177
  .productName {
@@ -14,8 +14,8 @@
14
14
  #config.reparse_changed_masterview_templates = true
15
15
 
16
16
  # Rails application options that you might want to enable for development
17
- #config.enable_admin_pages = false
18
- #config.enable_view_rhtml = false
17
+ #config.enable_admin_pages = true
18
+ #config.enable_view_rhtml = true
19
19
 
20
20
  # Sample of how you might want to modify logging config for development
21
21
  #config.log_level = 'WARN'
@@ -0,0 +1,105 @@
1
+ module MasterView
2
+ class ClosingCharAndMode #:nodoc:
3
+ attr_reader :closing_char, :in_string
4
+
5
+ def initialize(closing_char, in_string) #:nodoc:
6
+ @closing_char = closing_char
7
+ @in_string = in_string
8
+ end
9
+ end
10
+
11
+ # responsible for parsing up the attr_value string into arguments for consumation by directives
12
+ class AttrStringParser
13
+ # returns array of string arguments which are trimmed(stripped) representing the arguments
14
+ # declared in the attr_value string
15
+ # handles ([{%'" arguments and embedded quotes
16
+ def self.parse(str)
17
+ parser = self.new(str)
18
+ parser.parse
19
+ end
20
+
21
+ def initialize(str)
22
+ @string_scanner = StringScanner.new(str)
23
+ @closing_char_mode_stack = []
24
+ @partial_percent_sequence = nil
25
+ end
26
+
27
+ def parse
28
+ args = []
29
+ s = []
30
+ implicit_hash = false
31
+ while( c = @string_scanner.getch ) #not nil
32
+ if @closing_char_mode_stack.last && @closing_char_mode_stack.last.closing_char == c # finished closing_char search
33
+ @closing_char_mode_stack.pop unless (c == '\'' || c == '"') && s.last == '\\' # if this was an embedded quote
34
+ s << c
35
+ next # lets skip all the rest of the logic
36
+ end
37
+ unless @closing_char_mode_stack.last && @closing_char_mode_stack.last.in_string # unless searching for closing char and in string
38
+ # closings can be created ({["'%, commas break into args (if not in closing search)
39
+ if c == ',' && @closing_char_mode_stack.empty? && !implicit_hash # not searching for closing, found comma, strip string and push new arg
40
+ args << s.join.strip
41
+ s.clear
42
+ next
43
+ elsif @partial_percent_sequence
44
+ case @partial_percent_sequence
45
+ when '%' # @partial_percent_sequence is %
46
+ case c
47
+ when 'q', 'Q', 'r', 's', 'w'
48
+ @partial_percent_sequence += c
49
+ when '(', '{', '<', '[' # shorthand %(, %{, %<, %[
50
+ push_closing_char(c,true) #in_string
51
+ end
52
+ when /^%.$/ # @partial_percent_sequence is %q, %Q, %r, %s, %w
53
+ push_closing_char(c, true) #in_string
54
+ else
55
+ @partial_percent_sequence = nil # terminated
56
+ end
57
+ else # no partial_percent_sequence
58
+ case c
59
+ when '%'
60
+ @partial_percent_sequence = c if c == '%'
61
+ when '\'', '"'
62
+ push_closing_char(c, true) #in string
63
+ when '(', '{', '[' # we have started into a bracket, could be hash, array, paren
64
+ push_closing_char(c, false) #not in string
65
+ when '>'
66
+ if s.last == '=' && @closing_char_mode_stack.empty? # we are no in closing_char search and we have a => implying the rest is a hash
67
+ implicit_hash = true
68
+ end
69
+ end
70
+ end
71
+ end
72
+ s << c
73
+ end
74
+ args << s.join.strip unless s.empty? # anything left push as arg
75
+ args
76
+ end
77
+
78
+
79
+ # determine the closing char for this opening char
80
+ # used for all the ways to quote ',", %{ [ < ( |
81
+ # returns nil on alphanumeric
82
+ def determine_closing_char(opening_char)
83
+ case opening_char
84
+ when '{': '}'
85
+ when '[': ']'
86
+ when '(': ')'
87
+ when '<': '>'
88
+ when /[0-9a-zA-Z]/: nil
89
+ else
90
+ opening_char
91
+ end
92
+ end
93
+
94
+ # determine the closing char, push onto @closing_char_mode_stack
95
+ # clear @partial_percent_sequence
96
+ # if invalid opening char, nil will come back from determine so just clear
97
+ def push_closing_char(opening_char, in_string)
98
+ @partial_percent_sequence = nil
99
+ closing_char = determine_closing_char(opening_char)
100
+ @closing_char_mode_stack.push(ClosingCharAndMode.new(closing_char, in_string)) if closing_char
101
+ end
102
+
103
+
104
+ end
105
+ end