Module: Hyraft::Compiler::HtmlPurifier
- Included in:
- HyraftRenderer
- Defined in:
- lib/hyraft/compiler/html_purifier.rb
Instance Method Summary collapse
-
#escape_html(unsafe) ⇒ Object
Alias for purify_html for different use cases.
-
#format_datetime(datetime, format: '%Y-%m-%d %H:%M', default: '') ⇒ String
Format datetime object.
-
#highlight_text(text, term, highlight_tag: 'mark', css_class: nil) ⇒ String
Highlight text with search term while maintaining HTML safety.
-
#highlight_with_class(text, term, highlight_class: 'bg-warning text-dark px-1 rounded') ⇒ String
Alternative highlighting with span and default Bootstrap classes.
-
#link_to(text, url, **attrs) ⇒ String
Create a safe HTML link.
-
#number_with_delimiter(number, delimiter: ',', separator: '.') ⇒ String
Format a number with commas (e.g., 1000 -> “1,000”).
-
#pluralize(count, singular, plural = nil) ⇒ String
Pluralize a word based on count.
-
#purify_html(unsafe) ⇒ Object
Purifies HTML content by escaping dangerous characters to prevent XSS attacks Usage: purify_html(user_input) - makes any string safe for HTML output.
-
#purify_html_attribute(unsafe) ⇒ Object
Additional HTML safety methods.
- #purify_javascript(unsafe) ⇒ Object
-
#truncate_text(text, length: 100, suffix: '...', preserve_words: false) ⇒ String
Truncate text to specified length.
Instance Method Details
#escape_html(unsafe) ⇒ Object
Alias for purify_html for different use cases
18 19 20 |
# File 'lib/hyraft/compiler/html_purifier.rb', line 18 def escape_html(unsafe) purify_html(unsafe) end |
#format_datetime(datetime, format: '%Y-%m-%d %H:%M', default: '') ⇒ String
Format datetime object
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/hyraft/compiler/html_purifier.rb', line 137 def format_datetime(datetime, format: '%Y-%m-%d %H:%M', default: '') return default unless datetime if datetime.is_a?(String) # Try to parse the string begin datetime = Time.parse(datetime) rescue return default end end if datetime.respond_to?(:strftime) datetime.strftime(format) else default end end |
#highlight_text(text, term, highlight_tag: 'mark', css_class: nil) ⇒ String
Highlight text with search term while maintaining HTML safety
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/hyraft/compiler/html_purifier.rb', line 51 def highlight_text(text, term, highlight_tag: 'mark', css_class: nil) return text if term.empty? || text.empty? # First purify the text to make it safe safe_text = purify_html(text) safe_term = purify_html(term) # Escape the term for regex escaped_term = Regexp.escape(safe_term) # Build the opening tag with optional CSS class opening_tag = if css_class "<#{highlight_tag} class=\"#{purify_html_attribute(css_class)}\">" else "<#{highlight_tag}>" end closing_tag = "</#{highlight_tag}>" # Highlight the term safe_text.gsub(/(#{escaped_term})/i) do |match| "#{opening_tag}#{match}#{closing_tag}" end end |
#highlight_with_class(text, term, highlight_class: 'bg-warning text-dark px-1 rounded') ⇒ String
Alternative highlighting with span and default Bootstrap classes
81 82 83 |
# File 'lib/hyraft/compiler/html_purifier.rb', line 81 def highlight_with_class(text, term, highlight_class: 'bg-warning text-dark px-1 rounded') highlight_text(text, term, highlight_tag: 'span', css_class: highlight_class) end |
#link_to(text, url, **attrs) ⇒ String
Create a safe HTML link
121 122 123 124 125 126 127 128 129 130 |
# File 'lib/hyraft/compiler/html_purifier.rb', line 121 def link_to(text, url, **attrs) # Build attributes string attr_string = attrs.map do |key, value| "#{key}=\"#{purify_html_attribute(value)}\"" end.join(' ') attr_string = " #{attr_string}" unless attr_string.empty? "<a href=\"#{purify_html_attribute(url)}\"#{attr_string}>#{purify_html(text)}</a>" end |
#number_with_delimiter(number, delimiter: ',', separator: '.') ⇒ String
Format a number with commas (e.g., 1000 -> “1,000”)
161 162 163 164 165 166 167 168 |
# File 'lib/hyraft/compiler/html_purifier.rb', line 161 def number_with_delimiter(number, delimiter: ',', separator: '.') return '' unless number parts = number.to_s.split('.') parts[0] = parts[0].reverse.scan(/\d{1,3}/).join(delimiter).reverse parts.join(separator) end |
#pluralize(count, singular, plural = nil) ⇒ String
Pluralize a word based on count
175 176 177 178 |
# File 'lib/hyraft/compiler/html_purifier.rb', line 175 def pluralize(count, singular, plural = nil) plural ||= singular + 's' count == 1 ? "1 #{singular}" : "#{count} #{plural}" end |
#purify_html(unsafe) ⇒ Object
Purifies HTML content by escaping dangerous characters to prevent XSS attacks Usage: purify_html(user_input) - makes any string safe for HTML output
7 8 9 10 11 12 13 14 15 |
# File 'lib/hyraft/compiler/html_purifier.rb', line 7 def purify_html(unsafe) return '' unless unsafe unsafe.to_s .gsub(/&/, "&") .gsub(/</, "<") .gsub(/>/, ">") .gsub(/"/, """) .gsub(/'/, "'") end |
#purify_html_attribute(unsafe) ⇒ Object
Additional HTML safety methods
23 24 25 26 27 28 29 30 31 32 |
# File 'lib/hyraft/compiler/html_purifier.rb', line 23 def purify_html_attribute(unsafe) return '' unless unsafe unsafe.to_s .gsub(/&/, "&") .gsub(/</, "<") .gsub(/>/, ">") .gsub(/"/, """) .gsub(/'/, "'") .gsub(/\//, "/") end |
#purify_javascript(unsafe) ⇒ Object
34 35 36 37 38 39 40 41 42 43 |
# File 'lib/hyraft/compiler/html_purifier.rb', line 34 def purify_javascript(unsafe) return '' unless unsafe unsafe.to_s .gsub(/\\/, "\\\\") .gsub(/'/, "\\'") .gsub(/"/, "\\\"") .gsub(/\n/, "\\n") .gsub(/\r/, "\\r") .gsub(/</, "\\u003C") end |
#truncate_text(text, length: 100, suffix: '...', preserve_words: false) ⇒ String
Truncate text to specified length
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/hyraft/compiler/html_purifier.rb', line 93 def truncate_text(text, length: 100, suffix: '...', preserve_words: false) return '' unless text text = text.to_s if text.length <= length return text end if preserve_words # Try to break at a word boundary truncated = text[0, length] last_space = truncated.rindex(/\s/) if last_space && last_space > length * 0.8 # Only break if we have a reasonable word boundary truncated = text[0, last_space] end truncated + suffix else text[0, length] + suffix end end |