sw/qa/filter/html/data/centered-table.xhtml |    9 ++++
 sw/qa/filter/html/html.cxx                  |   57 ++++++++++++++++++++++++++++
 sw/source/filter/html/css1atr.cxx           |   11 +++++
 sw/source/filter/html/htmltab.cxx           |   29 ++++++++++++++
 sw/source/filter/html/htmltabw.cxx          |   14 +++++-
 sw/source/filter/html/svxcss1.cxx           |   16 +++++++
 sw/source/filter/html/svxcss1.hxx           |    2 
 7 files changed, 136 insertions(+), 2 deletions(-)

New commits:
commit 1e4bc6bbf90d9670c39a34b447840ffbbb96463b
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Jan 20 12:15:48 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Jan 20 15:27:33 2023 +0100

    sw HTML import: initial CSS support on tables
    
    This is the import side of commit
    6ce374140f3bd1cede959ccc8da69fdacecff191 (sw XHTML export: use CSS
    instead of <center> for tables, 2023-01-19), otherwise the import would
    not handle the new markup of the export.
    
    (cherry picked from commit 44c75d56cd441ad3d174db75a6e5ae672b7d2a08)
    
    Conflicts:
            sw/source/filter/html/svxcss1.cxx
    
    Change-Id: I7d18b06e10adff877dbbf1745861c65a07f807cb

