From 40b0417cd0c9ad95c01c8f38079221c601c79d16 Mon Sep 17 00:00:00 2001
From: Maximilian Krig
-replace, -use-link-source, accelerator, accent-color, align-content,
align-items, align-self, alignment-adjust, alignment-baseline,
- appearance, azimuth, baseline-shift, behavior, binding, bookmark-label,
+ appearance, aspect-ratio, azimuth, baseline-shift, behavior, binding, bookmark-label,
bookmark-level, bookmark-target, bottom, box-align, box-direction,
box-flex, box-flex-group, box-lines, box-orient, box-pack, box-shadow,
box-sizing, caption-side, clear, clip, color, color-profile,
@@ -147,6 +147,7 @@
"https://w3schools.com/css/css_units.asp"),
units_list_code: tag.br + tag.code(t(".numeric_values.description.units_list"))) %>
<%= t(".numeric_values.description.aspect_ratio_html", aspect_ratio_code: tag.code("aspect-ratio")) %>
<%= t(".numeric_values.description.em_unit_html", em_code: tag.code("em")) %>
diff --git a/config/config.yml b/config/config.yml index bd8c99fdc76..490b219e566 100644 --- a/config/config.yml +++ b/config/config.yml @@ -426,6 +426,7 @@ SUPPORTED_CSS_PROPERTIES: - alignment-adjust - alignment-baseline - appearance +- aspect-ratio - azimuth - baseline-shift - behavior diff --git a/config/locales/views/en.yml b/config/locales/views/en.yml index 630a3291f93..a67f0679348 100644 --- a/config/locales/views/en.yml +++ b/config/locales/views/en.yml @@ -1487,6 +1487,7 @@ en: header: You can create new skins for the Archive using our wizard, or by writing your own CSS (cascading style sheets) code numeric_values: description: + aspect_ratio_html: 'For the %{aspect_ratio_code} property, you can specify ratios using numeric values up to three decimal places.' em_unit_html: 'PS: we highly encourage learning about and using %{em_code}, which lets you set things relative to the viewer''s current font size! It will make your layouts much more flexible and responsive to different browser/font settings.' precision_html: 'You can specify numeric values up to two decimal places, either as percentages or in %{various_units_link}: %{units_list_code}' units_list: cm, em, ex, in, mm, pc, pt, px diff --git a/lib/css_cleaner.rb b/lib/css_cleaner.rb index 3325f826c5f..d8bd2132627 100644 --- a/lib/css_cleaner.rb +++ b/lib/css_cleaner.rb @@ -8,10 +8,13 @@ module CssCleaner ALPHA_REGEX = Regexp.new('[a-z\-]+') UNITS_REGEX = Regexp.new('deg|cm|em|ex|in|mm|pc|pt|px|s|%', Regexp::IGNORECASE) NUMBER_REGEX = Regexp.new('-?\.?\d{1,3}\.?\d{0,3}') + NUMBER_OR_RATIO_REGEX = Regexp.new("#{NUMBER_REGEX}(\s*\/\s*#{NUMBER_REGEX})?") NUMBER_WITH_UNIT_REGEX = Regexp.new("#{NUMBER_REGEX}\s*#{UNITS_REGEX}?\s*,?\s*") PAREN_NUMBER_REGEX = Regexp.new('\(\s*' + NUMBER_WITH_UNIT_REGEX.to_s + '+\s*\)') PREFIX_REGEX = Regexp.new('moz|ms|o|webkit') + GLOBAL_VALUE_REGEX = Regexp.new('inherit|initial|revert|revert-layer|unset', Regexp::IGNORECASE) + FUNCTION_NAME_REGEX = Regexp.new('scalex?y?|translatex?y?|skewx?y?|rotatex?y?|matrix', Regexp::IGNORECASE) TRANSFORM_FUNCTION_REGEX = Regexp.new("#{FUNCTION_NAME_REGEX}#{PAREN_NUMBER_REGEX}") @@ -136,6 +139,10 @@ def sanitize_css_declaration_value(property, value) if property == "font-family" # preserve the original capitalization clean = value if sanitize_css_font(value).present? + elsif property == "aspect-ratio" + # Allow either global values such as "inherit", "revert", etc; "auto"; a ratio; + # "auto" followed by a ratio; or a ratio followed by "auto". + clean = value if value.match(/^(#{GLOBAL_VALUE_REGEX}|auto|(auto\s+)?#{NUMBER_OR_RATIO_REGEX}(\s+auto)?)$/i) && !value.match(/^auto.*auto$/i) elsif property == "content" # don't allow var() function clean = value.match(/\bvar\b/i) ? "" : sanitize_css_content(value) diff --git a/spec/lib/css_cleaner_spec.rb b/spec/lib/css_cleaner_spec.rb index e2e09136f46..8019993f19d 100644 --- a/spec/lib/css_cleaner_spec.rb +++ b/spec/lib/css_cleaner_spec.rb @@ -243,6 +243,44 @@ skin = create(:work_skin, css: "p { color: red; }") expect(skin.reload.css).to include("#workskin p") end + + context "with aspect-ratio property" do + it "allows permitted values" do + skin = build(:work_skin, css: [ + "div { aspect-ratio: auto }", + "div { aspect-ratio: initial }", + "div { aspect-ratio: 1 }", + "div { aspect-ratio: 0.5 }", + "div { aspect-ratio: 16 /9 }", + "div { aspect-ratio: 16/ 9 }", + "div { aspect-ratio: 16 / 9}", + "div { aspect-ratio: 16/9 }", + "div { aspect-ratio: 1/1.75 }", + "div { aspect-ratio: auto 1 }", + "div { aspect-ratio: auto 0.25 }", + "div { aspect-ratio: auto 4/3 }", + "div { aspect-ratio: 1 auto }", + "div { aspect-ratio: 0.25 auto }", + "div { aspect-ratio: 0.5/ 1 auto }" + ].join("\n")) + expect(skin.save).to be_truthy + end + it "strips nonsensical values" do + skin = build(:work_skin, css: [ + "div { aspect-ratio: 1,300 }", + "div { aspect-ratio: 100% }", + "div { aspect-ratio: banana }", + "div { aspect-ratio: auto 1/1 auto }", + "div { aspect-ratio: auto auto }" + ].join("\n")) + expect(skin.save).to be_falsey + expect(skin.errors[:base]).to include("aspect-ratio in div cannot have the value 1,300, sorry!") + expect(skin.errors[:base]).to include("aspect-ratio in div cannot have the value 100%, sorry!") + expect(skin.errors[:base]).to include("aspect-ratio in div cannot have the value banana, sorry!") + expect(skin.errors[:base]).to include("aspect-ratio in div cannot have the value auto 1/1 auto, sorry!") + expect(skin.errors[:base]).to include("aspect-ratio in div cannot have the value auto auto, sorry!") + end + end end end end From 7de4f265c606b33250dd9734b05ec592ea2344fe Mon Sep 17 00:00:00 2001 From: Maximilian Krig