|
|
|
@@ -1,7 +1,7 @@
|
|
|
|
|
# coding: utf-8
|
|
|
|
|
# frozen_string_literal: true
|
|
|
|
|
require 'current_user'
|
|
|
|
|
require 'canonical_url'
|
|
|
|
|
require "current_user"
|
|
|
|
|
require "canonical_url"
|
|
|
|
|
|
|
|
|
|
module ApplicationHelper
|
|
|
|
|
include CurrentUser
|
|
|
|
@@ -14,7 +14,6 @@ module ApplicationHelper
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def discourse_config_environment(testing: false)
|
|
|
|
|
|
|
|
|
|
# TODO: Can this come from Ember CLI somehow?
|
|
|
|
|
config = {
|
|
|
|
|
modulePrefix: "discourse",
|
|
|
|
@@ -23,24 +22,27 @@ module ApplicationHelper
|
|
|
|
|
locationType: "history",
|
|
|
|
|
historySupportMiddleware: false,
|
|
|
|
|
EmberENV: {
|
|
|
|
|
FEATURES: {},
|
|
|
|
|
EXTEND_PROTOTYPES: { "Date": false },
|
|
|
|
|
FEATURES: {
|
|
|
|
|
},
|
|
|
|
|
EXTEND_PROTOTYPES: {
|
|
|
|
|
Date: false,
|
|
|
|
|
},
|
|
|
|
|
_APPLICATION_TEMPLATE_WRAPPER: false,
|
|
|
|
|
_DEFAULT_ASYNC_OBSERVERS: true,
|
|
|
|
|
_JQUERY_INTEGRATION: true
|
|
|
|
|
_JQUERY_INTEGRATION: true,
|
|
|
|
|
},
|
|
|
|
|
APP: {
|
|
|
|
|
name: "discourse",
|
|
|
|
|
version: "#{Discourse::VERSION::STRING} #{Discourse.git_version}",
|
|
|
|
|
exportApplicationGlobal: true
|
|
|
|
|
}
|
|
|
|
|
exportApplicationGlobal: true,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if testing
|
|
|
|
|
config[:environment] = "test"
|
|
|
|
|
config[:locationType] = "none"
|
|
|
|
|
config[:APP][:autoboot] = false
|
|
|
|
|
config[:APP][:rootElement] = '#ember-testing'
|
|
|
|
|
config[:APP][:rootElement] = "#ember-testing"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
config.to_json
|
|
|
|
@@ -48,15 +50,9 @@ module ApplicationHelper
|
|
|
|
|
|
|
|
|
|
def google_universal_analytics_json(ua_domain_name = nil)
|
|
|
|
|
result = {}
|
|
|
|
|
if ua_domain_name
|
|
|
|
|
result[:cookieDomain] = ua_domain_name.gsub(/^http(s)?:\/\//, '')
|
|
|
|
|
end
|
|
|
|
|
if current_user.present?
|
|
|
|
|
result[:userId] = current_user.id
|
|
|
|
|
end
|
|
|
|
|
if SiteSetting.ga_universal_auto_link_domains.present?
|
|
|
|
|
result[:allowLinker] = true
|
|
|
|
|
end
|
|
|
|
|
result[:cookieDomain] = ua_domain_name.gsub(%r{^http(s)?://}, "") if ua_domain_name
|
|
|
|
|
result[:userId] = current_user.id if current_user.present?
|
|
|
|
|
result[:allowLinker] = true if SiteSetting.ga_universal_auto_link_domains.present?
|
|
|
|
|
result.to_json
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@@ -73,7 +69,7 @@ module ApplicationHelper
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def shared_session_key
|
|
|
|
|
if SiteSetting.long_polling_base_url != '/' && current_user
|
|
|
|
|
if SiteSetting.long_polling_base_url != "/" && current_user
|
|
|
|
|
sk = "shared_session_key"
|
|
|
|
|
return request.env[sk] if request.env[sk]
|
|
|
|
|
|
|
|
|
@@ -95,10 +91,15 @@ module ApplicationHelper
|
|
|
|
|
path = ActionController::Base.helpers.asset_path("#{script}.js")
|
|
|
|
|
|
|
|
|
|
if GlobalSetting.use_s3? && GlobalSetting.s3_cdn_url
|
|
|
|
|
resolved_s3_asset_cdn_url = GlobalSetting.s3_asset_cdn_url.presence || GlobalSetting.s3_cdn_url
|
|
|
|
|
resolved_s3_asset_cdn_url =
|
|
|
|
|
GlobalSetting.s3_asset_cdn_url.presence || GlobalSetting.s3_cdn_url
|
|
|
|
|
if GlobalSetting.cdn_url
|
|
|
|
|
folder = ActionController::Base.config.relative_url_root || "/"
|
|
|
|
|
path = path.gsub(File.join(GlobalSetting.cdn_url, folder, "/"), File.join(resolved_s3_asset_cdn_url, "/"))
|
|
|
|
|
path =
|
|
|
|
|
path.gsub(
|
|
|
|
|
File.join(GlobalSetting.cdn_url, folder, "/"),
|
|
|
|
|
File.join(resolved_s3_asset_cdn_url, "/"),
|
|
|
|
|
)
|
|
|
|
|
else
|
|
|
|
|
# we must remove the subfolder path here, assets are uploaded to s3
|
|
|
|
|
# without it getting involved
|
|
|
|
@@ -121,8 +122,8 @@ module ApplicationHelper
|
|
|
|
|
path = path.gsub(/\.([^.]+)$/, '.gz.\1')
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
elsif GlobalSetting.cdn_url&.start_with?("https") && is_brotli_req? && Rails.env != "development"
|
|
|
|
|
elsif GlobalSetting.cdn_url&.start_with?("https") && is_brotli_req? &&
|
|
|
|
|
Rails.env != "development"
|
|
|
|
|
path = path.gsub("#{GlobalSetting.cdn_url}/assets/", "#{GlobalSetting.cdn_url}/brotli_asset/")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@@ -136,14 +137,17 @@ module ApplicationHelper
|
|
|
|
|
scripts.push(*chunks)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
scripts.map do |name|
|
|
|
|
|
path = script_asset_path(name)
|
|
|
|
|
preload_script_url(path)
|
|
|
|
|
end.join("\n").html_safe
|
|
|
|
|
scripts
|
|
|
|
|
.map do |name|
|
|
|
|
|
path = script_asset_path(name)
|
|
|
|
|
preload_script_url(path)
|
|
|
|
|
end
|
|
|
|
|
.join("\n")
|
|
|
|
|
.html_safe
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def preload_script_url(url)
|
|
|
|
|
add_resource_preload_list(url, 'script')
|
|
|
|
|
add_resource_preload_list(url, "script")
|
|
|
|
|
if GlobalSetting.preload_link_header
|
|
|
|
|
<<~HTML.html_safe
|
|
|
|
|
<script defer src="#{url}"></script>
|
|
|
|
@@ -157,50 +161,47 @@ module ApplicationHelper
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def add_resource_preload_list(resource_url, type)
|
|
|
|
|
@links_to_preload << %Q(<#{resource_url}>; rel="preload"; as="#{type}") if !@links_to_preload.nil?
|
|
|
|
|
if !@links_to_preload.nil?
|
|
|
|
|
@links_to_preload << %Q(<#{resource_url}>; rel="preload"; as="#{type}")
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def discourse_csrf_tags
|
|
|
|
|
# anon can not have a CSRF token cause these are all pages
|
|
|
|
|
# that may be cached, causing a mismatch between session CSRF
|
|
|
|
|
# and CSRF on page and horrible impossible to debug login issues
|
|
|
|
|
if current_user
|
|
|
|
|
csrf_meta_tags
|
|
|
|
|
end
|
|
|
|
|
csrf_meta_tags if current_user
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def html_classes
|
|
|
|
|
list = []
|
|
|
|
|
list << (mobile_view? ? 'mobile-view' : 'desktop-view')
|
|
|
|
|
list << (mobile_device? ? 'mobile-device' : 'not-mobile-device')
|
|
|
|
|
list << 'ios-device' if ios_device?
|
|
|
|
|
list << 'rtl' if rtl?
|
|
|
|
|
list << (mobile_view? ? "mobile-view" : "desktop-view")
|
|
|
|
|
list << (mobile_device? ? "mobile-device" : "not-mobile-device")
|
|
|
|
|
list << "ios-device" if ios_device?
|
|
|
|
|
list << "rtl" if rtl?
|
|
|
|
|
list << text_size_class
|
|
|
|
|
list << 'anon' unless current_user
|
|
|
|
|
list.join(' ')
|
|
|
|
|
list << "anon" unless current_user
|
|
|
|
|
list.join(" ")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def body_classes
|
|
|
|
|
result = ApplicationHelper.extra_body_classes.to_a
|
|
|
|
|
|
|
|
|
|
if @category && @category.url.present?
|
|
|
|
|
result << "category-#{@category.slug_path.join('-')}"
|
|
|
|
|
end
|
|
|
|
|
result << "category-#{@category.slug_path.join("-")}" if @category && @category.url.present?
|
|
|
|
|
|
|
|
|
|
if current_user.present? &&
|
|
|
|
|
current_user.primary_group_id &&
|
|
|
|
|
primary_group_name = Group.where(id: current_user.primary_group_id).pluck_first(:name)
|
|
|
|
|
if current_user.present? && current_user.primary_group_id &&
|
|
|
|
|
primary_group_name = Group.where(id: current_user.primary_group_id).pluck_first(:name)
|
|
|
|
|
result << "primary-group-#{primary_group_name.downcase}"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
result.join(' ')
|
|
|
|
|
result.join(" ")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def text_size_class
|
|
|
|
|
requested_cookie_size, cookie_seq = cookies[:text_size]&.split("|")
|
|
|
|
|
server_seq = current_user&.user_option&.text_size_seq
|
|
|
|
|
if cookie_seq && server_seq && cookie_seq.to_i >= server_seq &&
|
|
|
|
|
UserOption.text_sizes.keys.include?(requested_cookie_size&.to_sym)
|
|
|
|
|
UserOption.text_sizes.keys.include?(requested_cookie_size&.to_sym)
|
|
|
|
|
cookie_size = requested_cookie_size
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@@ -211,11 +212,11 @@ module ApplicationHelper
|
|
|
|
|
def escape_unicode(javascript)
|
|
|
|
|
if javascript
|
|
|
|
|
javascript = javascript.scrub
|
|
|
|
|
javascript.gsub!(/\342\200\250/u, '
')
|
|
|
|
|
javascript.gsub!(/(<\/)/u, '\u003C/')
|
|
|
|
|
javascript.gsub!(/\342\200\250/u, "
")
|
|
|
|
|
javascript.gsub!(%r{(</)}u, '\u003C/')
|
|
|
|
|
javascript
|
|
|
|
|
else
|
|
|
|
|
''
|
|
|
|
|
""
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@@ -260,7 +261,7 @@ module ApplicationHelper
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def rtl?
|
|
|
|
|
["ar", "ur", "fa_IR", "he"].include? I18n.locale.to_s
|
|
|
|
|
%w[ar ur fa_IR he].include? I18n.locale.to_s
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def html_lang
|
|
|
|
@@ -291,18 +292,19 @@ module ApplicationHelper
|
|
|
|
|
|
|
|
|
|
# Use the correct scheme for opengraph/twitter image
|
|
|
|
|
opts[:image] = get_absolute_image_url(opts[:image]) if opts[:image].present?
|
|
|
|
|
opts[:twitter_summary_large_image] =
|
|
|
|
|
get_absolute_image_url(opts[:twitter_summary_large_image]) if opts[:twitter_summary_large_image].present?
|
|
|
|
|
opts[:twitter_summary_large_image] = get_absolute_image_url(
|
|
|
|
|
opts[:twitter_summary_large_image],
|
|
|
|
|
) if opts[:twitter_summary_large_image].present?
|
|
|
|
|
|
|
|
|
|
result = []
|
|
|
|
|
result << tag(:meta, property: 'og:site_name', content: SiteSetting.title)
|
|
|
|
|
result << tag(:meta, property: 'og:type', content: 'website')
|
|
|
|
|
result << tag(:meta, property: "og:site_name", content: SiteSetting.title)
|
|
|
|
|
result << tag(:meta, property: "og:type", content: "website")
|
|
|
|
|
|
|
|
|
|
generate_twitter_card_metadata(result, opts)
|
|
|
|
|
|
|
|
|
|
result << tag(:meta, property: "og:image", content: opts[:image]) if opts[:image].present?
|
|
|
|
|
|
|
|
|
|
[:url, :title, :description].each do |property|
|
|
|
|
|
%i[url title description].each do |property|
|
|
|
|
|
if opts[property].present?
|
|
|
|
|
content = (property == :url ? opts[property] : gsub_emoji_to_unicode(opts[property]))
|
|
|
|
|
result << tag(:meta, { property: "og:#{property}", content: content }, nil, true)
|
|
|
|
@@ -311,27 +313,30 @@ module ApplicationHelper
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if opts[:read_time] && opts[:read_time] > 0 && opts[:like_count] && opts[:like_count] > 0
|
|
|
|
|
result << tag(:meta, name: 'twitter:label1', value: I18n.t("reading_time"))
|
|
|
|
|
result << tag(:meta, name: 'twitter:data1', value: "#{opts[:read_time]} mins 🕑")
|
|
|
|
|
result << tag(:meta, name: 'twitter:label2', value: I18n.t("likes"))
|
|
|
|
|
result << tag(:meta, name: 'twitter:data2', value: "#{opts[:like_count]} ❤")
|
|
|
|
|
result << tag(:meta, name: "twitter:label1", value: I18n.t("reading_time"))
|
|
|
|
|
result << tag(:meta, name: "twitter:data1", value: "#{opts[:read_time]} mins 🕑")
|
|
|
|
|
result << tag(:meta, name: "twitter:label2", value: I18n.t("likes"))
|
|
|
|
|
result << tag(:meta, name: "twitter:data2", value: "#{opts[:like_count]} ❤")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if opts[:published_time]
|
|
|
|
|
result << tag(:meta, property: 'article:published_time', content: opts[:published_time])
|
|
|
|
|
result << tag(:meta, property: "article:published_time", content: opts[:published_time])
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if opts[:ignore_canonical]
|
|
|
|
|
result << tag(:meta, property: 'og:ignore_canonical', content: true)
|
|
|
|
|
end
|
|
|
|
|
result << tag(:meta, property: "og:ignore_canonical", content: true) if opts[:ignore_canonical]
|
|
|
|
|
|
|
|
|
|
result.join("\n")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
private def generate_twitter_card_metadata(result, opts)
|
|
|
|
|
img_url = opts[:twitter_summary_large_image].present? ? \
|
|
|
|
|
opts[:twitter_summary_large_image] :
|
|
|
|
|
opts[:image]
|
|
|
|
|
img_url =
|
|
|
|
|
(
|
|
|
|
|
if opts[:twitter_summary_large_image].present?
|
|
|
|
|
opts[:twitter_summary_large_image]
|
|
|
|
|
else
|
|
|
|
|
opts[:image]
|
|
|
|
|
end
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Twitter does not allow SVGs, see https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/markup
|
|
|
|
|
if img_url.ends_with?(".svg")
|
|
|
|
@@ -339,29 +344,29 @@ module ApplicationHelper
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if opts[:twitter_summary_large_image].present? && img_url.present?
|
|
|
|
|
result << tag(:meta, name: 'twitter:card', content: "summary_large_image")
|
|
|
|
|
result << tag(:meta, name: "twitter:card", content: "summary_large_image")
|
|
|
|
|
result << tag(:meta, name: "twitter:image", content: img_url)
|
|
|
|
|
elsif opts[:image].present? && img_url.present?
|
|
|
|
|
result << tag(:meta, name: 'twitter:card', content: "summary")
|
|
|
|
|
result << tag(:meta, name: "twitter:card", content: "summary")
|
|
|
|
|
result << tag(:meta, name: "twitter:image", content: img_url)
|
|
|
|
|
else
|
|
|
|
|
result << tag(:meta, name: 'twitter:card', content: "summary")
|
|
|
|
|
result << tag(:meta, name: "twitter:card", content: "summary")
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def render_sitelinks_search_tag
|
|
|
|
|
if current_page?('/') || current_page?(Discourse.base_path)
|
|
|
|
|
if current_page?("/") || current_page?(Discourse.base_path)
|
|
|
|
|
json = {
|
|
|
|
|
'@context' => 'http://schema.org',
|
|
|
|
|
'@type' => 'WebSite',
|
|
|
|
|
url: Discourse.base_url,
|
|
|
|
|
potentialAction: {
|
|
|
|
|
'@type' => 'SearchAction',
|
|
|
|
|
target: "#{Discourse.base_url}/search?q={search_term_string}",
|
|
|
|
|
'query-input' => 'required name=search_term_string',
|
|
|
|
|
}
|
|
|
|
|
"@context" => "http://schema.org",
|
|
|
|
|
"@type" => "WebSite",
|
|
|
|
|
:url => Discourse.base_url,
|
|
|
|
|
:potentialAction => {
|
|
|
|
|
"@type" => "SearchAction",
|
|
|
|
|
:target => "#{Discourse.base_url}/search?q={search_term_string}",
|
|
|
|
|
"query-input" => "required name=search_term_string",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
content_tag(:script, MultiJson.dump(json).html_safe, type: 'application/ld+json')
|
|
|
|
|
content_tag(:script, MultiJson.dump(json).html_safe, type: "application/ld+json")
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@@ -370,33 +375,35 @@ module ApplicationHelper
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def application_logo_url
|
|
|
|
|
@application_logo_url ||= begin
|
|
|
|
|
if mobile_view?
|
|
|
|
|
if dark_color_scheme? && SiteSetting.site_mobile_logo_dark_url.present?
|
|
|
|
|
SiteSetting.site_mobile_logo_dark_url
|
|
|
|
|
elsif SiteSetting.site_mobile_logo_url.present?
|
|
|
|
|
SiteSetting.site_mobile_logo_url
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
if dark_color_scheme? && SiteSetting.site_logo_dark_url.present?
|
|
|
|
|
SiteSetting.site_logo_dark_url
|
|
|
|
|
@application_logo_url ||=
|
|
|
|
|
begin
|
|
|
|
|
if mobile_view?
|
|
|
|
|
if dark_color_scheme? && SiteSetting.site_mobile_logo_dark_url.present?
|
|
|
|
|
SiteSetting.site_mobile_logo_dark_url
|
|
|
|
|
elsif SiteSetting.site_mobile_logo_url.present?
|
|
|
|
|
SiteSetting.site_mobile_logo_url
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
SiteSetting.site_logo_url
|
|
|
|
|
if dark_color_scheme? && SiteSetting.site_logo_dark_url.present?
|
|
|
|
|
SiteSetting.site_logo_dark_url
|
|
|
|
|
else
|
|
|
|
|
SiteSetting.site_logo_url
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def application_logo_dark_url
|
|
|
|
|
@application_logo_dark_url ||= begin
|
|
|
|
|
if dark_scheme_id != -1
|
|
|
|
|
if mobile_view? && SiteSetting.site_mobile_logo_dark_url != application_logo_url
|
|
|
|
|
SiteSetting.site_mobile_logo_dark_url
|
|
|
|
|
elsif !mobile_view? && SiteSetting.site_logo_dark_url != application_logo_url
|
|
|
|
|
SiteSetting.site_logo_dark_url
|
|
|
|
|
@application_logo_dark_url ||=
|
|
|
|
|
begin
|
|
|
|
|
if dark_scheme_id != -1
|
|
|
|
|
if mobile_view? && SiteSetting.site_mobile_logo_dark_url != application_logo_url
|
|
|
|
|
SiteSetting.site_mobile_logo_dark_url
|
|
|
|
|
elsif !mobile_view? && SiteSetting.site_logo_dark_url != application_logo_url
|
|
|
|
|
SiteSetting.site_logo_dark_url
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def login_path
|
|
|
|
@@ -437,8 +444,11 @@ module ApplicationHelper
|
|
|
|
|
|
|
|
|
|
def ios_app_argument
|
|
|
|
|
# argument only makes sense for DiscourseHub app
|
|
|
|
|
SiteSetting.ios_app_id == "1173672076" ?
|
|
|
|
|
", app-argument=discourse://new?siteUrl=#{Discourse.base_url}" : ""
|
|
|
|
|
if SiteSetting.ios_app_id == "1173672076"
|
|
|
|
|
", app-argument=discourse://new?siteUrl=#{Discourse.base_url}"
|
|
|
|
|
else
|
|
|
|
|
""
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def include_splash_screen?
|
|
|
|
@@ -496,9 +506,9 @@ module ApplicationHelper
|
|
|
|
|
uri = UrlHelper.encode_and_parse(link)
|
|
|
|
|
uri = URI.parse("http://#{uri}") if uri.scheme.nil?
|
|
|
|
|
host = uri.host.downcase
|
|
|
|
|
host.start_with?('www.') ? host[4..-1] : host
|
|
|
|
|
rescue
|
|
|
|
|
''
|
|
|
|
|
host.start_with?("www.") ? host[4..-1] : host
|
|
|
|
|
rescue StandardError
|
|
|
|
|
""
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@@ -529,7 +539,8 @@ module ApplicationHelper
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def dark_scheme_id
|
|
|
|
|
cookies[:dark_scheme_id] || current_user&.user_option&.dark_scheme_id || SiteSetting.default_dark_mode_color_scheme_id
|
|
|
|
|
cookies[:dark_scheme_id] || current_user&.user_option&.dark_scheme_id ||
|
|
|
|
|
SiteSetting.default_dark_mode_color_scheme_id
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def current_homepage
|
|
|
|
@@ -556,7 +567,7 @@ module ApplicationHelper
|
|
|
|
|
theme_id,
|
|
|
|
|
mobile_view? ? :mobile : :desktop,
|
|
|
|
|
name,
|
|
|
|
|
skip_transformation: request.env[:skip_theme_ids_transformation].present?
|
|
|
|
|
skip_transformation: request.env[:skip_theme_ids_transformation].present?,
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@@ -565,7 +576,7 @@ module ApplicationHelper
|
|
|
|
|
theme_id,
|
|
|
|
|
:translations,
|
|
|
|
|
I18n.locale,
|
|
|
|
|
skip_transformation: request.env[:skip_theme_ids_transformation].present?
|
|
|
|
|
skip_transformation: request.env[:skip_theme_ids_transformation].present?,
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@@ -574,42 +585,41 @@ module ApplicationHelper
|
|
|
|
|
theme_id,
|
|
|
|
|
:extra_js,
|
|
|
|
|
nil,
|
|
|
|
|
skip_transformation: request.env[:skip_theme_ids_transformation].present?
|
|
|
|
|
skip_transformation: request.env[:skip_theme_ids_transformation].present?,
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def discourse_stylesheet_preload_tag(name, opts = {})
|
|
|
|
|
manager =
|
|
|
|
|
if opts.key?(:theme_id)
|
|
|
|
|
Stylesheet::Manager.new(
|
|
|
|
|
theme_id: customization_disabled? ? nil : opts[:theme_id]
|
|
|
|
|
)
|
|
|
|
|
Stylesheet::Manager.new(theme_id: customization_disabled? ? nil : opts[:theme_id])
|
|
|
|
|
else
|
|
|
|
|
stylesheet_manager
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
manager.stylesheet_preload_tag(name, 'all')
|
|
|
|
|
manager.stylesheet_preload_tag(name, "all")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def discourse_stylesheet_link_tag(name, opts = {})
|
|
|
|
|
manager =
|
|
|
|
|
if opts.key?(:theme_id)
|
|
|
|
|
Stylesheet::Manager.new(
|
|
|
|
|
theme_id: customization_disabled? ? nil : opts[:theme_id]
|
|
|
|
|
)
|
|
|
|
|
Stylesheet::Manager.new(theme_id: customization_disabled? ? nil : opts[:theme_id])
|
|
|
|
|
else
|
|
|
|
|
stylesheet_manager
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
manager.stylesheet_link_tag(name, 'all', self.method(:add_resource_preload_list))
|
|
|
|
|
manager.stylesheet_link_tag(name, "all", self.method(:add_resource_preload_list))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def discourse_preload_color_scheme_stylesheets
|
|
|
|
|
result = +""
|
|
|
|
|
result << stylesheet_manager.color_scheme_stylesheet_preload_tag(scheme_id, 'all')
|
|
|
|
|
result << stylesheet_manager.color_scheme_stylesheet_preload_tag(scheme_id, "all")
|
|
|
|
|
|
|
|
|
|
if dark_scheme_id != -1
|
|
|
|
|
result << stylesheet_manager.color_scheme_stylesheet_preload_tag(dark_scheme_id, '(prefers-color-scheme: dark)')
|
|
|
|
|
result << stylesheet_manager.color_scheme_stylesheet_preload_tag(
|
|
|
|
|
dark_scheme_id,
|
|
|
|
|
"(prefers-color-scheme: dark)",
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
result.html_safe
|
|
|
|
@@ -617,10 +627,18 @@ module ApplicationHelper
|
|
|
|
|
|
|
|
|
|
def discourse_color_scheme_stylesheets
|
|
|
|
|
result = +""
|
|
|
|
|
result << stylesheet_manager.color_scheme_stylesheet_link_tag(scheme_id, 'all', self.method(:add_resource_preload_list))
|
|
|
|
|
result << stylesheet_manager.color_scheme_stylesheet_link_tag(
|
|
|
|
|
scheme_id,
|
|
|
|
|
"all",
|
|
|
|
|
self.method(:add_resource_preload_list),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if dark_scheme_id != -1
|
|
|
|
|
result << stylesheet_manager.color_scheme_stylesheet_link_tag(dark_scheme_id, '(prefers-color-scheme: dark)', self.method(:add_resource_preload_list))
|
|
|
|
|
result << stylesheet_manager.color_scheme_stylesheet_link_tag(
|
|
|
|
|
dark_scheme_id,
|
|
|
|
|
"(prefers-color-scheme: dark)",
|
|
|
|
|
self.method(:add_resource_preload_list),
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
result.html_safe
|
|
|
|
@@ -630,12 +648,12 @@ module ApplicationHelper
|
|
|
|
|
result = +""
|
|
|
|
|
if dark_scheme_id != -1
|
|
|
|
|
result << <<~HTML
|
|
|
|
|
<meta name="theme-color" media="(prefers-color-scheme: light)" content="##{ColorScheme.hex_for_name('header_background', scheme_id)}">
|
|
|
|
|
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="##{ColorScheme.hex_for_name('header_background', dark_scheme_id)}">
|
|
|
|
|
<meta name="theme-color" media="(prefers-color-scheme: light)" content="##{ColorScheme.hex_for_name("header_background", scheme_id)}">
|
|
|
|
|
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="##{ColorScheme.hex_for_name("header_background", dark_scheme_id)}">
|
|
|
|
|
HTML
|
|
|
|
|
else
|
|
|
|
|
result << <<~HTML
|
|
|
|
|
<meta name="theme-color" media="all" content="##{ColorScheme.hex_for_name('header_background', scheme_id)}">
|
|
|
|
|
<meta name="theme-color" media="all" content="##{ColorScheme.hex_for_name("header_background", scheme_id)}">
|
|
|
|
|
HTML
|
|
|
|
|
end
|
|
|
|
|
result.html_safe
|
|
|
|
@@ -647,7 +665,7 @@ module ApplicationHelper
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def preloaded_json
|
|
|
|
|
return '{}' if @preloaded.blank?
|
|
|
|
|
return "{}" if @preloaded.blank?
|
|
|
|
|
@preloaded.transform_values { |value| escape_unicode(value) }.to_json
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@@ -658,8 +676,8 @@ module ApplicationHelper
|
|
|
|
|
base_uri: Discourse.base_path,
|
|
|
|
|
environment: Rails.env,
|
|
|
|
|
letter_avatar_version: LetterAvatar.version,
|
|
|
|
|
markdown_it_url: script_asset_path('markdown-it-bundle'),
|
|
|
|
|
service_worker_url: 'service-worker.js',
|
|
|
|
|
markdown_it_url: script_asset_path("markdown-it-bundle"),
|
|
|
|
|
service_worker_url: "service-worker.js",
|
|
|
|
|
default_locale: SiteSetting.default_locale,
|
|
|
|
|
asset_version: Discourse.assets_digest,
|
|
|
|
|
disable_custom_css: loading_admin?,
|
|
|
|
@@ -668,16 +686,14 @@ module ApplicationHelper
|
|
|
|
|
enable_js_error_reporting: GlobalSetting.enable_js_error_reporting,
|
|
|
|
|
color_scheme_is_dark: dark_color_scheme?,
|
|
|
|
|
user_color_scheme_id: scheme_id,
|
|
|
|
|
user_dark_scheme_id: dark_scheme_id
|
|
|
|
|
user_dark_scheme_id: dark_scheme_id,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if Rails.env.development?
|
|
|
|
|
setup_data[:svg_icon_list] = SvgSprite.all_icons(theme_id)
|
|
|
|
|
|
|
|
|
|
if ENV['DEBUG_PRELOADED_APP_DATA']
|
|
|
|
|
setup_data[:debug_preloaded_app_data] = true
|
|
|
|
|
end
|
|
|
|
|
setup_data[:mb_last_file_change_id] = MessageBus.last_id('/file-change')
|
|
|
|
|
setup_data[:debug_preloaded_app_data] = true if ENV["DEBUG_PRELOADED_APP_DATA"]
|
|
|
|
|
setup_data[:mb_last_file_change_id] = MessageBus.last_id("/file-change")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if guardian.can_enable_safe_mode? && params["safe_mode"]
|
|
|
|
@@ -694,10 +710,10 @@ module ApplicationHelper
|
|
|
|
|
|
|
|
|
|
def get_absolute_image_url(link)
|
|
|
|
|
absolute_url = link
|
|
|
|
|
if link.start_with?('//')
|
|
|
|
|
if link.start_with?("//")
|
|
|
|
|
uri = URI(Discourse.base_url)
|
|
|
|
|
absolute_url = "#{uri.scheme}:#{link}"
|
|
|
|
|
elsif link.start_with?('/uploads/', '/images/', '/user_avatar/')
|
|
|
|
|
elsif link.start_with?("/uploads/", "/images/", "/user_avatar/")
|
|
|
|
|
absolute_url = "#{Discourse.base_url}#{link}"
|
|
|
|
|
elsif GlobalSetting.relative_url_root && link.start_with?(GlobalSetting.relative_url_root)
|
|
|
|
|
absolute_url = "#{Discourse.base_url_no_prefix}#{link}"
|
|
|
|
@@ -713,9 +729,8 @@ module ApplicationHelper
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def can_sign_up?
|
|
|
|
|
SiteSetting.allow_new_registrations &&
|
|
|
|
|
!SiteSetting.invite_only &&
|
|
|
|
|
!SiteSetting.enable_discourse_connect
|
|
|
|
|
SiteSetting.allow_new_registrations && !SiteSetting.invite_only &&
|
|
|
|
|
!SiteSetting.enable_discourse_connect
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def rss_creator(user)
|
|
|
|
@@ -725,12 +740,11 @@ module ApplicationHelper
|
|
|
|
|
def authentication_data
|
|
|
|
|
return @authentication_data if defined?(@authentication_data)
|
|
|
|
|
|
|
|
|
|
@authentication_data = begin
|
|
|
|
|
value = cookies[:authentication_data]
|
|
|
|
|
if value
|
|
|
|
|
cookies.delete(:authentication_data, path: Discourse.base_path("/"))
|
|
|
|
|
@authentication_data =
|
|
|
|
|
begin
|
|
|
|
|
value = cookies[:authentication_data]
|
|
|
|
|
cookies.delete(:authentication_data, path: Discourse.base_path("/")) if value
|
|
|
|
|
current_user ? nil : value
|
|
|
|
|
end
|
|
|
|
|
current_user ? nil : value
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|