E-book viewer: Fix a regression in 5.15 that caused the viewer to not respect page-break properties

This commit is contained in:
Kovid Goyal 2021-04-18 21:58:41 +05:30
parent 36511cb505
commit 0b94f39d9a
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 39 additions and 3 deletions

View File

@ -313,7 +313,7 @@ class Token {
text.reserve(16);
}
Token(const TokenType type, const char32_t ch, size_t out_pos) :
Token(const TokenType type, const char32_t ch, size_t out_pos = 0) :
type(type), text(), unit_at(0), out_pos(out_pos) {
text.reserve(16);
if (ch) text.push_back(ch);
@ -391,6 +391,17 @@ class Token {
}
}
bool is_property_terminator() const {
switch(type) {
case TokenType::whitespace:
return text.size() > 0 && text.find_first_of('\n') != std::string::npos;
case TokenType::delimiter:
return text.size() == 1 && (text[0] == ';' || text[0] == '}');
default:
return false;
}
}
PyObject* get_text_as_python() const {
PyObject *ans = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, text.data(), text.size());
if (ans == NULL) throw python_error("Failed to convert token value to python unicode object");
@ -414,6 +425,10 @@ class Token {
text.replace(pos, len, (size_t)0u, 0);
}
void prepend(const char32_t *src) {
text.insert(0, src);
}
void set_text(const PyObject* src) {
if (PyUnicode_READY(src) != 0) throw python_error("Failed to set token value from unicode object as readying the unicode obect failed");
int kind = PyUnicode_KIND(src); void *data = PyUnicode_DATA(src);
@ -602,9 +617,21 @@ class TokenQueue {
case PropertyType::font_size:
process_values = std::bind(&TokenQueue::process_font_sizes, this, std::placeholders::_1);
break;
case PropertyType::page_break:
case PropertyType::page_break: {
it->erase_text_substring(0, 5);
size_t pos = std::distance(queue.begin(), it);
std::vector<Token> copies;
copies.reserve(queue.size());
while (it < queue.end() && !it->is_property_terminator()) { copies.push_back(*(it++)); }
if (copies.size()) {
queue.insert(queue.begin() + pos, std::make_move_iterator(copies.begin()), std::make_move_iterator(copies.end()));
size_t idx = pos + copies.size();
queue[idx].prepend(U"-webkit-column-");
queue.emplace(queue.begin() + idx, TokenType::whitespace, ' ');
queue.emplace(queue.begin() + idx, TokenType::delimiter, ';');
}
changed = true; keep_going = false;
}
break;
case PropertyType::non_standard_writing_mode:
it->set_text(U"writing-mode");

View File

@ -31,6 +31,13 @@ class TestTransform(SimpleTest):
def s(src, expected, url_callback=upper_case):
return d(src, expected, url_callback=url_callback, is_declaration=False)
s('.c { page-break-after: 1 always }', '.c { break-after: 1 always ; -webkit-column-break-after: 1 always }')
s('.c { page-break-after: always\ncolor:red }', '.c { break-after: always; -webkit-column-break-after: always\ncolor:red }')
s('.c { page-break-after: always\n}', '.c { break-after: always; -webkit-column-break-after: always\n}')
s('.c { page-break-after: always;color:red }', '.c { break-after: always; -webkit-column-break-after: always;color:red }')
s('.c { page-break-after: /**/always }', '.c { break-after: always ; -webkit-column-break-after: always }')
s('.c { page-break-after: always !important }', '.c { break-after: always !important ; -webkit-column-break-after: always !important }')
s('.c { page-break-after: always;}', '.c { break-after: always; -webkit-column-break-after: always;}')
s('.c{x:url(y)}', '.c{x:url("Y")}')
s('@im/* c */port "x.y";', '@import "X.Y";')
s('@import url("narrow.css") supports(display: flex) handheld and (max-width: 400px);',
@ -59,6 +66,7 @@ class TestTransform(SimpleTest):
d('-epub-writing-mode: a; -web/* */kit-writing-mode: b; writing-mode: c', 'writing-mode: a; writing-mode: b; writing-mode: c')
d('xxx:yyy', 'xxx:yyy')
d('page-break-before: always', 'break-before: always; -webkit-column-break-before: always')
sheet = '''
@import "b/loc.test";
@ -78,9 +86,10 @@ class TestTransform(SimpleTest):
@zoo {
not(.woo) and why {
font: 16px "something something" 16;
page-break-before: avoid
}
}
}
.why { font: 16px}
'''
s(sheet, sheet.replace('16px', '1rem').replace('b/loc.test', 'B/LOC.TEST'))
s(sheet, sheet.replace('16px', '1rem').replace('b/loc.test', 'B/LOC.TEST').replace('page-', 'break-before: avoid; -webkit-column-'))