<!-- Copyright 2012 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   -->
<!-- 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. License for the specific language governing permissions and   -->
<!-- limitations under the License.                                         -->

<html>
<head>
  <title>Loading...</title>

  <script>
    function updatePage(config) {
      var title = config.moduleName + " (GWT Code Server)";
      document.title = title;
      setTextContent(document.getElementById("title"), title);

      if (config.isCompiled) {
          clearClassName(".show-if-compiled");
          document.getElementById("logLink")
                  .setAttribute("href", "../log/" + config.moduleName);
          document.getElementById("srcLink")
                  .setAttribute("href", "../sourcemaps/" + config.moduleName + "/");
      } else {
          clearClassName(".show-if-not-compiled");
      }

      updateFileList(config, document.getElementById("files"));
    }

    function clearClassName(query) {
        var elts = document.querySelectorAll(query);
        for (var i = 0; i < elts.length; i++) {
            elts[i].className = "";
        }
    }

    function updateFileList(config, resultElement) {
      for (var i = 0; i < config.files.length; i++) {
        var file = config.files[i];

        var anchor = document.createElement("a");
        anchor.setAttribute("href", file.link);
        setTextContent(anchor, file.name);

        var listItem = document.createElement("li");
        listItem.appendChild(anchor);
        resultElement.appendChild(listItem);
      }
    }

    function setTextContent(element, text) {
      if (typeof element.textContent === 'string') {
        element.textContent = text;
      } else {
        // Use innerText when textContent is not supported (e.g. IE8).
        element.innerText = text;
      }
    }

    function onPageLoad() {
      updatePage(config);
    }

    if (window.addEventListener) {
      window.addEventListener("load", onPageLoad, false);
    }
    else if (window.attachEvent) {
      window.attachEvent("onload", onPageLoad);
    }
  </script>

  <style type="text/css">
    .show-if-compiled, .show-if-not-compiled {
        display: none;
    }
  </style>
</head>
<body>
<h1 id="title">Loading...</h1>

<div class="show-if-not-compiled">
<p>This module hasn't been compiled yet.</p>
</div>

<div class="show-if-compiled">
<p><a id="logLink">Messages</a> from the last time this module was compiled.</p>
<p><a id="srcLink">Source</a> from the last time this module was compiled.</p>
</div>

<h2>Output Files</h2>
<p>(From the last successful compile.)</p>
<ul id="files">
</ul>

</body>
</html>
