<html>
<!-- This page can create whatever iframe structure you want, across whatever
sites you want. This is useful for testing site isolation.

Example usage in a browsertest, explained:

  GURL url = embedded_test_server()->
      GetURL("a.com", "/cross_site_iframe_factory.html?a(b(c,d))");

When you navigate to the above URL, the outer document (on a.com) will create a
single iframe:

  <iframe src="http://b.com:1234/cross_site_iframe_factory.html?b(c(),d())">

Inside of which, then, are created the two leaf iframes:

  <iframe src="http://c.com:1234/cross_site_iframe_factory.html?c()">
  <iframe src="http://d.com:1234/cross_site_iframe_factory.html?d()">

Add iframe options by enclosing them in '{' and '}' characters after the
hostname (multiple options can be separated with commas):

  cross_site_iframe_factory.html?a(b{allowfullscreen}(),c{sandbox-allow-scripts}(d))

Will create two iframes:

  <iframe src="http://a.com:1234/cross_site_iframe_factory.html?b()" allowfullscreen>
  <iframe src="http://c.com:1234/cross_site_iframe_factory.html?c{sandbox-allow-scripts}(d())" sandbox="allow-scripts">

These options are supported:

  allowfullscreen
  allowpaymentrequest
  allow-{featurename} - Adds {featurename} to the "allow" attribute
  sandbox-{flagname} - Adds {flagname} to the "sandbox" attribute

To make this page work, your browsertest needs a MockHostResolver, like:

  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    ASSERT_TRUE(embedded_test_server()->Start());
  }

You can play around with the arguments by loading this page via file://, but
you probably won't get the same process behavior as if you loaded via http. -->
<head>
<title>Cross-site iframe factory</title>
<style>
body {
  font-family: "DejaVu Sans", Sans-Serif;
  text-align: center;
}
iframe {
  border-radius: 7px;
  border-style: solid;
  vertical-align: top;
  margin: 2px;
  box-shadow: 2px 2px 2px #888888;
}
</style>
</head>
<body>
<h2 id='siteNameHeading'></h2>


<script src='tree_parser_util.js'></script>
<script type='text/javascript'>

/**
 * Determines a random pastel-ish color from the first character of a string.
 */
function pastelColorForFirstCharacter(seedString, lightness) {
  // Map the first character to an index. This could be negative, we don't
  // really care.
  var index = seedString.charCodeAt(0) - 'a'.charCodeAt(0);

  // If the first character is 'a', this will the the starting color.
  var hueOfA = 200;  // Spoiler alert: it's blue.

  // Color palette generation articles suggest that spinning the hue wheel by
  // the golden ratio yields a magically nice color distribution. Something
  // about sunflower seeds. I am skeptical of the rigor of that claim (probably
  // any irrational number at a slight offset from 2/3 would do) but it does
  // look pretty.
  var phi = 2 / (1 + Math.pow(5, .5));
  var hue = Math.round((360 * index * phi + hueOfA) % 360);
  return 'hsl(' + hue + ', 60%, ' + Math.round(100 * lightness) + '%)';
}

function backgroundColorForSite(site) {
  // Light pastel.
  return pastelColorForFirstCharacter(site, .75);
}

function borderColorForSite(site) {
  // Darker color in the same hue has the background.
  return pastelColorForFirstCharacter(site, .32);
}

/**
 * Adds ".com" to an argument if it doesn't already have a top level domain.
 * This cuts down on noise in the query string, letting you use single-letter
 * names.
 */
function canonicalizeSite(siteString) {
  if (siteString.indexOf('.') == -1)
    return siteString + '.com';
  return siteString;
}

/**
 * Parses the list of iframe options and applies them to the provided element.
 */
function applyIFrameOptions(element, options) {
  var sandboxArguments = [];
  var allowFeatures = [];
  for (var option of options) {
    if (option == "allowfullscreen") {
      element.allowFullscreen = true;
    }
    if (option == "allowpaymentrequest") {
      element.allowPaymentRequest = true;
    }
    if (option.startsWith("sandbox-")) {
      sandboxArguments.push(option.slice(8));
    }
    if (option.startsWith("allow-")) {
      allowFeatures.push(option.slice(6))
    }
  }
  if (sandboxArguments.length) {
    element.sandbox = sandboxArguments.join(" ");
  }
  if (allowFeatures.length) {
    element.allow = allowFeatures.join(" ");
  }
}

/**
 * Simple recursive layout heuristic, since frames can't size themselves.
 * This scribbles .layoutX and .layoutY properties into |tree|.
 */
function layout(tree) {
  // Step 1: layout children.
  var numFrames = tree.children.length;
  for (var i = 0; i < numFrames; i++) {
    layout(tree.children[i]);
  }

  // Step 2: find largest child.
  var largestChildX = 0;
  var largestChildY = 0;
  for (var i = 0; i < numFrames; i++) {
    largestChildX = Math.max(largestChildX, tree.children[i].layoutX);
    largestChildY = Math.max(largestChildY, tree.children[i].layoutY);
  }

  // Step 3: Tweakable control parameters.
  var minX = 110;  // Should be wide enough to fit a decent sized domain.
  var minY = 110;  // Could be less, but squares look nice.
  var extraYPerLevel = 50;  // Needs to be tall enough to fit a line of text.
  var extraXPerLevel = 50;  // Could be less, but squares look nice.

  // Account for padding around each <iframe>.
  largestChildX += 30;
  largestChildY += 30;

  // Step 4: Assume a gridSizeX-by-gridSizeY layout that's big enough to fit if
  // all children were the size of the largest one.
  var gridSizeX = Math.ceil(Math.sqrt(numFrames));
  var gridSizeY = Math.round(Math.sqrt(numFrames));
  tree.layoutX = Math.max(gridSizeX * largestChildX + extraXPerLevel, minX);
  tree.layoutY = Math.max(gridSizeY * largestChildY + extraYPerLevel, minY);
}

function main() {
  var goCrossSite = !window.location.protocol.startsWith('file');
  var queryString = decodeURIComponent(window.location.search.substring(1));
  var frameTree = TreeParserUtil.parse(queryString);
  var currentSite = canonicalizeSite(frameTree.value);

  // Apply style to the current document.
  document.getElementById('siteNameHeading').appendChild(
      document.createTextNode(currentSite));
  document.body.style.backgroundColor = backgroundColorForSite(currentSite);

  // Determine how big the children should be (using a very rough heuristic).
  layout(frameTree);

  for (var i = 0; i < frameTree.children.length; i++) {
    // Compute the URL for this iframe.
    var site = canonicalizeSite(frameTree.children[i].value);
    var subtreeString = TreeParserUtil.flatten(frameTree.children[i]);
    var url = '';
    url += window.location.protocol + '//';              // scheme (preserved)
    url += goCrossSite ? site : window.location.host;    // host
    if (window.location.port)
      url += ':' + window.location.port;                 // port (preserved)
    url += window.location.pathname;                     // path (preserved)
    url += '?' + encodeURIComponent(subtreeString);      // query

    // Construct the iframe.
    var iframe = document.createElement('iframe');
    iframe.src = url;
    iframe.id = "child-" + i;
    iframe.style.borderColor = borderColorForSite(site);
    iframe.width = frameTree.children[i].layoutX;
    iframe.height = frameTree.children[i].layoutY;
    // Apply any additional attributes.
    applyIFrameOptions(iframe, frameTree.children[i].attributes);

    // Add the iframe to the document.
    document.body.appendChild(iframe);
  }
}

main();
</script>
</body></html>
