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
|
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/css-ruby/#line-height">
<link rel="stylesheet" href="/fonts/ahem.css">
<style>
body {
font: 16px/1 Ahem;
}
body > div {
border: 1px solid lime;
}
.over_emp {
-webkit-text-emphasis: 'x';
-webkit-text-emphasis-position: over left;
text-emphasis: 'x';
text-emphasis-position: over left;
}
.under_emp {
-webkit-text-emphasis: 'x';
-webkit-text-emphasis-position: under left;
text-emphasis: 'x';
text-emphasis-position: under left;
}
</style>
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
function renderRuby(source) {
document.body.insertAdjacentHTML('afterbegin', source);
const firstChild = document.body.firstChild;
const container = firstChild.tagName == 'RUBY' ? null : firstChild;
const ruby = firstChild.tagName == 'RUBY' ? firstChild : firstChild.querySelector('ruby');
return {container: container, ruby: ruby, rt: ruby.querySelector('rt')}
}
function renderRubyAndGetBoxes(source) {
const {container, ruby, rt} = renderRuby(source);
return {
container: container ? container.getBoundingClientRect() : null,
ruby: ruby ? ruby.getBoundingClientRect() : null,
rt: rt ? rt.getBoundingClientRect() : null
};
}
test(() => {
const {container, ruby, rt} = renderRubyAndGetBoxes(
'<div><ruby>base<rt>annotation</rt></ruby></div>');
assert_true(container.top <= rt.top);
assert_true(rt.top < ruby.top);
}, 'Over ruby doesn\'t overflow the block');
test(() => {
const {container, ruby, rt} = renderRubyAndGetBoxes(
'<div>before <span style="vertical-align:32px;">' +
'<ruby>base<rt>annotation</rt></ruby>' +
'</span> after</div>');
assert_true(container.top <= rt.top);
assert_true(rt.top < ruby.top);
}, 'Over ruby + vertical-align doesn\'t overflow the block');
test(() => {
const {container, ruby, rt} = renderRubyAndGetBoxes(
'<div><ruby style="ruby-position:under">base<rt>annotation</rt></ruby></div>');
assert_true(container.bottom >= rt.bottom);
assert_true(rt.bottom > ruby.bottom);
}, 'Under ruby doesn\'t overflow the block');
test(() => {
const {container, ruby, rt} = renderRubyAndGetBoxes(
'<div>before <ruby style="vertical-align:-32px; ruby-position:under">' +
'base<rt>annotation</rt></ruby> after</div>');
assert_true(container.bottom >= rt.bottom);
assert_true(rt.bottom > ruby.bottom);
}, 'Under ruby + vertical-align doesn\'t overflow the block');
test(() => {
const {container, ruby, rt} = renderRuby(
'<div><ruby style="ruby-position:under">base<rt>annotation</rt></ruby>' +
'<div>n</div></div>');
const nextBlockBox = container.querySelector('div').getBoundingClientRect();
const rtBox = rt.getBoundingClientRect();
assert_greater_than_equal(nextBlockBox.top, rtBox.bottom);
}, 'Under ruby doesn\'t overwrap with the next block');
test(() => {
const {container, ruby, rt} = renderRuby(
'<div><span>before</span><br><ruby>base<rt style="font-size:16px"' +
'>annotation</rt></ruby></div>');
const firstLine = container.querySelector('span').getBoundingClientRect();
assert_true(ruby.getBoundingClientRect().top - firstLine.bottom > 1);
}, 'Expand inter-lines spacing');
test(() => {
const {container, ruby, rt} = renderRuby(
'<div style="line-height:1.5;">' +
'<span>First line</span><br>' +
'<span>Second line</span><br>' +
'<ruby>base<rt style="font-size:50%">' +
'annotation</rt></ruby></div>');
const firstLine = container.querySelector('span').getBoundingClientRect();
const secondLine = container.querySelectorAll('span')[1].getBoundingClientRect();
const rubyLine = ruby.getBoundingClientRect();
assert_approx_equals(secondLine.top - firstLine.top, rubyLine.top - secondLine.top, 1);
}, 'Consume half-leading of the previous line');
test(() => {
const {container, ruby, rt} = renderRuby(
'<div style="line-height:1.5;">' +
'<span>First line</span><br>' +
'<span class="under_emp">Second line</span><br>' +
'<ruby>base<rt style="font-size:50%">' +
'annotation</rt></ruby></div>');
const firstLine = container.querySelector('span').getBoundingClientRect();
const secondLine = container.querySelectorAll('span')[1].getBoundingClientRect();
const rubyLine = ruby.getBoundingClientRect();
const RUBY_EMPHASIS_SIZE = 8;
assert_greater_than_equal(rubyLine.top - secondLine.top,
secondLine.top - firstLine.top + RUBY_EMPHASIS_SIZE);
}, 'Don\'t Consume half-leading of the previous line with text-emphasis');
test(() => {
const {container, ruby, rt} = renderRuby(
'<div style="line-height:1.5;">' +
'<span>First line</span><br>' +
'<ruby style="ruby-position:under">base<rt style="font-size:50%">' +
'annotation</rt></ruby><br>' +
'<span>Third line</span></div>');
const firstLine = container.querySelector('span').getBoundingClientRect();
const rubyLine = ruby.getBoundingClientRect();
const thirdLine = container.querySelectorAll('span')[1].getBoundingClientRect();
assert_approx_equals(rubyLine.top - firstLine.top, thirdLine.top - rubyLine.top, 1);
}, 'Consume half-leading of the next line');
test(() => {
const {container, ruby, rt} = renderRuby(
'<div style="line-height:1.5;">' +
'<span>First line</span><br>' +
'<ruby style="ruby-position:under">base<rt style="font-size:50%">' +
'annotation</rt></ruby><br>' +
'<span class="over_emp">Third line</span>' +
'</div>');
const firstLine = container.querySelector('span').getBoundingClientRect();
const rubyLine = ruby.getBoundingClientRect();
const thirdLine = container.querySelectorAll('span')[1].getBoundingClientRect();
const RUBY_EMPHASIS_SIZE = 8;
assert_greater_than_equal(thirdLine.top - rubyLine.top,
rubyLine.top - firstLine.top + RUBY_EMPHASIS_SIZE);
}, 'Don\'t Consume half-leading of the next line with text-emphasis');
</script>
</body>
|