Updated: Comment #25

Problem/Motivation

When using the Color module and switching color scheme, the css files are rewritten.
A problem occurs when an element has an id (#) that starts with a valid hex string (e.g. #bac is a valid hex string).
The css line with #bac in it will be replaced with a color (e.g. #ff0033 will change #background in a css line with #ff0033kground).

Proposed resolution

The solution proposed is to change the regular expression that filters the css tags to check for colors.
The current logic in #24 suggests a : followed by zero or more spaces, a # and three or six characters followed by a space (see #21).

Remaining tasks

Manual test if the regex and the replacement works properly.

The easiest way to test it is to patch Bartik with the following patch in #25 (https://drupal.org/files/color-css-bartik-manual-test-585172.patch).
Use Bartik as your theme and switch from the default color set to Firehouse.

All other manual testing is greatly encouraged.

Original report by @theresaanna

I am testing out a new theme using color module and I have two color schemes - my default and one other. Upon switching to my second color scheme, my "#background" id in style.css gets turned into "#fba6a6kground" after the conversion is done.

Here are my hex values:

'#B29269,#df783e,#F79F1A,#5C3F1C,#666666' => t('Sherbet (Default)'),
'#77E3FF,#3E6273,#293440,#454B4C,#666666' => t('Ocean Storms'),

Comments

theresaanna’s picture

Changing "#background" to ".background" un-confused color.module. So it seems the "#" is what is prompting this change. Which is not surprising but I thought I'd mention it anyway!

mattyoung’s picture

#bac is a legal css hex string. The color.module substitutes any #xxx string if xxx is a hex string it thinks it need to substitute. I have to make all my css id strings not begin with hex string to stop this. for example, if use #_background will solve the problem.

seanr’s picture

Definitely a bug - I just wasted some time on this too. Color.module's regexp needs to look for a # and three or six characters followed by a space.

seanr’s picture

Flagging for 7 - anyone know if this is still an issue?

seanr’s picture

Version: 6.14 » 7.x-dev
aspilicious’s picture

Something like this?

// Find all colors in the stylesheet and the chunks in between.
$style = preg_split('/(#[0-9a-f]{6}|#[0-9a-f]{3})/i', $style, -1, PREG_SPLIT_DELIM_CAPTURE);

TO

// Find all colors in the stylesheet and the chunks in between.
$style = preg_split('/(#([0-9a-f]{6}|[0-9a-f]{3})[^0-9a-zA-Z])/i', $style, -1, PREG_SPLIT_DELIM_CAPTURE);

mr.baileys’s picture

@aspilicious: the new regex should also take into account that hyphens and underscores are valid in CSS identifiers. So the regex you propose, while an improvement, could still rename "#bac-foo" to something else.

tim.plunkett’s picture

Version: 7.x-dev » 8.x-dev

Moving.

markhalliwell’s picture

I agree with @seanr's in #3. The regex needs to only match against # and three or six characters followed by a space.

seanr’s picture

It may not alway be a space (i.e. #fff;). What about this?

/(#[0-9a-f]{6}|#[0-9a-f]{3})\b/i

\b being word boundary. That still doesn't get us around the hyphen issue though.

iflista’s picture

Assigned: Unassigned » iflista

Working with this.

thijsvdanker’s picture

Title: Color.module changing class names when switching color scheme » Color.module changing css ids when switching color scheme
Issue tags: -Needs issue summary update

Updated the issue summary to match the current state of the issue.

mcrittenden’s picture

Assigned: iflista » Unassigned

@iflista please feel free to re-assign yourself if you'd like.

seanr’s picture

Status: Active » Needs review
StatusFileSize
new611 bytes

I created a patch based on #10. Not perfect as mentioned, but it's definitely an improvement.

markhalliwell’s picture

Issue tags: +Needs manual testing

Patch looks good. We need to manually test that this fixes the issue though.

thijsvdanker’s picture

StatusFileSize
new1.3 KB

I've tweaked it a little bit.

With the patch from #14, the css id's with a dash or a direct colon after it are still captured while they shouldn't be:
http://rubular.com/r/QASUuvVh8m

I've extended the regex to check for one or more spaces and 1 semicolon.
My result: http://rubular.com/r/X4QupGFn4Z

As a result of adding the semicolon to the regex it (the semicolon) is not spitted out as a chunk anymore.
Therefor I've added the

$chunk .= ';';

on line 443.

To review it manually:
Add this to the top of bartik's style.css:

#background: #bacbac;
#bac-ground: #bac;
#bac: #bac;
#bac: #bac ;
#BACKGROUND : #BACBBC;
#BAC-ground : #BACcbc ;

Add some styles to the different schemes of color.inc:

...
  // Pre-defined color schemes.
  'schemes' => array(
    'default' => array(
      'title' => t('Blue Lagoon (default)'),
      'colors' => array(
        'test' => '#bacbac',
        'test2' => '#bac',
        'top' => '#0779bf',
...
    'firehouse' => array(
      'title' => t('Firehouse'),
      'colors' => array(
        'test' => '#123456',
        'test2' => '#123',
        'top' => '#cd2d2d',

Start switching presets and check /sites/default/files/color/bartik-foobar/color.css.

mcrittenden’s picture

Title: Color.module changing css ids when switching color scheme » Color.module changes CSS IDs when switching color scheme

The one downside that I can think of about the approach in #16 is that a semicolon is not strictly required in CSS if it's the last property in a rule. For example, this is valid CSS:

#something {
  font-weight: bold;
  color: #000000
}

There's no semicolon after #000000 but it's still valid since it's the last rule, and the patch in #16 wouldn't catch that since it requires a semicolon be present. I'm not sure if this is really something we should worry about though, since I almost never see this in practice.

Thoughts?

thijsvdanker’s picture

Status: Needs review » Needs work
StatusFileSize
new1.3 KB

@mcrittenden: You're right.
I came up with:
/(#[0-9a-f]{6}\b|#[0-9a-f]{3}\b)\s*;*$/im
basically checking on an end-of-line.

but that fails on
#bac
{
bac-ground: #bac;
}

http://rubular.com/r/T7NeUVveZw

Patch attached, not sure if my regex-fu goes any further than this :)

markhalliwell’s picture

+++ b/core/modules/color/color.module
@@ -423,7 +423,7 @@ function _color_rewrite_stylesheet($theme, &$info, &$paths, $palette, $style) {
   // Find all colors in the stylesheet and the chunks in between.
-  $style = preg_split('/(#[0-9a-f]{6}|#[0-9a-f]{3})/i', $style, -1, PREG_SPLIT_DELIM_CAPTURE);
+  $style = preg_split('/(#[0-9a-f]{6}\b|#[0-9a-f]{3}\b)\s*;{1}/i', $style, -1, PREG_SPLIT_DELIM_CAPTURE);

I may not be getting the context of the function right now, but are we splitting these into "chunks" for any particular reason? Or are we just splitting them into chunks to try and find all the the hex values in the style sheet? It seems to me that this is just the wrong regex/function to begin with. Why iterate over each chunk when you can find them all at once?

Could we just not change this to preg_match_all and just find the hex values? Maybe something like:

$matches = array();
preg_match_all('/{[^#]*(#[0-9a-f]{6}|#[0-9a-f]{3})[^\n;\s]*/ims', $style, $matches, PREG_SET_ORDER);

Just a thought.

edit: note this regex only matches hexes inside curly brackets (to completely avoid #ids).

markhalliwell’s picture

StatusFileSize
new284.02 KB

Oops, forgot to upload a screenshot of my regex matches (note this has the "ims" pattern modifiers enabled):
color-regex.jpg

thijsvdanker’s picture

Status: Needs work » Needs review
StatusFileSize
new1.62 KB

The stylesheet is splitted into chunks because the css identifiers are also analyzed (to see if it is a link, text, or something else).
Link and text are special properties, and when they are detected in the chunk that is not a color, their value gets colorshifted.
see _color_shift().

My last attempt:
/\:\s*(#[0-9a-f]{6}\b|#[0-9a-f]{3}\b)/i
checking for a colon before the start of the color.
Worked pretty good for me!
http://rubular.com/r/p4E771NmFb

As the colon is now part of the capture, it needs to be added to the color chunk.

markhalliwell’s picture

Fair enough, this fixes the immediate issue. I still don't agree that this is really the right approach overall (for figuring out the right colors), but that is part of a bigger refactoring issue anyway. I'll just have to live with how bad color is until 9.x.

@thijsvdanker, could you update the issue summary with your steps to reproduce. Someone someone else, please manually test. Provide screenshots and upload the modified bartik source and the rewritten color files. Thanks!

Status: Needs review » Needs work

The last submitted patch, color-css_matching_regex-585172-21.patch, failed testing.

thijsvdanker’s picture

Status: Needs work » Needs review
StatusFileSize
new1.62 KB

The previous patch stripped of the space between the colon and the color, which is expected in the test.
This patch should make the test pass again.
I'll start updating the issue summary.

thijsvdanker’s picture

StatusFileSize
new2.12 KB

This patch can be used to modify Bartik to have some css that would fail before the patch.
Can be used to manually test the patch.

thijsvdanker’s picture

Issue summary: View changes

thijsvdanker: Changed the issue summary up to comment #11

thijsvdanker’s picture

Updated the issue summary.

Status: Needs review » Needs work

The last submitted patch, color-css-bartik-manual-test-585172.patch, failed testing.

thijsvdanker’s picture

Status: Needs work » Needs review

The patch in #25 is just to be used for manual testing.
The real patch in #24 passes the test.

markhalliwell’s picture

Status: Needs review » Needs work
StatusFileSize
new157.36 KB

I manually tested this. Everything looks good, but noticed that the gradients didn't get changed. I'm still convinced we should just try a different approach (like the one I suggested in #19) instead of trying to work inside of "chunks". Perhaps we should preg_match_all/preg_replace the color shifted things like links/text that match certain criteria first? Idk, just seems that we're trying to fix a broken system.

bartik-gradient.jpg

markhalliwell’s picture

Assigned: Unassigned » markhalliwell

I'm going to try and step through this to see how this is actually re-writing things.

markhalliwell’s picture

Assigned: markhalliwell » Unassigned
Status: Needs work » Needs review
Issue tags: -Novice, -Needs manual testing
StatusFileSize
new2.17 KB
new2.16 KB
new3.74 KB

Here is an 8.x version using preg_replace_callback and closures (which is far more powerful and easier to understand). This still does "chunks" but it is geared more around each selector group (between {}). @thijsvdanker, if you want we could still use the simpler regex for 7.x (if you can figure out the gradients).

Also attached is the before/after bartik CSS stylesheets.

markhalliwell’s picture

Issue summary: View changes

Updated issue summary to reflect state and manual testing.

jhedstrom’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll
kerby70’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new3.33 KB

Reroll attached.

Per #2361823: Remove usage of drupal_strtolower() changed drupal_strtolower to Unicode::strtolower

mgifford’s picture

StatusFileSize
new3.33 KB

Re-uploading for the bots.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Project: Drupal core » Color backport
Version: 9.4.x-dev » 2.x-dev
Component: color.module » Code

Color has been removed from core, #3270899: Remove Color module from core.