blob: f01cd3a4ee25e7ff5d6cf612fc44aa49304089ac [file] [log] [blame]
<html>
<head>
<script>
function setMetaViewport(override)
{
var VIEWPORTS = {
"w=320": "width=320",
"w=dw": "width=device-width",
"w=980": "width=980",
"none": "no viewport (desktop site)"
};
var viewport = VIEWPORTS["none"];
for (var key in VIEWPORTS) {
if (location.search.indexOf(key) !== -1) {
viewport = VIEWPORTS[key];
window.__viewport = key;
break;
}
}
if (override) {
viewport = VIEWPORTS[override];
window.__viewport = override;
}
if (viewport != VIEWPORTS["none"])
document.write('<meta name="viewport" content="'+viewport+'">');
}
// matchMedia() polyfill from https://github.com/paulirish/matchMedia.js
// Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license
window.matchMedia = window.matchMedia || (function(doc, undefined){
var bool,
docElem = doc.documentElement,
refNode = docElem.firstElementChild || docElem.firstChild,
// fakeBody required for <FF4 when executed in <head>
fakeBody = doc.createElement('body'),
div = doc.createElement('div');
div.id = 'mq-test-1';
div.style.cssText = "position:absolute;top:-100em";
fakeBody.style.background = "none";
fakeBody.appendChild(div);
return function(q){
div.innerHTML = '&shy;<style media="'+q+'"> #mq-test-1 { width: 42px; }</style>';
docElem.insertBefore(fakeBody, refNode);
bool = div.offsetWidth == 42;
docElem.removeChild(fakeBody);
return { matches: bool, media: q };
};
})(document);
var results;
function dumpMetrics(full)
{
results = [];
writeResult("Device:", "");
testJS("window.screenX");
testJS("window.screenY");
writeResult("Viewport:", "?" + window.__viewport);
testMQOrientation();
testJS("window.orientation", "");
if (full) {
testMQDimension("resolution", null, "dpi");
testMQDevicePixelRatio(window.devicePixelRatio);
testJS("window.devicePixelRatio", "");
}
writeResult("Widths:", "");
if (full) {
testMQDimension("device-width", screen.width);
testJS("screen.width");
testJS("screen.availWidth");
testJS("window.outerWidth");
testJS("window.innerWidth");
testMQDimension("width", document.documentElement.clientWidth);
}
testJS("document.documentElement.clientWidth");
testJS("document.documentElement.offsetWidth");
testJS("document.documentElement.scrollWidth");
if (full)
testJS("document.body.clientWidth");
testJS("document.body.offsetWidth");
testJS("document.body.scrollWidth");
writeResult("Heights:", "");
if (full) {
testMQDimension("device-height", screen.height);
testJS("screen.height");
testJS("screen.availHeight");
testJS("window.outerHeight");
testJS("window.innerHeight");
testMQDimension("height", document.documentElement.clientHeight);
}
testJS("document.documentElement.clientHeight");
testJS("document.documentElement.offsetHeight");
testJS("document.documentElement.scrollHeight");
if (full)
testJS("document.body.clientHeight");
testJS("document.body.offsetHeight");
testJS("document.body.scrollHeight");
return results.join("\n");
}
function dumpWindowSegments() {
let output = [];
output.push("Main frame segments:");
output = output.concat(dumpWindowSegmentsForWindow(this));
output.push("Iframe segments:");
output = output.concat(dumpWindowSegmentsForWindow(window.frames[0]));
return output.join("\n");
}
function dumpWindowSegmentsForWindow(window_object) {
let output = [];
output.push(window_object.getWindowSegments().length);
window_object.getWindowSegments().forEach((segment) => {
let segmentString = `${segment.x} ${segment.y} ${segment.width} ${segment.height}`;
output.push(segmentString);
});
return output;
}
function testJS(expr, unit)
{
if (unit === undefined)
unit = "px";
var ans = eval(expr);
if (typeof ans == "number")
ans += unit;
// Shorten long properties to make more readable
expr = expr.replace("documentElement", "docElem").replace("document", "doc");
writeResult(expr, ans);
}
function testMQOrientation()
{
if (matchMedia("screen and (orientation: portrait)").matches)
writeResult("@media orientation", "portrait");
else if (matchMedia("screen and (orientation: landscape)").matches)
writeResult("@media orientation", "landscape");
else
writeResult("@media orientation", "???");
}
function testMQDevicePixelRatio(guess)
{
// To save time, try the guess value first; otherwise try common values (TODO: binary search).
if (matchMedia("screen and (-webkit-device-pixel-ratio: "+guess+"), screen and (device-pixel-ratio: "+guess+")").matches)
writeResult("@media device-pixel-ratio", guess);
else if (matchMedia("screen and (-webkit-device-pixel-ratio: 2), screen and (device-pixel-ratio: 2)").matches)
writeResult("@media device-pixel-ratio", "2");
else if (matchMedia("screen and (-webkit-device-pixel-ratio: 1.5), screen and (device-pixel-ratio: 1.5)").matches)
writeResult("@media device-pixel-ratio", "1.5");
else if (matchMedia("screen and (-webkit-device-pixel-ratio: 1), screen and (device-pixel-ratio: 1)").matches)
writeResult("@media device-pixel-ratio", "1");
else if (matchMedia("screen and (-webkit-device-pixel-ratio: 2.25), screen and (device-pixel-ratio: 2.25)").matches)
writeResult("@media device-pixel-ratio", "2.25");
else
writeResult("@media device-pixel-ratio", "???");
}
function testMQDimension(feature, guess, unit)
{
unit = unit || "px";
// To save time, try the guess value first; otherwise binary search.
if (guess && matchMedia("screen and (" + feature + ":" + guess + unit + ")").matches) {
writeResult("@media " + feature, guess + unit);
} else {
var val = mqBinarySearch(feature, 1, 2560, unit);
writeResult("@media " + feature, val ? val + unit : "???");
}
}
// Searches the inclusive range [minValue, maxValue].
function mqBinarySearch(feature, minValue, maxValue, unit)
{
if (minValue == maxValue) {
if (matchMedia("screen and (" + feature + ":" + minValue + unit + ")").matches)
return minValue;
else
return null;
}
var mid = Math.ceil((minValue + maxValue) / 2);
if (matchMedia("screen and (min-" + feature + ":" + mid + unit + ")").matches)
return mqBinarySearch(feature, mid, maxValue, unit); // feature is >= mid
else
return mqBinarySearch(feature, minValue, mid - 1, unit); // feature is < mid
}
function writeResult(key, val)
{
results.push(key + (val ? " = " + val : ""));
}
</script>
<script>
// This test is based on http://jsbin.com/urowoh/latest.
setMetaViewport();
</script>
<style>
html {
overflow-x: hidden;
}
body {
margin: 0;
min-height: 1000px;
overflow-x: hidden;
}
body.small {
min-height: 100px;
}
</style>
</head>
<body>
<iframe src="about:blank"></iframe>
</body>
</html>