Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #8282 (new enhancement)

Opened 1 year ago

Last modified 3 months ago

[PATCH] String#extractStyles, String#insertStyle, String#applyStyles

Reported by: apinstein Assigned to: sam
Priority: normal Milestone: 2.x
Component: Prototype Version: edge
Severity: normal Keywords:
Cc:

Description

I ran into the problem discussed here:

http://groups.google.com/group/rubyonrails-spinoffs/browse_frm/thread/61a0fa25d3abdf3a/4a1ea48726c50b68?lnk=gst&q=ajax.updater+style&rnum=2&

Essentially, this is the exact same problem that the <script> tag faces. Prototype already has a solution there, in evalScripts().

The same technique works for <style>, which is just to PARSE the responseText for the desired data and then add it manually to the head element. This is described well here:

http://www.phpied.com/dynamic-script-and-style-elements-in-ie/

I actually needed to fix this in YUI, not prototype (although I use both), but you'll get the idea. You could easily patch prototype to do the same. I simply call this function with the "responseText" from the XHR in my XHR success callback.

Here's the browser differences:

1. Firefox handles this already, so you don't need to do anything for FF.

2. For Safari, you must insert the style tag into the head via the DOM.

3. For IE, you must insert the style tag into the head via IE's goofy "styleSheet" property of the head element.

YAHOO.widget.PhocoaDialog.prototype.applyStyles = function(rawHTML) {
    if (this.browser == 'gecko') return;

    var headEl = null;  // lazy-load

    // find all styles in the string
    var styleFragRegex = '<style[^>]*>([\u0001-\uFFFF]*?)</style>';
    var matchAll = new RegExp(styleFragRegex, 'img');
    var matchOne = new RegExp(styleFragRegex, 'im');
    var styles = (rawHTML.match(matchAll) || []).map(function(tagMatch) {  
                                                                            return (tagMatch.match(matchOne) || ['', ''])[1];
                                                                        });

    // add all found style blocks to the HEAD element.
    for (i = 0; i < styles.length; i++) {
        if (!headEl)
        {  
            headEl = document.getElementsByTagName('head')[0];
            if (!headEl)
            {  
                return;
            }
        }
        var newStyleEl = document.createElement('style');
        newStyleEl.type = 'text/css';
        if (this.browser == 'ie')
        {  
            newStyleEl.styleSheet.cssText = styles[i];
        }
        else
        {  
            var cssDefinitionsEl = document.createTextNode(styles[i]);
            newStyleEl.appendChild(cssDefinitionsEl);
        }
        headEl.appendChild(newStyleEl);
    }
};

Attachments

0010-patch-with-String-extractStyles-String-insertStyle.patch (2.0 kB) - added by kangax on 04/10/08 00:43:24.

Change History

04/02/08 23:42:09 changed by jdalton

  • type changed from enhancement to defect.

04/10/08 00:43:24 changed by kangax

  • attachment 0010-patch-with-String-extractStyles-String-insertStyle.patch added.

04/10/08 00:44:15 changed by kangax

  • type changed from defect to enhancement.
  • summary changed from Ajax.Updater response includes <style> definitions, but they only work in Firefox to [PATCH] String#extractStyles, String#insertStyle, String#applyStyles.

04/10/08 01:13:48 changed by jdalton

you might want to keep the fragment regexp consistent with the one provided on this patch: #9663, (It passes the 7000 char limit in Safari 2 too)

04/10/08 01:16:50 changed by kangax

just for the reference, the check for styleSheet.disabled is based on this post http://trac.dojotoolkit.org/ticket/1958

04/10/08 01:30:47 changed by jdalton

also see not on overly complicated extractScripts/extractStyle method:
http://dev.rubyonrails.org/ticket/9599[[BR]]

Benchmarks coming soon..

04/10/08 01:32:16 changed by jdalton

(darn the !wikiFormatting) #9599