Revision: 7760
Author: sp...@google.com
Date: Mon Mar 22 09:13:22 2010
Log: Extract from the selection script templates the functions
computeScriptBase() and processMetas() and put them in
their own files.  Those files are patched into the
selection script templates by SelectionScriptLinker.
Additionally, the now-isolated files are tested
using HtmlUnit.

Thanks to amitmanjhi for helping me with HtmlUnit.

Review at http://gwt-code-reviews.appspot.com/229802

http://code.google.com/p/google-web-toolkit/source/detail?r=7760

Added:
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/computeScriptBase.js
 /trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/processMetas.js
/trunk/dev/core/test/com/google/gwt/core/ext/linker/impl/SelectionScriptJavaScriptTest.java
Modified:
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/SelectionScriptLinker.java
 /trunk/dev/core/src/com/google/gwt/core/linker/IFrameTemplate.js
 /trunk/dev/core/src/com/google/gwt/core/linker/XSTemplate.js
 /trunk/user/test/com/google/gwt/core/ext/LinkerSuite.java

=======================================
--- /dev/null
+++ /trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/computeScriptBase.js Mon Mar 22 09:13:22 2010
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+/**
+ * Determine our own script's URL via magic :)
+ * This function produces one side-effect, it sets base to the module's
+ * base url.
+ *
+ * This is included into the selection scripts
+ * wherever COMPUTE_SCRIPT_BASE appears with underlines
+ * on each side.
+ */
+function computeScriptBase() {
+  var thisScript
+  ,markerId = "__gwt_marker___MODULE_NAME__"
+  ,markerScript;
+
+  if (metaProps['baseUrl']) {
+    base = metaProps['baseUrl'];
+    return;
+  }
+
+  $doc.write('<script id="' + markerId + '"></script>');
+  markerScript = $doc.getElementById(markerId);
+
+ // Our script element is assumed to be the closest previous script element
+  // to the marker, so start at the marker and walk backwards until we find
+  // a script.
+  thisScript = markerScript && markerScript.previousSibling;
+  while (thisScript && thisScript.tagName != 'SCRIPT') {
+    thisScript = thisScript.previousSibling;
+  }
+
+  // Gets the part of a url up to and including the 'path' portion.
+  function getDirectoryOfFile(path) {
+    // Truncate starting at the first '?' or '#', whichever comes first.
+    var hashIndex = path.lastIndexOf('#');
+    if (hashIndex == -1) {
+      hashIndex = path.length;
+    }
+    var queryIndex = path.indexOf('?');
+    if (queryIndex == -1) {
+      queryIndex = path.length;
+    }
+ var slashIndex = path.lastIndexOf('/', Math.min(queryIndex, hashIndex));
+    return (slashIndex >= 0) ? path.substring(0, slashIndex + 1) : '';
+  };
+
+  if (thisScript && thisScript.src) {
+    // Compute our base url
+    base = getDirectoryOfFile(thisScript.src);
+  }
+
+  // Make the base URL absolute
+  if (base == '') {
+    // If there's a base tag, use it.
+    var baseElements = $doc.getElementsByTagName('base');
+    if (baseElements.length > 0) {
+ // It's always the last parsed base tag that will apply to this script.
+      base = baseElements[baseElements.length - 1].href;
+    } else {
+      // No base tag; the base must be the same as the document location.
+      base = getDirectoryOfFile($doc.location.href);
+    }
+  } else if ((base.match(/^\w+:\/\//))) {
+    // If the URL is obviously absolute, do nothing.
+  } else {
+ // Probably a relative URL; use magic to make the browser absolutify it.
+    // I wish there were a better way to do this, but this seems the only
+    // sure way!  (A side benefit is it preloads clear.cache.gif)
+    // Note: this trick is harmless if the URL was really already absolute.
+    var img = $doc.createElement("img");
+    img.src = base + 'clear.cache.gif';
+    base = getDirectoryOfFile(img.src);
+  }
+
+  if (markerScript) {
+    // remove the marker element
+    markerScript.parentNode.removeChild(markerScript);
+  }
+}
=======================================
--- /dev/null
+++ /trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/processMetas.js Mon Mar 22 09:13:22 2010
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+/** Called to slurp up all <meta> tags:
+ * gwt:property, gwt:onPropertyErrorFn, gwt:onLoadErrorFn
+ *
+ * This is included into the selection scripts
+ * wherever PROCESS_METAS appears with underlines
+ * on each side.
+ */
+function processMetas() {
+  var metas = document.getElementsByTagName('meta');
+  for (var i = 0, n = metas.length; i < n; ++i) {
+    var meta = metas[i]
+    , name = meta.getAttribute('name')
+    , content;
+
+    if (name) {
+      name = name.replace('__MODULE_NAME__::', '');
+      if (name.indexOf('::') >= 0) {
+        // It's for a different module
+        continue;
+      }
+
+      if (name == 'gwt:property') {
+        content = meta.getAttribute('content');
+        if (content) {
+          var value, eq = content.indexOf('=');
+          if (eq >= 0) {
+            name = content.substring(0, eq);
+            value = content.substring(eq + 1);
+          } else {
+            name = content;
+            value = '';
+          }
+          metaProps[name] = value;
+        }
+      } else if (name == 'gwt:onPropertyErrorFn') {
+        content = meta.getAttribute('content');
+        if (content) {
+          try {
+               propertyErrorFunc = eval(content);
+          } catch (e) {
+               alert('Bad handler \"' + content +
+                   '\" for \"gwt:onPropertyErrorFn\"');
+          }
+       }
+      } else if (name == 'gwt:onLoadErrorFn') {
+        content = meta.getAttribute('content');
+        if (content) {
+             try {
+               onLoadErrorFunc = eval(content);
+             } catch (e) {
+ alert('Bad handler \"' + content + '\" for \"gwt:onLoadErrorFn\"');
+          }
+        }
+      }
+    }
+  }
+}
=======================================
--- /dev/null
+++ /trunk/dev/core/test/com/google/gwt/core/ext/linker/impl/SelectionScriptJavaScriptTest.java Mon Mar 22 09:13:22 2010
@@ -0,0 +1,235 @@
+/*
+ * 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.util.tools.Utility;
+
+import com.gargoylesoftware.htmlunit.AlertHandler;
+import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
+import com.gargoylesoftware.htmlunit.MockWebConnection;
+import com.gargoylesoftware.htmlunit.Page;
+import com.gargoylesoftware.htmlunit.WebClient;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Tests the JavaScript code in the selection script test using HtmlUnit.
+ */
+public class SelectionScriptJavaScriptTest extends TestCase {
+  private static String TEST_MODULE_NAME = "test.Module";
+
+  /**
+ * Return script code that includes the definition of computeScriptBase(),
+   * most of the variables it needs to run, and a call to the function. It
+   * assumes that the metaProps variable is already in scope.
+   */
+  private static String loadComputeScriptBase() throws IOException {
+    StringBuffer code = new StringBuffer();
+    code.append("var base = \"\", $doc=document;\n");
+ code.append(Utility.getFileFromClassPath(SelectionScriptLinker.COMPUTE_SCRIPT_BASE_JS));
+    code.append("computeScriptBase();\n");
+    return code.toString().replaceAll("__MODULE_NAME__", TEST_MODULE_NAME);
+  }
+
+  /**
+   * Return script code that includes the definition of processMetas(), all
+   * variables it needs to run, and a call to the function.
+   */
+  private static String loadProcessMetas() throws IOException {
+    StringBuffer code = new StringBuffer();
+ code.append("var metaProps = { }, propertyErrorFunc, onLoadErrorFunc;\n"); + code.append(Utility.getFileFromClassPath(SelectionScriptLinker.PROCESS_METAS_JS));
+    code.append("processMetas();\n");
+    return code.toString().replaceAll("__MODULE_NAME__", TEST_MODULE_NAME);
+  }
+
+  /**
+   * Test a meta tag specifying a base for this module
+   */
+  public void testModuleSpecificMetas1() throws IOException {
+    StringBuffer metas = new StringBuffer();
+    metas.append("<meta name=\"" + TEST_MODULE_NAME
+        + "::gwt:property\" content=\"baseUrl=http://new/base\";>\n");
+
+    StringBuffer testCode = new StringBuffer();
+    testCode.append(loadProcessMetas());
+    testCode.append("alert('baseUrl='+metaProps['baseUrl']);\n");
+
+    List<String> alerts = loadPage(makeHostPage(metas), testCode);
+
+    assertEquals(1, alerts.size());
+    assertEquals("baseUrl=http://new/base";, alerts.get(0));
+  }
+
+  /**
+   * Test a meta tag specifying a base for a different module.
+   */
+  public void testModuleSpecificMetas2() throws IOException {
+    StringBuffer metas = new StringBuffer();
+ metas.append("<meta name=\"some.other.module::gwt:property\" content=\"baseUrl=http://new/base\";>\n");
+
+    StringBuffer testCode = new StringBuffer();
+    testCode.append(loadProcessMetas());
+    testCode.append("alert('baseUrl='+metaProps['baseUrl']);\n");
+
+    List<String> alerts = loadPage(makeHostPage(metas), testCode);
+
+    assertEquals(1, alerts.size());
+    assertEquals("baseUrl=undefined", alerts.get(0));
+  }
+
+  /**
+   * Test that all the meta tags are extracted.
+   */
+  public void testProcessMetas() throws FailingHttpStatusCodeException,
+      MalformedURLException, IOException {
+    StringBuffer metas = new StringBuffer();
+ metas.append("<meta name=\"gwt:property\" content=\"baseUrl=http://new/base\";>\n");
+    metas.append("<meta name=\"gwt:property\" content=\"novalue\">\n");
+ metas.append("<meta name=\"gwt:onPropertyErrorFn\" content=\"function() { alert('custom prop error called');}\"}>\n"); + metas.append("<meta name=\"gwt:onLoadErrorFn\" content=\"function() { alert('custom onLoad error called');}\">\n");
+
+    StringBuffer testCode = new StringBuffer();
+    testCode.append(loadProcessMetas());
+    testCode.append("alert('baseUrl='+metaProps['baseUrl']);\n");
+    testCode.append("alert('novalue='+metaProps['novalue']);\n");
+    testCode.append("alert('absent='+metaProps['absent']);\n");
+    testCode.append("propertyErrorFunc();\n");
+    testCode.append("onLoadErrorFunc();\n");
+
+    List<String> alerts = loadPage(makeHostPage(metas), testCode);
+
+    assertEquals(5, alerts.size());
+    Iterator<String> alertsIter = alerts.iterator();
+    assertEquals("baseUrl=http://new/base";, alertsIter.next());
+    assertEquals("novalue=", alertsIter.next());
+    assertEquals("absent=undefined", alertsIter.next());
+    assertEquals("custom prop error called", alertsIter.next());
+    assertEquals("custom onLoad error called", alertsIter.next());
+  }
+
+  /**
+   * Test the fully magic script base with no meta properties.
+   */
+  public void testScriptBase() throws IOException {
+    StringBuffer testCode = new StringBuffer();
+    testCode.append("var metaProps = { };\n");
+    testCode.append(loadComputeScriptBase());
+    testCode.append("alert('base='+base);\n");
+
+    List<String> alerts = loadPage(makeHostPage(""), testCode);
+
+    assertEquals(1, alerts.size());
+    assertEquals("base=http://foo.test/foo/";, alerts.get(0));
+  }
+
+  /**
+   * Test the script base logic for an inlined selection script.
+   */
+  public void testScriptBaseForInlined() throws IOException {
+    StringBuffer hostPage = new StringBuffer();
+    hostPage.append("<html><head>\n");
+    hostPage.append("<script lang=\"javascript\"><!--\n");
+    hostPage.append("var metaProps = { }\n");
+    hostPage.append(loadComputeScriptBase());
+    hostPage.append("alert('base='+base);\n");
+    hostPage.append("--></script>\n");
+
+    List<String> alerts = loadPage(hostPage.toString(), "");
+
+    assertEquals(1, alerts.size());
+    assertEquals("base=http://foo.test/";, alerts.get(0));
+  }
+
+  /**
+   * Test getting a the base URL from the HTML base tag
+   */
+  public void testScriptBaseFromBaseTag() throws IOException {
+    StringBuffer hostPage = new StringBuffer();
+    hostPage.append("<html><head>\n");
+    hostPage.append("<base href=\"http://static.test/foo/\";>\n");
+    hostPage.append("<script lang=\"javascript\"><!--\n");
+    hostPage.append("var metaProps = { }\n");
+    hostPage.append(loadComputeScriptBase());
+    hostPage.append("alert('base='+base);\n");
+    hostPage.append("--></script>\n");
+
+    List<String> alerts = loadPage(hostPage.toString(), "");
+
+    assertEquals(1, alerts.size());
+    assertEquals("base=http://static.test/foo/";, alerts.get(0));
+  }
+
+  /**
+   * Test getting the base URL from a meta property
+   */
+  public void testScriptBaseFromMetas() throws IOException {
+    StringBuffer testCode = new StringBuffer();
+ testCode.append("var metaProps = { baseUrl : \"http://static.test/foo/\"; };\n");
+    testCode.append(loadComputeScriptBase());
+    testCode.append("alert('base='+base);\n");
+
+    List<String> alerts = loadPage(makeHostPage(""), testCode);
+
+    assertEquals(1, alerts.size());
+    assertEquals("base=http://static.test/foo/";, alerts.get(0));
+  }
+
+  /**
+   * Load a page and return all alerts that it generates.
+   */
+  private List<String> loadPage(String hostPage, CharSequence testScript)
+ throws FailingHttpStatusCodeException, MalformedURLException, IOException {
+    WebClient webClient = new WebClient();
+
+ // Make a mock web connection that can return the host page and the test
+    // script
+    MockWebConnection webConnection = new MockWebConnection();
+    webConnection.setDefaultResponse(hostPage, "text/html");
+    webConnection.setResponse(new URL(
+ "http://foo.test/foo/test.Module.nocache.js";), testScript.toString(),
+        "application/javascript");
+    webClient.setWebConnection(webConnection);
+
+    final List<String> alerts = new ArrayList<String>();
+    webClient.setAlertHandler(new AlertHandler() {
+      @Override
+      public void handleAlert(Page page, String msg) {
+        alerts.add(msg);
+      }
+    });
+
+    webClient.getPage("http://foo.test/";);
+    return alerts;
+  }
+
+  private String makeHostPage(CharSequence metas) {
+    StringBuffer buf = new StringBuffer();
+    buf.append("<html><head>\n");
+    buf.append(metas);
+    buf.append("<script src=\"/foo/test.Module.nocache.js\">\n");
+    buf.append("</head></html>");
+    return buf.toString();
+  }
+}
=======================================
--- /trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/SelectionScriptLinker.java Fri Mar 12 14:12:44 2010 +++ /trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/SelectionScriptLinker.java Mon Mar 22 09:13:22 2010
@@ -64,6 +64,16 @@
    */
   protected static final String FRAGMENT_SUBDIR = "deferredjs";

+  /**
+   * File name for computeScriptBase.js.
+   */
+ static final String COMPUTE_SCRIPT_BASE_JS = "com/google/gwt/core/ext/linker/impl/computeScriptBase.js";
+
+  /**
+   * File name for processMetas.js.
+   */
+ static final String PROCESS_METAS_JS = "com/google/gwt/core/ext/linker/impl/processMetas.js";
+
   /**
    * Determines whether or not the URL is relative.
    *
@@ -256,15 +266,22 @@
       LinkerContext context, ArtifactSet artifacts)
       throws UnableToCompleteException {
     StringBuffer selectionScript;
+    String processMetas;
+    String computeScriptBase;
     try {
       selectionScript = new StringBuffer(
- Utility.getFileFromClassPath(getSelectionScriptTemplate(logger, context)));
+          Utility.getFileFromClassPath(getSelectionScriptTemplate(logger,
+              context)));
+      processMetas = Utility.getFileFromClassPath(PROCESS_METAS_JS);
+ computeScriptBase = Utility.getFileFromClassPath(COMPUTE_SCRIPT_BASE_JS);
     } catch (IOException e) {
logger.log(TreeLogger.ERROR, "Unable to read selection script template",
           e);
       throw new UnableToCompleteException();
     }

+    replaceAll(selectionScript, "__PROCESS_METAS__", processMetas);
+ replaceAll(selectionScript, "__COMPUTE_SCRIPT_BASE__", computeScriptBase);
     replaceAll(selectionScript, "__MODULE_FUNC__",
         context.getModuleFunctionName());
replaceAll(selectionScript, "__MODULE_NAME__", context.getModuleName());
@@ -418,8 +435,8 @@
   protected abstract String getModuleSuffix(TreeLogger logger,
       LinkerContext context) throws UnableToCompleteException;

- protected abstract String getSelectionScriptTemplate(TreeLogger logger, LinkerContext context)
-      throws UnableToCompleteException;
+  protected abstract String getSelectionScriptTemplate(TreeLogger logger,
+      LinkerContext context) throws UnableToCompleteException;

   /**
    * Find all instances of {...@link SelectionInformation} and add them to the
=======================================
--- /trunk/dev/core/src/com/google/gwt/core/linker/IFrameTemplate.js Tue Mar 16 08:43:23 2010 +++ /trunk/dev/core/src/com/google/gwt/core/linker/IFrameTemplate.js Mon Mar 22 09:13:22 2010
@@ -111,131 +111,8 @@
     }
   }

-  // Determine our own script's URL via magic :)
-  // This function produces one side-effect, it sets base to the module's
-  // base url.
-  //
-  function computeScriptBase() {
-    var thisScript
-    ,markerId = "__gwt_marker___MODULE_NAME__"
-    ,markerScript;
-
-    if (metaProps['baseUrl']) {
-      base = metaProps['baseUrl'];
-      return;
-    }
-
-    $doc.write('<script id="' + markerId + '"></script>');
-    markerScript = $doc.getElementById(markerId);
-
- // Our script element is assumed to be the closest previous script element - // to the marker, so start at the marker and walk backwards until we find
-    // a script.
-    thisScript = markerScript && markerScript.previousSibling;
-    while (thisScript && thisScript.tagName != 'SCRIPT') {
-      thisScript = thisScript.previousSibling;
-    }
-
-    // Gets the part of a url up to and including the 'path' portion.
-    function getDirectoryOfFile(path) {
-      // Truncate starting at the first '?' or '#', whichever comes first.
-      var hashIndex = path.lastIndexOf('#');
-      if (hashIndex == -1) {
-        hashIndex = path.length;
-      }
-      var queryIndex = path.indexOf('?');
-      if (queryIndex == -1) {
-        queryIndex = path.length;
-      }
- var slashIndex = path.lastIndexOf('/', Math.min(queryIndex, hashIndex));
-      return (slashIndex >= 0) ? path.substring(0, slashIndex + 1) : '';
-    };
-
-    if (thisScript && thisScript.src) {
-      // Compute our base url
-      base = getDirectoryOfFile(thisScript.src);
-    }
-
-    // Make the base URL absolute
-    if (base == '') {
-      // If there's a base tag, use it.
-      var baseElements = $doc.getElementsByTagName('base');
-      if (baseElements.length > 0) {
- // It's always the last parsed base tag that will apply to this script.
-        base = baseElements[baseElements.length - 1].href;
-      } else {
-        // No base tag; the base must be the same as the document location.
-        base = getDirectoryOfFile($doc.location.href);
-      }
-    } else if ((base.match(/^\w+:\/\//))) {
-      // If the URL is obviously absolute, do nothing.
-    } else {
- // Probably a relative URL; use magic to make the browser absolutify it.
-      // I wish there were a better way to do this, but this seems the only
-      // sure way!  (A side benefit is it preloads clear.cache.gif)
- // Note: this trick is harmless if the URL was really already absolute.
-      var img = $doc.createElement("img");
-      img.src = base + 'clear.cache.gif';
-      base = getDirectoryOfFile(img.src);
-    }
-
-    if (markerScript) {
-      // remove the marker element
-      markerScript.parentNode.removeChild(markerScript);
-    }
-  }
-
-  // Called to slurp up all <meta> tags:
-  // gwt:property, gwt:onPropertyErrorFn, gwt:onLoadErrorFn
-  //
-  function processMetas() {
-    var metas = document.getElementsByTagName('meta');
-    for (var i = 0, n = metas.length; i < n; ++i) {
-      var meta = metas[i], name = meta.getAttribute('name'), content;
-
-      if (name) {
-        name = name.replace('__MODULE_NAME__::', '');
-        if (name.indexOf('::') >= 0) {
-          // It's for a different module
-          continue;
-       }
-
-        if (name == 'gwt:property') {
-          content = meta.getAttribute('content');
-          if (content) {
-            var value, eq = content.indexOf('=');
-            if (eq >= 0) {
-              name = content.substring(0, eq);
-              value = content.substring(eq+1);
-            } else {
-              name = content;
-              value = '';
-            }
-            metaProps[name] = value;
-          }
-        } else if (name == 'gwt:onPropertyErrorFn') {
-          content = meta.getAttribute('content');
-          if (content) {
-            try {
-              propertyErrorFunc = eval(content);
-            } catch (e) {
-              alert('Bad handler \"' + content +
-                '\" for \"gwt:onPropertyErrorFn\"');
-            }
-          }
-        } else if (name == 'gwt:onLoadErrorFn') {
-          content = meta.getAttribute('content');
-          if (content) {
-            try {
-              onLoadErrorFunc = eval(content);
-            } catch (e) {
- alert('Bad handler \"' + content + '\" for \"gwt:onLoadErrorFn\"');
-            }
-          }
-        }
-      }
-    }
-  }
+  __COMPUTE_SCRIPT_BASE__
+  __PROCESS_METAS__

   /**
* Determines whether or not a particular property value is allowed. Called by
=======================================
--- /trunk/dev/core/src/com/google/gwt/core/linker/XSTemplate.js Tue Mar 16 08:43:23 2010 +++ /trunk/dev/core/src/com/google/gwt/core/linker/XSTemplate.js Mon Mar 22 09:13:22 2010
@@ -95,131 +95,8 @@
     }
   }

-  // Determine our own script's URL via magic :)
-  // This function produces one side-effect, it sets base to the module's
-  // base url.
-  //
-  function computeScriptBase() {
-    var thisScript
-    ,markerId = "__gwt_marker___MODULE_NAME__"
-    ,markerScript;
-
-    if (metaProps['baseUrl']) {
-      base = metaProps['baseUrl'];
-      return;
-    }
-
-    $doc.write('<script id="' + markerId + '"></script>');
-    markerScript = $doc.getElementById(markerId);
-
- // Our script element is assumed to be the closest previous script element - // to the marker, so start at the marker and walk backwards until we find
-    // a script.
-    thisScript = markerScript && markerScript.previousSibling;
-    while (thisScript && thisScript.tagName != 'SCRIPT') {
-      thisScript = thisScript.previousSibling;
-    }
-
-    // Gets the part of a url up to and including the 'path' portion.
-    function getDirectoryOfFile(path) {
-      // Truncate starting at the first '?' or '#', whichever comes first.
-      var hashIndex = path.lastIndexOf('#');
-      if (hashIndex == -1) {
-        hashIndex = path.length;
-      }
-      var queryIndex = path.indexOf('?');
-      if (queryIndex == -1) {
-        queryIndex = path.length;
-      }
- var slashIndex = path.lastIndexOf('/', Math.min(queryIndex, hashIndex));
-      return (slashIndex >= 0) ? path.substring(0, slashIndex + 1) : '';
-    };
-
-    if (thisScript && thisScript.src) {
-      // Compute our base url
-      base = getDirectoryOfFile(thisScript.src);
-    }
-
-    // Make the base URL absolute
-    if (base == '') {
-      // If there's a base tag, use it.
-      var baseElements = $doc.getElementsByTagName('base');
-      if (baseElements.length > 0) {
- // It's always the last parsed base tag that will apply to this script.
-        base = baseElements[baseElements.length - 1].href;
-      } else {
-        // No base tag; the base must be the same as the document location.
-        base = getDirectoryOfFile($doc.location.href);
-      }
-    } else if ((base.match(/^\w+:\/\//))) {
-      // If the URL is obviously absolute, do nothing.
-    } else {
- // Probably a relative URL; use magic to make the browser absolutify it.
-      // I wish there were a better way to do this, but this seems the only
-      // sure way!  (A side benefit is it preloads clear.cache.gif)
- // Note: this trick is harmless if the URL was really already absolute.
-      var img = $doc.createElement("img");
-      img.src = base + 'clear.cache.gif';
-      base = getDirectoryOfFile(img.src);
-    }
-
-    if (markerScript) {
-      // remove the marker element
-      markerScript.parentNode.removeChild(markerScript);
-    }
-  }
-
-  // Called to slurp up all <meta> tags:
-  // gwt:property, gwt:onPropertyErrorFn, gwt:onLoadErrorFn
-  //
-  function processMetas() {
-    var metas = document.getElementsByTagName('meta');
-    for (var i = 0, n = metas.length; i < n; ++i) {
-      var meta = metas[i], name = meta.getAttribute('name'), content;
-
-      if (name) {
-        name = name.replace('__MODULE_NAME__::', '');
-        if (name.indexOf('::') >= 0) {
-          // It's for a different module
-          continue;
-        }
-
-       if (name == 'gwt:property') {
-          content = meta.getAttribute('content');
-          if (content) {
-            var value, eq = content.indexOf('=');
-            if (eq >= 0) {
-              name = content.substring(0, eq);
-              value = content.substring(eq+1);
-            } else {
-              name = content;
-              value = '';
-            }
-            metaProps[name] = value;
-          }
-        } else if (name == 'gwt:onPropertyErrorFn') {
-          content = meta.getAttribute('content');
-          if (content) {
-            try {
-              propertyErrorFunc = eval(content);
-            } catch (e) {
-              alert('Bad handler \"' + content +
-                '\" for \"gwt:onPropertyErrorFn\"');
-            }
-          }
-        } else if (name == 'gwt:onLoadErrorFn') {
-          content = meta.getAttribute('content');
-          if (content) {
-            try {
-              onLoadErrorFunc = eval(content);
-            } catch (e) {
- alert('Bad handler \"' + content + '\" for \"gwt:onLoadErrorFn\"');
-            }
-          }
-        }
-      }
-    }
-  }
+  __COMPUTE_SCRIPT_BASE__
+  __PROCESS_METAS__

   /**
* Determines whether or not a particular property value is allowed. Called by
=======================================
--- /trunk/user/test/com/google/gwt/core/ext/LinkerSuite.java Thu Nov 20 14:17:44 2008 +++ /trunk/user/test/com/google/gwt/core/ext/LinkerSuite.java Mon Mar 22 09:13:22 2010
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.core.ext;

+import com.google.gwt.core.ext.linker.impl.SelectionScriptJavaScriptTest;
 import com.google.gwt.core.ext.test.IFrameLinkerTest;
 import com.google.gwt.core.ext.test.XSLinkerTest;
 import com.google.gwt.junit.tools.GWTTestSuite;
@@ -31,6 +32,7 @@

     // $JUnit-BEGIN$
     suite.addTestSuite(IFrameLinkerTest.class);
+    suite.addTestSuite(SelectionScriptJavaScriptTest.class);
     suite.addTestSuite(XSLinkerTest.class);
     /*
      *  Note: Single-script linking is disabled by default, because

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

To unsubscribe from this group, send email to 
google-web-toolkit-contributors+unsubscribegooglegroups.com or reply to this email with 
the words "REMOVE ME" as the subject.

Reply via email to