<html><head>
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="-1" />
<link rel="stylesheet" href="test_page.css">
<script>
// Do a deep comparison of two values. Return true if their values are
// identical, false otherwise.
function deepCompare(left, right) {
  if (typeof(left) !== typeof(right))
    return false;
  // If their identity is the same or they're basic types with the same value,
  // they are equal.
  if (left === right)
    return true;
  // If it's a basic type and we got here, we know they're not equal.
  if (["undefined", "boolean", "number", "string", "function"].indexOf(
          typeof(left)) > -1) {
    return false;
  }
  // Use right_keys as a set containing all keys from |right| which we haven't
  // yet compared.
  var right_keys = {};
  for (var key in right)
    right_keys[key] = true;
  for (var key in left) {
    if (key in right_keys) {
       if (!deepCompare(left[key], right[key]))
        return false;
    } else {
      // |left| had a key that |right| didn't.
      return false;
    }
    delete right_keys[key];
  }
  // If there are keys left in |right_keys|, it means they didn't exist in
  // |left|, so the objects aren't equal.
  if (Object.keys(right_keys).length > 0)
    return false;
  return true;
}

function AdjustHeight(frameWin) {
  var div = frameWin.document.getElementsByTagName("div")[0];
  var height = frameWin.getComputedStyle(div).height;
  frameWin.frameElement.style.height = height;
}

// Called when the tests are completed. |result| should be "PASS" if the test(s)
// passed, or information about the failure if the test(s) did not pass.
function DidExecuteTests(result) {
  var plugin = document.getElementById("plugin");
  if (plugin.parentNode.removePlugin) {
    plugin.parentNode.removeChild(plugin);
    plugin = undefined;
  }
  if (CheckPostConditions())
    sendAutomationMessage(result);

  if (window == top)
    return;

  // Otherwise, we are in a subframe, so we can use this opportunity to resize
  // ourselves.
  AdjustHeight(window);
}

function AppendFrame(testcase, i) {
  var p = document.createElement("P");
  p.setAttribute("class", "frame-container");

  var title = document.createElement("H2");
  title.appendChild(document.createTextNode(testcase));
  p.appendChild(title);

  var frame = document.createElement("IFRAME");
  var mode = ExtractSearchParameter("mode");
  var websocket_host = ExtractSearchParameter("websocket_host");
  var websocket_port = ExtractSearchParameter("websocket_port");
  var ssl_server_port = ExtractSearchParameter("ssl_server_port");
  var src = "?testcase=" + testcase;
  if (mode == "nacl")
    src += "&mode=nacl";
  if (websocket_host != "")
    src += "&websocket_host=" + websocket_host;
  if (websocket_port != "")
    src += "&websocket_port=" + websocket_port;
  if (ssl_server_port != "")
    src += "&ssl_server_port=" + ssl_server_port;
  frame.setAttribute("src", src);

  frame.setAttribute("onload", "LoadNext(" + (i + 1) + ")");
  p.appendChild(frame);

  document.body.appendChild(p);
}

function LoadNext(i) {
  var links = document.links;
  if (links.length > i)
    AppendFrame(links[i].firstChild.nodeValue, i);
}

function RunAll() {
  // Remove any existing frames.
  var existing = document.getElementsByClassName("frame-container");
  while (existing.length)
    existing[0].parentNode.removeChild(existing[0]);

  // Add new frames for each test, but do so one frame at a time.
  LoadNext(0);
}

function ExtractSearchParameter(name) {
  var nameIndex = location.search.indexOf(name + "=");
  if (nameIndex != -1) {
    var value = location.search.substring(nameIndex + name.length + 1);
    var endIndex = value.indexOf("&");
    if (endIndex != -1)
      value = value.substring(0, endIndex);
    return value;
  }
  return "";
}

