blob: 8061ac3be8b48dbb007ce2dde282333287811cbe [file] [log] [blame]
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.core.ext.linker.impl;
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.ScriptReference;
import com.google.gwt.core.ext.linker.StylesheetReference;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Utility class to help linkers do resource injection.
*/
public class ResourceInjectionUtil {
/**
* Installs stylesheets and scripts.
*/
public static StringBuffer injectResources(StringBuffer selectionScript,
ArtifactSet artifacts) {
// Add external dependencies
int startPos = selectionScript.indexOf("// __MODULE_STYLES_END__");
if (startPos != -1) {
for (StylesheetReference resource : artifacts.find(StylesheetReference.class)) {
String text = generateStylesheetInjector(resource.getSrc());
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();
}
}
return selectionScript;
}
/**
* Installs stylesheets using the installOneStylesheet method, which is
* assumed to be defined on the page. The installOneStylesheet()
* helper function is invoked as follows:
*
* <pre>
* installOneStylesheet(URL);
* </pre>
*/
public static StringBuffer injectStylesheets(StringBuffer selectionScript,
ArtifactSet artifacts) {
int startPos = selectionScript.indexOf("// __MODULE_STYLES__");
if (startPos != -1) {
for (StylesheetReference resource : artifacts.find(StylesheetReference.class)) {
String text = "installOneStylesheet('" + resource.getSrc() + "');\n";
selectionScript.insert(startPos, text);
startPos += text.length();
}
}
return selectionScript;
}
private static String generateScriptInjector(String scriptUrl) {
if (isRelativeURL(scriptUrl)) {
return " if (!__gwt_scriptsLoaded['"
+ scriptUrl
+ "']) {\n"
+ " __gwt_scriptsLoaded['"
+ scriptUrl
+ "'] = true;\n"
+ " document.write('<script language=\\\"javascript\\\" src=\\\"'+base+'"
+ scriptUrl + "\\\"></script>');\n" + " }\n";
} else {
return " if (!__gwt_scriptsLoaded['" + scriptUrl + "']) {\n"
+ " __gwt_scriptsLoaded['" + scriptUrl + "'] = true;\n"
+ " document.write('<script language=\\\"javascript\\\" src=\\\""
+ scriptUrl + "\\\"></script>');\n" + " }\n";
}
}
/**
* Generate a Snippet of JavaScript to inject an external stylesheet.
*
* <pre>
* if (!__gwt_stylesLoaded['URL']) {
* var l = $doc.createElement('link');
* __gwt_styleLoaded['URL'] = l;
* l.setAttribute('rel', 'stylesheet');
* l.setAttribute('href', HREF_EXPR);
* $doc.getElementsByTagName('head')[0].appendChild(l);
* }
* </pre>
*/
private static String generateStylesheetInjector(String stylesheetUrl) {
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";
}
/**
* Determines whether or not the URL is relative.
*
* @param src the test url
* @return <code>true</code> if the URL is relative, <code>false</code> if not
*/
private static boolean isRelativeURL(String src) {
// A straight absolute url for the same domain, server, and protocol.
if (src.startsWith("/")) {
return false;
}
// If it can be parsed as a URL, then it's probably absolute.
try {
// Just check to see if it can be parsed, no need to store the result.
new URL(src);
// Let's guess that it is absolute (thus, not relative).
return false;
} catch (MalformedURLException e) {
// Do nothing, since it was a speculative parse.
}
// Since none of the above matched, let's guess that it's relative.
return true;
}
}