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
|
function getWritingMode(element, reference) {
var style = window.getComputedStyle(reference);
if (style.getPropertyValue("writing-mode") !== "horizontal-tb" ||
style.getPropertyValue("direction") !== "ltr")
throw "Reference should have writing mode horizontal-tb and ltr";
style = window.getComputedStyle(element);
var param = {
rtl: style.getPropertyValue("direction") === "rtl",
mode: style.getPropertyValue("writing-mode")
};
return param;
}
function compareSize(element, reference, epsilon) {
var param = getWritingMode(element, reference);
var elementBox = element.getBoundingClientRect();
var referenceBox = reference.getBoundingClientRect();
switch(param.mode) {
case "horizontal-tb":
assert_approx_equals(elementBox.width, referenceBox.width, epsilon,
"inline size");
assert_approx_equals(elementBox.height, referenceBox.height, epsilon,
"block size");
break;
case "vertical-lr":
case "vertical-rl":
assert_approx_equals(elementBox.width, referenceBox.height, epsilon,
"inline size");
assert_approx_equals(elementBox.height, referenceBox.width, epsilon,
"block size");
break;
default:
throw "compareSize: Unrecognized writing-mode value";
}
}
function childrenHaveEmptyBoundingClientRects(element) {
Array.from(element.children).forEach(child => {
var childBox = child.getBoundingClientRect();
assert_true(childBox.left == 0 && childBox.right == 0 && childBox.top == 0 && childBox.bottom == 0);
})
}
function participateToParentLayout(child) {
var style = window.getComputedStyle(child);
return style.getPropertyValue("display") !== "none" &&
style.getPropertyValue("position") !== "absolute" &&
style.getPropertyValue("position") !== "fixed";
}
function childrenParticipatingToLayout(element) {
var children = [];
Array.from(element.children).forEach(child => {
if (participateToParentLayout(child))
children.push(child);
})
return children;
}
function compareLayout(element, reference, epsilon) {
// Compare sizes of elements and children.
var param = getWritingMode(element, reference);
compareSize(element, reference, epsilon);
var elementBox = element.getBoundingClientRect();
var referenceBox = reference.getBoundingClientRect();
var elementChildren = childrenParticipatingToLayout(element);
var referenceChildren = childrenParticipatingToLayout(reference);
if (elementChildren.length != referenceChildren.length)
throw "Reference should have the same number of children participating to layout."
for (var i = 0; i < elementChildren.length; i++) {
compareSize(elementChildren[i], referenceChildren[i], epsilon);
var childBox = elementChildren[i].getBoundingClientRect();
var referenceChildBox = referenceChildren[i].getBoundingClientRect();
switch(param.mode) {
case "horizontal-tb":
assert_approx_equals(param.rtl ?
elementBox.right - childBox.right :
childBox.left - elementBox.left,
referenceChildBox.left - referenceBox.left,
epsilon,
`inline position (child ${i})`);
assert_approx_equals(childBox.top - elementBox.top,
referenceChildBox.top - referenceBox.top,
epsilon,
`block position (child ${i})`);
break;
case "vertical-lr":
case "vertical-rl":
assert_approx_equals(param.rtl ?
elementBox.bottom - childBox.bottom :
childBox.top - elementBox.top,
referenceChildBox.left - referenceBox.left,
epsilon,
`inline position (child ${i})`);
assert_approx_equals(elementBox.right - childBox.right,
referenceChildBox.top - referenceBox.top,
epsilon,
`block position (child ${i})`);
break;
default:
throw "compareLayout: Unrecognized writing-mode value";
}
}
}
|