diff --git a/sw/qa/filter/html/data/centered-table.xhtml 
b/sw/qa/filter/html/data/centered-table.xhtml
new file mode 100644
index 000000000000..4ec88792f119
--- /dev/null
+++ b/sw/qa/filter/html/data/centered-table.xhtml
@@ -0,0 +1,9 @@
+<reqif-xhtml:div>
+       <reqif-xhtml:table width="400" cellpadding="0" cellspacing="0" 
style="margin-left: auto; margin-right: auto">
+               <reqif-xhtml:tr>
+                       <reqif-xhtml:td><reqif-xhtml:p>A1</reqif-xhtml:p>
+                       </reqif-xhtml:td>
+               </reqif-xhtml:tr>
+       </reqif-xhtml:table>
+<reqif-xhtml:p></reqif-xhtml:p>
+</reqif-xhtml:div>
diff --git a/sw/qa/filter/html/html.cxx b/sw/qa/filter/html/html.cxx
index 7ad6bd5b0ffa..b987a00677c2 100644
--- a/sw/qa/filter/html/html.cxx
+++ b/sw/qa/filter/html/html.cxx
@@ -248,6 +248,31 @@ CPPUNIT_TEST_FIXTURE(Test, testCenteredTableCSSExport)
     assertXPath(pXmlDoc, "//reqif-xhtml:center", 0);
     assertXPath(pXmlDoc, "//reqif-xhtml:table", "style", "margin-left: auto; 
margin-right: auto");
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testCenteredTableCSSImport)
+{
+    // Given an XHTML file with a centered (with inline CSS) table, when 
importing that document:
+    setImportFilterOptions("xhtmlns=reqif-xhtml");
+    setImportFilterName("HTML (StarWriter)");
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + 
"centered-table.xhtml";
+    uno::Sequence<beans::PropertyValue> aLoadArgs = {
+        comphelper::makePropertyValue("FilterName", OUString("HTML 
(StarWriter)")),
+        comphelper::makePropertyValue("FilterOptions", 
OUString("xhtmlns=reqif-xhtml")),
+    };
+    mxComponent = loadFromDesktop(aURL, OUString(), aLoadArgs);
+
+    // Then make sure that the table is centered:
+    auto pTextDocument = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    SwDoc* pDoc = pTextDocument->GetDocShell()->GetDoc();
+    const SwFrameFormats& rTableFormats = *pDoc->GetTableFrameFormats();
+    const SwFrameFormat* pTableFormat = rTableFormats[0];
+    sal_Int16 eHoriOrient = pTableFormat->GetHoriOrient().GetHoriOrient();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 2 (CENTER)
+    // - Actual  : 3 (LEFT)
+    // i.e. the table alignment was lost on import.
+    CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER, eHoriOrient);
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/html/htmltab.cxx 
b/sw/source/filter/html/htmltab.cxx
index 21a387fdc80f..9ba74ecf44a9 100644
--- a/sw/source/filter/html/htmltab.cxx
+++ b/sw/source/filter/html/htmltab.cxx
@@ -5040,6 +5040,35 @@ std::shared_ptr<HTMLTable> 
SwHTMLParser::BuildTable(SvxAdjust eParentAdjust,
     else
     {
         m_xTable.reset();
+
+        // Parse CSS on the table.
+        OUString aStyle;
+        const HTMLOptions& rHTMLOptions = GetOptions();
+        for (size_t i = rHTMLOptions.size(); i;)
+        {
+            const HTMLOption& rOption = rHTMLOptions[--i];
+            if (rOption.GetToken() == HtmlOptionId::STYLE)
+            {
+                aStyle = rOption.GetString();
+            }
+        }
+        if (!aStyle.isEmpty())
+        {
+            // Have inline CSS.
+            SfxItemSet aItemSet(m_xDoc->GetAttrPool(), 
m_pCSS1Parser->GetWhichMap());
+            SvxCSS1PropertyInfo aPropInfo;
+            if (ParseStyleOptions(aStyle, /*aId=*/OUString(), 
/*aClass=*/OUString(), aItemSet,
+                                  aPropInfo))
+            {
+                if (aPropInfo.m_eLeftMarginType == SVX_CSS1_LTYPE_AUTO
+                    && aPropInfo.m_eRightMarginType == SVX_CSS1_LTYPE_AUTO)
+                {
+                    // Both left & right is set to auto: that's our center.
+                    eParentAdjust = SvxAdjust::Center;
+                }
+            }
+        }
+
         HTMLTableOptions aTableOptions(GetOptions(), eParentAdjust);
 
         if (!aTableOptions.aId.isEmpty())
diff --git a/sw/source/filter/html/svxcss1.cxx 
b/sw/source/filter/html/svxcss1.cxx
index f64acdb4daab..0c219e3a25b7 100644
--- a/sw/source/filter/html/svxcss1.cxx
+++ b/sw/source/filter/html/svxcss1.cxx
@@ -400,6 +400,8 @@ SvxCSS1PropertyInfo::SvxCSS1PropertyInfo( const 
SvxCSS1PropertyInfo& rProp ) :
     m_eTopType( rProp.m_eTopType ),
     m_eWidthType( rProp.m_eWidthType ),
     m_eHeightType( rProp.m_eHeightType ),
+    m_eLeftMarginType( rProp.m_eLeftMarginType ),
+    m_eRightMarginType( rProp.m_eRightMarginType ),
     m_eSizeType( rProp.m_eSizeType ),
     m_ePageBreakBefore( rProp.m_ePageBreakBefore ),
     m_ePageBreakAfter( rProp.m_ePageBreakAfter )
@@ -439,6 +441,8 @@ void SvxCSS1PropertyInfo::Clear()
 
     m_nLeft = m_nTop = m_nWidth = m_nHeight = 0;
     m_eLeftType = m_eTopType = m_eWidthType = m_eHeightType = 
SVX_CSS1_LTYPE_NONE;
+    m_eLeftMarginType = SVX_CSS1_LTYPE_NONE;
+    m_eRightMarginType = SVX_CSS1_LTYPE_NONE;
 
 // Feature: PrintExt
     m_eSizeType = SVX_CSS1_STYPE_NONE;
@@ -2034,6 +2038,12 @@ static void ParseCSS1_margin_left( const CSS1Expression 
*pExpr,
         ;
     }
 
+    if (pExpr->GetString() == "auto")
+    {
+        rPropInfo.m_bLeftMargin = true;
+        rPropInfo.m_eLeftMarginType = SVX_CSS1_LTYPE_AUTO;
+    }
+
     if( bSet )
     {
         rPropInfo.m_nLeftMargin = nLeft;
@@ -2093,6 +2103,12 @@ static void ParseCSS1_margin_right( const CSS1Expression 
*pExpr,
         ;
     }
 
+    if (pExpr->GetString() == "auto")
+    {
+        rPropInfo.m_bRightMargin = true;
+        rPropInfo.m_eRightMarginType = SVX_CSS1_LTYPE_AUTO;
+    }
+
     if( bSet )
     {
         rPropInfo.m_nRightMargin = nRight;
diff --git a/sw/source/filter/html/svxcss1.hxx 
b/sw/source/filter/html/svxcss1.hxx
index 8bc1f47b380a..f0f61638a760 100644
--- a/sw/source/filter/html/svxcss1.hxx
+++ b/sw/source/filter/html/svxcss1.hxx
@@ -136,6 +136,8 @@ public:
 
     SvxCSS1LengthType m_eLeftType, m_eTopType;
     SvxCSS1LengthType m_eWidthType, m_eHeightType;
+    SvxCSS1LengthType m_eLeftMarginType;
+    SvxCSS1LengthType m_eRightMarginType;
 
     SvxCSS1SizeType m_eSizeType;
 
commit a0f0f2b2ca316738e76b5f773779240121c551a8
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Jan 19 15:46:37 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Jan 20 14:59:33 2023 +0100

    sw XHTML export: use CSS instead of <center> for tables
    
    <center> is not valid XHTML, have to use CSS styling instead.
    
    HTML export uses <center> by default around tables where the alignment
    is center.
    
    Fix the problem by avoiding <center> in the XHTML case and set the left
    and right margin to auto, which means:
    
            If the values of margin-left and margin-right are both auto, the
            calculated space is evenly distributed.
    
    according to
    <https://developer.mozilla.org/en-US/docs/Web/CSS/margin-left>.
    
    The import will be adjusted to recognize the new markup in a follow-up
    change.
    
    (cherry picked from commit 6ce374140f3bd1cede959ccc8da69fdacecff191)
    
    Conflicts:
            sw/source/filter/html/htmltabw.cxx
    
    Change-Id: I51e3507e9cde713f961b783378d66db59194a6ca

diff --git a/sw/qa/filter/html/html.cxx b/sw/qa/filter/html/html.cxx
index ef44aa39817a..7ad6bd5b0ffa 100644
--- a/sw/qa/filter/html/html.cxx
+++ b/sw/qa/filter/html/html.cxx
@@ -20,6 +20,7 @@
 #include <itabenum.hxx>
 #include <wrtsh.hxx>
 #include <cellatr.hxx>
+#include <fmtornt.hxx>
 
 namespace
 {
@@ -216,6 +217,37 @@ CPPUNIT_TEST_FIXTURE(Test, testTableRowSpanInAllCells)
     assertXPathNoAttribute(pHtmlDoc, "//tr[1]/td[1]", "rowspan");
     assertXPath(pHtmlDoc, "//tr", 1);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testCenteredTableCSSExport)
+{
+    // Given a document with a centered table:
+    loadURL("private:factory/swriter", nullptr);
+    auto pTextDocument = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    SwDoc* pDoc = pTextDocument->GetDocShell()->GetDoc();
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    SwInsertTableOptions aTableOptions(SwInsertTableFlags::NONE, 0);
+    pWrtShell->InsertTable(aTableOptions, 1, 1);
+    pWrtShell->MoveTable(GotoPrevTable, fnTableStart);
+    SfxItemSet aSet(pDoc->GetAttrPool(), svl::Items<RES_FRMATR_BEGIN, 
RES_FRMATR_END - 1>{});
+    SwFormatHoriOrient aHoriOrientItem(/*nX=*/0, 
text::HoriOrientation::CENTER);
+    aSet.Put(aHoriOrientItem);
+    pWrtShell->SetTableAttr(aSet);
+
+    // When exporting to XHTML:
+    setFilterOptions("xhtmlns=reqif-xhtml");
+    save("HTML (StarWriter)", maTempFile);
+
+    // Then make sure that CSS is used to horizontally position the table:
+    SvMemoryStream aStream;
+    WrapReqifFromTempFile(aStream);
+    xmlDocUniquePtr pXmlDoc = parseXmlStream(&aStream);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 0
+    // - Actual  : 1
+    // i.e <center> was used to position the table, not CSS.
+    assertXPath(pXmlDoc, "//reqif-xhtml:center", 0);
+    assertXPath(pXmlDoc, "//reqif-xhtml:table", "style", "margin-left: auto; 
margin-right: auto");
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/html/css1atr.cxx 
b/sw/source/filter/html/css1atr.cxx
index 8a0bc881e1c8..8138f5e0dcd7 100644
--- a/sw/source/filter/html/css1atr.cxx
+++ b/sw/source/filter/html/css1atr.cxx
@@ -2115,6 +2115,17 @@ void SwHTMLWriter::OutCSS1_TableFrameFormatOptions( 
const SwFrameFormat& rFrameF
     if( SfxItemState::SET==rItemSet.GetItemState( RES_LAYOUT_SPLIT, false, 
&pItem ) )
         OutCSS1_SwFormatLayoutSplit( *this, *pItem );
 
+    if (mbXHTML)
+    {
+        sal_Int16 eTabHoriOri = rFrameFormat.GetHoriOrient().GetHoriOrient();
+        if (eTabHoriOri == text::HoriOrientation::CENTER)
+        {
+            // Emit XHTML's center using inline CSS.
+            OutCSS1_Property(sCSS1_P_margin_left, "auto", nullptr, 
sw::Css1Background::Table);
+            OutCSS1_Property(sCSS1_P_margin_right, "auto", nullptr, 
sw::Css1Background::Table);
+        }
+    }
+
     if( !m_bFirstCSS1Property )
         Strm().WriteChar( '\"' );
 }
diff --git a/sw/source/filter/html/htmltabw.cxx 
b/sw/source/filter/html/htmltabw.cxx
index 5cdbb8a5c205..1150b72d5320 100644
--- a/sw/source/filter/html/htmltabw.cxx
+++ b/sw/source/filter/html/htmltabw.cxx
@@ -1115,7 +1115,13 @@ Writer& OutHTML_SwTableNode( Writer& rWrt, SwTableNode & 
rNode,
         if( rHTMLWrt.m_bLFPossible )
             rHTMLWrt.OutNewLine();  // <CENTER> in new line
         if( text::HoriOrientation::CENTER==eDivHoriOri )
-            HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), rHTMLWrt.GetNamespace() + 
OOO_STRING_SVTOOLS_HTML_center );
+        {
+            if (!rHTMLWrt.mbXHTML)
+            {
+                // Not XHTML's css center: start <center>.
+                HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), 
rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_center );
+            }
+        }
         else
         {
             OString sOut = OOO_STRING_SVTOOLS_HTML_division
@@ -1168,7 +1174,11 @@ Writer& OutHTML_SwTableNode( Writer& rWrt, SwTableNode & 
rNode,
         OString aTag = text::HoriOrientation::CENTER == eDivHoriOri
                            ? OOO_STRING_SVTOOLS_HTML_center
                            : OOO_STRING_SVTOOLS_HTML_division;
-        HTMLOutFuncs::Out_AsciiTag(rWrt.Strm(), rHTMLWrt.GetNamespace() + 
aTag, false);
+        if (!rHTMLWrt.mbXHTML || eDivHoriOri != text::HoriOrientation::CENTER)
+        {
+            // Not XHTML's css center: end <center>.
+            HTMLOutFuncs::Out_AsciiTag(rWrt.Strm(), rHTMLWrt.GetNamespace() + 
aTag, false);
+        }
         rHTMLWrt.m_bLFPossible = true;
     }
 

Reply via email to