forked from jeresig/env-js
-
Notifications
You must be signed in to change notification settings - Fork 76
/
iframe.js
234 lines (187 loc) · 8.79 KB
/
iframe.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
* This file is a component of env.js,
* http://github.com/gleneivey/env-js/commits/master/README
* a Pure JavaScript Browser Environment
* Copyright 2009 John Resig, licensed under the MIT License
* http://www.opensource.org/licenses/mit-license.php
*/
module("iframe");
// In general, the tests here use the files ../html/iframe*.html
// I've tried to keep all of the id attributes and text fragments in these
// files unique from each other and from the content of index.html
// to ensure that we can correctly identify which file has loaded into
// which frame/window. When making modifications/additions, paying
// attention to uniqueness is recommended.
// all tests to next comment rely on content of ../html/iframe1.html and
// ../html/iframe1a.html
// iframe1 and iframe1a are identical in structure (so we can use the
// same assertions against both), but different in content text (so
// that we can tell which one is currently loaded). So, create an
// object (associative array) that is specific to the content of each.
contentOfIframe1 = {
url : "html/iframe1.html",
titleRE : /IFRAME/,
elementId : 'anElementWithText',
elementRE : /content of a paragraph/
};
contentOfIframe1a = {
url : "html/iframe1a.html",
titleRE : /iframe1a.html/,
elementId : 'anotherElementWithText',
elementRE : /block-quote element/
};
var accessChecksForIframe1 = function(flag, iframe, contentOf) {
expect(6);
try{ok (iframe.src == contentOf.url,
flag + ": Initial iframe src matches test page source");
}catch(e){print(e);}
var idoc = iframe.contentDocument;
var mtch = idoc.title.match(contentOf.titleRE);
try{ok (mtch && mtch.length > 0,
flag + ": Can get 'document' object from test iframe");
}catch(e){print(e);}
var para = idoc.getElementById(contentOf.elementId);
mtch = para.innerHTML.match(contentOf.elementRE);
try{ok (mtch && mtch.length > 0,
flag + ": Can get text from element in an iframe");
}catch(e){print(e);}
try{ok (idoc.parentWindow == iframe.contentWindow,
flag + ": doc's .parentWindow points to iframe's .contentWindow");
}catch(e){print(e);}
try{ok (idoc.parentWindow.parent == window,
flag + ": Can follow chain from iframe's doc to containing window");
}catch(e){print(e);}
try{ok (iframe.contentWindow.top == window,
flag + ": '.top' from iframe does point to top window");
}catch(e){print(e);}
};
test("IFRAMEs load with accessible content", function() {
var iframe = document.getElementById('loadediframe');
// iframe1.html loaded via src= attribute when index.html was parsed
accessChecksForIframe1("1", iframe, contentOfIframe1);
});
test("IFRAMEs still load when .src is set after the page is parsed",function() {
var iframe = document.getElementById('emptyiframe');
iframe.src = "html/iframe1.html";
accessChecksForIframe1("2", iframe, contentOfIframe1);
});
test("IFRAMEs reload with accessible content", function() {
var iframe = document.getElementById('loadediframe');
iframe.src = "html/iframe1a.html";
accessChecksForIframe1("3", iframe, contentOfIframe1a);
});
// this test relies on iframe3.html, iframe2.html, and iframeN.html
test("IFRAMEs can be nested, created dynamically", function() {
var startingDepth = 3;
var endingDepth = 7
expect(5 + (10*((endingDepth - startingDepth)+1)));
// manually load iframe3.html
var firstIframe = document.getElementById('emptyiframe');
firstIframe.src = "html/iframe3.html";
// iframe3.html contains a static <iframe> element that loads iframe2.html,
// so at this point, we should have both loaded, with the structure that
// index.html --contains--> iframe3.html --contains--> iframe2.html
// w/ id's = emptyiframe nested1Level
////////////////////////////////////////
// first, verify that we've got the structure we expect:
var mtch = firstIframe.contentDocument.title.match(/nested-IFRAME/);
try{ok (mtch && mtch.length > 0,
"top-level IFRAME reloaded from correct source");
}catch(e){print(e);}
var secondIframe = firstIframe.contentDocument.
getElementById('nested1Level');
mtch = secondIframe.contentDocument.title.match(/IFRAME loading/);
try{ok (mtch && mtch.length > 0,
"can access content of an IFRAME nested in another");
}catch(e){print(e);}
try{ok (secondIframe.contentDocument.parentWindow.parent.parent == window,
"can follow path from nested IFRAME to root window");
}catch(e){print(e);}
try{ok (secondIframe.contentWindow.parent.parent == window,
"also path through .contentWindow to root window");
}catch(e){print(e);}
try{ok (secondIframe.contentWindow.top == window,
"nested IFRAME has correct .top");
}catch(e){print(e);}
////////////////////////////////////////
// OK, now we'll programatically extend the nesting depth from 2 to many
window.numberNestedIframeLoads = 0;
window.winLoadCount = 0;
window.bodyLoadCount = 0;
window.frameLoadCount = 0;
for (var c = startingDepth, bottomIframe = secondIframe; c <= endingDepth;
c++){
// add a new iframe within the current leaf iframe
var newIframe = bottomIframe.contentDocument.createElement("iframe");
newIframe.setAttribute("id", "iframe_of_depth_" + c);
newIframe.setAttribute("onload", "iframeOnloadHandler();");
var bottomBody = bottomIframe.contentDocument.
getElementsByTagName('body')[0];
bottomBody.appendChild(newIframe);
newIframe.src = "html/iframeN.html";
bottomIframe = newIframe;
////////////////////////////////////////
// verify contents of just-loaded iframe
mtch = bottomIframe.contentDocument.getElementById('nestingLevel').
innerHTML.match(/[0-9]+/);
try{ok (mtch && mtch.length > 0 && parseInt(mtch[0]) == c,
"nested " + c + " levels: can access content");
}catch(e){print(e);}
for (var aWindow = bottomIframe.contentWindow, cn = c; cn > 0; cn--)
aWindow = aWindow.parent;
try{ok (aWindow == window,
"nested " + c + " levels: can follow path to root window");
}catch(e){print(e);}
try{ok (bottomIframe.contentWindow.top == window,
"nested " + c + " levels: IFRAME has correct .top");
}catch(e){print(e);}
////////////////////////////////////////
// verify events related to iframe load:
// iframe.onload (container); window.onload and body.onload (contained)
var num = (c - startingDepth) + 1;
try{ok (num == window.numberNestedIframeLoads,
"nested " + c + " levels: event <script> executed");
}catch(e){print(e);}
try{ok (num == window.winLoadCount,
"nested " + c + " levels: window-onload handler executed");
}catch(e){print(e);}
try{ok (num == window.bodyLoadCount,
"nested " + c + " levels: body-onload handler executed");
}catch(e){print(e);}
try{ok (num == window.frameLoadCount,
"nested " + c + " levels: iframe-onload handler executed");
}catch(e){print(e);}
mtch = bottomIframe.contentWindow.parent.document.
getElementById("pCreatedIframeOnload" + num).innerHTML.
match(/para iframe onload ([0-9]+)/);
try{ok (mtch && mtch.length > 0 && parseInt(mtch[1]) == num,
"nested " + c + " levels: confirmed iframe-onload");
}catch(e){print(e);}
mtch = bottomIframe.contentDocument.
getElementById("pCreatedWindowOnload" + num).innerHTML.
match(/para window onload ([0-9]+)/);
try{ok (mtch && mtch.length > 0 && parseInt(mtch[1]) == num,
"nested " + c + " levels: confirmed window-onload");
}catch(e){print(e);}
mtch = bottomIframe.contentDocument.
getElementById("pCreatedBodyOnload" + num).innerHTML.
match(/para body onload ([0-9]+)/);
try{ok (mtch && mtch.length > 0 && parseInt(mtch[1]) == num,
"nested " + c + " levels: confirmed body-onload");
}catch(e){print(e);}
}
});
// all tests to next comment rely on content of ../html/iframe2.html
test("IFRAMEs reload on assignment to 'src'", function() {
expect(2);
var iframe = document.getElementById('loadediframe');
iframe.src = "html/iframe2.html";
try{ok (iframe.src == "html/iframe2.html",
"iframe.src matches value assigned");
}catch(e){print(e);}
var para = iframe.contentDocument.getElementById('aParaInAnIframe');
var mtch = para.innerHTML.match(/short paragraph/);
try{ok (mtch && mtch.length > 0,
"IFRAME reloaded from correct source");
}catch(e){print(e);}
});