Project

General

Profile

Feature #44415 ยป 0001-Resolve-each-icon-sprite-path-only-once-per-request.patch

Go MAEDA, 2026-09-03 11:35

View differences:

app/helpers/icons_helper.rb
150 150
    css_classes += " #{css_class}" unless css_class.nil?
151 151
    css_classes += " icon-rtl" if rtl
152
    # Resolve each sprite path only once per request: asset_path is not
153
    # cheap and this helper runs for every icon on a page
154
    @sprite_asset_paths ||= {}
155
    path = @sprite_asset_paths[sprite] ||= asset_path(sprite)
156

  
152 157
    content_tag(
153 158
      :svg,
154
      content_tag(:use, '', { 'href' => "#{asset_path(sprite)}#icon--#{icon_name}" }),
159
      content_tag(:use, '', { 'href' => "#{path}#icon--#{icon_name}" }),
155 160
      class: css_classes,
156 161
      aria: {
157 162
        hidden: true
test/helpers/icons_helper_test.rb
144 144
    assert_match expected, icon
145 145
  end
146
  def test_sprite_icon_should_resolve_each_sprite_path_once
147
    expects(:asset_path).with('icons.svg').once.returns('/assets/icons-abc.svg')
148
    expects(:asset_path).with('custom.svg').once.returns('/assets/custom.svg')
149

  
150
    3.times { sprite_icon('edit') }
151
    2.times { sprite_icon('edit', sprite: 'custom') }
152

  
153
    assert_match %r{href="/assets/icons-abc.svg#icon--edit"}, sprite_icon('edit')
154
    assert_match %r{href="/assets/custom.svg#icon--edit"}, sprite_icon('edit', sprite: 'custom')
155
  end
156

  
146 157
  def test_sprite_icon_should_return_svg_with_custom_sprite
147 158
    expected = %r{<svg class="s18 icon-svg" aria-hidden="true"><use href="/assets/custom.svg#icon--edit"></use></svg>$}
148 159
    icon = sprite_icon('edit', sprite: 'custom')
    (1-1/1)