mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 23:06:57 +08:00
c2fcd55a80
Prior to this commit, we didn't have RTL versions of our admin and plugins CSS bundles and we always served LTR versions of those bundles even when users used an RTL locale, causing admin and plugins UI elements to never look as good as when an LTR locale was used. Example of UI issues prior to this commit were: missing margins, borders on the wrong side and buttons too close to each other etc. This commit creates an RTL version for the admin CSS bundle as well as RTL bundles for all the installed plugins and serves those RTL bundles to users/sites who use RTL locales.
188 lines
5.4 KiB
Ruby
188 lines
5.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class BootstrapController < ApplicationController
|
|
include ApplicationHelper
|
|
|
|
skip_before_action :redirect_to_login_if_required, :check_xhr
|
|
|
|
# This endpoint allows us to produce the data required to start up Discourse via JSON API,
|
|
# so that you don't have to scrape the HTML for `data-*` payloads
|
|
def index
|
|
locale = script_asset_path("locales/#{I18n.locale}")
|
|
|
|
preload_anonymous_data
|
|
if current_user
|
|
current_user.sync_notification_channel_position
|
|
preload_current_user_data
|
|
end
|
|
|
|
@stylesheets = []
|
|
|
|
add_scheme(scheme_id, "all", "light-scheme")
|
|
add_scheme(dark_scheme_id, "(prefers-color-scheme: dark)", "dark-scheme")
|
|
|
|
if rtl?
|
|
add_style(mobile_view? ? :mobile_rtl : :desktop_rtl)
|
|
else
|
|
add_style(mobile_view? ? :mobile : :desktop)
|
|
end
|
|
add_style(rtl? ? :admin_rtl : :admin) if staff?
|
|
add_style(rtl? ? :wizard_rtl : :wizard) if admin?
|
|
|
|
assets_fake_request = ActionDispatch::Request.new(request.env.dup)
|
|
assets_for_url = params[:for_url]
|
|
if assets_for_url
|
|
path, query = assets_for_url.split("?", 2)
|
|
assets_fake_request.env["PATH_INFO"] = path
|
|
assets_fake_request.env["QUERY_STRING"] = query
|
|
end
|
|
|
|
Discourse
|
|
.find_plugin_css_assets(
|
|
include_official: allow_plugins?,
|
|
include_unofficial: allow_third_party_plugins?,
|
|
mobile_view: mobile_view?,
|
|
desktop_view: !mobile_view?,
|
|
request: assets_fake_request,
|
|
rtl: rtl?,
|
|
)
|
|
.each { |file| add_style(file, plugin: true) }
|
|
add_style(mobile_view? ? :mobile_theme : :desktop_theme) if theme_id.present?
|
|
|
|
extra_locales = []
|
|
if ExtraLocalesController.client_overrides_exist?
|
|
extra_locales << ExtraLocalesController.url("overrides")
|
|
end
|
|
|
|
extra_locales << ExtraLocalesController.url("admin") if staff?
|
|
|
|
extra_locales << ExtraLocalesController.url("wizard") if admin?
|
|
|
|
plugin_js =
|
|
Discourse
|
|
.find_plugin_js_assets(
|
|
include_official: allow_plugins?,
|
|
include_unofficial: allow_third_party_plugins?,
|
|
request: assets_fake_request,
|
|
)
|
|
.map { |f| script_asset_path(f) }
|
|
|
|
plugin_test_js =
|
|
if Rails.env != "production"
|
|
script_asset_path("plugin-tests")
|
|
else
|
|
[]
|
|
end
|
|
|
|
bootstrap = {
|
|
theme_id: theme_id,
|
|
theme_color: "##{ColorScheme.hex_for_name("header_background", scheme_id)}",
|
|
title: SiteSetting.title,
|
|
current_homepage: current_homepage,
|
|
locale_script: locale,
|
|
stylesheets: @stylesheets,
|
|
plugin_js: plugin_js,
|
|
plugin_test_js: plugin_test_js,
|
|
setup_data: client_side_setup_data,
|
|
preloaded: @preloaded,
|
|
html: create_html,
|
|
theme_html: create_theme_html,
|
|
html_classes: html_classes,
|
|
html_lang: html_lang,
|
|
login_path: main_app.login_path,
|
|
authentication_data: authentication_data,
|
|
}
|
|
bootstrap[:extra_locales] = extra_locales if extra_locales.present?
|
|
bootstrap[:csrf_token] = form_authenticity_token if current_user
|
|
|
|
render_json_dump(bootstrap: bootstrap)
|
|
end
|
|
|
|
def plugin_css_for_tests
|
|
urls =
|
|
Discourse
|
|
.find_plugin_css_assets(include_disabled: true, desktop_view: true)
|
|
.map do |target|
|
|
details = Stylesheet::Manager.new().stylesheet_details(target, "all")
|
|
details[0][:new_href]
|
|
end
|
|
|
|
stylesheet = <<~CSS
|
|
/* For use in tests only - `@import`s all plugin stylesheets */
|
|
#{urls.map { |url| "@import \"#{url}\";" }.join("\n")}
|
|
CSS
|
|
|
|
render plain: stylesheet, content_type: "text/css"
|
|
end
|
|
|
|
private
|
|
|
|
def add_scheme(scheme_id, media, css_class)
|
|
return if scheme_id.to_i == -1
|
|
|
|
if style =
|
|
Stylesheet::Manager.new(theme_id: theme_id).color_scheme_stylesheet_details(
|
|
scheme_id,
|
|
media,
|
|
)
|
|
@stylesheets << { href: style[:new_href], media: media, class: css_class }
|
|
end
|
|
end
|
|
|
|
def add_style(target, opts = nil)
|
|
if styles = Stylesheet::Manager.new(theme_id: theme_id).stylesheet_details(target, "all")
|
|
styles.each do |style|
|
|
@stylesheets << {
|
|
href: style[:new_href],
|
|
media: "all",
|
|
theme_id: style[:theme_id],
|
|
target: style[:target],
|
|
}.merge(opts || {})
|
|
end
|
|
end
|
|
end
|
|
|
|
def create_html
|
|
html = {}
|
|
return html unless allow_plugins?
|
|
|
|
add_plugin_html(html, :before_body_close)
|
|
add_plugin_html(html, :before_head_close)
|
|
add_plugin_html(html, :before_script_load)
|
|
add_plugin_html(html, :header)
|
|
|
|
html
|
|
end
|
|
|
|
def add_plugin_html(html, key)
|
|
add_if_present(
|
|
html,
|
|
key,
|
|
DiscoursePluginRegistry.build_html("server:#{key.to_s.dasherize}", self),
|
|
)
|
|
end
|
|
|
|
def create_theme_html
|
|
theme_html = {}
|
|
return theme_html if customization_disabled?
|
|
|
|
theme_view = mobile_view? ? :mobile : :desktop
|
|
|
|
add_if_present(theme_html, :body_tag, Theme.lookup_field(theme_id, theme_view, "body_tag"))
|
|
add_if_present(theme_html, :head_tag, Theme.lookup_field(theme_id, theme_view, "head_tag"))
|
|
add_if_present(theme_html, :header, Theme.lookup_field(theme_id, theme_view, "header"))
|
|
add_if_present(
|
|
theme_html,
|
|
:translations,
|
|
Theme.lookup_field(theme_id, :translations, I18n.locale),
|
|
)
|
|
add_if_present(theme_html, :js, Theme.lookup_field(theme_id, :extra_js, nil))
|
|
|
|
theme_html
|
|
end
|
|
|
|
def add_if_present(hash, key, val)
|
|
hash[key] = val if val.present?
|
|
end
|
|
end
|