// Parses the message, looking for strings of the form:
// TESTING_MESSAGE:<message_type>:<message_contents>
//
// If the message_data is not a string or does not match the above format, then
// undefined is returned.
//
// Otherwise, returns an array containing 2 items. The 0th element is the
// message_type, one of:
//  - AddPostCondition
//  - ClearConsole
//  - DidExecuteTests
//  - EvalScript
//  - LogHTML
//  - RemovePluginWhenFinished
//  - ReportProgress
// The second item is the verbatim message_contents.
function ParseTestingMessage(message_data) {
  if (typeof(message_data) != "string")
    return undefined;
  var testing_message_prefix = "TESTING_MESSAGE";
  var delim_str = ":";
  var delim1 = message_data.indexOf(delim_str);
  if (message_data.substring(0, delim1) !== testing_message_prefix)
    return undefined;
  var delim2 = message_data.indexOf(delim_str, delim1 + 1);
  if (delim2 == -1)
    delim2 = message_data.length;
  var message_type = message_data.substring(delim1 + 1, delim2);
  var message_contents = message_data.substring(delim2 + 1);
  return [message_type, message_contents];
}

function ClearConsole() {
  window.document.getElementById("console").innerHTML = "";
}

function LogHTML(html) {
  window.document.getElementById("console").innerHTML += html;
}

function RemovePluginWhenFinished() {
  window.document.getElementById("container").removePlugin = true;
}

function sendAutomationMessage(msg) {
  if (window.domAutomationController) {
    window.domAutomationController.setAutomationId(0);
    window.domAutomationController.send(msg);
  }
}

function LogTestTime(test_time) {
  console.log(test_time);
}

// If something goes really wrong, the test running inside the plugin may not
// terminate.  For example, if the plugin does not load, the test will never
// send "PASS" to the browser.  In this case we should explicitly use the
// automation controller to terminate the test.
function InternalError(msg) {
  LogHTML("<p>" + msg);
  sendAutomationMessage(msg);
}

function EvalScript(script) {
  try {
    eval(script);
  } catch(ex) {
  }
}

var conditions = [];
// Add a "PostCondition". These are bits of script that are run after the plugin
// is destroyed. If they evaluate to false or throw an exception, it's
// considered a failure.
function AddPostCondition(script) {
  conditions.push(script);
}
// Update the HTML to show the failure and update cookies so that ui_tests
// doesn't count this as a pass.
function ConditionFailed(error) {
  error_string = "Post condition check failed: " + error;
  InternalError(error_string);
}
// Iterate through the post conditions defined in |conditions| and check that
// they all pass.
function CheckPostConditions() {
  var success = true;
  for (var i = 0; i < conditions.length; ++i) {
    var script = conditions[i];
    try {
      if (!eval(script)) {
        ConditionFailed("\"" + script + "\"");
        success = false;
      }
    } catch (ex) {
      ConditionFailed("\"" + script + "\"" + " failed with exception: " +
                      "\"" + ex.toString() + "\"");
      success = false;
    }
  }
  return success;
}

function IsTestingMessage(message_data) {
  return (ParseTestingMessage(message_data) != undefined);
}

function handleTestingMessage(message_event) {
  var type_contents_tuple = ParseTestingMessage(message_event.data);
  if (type_contents_tuple) {
    var type = type_contents_tuple[0];
    var contents = type_contents_tuple[1];
    if (type === "AddPostCondition")
      AddPostCondition(contents);
    else if (type === "ClearConsole")
      ClearConsole();
    else if (type === "DidExecuteTests")
      DidExecuteTests(contents);
    else if (type === "EvalScript")
      EvalScript(contents);
    else if (type === "LogHTML")
      LogHTML(contents);
    else if (type === "RemovePluginWhenFinished")
      RemovePluginWhenFinished();
    else if (type === "ReportProgress")
      sendAutomationMessage(contents);
    else if (type === "LogTestTime")
      LogTestTime(contents);
  }
}

function sendProgress() {
  // We send "..." to signal that we're still working. See
  // ppapi/tests/testing_instance.h for how this works.
  sendAutomationMessage("...");
}

