I have the following css:

.inner-wrap, .page-body {
  max-width: 80em;
  padding: 0 0.8em;
  margin: 0 auto;
  position: relative;
}

.page-body {
  padding-top: 2.4em;
  padding-bottom: 2.4em;
}

In that order. When I turn on advagg with default settings, suddenly the compressed css has the .inner-wrap selector after and therefore overriding my padding-top and bottom.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

aeotrin created an issue. See original summary.

mikeytown2’s picture

Need more info to reproduce this reported issue

$css = '.inner-wrap, .page-body {
  max-width: 80em;
  padding: 0 0.8em;
  margin: 0 auto;
  position: relative;
}

.page-body {
  padding-top: 2.4em;
  padding-bottom: 2.4em;
}';

$output = advagg_load_stylesheet_content($css, TRUE);
echo $output;

.inner-wrap,.page-body{max-width:80em;padding:0 0.8em;margin:0 auto;position:relative;}.page-body{padding-top:2.4em;padding-bottom:2.4em;}

aeotrin’s picture

I'll see if I can record the steps to reproduce. This just started happening on the last version update. I will test but I have a feeling it might have to do with the IE selector limit or any optimizers that might be running.

mikeytown2’s picture

Spliting up CSS was rewritten due to this issue #2852487: advagg_split_css_file() can lead to infinite loop; issue with large css files. (over 5k selectors for a single set of rules).

aeotrin’s picture

Thanks, Ill debug it and see if I can find out what might be causing it.
For reference my compiled css file is approximately 16K lines and the 2 selectors that I am finding out of order appear in the middle and the end of this file. Ill let you know what I find.

aeotrin’s picture

Found the bug. The grouping smaller chunks together was adding the first chunk to the end of the second chunk if the selector count was within the limit. It should have been changing the second chunk to be equal to the first chunk + second chunk.

See patch.

mikeytown2’s picture

Status: Active » Needs review
mikeytown2’s picture

I'll work on this tomorrow. Only concern is if multiple CSS parts get combined (think media queries). I'll want to test it.

aeotrin’s picture

Sounds good. My only concern that the patch solves is this:

-      $major_chunks[$next_key] .= ' ' . $value;
+      $major_chunks[$next_key] = $value . ' ' . $next_value;

It should not be appending the previous value to the end of the next value. It should be prepending the previous value to the next value.

mikeytown2’s picture

mikeytown2’s picture

Status: Needs review » Needs work

Verified and this works. Found a flaw in advagg_split_css_string where it's dropping the last selector in large rule sets (over the 4k limit). Will work on a solution and hopefully create a test; the test css file will have to be generated as I'm using a 5mb css file for testing currently.

  • mikeytown2 committed 4a3a152 on 7.x-2.x
    Issue #2866766 by aeotrin, mikeytown2: Reordering of css selectors
    
mikeytown2’s picture

Status: Needs work » Fixed
FileSize
5.6 KB

Code used to test

  module_load_include('inc', 'advagg', 'advagg');
  $file_info = array(
    'data' => 'main.css',
  );
  $before = (string) @file_get_contents($file_info['data']);
  $before_selector_count = advagg_count_css_selectors($before);

  $parts = advagg_split_css_file($file_info);
  $after = '';
  foreach ($parts as $part) {
    $after .= "\n" . (string) @file_get_contents($part['data']);
  }
  $after_selector_count = advagg_count_css_selectors($after);

If the selector counts don't match then it messed up.

To check the order diff seems like the only way to do it... which I can do locally but not in an automated way.

  module_load_include('inc', 'advagg', 'advagg');
  $file_info = array(
    'data' => 'main.css',
  );
  $before = (string) @file_get_contents($file_info['data']);
  $before_selector_count = advagg_count_css_selectors($before);

  $parts = advagg_split_css_file($file_info);
  $after = '';
  foreach ($parts as $part) {
    $after .= "\n" . (string) @file_get_contents($part['data']);
  }
  $after_selector_count = advagg_count_css_selectors($after);

  $before = str_replace(', ', ",\n", $before);
  $before = str_replace("\r", "\n", $before);
  $before = str_replace("\n\n", "\n", $before);
  $before = str_replace("} }", "}}\n", $before);
  $before = str_replace("}\n}", "}}\n", $before);
  $before = str_replace("\n \n", "\n", $before);
  $before = str_replace("\n\n", "\n", $before);


  $after = str_replace(', ', ",\n", $after);
  $after = str_replace("\r", "\n", $after);
  $after = str_replace("\n\n", "\n", $after);
  $after = str_replace("} }", "}}\n", $after);
  $after = str_replace("}\n}", "}}\n", $after);
  $after = str_replace("\n \n", "\n", $after);
  $after = str_replace("\n\n", "\n", $after);


  $uuid = uniqid();
  file_put_contents("temporary://before{$uuid}.txt", $before);
  file_put_contents("temporary://after{$uuid}.txt", $after);

  $return = array();
  $temp_dir = DRUPAL_ROOT . '/' . advagg_get_relative_path('temporary://');
  exec("diff -u -U 30 {$temp_dir}/before{$uuid}.txt {$temp_dir}/after{$uuid}.txt", $return);

  unlink("temporary://before{$uuid}.txt");
  unlink("temporary://after{$uuid}.txt");

  print_r($return);

Still need to generate a large css file for testing purposes.

  • mikeytown2 committed a462402 on 7.x-2.x
    Issue #2866766 by mikeytown2: Allow for better testing.
    
mikeytown2’s picture

Tests a generated file with 280,028 selectors making sure it gets split correctly.

  • mikeytown2 committed 49d9f98 on 7.x-2.x
    Issue #2866766 by mikeytown2: Add in tests for advagg_split_css_file().
    
mikeytown2’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.