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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
<!DOCTYPE html [
<!ATTLIST foo:base
id ID #IMPLIED
>
]>
<html xmlns:foo="http://foo.com" xmlns="http://www.w3.org/1999/xhtml">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=209275
-->
<head>
<title>Test for Bug 209275</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<style>
@namespace svg url("http://www.w3.org/2000/svg");
svg|a { fill:blue; }
svg|a:visited { fill:purple; }
</style>
<!--
base0 should be ignored because it's not in the XHTML namespace
-->
<foo:base id="base0" href="http://www.foo.com" />
<!--
baseEmpty should be ignored because it has no href and never gets one.
-->
<base id="baseEmpty" />
<!--
baseWrongAttrNS should be ignored because its href attribute isn't in the empty
namespace.
-->
<base id="baseWrongAttrNS" foo:href="http://foo.com" />
<base id="base1" />
<base id="base2" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=209275">Mozilla Bug 209275</a>
<p id="display">
</p>
<div id="content">
<a href="/" id="link1">link1</a>
<div style="display:none">
<a href="/" id="link2">link2</a>
</div>
<a href="/" id="link3" style="display:none">link3</a>
<a href="#" id="link4">link4</a>
<a href="" id="colorlink">colorlink</a>
<a href="#" id="link5">link5</a>
<iframe id="iframe"></iframe>
<svg width="5cm" height="3cm" viewBox="0 0 5 3" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<a xlink:href="" id="ellipselink">
<ellipse cx="2.5" cy="1.5" rx="2" ry="1" id="ellipse" />
</a>
</svg>
</div>
<pre id="test">
<script type="text/javascript;version=1.7">
<![CDATA[
/** Test for Bug 209275 **/
SimpleTest.waitForExplicitFinish();
function link123HrefIs(href, testNum) {
is($('link1').href, href, "link1 test " + testNum);
is($('link2').href, href, "link2 test " + testNum);
is($('link3').href, href, "link3 test " + testNum);
}
var gGen;
function visitedDependentComputedStyle(win, elem, property) {
var utils = SpecialPowers.getDOMWindowUtils(window);
return utils.getVisitedDependentComputedStyle(elem, "", property);
}
function getColor(elem) {
return visitedDependentComputedStyle(document.defaultView, elem, "color");
}
function getFill(elem) {
return visitedDependentComputedStyle(document.defaultView, elem, "fill");
}
function setXlinkHref(elem, href) {
elem.setAttributeNS("http://www.w3.org/1999/xlink", "href", href);
}
function continueTest() {
gGen.next();
}
var iframe = document.getElementById("iframe");
var iframeCw = iframe.contentWindow;
function run() {
var iframe = document.getElementById("iframe");
var iframeCw = iframe.contentWindow;
// First, set the visited/unvisited link/ellipse colors.
const unvisitedColor = "rgb(0, 0, 238)";
const visitedColor = "rgb(85, 26, 139)";
const unvisitedFill = "rgb(0, 0, 255)";
const visitedFill = "rgb(128, 0, 128)";
const rand = Date.now() + "-" + Math.random();
// Now we can start the tests in earnest.
var loc = location;
// everything from the location up to and including the final forward slash
var path = /(.*\/)[^\/]*/.exec(location)[1];
// Set colorlink's href so we can check that it changes colors after we
// change the base href.
$('colorlink').href = "http://example.com/" + rand;
setXlinkHref($("ellipselink"), "http://example.com/" + rand);
// Load http://example.com/${rand} into an iframe so we can test that changing
// the document's base changes the visitedness of our links.
iframe.onload = continueTest;
iframeCw.location = "http://example.com/" + rand;
yield undefined; // wait for onload to fire.
// Make sure things are what as we expect them at the beginning.
link123HrefIs("http://mochi.test:8888/", 1);
is($('link4').href, loc + "#", "link 4 test 1");
is($('link5').href, loc + "#", "link 5 test 1");
// Remove link5 from the document. We're going to test that its href changes
// properly when we change our base.
var link5 = $('link5');
link5.parentNode.removeChild(link5);
$('base1').href = "http://example.com";
// Were the links' hrefs updated after the base change?
link123HrefIs("http://example.com/", 2);
is($('link4').href, "http://example.com/#", "link 4 test 2");
is(link5.href, "http://example.com/#", "link 5 test 2");
// Were colorlink's color and ellipse's fill updated appropriately?
// Because link coloring is asynchronous, we wait until it is updated (or we
// timeout and fail anyway).
while (getColor($('colorlink')) != visitedColor) {
setTimeout(continueTest, 0);
yield undefined;
}
is(getColor($('colorlink')), visitedColor,
"Wrong link color after base change.");
while (getFill($('ellipselink')) != visitedFill) {
setTimeout(continueTest, 0);
yield undefined;
}
is(getFill($('ellipselink')), visitedFill,
"Wrong ellipse fill after base change.");
$('base1').href = "foo/";
// Should be interpreted relative to current URI (not the current base), so
// base should now be http://mochi.test:8888/foo/
link123HrefIs("http://mochi.test:8888/", 3);
is($('link4').href, path + "foo/#", "link 4 test 3");
// Changing base2 shouldn't affect anything, because it's not the first base
// tag.
$('base2').href = "http://example.org/bar/";
link123HrefIs("http://mochi.test:8888/", 4);
is($('link4').href, path + "foo/#", "link 4 test 4");
// If we unset base1's href attribute, the document's base should come from
// base2, whose href is http://example.org/bar/.
$('base1').removeAttribute("href");
link123HrefIs("http://example.org/", 5);
is($('link4').href, "http://example.org/bar/#", "link 4 test 5");
// If we remove base1, base2 should become the first base tag, and the hrefs
// of all the links should change accordingly.
$('base1').parentNode.removeChild($('base1'));
link123HrefIs("http://example.org/", 6);
is($('link4').href, "http://example.org/bar/#", "link 4 test 6");
// If we add a new base after base2, nothing should change.
var base3 = document.createElement("base");
base3.href = "http://base3.example.org/";
$('base2').parentNode.insertBefore(base3, $('base2').nextSibling);
link123HrefIs("http://example.org/", 7);
is($('link4').href, "http://example.org/bar/#", "link 4 test 7");
// But now if we add a new base before base 2, it should become the primary
// base.
var base4 = document.createElement("base");
base4.href = "http://base4.example.org/";
$('base2').parentNode.insertBefore(base4, $('base2'));
link123HrefIs("http://base4.example.org/", 8);
is($('link4').href, "http://base4.example.org/#", "link 4 test 8");
// Now if we remove all the base tags, the base should become the page's URI
// again.
$('base2').parentNode.removeChild($('base2'));
base3.parentNode.removeChild(base3);
base4.parentNode.removeChild(base4);
link123HrefIs("http://mochi.test:8888/", 9);
is($('link4').href, loc + "#", "link 4 test 9");
// Setting the href of base0 shouldn't do anything because it's not in the
// XHTML namespace.
$('base0').href = "http://bar.com";
link123HrefIs("http://mochi.test:8888/", 10);
is($('link4').href, loc + "#", "link 4 test 10");
// We load into an iframe a document with a <base href="...">, then remove
// the document element. Then we add an <html>, <body>, and <a>, and make
// sure that the <a> is resolved relative to the page's location, not its
// original base. We do this twice, rebuilding the document in a different
// way each time.
iframe.onload = null;
iframeCw.location = "file_bug209275_1.html";
yield undefined; // wait for our child to call us back.
is(iframeCw.document.getElementById("link").href,
path + "file_bug209275_1.html#",
"Wrong href after nuking document.");
iframeCw.location = "file_bug209275_2.html";
yield undefined; // wait for callback from child
is(iframeCw.document.getElementById("link").href,
"http://mochi.test:8888/",
"Wrong href after nuking document second time.");
// Make sure that document.open() makes the document forget about any <base>
// tags it has.
iframeCw.location = "file_bug209275_3.html";
yield undefined; // wait for callback from child
is(iframeCw.document.getElementById("link").href,
"http://mochi.test:8888/",
"Wrong href after document.open().");
SimpleTest.finish();
yield undefined;
}
window.addEventListener("load", function() {
gGen = run();
gGen.next();
}, false);
]]>
</script>
</pre>
</body>
</html>
|