Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error parsing bootstrap css #77

Closed
arbh89 opened this issue Jan 13, 2016 · 8 comments
Closed

Error parsing bootstrap css #77

arbh89 opened this issue Jan 13, 2016 · 8 comments

Comments

@arbh89
Copy link

arbh89 commented Jan 13, 2016

I am getting an error when tring to parse bootstrap css framework.

The string did not match the expected pattern.
at AngleSharp.Extensions.QueryExtensions.QuerySelectorAll(INodeList elements, String selectors)
at AngleSharp.Dom.Document.QuerySelectorAll(String selectors)
at PreMailer.Net.PreMailer.FindElementsWithStyles(SortedList`2 stylesToApply) in PreMailer.cs:line 305
at PreMailer.Net.PreMailer.MoveCssInline(Boolean removeStyleElements, String ignoreElements, String css, Boolean stripIdAndClassAttributes, Boolean removeComments) in PreMailer.cs:line 104
at PreMailer.Net.PreMailer.MoveCssInline(String html, Boolean removeStyleElements, String ignoreElements, String css, Boolean stripIdAndClassAttributes, Boolean removeComments) in PreMailer.cs:line 51

Do you have any idea?

@martinnormark
Copy link
Contributor

Can you debug and find out the string passed to AngleSharp´s QuerySelectorAll method, in FindElementsWithStyles when it fails?

As a workaround now, use the v1.4.3 tag - the current version on Nu Get, which uses the old HTML parser instead of AngleSharp introduced in #76.

@arbh89
Copy link
Author

arbh89 commented Jan 13, 2016

The string passed was @Keyframes progress-bar-stripes, i found that the error is when the selector starts with @, i added the next validation to the method FindElementsWithStyles.

foreach (var style in stylesToApply)
{
if (!style.Value.Name.StartsWith("@"))
{
var elementsForSelector = _document.QuerySelectorAll(style.Value.Name);

                foreach (var el in elementsForSelector)
                {
                    var existing = result.ContainsKey(el) ? result[el] : new List<StyleClass>();
                    existing.Add(style.Value);
                    result[el] = existing;
                }
            }
        }

Now it is working.

@CodeAnimal
Copy link
Contributor

@martinnormark You said in #78 that you're waiting on this issue to be sorted before a NuGet release with the new AngelSharp. Is there any idea when this will be? I'm actually getting the same issue as #9 and I'm hoping the AngelSharp switch will fix this.

@martinnormark
Copy link
Contributor

Have you tried verifying using current master branch, and writing a test case for it?

Haven't looked further into a general way of solving this issue yet.

@arbh89
Copy link
Author

arbh89 commented Jan 27, 2016

I have downloaded bootstrap from here https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css to my C drive and have added the next test case to PreMailerTests.cs to reproduce the error.

        public void MoveCssInline_BootstrapFramework()
        {
            string input = "<html lang=\"en\"><head></head><body><div class=\"container\"><form class=\"form-signin\"><h2 class=\"form-signin-heading\">Please sign in</h2><label for=\"inputEmail\" class=\"sr-only\">Email address</label><input type=\"email\" id=\"inputEmail\" class=\"form-control\" placeholder=\"Email address\" required=\"\" autofocus=\"\"><label for=\"inputPassword\" class=\"sr-only\">Password</label><input type=\"password\" id=\"inputPassword\" class=\"form-control\" placeholder=\"Password\" required=\"\"><div class=\"checkbox\"><label><input type=\"checkbox\" value=\"remember-me\"> Remember me</label></div><button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button></form></div> <!-- /container --></body></html>";

            string bootstrapFrameworkContent = File.ReadAllText("C:\\bootstrap.min.css");

            var premailedOutput = PreMailer.MoveCssInline(input, css: bootstrapFrameworkContent);

            Assert.IsTrue(premailedOutput.Html.Contains("<html lang=\"en\">"));
        }

@CodeAnimal
Copy link
Contributor

@arbh89 Is that method to test #9? Or for this issue? I'll see if I can find some time to write up a test case if not (although I'm crazy busy at the minute).

@martinnormark
Copy link
Contributor

This issue. There's a comment with markup to test #9 in that issue: #9 (comment)

@martinnormark
Copy link
Contributor

As a catch all, I've wrapped querying DOM elements by CSS selector in a try-catch block, adding to the warnings array of the result the failed selectors.

For this particular issue, note that even the minified Bootstrap CSS is a 118 KB footprint in every email you sent.

Currently PreMailer does not parse a keyframe block correctly, since each percentage step within will become their own selector. It should probably identify blocks such as this as unsupported selectors, and force it into the actual style block of the email so that animations will work - regardless of the removeStyleElements flag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants