Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 2 subtest issues.
 - This WPT test may be referenced by the following Test IDs:
            
- /css/css-ruby/line-spacing.html - WPT Dashboard Interop Dashboard
 
 
<!DOCTYPE html>
<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;
}
#log {
  font-family: sans-serif;
}
</style>
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
setup({ explicit_done: true });
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
  };
}
document.fonts.load("16px Ahem").then(() => {
  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');
  // crbug.com/336592423
  test(() => {
    const {container, ruby, rt} = renderRuby(
        '<div style="line-height:1;">' +
        '<span style="display:inline-block; width:1em; height:4em; vertical-align:top"></span><br>' +
        '<ruby>base<rt>annotation</rt></ruby></div>');
    const firstLine = container.querySelector('span').getBoundingClientRect();
    const rtBox = rt.getBoundingClientRect();
    assert_greater_than_equal(rtBox.top, firstLine.bottom);
  }, 'An atomic-inline should not overlap with an annotation in the next line');
  done();
});
</script>
</body>