DEV: More refactoring of SCSS importers (#12143)
This commit is contained in:
parent
95fb363c2a
commit
5604ce70d4
|
@ -77,7 +77,6 @@ $line-height-large: 1.4; // Normal or small text
|
||||||
// These files don't actually exist. They're injected by Stylesheet::Compiler.
|
// These files don't actually exist. They're injected by Stylesheet::Compiler.
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
@import "theme_colors";
|
|
||||||
@import "plugins_variables";
|
@import "plugins_variables";
|
||||||
@import "common/foundation/math";
|
@import "common/foundation/math";
|
||||||
|
|
||||||
|
|
|
@ -346,21 +346,19 @@ class ThemeField < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def compile_scss
|
def compile_scss(prepended_scss = nil)
|
||||||
scss = <<~SCSS
|
prepended_scss ||= Stylesheet::Importer.new({}).prepended_scss
|
||||||
@import "common/foundation/variables"; @import "common/foundation/mixins"; #{self.theme.scss_variables.to_s} #{self.value}
|
|
||||||
SCSS
|
|
||||||
|
|
||||||
Stylesheet::Compiler.compile(scss,
|
Stylesheet::Compiler.compile("#{prepended_scss} #{self.theme.scss_variables.to_s} #{self.value}",
|
||||||
"#{Theme.targets[self.target_id]}.scss",
|
"#{Theme.targets[self.target_id]}.scss",
|
||||||
theme: self.theme,
|
theme: self.theme,
|
||||||
load_paths: self.theme.scss_load_paths
|
load_paths: self.theme.scss_load_paths
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def compiled_css
|
def compiled_css(prepended_scss)
|
||||||
css, _source_map = begin
|
css, _source_map = begin
|
||||||
compile_scss
|
compile_scss(prepended_scss)
|
||||||
rescue SassC::SyntaxError => e
|
rescue SassC::SyntaxError => e
|
||||||
# We don't want to raise a blocking error here
|
# We don't want to raise a blocking error here
|
||||||
# admin theme editor or discourse_theme CLI will show it nonetheless
|
# admin theme editor or discourse_theme CLI will show it nonetheless
|
||||||
|
|
|
@ -9,12 +9,13 @@ module Stylesheet
|
||||||
class Compiler
|
class Compiler
|
||||||
|
|
||||||
def self.compile_asset(asset, options = {})
|
def self.compile_asset(asset, options = {})
|
||||||
file = "@import \"common/foundation/variables\"; @import \"common/foundation/mixins\";"
|
importer = Importer.new(options)
|
||||||
|
file = importer.prepended_scss
|
||||||
|
|
||||||
if Importer::THEME_TARGETS.include?(asset.to_s)
|
if Importer::THEME_TARGETS.include?(asset.to_s)
|
||||||
filename = "theme_#{options[:theme_id]}.scss"
|
filename = "theme_#{options[:theme_id]}.scss"
|
||||||
file += options[:theme_variables].to_s
|
file += options[:theme_variables].to_s
|
||||||
file += Importer.new({ theme_id: options[:theme_id] }).theme_import(asset)
|
file += importer.theme_import(asset)
|
||||||
elsif Importer.special_imports[asset.to_s]
|
elsif Importer.special_imports[asset.to_s]
|
||||||
filename = "theme_#{options[:theme_id]}.scss"
|
filename = "theme_#{options[:theme_id]}.scss"
|
||||||
file += " @import \"#{asset}\";"
|
file += " @import \"#{asset}\";"
|
||||||
|
@ -24,13 +25,12 @@ module Stylesheet
|
||||||
file += File.read path
|
file += File.read path
|
||||||
|
|
||||||
if asset.to_s == Stylesheet::Manager::COLOR_SCHEME_STYLESHEET
|
if asset.to_s == Stylesheet::Manager::COLOR_SCHEME_STYLESHEET
|
||||||
file += Stylesheet::Importer.import_color_definitions(options[:theme_id])
|
file += importer.import_color_definitions
|
||||||
file += Stylesheet::Importer.import_wcag_overrides(options[:color_scheme_id])
|
file += importer.import_wcag_overrides
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
compile(file, filename, options)
|
compile(file, filename, options)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.compile(stylesheet, filename, options = {})
|
def self.compile(stylesheet, filename, options = {})
|
||||||
|
|
|
@ -95,25 +95,6 @@ module Stylesheet
|
||||||
import_files(DiscoursePluginRegistry.sass_variables)
|
import_files(DiscoursePluginRegistry.sass_variables)
|
||||||
end
|
end
|
||||||
|
|
||||||
register_import "theme_colors" do
|
|
||||||
contents = +""
|
|
||||||
if @color_scheme_id
|
|
||||||
colors = begin
|
|
||||||
ColorScheme.find(@color_scheme_id).resolved_colors
|
|
||||||
rescue
|
|
||||||
ColorScheme.base_colors
|
|
||||||
end
|
|
||||||
else
|
|
||||||
colors = (@theme_id && theme.color_scheme) ? theme.color_scheme.resolved_colors : ColorScheme.base_colors
|
|
||||||
end
|
|
||||||
|
|
||||||
colors.each do |n, hex|
|
|
||||||
contents << "$#{n}: ##{hex} !default;\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
Import.new("theme_colors.scss", source: contents)
|
|
||||||
end
|
|
||||||
|
|
||||||
register_import "category_backgrounds" do
|
register_import "category_backgrounds" do
|
||||||
contents = +""
|
contents = +""
|
||||||
Category.where('uploaded_background_id IS NOT NULL').each do |c|
|
Category.where('uploaded_background_id IS NOT NULL').each do |c|
|
||||||
|
@ -127,7 +108,7 @@ module Stylesheet
|
||||||
|
|
||||||
register_imports!
|
register_imports!
|
||||||
|
|
||||||
def self.import_color_definitions(theme_id)
|
def import_color_definitions
|
||||||
contents = +""
|
contents = +""
|
||||||
DiscoursePluginRegistry.color_definition_stylesheets.each do |name, path|
|
DiscoursePluginRegistry.color_definition_stylesheets.each do |name, path|
|
||||||
contents << "// Color definitions from #{name}\n\n"
|
contents << "// Color definitions from #{name}\n\n"
|
||||||
|
@ -135,7 +116,7 @@ module Stylesheet
|
||||||
contents << "\n\n"
|
contents << "\n\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
theme_id ||= SiteSetting.default_theme_id
|
theme_id = @theme_id || SiteSetting.default_theme_id
|
||||||
resolved_ids = Theme.transform_ids([theme_id])
|
resolved_ids = Theme.transform_ids([theme_id])
|
||||||
|
|
||||||
if resolved_ids
|
if resolved_ids
|
||||||
|
@ -147,7 +128,7 @@ module Stylesheet
|
||||||
if field.theme_id == theme.id
|
if field.theme_id == theme.id
|
||||||
contents << field.value
|
contents << field.value
|
||||||
else
|
else
|
||||||
contents << field.compiled_css
|
contents << field.compiled_css(prepended_scss)
|
||||||
end
|
end
|
||||||
contents << "\n\n"
|
contents << "\n\n"
|
||||||
end
|
end
|
||||||
|
@ -155,13 +136,36 @@ module Stylesheet
|
||||||
contents
|
contents
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.import_wcag_overrides(color_scheme_id)
|
def import_wcag_overrides
|
||||||
if color_scheme_id && ColorScheme.find_by_id(color_scheme_id)&.is_wcag?
|
if @color_scheme_id && ColorScheme.find_by_id(@color_scheme_id)&.is_wcag?
|
||||||
return "@import \"wcag\";"
|
return "@import \"wcag\";"
|
||||||
end
|
end
|
||||||
""
|
""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def color_variables
|
||||||
|
contents = +""
|
||||||
|
if @color_scheme_id
|
||||||
|
colors = begin
|
||||||
|
ColorScheme.find(@color_scheme_id).resolved_colors
|
||||||
|
rescue
|
||||||
|
ColorScheme.base_colors
|
||||||
|
end
|
||||||
|
else
|
||||||
|
colors = (@theme_id && theme.color_scheme) ? theme.color_scheme.resolved_colors : ColorScheme.base_colors
|
||||||
|
end
|
||||||
|
|
||||||
|
colors.each do |n, hex|
|
||||||
|
contents << "$#{n}: ##{hex} !default; "
|
||||||
|
end
|
||||||
|
|
||||||
|
contents
|
||||||
|
end
|
||||||
|
|
||||||
|
def prepended_scss
|
||||||
|
"#{color_variables} @import \"common/foundation/variables\"; @import \"common/foundation/mixins\"; "
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(options)
|
def initialize(options)
|
||||||
@theme = options[:theme]
|
@theme = options[:theme]
|
||||||
@theme_id = options[:theme_id]
|
@theme_id = options[:theme_id]
|
||||||
|
@ -204,7 +208,7 @@ module Stylesheet
|
||||||
if field.theme_id == theme.id
|
if field.theme_id == theme.id
|
||||||
contents << value
|
contents << value
|
||||||
else
|
else
|
||||||
contents << field.compiled_css
|
contents << field.compiled_css(prepended_scss)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ describe Stylesheet::Importer do
|
||||||
}}
|
}}
|
||||||
|
|
||||||
it "should include color definitions in the theme" do
|
it "should include color definitions in the theme" do
|
||||||
styles = Stylesheet::Importer.import_color_definitions(theme.id)
|
styles = Stylesheet::Importer.new({ theme_id: theme.id }).import_color_definitions
|
||||||
expect(styles).to include(scss)
|
expect(styles).to include(scss)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -88,14 +88,14 @@ describe Stylesheet::Importer do
|
||||||
theme.add_relative_theme!(:child, child)
|
theme.add_relative_theme!(:child, child)
|
||||||
theme.save!
|
theme.save!
|
||||||
|
|
||||||
styles = Stylesheet::Importer.import_color_definitions(theme.id)
|
styles = Stylesheet::Importer.new({ theme_id: theme.id }).import_color_definitions
|
||||||
expect(styles).to include(scss_child)
|
expect(styles).to include(scss_child)
|
||||||
expect(styles).to include("Color definitions from Child Theme")
|
expect(styles).to include("Color definitions from Child Theme")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should include default theme color definitions" do
|
it "should include default theme color definitions" do
|
||||||
SiteSetting.default_theme_id = theme.id
|
SiteSetting.default_theme_id = theme.id
|
||||||
styles = Stylesheet::Importer.import_color_definitions(nil)
|
styles = Stylesheet::Importer.new({}).import_color_definitions
|
||||||
expect(styles).to include(scss)
|
expect(styles).to include(scss)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -103,12 +103,12 @@ describe Stylesheet::Importer do
|
||||||
context "#import_wcag_overrides" do
|
context "#import_wcag_overrides" do
|
||||||
it "should do nothing on a regular scheme" do
|
it "should do nothing on a regular scheme" do
|
||||||
scheme = ColorScheme.create_from_base(name: 'Regular')
|
scheme = ColorScheme.create_from_base(name: 'Regular')
|
||||||
expect(Stylesheet::Importer.import_wcag_overrides(scheme.id)).to eq("")
|
expect(Stylesheet::Importer.new({ color_scheme_id: scheme.id }).import_wcag_overrides).to eq("")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should include WCAG overrides for WCAG based scheme" do
|
it "should include WCAG overrides for WCAG based scheme" do
|
||||||
scheme = ColorScheme.create_from_base(name: 'WCAG New', base_scheme_id: "WCAG Dark")
|
scheme = ColorScheme.create_from_base(name: 'WCAG New', base_scheme_id: "WCAG Dark")
|
||||||
expect(Stylesheet::Importer.import_wcag_overrides(scheme.id)).to eq("@import \"wcag\";")
|
expect(Stylesheet::Importer.new({ color_scheme_id: scheme.id }).import_wcag_overrides).to eq("@import \"wcag\";")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -288,14 +288,38 @@ describe Stylesheet::Manager do
|
||||||
t.set_field(target: :common, name: "color_definitions", value: ':root {--special: rebeccapurple;}')
|
t.set_field(target: :common, name: "color_definitions", value: ':root {--special: rebeccapurple;}')
|
||||||
t.save!
|
t.save!
|
||||||
}}
|
}}
|
||||||
|
let(:scss_child) { ':root {--child-definition: #{dark-light-choose(#c00, #fff)};}' }
|
||||||
|
let(:child) { Fabricate(:theme, component: true, name: "Child Theme").tap { |t|
|
||||||
|
t.set_field(target: :common, name: "color_definitions", value: scss_child)
|
||||||
|
t.save!
|
||||||
|
}}
|
||||||
|
|
||||||
let(:scheme) { ColorScheme.base }
|
let(:scheme) { ColorScheme.base }
|
||||||
|
let(:dark_scheme) { ColorScheme.create_from_base(name: 'Dark', base_scheme_id: 'Dark') }
|
||||||
|
|
||||||
it "includes theme color definitions in color scheme" do
|
it "includes theme color definitions in color scheme" do
|
||||||
stylesheet = Stylesheet::Manager.new(:color_definitions, theme.id, scheme).compile(force: true)
|
stylesheet = Stylesheet::Manager.new(:color_definitions, theme.id, scheme).compile(force: true)
|
||||||
expect(stylesheet).to include("--special: rebeccapurple")
|
expect(stylesheet).to include("--special: rebeccapurple")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "includes child color definitions in color schemes" do
|
||||||
|
theme.add_relative_theme!(:child, child)
|
||||||
|
theme.save!
|
||||||
|
stylesheet = Stylesheet::Manager.new(:color_definitions, theme.id, scheme).compile(force: true)
|
||||||
|
|
||||||
|
expect(stylesheet).to include("--special: rebeccapurple")
|
||||||
|
expect(stylesheet).to include("--child-definition: #c00")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "respects selected color scheme in child color definitions" do
|
||||||
|
theme.add_relative_theme!(:child, child)
|
||||||
|
theme.save!
|
||||||
|
|
||||||
|
stylesheet = Stylesheet::Manager.new(:color_definitions, theme.id, dark_scheme).compile(force: true)
|
||||||
|
expect(stylesheet).to include("--special: rebeccapurple")
|
||||||
|
expect(stylesheet).to include("--child-definition: #fff")
|
||||||
|
end
|
||||||
|
|
||||||
it "fails gracefully for broken SCSS" do
|
it "fails gracefully for broken SCSS" do
|
||||||
scss = "$test: $missing-var;"
|
scss = "$test: $missing-var;"
|
||||||
theme.set_field(target: :common, name: "color_definitions", value: scss)
|
theme.set_field(target: :common, name: "color_definitions", value: scss)
|
||||||
|
|
Loading…
Reference in New Issue