Problem extending SelectionScriptLinker

28 views
Skip to first unread message

Kamlesh

unread,
Jan 12, 2009, 8:34:15 AM1/12/09
to Google Web Toolkit
Hi,

I am a newbie in GWT. I have tried extending the SelectionScriptLinker
class to apply stylesheet based on some condition. But after
successful compilation of the code, when I run the main html file it
appears to go in infinite loop. The browser keeps on trying opening
the html, but it could not open it. Following is my code:

---------------------------------------------------------------------------------------------------------------------------------------------------------------
@LinkerOrder(LinkerOrder.Order.PRIMARY)
public class StyleSheetLinker extends SelectionScriptLinker {

@Override
protected String generateStylesheetInjector(String stylesheetUrl) {
if (stylesheetUrl.endsWith("styles1.css")) {
System.out.println("Using different style styles2.css");
stylesheetUrl = "styles2.css";
}
String hrefExpr = "'" + stylesheetUrl + "'";
if (isRelativeURL(stylesheetUrl)) {
hrefExpr = "base + " + hrefExpr;
}

return "if (!__gwt_stylesLoaded['"
+ stylesheetUrl
+ "']) {\n "
+ " var l = $doc.createElement('link');
\n "
+ " __gwt_stylesLoaded['"
+ stylesheetUrl
+ "'] = l;\n "
+ " l.setAttribute('rel', 'stylesheet');
\n "
+ " l.setAttribute('href', "
+ hrefExpr
+ ");\n "
+ " $doc.getElementsByTagName('head')[0].appendChild(l);
\n "
+ "}\n";
}

@Override
public ArtifactSet link(TreeLogger logger, LinkerContext context,
ArtifactSet artifacts) throws UnableToCompleteException {
ArtifactSet toReturn = new ArtifactSet(artifacts);

for (CompilationResult compilation : toReturn
.find(CompilationResult.class)) {
System.out.println("calling doEmitCompilation");
toReturn.add(doEmitCompilation(logger, context, compilation));
}

toReturn.add(emitSelectionScript(logger, context, artifacts));

return toReturn;
}

@Override
protected EmittedArtifact emitSelectionScript(TreeLogger logger,
LinkerContext context, ArtifactSet artifacts)
throws UnableToCompleteException {

DefaultTextOutput out = new DefaultTextOutput(true);

// Emit the selection script in a function closure.
out.print("(function () {");
out.newlineOpt();
String bootstrap = generateSelectionScript(logger, context,
artifacts);
bootstrap = context.optimizeJavaScript(logger, bootstrap);
out.print(bootstrap);
out.print("})();");
out.newlineOpt();

byte[] selectionScriptBytes = Util.getBytes(out.toString());
return emitBytes(logger, selectionScriptBytes, context.getModuleName
()
+ ".nocache.js");
}

@Override
protected String generateSelectionScript(TreeLogger logger,
LinkerContext context, ArtifactSet artifacts)
throws UnableToCompleteException {

StringBuffer selectionScript;
try {
selectionScript = new StringBuffer(Utility
.getFileFromClassPath(getSelectionScriptTemplate(logger,
context)));
} catch (IOException e) {
logger.log(TreeLogger.ERROR,
"Unable to read selection script template", e);
throw new UnableToCompleteException();
}

replaceAll(selectionScript, "__MODULE_FUNC__", context
.getModuleFunctionName());
replaceAll(selectionScript, "__MODULE_NAME__", context.getModuleName
());

int startPos;

// Add external dependencies
startPos = selectionScript.indexOf("// __MODULE_STYLES_END__");
if (startPos != -1) {
for (StylesheetReference resource : artifacts
.find(StylesheetReference.class)) {
String text = generateStylesheetInjector(resource.getSrc());
//System.out.println("StylesheetInjector\n"+text);
selectionScript.insert(startPos, text);
startPos += text.length();
}
}

startPos = selectionScript.indexOf("// __MODULE_SCRIPTS_END__");
if (startPos != -1) {
for (ScriptReference resource : artifacts
.find(ScriptReference.class)) {
String text = generateScriptInjector(resource.getSrc());
selectionScript.insert(startPos, text);
startPos += text.length();
}
}

// Add property providers
startPos = selectionScript.indexOf("// __PROPERTIES_END__");
if (startPos != -1) {
for (SelectionProperty p : context.getProperties()) {
String text = generatePropertyProvider(p);
selectionScript.insert(startPos, text);
startPos += text.length();
}
}

// Possibly add permutations
SortedSet<CompilationResult> compilations = artifacts
.find(CompilationResult.class);
startPos = selectionScript.indexOf("// __PERMUTATIONS_END__");
if (startPos != -1) {
StringBuffer text = new StringBuffer();
if (compilations.size() == 0) {
// We'll see this when running in Hosted Mode. The way the
// selection
// templates are structured is such that this line won't be
// executed
text.append("strongName = null;");

} else if (compilations.size() == 1) {
// Just one distinct compilation; no need to evaluate properties
Iterator<CompilationResult> iter = compilations.iterator();
CompilationResult result = iter.next();
text.append("strongName = null;");
// + compilationPartialPaths.get(result) + "';");

} else {
for (CompilationResult r : compilations) {
for (Map<SelectionProperty, String> propertyMap : r
.getPropertyMap()) {
// unflatten([v1, v2, v3], 'strongName');
text.append("unflattenKeylistIntoAnswers([");
boolean needsComma = false;
for (SelectionProperty p : context.getProperties()) {
if (!propertyMap.containsKey(p)) {
continue;
}

if (needsComma) {
text.append(",");
} else {
needsComma = true;
}
text.append("'" + propertyMap.get(p) + "'");
}
text.append("], '").append("');\n");
}
}

// strongName = answers[compute('p1')][compute('p2')];
text.append("strongName = answers[");
boolean needsIndexMarkers = false;
for (SelectionProperty p : context.getProperties()) {
if (p.tryGetValue() != null) {
continue;
}
if (needsIndexMarkers) {
text.append("][");
} else {
needsIndexMarkers = true;
}
text.append("computePropValue('" + p.getName() + "')");
}
text.append("];");
}
selectionScript.insert(startPos, text);
}

return selectionScript.toString();
}

@Override
protected String getCompilationExtension(TreeLogger logger,
LinkerContext context) throws UnableToCompleteException {
return ".cache.html";
}

@Override
protected String getModulePrefix(TreeLogger logger, LinkerContext
context)
throws UnableToCompleteException {

DefaultTextOutput out = new DefaultTextOutput(context.isOutputCompact
());
out.print("<!-- Nothing to print -->");
//out.newlineOpt();

/*// Setup the well-known variables.
out.print("<head><script>");
out.newlineOpt();
out.print("var $gwt_version = \"" + About.GWT_VERSION_NUM + "\";");
out.newlineOpt();
out.print("var $wnd = parent;");
out.newlineOpt();
out.print("var $doc = $wnd.document;");
out.newlineOpt();
out.print("var $moduleName, $moduleBase;");
out.newlineOpt();
if (supportRunAsync) {
out.print("function __gwtStartLoadingFragment(frag) {");
out.newlineOpt();
out.indentIn();
out.print(" var script = document.createElement('script');");
out.newlineOpt();
out.print(" script.src = '" + FRAGMENT_SUBDIR + "/" + strongName
+ "/' + frag + '" + FRAGMENT_EXTENSION + "';");
out
.print(" document.getElementsByTagName('head').item
(0).appendChild(script);");
out.indentOut();
out.newlineOpt();
out.print("};");
out.newlineOpt();
}
out
.print("var $stats = $wnd.__gwtStatsEvent ? function(a) {return
$wnd.__gwtStatsEvent(a);} : null;");
out.newlineOpt();
out.print("$stats && $stats({moduleName:'" + context.getModuleName()
+ "',subSystem:'startup',evtGroup:'moduleStartup'"
+ ",millis:(new Date()).getTime(),type:'moduleEvalStart'});");
out.newlineOpt();
out.print("</script></head>");
out.newlineOpt();
out.print("<body>");
out.newlineOpt();

// Begin a script block inside the body. It's commented out so that
the
// browser won't mistake strings containing "<script>" for actual
// script.
out.print("<script><!--");
*/ out.newline();
return out.toString();

}

@Override
protected String getModuleSuffix(TreeLogger logger, LinkerContext
context)
throws UnableToCompleteException {
DefaultTextOutput out = new DefaultTextOutput(context.isOutputCompact
());
/*out.print("$stats && $stats({moduleName:'" + context.getModuleName
()
+ "',subSystem:'startup',evtGroup:'moduleStartup'"
+ ",millis:(new Date()).getTime(),type:'moduleEvalEnd'});");

// Generate the call to tell the bootstrap code that we're ready to
go.
out.newlineOpt();
out.print("if ($wnd." + context.getModuleFunctionName() + ") $wnd."
+ context.getModuleFunctionName() + ".onScriptLoad();");
out.newline();
out.print("--></script></body></html>");
out.newlineOpt();*/

out.print("<!-- Nothing to print -->");

return out.toString();

}

@Override
protected String getSelectionScriptTemplate(TreeLogger logger,
LinkerContext context) throws UnableToCompleteException {
return "com/google/gwt/core/ext/linker/impl/HostedModeTemplate.js";
}

@Override
public String getDescription() {
// TODO Auto-generated method stub
return "StyleSheet";
}

}
-------------------------------------------------------------------------------------------------------------------------------------------------------------

I am able to see the script file name changed to styles2.css in the
generated nocache.js file.

Also this linker class has no affect on hosted mode. (?)

Please clear my doubts and let me know what needs to be done to
achieve the desired functionality.

Regards,
Kamlesh

olivier FRESSE

unread,
Jan 12, 2009, 12:46:38 PM1/12/09
to Google-We...@googlegroups.com
Extending a GWT component is not a good idea.
It's better to use a composite to create the component that fit your needs.
Take a look at http://code.google.com/intl/fr/docreader/#p=google-web-toolkit-doc-1-5&s=google-web-toolkit-doc-1-5&t=DevGuideCreatingCustomWidgets
Regards.


2009/1/12 Kamlesh <kkn...@gmail.com>
Reply all
Reply to author
Forward
0 new messages