[Libreoffice-commits] core.git: sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Tue May 19 16:59:40 UTC 2020


 sw/qa/extras/htmlimport/data/hidden-textframe.html |    8 ++++++++
 sw/qa/extras/htmlimport/htmlimport.cxx             |   21 +++++++++++++++++++++
 sw/source/filter/html/css1kywd.cxx                 |    1 +
 sw/source/filter/html/css1kywd.hxx                 |    1 +
 sw/source/filter/html/htmlcss1.cxx                 |    6 ++++++
 sw/source/filter/html/htmlsect.cxx                 |   13 +++++++++++++
 sw/source/filter/html/svxcss1.cxx                  |   10 ++++++++++
 sw/source/filter/html/svxcss1.hxx                  |    2 ++
 sw/source/filter/html/swhtml.hxx                   |    5 +++++
 9 files changed, 67 insertions(+)

New commits:
commit 0b725c38e01de528b3102975a842a700f4188087
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue May 19 14:32:58 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue May 19 18:59:01 2020 +0200

    sw HTML import: ignore hidden text frames
    
    Use-case: HTML-copy 2 lines from a browser from a mattermost chat, paste
    it into Writer. The content is not visible at all, because there are 5
    invisible full-page textframes covering the actual content.
    
    The browser has no problem with showing the content as these divs are
    all invisible. Writer does not support hiding textframes, so just ignore
    them on import for now.
    
    Change-Id: I36a807d46f5f8348239e4693ec85da49a2205854
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94500
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/extras/htmlimport/data/hidden-textframe.html b/sw/qa/extras/htmlimport/data/hidden-textframe.html
new file mode 100644
index 000000000000..5e9704279959
--- /dev/null
+++ b/sw/qa/extras/htmlimport/data/hidden-textframe.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>test</p>
+<div style="position: absolute; visibility: hidden; width: 100%; height: 100%; left: 0px; top: 0px;">
+</div>
+</body>
+</html>
diff --git a/sw/qa/extras/htmlimport/htmlimport.cxx b/sw/qa/extras/htmlimport/htmlimport.cxx
index f0d28644b3e1..35af0a03ad3e 100644
--- a/sw/qa/extras/htmlimport/htmlimport.cxx
+++ b/sw/qa/extras/htmlimport/htmlimport.cxx
@@ -424,6 +424,27 @@ CPPUNIT_TEST_FIXTURE(SwHtmlOptionsImportTest, testAllowedRTFOLEMimeTypes)
     CPPUNIT_ASSERT(xEmbeddedObject.is());
 }
 
+CPPUNIT_TEST_FIXTURE(SwHtmlOptionsImportTest, testHiddenTextframe)
+{
+    // Load HTML content into Writer, similar to HTML paste.
+    uno::Sequence<beans::PropertyValue> aLoadProperties = {
+        comphelper::makePropertyValue("FilterName", OUString("HTML (StarWriter)")),
+    };
+    OUString aURL
+        = m_directories.getURLFromSrc(DATA_DIRECTORY) + "hidden-textframe.html";
+    mxComponent = loadFromDesktop(aURL, "com.sun.star.text.TextDocument", aLoadProperties);
+
+    // Check the content of the draw page.
+    uno::Reference<drawing::XDrawPageSupplier> xSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPage> xDrawPage = xSupplier->getDrawPage();
+
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 0
+    // - Actual  : 1
+    // i.e. an unexpected text frame was created, covering the actual content.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), xDrawPage->getCount());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/html/css1kywd.cxx b/sw/source/filter/html/css1kywd.cxx
index a99b5929a5ed..f8914dedb274 100644
--- a/sw/source/filter/html/css1kywd.cxx
+++ b/sw/source/filter/html/css1kywd.cxx
@@ -217,6 +217,7 @@ const char* const sCSS1_P_page_break_after = "page-break-after";
 const char* const sCSS1_P_page_break_inside = "page-break-inside";
 const char* const sCSS1_P_size = "size";
 const char* const sCSS1_P_widows = "widows";
+const char* const sCSS1_P_visibility = "visibility";
 const char* const sCSS1_P_orphans = "orphans";
 //const char* const sCSS1_P_marks = "marks";
 
diff --git a/sw/source/filter/html/css1kywd.hxx b/sw/source/filter/html/css1kywd.hxx
index 00de608c0af9..7c0e326fd86a 100644
--- a/sw/source/filter/html/css1kywd.hxx
+++ b/sw/source/filter/html/css1kywd.hxx
@@ -220,6 +220,7 @@ extern const char* const sCSS1_P_page_break_after;
 extern const char* const sCSS1_P_page_break_inside;
 extern const char* const sCSS1_P_size;
 extern const char* const sCSS1_P_widows;
+extern const char* const sCSS1_P_visibility;
 extern const char* const sCSS1_P_orphans;
 //extern const char* const sCSS1_P_marks;
 
diff --git a/sw/source/filter/html/htmlcss1.cxx b/sw/source/filter/html/htmlcss1.cxx
index d314b2caa7dd..ce608edc98f2 100644
--- a/sw/source/filter/html/htmlcss1.cxx
+++ b/sw/source/filter/html/htmlcss1.cxx
@@ -1425,6 +1425,12 @@ const SwPageDesc *SwCSS1Parser::GetPageDesc( sal_uInt16 nPoolId, bool bCreate )
 bool SwCSS1Parser::MayBePositioned( const SvxCSS1PropertyInfo& rPropInfo,
                                     bool bAutoWidth )
 {
+    if (!rPropInfo.m_bVisible)
+    {
+        // Don't create a textframe for this div if it's hidden.
+        return false;
+    }
+
     // abs-pos
     // left/top none    auto    twip    perc
 
diff --git a/sw/source/filter/html/htmlsect.cxx b/sw/source/filter/html/htmlsect.cxx
index 8fdee86e4bed..024464355ac0 100644
--- a/sw/source/filter/html/htmlsect.cxx
+++ b/sw/source/filter/html/htmlsect.cxx
@@ -131,7 +131,19 @@ void SwHTMLParser::NewDivision( HtmlTokenId nToken )
                           CreateContainer(aClass, aItemSet, aPropInfo,
                                           xCntxt.get());
             if( !bPositioned )
+            {
+                if (aPropInfo.m_bVisible && m_aContexts.size())
+                {
+                    const std::unique_ptr<HTMLAttrContext>& pParent
+                        = m_aContexts[m_aContexts.size() - 1];
+                    if (!pParent->IsVisible())
+                    {
+                        // If the parent context is hidden, we are not visible, either.
+                        aPropInfo.m_bVisible = false;
+                    }
+                }
                 bPositioned = DoPositioning(aItemSet, aPropInfo, xCntxt.get());
+            }
         }
     }
 