onload = function() {
  var testcase = ExtractSearchParameter("testcase");
  var mode = ExtractSearchParameter("mode");
  document.title = 'Test ' + testcase;
  var obj;
  if (mode == "nacl_newlib") {
    obj = document.createElement("EMBED");
    obj.setAttribute("src", "ppapi_nacl_tests_newlib.nmf");
    obj.setAttribute("type", "application/x-nacl");
    obj.setAttribute("mode", mode);
  } else if (mode == "nacl_glibc") {
    obj = document.createElement("EMBED");
    obj.setAttribute("src", "ppapi_nacl_tests_glibc.nmf");
    obj.setAttribute("type", "application/x-nacl");
    obj.setAttribute("mode", mode);
  } else if (mode == "nacl_pnacl") {
    obj = document.createElement("EMBED");
    obj.setAttribute("src", "ppapi_nacl_tests_pnacl.nmf");
    obj.setAttribute("type", "application/x-nacl");
    obj.setAttribute("mode", mode);
  } else if (mode == "nacl_pnacl_nonsfi") {
    obj = document.createElement("EMBED");
    obj.setAttribute("src", "ppapi_nacl_tests_pnacl_nonsfi.nmf");
    obj.setAttribute("type", "application/x-nacl");
    obj.setAttribute("mode", mode);
  } else {
    var mimeType = "application/x-ppapi-tests";
    if (mimeType in navigator.mimeTypes) {
      obj = document.createElement("EMBED");
      obj.setAttribute("src", "http://a.b.c/test");
      obj.setAttribute("type", mimeType);
    } else {
      document.getElementById("console").innerHTML =
          '<span class="fail">FAIL</span>: ' +
          '<span class="err_msg">Test plug-in is not registered.</span>';
    }
  }
  if (obj) {
    obj.setAttribute("width", 80);
    obj.setAttribute("height", 80);
    obj.setAttribute("style",
                     "background-color:#AAAAAA;border:1px solid black;");
    obj.setAttribute("id", "plugin");
    obj.setAttribute("testcase", testcase);
    obj.setAttribute("protocol", window.location.protocol);
    var websocket_host = ExtractSearchParameter("websocket_host");
    if (websocket_host != "")
      obj.setAttribute("websocket_host", websocket_host);
    var websocket_port = ExtractSearchParameter("websocket_port");
    if (websocket_port != "")
      obj.setAttribute("websocket_port", websocket_port);
    var ssl_server_port = ExtractSearchParameter("ssl_server_port");
    if (ssl_server_port != "")
      obj.setAttribute("ssl_server_port", ssl_server_port);

    var container = document.getElementById("container");
    container.addEventListener("message", handleTestingMessage, true);

    // "error" and "crash" events will only fire for NaCl, but adding these
    // listeners doesn't hurt in the non-NaCl cases.
    obj.addEventListener("error", function() {
      InternalError("Plugin did not load. '" + obj.lastError + "'");
    }, true);
    obj.addEventListener("crash", function() {
      InternalError("Plugin crashed. '" + obj.lastError + "'");
    }, true);

    // NaCl sends progress events while loading. When we get one, notify the
    // domAutomationController so that it knows we're still working.
    obj.addEventListener("loadstart", sendProgress, true);
    obj.addEventListener("progress", sendProgress, true);
    obj.addEventListener("load", sendProgress, true);
    obj.addEventListener("loadend", sendProgress, true);

    // Register a bad dispatchEvent to make sure it isn't used. See 'EVIL' note
    // below.
    var original = obj.dispatchEvent;
    obj.dispatchEvent = function() {
      InternalError("Bad dispatchEvent called!");
    }
    container.appendChild(obj);
  }
}

// EVIL Note:
// This part of the script does some nefarious things to make sure that it
// doesn't affect the behavior of PostMessage (on which all the tests rely). In
// particular, we replace document.createEvent, MessageEvent.initMessageEvent,
// and the MessageEvent constructor. Previously, the NaCl integration
// implementation made use of these and would fail (http://crbug.com/82604
// and http://crbug.com/109775).
document.createEvent = function() {
  InternalError("Bad document.createEvent called!");
}
function MessageEvent() {
  InternalError("Bad MessageEvent constructor called!");
}
MessageEvent.prototype.initMessageEvent = function() {
  InternalError("Bad MessageEvent.initMessageEvent called!");
}

</script>
</head><body>
<div>
  <div id="container"></div>
  <div id="console"><span class="load_msg">loading...</span></div>
</div>
</body></html>
