The current way Wysiwyg gets the stylesheets for a theme has several limitations, see linked issues.
It is currently only possible to get the stylesheets for the "active" theme, and the active theme changes with where on the site you are.

Main issue:

Drupal provides no direct mechanism for a module to get a list of all stylesheets to be used at render time. Implementing something like that is a chicken-or-egg-problem since the theme (running after modules) could also add more stylesheets during rendering.

Secondary issue:

Drupal provides no mechanism for a module to switch to a different active theme at runtime, or render something with anything but the active theme. There are too many caches and functions which need to be replaced for something like that to work.

Solution:

This patch suggest a method where an additional page request is performed the first time a list of stylesheets are requested, for any theme. The requested path uses its own theme callback, page callback, and delivery callback to activate a given theme, render a dummy string, collect and cache the added stylesheets, and finally return the contents of the cache once the background request is done. The theme callback can only "suggest" a theme to use for a page, so the page only callback checks if the requested theme was actually activated. Using a pre render callback for the style tag not only means we can go through all stylesheets just before they're added to the page, but that they've already been optimized and/or aggregated, so the editors can use the same files used by the themes.

This patch would allow properly implementing features like #1309040: Select which theme's CSS to use when choosing 'Use theme CSS' in settings and #1017564: Allow user to dynamically change in-editor theme.

Note:

On some server configurations, it may not be possible to use drupal_http_request() to ready the stylesheet cache. Maybe we could detect this and either tell an admin to visit the dummy page manually once for each theme, or some other way.

This patch needs careful testing to make sure no user is given information about a theme which they do not have access to!
wysiwyg_get_css() does not perform any checks to see if the current user has access to the requested theme, since I've put the responsibility on the caller for now. Wysiwyg does still not actually call this with a specific theme, so it always defaults to the active theme, maintaining backwards compatibility (even though that's a bit unpredictable) and ensuring it's a theme the current user must have access to.

Suggestions appreciated!

Comments

twod’s picture

StatusFileSize
new17.77 KB

Here's a new version, which includes the theme select functionality from #1309040: Select which theme's CSS to use when choosing 'Use theme CSS' in settings as these issues overlap quite a bit.
Many thanks for the hard work of all contributors in that issue, and in the other issues related to this one.
I will close the other issuess and point people here as this change should cover all those use cases.

TwoD credited Alan D..

TwoD credited fenstrat.

TwoD credited hefox.

TwoD credited jhedstrom.

TwoD credited joegraduate.

TwoD credited jyee.

TwoD credited mstrelan.

TwoD credited willvincent.

twod’s picture

  • TwoD committed 952b057 on 7.x-2.x
    - #2289683 by TwoD: Added the ability to select the in-editor theme....
twod’s picture

Title: Get all stylesheets from a theme » Select in-editor theme and get all stylesheets
Status: Needs review » Fixed

In the interest of fixing many of these CSS-related issues and speeding up the next release I've committed this.
i forgot to add all the usernames in the commit message though, apologies for that.

jurriaanroelofs’s picture

Status: Fixed » Needs work

This patch produces notices when saving the theme settings form:

Notice: Undefined index: theme in _wysiwyg_system_theme_settings_submit() (line 770 of /home/r1qga/www/sites/default/modules/wysiwyg/wysiwyg.module).

I could reproduce this notice on a fresh Drupal 7-standard profile installation with only wysiwyg added to it (only simplytest.me).

twod’s picture

Interesting, will have to check why that value is not there...
Thanks for finding it!

jurriaanroelofs’s picture

welcome to the theme settings form, where nothing makes sense and everything is possible ;)
(I spend too much time in the theme settings form)

twod’s picture

LOL!

Do you think just looking at arg(3) is enough? Seems not all themes used the form state variable as I though.

  • TwoD committed 128926a on 7.x-2.x
    - #2289683 by TwoD, JurriaanRoelofs: Fixed notice when saving theme...
twod’s picture

Status: Needs work » Fixed

Looking at the form build args was better as it also avoids the case when saving the global settings.
Thanks again!

Status: Fixed » Closed (fixed)

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

smustgrave’s picture

How are the values in _wysiwyg_pre_render_styles set? I checked the array that's passed in and all the css files are there except the ones from my theme.

smustgrave’s picture

After some more testing and config changes nothing seems to work. No matter the config setting 'Active, 'Admin', etc it won't pick up my current theme. And I noticed it's loading some css from a second profile who's themes are disabled? Forgot to also mention that I checked the return value of wysiwyg_ckeditor_settings and it's returning the correct files so something along the way is messing that up. Any assistance would be appreciated.

twod’s picture

@smustgrave, What do you mean by how the values are set? That function is a #pre_render callback for the styles element so it gets all the stylesheets passed in through the $variables argument. It then saves them for use in the original request using cache_set(), as any PHP variable would be lost when the sub-request ends.

If you've set an editor profile to use a disabled theme, then yes it may try to load those files (or something else may be trying to load a disabled theme).

smustgrave’s picture

So I've tried to set the wysiwyg to use my default theme, active theme, and I selected the particular theme I wanted it to use. But it keeps defaulting to my admin theme and never loads the css in my custom theme.

dsnopek’s picture

@smustgrave In case you're having the same issue I am, I just opened an issue describing how the patch here doesn't work in my environment:

#2884450: Theme CSS not added correctly when PHP can't make HTTP requests to the site itself

dsnopek’s picture

Here's another problem I'm having with the new implementation added in this issue:

#2884691: "Use theme CSS" gives incorrect CSS when '#groups' array doesn't line up with child elements

cilefen’s picture

The http request to determine theme access has been very slow or actually timing out on a site I manage on Acquia Cloud.

+++ b/wysiwyg.module
@@ -665,28 +680,104 @@ function wysiwyg_get_editor_config($profile, $theme) {
+    $url = url('wysiwyg_theme/' . $theme, array('absolute' => TRUE, 'max_redirects' => 0));
+    $response = drupal_http_request($url);;