|  | 
| 14 | 14 | #  * https://github.com/shakacode/react_on_rails/blob/master/REACT-ON-RAILS-PRO-LICENSE.md | 
| 15 | 15 | #  */ | 
| 16 | 16 | 
 | 
| 17 |  | -module ReactOnRails::Pro | 
| 18 |  | -  module Helper | 
| 19 |  | -    IMMEDIATE_HYDRATION_PRO_WARNING = "[REACT ON RAILS] The 'immediate_hydration' feature requires a " \ | 
| 20 |  | -                                      "React on Rails Pro license. " \ | 
| 21 |  | -                                      "Please visit https://shakacode.com/react-on-rails-pro to learn more." | 
|  | 17 | +module ReactOnRails | 
|  | 18 | +  module Pro | 
|  | 19 | +    module Helper | 
|  | 20 | +      IMMEDIATE_HYDRATION_PRO_WARNING = "[REACT ON RAILS] The 'immediate_hydration' feature requires a " \ | 
|  | 21 | +                                        "React on Rails Pro license. " \ | 
|  | 22 | +                                        "Please visit https://shakacode.com/react-on-rails-pro to learn more." | 
| 22 | 23 | 
 | 
| 23 |  | -    # Generates the complete component specification script tag. | 
| 24 |  | -    # Handles both immediate hydration (Pro feature) and standard cases. | 
| 25 |  | -    def generate_component_script(render_options) | 
| 26 |  | -      # Setup the page_loaded_js, which is the same regardless of prerendering or not! | 
| 27 |  | -      # The reason is that React is smart about not doing extra work if the server rendering did its job. | 
| 28 |  | -      component_specification_tag = content_tag(:script, | 
| 29 |  | -        json_safe_and_pretty(render_options.client_props).html_safe, | 
| 30 |  | -        type: "application/json", | 
| 31 |  | -        class: "js-react-on-rails-component", | 
| 32 |  | -        id: "js-react-on-rails-component-#{render_options.dom_id}", | 
| 33 |  | -        "data-component-name" => render_options.react_component_name, | 
| 34 |  | -        "data-trace" => (render_options.trace ? true : nil), | 
| 35 |  | -        "data-dom-id" => render_options.dom_id, | 
| 36 |  | -        "data-store-dependencies" => render_options.store_dependencies&.to_json, | 
| 37 |  | -        "data-immediate-hydration" => | 
| 38 |  | -          (render_options.immediate_hydration ? true : nil)) | 
|  | 24 | +      # Generates the complete component specification script tag. | 
|  | 25 | +      # Handles both immediate hydration (Pro feature) and standard cases. | 
|  | 26 | +      def generate_component_script(render_options) | 
|  | 27 | +        # Setup the page_loaded_js, which is the same regardless of prerendering or not! | 
|  | 28 | +        # The reason is that React is smart about not doing extra work if the server rendering did its job. | 
|  | 29 | +        component_specification_tag = content_tag(:script, | 
|  | 30 | +                                                  json_safe_and_pretty(render_options.client_props).html_safe, | 
|  | 31 | +                                                  type: "application/json", | 
|  | 32 | +                                                  class: "js-react-on-rails-component", | 
|  | 33 | +                                                  id: "js-react-on-rails-component-#{render_options.dom_id}", | 
|  | 34 | +                                                  "data-component-name" => render_options.react_component_name, | 
|  | 35 | +                                                  "data-trace" => (render_options.trace ? true : nil), | 
|  | 36 | +                                                  "data-dom-id" => render_options.dom_id, | 
|  | 37 | +                                                  "data-store-dependencies" => render_options.store_dependencies&.to_json, | 
|  | 38 | +                                                  "data-immediate-hydration" => | 
|  | 39 | +                                                    (render_options.immediate_hydration ? true : nil)) | 
| 39 | 40 | 
 | 
