[jQuery] Cross-browser inline style injection in DOM

[jQuery] Cross-browser inline style injection in DOM


Hello all jQuery people.
This is my first post in this list but I hope I can make sense with my
question.
Currently I'm developing some web applications for internal use,
porting some old ones.
I'd love the jQuery-way to do asynchronous requests, so I developed a
plugin similar to Pimentech jFrame. Basicly, it "automagically"
catches all clicks on links, sends an AJAH request and loads the
response inside a container.
The problem came when the response contains STYLE or LINK tags. Using
Firefox and Opera all was perfect, but no style was applied with IE6,
IE7, Chrome or Safari. I was thinking that was my plugin's fault, but
when I test the use case without it, the problem remains. No style
applied.
Check this simplified case without even jQuery:
<body>
    <p id="test">This is a test and should have a border around and 1ex
padding!
    <script type="text/javascript">
        var div = document.createElement('div');
        // <br/> added to avoid a bug in IE
        div.innerHTML = '<br /><style>#test { border:2px solid #000; padding:
1ex; }</style>';
        var span = div.getElementsByTagName('span')[0];
        document.body.appendChild(div);
    </script>
</body>
I thought that jQuery have workarounds to this, but I found none, so I
created a plugin to do the work.
In case I missed some jQuery functionality, please tell me. I prefer
the jQuery way.
This plugin relies on detecting whether inlined styles are processed
or not. If not, modify $.fn.html to move all style's and link's to
document.head, mark them with a 'data-style-loader' attribute and
adding a dummy link to the target. When te dummy link is removed (with
the same $.fn.html function), it removes all related style's and
link's from head.
Well, that's the code:
$(function($) {
    // Checks for some supported features
    (function() {
        var div = document.createElement('div');
        div.id = 'jquery-support-styled';
        document.body.appendChild(div);
        // Checks whether inlined styles applies automaticly (Firefox and
Opera returns true)
        div.innerHTML = '<style>#'+div.id+' span { display:block; width:
3px; }</style><span />';
        var span = div.getElementsByTagName('span')[0];
        $.support.inlineStyleApplies = $(span).width() == 3;
        // Checks whether inlined styles applies if they are inside 'br'
context (for IE)
        $.support.mustPrependBrToInlineStyles = !
$.support.inlineStyleApplies && (function(){
            div.innerHTML = '<br /><style>#'+div.id+' span { display:block;
width:5px; }</style><span />';
            var span = div.getElementsByTagName('span')[0];
            return ($.support.inlineStyleApplies = $(span).width() == 5);
        })();
        document.body.removeChild(div);
    })();
    // Saves old $().html function
    var old_html = $.fn.html;
    if($.support.mustPrependBrToInlineStyles) {
        // Modify old $().html to add br before styles and links
        $.fn.html = function(_value) {
            if(typeof _value !== 'string') {
                _value = _value.replace(/<style|<link/gi, function(_text) {
                    return '<br style="display:none"/>'+_text
                })
            }
            return old_html.call(this, _value);
        }
    } else if(!$.support.inlineStyleApplies) {
        // Change old $().html to move link´s and style´s to the head
        $.fn.html = function(_text) {
            // Remove css-pointers and their pointees
            var $styles = this.find('link[data-style-loader]');
            if($styles.length) { clean_css($styles); }
            // Calls old $().html
            old_html.call(this, _text);
            // Promote new links and styles to document.head
            $styles = this.find('style,link[rel*=stylesheet]');
            if($styles.length) { add_styles.call(this, $styles) }
            return this;
        }
        // Remove css-pointers and their pointees
        function    clean_css(_$styles) {
            // Get pointees id
            var st = [];
            for(var i = 0; i < _$styles.length; ++i) {
                st[st.length] = '[data-style-loader='+$(_$styles[i]).attr('data-
style-loader')+']'
            }
            // Remove all links pointed
            $('head').find(st.join(', ')).remove();
        }
        // Promote new links and styles to document.head
        function    add_styles(_$styles) {
            // Selects a pointer id
            var tm = (new Date).getTime();
            // Move to head and add attribute with pointer id
            _$styles.attr('data-style-loader', tm).appendTo('head')
            // Create a pointer (link inside target) that points to the new
links and styles
            this.append('<link data-style-loader='+tm+' />')
        }
    }
})
I have tested the plugin with these cases:
1)

Default, no style


2) <style type="text/css">#test { color:red; }</style>
3) <link rel="stylesheet" href="remote.css" /> and remote.css #test
{ color:red; }
4) <style type="text/css">@import url("remote.css")</style>
5) <link rel="stylesheet" href="import.css" /> and import.css @import
url("remote.css")
The plugin works ok with some exceptions.
In IE6 and IE7, case 4 fails silently. Surprisingly, 5 is no problem.
In Safari and Chrome, the style isn't removed when loading 1) after 3)
or 5). After 2) or 4) it works ok.
So, any suggestions? I hope that jQuery has something on those lines.
Thanks all for reading, and sorry for the long post.
And thanks to the jQuery Team for such a marvelous tool!
Best regards!