views:

372

answers:

3

Im having problems with a css text variable in this javascript with webkit based browsers(Chrome & Safari) but it works in firefox 3.6

importScript('User:Gerbrant/hidePane.js');//Special thanks to Gerbrant for this wonderful script
function addGlobalStyle(css) {
    var head = document.getElementsByTagName('head')[0];
    if (!head) { return; }
    var style = document.createElement('style');
    style.type = 'text/css';
    style.rel = 'stylesheet';
    style.media = 'screen';
    style.href = 'FireFox.css';
    style.innerHTML = css;
    head.appendChild(style);
}

//The page styling
var NewSyleText = 
"h1, h2, h3, h4, h5 {font-family: 'Verdana','Helvetica',sans-serif; font-style: normal; font-weight:normal;}" + 
"body, b {background: #fbfbfb; font-style: normal; font-family: 'Cochin','GaramondNo8','Garamond','Big Caslon','Georgia','Times',serif;font-size: 11pt;}" +
"p { margin: 0pt; text-indent:1.25em;  margin-top: 0.3em; }" +
"a {    text-decoration: none; color: Navy; background: none;}" +
"a:visited {    color: #500050;}" +
"a:active { color: #faa700;}" +
"a:hover {  text-decoration: underline;}" +
"a.stub {   color: #772233;}" +
"a.new, #p-personal a.new { color: #ba0000;}" +
"a.new:visited, #p-personal a.new:visited { color: #a55858;}" +
"a.new, #quickbar a.new { color: #CC2200; }" +
/* removes "From Wikipedia, the free encyclopedia" for those of you who actually know what site you are on */
"#siteSub { display: none; }" +
/* hides the speaker icon in some articles */
"#spoken-icon .image {  display:none;}" +
/* KHTMLFix.css */
"#column-content { margin-left: 0; }" +
/* Remove contents of the footer, but not the footer itself */
"#f-poweredbyico, #f-copyrightico { display:none;}" +
/* Needed to show the star icon in a featured article correctly */
"#featured-star div div {   line-height: 10px;}" +
/* And the content expands to top and left */
"#content {margin: 0; padding: 0; background:none;}" +
"#content div.thumb {border-color:white;}" +
/* Hiding the bar under the entry header */
"h1.firstHeading {  border-bottom: none;}" +
/* Used for US city entries */
"#coordinates {  top:1.2em;}";

addGlobalStyle(NewSyleText);//inserts the page styling
+1  A: 
var style = document.createElement('style');

Adding new stylesheets and scripts by creating elements using DOM methods is something that has always been dicey cross-browser. This won't work in IE or WebKit.

style.rel = 'stylesheet';
style.href = 'FireFox.css';

There's no such properties on an HTMLStyleElement. <style> contains inline code. For external stylesheets, use a <link>. By luck, it happens this does work:

var link= document.createElement('link');
link.rel= 'stylesheet';
link.href= 'something.css';
head.appendChild(link);

But doesn't give you a convenient way to insert rules from script.

You can also add new rules to an existing stylesheet (eg. an empty style in the <head>) by using the document.styleSheets interface. Unfortunately, IE's interface doesn't quite match the standard here so you need code branching:

var style= document.styleSheets[0];
if ('insertRule' in style)
    style.insertRule('p { margin: 0; }', 0);
else if ('addRule' in style)
    style.addRule('p', 'margin: 0', 0);
bobince
+1  A: 

I came up with the following code after trial and error for inserting dynamic CSS, which now works on all major browsers (Chrome/Safari/IE/FF/Opera):

function CreateCSS(CSS, doc) {
    // Default back to the current document if none specified,
    // otherwise use the specified document of e.g. an IFrame
    doc = doc||document

    // Create a CSS element
    var _CSS = doc.createElement('div')
    _CSS.innerHTML = '&nbsp;<style id="" type="text/css">'+CSS+'</style>&nbsp;'
    var Head = doc.getElementsByTagName("head")[0]
    if (!Head) {
        // SAFARI EARLY VERSIONS HACK!
        // Some safari versions don't find the "head" tag
        Head = doc.createElement('div')
        doc.body.appendChild(Head)}

    // Add the new style of higher priority than the last 
    // ones if there's already other elements in the head
    if (Head.firstChild)
        Head.insertBefore(_CSS.childNodes[1], Head.firstChild)
    else Head.appendChild(_CSS.childNodes[1])
    delete _CSS
}

I'm sure the code could be cleaned up a fair bit though. Some browsers seem to have trouble setting innerHTML of <style> tags unless the style tag itself is included in the HTML.

As that code is written, it is relative to the document being served so may need to be modified to make it relative to another path, or you could use absolute image paths in the CSS.

David Morrissey
This looks like a very legitimate answer;not that the other answers aren't that bad. going to do some testing 1st, before I pick it as the accepted answer. THANK YOU very much, if it does work.
GlassGhost
@GlassGhost: no worries - I use it in my web app so it should be fairly heavily tested
David Morrissey
A: 

I know this is a old thread but i was looking for a solution to insert CSS styles dynamicly that works with all common/major browsers. I want to share my solution with you. The solution of david doesn't work well (sorry). I have made a tooltip javascript/jQuery class that can work with inline styles for example but can also work with CSS styled styles. (offtopic: Also the class can auto align tooltips like the default tooltips).

Maybe you wonder what the benefits are when you insert CSS like the example above. Well, you don't need an extra CSS file with the styles and you can dynamicly add styles from script and when you working with images you can dynamicly change the path to the images if you want (so you don't need to change any file). Also you can insert the styles ABOVE other stylesheets/style rules and the aplied style rules can be modified in the other stylesheets below (this is not possible when you use inline styles or when placing the inserted rules BELOW any existing stylesheet).

This function works with Opera/Firefox/IE7/IE8/IE9/Chrome/Safari (without any hack applied!):

    function addHtmlStyles( sCss, oBefore ) 
    {
     var oHead = document.getElementsByTagName('head')[0];
     if( !oHead || oHead == null ) 
      { return false; }

     var bResult = false,
         oStyle = document.createElement('style');
     oStyle.type = 'text/css';
     oStyle.rel = 'stylesheet';
     oStyle.media = 'screen';

     if( typeof oStyle.styleSheet == 'object' ) 
      {  // IE route (and opera)
        try{ oStyle.styleSheet.cssText = sCss; bResult = true; }
        catch(e) {}  
      }
     else { 
             // Mozilla route
            try{ oStyle.innerHTML = sCss; bResult = true; }
            catch(e) {};
            if( !bResult )
            {
               // Webkit route
              try{ oStyle.innerText = sCss; bResult = true; }
              catch(e) {};
            }
          }

     if( bResult )
     {
      try 
      {
      if( typeof oBefore == 'object' )
       { oHead.insertBefore(oStyle, oBefore ); }
      else { oHead.appendChild(oStyle); }
      }
      catch(e) { bResult = false; }
     }

 return bResult;
}

It returns true when ok or false when fail. For example:

var sCss = '#tooltip {background:"#FF0000";}';

// get first stylesheet with jQuery, we don't use $('head') because it not always working
// If there is no stylesheet available, it will be added at the end of the head tag.
var oHead = $(document.getElementsByTagName('head')[0]),
    oFirst = oHead.find('[rel=stylesheet]').get(0);

if( addHtmlStyles( sCss, oFirst ))
 { alert( 'OK' ); }
else { alert( 'NOT OK' ); }

That's all. Hope you like the solution. Greetz, Erwin Haantjes

Erwinus