mirror of
https://github.com/servo/servo.git
synced 2025-08-15 02:15:33 +01:00
Update web-platform-tests to revision 314de955a5102650136404f6439f22f8d838e0f4
This commit is contained in:
parent
521748c01e
commit
6b4094e2a4
133 changed files with 1609 additions and 628 deletions
|
@ -49,10 +49,10 @@ def main(request, response):
|
|||
|
||||
# The only-if-cached redirect tests wants CORS to be okay, the other tests
|
||||
# are all same-origin anyways and don't care.
|
||||
response.headers.set("Access-Control-Allow-Origin", "*");
|
||||
response.headers.set("Access-Control-Allow-Origin", "*")
|
||||
|
||||
if redirect:
|
||||
response.headers.set("Location", redirect);
|
||||
response.headers.set("Location", redirect)
|
||||
response.status = (302, "Redirect")
|
||||
return ""
|
||||
elif ((inm is not None and inm == tag) or
|
||||
|
|
|
@ -12,4 +12,3 @@ def main(request, response):
|
|||
return ((401, "Unauthorized"),
|
||||
[("WWW-Authenticate", 'Basic realm="' + realm + '"')],
|
||||
"Please login with credentials 'user' and 'password'")
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ def main(request, response):
|
|||
time.sleep(delay)
|
||||
response.headers.set("Transfer-Encoding", "chunked")
|
||||
response.write_status_headers()
|
||||
time.sleep(delay);
|
||||
time.sleep(delay)
|
||||
for i in xrange(count):
|
||||
response.writer.write_content("a\r\nTEST_CHUNK\r\n")
|
||||
time.sleep(delay)
|
||||
|
|
|
@ -4,8 +4,8 @@ def main(request, response):
|
|||
if "headers" in request.GET:
|
||||
checked_headers = request.GET.first("headers").split("|")
|
||||
for header in checked_headers:
|
||||
if header in request.headers:
|
||||
headers.append(("x-request-" + header, request.headers.get(header, "") ))
|
||||
if header in request.headers:
|
||||
headers.append(("x-request-" + header, request.headers.get(header, "")))
|
||||
|
||||
if "cors" in request.GET:
|
||||
if "Origin" in request.headers:
|
||||
|
|
|
@ -59,12 +59,12 @@ def main(request, response):
|
|||
headers.append(("Access-Control-Expose-Headers", "x-did-preflight, x-control-request-headers, x-referrer, x-preflight-referrer, x-origin"))
|
||||
headers.append(("x-did-preflight", stashed_data['preflight']))
|
||||
if stashed_data['control_request_headers'] != None:
|
||||
headers.append(("x-control-request-headers", stashed_data['control_request_headers']))
|
||||
headers.append(("x-control-request-headers", stashed_data['control_request_headers']))
|
||||
headers.append(("x-preflight-referrer", stashed_data['preflight_referrer']))
|
||||
headers.append(("x-referrer", request.headers.get("Referer", "") ))
|
||||
headers.append(("x-origin", request.headers.get("Origin", "") ))
|
||||
headers.append(("x-referrer", request.headers.get("Referer", "")))
|
||||
headers.append(("x-origin", request.headers.get("Origin", "")))
|
||||
|
||||
if token:
|
||||
request.server.stash.put(token, stashed_data)
|
||||
request.server.stash.put(token, stashed_data)
|
||||
|
||||
return headers, ""
|
||||
|
|
|
@ -28,7 +28,7 @@ def main(request, response):
|
|||
#Preflight is not redirected: return 200
|
||||
if not "redirect_preflight" in request.GET:
|
||||
if token:
|
||||
request.server.stash.put(request.GET.first("token"), stashed_data)
|
||||
request.server.stash.put(request.GET.first("token"), stashed_data)
|
||||
return 200, headers, ""
|
||||
|
||||
if "redirect_status" in request.GET:
|
||||
|
@ -59,7 +59,7 @@ def main(request, response):
|
|||
if token:
|
||||
request.server.stash.put(request.GET.first("token"), stashed_data)
|
||||
if "max_count" in request.GET:
|
||||
max_count = int(request.GET['max_count'])
|
||||
max_count = int(request.GET['max_count'])
|
||||
#stop redirecting and return count
|
||||
if stashed_data['count'] > max_count:
|
||||
# -1 because the last is not a redirection
|
||||
|
|
|
@ -8,7 +8,7 @@ def main(request, response):
|
|||
time.sleep(delay)
|
||||
response.headers.set("Content-type", "text/plain")
|
||||
response.write_status_headers()
|
||||
time.sleep(delay);
|
||||
time.sleep(delay)
|
||||
for i in xrange(count):
|
||||
response.writer.write_content("TEST_TRICKLE\n")
|
||||
time.sleep(delay)
|
||||
|
|
|
@ -30,7 +30,7 @@ def main(request, response):
|
|||
noted_headers[header[0].lower()] = header[1]
|
||||
|
||||
if "access-control-allow-origin" not in noted_headers:
|
||||
response.headers.set("Access-Control-Allow-Origin", "*");
|
||||
response.headers.set("Access-Control-Allow-Origin", "*")
|
||||
if "content-type" not in noted_headers:
|
||||
response.headers.set("Content-Type", "text/plain")
|
||||
response.headers.set("Server-Request-Count", len(server_state))
|
||||
|
|
|
@ -6,18 +6,18 @@ def main(request, response):
|
|||
|
||||
response.add_required_headers = False
|
||||
if is_revalidation is not None:
|
||||
response.writer.write_status(304)
|
||||
response.writer.write_header("x-content-type-options", "nosniff")
|
||||
response.writer.write_header("content-length", 0)
|
||||
if(type != None):
|
||||
response.writer.write_header("content-type", type)
|
||||
response.writer.end_headers()
|
||||
response.writer.write("")
|
||||
response.writer.write_status(304)
|
||||
response.writer.write_header("x-content-type-options", "nosniff")
|
||||
response.writer.write_header("content-length", 0)
|
||||
if(type != None):
|
||||
response.writer.write_header("content-type", type)
|
||||
response.writer.end_headers()
|
||||
response.writer.write("")
|
||||
else:
|
||||
response.writer.write_status(200)
|
||||
response.writer.write_header("x-content-type-options", "nosniff")
|
||||
response.writer.write_header("content-length", len(content))
|
||||
if(type != None):
|
||||
response.writer.write_header("content-type", type)
|
||||
response.writer.end_headers()
|
||||
response.writer.write(content)
|
||||
response.writer.write_status(200)
|
||||
response.writer.write_header("x-content-type-options", "nosniff")
|
||||
response.writer.write_header("content-length", len(content))
|
||||
if(type != None):
|
||||
response.writer.write_header("content-type", type)
|
||||
response.writer.end_headers()
|
||||
response.writer.write(content)
|
||||
|
|
|
@ -4,9 +4,9 @@ def main(request, response):
|
|||
type = request.GET.first("type", None)
|
||||
|
||||
if type != None and "svg" in type:
|
||||
filename = "green-96x96.svg"
|
||||
filename = "green-96x96.svg"
|
||||
else:
|
||||
filename = "blue96x96.png"
|
||||
filename = "blue96x96.png"
|
||||
|
||||
path = os.path.join(os.path.dirname(__file__), "../../../images", filename)
|
||||
body = open(path, "rb").read()
|
||||
|
@ -16,7 +16,7 @@ def main(request, response):
|
|||
response.writer.write_header("x-content-type-options", "nosniff")
|
||||
response.writer.write_header("content-length", len(body))
|
||||
if(type != None):
|
||||
response.writer.write_header("content-type", type)
|
||||
response.writer.write_header("content-type", type)
|
||||
response.writer.end_headers()
|
||||
|
||||
response.writer.write(body)
|
||||
|
|
|
@ -11,7 +11,7 @@ def main(request, response):
|
|||
response.writer.write_header("x-content-type-options", "nosniff")
|
||||
response.writer.write_header("content-length", len(content))
|
||||
if(type != "Content-Type missing"):
|
||||
response.writer.write_header("content-type", type)
|
||||
response.writer.write_header("content-type", type)
|
||||
response.writer.end_headers()
|
||||
|
||||
response.writer.write(content)
|
||||
|
|
|
@ -10,7 +10,7 @@ def main(request, response):
|
|||
response.writer.write_header("x-content-type-options", "nosniff")
|
||||
response.writer.write_header("content-length", len(content))
|
||||
if(type != None):
|
||||
response.writer.write_header("content-type", type)
|
||||
response.writer.write_header("content-type", type)
|
||||
response.writer.end_headers()
|
||||
|
||||
response.writer.write(content)
|
||||
|
|
11
tests/wpt/web-platform-tests/fetch/sec-metadata/README.md
Normal file
11
tests/wpt/web-platform-tests/fetch/sec-metadata/README.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
`Sec-Metadata` Tests
|
||||
====================
|
||||
|
||||
This directory contains tests related to the `Sec-Metadata` proposal:
|
||||
|
||||
: Explainer
|
||||
:: <https://github.com/mikewest/sec-metadata>
|
||||
: "Spec"
|
||||
:: <https://mikewest.github.io/sec-metadata/>
|
||||
|
||||
Note: All of this is tentative, and will change (rapidly).
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<script>
|
||||
promise_test(t => {
|
||||
return fetch("https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/echo-as-json.py")
|
||||
.then(r => r.json())
|
||||
.then(j => {
|
||||
assert_header_equals(j.header, {
|
||||
"cause": "forced",
|
||||
"destination": "\"\"",
|
||||
"target": "subresource",
|
||||
"site": "same-origin"
|
||||
});
|
||||
});
|
||||
}, "Same-origin fetch");
|
||||
|
||||
promise_test(t => {
|
||||
return fetch("https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/echo-as-json.py")
|
||||
.then(r => r.json())
|
||||
.then(j => {
|
||||
assert_header_equals(j.header, {
|
||||
"cause": "forced",
|
||||
"destination": "\"\"",
|
||||
"target": "subresource",
|
||||
"site": "same-site"
|
||||
});
|
||||
});
|
||||
}, "Same-site fetch");
|
||||
|
||||
promise_test(t => {
|
||||
return fetch("https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/echo-as-json.py")
|
||||
.then(r => r.json())
|
||||
.then(j => {
|
||||
assert_header_equals(j.header, {
|
||||
"cause": "forced",
|
||||
"destination": "\"\"",
|
||||
"target": "subresource",
|
||||
"site": "cross-site"
|
||||
});
|
||||
});
|
||||
}, "Cross-site fetch");
|
||||
</script>
|
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE html>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
<script>
|
||||
async_test(t => {
|
||||
let i = document.createElement('iframe');
|
||||
i.src = "https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/post-to-owner.py";
|
||||
window.addEventListener('message', t.step_func(e => {
|
||||
if (e.source != i.contentWindow)
|
||||
return;
|
||||
|
||||
assert_header_equals(e.data, {
|
||||
"cause": "forced",
|
||||
"destination": "document",
|
||||
"target": "nested",
|
||||
"site": "same-origin"
|
||||
});
|
||||
t.done();
|
||||
}));
|
||||
|
||||
document.body.appendChild(i);
|
||||
}, "Same-origin iframe");
|
||||
|
||||
async_test(t => {
|
||||
let i = document.createElement('iframe');
|
||||
i.src = "https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/post-to-owner.py";
|
||||
window.addEventListener('message', t.step_func(e => {
|
||||
if (e.source != i.contentWindow)
|
||||
return;
|
||||
|
||||
assert_header_equals(e.data, {
|
||||
"cause": "forced",
|
||||
"destination": "document",
|
||||
"target": "nested",
|
||||
"site": "same-site"
|
||||
});
|
||||
t.done();
|
||||
}));
|
||||
|
||||
document.body.appendChild(i);
|
||||
}, "Same-site iframe");
|
||||
|
||||
async_test(t => {
|
||||
let i = document.createElement('iframe');
|
||||
i.src = "https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/post-to-owner.py";
|
||||
window.addEventListener('message', t.step_func(e => {
|
||||
if (e.source != i.contentWindow)
|
||||
return;
|
||||
|
||||
assert_header_equals(e.data, {
|
||||
"cause": "forced",
|
||||
"destination": "document",
|
||||
"target": "nested",
|
||||
"site": "cross-site"
|
||||
});
|
||||
t.done();
|
||||
}));
|
||||
|
||||
document.body.appendChild(i);
|
||||
}, "Cross-site iframe");
|
||||
</script>
|
|
@ -0,0 +1,54 @@
|
|||
<!DOCTYPE html>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/referrer-policy/generic/common.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
<script>
|
||||
// These tests reuse the `referrer-policy` infrastructure to load images that
|
||||
// encode their request headers in their pixels. Fun stuff!
|
||||
async_test(t => {
|
||||
loadImageInWindow(
|
||||
"https://{{host}}:{{ports[https][0]}}/referrer-policy/generic/subresource/image.py",
|
||||
t.step_func_done(img => {
|
||||
assert_header_equals(decodeImageData(extractImageData(img)).headers["sec-metadata"], {
|
||||
"cause": "forced",
|
||||
"destination": "image",
|
||||
"target": "subresource",
|
||||
"site": "same-origin"
|
||||
});
|
||||
}),
|
||||
[],
|
||||
window);
|
||||
}, "Same-origin image");
|
||||
|
||||
async_test(t => {
|
||||
loadImageInWindow(
|
||||
"https://{{hosts[][www]}}:{{ports[https][0]}}/referrer-policy/generic/subresource/image.py",
|
||||
t.step_func_done(img => {
|
||||
assert_header_equals(decodeImageData(extractImageData(img)).headers["sec-metadata"], {
|
||||
"cause": "forced",
|
||||
"destination": "image",
|
||||
"target": "subresource",
|
||||
"site": "same-site"
|
||||
});
|
||||
}),
|
||||
[],
|
||||
window);
|
||||
}, "Same-site image");
|
||||
|
||||
async_test(t => {
|
||||
loadImageInWindow(
|
||||
"https://{{hosts[alt][www]}}:{{ports[https][0]}}/referrer-policy/generic/subresource/image.py",
|
||||
t.step_func_done(img => {
|
||||
assert_header_equals(decodeImageData(extractImageData(img)).headers["sec-metadata"], {
|
||||
"cause": "forced",
|
||||
"destination": "image",
|
||||
"target": "subresource",
|
||||
"site": "cross-site"
|
||||
});
|
||||
}),
|
||||
[],
|
||||
window);
|
||||
}, "Cross-site image");
|
||||
</script>
|
|
@ -0,0 +1,12 @@
|
|||
import json
|
||||
|
||||
def main(request, response):
|
||||
headers = [("Content-Type", "application/json"),
|
||||
("Access-Control-Allow-Credentials", "true")]
|
||||
|
||||
if "origin" in request.headers:
|
||||
headers.append(("Access-Control-Allow-Origin", request.headers["origin"]))
|
||||
|
||||
|
||||
body = json.dumps({ "header": request.headers["sec-metadata"] })
|
||||
return headers, body
|
|
@ -0,0 +1,8 @@
|
|||
import json
|
||||
|
||||
def main(request, response):
|
||||
headers = [("Content-Type", "text/javascript")]
|
||||
|
||||
body = "var header = %s;" % json.dumps(request.headers["sec-metadata"]);
|
||||
|
||||
return headers, body
|
|
@ -0,0 +1,16 @@
|
|||
function parse_metadata(value) {
|
||||
let result = {};
|
||||
value.split(',').forEach(item => {
|
||||
let parsed = item.trim().split('=');
|
||||
result[parsed[0]] = parsed[1];
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function assert_header_equals(value, expected) {
|
||||
let result = parse_metadata(value);
|
||||
assert_equals(result.cause, expected.cause, "cause");
|
||||
assert_equals(result.destination, expected.destination, "destination");
|
||||
assert_equals(result.target, expected.target, "target");
|
||||
assert_equals(result.site, expected.site, "site");
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import json
|
||||
|
||||
def main(request, response):
|
||||
headers = [("Content-Type", "text/html")]
|
||||
|
||||
body = """
|
||||
<!DOCTYPE html>
|
||||
<script>
|
||||
var data = %s;
|
||||
if (window.opener)
|
||||
window.opener.postMessage(data, "*");
|
||||
if (window.top != window)
|
||||
window.top.postMessage(data, "*");
|
||||
</script>
|
||||
""" % json.dumps(request.headers["sec-metadata"])
|
||||
return headers, body
|
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
|
||||
<!-- Same-origin script -->
|
||||
<script src="https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/echo-as-script.py"></script>
|
||||
<script>
|
||||
test(t => {
|
||||
t.add_cleanup(_ => header = null);
|
||||
|
||||
assert_header_equals(header, {
|
||||
"cause": "forced",
|
||||
"destination": "script",
|
||||
"target": "subresource",
|
||||
"site": "same-origin"
|
||||
});
|
||||
}, "Same-origin script");
|
||||
</script>
|
||||
|
||||
<!-- Same-site script -->
|
||||
<script src="https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/echo-as-script.py"></script>
|
||||
<script>
|
||||
test(t => {
|
||||
t.add_cleanup(_ => header = null);
|
||||
|
||||
assert_header_equals(header, {
|
||||
"cause": "forced",
|
||||
"destination": "script",
|
||||
"target": "subresource",
|
||||
"site": "same-site"
|
||||
});
|
||||
}, "Same-site script");
|
||||
</script>
|
||||
|
||||
<!-- Cross-site script -->
|
||||
<script src="https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/echo-as-script.py"></script>
|
||||
<script>
|
||||
test(t => {
|
||||
t.add_cleanup(_ => header = null);
|
||||
|
||||
assert_header_equals(header, {
|
||||
"cause": "forced",
|
||||
"destination": "script",
|
||||
"target": "subresource",
|
||||
"site": "cross-site"
|
||||
});
|
||||
}, "Cross-site script");
|
||||
</script>
|
|
@ -0,0 +1,127 @@
|
|||
<!DOCTYPE html>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/resources/testdriver.js></script>
|
||||
<script src=/resources/testdriver-vendor.js></script>
|
||||
<script src=/fetch/sec-metadata/resources/helper.js></script>
|
||||
<body>
|
||||
<script>
|
||||
// Forced navigations:
|
||||
async_test(t => {
|
||||
let w = window.open("https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/post-to-owner.py");
|
||||
t.add_cleanup(_ => w.close());
|
||||
window.addEventListener('message', t.step_func(e => {
|
||||
if (e.source != w)
|
||||
return;
|
||||
|
||||
assert_header_equals(e.data, {
|
||||
"cause": "forced",
|
||||
"destination": "document",
|
||||
"target": "top-level",
|
||||
"site": "same-origin"
|
||||
});
|
||||
t.done();
|
||||
}));
|
||||
}, "Same-origin window, forced");
|
||||
|
||||
async_test(t => {
|
||||
let w = window.open("https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/post-to-owner.py");
|
||||
t.add_cleanup(_ => w.close());
|
||||
window.addEventListener('message', t.step_func(e => {
|
||||
if (e.source != w)
|
||||
return;
|
||||
|
||||
assert_header_equals(e.data, {
|
||||
"cause": "forced",
|
||||
"destination": "document",
|
||||
"target": "top-level",
|
||||
"site": "same-site"
|
||||
});
|
||||
t.done();
|
||||
}));
|
||||
}, "Same-site window, forced");
|
||||
|
||||
async_test(t => {
|
||||
let w = window.open("https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/post-to-owner.py");
|
||||
t.add_cleanup(_ => w.close());
|
||||
window.addEventListener('message', t.step_func(e => {
|
||||
if (e.source != w)
|
||||
return;
|
||||
|
||||
assert_header_equals(e.data, {
|
||||
"cause": "forced",
|
||||
"destination": "document",
|
||||
"target": "top-level",
|
||||
"site": "cross-site"
|
||||
});
|
||||
t.done();
|
||||
}));
|
||||
}, "Cross-site window, forced");
|
||||
|
||||
// User-activated navigations:
|
||||
async_test(t => {
|
||||
let b = document.createElement('button');
|
||||
b.onclick = t.step_func(_ => {
|
||||
let w = window.open("https://{{host}}:{{ports[https][0]}}/fetch/sec-metadata/resources/post-to-owner.py");
|
||||
t.add_cleanup(_ => w.close());
|
||||
window.addEventListener('message', t.step_func(e => {
|
||||
if (e.source != w)
|
||||
return;
|
||||
|
||||
assert_header_equals(e.data, {
|
||||
"cause": "user-activated",
|
||||
"destination": "document",
|
||||
"target": "top-level",
|
||||
"site": "same-origin"
|
||||
});
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
document.body.appendChild(b);
|
||||
test_driver.click(b);
|
||||
}, "Same-origin window, user-activated");
|
||||
|
||||
async_test(t => {
|
||||
let b = document.createElement('button');
|
||||
b.onclick = t.step_func(_ => {
|
||||
let w = window.open("https://{{hosts[][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/post-to-owner.py");
|
||||
t.add_cleanup(_ => w.close());
|
||||
window.addEventListener('message', t.step_func(e => {
|
||||
if (e.source != w)
|
||||
return;
|
||||
|
||||
assert_header_equals(e.data, {
|
||||
"cause": "user-activated",
|
||||
"destination": "document",
|
||||
"target": "top-level",
|
||||
"site": "same-site"
|
||||
});
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
document.body.appendChild(b);
|
||||
test_driver.click(b);
|
||||
}, "Same-site window, user-activated");
|
||||
|
||||
async_test(t => {
|
||||
let b = document.createElement('button');
|
||||
b.onclick = t.step_func(_ => {
|
||||
let w = window.open("https://{{hosts[alt][www]}}:{{ports[https][0]}}/fetch/sec-metadata/resources/post-to-owner.py");
|
||||
t.add_cleanup(_ => w.close());
|
||||
window.addEventListener('message', t.step_func(e => {
|
||||
if (e.source != w)
|
||||
return;
|
||||
|
||||
assert_header_equals(e.data, {
|
||||
"cause": "user-activated",
|
||||
"destination": "document",
|
||||
"target": "top-level",
|
||||
"site": "cross-site"
|
||||
});
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
document.body.appendChild(b);
|
||||
test_driver.click(b);
|
||||
}, "Cross-site window, user-activated");
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue