From 31c7698acb476aea2bcbfe3b5eccdafe3107dd66 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 21 Mar 2021 12:07:26 +0530 Subject: [PATCH] Get url transforms working --- src/calibre/srv/fast_css_transform.cpp | 8 +++++--- src/calibre/srv/tests/fast_css_transform.py | 13 +++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/calibre/srv/fast_css_transform.cpp b/src/calibre/srv/fast_css_transform.cpp index ccdf80dd81..63bd18c89d 100644 --- a/src/calibre/srv/fast_css_transform.cpp +++ b/src/calibre/srv/fast_css_transform.cpp @@ -84,7 +84,7 @@ class pyobject_raii { public: pyobject_raii() : handle(NULL) {} - pyobject_raii(PyObject* h) : handle(h) {} + pyobject_raii(PyObject* h, bool incref=false) : handle(h) { if (incref && handle) Py_INCREF(handle); } ~pyobject_raii() { Py_CLEAR(handle); } @@ -648,7 +648,7 @@ class TokenQueue { public: TokenQueue(const size_t src_sz, PyObject *url_callback=NULL) : - pool(), queue(), out(), scratch(), scratch2(), url_callback(url_callback) { + pool(), queue(), out(), scratch(), scratch2(), url_callback(url_callback, true) { out.reserve(src_sz * 2); scratch.reserve(16); scratch2.reserve(16); } @@ -1047,6 +1047,7 @@ class Parser { if (starting_string()) { pop_state(); end_string_with = ch; states.push(ParseState::url_string); return; } if (ch == ')') { pop_state(); return; } pop_state(); states.push(ParseState::url); + token_queue.add_char(ch); } void handle_url_string() { @@ -1059,8 +1060,9 @@ class Parser { } void handle_url() { - if (has_valid_escape()) enter_escape_mode(); + if (ch == '\\' && has_valid_escape()) enter_escape_mode(); else if (ch == ')') exit_url_mode(true); + else token_queue.add_char(ch); } void exit_url_mode(bool trim=false) { diff --git a/src/calibre/srv/tests/fast_css_transform.py b/src/calibre/srv/tests/fast_css_transform.py index c1d8d14387..a68f183bea 100644 --- a/src/calibre/srv/tests/fast_css_transform.py +++ b/src/calibre/srv/tests/fast_css_transform.py @@ -22,6 +22,18 @@ class TestTransform(SimpleTest): def d(src, expected, is_declaration=True, url_callback=None): self.ae(transform_properties(src, is_declaration=is_declaration, url_callback=url_callback), expected) + def upper_case(val): + return val.upper() + + def u(src, expected, is_declaration=True, url_callback=upper_case): + return d(src, expected, url_callback=url_callback, is_declaration=is_declaration) + + u('background: url( te st.gif ); src: url(x)', 'background: url("TE ST.GIF"); src: url("X")') + u('background: url(test.gif); xxx: url()', 'background: url("TEST.GIF"); xxx: url()') + u(r'background: url(t\)est.gif)', 'background: url("T)EST.GIF")') + u('a:url( "( )" )', 'a:url("( )")') + u('a:url( "()" )', 'a:url( "()" )', url_callback=lambda x: x) + d(r'f\ont-s\69z\65 : 16\px', 'font-size: 1rem') d('font -size: 16px', 'font -size: 16px') d('font-size: 16px', 'font-size: 1rem') @@ -35,3 +47,4 @@ class TestTransform(SimpleTest): d('font: sans-serif 16px/3', 'font: sans-serif 1rem/3') d('-epub-writing-mode: a; -webkit-writing-mode: b; writing-mode: c', 'writing-mode: a; writing-mode: b; writing-mode: c') + d('xxx:yyy', 'xxx:yyy')