diff --git a/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb b/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb index e2a566844..c7d2bd3ec 100644 --- a/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +++ b/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb @@ -6,9 +6,11 @@ def scrolled_theme_asset_path(theme, theme_file_role: nil, theme_file_style: :resized, relative_url: false) + theme_directory, path = extract_theme_directory_from_scrolled_theme_asset_path(theme, path) + path = theme.files.dig(theme_file_role, theme_file_style) || - asset_pack_path("static/pageflow-scrolled/themes/#{theme.name}/#{path}") + asset_pack_path("static/pageflow-scrolled/themes/#{theme_directory}/#{path}") if relative_url URI.parse(path).path @@ -122,5 +124,17 @@ def scrolled_theme_deep_declarations(hash, suffix = nil, prefix = []) end end end + + def extract_theme_directory_from_scrolled_theme_asset_path(theme, path) + if path.starts_with?('../shared/') + ['shared', path.gsub!('../shared/', '')] + elsif path.starts_with?('../') + raise(ArgumentError, + 'Upward navigation to other directory than the shared ' \ + 'theme directory not allowed in theme asset path.') + else + [theme.name, path] + end + end end end diff --git a/entry_types/scrolled/spec/helpers/pageflow_scrolled/entry_json_seed_helper_spec.rb b/entry_types/scrolled/spec/helpers/pageflow_scrolled/entry_json_seed_helper_spec.rb index 61eb8ea6a..f44ae386e 100644 --- a/entry_types/scrolled/spec/helpers/pageflow_scrolled/entry_json_seed_helper_spec.rb +++ b/entry_types/scrolled/spec/helpers/pageflow_scrolled/entry_json_seed_helper_spec.rb @@ -737,6 +737,34 @@ def render(helper, entry, options = {}) }) end + it 'supports shared theme directory in custom icons directories' do + pageflow_configure do |config| + config.themes.register(:default, + custom_icons: [:share], + custom_icons_directory: '../shared/icons') + end + entry = create(:published_entry, type_name: 'scrolled') + default_theme_directory = Rails.root.join('app/javascript/pageflow-scrolled/themes/default') + shared_theme_directory = Rails.root.join('app/javascript/pageflow-scrolled/themes/shared') + FileUtils.mkdir_p(shared_theme_directory.join('icons')) + FileUtils.cp( + default_theme_directory.join('icons/share.svg'), + shared_theme_directory.join('icons/share.svg') + ) + + result = render(helper, entry) + + expect(result).to include_json(config: { + theme: { + assets: { + icons: { + share: %r{themes/shared/icons/share.*svg$} + } + } + } + }) + end + it 'does not use asset host in icon paths to allow xlink:href usage' do controller.config.asset_host = 'some-asset-host' pageflow_configure do |config| diff --git a/entry_types/scrolled/spec/helpers/pageflow_scrolled/themes_helper_spec.rb b/entry_types/scrolled/spec/helpers/pageflow_scrolled/themes_helper_spec.rb index 1b6d3a88c..8fa9b91f3 100644 --- a/entry_types/scrolled/spec/helpers/pageflow_scrolled/themes_helper_spec.rb +++ b/entry_types/scrolled/spec/helpers/pageflow_scrolled/themes_helper_spec.rb @@ -2,6 +2,42 @@ module PageflowScrolled RSpec.describe ThemesHelper, type: :helper do + describe '#scrolled_theme_asset_path' do + it 'retrieves asset pack path from theme directory' do + entry = create(:entry) + theme = Pageflow::Theme.new(:test) + customized_theme = Pageflow::CustomizedTheme.find(entry: , theme:) + + expect(helper).to receive(:asset_pack_path).with( + 'static/pageflow-scrolled/themes/test/icons/muted.svg' + ) + + helper.scrolled_theme_asset_path(customized_theme, 'icons/muted.svg') + end + + it 'expands relative path to shared theme directory' do + entry = create(:entry) + theme = Pageflow::Theme.new(:test) + customized_theme = Pageflow::CustomizedTheme.find(entry: , theme:) + + expect(helper).to receive(:asset_pack_path).with( + 'static/pageflow-scrolled/themes/shared/icons/muted.svg' + ) + + helper.scrolled_theme_asset_path(customized_theme, '../shared/icons/muted.svg') + end + + it 'raises helpful error for relative paths to other sibling or parent directory' do + entry = create(:entry) + theme = Pageflow::Theme.new(:test) + customized_theme = Pageflow::CustomizedTheme.find(entry: , theme:) + + expect { + helper.scrolled_theme_asset_path(customized_theme, '../other/icons/muted.svg') + }.to raise_error(/not allowed in theme asset path/) + end + end + describe '#scrolled_theme_stylesheet_pack_tags' do it 'renders stylesheet pack tags for theme' do theme = Pageflow::Theme.new(:test, stylesheet_packs: ['fonts/sourceSansPro'])