| 40 |  | -      # Add immediate invocation script if immediate hydration is enabled | 
| 41 |  | -      spec_tag = if render_options.immediate_hydration | 
| 42 |  | -        # Escape dom_id for JavaScript context | 
| 43 |  | -        escaped_dom_id = escape_javascript(render_options.dom_id) | 
| 44 |  | -        immediate_script = content_tag(:script, %( | 
|  | 41 | +        # Add immediate invocation script if immediate hydration is enabled | 
|  | 42 | +        spec_tag = if render_options.immediate_hydration | 
|  | 43 | +                     # Escape dom_id for JavaScript context | 
|  | 44 | +                     escaped_dom_id = escape_javascript(render_options.dom_id) | 
|  | 45 | +                     immediate_script = content_tag(:script, %( | 
| 45 | 46 |           typeof ReactOnRails === 'object' && ReactOnRails.reactOnRailsComponentLoaded('#{escaped_dom_id}'); | 
| 46 | 47 |         ).html_safe) | 
| 47 |  | -        "#{component_specification_tag}\n#{immediate_script}" | 
| 48 |  | -      else | 
| 49 |  | -        component_specification_tag | 
|  | 48 | +                     "#{component_specification_tag}\n#{immediate_script}" | 
|  | 49 | +                   else | 
|  | 50 | +                     component_specification_tag | 
|  | 51 | +                   end | 
|  | 52 | + | 
|  | 53 | +        pro_warning_badge = pro_warning_badge_if_needed(render_options.explicitly_disabled_pro_options) | 
|  | 54 | +        "#{pro_warning_badge}\n#{spec_tag}".html_safe | 
| 50 | 55 |       end | 
| 51 | 56 | 
 | 
| 52 |  | -      pro_warning_badge = pro_warning_badge_if_needed(render_options.explicitly_disabled_pro_options) | 
| 53 |  | -      "#{pro_warning_badge}\n#{spec_tag}".html_safe | 
| 54 |  | -    end | 
|  | 57 | +      # Generates the complete store hydration script tag. | 
|  | 58 | +      # Handles both immediate hydration (Pro feature) and standard cases. | 
|  | 59 | +      def generate_store_script(redux_store_data) | 
|  | 60 | +        pro_options_check_result = ReactOnRails::Pro::Utils.disable_pro_render_options_if_not_licensed(redux_store_data) | 
|  | 61 | +        redux_store_data = pro_options_check_result[:raw_options] | 
|  | 62 | +        explicitly_disabled_pro_options = pro_options_check_result[:explicitly_disabled_pro_options] | 
| 55 | 63 | 
 | 
| 56 |  | -    # Generates the complete store hydration script tag. | 
| 57 |  | -    # Handles both immediate hydration (Pro feature) and standard cases. | 
| 58 |  | -    def generate_store_script(redux_store_data) | 
| 59 |  | -      pro_options_check_result = ReactOnRails::Pro::Utils.disable_pro_render_options_if_not_licensed(redux_store_data) | 
| 60 |  | -      redux_store_data = pro_options_check_result[:raw_options] | 
| 61 |  | -      explicitly_disabled_pro_options = pro_options_check_result[:explicitly_disabled_pro_options] | 
|  | 64 | +        store_hydration_data = content_tag(:script, | 
|  | 65 | +                                           json_safe_and_pretty(redux_store_data[:props]).html_safe, | 
|  | 66 | +                                           type: "application/json", | 
|  | 67 | +                                           "data-js-react-on-rails-store" => redux_store_data[:store_name].html_safe, | 
|  | 68 | +                                           "data-immediate-hydration" => | 
|  | 69 | +                                             (redux_store_data[:immediate_hydration] ? true : nil)) | 
| 62 | 70 | 
 | 
| 63 |  | -      store_hydration_data = content_tag(:script, | 
| 64 |  | -        json_safe_and_pretty(redux_store_data[:props]).html_safe, | 
| 65 |  | -        type: "application/json", | 
| 66 |  | -        "data-js-react-on-rails-store" => redux_store_data[:store_name].html_safe, | 
| 67 |  | -        "data-immediate-hydration" => | 
| 68 |  | -          (redux_store_data[:immediate_hydration] ? true : nil)) | 
|  | 71 | +        # Add immediate invocation script if immediate hydration is enabled and Pro license is valid | 
|  | 72 | +        store_hydration_scripts = if redux_store_data[:immediate_hydration] | 
|  | 73 | +                                    # Escape store_name for JavaScript context | 
|  | 74 | +                                    escaped_store_name = escape_javascript(redux_store_data[:store_name]) | 
|  | 75 | +                                    immediate_script = content_tag(:script, <<~JS.strip_heredoc.html_safe | 
|  | 76 | +                                      typeof ReactOnRails === 'object' && ReactOnRails.reactOnRailsStoreLoaded('#{escaped_store_name}'); | 
|  | 77 | +                                    JS | 
|  | 78 | +                                    ) | 
|  | 79 | +                                    "#{store_hydration_data}\n#{immediate_script}" | 
|  | 80 | +                                  else | 
|  | 81 | +                                    store_hydration_data | 
|  | 82 | +                                  end | 
| 69 | 83 | 
 | 
| 70 |  | -      # Add immediate invocation script if immediate hydration is enabled and Pro license is valid | 
| 71 |  | -      store_hydration_scripts =if redux_store_data[:immediate_hydration] | 
| 72 |  | -        # Escape store_name for JavaScript context | 
| 73 |  | -        escaped_store_name = escape_javascript(redux_store_data[:store_name]) | 
| 74 |  | -        immediate_script = content_tag(:script, <<~JS.strip_heredoc.html_safe | 
| 75 |  | -          typeof ReactOnRails === 'object' && ReactOnRails.reactOnRailsStoreLoaded('#{escaped_store_name}'); | 
| 76 |  | -        JS | 
| 77 |  | -        ) | 
| 78 |  | -        "#{store_hydration_data}\n#{immediate_script}" | 
| 79 |  | -      else | 
| 80 |  | -        store_hydration_data | 
|  | 84 | +        pro_warning_badge = pro_warning_badge_if_needed(explicitly_disabled_pro_options) | 
|  | 85 | +        "#{pro_warning_badge}\n#{store_hydration_scripts}".html_safe | 
| 81 | 86 |       end | 
| 82 | 87 | 
 | 
| 83 |  | -      pro_warning_badge = pro_warning_badge_if_needed(explicitly_disabled_pro_options) | 
| 84 |  | -      "#{pro_warning_badge}\n#{store_hydration_scripts}".html_safe | 
| 85 |  | -    end | 
| 86 |  | - | 
| 87 |  | -    def pro_warning_badge_if_needed(explicitly_disabled_pro_options) | 
| 88 |  | -      return "" unless explicitly_disabled_pro_options.any? | 
|  | 88 | +      def pro_warning_badge_if_needed(explicitly_disabled_pro_options) | 
|  | 89 | +        return "" unless explicitly_disabled_pro_options.any? | 
| 89 | 90 | 
 | 
| 90 |  | -      disabled_features_message = disabled_pro_features_message(explicitly_disabled_pro_options) | 
| 91 |  | -      warning_message = "[REACT ON RAILS] #{disabled_features_message}" + "\n" + | 
| 92 |  | -                        "Please visit https://shakacode.com/react-on-rails-pro to learn more." | 
| 93 |  | -      puts warning_message | 
| 94 |  | -      Rails.logger.warn warning_message | 
|  | 91 | +        disabled_features_message = disabled_pro_features_message(explicitly_disabled_pro_options) | 
|  | 92 | +        warning_message = "[REACT ON RAILS] #{disabled_features_message}\n" \ | 
|  | 93 | +                          "Please visit https://shakacode.com/react-on-rails-pro to learn more." | 
|  | 94 | +        puts warning_message | 
|  | 95 | +        Rails.logger.warn warning_message | 
| 95 | 96 | 
 | 
| 96 |  | -      tooltip_text = "#{disabled_features_message} Click to learn more." | 
|  | 97 | +        tooltip_text = "#{disabled_features_message} Click to learn more." | 
| 97 | 98 | 
 | 
| 98 |  | -      badge_html = <<~HTML.strip | 
| 99 |  | -        <a href="https://shakacode.com/react-on-rails-pro" target="_blank" rel="noopener noreferrer" title="#{tooltip_text}"> | 
| 100 |  | -          <div style="position: fixed; top: 0; right: 0; width: 180px; height: 180px; overflow: hidden; z-index: 9999; pointer-events: none;"> | 
| 101 |  | -            <div style="position: absolute; top: 50px; right: -40px; transform: rotate(45deg); background-color: rgba(220, 53, 69, 0.85); color: white; padding: 7px 40px; text-align: center; font-weight: bold; font-family: sans-serif; font-size: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.3); pointer-events: auto;"> | 
| 102 |  | -              React On Rails Pro Required | 
|  | 99 | +        <<~HTML.strip | 
|  | 100 | +          <a href="https://shakacode.com/react-on-rails-pro" target="_blank" rel="noopener noreferrer" title="#{tooltip_text}"> | 
|  | 101 | +            <div style="position: fixed; top: 0; right: 0; width: 180px; height: 180px; overflow: hidden; z-index: 9999; pointer-events: none;"> | 
|  | 102 | +              <div style="position: absolute; top: 50px; right: -40px; transform: rotate(45deg); background-color: rgba(220, 53, 69, 0.85); color: white; padding: 7px 40px; text-align: center; font-weight: bold; font-family: sans-serif; font-size: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.3); pointer-events: auto;"> | 
|  | 103 | +                React On Rails Pro Required | 
|  | 104 | +              </div> | 
| 103 | 105 |             </div> | 
| 104 |  | -          </div> | 
| 105 |  | -        </a> | 
| 106 |  | -      HTML | 
| 107 |  | -      badge_html | 
| 108 |  | -    end | 
|  | 106 | +          </a> | 
|  | 107 | +        HTML | 
|  | 108 | +      end | 
| 109 | 109 | 
 | 
| 110 |  | -    def disabled_pro_features_message(explicitly_disabled_pro_options) | 
| 111 |  | -      return "".html_safe unless explicitly_disabled_pro_options.any? | 
|  | 110 | +      def disabled_pro_features_message(explicitly_disabled_pro_options) | 
|  | 111 | +        return "".html_safe unless explicitly_disabled_pro_options.any? | 
| 112 | 112 | 
 | 
| 113 |  | -      feature_list = explicitly_disabled_pro_options.join(', ') | 
| 114 |  | -      feature_word = explicitly_disabled_pro_options.size == 1 ? "feature" : "features" | 
| 115 |  | -      "The '#{feature_list}' #{feature_word} #{explicitly_disabled_pro_options.size == 1 ? 'requires' : 'require'} a " \ | 
| 116 |  | -      "React on Rails Pro license. " | 
|  | 113 | +        feature_list = explicitly_disabled_pro_options.join(", ") | 
|  | 114 | +        feature_word = explicitly_disabled_pro_options.size == 1 ? "feature" : "features" | 
|  | 115 | +        "The '#{feature_list}' #{feature_word} #{explicitly_disabled_pro_options.size == 1 ? 'requires' : 'require'} a " \ | 
|  | 116 | +          "React on Rails Pro license. " | 
|  | 117 | +      end | 
| 117 | 118 |     end | 
| 118 | 119 |   end | 
| 119 | 120 | end | 
0 commit comments