@@ -378,6 +390,7 @@ void SwHTMLParser::NewDivision( HtmlTokenId nToken )
     if( bStyleParsed )
         InsertAttrs( aItemSet, aPropInfo, xCntxt.get(), true );
 
+    xCntxt->SetVisible(aPropInfo.m_bVisible);
     PushContext(xCntxt);
 }
 
diff --git a/sw/source/filter/html/svxcss1.cxx b/sw/source/filter/html/svxcss1.cxx
index 4045c8ca3a82..f64acdb4daab 100644
--- a/sw/source/filter/html/svxcss1.cxx
+++ b/sw/source/filter/html/svxcss1.cxx
@@ -3065,6 +3065,15 @@ static void ParseCSS1_so_language( const CSS1Expression *pExpr,
     }
 }
 
+static void ParseCSS1_visibility(const CSS1Expression* pExpr, SfxItemSet& /*rItemSet*/,
+                                 SvxCSS1PropertyInfo& rPropInfo, const SvxCSS1Parser& /*rParser*/)
+{
+    if (pExpr->GetType() != CSS1_IDENT)
+        return;
+
+    rPropInfo.m_bVisible = pExpr->GetString() != "hidden";
+}
+
 namespace {
 
 // the assignment of property to parsing function
@@ -3133,6 +3142,7 @@ static CSS1PropEntry const aCSS1PropFnTab[] =
     CSS1_PROP_ENTRY(text_indent),
     CSS1_PROP_ENTRY(text_transform),
     CSS1_PROP_ENTRY(top),
+    CSS1_PROP_ENTRY(visibility),
     CSS1_PROP_ENTRY(widows),
     CSS1_PROP_ENTRY(width),
 };
diff --git a/sw/source/filter/html/svxcss1.hxx b/sw/source/filter/html/svxcss1.hxx
index 677fe19bf57c..8bc1f47b380a 100644
--- a/sw/source/filter/html/svxcss1.hxx
+++ b/sw/source/filter/html/svxcss1.hxx
@@ -142,6 +142,8 @@ public:
     SvxCSS1PageBreak m_ePageBreakBefore;
     SvxCSS1PageBreak m_ePageBreakAfter;
 
+    bool m_bVisible = true;
+
     SvxCSS1PropertyInfo();
     SvxCSS1PropertyInfo( const SvxCSS1PropertyInfo& rProp );
     ~SvxCSS1PropertyInfo();
diff --git a/sw/source/filter/html/swhtml.hxx b/sw/source/filter/html/swhtml.hxx
index f1e5b99eba9f..59b7db28c467 100644
--- a/sw/source/filter/html/swhtml.hxx
+++ b/sw/source/filter/html/swhtml.hxx
@@ -233,6 +233,8 @@ class HTMLAttrContext
     bool    m_bRestartListing : 1;
     bool    m_bHeaderOrFooter : 1;
 
+    bool m_bVisible = true;
+
 public:
     void ClearSaveDocContext();
 
@@ -291,6 +293,9 @@ public:
 
     void SetAppendMode( SwHTMLAppendMode eMode ) { m_eAppend = eMode; }
     SwHTMLAppendMode GetAppendMode() const { return m_eAppend; }
+
+    void SetVisible(bool bVisible) { m_bVisible = bVisible; }
+    bool IsVisible() const { return m_bVisible; }
 };
 
 typedef std::vector<std::unique_ptr<HTMLAttrContext>> HTMLAttrContexts;


More information about the Libreoffice-commits mailing list