quixote
Version:
CSS unit and integration testing
112 lines (91 loc) • 3.75 kB
JavaScript
// Copyright (c) 2014 Titanium I.T. LLC. All rights reserved. For license, see "README" or "LICENSE" file.
;
var ensure = require("../util/ensure.js");
var PositionDescriptor = require("./position_descriptor.js");
var Position = require("../values/position.js");
var TOP = "top";
var RIGHT = "right";
var BOTTOM = "bottom";
var LEFT = "left";
var Me = module.exports = function ViewportEdge(position, browsingContext) {
var BrowsingContext = require("../browsing_context.js"); // break circular dependency
ensure.signature(arguments, [ String, BrowsingContext ]);
this.should = this.createShould();
if (position === LEFT || position === RIGHT) PositionDescriptor.x(this);
else if (position === TOP || position === BOTTOM) PositionDescriptor.y(this);
else ensure.unreachable("Unknown position: " + position);
this._position = position;
this._browsingContext = browsingContext;
};
PositionDescriptor.extend(Me);
Me.top = factoryFn(TOP);
Me.right = factoryFn(RIGHT);
Me.bottom = factoryFn(BOTTOM);
Me.left = factoryFn(LEFT);
Me.prototype.value = function() {
ensure.signature(arguments, []);
var scroll = this._browsingContext.getRawScrollPosition();
var x = Position.x(scroll.x);
var y = Position.y(scroll.y);
var size = viewportSize(this._browsingContext.contentDocument.documentElement);
switch(this._position) {
case TOP: return y;
case RIGHT: return x.plus(Position.x(size.width));
case BOTTOM: return y.plus(Position.y(size.height));
case LEFT: return x;
default: ensure.unreachable();
}
};
Me.prototype.toString = function() {
ensure.signature(arguments, []);
return this._position + " edge of viewport";
};
function factoryFn(position) {
return function factory(content) {
return new Me(position, content);
};
}
// USEFUL READING: http://www.quirksmode.org/mobile/viewports.html
// and http://www.quirksmode.org/mobile/viewports2.html
// BROWSERS TESTED: Safari 6.2.0 (Mac OS X 10.8.5); Mobile Safari 7.0.0 (iOS 7.1); Firefox 32.0.0 (Mac OS X 10.8);
// Firefox 33.0.0 (Windows 7); Chrome 38.0.2125 (Mac OS X 10.8.5); Chrome 38.0.2125 (Windows 7); IE 8, 9, 10, 11
// Width techniques I've tried: (Note: results are different in quirks mode)
// body.clientWidth
// body.offsetWidth
// body.getBoundingClientRect().width
// fails on all browsers: doesn't include margin
// body.scrollWidth
// works on Safari, Mobile Safari, Chrome
// fails on Firefox, IE 8, 9, 10, 11: doesn't include margin
// html.getBoundingClientRect().width
// html.offsetWidth
// works on Safari, Mobile Safari, Chrome, Firefox
// fails on IE 8, 9, 10: includes scrollbar
// html.scrollWidth
// html.clientWidth
// WORKS! Safari, Mobile Safari, Chrome, Firefox, IE 8, 9, 10, 11
// Height techniques I've tried: (Note that results are different in quirks mode)
// body.clientHeight
// body.offsetHeight
// body.getBoundingClientRect().height
// fails on all browsers: only includes height of content
// body getComputedStyle("height")
// fails on all browsers: IE8 returns "auto"; others only include height of content
// body.scrollHeight
// works on Safari, Mobile Safari, Chrome;
// fails on Firefox, IE 8, 9, 10, 11: only includes height of content
// html.getBoundingClientRect().height
// html.offsetHeight
// works on IE 8, 9, 10
// fails on IE 11, Safari, Mobile Safari, Chrome: only includes height of content
// html.scrollHeight
// works on Firefox, IE 8, 9, 10, 11
// fails on Safari, Mobile Safari, Chrome: only includes height of content
// html.clientHeight
// WORKS! Safari, Mobile Safari, Chrome, Firefox, IE 8, 9, 10, 11
function viewportSize(htmlElement) {
return {
width: htmlElement.clientWidth,
height: htmlElement.clientHeight
};
}