diff --git a/CHANGELOG.md b/CHANGELOG.md index e85db7d..588a794 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## v0.3.20 (TBA) * Require Elixir 1.13 +* `Premailex.CSSParser.parse/1` now ignores empty selectors ## v0.3.19 (2023-11-19) diff --git a/lib/premailex/css_parser.ex b/lib/premailex/css_parser.ex index 1caef86..30dd235 100644 --- a/lib/premailex/css_parser.ex +++ b/lib/premailex/css_parser.ex @@ -2,6 +2,7 @@ defmodule Premailex.CSSParser do @moduledoc """ Module that handles CSS parsing with naive Regular Expression. """ + require Logger @type rule :: %{directive: String.t(), value: String.t(), important?: boolean} @type rule_set :: %{rules: [rule], selector: String.t(), specificity: number} @@ -65,12 +66,27 @@ defmodule Premailex.CSSParser do selector # Ignore escaped commas |> String.split(~r/(? normalize_selectors(selector) |> Enum.map(&parse_selector_rules(&1, rules)) end + defp normalize_selectors(selectors, original) do + Enum.reduce(selectors, [], fn selector, acc -> + case String.trim(selector) do + "" -> + Logger.debug("Empty selector found in #{inspect(String.trim(original))}. Ignoring.") + + acc + + selector -> + acc ++ [selector] + end + end) + end + defp parse_selector_rules(selector, rules) do %{ - selector: String.trim(selector), + selector: selector, rules: parse_rules(rules), specificity: calculate_specificity(selector) } diff --git a/test/premailex/css_parser_test.exs b/test/premailex/css_parser_test.exs index 6de4f2c..22a125f 100644 --- a/test/premailex/css_parser_test.exs +++ b/test/premailex/css_parser_test.exs @@ -2,6 +2,8 @@ defmodule Premailex.CSSParserTest do use ExUnit.Case doctest Premailex.CSSParser + alias ExUnit.CaptureLog + @input """ body, table {/* text-decoration:underline */background-color:#ffffff;background-image:url('http://example.com/image.png');color:#000000;} div p > a:hover {color:#000000 !important;text-decoration:underline} @@ -19,6 +21,7 @@ defmodule Premailex.CSSParserTest do url("/fonts/OpenSans-Regular-webfont.woff") format("woff"); } .with\\,escaped\\,commas {} + .with-empty-selector, {} """ @parsed [ @@ -60,10 +63,17 @@ defmodule Premailex.CSSParserTest do rules: [], selector: ".with\\,escaped\\,commas", specificity: 1 + }, + %{ + rules: [], + selector: ".with-empty-selector", + specificity: 1 } ] test "parse/1" do - assert Premailex.CSSParser.parse(@input) == @parsed + assert CaptureLog.capture_log(fn -> + assert Premailex.CSSParser.parse(@input) == @parsed + end) =~ "Empty selector found in \".with-empty-selector,\". Ignoring." end end diff --git a/test/premailex/html_inline_styles_test.exs b/test/premailex/html_inline_styles_test.exs index 4630ec2..700b2da 100644 --- a/test/premailex/html_inline_styles_test.exs +++ b/test/premailex/html_inline_styles_test.exs @@ -12,6 +12,7 @@ defmodule Premailex.HTMLInlineStylesTest do h1, h2, h3, h4, p {margin: 0; padding: 0;} p:first-of-type {font-size:16px;font-weight:bold;} + .invalid-empty-selector, {} """ @css_inline_content """