fortitude 0.9.4-java → 0.9.5-java

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/.fix_bundler_for_jruby_17 +26 -0
  3. data/.gitignore +1 -0
  4. data/.travis.yml +33 -40
  5. data/CHANGES.md +44 -0
  6. data/CONTRIBUTORS.md +26 -0
  7. data/Rakefile +1 -1
  8. data/ext/com/fortituderuby/ext/fortitude/FortitudeNativeLibrary.java +45 -33
  9. data/ext/fortitude_native_ext/fortitude_native_ext.c +23 -23
  10. data/fortitude.gemspec +25 -8
  11. data/lib/fortitude/erector.rb +26 -18
  12. data/lib/fortitude/errors.rb +15 -4
  13. data/lib/fortitude/extensions/fortitude_ruby_ext.rb +35 -10
  14. data/lib/fortitude/rails/helpers.rb +59 -2
  15. data/lib/fortitude/rails/railtie.rb +238 -157
  16. data/lib/fortitude/rails/renderer.rb +15 -0
  17. data/lib/fortitude/rails/rendering_methods.rb +46 -33
  18. data/lib/fortitude/rails/template_handler.rb +49 -18
  19. data/lib/fortitude/rails/yielded_object_outputter.rb +3 -2
  20. data/lib/fortitude/rendering_context.rb +14 -5
  21. data/lib/fortitude/support/method_overriding.rb +90 -0
  22. data/lib/fortitude/support/staticized_method.rb +12 -0
  23. data/lib/fortitude/version.rb +1 -1
  24. data/lib/fortitude/widget/content.rb +4 -2
  25. data/lib/fortitude/widget/files.rb +17 -11
  26. data/lib/fortitude/widget/helpers.rb +7 -1
  27. data/lib/fortitude/widget/integration.rb +4 -0
  28. data/lib/fortitude/widget/localization.rb +63 -4
  29. data/lib/fortitude/widget/rendering.rb +17 -10
  30. data/lib/fortitude_jruby_native_ext.jar +0 -0
  31. data/spec/helpers/fortitude_rails_helpers.rb +26 -4
  32. data/spec/rails/capture_system_spec.rb +1 -1
  33. data/spec/rails/class_loading_system_spec.rb +16 -2
  34. data/spec/rails/complex_helpers_system_spec.rb +29 -0
  35. data/spec/rails/data_passing_system_spec.rb +2 -2
  36. data/spec/rails/development_mode_system_spec.rb +1 -1
  37. data/spec/rails/erector_coexistence_system_spec.rb +1 -1
  38. data/spec/rails/helpers_system_spec.rb +20 -2
  39. data/spec/rails/layouts_system_spec.rb +1 -1
  40. data/spec/rails/rendering_system_spec.rb +4 -4
  41. data/spec/rails/rules_system_spec.rb +2 -2
  42. data/spec/rails/templates/class_loading_system_spec/app/views/some_namespace/some_other_namespace/placeholder.rb +5 -0
  43. data/spec/rails/templates/complex_helpers_system_spec/app/controllers/complex_helpers_system_spec_controller.rb +4 -0
  44. data/spec/rails/templates/complex_helpers_system_spec/app/views/complex_helpers_system_spec/label_block_test.rb +9 -0
  45. data/spec/rails/templates/helpers_system_spec/app/controllers/helpers_system_spec_controller.rb +4 -0
  46. data/spec/rails/templates/helpers_system_spec/app/controllers/home_controller.rb +9 -0
  47. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/rails_helpers_without_automatic_helper_access.rb +37 -0
  48. data/spec/rails/templates/helpers_system_spec/app/views/helpers_system_spec/url_helpers_without_automatic_helper_access.rb +45 -0
  49. data/spec/rails/templates/helpers_system_spec/config/initializers/host.rb +1 -0
  50. data/spec/rails/templates/helpers_system_spec/config/routes.rb +7 -0
  51. data/spec/rails/templates/static_method_system_spec/app/views/static_method_system_spec/localization.rb +1 -1
  52. data/spec/rails/templates/view_paths_system_spec/app/controllers/view_paths_system_spec_controller.rb +15 -0
  53. data/spec/rails/templates/view_paths_system_spec/config/application.rb +30 -0
  54. data/spec/rails/templates/view_paths_system_spec/view_path_one/baseone/basetwo/base_class_one.rb +5 -0
  55. data/spec/rails/templates/view_paths_system_spec/view_path_one/view_paths_system_spec/added_view_path.html.rb +5 -0
  56. data/spec/rails/templates/view_paths_system_spec/view_path_one/view_paths_system_spec/autoloading_from_added_view_path.html.rb +5 -0
  57. data/spec/rails/templates/view_paths_system_spec/view_path_two/view_paths_system_spec/added_view_path_from_controller.html.rb +5 -0
  58. data/spec/rails/templates/view_paths_system_spec/view_path_two/view_paths_system_spec/added_view_path_from_controller_with_impossible_to_guess_name.html.rb +14 -0
  59. data/spec/rails/view_paths_system_spec.rb +19 -0
  60. data/spec/system/escaping_system_spec.rb +10 -2
  61. data/spec/system/helpers_system_spec.rb +37 -6
  62. data/spec/system/inline_system_spec.rb +19 -0
  63. data/spec/system/static_method_system_spec.rb +16 -0
  64. data/spec/system/tag_rendering_system_spec.rb +4 -4
  65. data/spec/system/widget_class_from_spec.rb +39 -0
  66. data/spec/system/yield_system_spec.rb +53 -1
  67. metadata +90 -58
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2884a8e72cb352ce8949fb50d90e09a3c088cd4d
4
- data.tar.gz: 2570a3cc59ba2567fb99c125826cc7c8c7aca494
3
+ metadata.gz: 6c0cdd4f8163e6329ea53df6eb0f3cdd0f7b462a
4
+ data.tar.gz: e562cb7ca19a1fdb2ae5aad46045e44da00f9e7e
5
5
  SHA512:
