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) %>
|
<%= discourse_stylesheet_link_tag(mobile_view? ? :mobile_theme : :desktop_theme) %>
|
||||||
<%- end %>
|
<%- 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) %>
|
<%= discourse_stylesheet_link_tag(file) %>
|
||||||
<%- end %>
|
<%- end %>
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
<%= preload_script "vendor" %>
|
<%= preload_script "vendor" %>
|
||||||
<%= preload_script "pretty-text-bundle" %>
|
<%= preload_script "pretty-text-bundle" %>
|
||||||
<%= preload_script "application" %>
|
<%= 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 %>
|
<%= preload_script file %>
|
||||||
<%- end %>
|
<%- end %>
|
||||||
<%- if staff? %>
|
<%- if staff? %>
|
||||||
|
|
|
@ -271,6 +271,10 @@ module Discourse
|
||||||
def self.find_plugin_css_assets(args)
|
def self.find_plugin_css_assets(args)
|
||||||
plugins = self.find_plugins(args)
|
plugins = self.find_plugins(args)
|
||||||
|
|
||||||
|
plugins = plugins.select do |plugin|
|
||||||
|
plugin.asset_filters.all? { |b| b.call(:css, args[:request]) }
|
||||||
|
end
|
||||||
|
|
||||||
assets = []
|
assets = []
|
||||||
|
|
||||||
targets = [nil]
|
targets = [nil]
|
||||||
|
@ -289,9 +293,15 @@ module Discourse
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.find_plugin_js_assets(args)
|
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?
|
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
|
end
|
||||||
|
|
||||||
def self.assets_digest
|
def self.assets_digest
|
||||||
|
|
|
@ -49,6 +49,7 @@ class Plugin::Instance
|
||||||
:styles,
|
:styles,
|
||||||
:themes,
|
:themes,
|
||||||
:csp_extensions,
|
:csp_extensions,
|
||||||
|
:asset_filters
|
||||||
].each do |att|
|
].each do |att|
|
||||||
class_eval %Q{
|
class_eval %Q{
|
||||||
def #{att}
|
def #{att}
|
||||||
|
@ -413,6 +414,14 @@ class Plugin::Instance
|
||||||
csp_extensions << extension
|
csp_extensions << extension
|
||||||
end
|
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] :name
|
||||||
# @option opts [String] :nativeName
|
# @option opts [String] :nativeName
|
||||||
# @option opts [String] :fallbackLocale
|
# @option opts [String] :fallbackLocale
|
||||||
|
|
|
@ -20,22 +20,9 @@ DiscourseEvent.on(:after_plugin_activation) do ||
|
||||||
end
|
end
|
||||||
|
|
||||||
after_initialize do
|
after_initialize do
|
||||||
|
# Conditionally load the stylesheet
|
||||||
# Conditionally load the stylesheet. There is unfortunately no easy way to do this via
|
register_asset_filter do |type, request|
|
||||||
# Plugin API.
|
request.nil? || request.env['HTTP_USER_AGENT'] =~ /MSIE|Trident/
|
||||||
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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
register_anonymous_cache_key(:ie) do
|
register_anonymous_cache_key(:ie) do
|
||||||
|
|
|
@ -75,12 +75,17 @@ describe Discourse do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:plugin1) { plugin_class.new.tap { |p| p.enabled = true } }
|
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 } }
|
let(:plugin2) { plugin_class.new.tap { |p| p.enabled = false; p.path = "my-plugin-1" } }
|
||||||
|
|
||||||
before { Discourse.plugins.append(plugin1, plugin2) }
|
before { Discourse.plugins.append(plugin1, plugin2) }
|
||||||
after { Discourse.plugins.clear }
|
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
|
it 'can find plugins correctly' do
|
||||||
expect(Discourse.plugins).to contain_exactly(plugin1, plugin2)
|
expect(Discourse.plugins).to contain_exactly(plugin1, plugin2)
|
||||||
|
|
||||||
|
@ -90,6 +95,19 @@ describe Discourse do
|
||||||
# Include disabled plugins when requested
|
# Include disabled plugins when requested
|
||||||
expect(Discourse.find_plugins(include_disabled: true)).to contain_exactly(plugin1, plugin2)
|
expect(Discourse.find_plugins(include_disabled: true)).to contain_exactly(plugin1, plugin2)
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
context 'authenticators' do
|
context 'authenticators' do
|
||||||
|
|
Loading…
Reference in New Issue