summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2020-05-19 14:32:58 +0200
committerMiklos Vajna <vmiklos@collabora.com>2020-05-20 17:03:15 +0200
commit7fe504586aa74042c14ed79edc7be99f27d6bc61 (patch)
treee96871e1a789b092956928eef54869ec246e4d01 /sw
parent73886f62f26ae26d4a0fe1687b31dfd0d7394c92 (diff)
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. (cherry picked from commit 0b725c38e01de528b3102975a842a700f4188087) Conflicts: sw/qa/extras/htmlimport/htmlimport.cxx sw/source/filter/html/css1kywd.cxx sw/source/filter/html/css1kywd.hxx sw/source/filter/html/svxcss1.cxx Change-Id: I36a807d46f5f8348239e4693ec85da49a2205854 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94566 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/extras/htmlimport/data/hidden-textframe.html8
-rw-r--r--sw/qa/extras/htmlimport/htmlimport.cxx29
-rw-r--r--sw/source/filter/html/css1kywd.cxx1
-rw-r--r--sw/source/filter/html/css1kywd.hxx1
-rw-r--r--sw/source/filter/html/htmlcss1.cxx6
-rw-r--r--sw/source/filter/html/htmlsect.cxx13
-rw-r--r--sw/source/filter/html/svxcss1.cxx10
-rw-r--r--sw/source/filter/html/svxcss1.hxx2
-rw-r--r--sw/source/filter/html/swhtml.hxx5
9 files changed, 75 insertions, 0 deletions
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 dd6281d9b845..0f28d9bf79c9 100644
--- a/sw/qa/extras/htmlimport/htmlimport.cxx
+++ b/sw/qa/extras/htmlimport/htmlimport.cxx
@@ -21,6 +21,7 @@
#include <unotools/datetime.hxx>
#include <vcl/GraphicNativeTransform.hxx>
#include <sfx2/linkmgr.hxx>
+#include <comphelper/propertyvalue.hxx>
#include <docsh.hxx>
#include <editsh.hxx>
@@ -368,6 +369,34 @@ DECLARE_HTMLIMPORT_TEST(testReqIfPageStyle, "reqif-page-style.xhtml")
getProperty<OUString>(getParagraph(1), "PageStyleName"));
}
+/// HTML import to the sw doc model tests.
+class SwHtmlOptionsImportTest : public SwModelTestBase
+{
+};
+
+char const DATA_DIRECTORY[] = "/sw/qa/extras/htmlimport/data/";
+
+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 7f8cc83da409..fb7d336020d8 100644
--- a/sw/source/filter/html/css1kywd.cxx
+++ b/sw/source/filter/html/css1kywd.cxx
@@ -217,6 +217,7 @@ const sal_Char* sCSS1_P_page_break_after = "page-break-after";
const sal_Char* sCSS1_P_page_break_inside = "page-break-inside";
const sal_Char* sCSS1_P_size = "size";
const sal_Char* sCSS1_P_widows = "widows";
+const sal_Char* sCSS1_P_visibility = "visibility";
const sal_Char* sCSS1_P_orphans = "orphans";
//const sal_Char* sCSS1_P_marks = "marks";
diff --git a/sw/source/filter/html/css1kywd.hxx b/sw/source/filter/html/css1kywd.hxx
index 49e41a28cadd..f141dbe207f0 100644
--- a/sw/source/filter/html/css1kywd.hxx
+++ b/sw/source/filter/html/css1kywd.hxx
@@ -220,6 +220,7 @@ extern const sal_Char* sCSS1_P_page_break_after;
extern const sal_Char* sCSS1_P_page_break_inside;
extern const sal_Char* sCSS1_P_size;
extern const sal_Char* sCSS1_P_widows;
+extern const sal_Char* sCSS1_P_visibility;
extern const sal_Char* sCSS1_P_orphans;
//extern const sal_Char* sCSS1_P_marks;
diff --git a/sw/source/filter/html/htmlcss1.cxx b/sw/source/filter/html/htmlcss1.cxx
index 26b6d2d370fe..f2e3ddc56e27 100644
--- a/sw/source/filter/html/htmlcss1.cxx
+++ b/sw/source/filter/html/htmlcss1.cxx
@@ -1420,6 +1420,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 5ce635e6aa7c..09b711494758 100644
--- a/sw/source/filter/html/htmlsect.cxx
+++ b/sw/source/filter/html/htmlsect.cxx
@@ -135,7 +135,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());
+ }
}
}
@@ -382,6 +394,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 ba523eb0d207..b8d73e47b4f0 100644
--- a/sw/source/filter/html/svxcss1.cxx
+++ b/sw/source/filter/html/svxcss1.cxx
@@ -3076,6 +3076,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";
+}
+
// the assignment of property to parsing function
struct CSS1PropEntry
{
@@ -3140,6 +3149,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 2c1c70525146..d32ab4395637 100644
--- a/sw/source/filter/html/svxcss1.hxx
+++ b/sw/source/filter/html/svxcss1.hxx
@@ -141,6 +141,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 baf039ef8e4e..d609401f2a4a 100644
--- a/sw/source/filter/html/swhtml.hxx
+++ b/sw/source/filter/html/swhtml.hxx
@@ -234,6 +234,8 @@ class HTMLAttrContext
bool m_bRestartListing : 1;
bool m_bHeaderOrFooter : 1;
+ bool m_bVisible = true;
+
public:
void ClearSaveDocContext();
@@ -292,6 +294,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;