| /* |
| * 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; |
| } |
| |
| } |