6
- metadata.gz: 694c82aea14f52773ead6cfb78761571f5e2f8c0bf0f16a536f58ebcfaac9fdab583d717930f0180886d6d57564c6ab89cd8b06106b1320aeb27c95aa9a0f3a6
7
- data.tar.gz: f898850d1ae571dd410b0919e557c1190700a0512c51a7a6ab4274a771ec5c4587e6dc58ef892e111a13df30dec62e13db9002544a2733e0b6df59d7d9312178
6
+ metadata.gz: cab578b4fa509f130887152e3ee5f82784f436b02b9b2c12bd8d853e386954d5fba911ff646d1b95bb8849919f9f75dfc6606d9e5d9c7992008e284e65842141
7
+ data.tar.gz: 5cdc304ee2ffec321ee2b6c316007208b043accc297b0e6299f5748889e919e3b8a9d29358c9745ef5b0d685c4c5181b1ee2a45d6f24e872955cfc11669ed98e
@@ -0,0 +1,26 @@
1
+ def safe_system(cmd)
2
+ $stderr.puts "Running: #{cmd}"
3
+ result = system("#{cmd} 2>&1")
4
+ unless result && $? && $?.success?
5
+ raise "Command failed: #{$?.inspect}"
6
+ end
7
+ end
8
+
9
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE.to_s == 'jruby' && defined?(JRUBY_VERSION) && JRUBY_VERSION.to_s =~ /^1\.7\./
10
+ safe_system("gem update --system")
11
+
12
+ target_dir = "/home/travis/.rvm/gems"
13
+ targets = Dir.entries(target_dir).select { |e| e =~ /^jruby\-#{JRUBY_VERSION}.*@global$/i }
14
+
15
+ targets.each do |target|
16
+ full_path = File.join(target_dir, target)
17
+ safe_system("gem uninstall -i '#{full_path}' bundler")
18
+ end
19
+
20
+ safe_system("gem install bundler -v 1.12.5 --no-rdoc --no-ri --no-document")
21
+ else
22
+ ruby_engine = if defined?(RUBY_ENGINE) then RUBY_ENGINE.inspect else 'nil' end
23
+ jruby_version = if defined?(JRUBY_VERSION) then JRUBY_VERSION.inspect else 'nil' end
24
+
25
+ puts "No need to fix Bundler versions. RUBY_ENGINE is #{ruby_engine} and JRUBY_VERSION is #{jruby_version}."
26
+ end
data/.gitignore CHANGED
@@ -18,3 +18,4 @@ lib/*.bundle
18
18
  /*.sublime-project
19
19
  /*.sublime-workspace
20
20
  /doc/source/.retina_images_workaround
21
+ *.swp
data/.travis.yml CHANGED
@@ -1,56 +1,49 @@
1
+ sudo: false
1
2
  rvm:
2
3
  - "1.8.7"
3
4
  - "1.9.3-p551"
4
- - "2.0.0-p598"
5
- - "2.1.5"
6
- - "2.2.0"
7
- - "jruby-1.7.18"
5
+ - "2.0.0-p648"
6
+ - "2.1.10"
7
+ - "2.2.5"
8
+ - "2.3.1"
9
+ - "jruby-1.7.26"
10
+ - "jruby-9.1.5.0"
11
+ # 2016-09-20 ageweke -- This is temporary, and is because JRuby 1.7.26 is incompatible with Bundler 1.13.0/1,
12
+ # because of the following issue: https://github.com/bundler/bundler/issues/4975.
13
+ before_install:
14
+ - ruby .fix_bundler_for_jruby_17
8
15
  env:
9
- - FORTITUDE_SPECS_RAILS_VERSION=4.2.0
10
- - FORTITUDE_SPECS_RAILS_VERSION=4.1.9
16
+ - FORTITUDE_SPECS_RAILS_VERSION=5.0.0.1
17
+ - FORTITUDE_SPECS_RAILS_VERSION=4.2.7.1
18
+ - FORTITUDE_SPECS_RAILS_VERSION=4.1.16
11
19
  - FORTITUDE_SPECS_RAILS_VERSION=4.0.13
12
- - FORTITUDE_SPECS_RAILS_VERSION=3.2.21
20
+ - FORTITUDE_SPECS_RAILS_VERSION=3.2.22.5
13
21
  - FORTITUDE_SPECS_RAILS_VERSION=3.1.12
14
22
  - FORTITUDE_SPECS_RAILS_VERSION=3.0.20
15
- - FORTITUDE_NATIVE_EXTENSIONS=false FORTITUDE_SPECS_RAILS_VERSION=4.2.0
23
+ - FORTITUDE_NATIVE_EXTENSIONS=false FORTITUDE_SPECS_RAILS_VERSION=4.2.7.1
16
24
  - FORTITUDE_NATIVE_EXTENSIONS=false FORTITUDE_SPECS_RAILS_VERSION=3.0.20
17
- before_script:
18
- - export JRUBY_OPTS="$JRUBY_OPTS -J-Xmx128m -J-Xms128m -J-Xss2048k"
19
25
  matrix:
20
26
  exclude:
21
27
  # Rails 4.x doesn't support Ruby 1.8.7
22
28
  - rvm: 1.8.7
23
- env: FORTITUDE_SPECS_RAILS_VERSION=4.2.0
29
+ env: FORTITUDE_SPECS_RAILS_VERSION=4.2.7.1
24
30
  - rvm: 1.8.7
25
- env: FORTITUDE_SPECS_RAILS_VERSION=4.1.9
31
+ env: FORTITUDE_SPECS_RAILS_VERSION=4.1.16
26
32
  - rvm: 1.8.7
27
- env: FORTITUDE_NATIVE_EXTENSIONS=false FORTITUDE_SPECS_RAILS_VERSION=4.2.0
33
+ env: FORTITUDE_NATIVE_EXTENSIONS=false FORTITUDE_SPECS_RAILS_VERSION=4.2.7.1
28
34
  - rvm: 1.8.7
29
35
  env: FORTITUDE_SPECS_RAILS_VERSION=4.0.13
30
- # 2014-06-19 ageweke -- ARGH. After trying about seventeen different things, no matter what I do,
31
- # Travis fails JRuby builds about 20% of the time with "Killed". Their documentation indicates that this
32
- # is likely an out-of-memory issue (i.e., entire VM's memory is consumed). However, I'm running JRuby with
33
- # only 128MB allocated to each VM (per above) -- yuck -- and it's still happening; this makes no sense, as it
34
- # would take something like 20+ concurrent JRuby processes to consume 3GB, and we should never be running
35
- # more than 2-3.
36
- #
37
- # At this point, I have little choice other than to mark these as 'allowed failures', and check in on each
38
- # one manually to make sure there aren't other failures, too. This is very frustrating, but I can't seem to
39
- # find a way around it. If there's a fix out there somewhere, I'm all ears!
40
- allow_failures:
41
- - rvm: jruby-1.7.18
42
- env: FORTITUDE_SPECS_RAILS_VERSION=4.2.0
43
- - rvm: jruby-1.7.18
44
- env: FORTITUDE_SPECS_RAILS_VERSION=4.1.9
45
- - rvm: jruby-1.7.18
46
- env: FORTITUDE_SPECS_RAILS_VERSION=4.0.13
47
- - rvm: jruby-1.7.18
48
- env: FORTITUDE_SPECS_RAILS_VERSION=3.2.21
49
- - rvm: jruby-1.7.18
50
- env: FORTITUDE_SPECS_RAILS_VERSION=3.1.12
51
- - rvm: jruby-1.7.18
52
- env: FORTITUDE_SPECS_RAILS_VERSION=3.0.20
53
- - rvm: jruby-1.7.18
54
- env: FORTITUDE_NATIVE_EXTENSIONS=false FORTITUDE_SPECS_RAILS_VERSION=4.2.0
55
- - rvm: jruby-1.7.18
56
- env: FORTITUDE_NATIVE_EXTENSIONS=false FORTITUDE_SPECS_RAILS_VERSION=3.0.20
36
+ # Rails 5.x doesn't support Ruby < 2.2
37
+ - rvm: 1.8.7
38
+ env: FORTITUDE_SPECS_RAILS_VERSION=5.0.0.1
39
+ - rvm: "1.9.3-p551"
40
+ env: FORTITUDE_SPECS_RAILS_VERSION=5.0.0.1
41
+ - rvm: "2.0.0-p648"
42
+ env: FORTITUDE_SPECS_RAILS_VERSION=5.0.0.1
43
+ - rvm: "2.1.10"
44
+ env: FORTITUDE_SPECS_RAILS_VERSION=5.0.0.1
45
+ - rvm: "jruby-1.7.26"
46
+ env: FORTITUDE_SPECS_RAILS_VERSION=5.0.0.1
47
+ # JRuby doesn't support Rails 5 yet
48
+ - rvm: jruby-9.1.5.0
49
+ env: FORTITUDE_SPECS_RAILS_VERSION=5.0.0.1
data/CHANGES.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # Fortitude Releases
2
2
 
3
+ ## 0.9.5, 12 October 2016
4
+
5
+ * Rails 5 compatibility: Fortitude now is fully compatible with Rails 5.0.0.1.
6
+ * Significant improvements in performance to our dispatching to #t, the Rails method to produce translations of
7
+ localized strings. Localized Rails applications tend to use this method a _lot_, so its performance can have a
8
+ big impact on overall application performance.
9
+ * A much better error message if you try to declare a method `static` when it hasn't been defined yet &mdash; this
10
+ can often be the result of putting the `static` declaration above the method definition in the source file,
11
+ rather than below it. (Thanks to [`tobymao`](https://github.com/tobymao) for the bug report!)
12
+ * Updated versions of Ruby and Rails that Travis CI tests against to the very latest.
13
+ * Fixed an issue where Fortitude wasn't properly respecting Rails' view paths. Fortitude templates could be found at
14
+ alternate view paths, but our trick of namespacing views under `Views::` wouldn't apply. Now, it all works
15
+ perfectly. (Thanks to [Karl He](https://github.com/karlhe) for the bug report and example patch!)
16
+ * Fixed an issue where `#block_given?` always returned `true` inside a Fortitude widget's `#content` method, whether
17
+ a block was supplied to it or not. (Thanks to [Jeff Dickey](https://github.com/jdickey) for the bug report!)
18
+ * Fixed an incompatibility between Fortitude and Rails 4.2.5.1, since Rails 4.2.5.1 added a fifth parameter to
19
+ `ActionView::PathResolver#find_templates`. (Thanks to [Luke Francl](https://github.com/look) for the bug report!)
20
+ * Fixed incompatibilities with more-recently released versions of gems (`uglifier`, `rake`, `activesupport`) that
21
+ otherwise broke compatibility with previous Ruby versions.
22
+ * Fixed an issue where Fortitude’s system for figuring out what the name of a Fortitude widget would be, based on its
23
+ filename, could be confused by filenames ending in other extensions before `.rb` (for example, `.html.rb`).
24
+ * Eliminated a deprecation warning from Rails 5 caused by Fortitude's use of `render :text` internally.
25
+ * Removed usage of `alias_method_chain` on Ruby 2.0 and later, in favor of `Module#prepend`. This removes deprecation
26
+ warnings otherwise triggered by Rails 5. (Using `Module#prepend` causes problems in JRuby, so `alias_method_chain`
27
+ is still used on JRuby instead.)
28
+ * Changed the behavior of `automatic_helper_access false` so that, in a Rails application, it still makes all the
29
+ built-in Rails helpers properly accessible, but does not make user-defined helpers accessible. (If there are even
30
+ certain built-in Rails helpers you don’t want people using, you can easily override them in your widget class to
31
+ raise an exception.) Without this, `automatic_helper_access false` became so cumbersome to use that it was nearly
32
+ pointless. (Thanks to [Matt Walters](https://github.com/mattwalters) for the pull request!)
33
+ * Fixed an issue where explicitly declaring an assignment method as a helper (_e.g._, `helper :foo=`) did not work
34
+ properly.
35
+ * Fixed an issue where passing a block to (_e.g._) `f.label`, where `f` is the object yielded to a `form_for` helper,
36
+ did not work properly. (Thanks to [Adam Becker](https://github.com/ajb) for the bug report and test case!)
37
+ * Reduced escaping in attribute values: only `"` and `&` need to be escaped, not `<`, `>`, or `'`. (Thanks to
38
+ [Adam Becker](https://github.com/ajb) for the bug report!)
39
+ * Fixed an issue where, under certain extremely rare circumstances, adding a view path in the controller (using
40
+ [`ActionView::ViewPaths.append_view_path`](http://api.rubyonrails.org/classes/ActionView/ViewPaths/ClassMethods.html#method-i-prepend_view_path)
41
+ and related methods) would not be able to figure out the proper class name of the widget, and would fail. (Thanks
42
+ to [Leaf](https://github.com/leafo) for the bug report!)
43
+ * Added the ability for the `inline_html` method on a widget class to accept a `Fortitude::RenderingContext`, thus
44
+ allowing you to use it with code requiring access to helpers. (Thanks to [Adam Becker](https://github.com/ajb) for
45
+ the bug report!)
46
+
3
47
  ## 0.9.4, 11 February 2015
4
48
 
5
49
  * Fixed an issue where use of Rails' `form_for` or `fields_for` from within another `form_for` or `fields_for` block
data/CONTRIBUTORS.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Fortitude is written by [Andrew Geweke](https://github.com/ageweke), with contributions from:
4
4
 
5
+ * [`tobymao`](https://github.com/tobymao): reporting a bug where trying to declare a method `static` before it's been
6
+ defined resulted in a confusing error.
5
7
  * [Ahto Jussila](https://github.com/ahto): a patch to provide separate MRI and JRuby gems, so that
6
8
  `gem install fortitude` works properly no matter which platform you're on.
7
9
  * [Roman Heinrich](https://github.com/mindreframer): reporting a bug where trying to use Fortitude as a Tilt
@@ -37,7 +39,31 @@ Fortitude is written by [Andrew Geweke](https://github.com/ageweke), with contri
37
39
  a memory leak.
38
40
  * Reporting an issue where use of Rails' `form_for` and/or `fields_for` from within another `form_for` or
39
41
  `fields_for` block would not produce the correct output.
42
+ * Reporting an issue where, under certain extremely rare circumstances, adding a view path in the controller (using
43
+ [`ActionView::ViewPaths.append_view_path`](http://api.rubyonrails.org/classes/ActionView/ViewPaths/ClassMethods.html#method-i-prepend_view_path)
44
+ and related methods) would not be able to figure out the proper class name of the widget, and would fail.
40
45
  * [Adam Becker](https://github.com/ajb) for:
41
46
  * Discussion and details around exactly what `:attribute => true`, `:attribute => false`, and so on should render
42
47
  from Fortitude.
43
48
  * Reporting an issue where you could not easily render a Fortitude widget from Erector, nor vice-versa.
49
+ * Fixes for compatibility with Rails 5.
50
+ * Fix for a deprecation warning from Rails 5 caused by Fortitude's use of `render :text` internally.
51
+ * Reporting an issue and providing a test case and patch for an issue where calling `f.label` with a block, where
52
+ `f` is the object yielded to Rails' `form_for`, would cause an exception from Fortitude.
53
+ * Reporting an issue where Fortitude was escaping characters that it didn’t need to in attribute values
54
+ (specifically, `<`, `>`, and `'`).
55
+ * Reporting an issue where you couldn't use `inline_html` in a way that allowed you to pass a
56
+ `Fortitude::RenderingContext`, thus preventing you from using it with code that required access to helpers.
57
+ * [Karl He](https://github.com/karlhe) for:
58
+ * Reporting an issue (and supplying an example patch) where Fortitude wasn't respecting Rails' additional view
59
+ paths correctly &mdash; only `app/views`.
60
+ * [Jeff Dickey](https://github.com/jdickey) for:
61
+ * Reporting an issue where `#block_given?` inside a Fortitude widget's `#content` method returned `true` always,
62
+ whether or not there was anything to yield to.
63
+ * [Luke Francl](https://github.com/look) for:
64
+ * Reporting an incompatibility between Fortitude and Rails 4.2.5.1, and discovering the underlying cause (a fifth
65
+ parameter added to `ActionView::PathResolver#find_templates`.)
66
+ * [Victor Lymar](https://github.com/vlymar) for:
67
+ * Fixes for compatibility with Rails 5.
68
+ * [Matt Walters](https://github.com/mattwalters) for:
69
+ * A patch to make built-in Rails helpers work even when `automatic_helper_access` was set to `false`.
data/Rakefile CHANGED
@@ -32,7 +32,7 @@ namespace :jruby do
32
32
  end
33
33
 
34
34
  task :ensure_jruby do
35
- unless RUBY_ENGINE == 'jruby'
35
+ unless defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
36
36
  raise "You must run this task using JRuby, not #{RUBY_ENGINE}"
37
37
  end
38
38
  end
@@ -57,13 +57,13 @@ public class FortitudeNativeLibrary implements Library {
57
57
  outputString.cat(selfString);
58
58
  } else {
59
59
  byte[] selfBytes = selfString.getBytes();
60
- fortitude_escaped_strcpy(outputString, selfBytes);
60
+ fortitude_escaped_strcpy(outputString, selfBytes, false);
61
61
  }
62
62
 
63
63
  return runtime.getNil();
64
64
  }
65
65
 
66
- public static void fortitude_escaped_strcpy(RubyString output, byte[] source) {
66
+ public static void fortitude_escaped_strcpy(RubyString output, byte[] source, boolean forAttributeValue) {
67
67
  byte[] buffer = new byte[BUFFER_SIZE];
68
68
  int bufferPos = 0;
69
69
 
@@ -84,35 +84,47 @@ public class FortitudeNativeLibrary implements Library {
84
84
  buffer[bufferPos++] = ';';
85
85
  break;
86
86
 
87
- case LESS_THAN_BYTE:
87
+ case DOUBLE_QUOTE_BYTE:
88
88
  buffer[bufferPos++] = '&';
89
- buffer[bufferPos++] = 'l';
89
+ buffer[bufferPos++] = 'q';
90
+ buffer[bufferPos++] = 'u';
91
+ buffer[bufferPos++] = 'o';
90
92
  buffer[bufferPos++] = 't';
91
93
  buffer[bufferPos++] = ';';
92
94
  break;
93
95
 
94
- case GREATER_THAN_BYTE:
95
- buffer[bufferPos++] = '&';
96
- buffer[bufferPos++] = 'g';
97
- buffer[bufferPos++] = 't';
98
- buffer[bufferPos++] = ';';
96
+ case LESS_THAN_BYTE:
97
+ if (forAttributeValue) {
98
+ buffer[bufferPos++] = '<';
99
+ } else {
100
+ buffer[bufferPos++] = '&';
101
+ buffer[bufferPos++] = 'l';
102
+ buffer[bufferPos++] = 't';
103
+ buffer[bufferPos++] = ';';
104
+ }
99
105
  break;
100
106
 
101
- case SINGLE_QUOTE_BYTE:
102
- buffer[bufferPos++] = '&';
103
- buffer[bufferPos++] = '#';
104
- buffer[bufferPos++] = '3';
105
- buffer[bufferPos++] = '9';
106
- buffer[bufferPos++] = ';';
107
+ case GREATER_THAN_BYTE:
108
+ if (forAttributeValue) {
109
+ buffer[bufferPos++] = '>';
110
+ } else {
111
+ buffer[bufferPos++] = '&';
112
+ buffer[bufferPos++] = 'g';
113
+ buffer[bufferPos++] = 't';
114
+ buffer[bufferPos++] = ';';
115
+ }
107
116
  break;
108
117
 
109
- case DOUBLE_QUOTE_BYTE:
110
- buffer[bufferPos++] = '&';
111
- buffer[bufferPos++] = 'q';
112
- buffer[bufferPos++] = 'u';
113
- buffer[bufferPos++] = 'o';
114
- buffer[bufferPos++] = 't';
115
- buffer[bufferPos++] = ';';
118
+ case SINGLE_QUOTE_BYTE:
119
+ if (forAttributeValue) {
120
+ buffer[bufferPos++] = '\'';
121
+ } else {
122
+ buffer[bufferPos++] = '&';
123
+ buffer[bufferPos++] = '#';
124
+ buffer[bufferPos++] = '3';
125
+ buffer[bufferPos++] = '9';
126
+ buffer[bufferPos++] = ';';
127
+ }
116
128
  break;
117
129
 
118
130
  default:
@@ -130,11 +142,11 @@ public class FortitudeNativeLibrary implements Library {
130
142
  public static class FortitudeHashExtensions {
131
143
  public static final byte SPACE = (byte) ' ';
132
144
 
133
- public static void fortitude_append_to(IRubyObject object, RubyString rbOutput) {
145
+ public static void fortitude_append_to(IRubyObject object, RubyString rbOutput, boolean forAttributeValue) {
134
146
  if (object instanceof RubyString) {
135
- FortitudeStringExtensions.fortitude_escaped_strcpy(rbOutput, ((RubyString) object).getBytes());
147
+ FortitudeStringExtensions.fortitude_escaped_strcpy(rbOutput, ((RubyString) object).getBytes(), forAttributeValue);
136
148
  } else if (object instanceof RubySymbol) {
137
- FortitudeStringExtensions.fortitude_escaped_strcpy(rbOutput, ((RubyString) ((RubySymbol) object).to_s()).getBytes());
149
+ FortitudeStringExtensions.fortitude_escaped_strcpy(rbOutput, ((RubyString) ((RubySymbol) object).to_s()).getBytes(), forAttributeValue);
138
150
  } else if (object instanceof RubyArray) {
139
151
  RubyArray array = (RubyArray) object;
140
152
 
@@ -143,16 +155,16 @@ public class FortitudeNativeLibrary implements Library {
143
155
  if (i > 0) {
144
156
  rbOutput.cat(SPACE);
145
157
  }
146
- fortitude_append_to(element, rbOutput);
158
+ fortitude_append_to(element, rbOutput, forAttributeValue);
147
159
  }
148
160
  } else if (object instanceof RubyNil) {
149
161
  // nothing here
150
162
  } else if (object instanceof RubyFixnum) {
151
163
  RubyString asString = ((RubyFixnum) object).to_s();
152
- FortitudeStringExtensions.fortitude_escaped_strcpy(rbOutput, asString.getBytes());
164
+ FortitudeStringExtensions.fortitude_escaped_strcpy(rbOutput, asString.getBytes(), forAttributeValue);
153
165
  } else {
154
166
  RubyString asString = (RubyString) ((RubyBasicObject) object).callMethod("to_s");
155
- FortitudeStringExtensions.fortitude_escaped_strcpy(rbOutput, asString.getBytes());
167
+ FortitudeStringExtensions.fortitude_escaped_strcpy(rbOutput, asString.getBytes(), forAttributeValue);
156
168
  }
157
169
  }
158
170
 
@@ -177,10 +189,10 @@ public class FortitudeNativeLibrary implements Library {
177
189
 
178
190
  if (prefix != null) {
179
191
  newPrefix = (RubyString) prefix.dup();
180
- fortitude_append_to(key, newPrefix);
192
+ fortitude_append_to(key, newPrefix, false);
181
193
  } else {
182
194
  newPrefix = RubyString.newEmptyString(runtime);
183
- fortitude_append_to(key, newPrefix);
195
+ fortitude_append_to(key, newPrefix, false);
184
196
  }
185
197
 
186
198
  newPrefix.cat('-');
@@ -196,19 +208,19 @@ public class FortitudeNativeLibrary implements Library {
196
208
  // nothing here
197
209
  }
198
210
 
199
- fortitude_append_to(key, output);
211
+ fortitude_append_to(key, output, false);
200
212
 
201
213
  if ((value instanceof RubyBoolean) && (value.isTrue())) {
202
214
  if (this.allowsBareAttributes.isTrue()) {
203
215
  // ok, nothing here
204
216
  } else {
205
217
  output.cat(EQUALS_QUOTE);
206
- fortitude_append_to(key, output);
218
+ fortitude_append_to(key, output, false);
207
219
  output.cat('"');
208
220
  }
209
221
  } else {
210
222
  output.cat(EQUALS_QUOTE);
211
- fortitude_append_to(value, output);
223
+ fortitude_append_to(value, output, true);
212
224
  output.cat('"');
213
225
  }
214
226
  }
@@ -18,7 +18,7 @@ void Init_fortitude_native_ext() {
18
18
  #define BUF_SIZE 256
19
19
  #define MAX_SUBSTITUTION_LENGTH 6
20
20
 
21
- void fortitude_escaped_strcpy(VALUE rb_output, const char * src) {
21
+ void fortitude_escaped_strcpy(VALUE rb_output, const char * src, int for_attribute_value) {
22
22
  char buf[BUF_SIZE + 1];
23
23
  char* buf_pos = buf;
24
24
  char* max_buf_pos = buf + (BUF_SIZE - MAX_SUBSTITUTION_LENGTH);
@@ -39,29 +39,29 @@ void fortitude_escaped_strcpy(VALUE rb_output, const char * src) {
39
39
  *buf_pos++ = 'm';
40
40
  *buf_pos++ = 'p';
41
41
  *buf_pos++ = ';';
42
- } else if (ch == '<') {
42
+ } else if (ch == '"') {
43
+ *buf_pos++ = '&';
44
+ *buf_pos++ = 'q';
45
+ *buf_pos++ = 'u';
46
+ *buf_pos++ = 'o';
47
+ *buf_pos++ = 't';
48
+ *buf_pos++ = ';';
49
+ } else if (ch == '<' && (! for_attribute_value)) {
43
50
  *buf_pos++ = '&';
44
51
  *buf_pos++ = 'l';
45
52
  *buf_pos++ = 't';
46
53
  *buf_pos++ = ';';
47
- } else if (ch == '>') {
54
+ } else if (ch == '>' && (! for_attribute_value)) {
48
55
  *buf_pos++ = '&';
49
56
  *buf_pos++ = 'g';
50
57
  *buf_pos++ = 't';
51
58
  *buf_pos++ = ';';
52
- } else if (ch == '\'') {
59
+ } else if (ch == '\'' && (! for_attribute_value)) {
53
60
  *buf_pos++ = '&';
54
61
  *buf_pos++ = '#';
55
62
  *buf_pos++ = '3';
56
63
  *buf_pos++ = '9';
57
64
  *buf_pos++ = ';';
58
- } else if (ch == '"') {
59
- *buf_pos++ = '&';
60
- *buf_pos++ = 'q';
61
- *buf_pos++ = 'u';
62
- *buf_pos++ = 'o';
63
- *buf_pos++ = 't';
64
- *buf_pos++ = ';';
65
65
  } else {
66
66
  if (ch == '\0') {
67
67
  break;
@@ -92,11 +92,11 @@ VALUE method_append_escaped_string(VALUE self, VALUE rb_output) {
92
92
  return Qnil;
93
93
  }
94
94
 
95
- fortitude_escaped_strcpy(rb_output, c_self);
95
+ fortitude_escaped_strcpy(rb_output, c_self, 0);
96
96
  return Qnil;
97
97
  }
98
98
 
99
- void fortitude_append_to(VALUE object, VALUE rb_output) {
99
+ void fortitude_append_to(VALUE object, VALUE rb_output, int for_attribute_value) {
100
100
  ID to_s;
101
101
  char buf[25];
102
102
  long value;
@@ -111,11 +111,11 @@ void fortitude_append_to(VALUE object, VALUE rb_output) {
111
111
 
112
112
  switch (TYPE(object)) {
113
113
  case T_STRING:
114
- fortitude_escaped_strcpy(rb_output, RSTRING_PTR(object));
114
+ fortitude_escaped_strcpy(rb_output, RSTRING_PTR(object), for_attribute_value);
115
115
  break;
116
116
 
117
117
  case T_SYMBOL:
118
- fortitude_escaped_strcpy(rb_output, rb_id2name(SYM2ID(object)));
118
+ fortitude_escaped_strcpy(rb_output, rb_id2name(SYM2ID(object)), for_attribute_value);
119
119
  break;
120
120
 
121
121
  case T_ARRAY:
@@ -125,7 +125,7 @@ void fortitude_append_to(VALUE object, VALUE rb_output) {
125
125
  if (i > 0) {
126
126
  rb_str_cat2(rb_output, " ");
127
127
  }
128
- fortitude_append_to(array_element, rb_output);
128
+ fortitude_append_to(array_element, rb_output, for_attribute_value);
129
129
  }
130
130
 
131
131
  case T_NONE:
@@ -140,7 +140,7 @@ void fortitude_append_to(VALUE object, VALUE rb_output) {
140
140
 
141
141
  default:
142
142
  new_string = rb_funcall(object, to_s, 0);
143
- fortitude_escaped_strcpy(rb_output, RSTRING_PTR(new_string));
143
+ fortitude_escaped_strcpy(rb_output, RSTRING_PTR(new_string), for_attribute_value);
144
144
  break;
145
145
  }
146
146
  }
@@ -175,12 +175,12 @@ int fortitude_append_key_and_value(VALUE key, VALUE value, VALUE key_and_value_d
175
175
  switch (TYPE(prefix)) {
176
176
  case T_STRING:
177
177
  new_prefix_as_string = rb_funcall(prefix, dup, 0);
178
- fortitude_append_to(key, new_prefix_as_string);
178
+ fortitude_append_to(key, new_prefix_as_string, 0);
179
179
  break;
180
180
 
181
181
  case T_NIL:
182
182
  new_prefix_as_string = rb_str_new("", 0);
183
- fortitude_append_to(key, new_prefix_as_string);
183
+ fortitude_append_to(key, new_prefix_as_string, 0);
184
184
  break;
185
185
 
186
186
  default:
@@ -212,12 +212,12 @@ int fortitude_append_key_and_value(VALUE key, VALUE value, VALUE key_and_value_d
212
212
  break;
213
213
  }
214
214
 
215
- fortitude_append_to(key, rb_output);
215
+ fortitude_append_to(key, rb_output, 0);
216
216
  if (TYPE(allows_bare_attributes) == T_TRUE) {
217
217
  /* ok */
218
218
  } else {
219
219
  rb_str_cat2(rb_output, "=\"");
220
- fortitude_append_to(key, rb_output);
220
+ fortitude_append_to(key, rb_output, 1);
221
221
  rb_str_cat2(rb_output, "\"");
222
222
  }
223
223
  break;
@@ -238,9 +238,9 @@ int fortitude_append_key_and_value(VALUE key, VALUE value, VALUE key_and_value_d
238
238
  break;
239
239
  }
240
240
 
241
- fortitude_append_to(key, rb_output);
241
+ fortitude_append_to(key, rb_output, 0);
242
242
  rb_str_cat2(rb_output, "=\"");
243
- fortitude_append_to(value, rb_output);
243
+ fortitude_append_to(value, rb_output, 1);
244
244
  rb_str_cat2(rb_output, "\"");
245
245
  break;
246
246
  }