Inserting custom CSS style tag into head

Hi,

I want to insert a custom style tag in the header from within a widget and I’m using the following native method to do it:

private native void setCss(String css) /*-{
	
		var styleElem = document.getElementById("p-pagestyle");
		if (styleElem == null) {

			styleElem = document.createElement("style");
			styleElem.setAttribute("id", "p-pagestyle");
			styleElem.setAttribute("type", "text/css");
		
			document.getElementsByTagName('head')[0]
.appendChild(styleElem);
		}
			
		if (styleElem.styleSheet)
			styleElem.styleSheet.cssText = css;
		else {
			styleElem.innerHTML = css;
		}
		
		alert(document.getElementsByTagName('head')[0]
.innerHTML);
	}-*/;

This doesn’t work. When I inspect the head tag with Firebug, the tag is not there.

The weird thing though, is that “alert(document.getElementsByTagName(‘head’)[0]
.innerHTML);” returns a completely different head, so I believe there’s something I’ve missed.

Firebug shows the following head tag:

<head>
<style>
HTML{margin:0 !important;border:none !important;}
.dragdrop-handle{cursor:move;user-select:none;-khtml-user-select:none;-moz-user-select:none;}
.dragdrop-draggable{zoom:1;}
.dragdrop-dragging{zoom:normal;}
.dragdrop-positioner{border:1px dashed #1e90ff;margin:0 !important;zoom:1;z-index:100;}
.dragdrop-flow-panel-positioner{color:#1e90ff;display:inline;text-align:center;vertical-align:middle;}
.dragdrop-proxy{background-color:#7af;}
.dragdrop-selected,.dragdrop-dragging,.dragdrop-proxy{filter:alpha(opacity\=30);opacity:0.3;}
.dragdrop-movable-panel{z-index:200;margin:0 !important;border:none !important;}
</style>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<style type="text/css">html, body {height:100%;margin:0;}</style>
<link href="/TestProject/VAADIN/themes/mytheme/favicon.ico" type="image/vnd.microsoft.icon" rel="shortcut icon">
<link href="/TestProject/VAADIN/themes/mytheme/favicon.ico" type="image/vnd.microsoft.icon" rel="icon">
<title></title>
<link rel="stylesheet" type="text/css" href="/TestProject/VAADIN/themes/mytheme/styles.css">
</head>

But the alert gives me the following head:

<meta charset="UTF-8">
<script>var $gwt_version = "2.0.3";var $wnd = parent;var $doc = $wnd.document;var $moduleName, $moduleBase;var $strongName = '819DEA66B88D01A30082EDA0762AB078';var $stats = $wnd.__gwtStatsEvent ? function(a) {return $wnd.__gwtStatsEvent(a);} : null,$sessionId = $wnd.__gwtStatsSessionId ? $wnd.__gwtStatsSessionId : null;$stats && $stats({moduleName:'com.testproject.widgetset.MyWidgetset',sessionId:$sessionId,subSystem:'startup',evtGroup:'moduleStartup',millis:(new Date()).getTime(),type:'moduleEvalStart'});</script>
<style type="text/css" id="p-pagestyle">body { color: #ff0000; }</style>

Which does contain my inserted style object.

Why does it seem like there are two tags?

Usually you don’t need to inject any style tags to the head when using Vaadin. Just add your style declarations to the theme and you should be good to go.

Check out the Theme section in
Book Of Vaadin

I know, but the widget in this case compiles the css during runtime and has to insert it into .

Simple answer: because GWT code is sandboxed inside an IFRAME (so the default ‘document’ variable refers to the IFRAME’s document element).

All references to either the actual application’s window object of the document object should be made using the $wnd and $doc variables (inside JSNI methods).

private native void setCss(String css) /*-{
	
		var styleElem = [b]
$doc
[/b].getElementById("p-pagestyle");
		if (styleElem == null) {

			styleElem = [b]
$doc
[/b].createElement("style");
			styleElem.setAttribute("id", "p-pagestyle");
			styleElem.setAttribute("type", "text/css");
		
			[b]
$doc
[/b].getElementsByTagName('head')[0]
.appendChild(styleElem);
		}
			
		if (styleElem.styleSheet)
			styleElem.styleSheet.cssText = css;
		else {
			styleElem.innerHTML = css;
		}
		
		alert([b]
$doc
[/b].getElementsByTagName('head')[0]
.innerHTML);
	}-*/;

Perfect, thanks.