diff --git a/.gitignore b/.gitignore index 543d7dd0b01..0a8b03749d8 100644 --- a/.gitignore +++ b/.gitignore @@ -132,7 +132,6 @@ node_modules # ignore auto-generated plugin js assets /app/assets/javascripts/plugins/* -/app/assets/stylesheets/common/fonts.scss # ignore generated api documentation files openapi/* diff --git a/Gemfile.lock b/Gemfile.lock index 2dc830a8861..cd3dce30551 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -99,7 +99,7 @@ GEM diff-lcs (1.4.4) diffy (3.4.0) discourse-ember-source (3.12.2.2) - discourse-fonts (0.0.2) + discourse-fonts (0.0.3) discourse_image_optim (0.26.2) exifr (~> 1.2, >= 1.2.2) fspath (~> 3.0) diff --git a/app/assets/javascripts/wizard/components/font-preview.js b/app/assets/javascripts/wizard/components/font-preview.js index 9ff773b5811..a41aa21f17e 100644 --- a/app/assets/javascripts/wizard/components/font-preview.js +++ b/app/assets/javascripts/wizard/components/font-preview.js @@ -58,7 +58,11 @@ export default createPreviewComponent(305, 165, { ctx.beginPath(); ctx.fillStyle = colors.primary; ctx.font = `bold ${titleFontSize}em '${font}'`; - ctx.fillText(I18n.t("wizard.previews.topic_title"), margin, height * 0.3); + ctx.fillText( + I18n.t("wizard.previews.font_title", { font }), + margin, + height * 0.3 + ); const bodyFontSize = height / 220.0; ctx.font = `${bodyFontSize}em '${font}'`; diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss index c1f73229554..96ab90c4b60 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@ -1,3 +1,4 @@ +@import "font"; @import "vendor/normalize"; @import "vendor/normalize-ext"; @import "vendor/pikaday"; @@ -13,4 +14,3 @@ @import "common/base/*"; @import "common/d-editor"; @import "common/topic-timeline"; -@import "common/fonts"; diff --git a/app/assets/stylesheets/wizard.scss b/app/assets/stylesheets/wizard.scss index e474b24a291..c5287f2fac5 100644 --- a/app/assets/stylesheets/wizard.scss +++ b/app/assets/stylesheets/wizard.scss @@ -1,3 +1,4 @@ +@import "wizard_fonts"; @import "color_definitions"; @import "vendor/normalize"; @import "vendor/normalize-ext"; @@ -7,7 +8,6 @@ @import "common/foundation/mixins"; @import "common/select-kit/*"; @import "common/components/svg"; -@import "common/fonts"; body.wizard { background-color: #fff; diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 2878111d98f..c0dec694b17 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -119,7 +119,6 @@ module ApplicationHelper list << 'ios-device' if ios_device? list << 'rtl' if rtl? list << text_size_class - list << font_class list << 'anon' unless current_user list.join(' ') end @@ -152,10 +151,6 @@ module ApplicationHelper "text-size-#{size}" end - def font_class - "font-#{SiteSetting.base_font.tr("_", "-")}" - end - def escape_unicode(javascript) if javascript javascript = javascript.scrub diff --git a/config/application.rb b/config/application.rb index 7ec0060ff25..f05f95dc41f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -311,39 +311,7 @@ module Discourse # Use discourse-fonts gem to symlink fonts and generate .scss file fonts_path = File.join(config.root, 'public/fonts') - - # TODO cache breaker should be supplied from both the gem - # and the app - # we may want to keep a cache breaker in Discourse in case somehow - # Discourse changes rules for the particular asset - # - # TODO this code should move to SCSS compilation pipeline, we can have the - # font gem inject some variables into the SCSS that it can consume, instead of writing a file - # on boot - font_cache_breaker = "1" - Discourse::Utils.atomic_ln_s(DiscourseFonts.path_for_fonts, fonts_path) - File.open(File.join(config.root, 'app/assets/stylesheets/common/fonts.scss'), 'w') do |file| - DiscourseFonts.fonts.each do |font| - file.write <<~EOF - .font-#{font[:key].tr("_", "-")} { - --font-family: #{font[:name]}; - } - EOF - - if font[:variants].present? - font[:variants].each do |variant| - file.write <<~EOF - @font-face { - font-family: #{font[:name]}; - src: asset-url("/fonts/#{variant[:filename]}?#{font_cache_breaker}") format("#{variant[:format]}"); - font-weight: #{variant[:weight]}; - } - EOF - end - end - end - end require_dependency 'stylesheet/manager' require_dependency 'svg_sprite/svg_sprite' diff --git a/config/initializers/014-track-setting-changes.rb b/config/initializers/014-track-setting-changes.rb index c469af48fc4..e6c8dc4e45b 100644 --- a/config/initializers/014-track-setting-changes.rb +++ b/config/initializers/014-track-setting-changes.rb @@ -27,6 +27,8 @@ DiscourseEvent.on(:site_setting_changed) do |name, old_value, new_value| end end + Stylesheet::Manager.clear_core_cache!(["desktop", "mobile", "admin"]) if name == :base_font + Report.clear_cache(:storage_stats) if [:backup_location, :s3_backup_bucket].include?(name) if name == :slug_generation_method diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index a8c2e8f530c..7454e26609e 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -4910,5 +4910,6 @@ en: previews: topic_title: "Discussion topic" + font_title: "%{font} Font" share_button: "Share" reply_button: "Reply" diff --git a/lib/stylesheet/importer.rb b/lib/stylesheet/importer.rb index e08d766ebf5..1e741168c2c 100644 --- a/lib/stylesheet/importer.rb +++ b/lib/stylesheet/importer.rb @@ -40,6 +40,35 @@ module Stylesheet end end + register_import "font" do + font = DiscourseFonts.fonts.find { |f| f[:key] == SiteSetting.base_font } + + contents = <<~EOF + #{font_css(font)} + + :root { + --font-family: #{font[:stack]}; + } + EOF + + Import.new("font.scss", source: contents) + end + + register_import "wizard_fonts" do + contents = +"" + + DiscourseFonts.fonts.each do |font| + contents << font_css(font) + contents << <<~EOF + .font-#{font[:key].tr("_", "-")} { + font-family: #{font[:stack]}; + } + EOF + end + + Import.new("wizard_fonts.scss", source: contents) + end + register_import "plugins_variables" do import_files(DiscoursePluginRegistry.sass_variables) end @@ -223,6 +252,24 @@ module Stylesheet "body.category-#{category.slug}, body.category-#{category.full_slug} { background-image: url(#{upload_cdn_path(category.uploaded_background.url)}) }\n" end + def font_css(font) + contents = +"" + + if font[:variants].present? + font[:variants].each do |variant| + contents << <<~EOF + @font-face { + font-family: #{font[:name]}; + src: asset-url("/fonts/#{variant[:filename]}?v=#{DiscourseFonts::VERSION}") format("#{variant[:format]}"); + font-weight: #{variant[:weight]}; + } + EOF + end + end + + contents + end + def to_scss_variable(name, value) escaped = SassC::Script::Value::String.quote(value, sass: true) "$#{name}: unquote(#{escaped});\n" diff --git a/lib/stylesheet/manager.rb b/lib/stylesheet/manager.rb index 209d25ad52c..8b53166c382 100644 --- a/lib/stylesheet/manager.rb +++ b/lib/stylesheet/manager.rb @@ -398,7 +398,7 @@ class Stylesheet::Manager if cs || category_updated > 0 theme_color_defs = theme&.resolve_baked_field(:common, :color_definitions) - Digest::SHA1.hexdigest "#{RailsMultisite::ConnectionManagement.current_db}-#{cs&.id}-#{cs&.version}-#{theme_color_defs}-#{Stylesheet::Manager.last_file_updated}-#{category_updated}" + Digest::SHA1.hexdigest "#{RailsMultisite::ConnectionManagement.current_db}-#{cs&.id}-#{cs&.version}-#{theme_color_defs}-#{Stylesheet::Manager.last_file_updated}-#{category_updated}-#{SiteSetting.base_font}" else digest_string = "defaults-#{Stylesheet::Manager.last_file_updated}" diff --git a/spec/components/stylesheet/importer_spec.rb b/spec/components/stylesheet/importer_spec.rb index 6e653e8eb42..9c95d86cb8a 100644 --- a/spec/components/stylesheet/importer_spec.rb +++ b/spec/components/stylesheet/importer_spec.rb @@ -35,6 +35,19 @@ describe Stylesheet::Importer do expect(compile_css("category_backgrounds")).to include("body.category-#{category.full_slug}{background-image:url(https://s3.cdn/original") end + it "includes font variable" do + expect(compile_css("desktop")) + .to include(":root{--font-family: Helvetica, Arial, sans-serif}") + end + + it "includes all fonts in wizard" do + expect(compile_css("wizard").scan(/\.font-/).count) + .to eq(DiscourseFonts.fonts.count) + + expect(compile_css("wizard").scan(/@font-face/).count) + .to eq(DiscourseFonts.fonts.map { |f| f[:variants]&.count || 0 }.sum) + end + context "#theme_variables" do let!(:theme) { Fabricate(:theme) }