Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: content/test/data/cross_site_iframe_factory.html

Issue 1264923002: Introduce cross_site_iframe_factory.html, and use it in a test (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Self-review fixes. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <html><!--
dcheng 2015/07/30 23:35:04 Super minor nit: I feel like placing the <!-- migh
ncarter (slow) 2015/08/04 23:51:21 Done -- though check my work, since I wasn't 100%
2 This page can create whatever iframe structure you want, across whatever
3 sites you want. This is useful for testing site isolation.
4
5 Example usage in a browsertest, explained:
6
7 GURL url =
8 test_server()->GetURL("a.com", "/cross_site_iframe_factory.html?a(b(c,d))");
9
10 When you navigate to the above URL, the outer document (on a.com) will create a
11 single iframe:
12
13 <iframe src="http://b.com:1234/cross_site_iframe_factory.html?b(c(),d())">
14
15 Inside of which, then, are created the two leaf iframes:
16
17 <iframe src="http://c.com:1234/cross_site_iframe_factory.html?c()">
18 <iframe src="http://d.com:1234/cross_site_iframe_factory.html?d()">
19
20 To make this page work, your browsertest needs a MockHostResolver, like:
21
22 void SetUpOnMainThread() override {
23 host_resolver()->AddRule("*", "127.0.0.1");
24 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
25 }
26
27 You can play around with the arguments by loading this page via file://, but
28 you probably won't get the same process behavior as if you loaded via http.
29 -->
30 <head>
31 <title>Cross-site iframe factory</title>
32 <style>
33 body {
34 font-family: Sans-Serif;
35 text-align: center;
36 }
37 iframe {
38 border-radius: 7px;
dcheng 2015/07/30 23:35:04 Fancy!
ncarter (slow) 2015/08/04 23:51:21 Acknowledged.
39 border-style: solid;
40 vertical-align: top;
41 margin: 2px;
42 box-shadow: 2px 2px 2px #888888;
43 }
44 </style>
45 </head>
46 <body>
47 <h2 id='siteNameHeading'></h2>
48
49
50 <script src='tree_parser_util.js'></script>
51 <script type='text/javascript'>
52
53 /**
54 * Determines a random pastel-ish color from the first character of a string.
55 */
56 function pastelColorForFirstCharacter(seedString, lightness) {
57 // Map the first character to an index. This could be negative, we don't
58 // really care.
59 var index = seedString.charCodeAt(0) - 'a'.charCodeAt(0);
60
61 // If the first character is 'a', this will the the starting color.
62 var hueOfA = 200; // Spoiler alert: it's blue.
63
64 // Color palette generation articles suggest that spinning the hue wheel by
65 // the golden ratio yields a magically nice color distribution. Something
66 // about sunflower seeds. I am skeptical of the rigor of that claim (probably
67 // any irrational number at a slight offset from 2/3 would do) but it does
68 // look pretty.
69 var phi = 2 / (1 + Math.pow(5, .5));
70 var hue = Math.round((360 * index * phi + hueOfA) % 360);
71 return 'hsl(' + hue + ', 60%, ' + Math.round(100 * lightness) + '%)';
72 }
73
74 function backgroundColorForSite(site) {
75 // Light pastel.
76 return pastelColorForFirstCharacter(site, .75);
77 }
78
79 function borderColorForSite(site) {
80 // Darker color in the same hue has the background.
81 return pastelColorForFirstCharacter(site, .32);
82 }
83
84 /**
85 * Adds ".com" to an argument if it doesn't already have a top level domain.
86 * This cuts down on noise in the query string, letting you use single-letter
87 * names.
88 */
89 function canonicalizeSite(siteString) {
90 if (siteString.indexOf('.') == -1)
91 return siteString + '.com';
92 return siteString;
93 }
94
95 /**
96 * Simple recursive layout heuristic, since frames can't size themselves.
97 * This scribbles .layoutX and .layoutY properties into |tree|.
98 */
99 function layout(tree) {
100 // Step 1: layout children.
101 var numFrames = tree.children.length;
102 for (var i = 0; i < numFrames; i++) {
103 layout(tree.children[i]);
104 }
105
106 // Step 2: find largest child.
107 var largestChildX = 0;
108 var largestChildY = 0;
109 for (var i = 0; i < numFrames; i++) {
110 largestChildX = Math.max(largestChildX, tree.children[i].layoutX);
111 largestChildY = Math.max(largestChildY, tree.children[i].layoutY);
112 }
113
114 // Step 3: Tweakable control parameters.
115 var minX = 110; // Needs to be tall enough for
dcheng 2015/08/04 00:14:41 for what? =)
ncarter (slow) 2015/08/04 23:51:21 Done.
116 var minY = 110; // Could be less, but squares look nice.
117 var extraXPerLevel = 50; // Could be less, but squares look nice.
118 var extraYPerLevel = 50; // Needs to be tall enough for our value.
119
120 // Account for padding around each <iframe>.
121 largestChildX += 30;
122 largestChildY += 30;
123
124 // Step 4: Assume a gridSizeX-by-gridSizeY layout that's big enough to fit if
125 // all children were the size of the largest one.
126 var gridSizeX = Math.ceil(Math.sqrt(numFrames));
127 var gridSizeY = Math.round(Math.sqrt(numFrames));
128 tree.layoutX = Math.max(gridSizeX * largestChildX + extraXPerLevel, minX);
129 tree.layoutY = Math.max(gridSizeY * largestChildY + extraYPerLevel, minY);
130 }
131
132 function main() {
133 var goCrossSite = !window.location.protocol.startsWith('file');
134 var queryString = unescape(window.location.search.substring(1));
135 var frameTree = TreeParserUtil.parse(queryString);
136 var currentSite = canonicalizeSite(frameTree.value);
137
138 // Apply style to the current document.
139 document.getElementById('siteNameHeading').appendChild(
140 document.createTextNode(currentSite));
141 document.body.style.backgroundColor = backgroundColorForSite(currentSite);
142
143 // Determine how big the children should be (using a very rough heuristic).
144 layout(frameTree);
145
146 for (var i = 0; i < frameTree.children.length; i++) {
147 // Compute the URL for this iframe .
148 var site = canonicalizeSite(frameTree.children[i].value);
149 var subtreeString = TreeParserUtil.flatten(frameTree.children[i]);
150 var url = '';
151 url += window.location.protocol + '//'; // scheme (preserved)
152 url += goCrossSite ? site : window.location.host; // host
153 if (window.location.port)
154 url += ':' + window.location.port; // port (preserved)
155 url += window.location.pathname; // path (preserved)
156 url += '?' + escape(subtreeString); // query
dcheng 2015/08/04 00:14:41 escape => encodeURIComponent
ncarter (slow) 2015/08/04 23:51:21 Done.
157
158 // Add the iframe to the document.
159 var iframe = document.createElement('iframe');
160 iframe.src = url;
161 iframe.style.borderColor = borderColorForSite(site);
162 iframe.scrolling = 'no';
dcheng 2015/08/04 00:14:41 Is this necessary given the layout() call? It migh
ncarter (slow) 2015/08/04 23:51:21 Good call. I added this early on, before the layou
163 iframe.width = frameTree.children[i].layoutX;
164 iframe.height = frameTree.children[i].layoutY;
165 document.body.appendChild(iframe);
166 }
167 }
168
169 main();
170 </script>
171 </body></html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698