DEV: Introduce plugin api for conditionally rendering assets (#9200)
This commit is contained in:
parent
8a4784d36f
commit
3d71b68195
|
@ -12,6 +12,6 @@
|
|||
<%= discourse_stylesheet_link_tag(mobile_view? ? :mobile_theme : :desktop_theme) %>
|
||||
<%- end %>
|
||||
|
||||
<%- Discourse.find_plugin_css_assets(include_official: allow_plugins?, include_unofficial: allow_third_party_plugins?, mobile_view: mobile_view?, desktop_view: !mobile_view?).each do |file| %>
|
||||
<%- Discourse.find_plugin_css_assets(include_official: allow_plugins?, include_unofficial: allow_third_party_plugins?, mobile_view: mobile_view?, desktop_view: !mobile_view?, request: request).each do |file| %>
|
||||
<%= discourse_stylesheet_link_tag(file) %>
|
||||
<%- end %>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<%= preload_script "vendor" %>
|
||||
<%= preload_script "pretty-text-bundle" %>
|
||||
<%= preload_script "application" %>
|
||||
<%- Discourse.find_plugin_js_assets(include_official: allow_plugins?, include_unofficial: allow_third_party_plugins?).each do |file| %>
|
||||
<%- Discourse.find_plugin_js_assets(include_official: allow_plugins?, include_unofficial: allow_third_party_plugins?, request: request).each do |file| %>
|
||||
<%= preload_script file %>
|
||||
<%- end %>
|
||||
<%- if staff? %>
|
||||
|
|
|
@ -271,6 +271,10 @@ module Discourse
|
|||
def self.find_plugin_css_assets(args)
|
||||
plugins = self.find_plugins(args)
|
||||
|
||||
plugins = plugins.select do |plugin|
|
||||
plugin.asset_filters.all? { |b| b.call(:css, args[:request]) }
|
||||
end
|
||||
|
||||
assets = []
|
||||
|
||||
targets = [nil]
|
||||
|
@ -289,9 +293,15 @@ module Discourse
|
|||
end
|
||||
|
||||
def self.find_plugin_js_assets(args)
|
||||
self.find_plugins(args).find_all do |plugin|
|
||||
plugins = self.find_plugins(args).select do |plugin|
|
||||
plugin.js_asset_exists?
|
||||
end.map { |plugin| "plugins/#{plugin.directory_name}" }
|
||||
end
|
||||
|
||||
plugins = plugins.select do |plugin|
|
||||
plugin.asset_filters.all? { |b| b.call(:js, args[:request]) }
|
||||
end
|
||||
|
||||
plugins.map { |plugin| "plugins/#{plugin.directory_name}" }
|
||||
end
|
||||
|
||||
def self.assets_digest
|
||||
|
|
|
@ -49,6 +49,7 @@ class Plugin::Instance
|
|||
:styles,
|
||||
:themes,
|
||||
:csp_extensions,
|
||||
:asset_filters
|
||||
].each do |att|
|
||||
class_eval %Q{
|
||||
def #{att}
|
||||
|
@ -413,6 +414,14 @@ class Plugin::Instance
|
|||
csp_extensions << extension
|
||||
end
|
||||
|
||||
# Register a block to run when adding css and js assets
|
||||
# Two arguments will be passed: (type, request)
|
||||
# Type is :css or :js. `request` is an instance of Rack::Request
|
||||
# When using this, make sure to consider the effect on AnonymousCache
|
||||
def register_asset_filter(&blk)
|
||||
asset_filters << blk
|
||||
end
|
||||
|
||||
# @option opts [String] :name
|
||||
# @option opts [String] :nativeName
|
||||
# @option opts [String] :fallbackLocale
|
||||
|
|
|
@ -20,22 +20,9 @@ DiscourseEvent.on(:after_plugin_activation) do ||
|
|||
end
|
||||
|
||||
after_initialize do
|
||||
|
||||
# Conditionally load the stylesheet. There is unfortunately no easy way to do this via
|
||||
# Plugin API.
|
||||
reloadable_patch do |plugin|
|
||||
ApplicationHelper.module_eval do
|
||||
alias_method :previous_discourse_stylesheet_link_tag, :discourse_stylesheet_link_tag
|
||||
def discourse_stylesheet_link_tag(name, opts = {})
|
||||
|
||||
if name == 'discourse-internet-explorer'
|
||||
return unless SiteSetting.discourse_internet_explorer_enabled?
|
||||
return unless request.env['HTTP_USER_AGENT'] =~ /MSIE|Trident/
|
||||
end
|
||||
|
||||
previous_discourse_stylesheet_link_tag(name, opts)
|
||||
end
|
||||
end
|
||||
# Conditionally load the stylesheet
|
||||
register_asset_filter do |type, request|
|
||||
request.nil? || request.env['HTTP_USER_AGENT'] =~ /MSIE|Trident/
|
||||
end
|
||||
|
||||
register_anonymous_cache_key(:ie) do
|
||||
|
|
|
@ -75,12 +75,17 @@ describe Discourse do
|
|||
end
|
||||
end
|
||||
|
||||
let(:plugin1) { plugin_class.new.tap { |p| p.enabled = true } }
|
||||
let(:plugin2) { plugin_class.new.tap { |p| p.enabled = false } }
|
||||
let(:plugin1) { plugin_class.new.tap { |p| p.enabled = true; p.path = "my-plugin-1" } }
|
||||
let(:plugin2) { plugin_class.new.tap { |p| p.enabled = false; p.path = "my-plugin-1" } }
|
||||
|
||||
before { Discourse.plugins.append(plugin1, plugin2) }
|
||||
after { Discourse.plugins.clear }
|
||||
|
||||
before do
|
||||
plugin_class.any_instance.stubs(:css_asset_exists?).returns(true)
|
||||
plugin_class.any_instance.stubs(:js_asset_exists?).returns(true)
|
||||
end
|
||||
|
||||
it 'can find plugins correctly' do
|
||||
expect(Discourse.plugins).to contain_exactly(plugin1, plugin2)
|
||||
|
||||
|
@ -90,6 +95,19 @@ describe Discourse do
|
|||
# Include disabled plugins when requested
|
||||
expect(Discourse.find_plugins(include_disabled: true)).to contain_exactly(plugin1, plugin2)
|
||||
end
|
||||
|
||||
it 'can find plugin assets' do
|
||||
plugin2.enabled = true
|
||||
|
||||
expect(Discourse.find_plugin_css_assets({}).length).to eq(2)
|
||||
expect(Discourse.find_plugin_js_assets({}).length).to eq(2)
|
||||
plugin1.register_asset_filter do |type, request|
|
||||
false
|
||||
end
|
||||
expect(Discourse.find_plugin_css_assets({}).length).to eq(1)
|
||||
expect(Discourse.find_plugin_js_assets({}).length).to eq(1)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'authenticators' do
|
||||
|
|
Loading…
Reference in New Issue