sw/CppunitTest_sw_htmlexport.mk         |    1 
 sw/qa/extras/htmlexport/htmlexport.cxx  |   91 +++++++++++++++++++++++++++++++-
 sw/source/filter/html/css1atr.cxx       |   65 ++++++++++++++--------
 sw/source/filter/html/htmlnumwriter.cxx |   12 +++-
 sw/source/filter/html/htmltabw.cxx      |   25 ++++++--
 sw/source/filter/html/wrthtml.hxx       |   27 ++++++++-
 6 files changed, 183 insertions(+), 38 deletions(-)

New commits:
commit 31850ef3505bc15a75c9a9a50ed04f970670b244
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Jun 10 09:12:33 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Jul 1 10:08:46 2022 +0200

    sw XHTML export: avoid writing default transparent background for ReqIF
    
    We started writing properties of tables and rows since commit
    c3c3303516c3da9372dce3f05f38f15a104e961c (sw XHTML export: output table
    / table row background format using CSS, 2022-05-10).
    
    In case the SwTableLine has an explicit SvxBrushItem with its color set
    to COL_TRANSPARENT, we turn that into a "background: transparent" CSS by
    default. This is a 1:1 mapping from the doc model, but HTML defaults to
    this already, so this is considered as noise.
    
    Extend IgnorePropertyForReqIF() to filter out these unwanted defaults,
    and fix SwHTMLWriter::OutCSS1_Property(), because it used to not pass
    the CSS value for the filter function.
    
    The behavior for table cells is unchanged, we continue to not export
    cell properties (in the ReqIF case) at all.
    
    (cherry picked from commit 04cc6e079e3122c183054fde046c054ed6c7b737)
    
    Conflicts:
            sw/source/filter/html/css1atr.cxx
    
    (cherry picked from commit bd1d738e78e5287b35e2d17f84971d44b384425b)
    
    Change-Id: Idbcd07809e159def694f4de017eebc7ad4104575

diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx 
b/sw/qa/extras/htmlexport/htmlexport.cxx
index 535a484dd0e2..cb2d697d7664 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -1641,10 +1641,14 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, 
testTableBackground)
     pWrtShell->SetTabBackground(aBrush);
     pWrtShell->Down(/*bSelect=*/false);
     pWrtShell->SplitNode();
-    pWrtShell->InsertTable(aInsertTableOptions, /*nRows=*/1, /*nCols=*/1);
+    pWrtShell->InsertTable(aInsertTableOptions, /*nRows=*/2, /*nCols=*/1);
     pWrtShell->MoveTable(GotoPrevTable, fnTableStart);
     aBrush.SetColor(0x00ff00);
     pWrtShell->SetRowBackground(aBrush);
+    pWrtShell->Down(/*bSelect=*/false);
+    // Second row has an explicit transparent background.
+    aBrush.SetColor(COL_TRANSPARENT);
+    pWrtShell->SetRowBackground(aBrush);
 
     // When exporting to reqif-xhtml:
     ExportToReqif();
@@ -1661,6 +1665,8 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, 
testTableBackground)
     assertXPath(pXmlDoc, "//reqif-xhtml:table[2]/reqif-xhtml:tr[1]", "style",
                 "background: #00ff00");
     assertXPathNoAttribute(pXmlDoc, 
"//reqif-xhtml:table[2]/reqif-xhtml:tr[1]", "bgcolor");
+    // Second row has no explicit style, the default is not written.
+    assertXPathNoAttribute(pXmlDoc, 
"//reqif-xhtml:table[2]/reqif-xhtml:tr[2]", "style");
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/html/css1atr.cxx 
b/sw/source/filter/html/css1atr.cxx
index eccbbdae4f3d..18ee264324f6 100644
--- a/sw/source/filter/html/css1atr.cxx
+++ b/sw/source/filter/html/css1atr.cxx
@@ -180,9 +180,21 @@ OString lclConvToHex(sal_uInt16 nHex)
 bool IgnorePropertyForReqIF(bool bReqIF, const OString& rProperty, const 
OString& rValue,
                             std::optional<sw::Css1Background> oMode)
 {
-    if (!bReqIF || (oMode.has_value() && *oMode != 
sw::Css1Background::TableCell))
+    if (!bReqIF)
         return false;
 
+    if (oMode.has_value() && *oMode != sw::Css1Background::TableCell)
+    {
+        // Table or row.
+        if (rProperty == sCSS1_P_background && rValue == "transparent")
+        {
+            // This is the default already.
+            return true;
+        }
+
+        return false;
+    }
+
     // Only allow these two keys, nothing else in ReqIF mode.
     if (rProperty == sCSS1_P_text_decoration)
     {
@@ -239,7 +251,12 @@ void SwHTMLWriter::OutCSS1_Property( const char *pProp,
                                      const OUString *pSVal,
                                      std::optional<sw::Css1Background> oMode )
 {
-    if (IgnorePropertyForReqIF(mbReqIF, pProp, pVal, oMode))
+    OString aPropertyValue(pVal);
+    if (aPropertyValue.isEmpty() && pSVal)
+    {
+        aPropertyValue = pSVal->toUtf8();
+    }
+    if (IgnorePropertyForReqIF(mbReqIF, pProp, aPropertyValue, oMode))
         return;
 
     OStringBuffer sOut;
commit efe41847428e61a8456706861ddf880a36b816a0
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Jun 10 08:08:52 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Jul 1 10:07:18 2022 +0200

    sw XHTML export: avoid writing background of table cells in ReqIF mode
    
    ReqIF mostly forbids using CSS styling on elements:
    IgnorePropertyForReqIF() only allows 2 CSS keys by default.
    
    This restriction was relaxed in commit
    c3c3303516c3da9372dce3f05f38f15a104e961c (sw XHTML export: output table
    / table row background format using CSS, 2022-05-10), to allow
    background for tables and table rows, using CSS markup. An unwanted side
    effect of this is background for table cells, which is still considered
    invalid. To make this nontrivial to fix, Css1Background::Table is used
    to track formatting for all of tables, rows and cells.
    
    Fix the problem by extending Css1Background with a TableRow and
    TableCell and then audit all uses of Css1Background::Table to explicitly
    say if they mean table, row or cell. This keeps table and row
    backgrounds, but fixes the unwanted cell background.
    
    Also document the 3 functions doing the export of table / row / cell
    background export to improve readability.
    
    (cherry picked from commit d701eff3519287db599a2612a635bc5f610ba082)
    
    Conflicts:
            sw/source/filter/html/css1atr.cxx
            sw/source/filter/html/wrthtml.hxx
    
    (cherry picked from commit 35b05d6d2dcbae2fc10f979fe7d8a43b3686a26e)
    
    Change-Id: I03301b1fd25593cbe83489dbf140e80138d4a0de

diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx 
b/sw/qa/extras/htmlexport/htmlexport.cxx
index f0792a197a52..535a484dd0e2 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -701,9 +701,8 @@ DECLARE_HTMLEXPORT_TEST(testReqIfTable, "reqif-table.xhtml")
     // <div> was missing, so the XHTML fragment wasn't a valid
     // xhtml.BlkStruct.class type anymore.
     assertXPath(pDoc, "/html/body/div/table/tr/th", 1);
-    // Make sure that row background is written using CSS.
-    OUString aStyle = getXPath(pDoc, "/html/body/div/table/tr/th", "style");
-    CPPUNIT_ASSERT(aStyle.startsWith("background: "));
+    // Make sure that the cell background is not written using CSS.
+    assertXPathNoAttribute(pDoc, "/html/body/div/table/tr/th", "style");
     // The attribute was present, which is not valid in reqif-xhtml.
     assertXPathNoAttribute(pDoc, "/html/body/div/table/tr/th", "bgcolor");
 }
diff --git a/sw/source/filter/html/css1atr.cxx 
b/sw/source/filter/html/css1atr.cxx
index 368f97926656..eccbbdae4f3d 100644
--- a/sw/source/filter/html/css1atr.cxx
+++ b/sw/source/filter/html/css1atr.cxx
@@ -97,14 +97,6 @@ using editeng::SvxBorderLine;
 
 namespace {
 
-enum class Css1Background {
-    Attr    = 1,
-    Page    = 2,
-    Table   = 3,
-    Fly     = 4,
-    Section = 5
-};
-
 enum class Css1FrameSize {
     NONE       = 0x00,
     Width      = 0x01,
@@ -148,7 +140,7 @@ static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
 static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
                                         const SfxItemSet& rItemSet );
 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt,
-                                 Css1Background nMode,
+                                 sw::Css1Background nMode,
                                  const OUString *pGraphicName );
 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt );
 static Writer& OutCSS1_SwFormatFrameSize( Writer& rWrt, const SfxPoolItem& rHt,
@@ -186,9 +178,9 @@ OString lclConvToHex(sal_uInt16 nHex)
 }
 
 bool IgnorePropertyForReqIF(bool bReqIF, const OString& rProperty, const 
OString& rValue,
-                            bool bTable)
+                            std::optional<sw::Css1Background> oMode)
 {
-    if (!bReqIF || bTable)
+    if (!bReqIF || (oMode.has_value() && *oMode != 
sw::Css1Background::TableCell))
         return false;
 
     // Only allow these two keys, nothing else in ReqIF mode.
@@ -245,9 +237,9 @@ public:
 void SwHTMLWriter::OutCSS1_Property( const char *pProp,
                                      const char *pVal,
                                      const OUString *pSVal,
-                                     bool bTable )
+                                     std::optional<sw::Css1Background> oMode )
 {
-    if (IgnorePropertyForReqIF(mbReqIF, pProp, pVal, bTable))
+    if (IgnorePropertyForReqIF(mbReqIF, pProp, pVal, oMode))
         return;
 
     OStringBuffer sOut;
@@ -1813,7 +1805,7 @@ Writer& OutCSS1_BodyTagStyleOpt( Writer& rWrt, const 
SfxItemSet& rItemSet )
                                                &pItem ) )
     {
         OUString rEmbeddedGraphicName;
-        OutCSS1_SvxBrush( rWrt, *pItem, Css1Background::Page, 
&rEmbeddedGraphicName );
+        OutCSS1_SvxBrush( rWrt, *pItem, sw::Css1Background::Page, 
&rEmbeddedGraphicName );
     }
 
     if( SfxItemState::SET == rItemSet.GetItemState( RES_BOX, false,
@@ -1843,7 +1835,6 @@ Writer& OutCSS1_ParaTagStyleOpt( Writer& rWrt, const 
SfxItemSet& rItemSet )
     return rWrt;
 }
 
-// Wrapper for Table background
 Writer& OutCSS1_TableBGStyleOpt( Writer& rWrt, const SfxPoolItem& rHt )
 {
     SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
@@ -1851,7 +1842,7 @@ Writer& OutCSS1_TableBGStyleOpt( Writer& rWrt, const 
SfxPoolItem& rHt )
     SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON |
                                    CSS1_OUTMODE_ENCODE|
                                    CSS1_OUTMODE_TABLEBOX, nullptr );
-    OutCSS1_SvxBrush( rWrt, rHt, Css1Background::Table, nullptr );
+    OutCSS1_SvxBrush( rWrt, rHt, sw::Css1Background::TableRow, nullptr );
 
     if( !rHTMLWrt.m_bFirstCSS1Property )
         rWrt.Strm().WriteChar( '\"' );
@@ -2099,7 +2090,7 @@ void SwHTMLWriter::OutCSS1_TableFrameFormatOptions( const 
SwFrameFormat& rFrameF
     const SfxPoolItem *pItem;
     const SfxItemSet& rItemSet = rFrameFormat.GetAttrSet();
     if( SfxItemState::SET==rItemSet.GetItemState( RES_BACKGROUND, false, 
&pItem ) )
-        OutCSS1_SvxBrush( *this, *pItem, Css1Background::Table, nullptr );
+        OutCSS1_SvxBrush( *this, *pItem, sw::Css1Background::Table, nullptr );
 
     if( IsHTMLMode( HTMLMODE_PRINT_EXT ) )
         OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( *this, rItemSet, 
false );
@@ -2116,7 +2107,7 @@ void 
SwHTMLWriter::OutCSS1_TableCellBordersAndBG(SwFrameFormat const& rFrameForm
     SwCSS1OutMode const aMode( *this,
         CSS1_OUTMODE_STYLE_OPT_ON|CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_TABLEBOX, 
nullptr );
     if (pBrushItem)
-        OutCSS1_SvxBrush(*this, *pBrushItem, Css1Background::Table, nullptr);
+        OutCSS1_SvxBrush(*this, *pBrushItem, sw::Css1Background::TableCell, 
nullptr);
     OutCSS1_SvxBox(*this, rFrameFormat.GetBox());
     if (!m_bFirstCSS1Property)
     {
@@ -2133,7 +2124,7 @@ void SwHTMLWriter::OutCSS1_SectionFormatOptions( const 
SwFrameFormat& rFrameForm
     const SfxPoolItem *pItem;
     const SfxItemSet& rItemSet = rFrameFormat.GetAttrSet();
     if( SfxItemState::SET==rItemSet.GetItemState( RES_BACKGROUND, false, 
&pItem ) )
-        OutCSS1_SvxBrush( *this, *pItem, Css1Background::Section, nullptr );
+        OutCSS1_SvxBrush( *this, *pItem, sw::Css1Background::Section, nullptr 
);
 
     if (pCol)
     {
@@ -2155,7 +2146,7 @@ static bool OutCSS1_FrameFormatBrush( SwHTMLWriter& rWrt,
         !rBrushItem.GetGraphicLink().isEmpty() ||
         0 != rBrushItem.GetGraphicPos() )
     {
-        OutCSS1_SvxBrush( rWrt, rBrushItem, Css1Background::Fly, nullptr );
+        OutCSS1_SvxBrush( rWrt, rBrushItem, sw::Css1Background::Fly, nullptr );
         bWritten = true;
     }
     return bWritten;
@@ -3132,12 +3123,12 @@ static Writer& 
OutCSS1_SvxFormatBreak_SwFormatPDesc_SvxFormatKeep( Writer& rWrt,
 // Wrapper for OutCSS1_SfxItemSet etc.
 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt )
 {
-    OutCSS1_SvxBrush( rWrt, rHt, Css1Background::Attr, nullptr );
+    OutCSS1_SvxBrush( rWrt, rHt, sw::Css1Background::Attr, nullptr );
     return rWrt;
 }
 
 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt,
-                                 Css1Background nMode,
+                                 sw::Css1Background nMode,
                                  const OUString* pGraphicName)
 {
     SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
@@ -3154,7 +3145,7 @@ static Writer& OutCSS1_SvxBrush( Writer& rWrt, const 
SfxPoolItem& rHt,
     OUString aLink = pGraphicName ? *pGraphicName
                             : static_cast<const SvxBrushItem 
&>(rHt).GetGraphicLink();
     SvxGraphicPosition ePos = static_cast<const SvxBrushItem 
&>(rHt).GetGraphicPos();
-    if( Css1Background::Page == nMode && !rHTMLWrt.mbEmbedImages )
+    if( sw::Css1Background::Page == nMode && !rHTMLWrt.mbEmbedImages )
     {
         // page style images are exported if not tiled
         if( aLink.isEmpty() || GPOS_TILED==ePos )
@@ -3197,7 +3188,7 @@ static Writer& OutCSS1_SvxBrush( Writer& rWrt, const 
SfxPoolItem& rHt,
         aLink = aGraphicAsLink;
     }
     // In tables we only export something if there is a Graphic
-    if( Css1Background::Table==nMode && !pGrf && !aLink.isEmpty())
+    if( (nMode == sw::Css1Background::Table || nMode == 
sw::Css1Background::TableRow) && !pGrf && !aLink.isEmpty())
         return rWrt;
 
     // if necessary, add the orientation of the Graphic
@@ -3268,7 +3259,7 @@ static Writer& OutCSS1_SvxBrush( Writer& rWrt, const 
SfxPoolItem& rHt,
     if( !pGrf && aLink.isEmpty() && !bColor )
     {
         // no color and no Link, but a transparent Brush
-        if( bTransparent && Css1Background::Fly != nMode )
+        if( bTransparent && sw::Css1Background::Fly != nMode )
             sOut += OStringToOUString(sCSS1_PV_transparent, 
RTL_TEXTENCODING_ASCII_US);
     }
     else
@@ -3315,8 +3306,10 @@ static Writer& OutCSS1_SvxBrush( Writer& rWrt, const 
SfxPoolItem& rHt,
     }
 
     if( !sOut.isEmpty() )
+    {
         rHTMLWrt.OutCSS1_Property(sCSS1_P_background, nullptr, &sOut,
-                                  nMode == Css1Background::Table);
+                                  nMode);
+    }
 
     return rWrt;
 }
diff --git a/sw/source/filter/html/wrthtml.hxx 
b/sw/source/filter/html/wrthtml.hxx
index 43e657261b31..ef5226f95674 100644
--- a/sw/source/filter/html/wrthtml.hxx
+++ b/sw/source/filter/html/wrthtml.hxx
@@ -253,6 +253,20 @@ typedef std::set<std::unique_ptr<SwHTMLFormatInfo>,
 
 class IDocumentStylePoolAccess;
 
+namespace sw
+{
+enum class Css1Background
+{
+    Attr = 1,
+    Page = 2,
+    Table = 3,
+    Fly = 4,
+    Section = 5,
+    TableRow = 6,
+    TableCell = 7,
+};
+}
+
 class SW_DLLPUBLIC SwHTMLWriter : public Writer
 {
     std::unique_ptr<SwHTMLPosFlyFrames> m_pHTMLPosFlyFrames;
@@ -457,7 +471,7 @@ public:
                                        const OString& rVal );
     inline void OutCSS1_Property( const char *pProp, const OUString& rVal );
     void OutCSS1_Property( const char *pProp, const char *pVal,
-                           const OUString *pSVal, bool bTable = false );
+                           const OUString *pSVal, 
std::optional<sw::Css1Background> oBackground = std::nullopt );
     void OutCSS1_UnitProperty( const char *pProp, long nVal );
     void OutCSS1_PixelProperty( const char *pProp, long nVal, bool bVert );
     void OutCSS1_SfxItemSet( const SfxItemSet& rItemSet, bool bDeep=true );
@@ -483,8 +497,12 @@ public:
 
     void writeFrameFormatOptions(HtmlWriter& aHtml, const SwFrameFormat& 
rFrameFormat, const OUString& rAltText, HtmlFrmOpts nFrameOpts);
 
+    /// Writes the formatting for tables.
     void OutCSS1_TableFrameFormatOptions( const SwFrameFormat& rFrameFormat );
+
+    /// Writes the borders and background for table cells.
     void OutCSS1_TableCellBordersAndBG(const SwFrameFormat& rFrameFormat, 
const SvxBrushItem *pBrushItem);
+
     void OutCSS1_SectionFormatOptions( const SwFrameFormat& rFrameFormat, 
const SwFormatCol *pCol );
     void OutCSS1_FrameFormatOptions( const SwFrameFormat& rFrameFormat, 
HtmlFrmOpts nFrameOpts,
                                      const SdrObject *pSdrObj=nullptr,
@@ -684,7 +702,9 @@ Writer& OutCSS1_ParaTagStyleOpt( Writer& rWrt, const 
SfxItemSet& rItemSet );
 Writer& OutCSS1_HintSpanTag( Writer& rWrt, const SfxPoolItem& rHt );
 Writer& OutCSS1_HintStyleOpt( Writer& rWrt, const SfxPoolItem& rHt );
 
+/// Writes the background of table rows.
 Writer& OutCSS1_TableBGStyleOpt( Writer& rWrt, const SfxPoolItem& rHt );
+
 Writer& OutCSS1_NumberBulletListStyleOpt( Writer& rWrt, const SwNumRule& 
rNumRule,
                                     sal_uInt8 nLevel );
 
@@ -699,7 +719,7 @@ OString GetCSS1_Color(const Color& rColor);
 
 /// Determines if rProperty with a given rValue has to be suppressed due to 
ReqIF mode.
 bool IgnorePropertyForReqIF(bool bReqIF, const OString& rProperty, const 
OString& rValue,
-                            bool bTable = false);
+                            std::optional<sw::Css1Background> oBackground = 
std::nullopt);
 
 #endif // INCLUDED_SW_SOURCE_FILTER_HTML_WRTHTML_HXX
 
commit ff1f64b8019a6ac1f2d28105155c335191c537ad
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Thu Aug 12 12:55:30 2021 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Jul 1 10:04:53 2022 +0200

    Resolves: tdf#132739 two style tags where there should be just one
    
    (cherry picked from commit 6833e0c0af09637bb410dc800435dcc6c8333680)
    
    (cherry picked from commit 766b501cf48440d042b598215e101e5851743b09)
    
    Change-Id: Id9c8c8cc8c5ffdd21ba79ff39a6279cf2ddc8025

diff --git a/sw/source/filter/html/css1atr.cxx 
b/sw/source/filter/html/css1atr.cxx
index b2d5aecb9e78..368f97926656 100644
--- a/sw/source/filter/html/css1atr.cxx
+++ b/sw/source/filter/html/css1atr.cxx
@@ -2111,10 +2111,12 @@ void SwHTMLWriter::OutCSS1_TableFrameFormatOptions( 
const SwFrameFormat& rFrameF
         Strm().WriteChar( '\"' );
 }
 
-void SwHTMLWriter::OutCSS1_TableCellBorderHack(SwFrameFormat const& 
rFrameFormat)
+void SwHTMLWriter::OutCSS1_TableCellBordersAndBG(SwFrameFormat const& 
rFrameFormat, const SvxBrushItem *pBrushItem)
 {
     SwCSS1OutMode const aMode( *this,
         CSS1_OUTMODE_STYLE_OPT_ON|CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_TABLEBOX, 
nullptr );
+    if (pBrushItem)
+        OutCSS1_SvxBrush(*this, *pBrushItem, Css1Background::Table, nullptr);
     OutCSS1_SvxBox(*this, rFrameFormat.GetBox());
     if (!m_bFirstCSS1Property)
     {
diff --git a/sw/source/filter/html/htmltabw.cxx 
b/sw/source/filter/html/htmltabw.cxx
index 46632157af43..dea6d9d01b62 100644
--- a/sw/source/filter/html/htmltabw.cxx
+++ b/sw/source/filter/html/htmltabw.cxx
@@ -430,11 +430,14 @@ void SwHTMLWrtTable::OutTableCell( SwHTMLWriter& rWrt,
             // Avoid non-CSS version in the ReqIF case.
             rWrt.OutBackground( pBrushItem, false );
 
-        if( rWrt.m_bCfgOutStyles )
-            OutCSS1_TableBGStyleOpt( rWrt, *pBrushItem );
+        if (!rWrt.m_bCfgOutStyles)
+            pBrushItem = nullptr;
     }
 
-    rWrt.OutCSS1_TableCellBorderHack(*pBox->GetFrameFormat());
+    // tdf#132739 with rWrt.m_bCfgOutStyles of true bundle the brush item css
+    // properties into the same "style" tag as the borders so there is only one
+    // style tag
+    rWrt.OutCSS1_TableCellBordersAndBG(*pBox->GetFrameFormat(), pBrushItem);
 
     sal_uInt32 nNumFormat = 0;
     double nValue = 0.0;
diff --git a/sw/source/filter/html/wrthtml.hxx 
b/sw/source/filter/html/wrthtml.hxx
index 66f1b6a57198..43e657261b31 100644
--- a/sw/source/filter/html/wrthtml.hxx
+++ b/sw/source/filter/html/wrthtml.hxx
@@ -484,7 +484,7 @@ public:
     void writeFrameFormatOptions(HtmlWriter& aHtml, const SwFrameFormat& 
rFrameFormat, const OUString& rAltText, HtmlFrmOpts nFrameOpts);
 
     void OutCSS1_TableFrameFormatOptions( const SwFrameFormat& rFrameFormat );
-    void OutCSS1_TableCellBorderHack(const SwFrameFormat& rFrameFormat);
+    void OutCSS1_TableCellBordersAndBG(const SwFrameFormat& rFrameFormat, 
const SvxBrushItem *pBrushItem);
     void OutCSS1_SectionFormatOptions( const SwFrameFormat& rFrameFormat, 
const SwFormatCol *pCol );
     void OutCSS1_FrameFormatOptions( const SwFrameFormat& rFrameFormat, 
HtmlFrmOpts nFrameOpts,
                                      const SdrObject *pSdrObj=nullptr,
commit 4f26bf4c1382d7c32dc61be15db92a2503628b9c
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue May 10 16:15:52 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Jul 1 10:03:07 2022 +0200

    sw XHTML export: output table / table row background format using CSS
    
    The HTML export uses HTML elements / attributes to describe the
    background color of tables / table rows. CSS markup is used when
    exporting styles, not direct formatting.
    
    This behavior makes sense for the HTML mode, but XHTML wants to CSS
    markup whenever possible, and usage of CSS markup for the reqif mode is
    not even optional.
    
    Fix the problem by switching to CSS markup for table and table row
    backgrounds in the XHTML case -- this is OK for reqif when describing
    tables (the reqif spec only forbids detailed CSS markup for spans, not
    tables or table rows).
    
    This amends the behavior of commit
    4cd3c436923bfba281b1bf16d9785208a2119cea (sw reqif-xhtml export: limit
    values of the style attribute, 2018-04-11), which avoided invalid table
    row background markup by losing it on export.
    
    (cherry picked from commit c3c3303516c3da9372dce3f05f38f15a104e961c)
    
    Conflicts:
            sw/qa/extras/htmlexport/htmlexport.cxx
            sw/source/filter/html/css1atr.cxx
            sw/source/filter/html/wrthtml.hxx
    
    (cherry picked from commit e14b6d2e63990c7571c0a4f0f1a767d5955055fb)
    
    Conflicts:
            sw/qa/extras/htmlexport/htmlexport.cxx
    
    Change-Id: Ia0858986c3e8a3ea41adf8a24119442fe5068ee3

diff --git a/sw/CppunitTest_sw_htmlexport.mk b/sw/CppunitTest_sw_htmlexport.mk
index 3315566bb087..efa4a82d807f 100644
--- a/sw/CppunitTest_sw_htmlexport.mk
+++ b/sw/CppunitTest_sw_htmlexport.mk
@@ -21,6 +21,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_htmlexport, \
     comphelper \
     cppu \
        cppuhelper \
+       editeng \
        i18nlangtag \
        msfilter \
     sal \
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx 
b/sw/qa/extras/htmlexport/htmlexport.cxx
index ca66e36fff8e..f0792a197a52 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -39,6 +39,9 @@
 #include <sot/storage.hxx>
 #include <svl/eitem.hxx>
 #include <vcl/dibtools.hxx>
+#include <editeng/brushitem.hxx>
+
+#include <itabenum.hxx>
 
 namespace
 {
@@ -698,9 +701,9 @@ DECLARE_HTMLEXPORT_TEST(testReqIfTable, "reqif-table.xhtml")
     // <div> was missing, so the XHTML fragment wasn't a valid
     // xhtml.BlkStruct.class type anymore.
     assertXPath(pDoc, "/html/body/div/table/tr/th", 1);
-    // The attribute was present to contain "background" and "border", which is
-    // ignored in reqif-xhtml.
-    assertXPathNoAttribute(pDoc, "/html/body/div/table/tr/th", "style");
+    // Make sure that row background is written using CSS.
+    OUString aStyle = getXPath(pDoc, "/html/body/div/table/tr/th", "style");
+    CPPUNIT_ASSERT(aStyle.startsWith("background: "));
     // The attribute was present, which is not valid in reqif-xhtml.
     assertXPathNoAttribute(pDoc, "/html/body/div/table/tr/th", "bgcolor");
 }
@@ -1623,6 +1626,44 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, 
testNestedBullets)
         "second");
 }
 
+CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testTableBackground)
+{
+    // Given a document with two tables: first stable has a background, second 
table has a
+    // background in its first row:
+    loadURL("private:factory/swriter", nullptr);
+    SwXTextDocument* pTextDoc = 
dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    SwInsertTableOptions aInsertTableOptions(SwInsertTableFlags::DefaultBorder,
+                                             /*nRowsToRepeat=*/0);
+    pWrtShell->InsertTable(aInsertTableOptions, /*nRows=*/1, /*nCols=*/1);
+    pWrtShell->MoveTable(GotoPrevTable, fnTableStart);
+    SvxBrushItem aBrush(Color(0xff0000), RES_BACKGROUND);
+    pWrtShell->SetTabBackground(aBrush);
+    pWrtShell->Down(/*bSelect=*/false);
+    pWrtShell->SplitNode();
+    pWrtShell->InsertTable(aInsertTableOptions, /*nRows=*/1, /*nCols=*/1);
+    pWrtShell->MoveTable(GotoPrevTable, fnTableStart);
+    aBrush.SetColor(0x00ff00);
+    pWrtShell->SetRowBackground(aBrush);
+
+    // When exporting to reqif-xhtml:
+    ExportToReqif();
+
+    // Then make sure that CSS markup is used, not HTML one:
+    SvMemoryStream aStream;
+    HtmlExportTest::wrapFragment(maTempFile, aStream);
+    xmlDocUniquePtr pXmlDoc = parseXmlStream(&aStream);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - XPath '//reqif-xhtml:table[1]' no attribute 'style' exist
+    // i.e. HTML markup was used for the table background color.
+    assertXPath(pXmlDoc, "//reqif-xhtml:table[1]", "style", "background: 
#ff0000");
+    assertXPathNoAttribute(pXmlDoc, "//reqif-xhtml:table[1]", "bgcolor");
+    assertXPath(pXmlDoc, "//reqif-xhtml:table[2]/reqif-xhtml:tr[1]", "style",
+                "background: #00ff00");
+    assertXPathNoAttribute(pXmlDoc, 
"//reqif-xhtml:table[2]/reqif-xhtml:tr[1]", "bgcolor");
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/html/css1atr.cxx 
b/sw/source/filter/html/css1atr.cxx
index 9d773603a1ab..b2d5aecb9e78 100644
--- a/sw/source/filter/html/css1atr.cxx
+++ b/sw/source/filter/html/css1atr.cxx
@@ -185,9 +185,10 @@ OString lclConvToHex(sal_uInt16 nHex)
 }
 }
 
-bool IgnorePropertyForReqIF(bool bReqIF, const OString& rProperty, const 
OString& rValue)
+bool IgnorePropertyForReqIF(bool bReqIF, const OString& rProperty, const 
OString& rValue,
+                            bool bTable)
 {
-    if (!bReqIF)
+    if (!bReqIF || bTable)
         return false;
 
     // Only allow these two keys, nothing else in ReqIF mode.
@@ -243,9 +244,10 @@ public:
 
 void SwHTMLWriter::OutCSS1_Property( const char *pProp,
                                      const char *pVal,
-                                     const OUString *pSVal )
+                                     const OUString *pSVal,
+                                     bool bTable )
 {
-    if (IgnorePropertyForReqIF(mbReqIF, pProp, pVal))
+    if (IgnorePropertyForReqIF(mbReqIF, pProp, pVal, bTable))
         return;
 
     OStringBuffer sOut;
@@ -3311,7 +3313,8 @@ static Writer& OutCSS1_SvxBrush( Writer& rWrt, const 
SfxPoolItem& rHt,
     }
 
     if( !sOut.isEmpty() )
-        rHTMLWrt.OutCSS1_Property( sCSS1_P_background, sOut );
+        rHTMLWrt.OutCSS1_Property(sCSS1_P_background, nullptr, &sOut,
+                                  nMode == Css1Background::Table);
 
     return rWrt;
 }
diff --git a/sw/source/filter/html/htmltabw.cxx 
b/sw/source/filter/html/htmltabw.cxx
index 1febebd9ff34..46632157af43 100644
--- a/sw/source/filter/html/htmltabw.cxx
+++ b/sw/source/filter/html/htmltabw.cxx
@@ -533,11 +533,14 @@ void SwHTMLWrtTable::OutTableCells( SwHTMLWriter& rWrt,
     rWrt.Strm().WriteChar( '<' ).WriteOString( rWrt.GetNamespace() + 
OOO_STRING_SVTOOLS_HTML_tablerow );
     if( pBrushItem )
     {
-        rWrt.OutBackground( pBrushItem, false );
+        if (!rWrt.mbXHTML)
+        {
+            rWrt.OutBackground(pBrushItem, false);
+        }
 
         rWrt.m_bTextAttr = false;
         rWrt.m_bOutOpts = true;
-        if( rWrt.m_bCfgOutStyles )
+        if (rWrt.m_bCfgOutStyles || rWrt.mbXHTML)
             OutCSS1_TableBGStyleOpt( rWrt, *pBrushItem );
     }
 
@@ -702,10 +705,15 @@ void SwHTMLWrtTable::Write( SwHTMLWriter& rWrt, sal_Int16 
eAlign,
     // output background
     if( pFrameFormat )
     {
-        rWrt.OutBackground( pFrameFormat->GetAttrSet(), false );
+        if (!rWrt.mbXHTML)
+        {
+            rWrt.OutBackground(pFrameFormat->GetAttrSet(), false);
+        }
 
-        if (rWrt.m_bCfgOutStyles)
+        if (rWrt.m_bCfgOutStyles || rWrt.mbXHTML)
+        {
             rWrt.OutCSS1_TableFrameFormatOptions( *pFrameFormat );
+        }
     }
 
     sOut.append('>');
diff --git a/sw/source/filter/html/wrthtml.hxx 
b/sw/source/filter/html/wrthtml.hxx
index ffc416f22662..66f1b6a57198 100644
--- a/sw/source/filter/html/wrthtml.hxx
+++ b/sw/source/filter/html/wrthtml.hxx
@@ -457,7 +457,7 @@ public:
                                        const OString& rVal );
     inline void OutCSS1_Property( const char *pProp, const OUString& rVal );
     void OutCSS1_Property( const char *pProp, const char *pVal,
-                           const OUString *pSVal );
+                           const OUString *pSVal, bool bTable = false );
     void OutCSS1_UnitProperty( const char *pProp, long nVal );
     void OutCSS1_PixelProperty( const char *pProp, long nVal, bool bVert );
     void OutCSS1_SfxItemSet( const SfxItemSet& rItemSet, bool bDeep=true );
@@ -698,7 +698,8 @@ Writer& OutCSS1_SvxBox( Writer& rWrt, const SfxPoolItem& 
rHt );
 OString GetCSS1_Color(const Color& rColor);
 
 /// Determines if rProperty with a given rValue has to be suppressed due to 
ReqIF mode.
-bool IgnorePropertyForReqIF(bool bReqIF, const OString& rProperty, const 
OString& rValue);
+bool IgnorePropertyForReqIF(bool bReqIF, const OString& rProperty, const 
OString& rValue,
+                            bool bTable = false);
 
 #endif // INCLUDED_SW_SOURCE_FILTER_HTML_WRTHTML_HXX
 
commit 3dc5b937736d4dedb2e02120df12b75740460e8e
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Mon Oct 11 16:46:21 2021 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Jul 1 09:59:35 2022 +0200

    sw XHTML export: fix missing <li> around nested <ul>/<ol>
    
    This was fine in practice in the HTML case, so make it conditional on
    the XHTML flag for now.
    
    (cherry picked from commit 869e554a017d57da14b0c5b1e1f6ce742db316e0)
    
    Conflicts:
            sw/source/filter/html/htmlnumwriter.cxx
    
    (cherry picked from commit f6db057a505bc2a9fab66004f35b48bc89c72340)
    
    Conflicts:
            sw/qa/extras/htmlexport/htmlexport.cxx
            sw/source/filter/html/htmlnumwriter.cxx
    
    Change-Id: Ie96357ba78f4a7fae125165c1c4e47c3f5686ddf

diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx 
b/sw/qa/extras/htmlexport/htmlexport.cxx
index cf64738d0e40..ca66e36fff8e 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -1582,6 +1582,47 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, 
testReqifOleBmpTransparent)
     CPPUNIT_ASSERT_EQUAL(COL_WHITE, nActualColor);
 }
 
+CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testNestedBullets)
+{
+    // Given a documented with nested lists:
+    loadURL("private:factory/swriter", nullptr);
+    SwXTextDocument* pTextDoc = 
dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
+    SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
+    pWrtShell->Insert("first");
+    sal_uInt16 nPos = pDoc->MakeNumRule(pDoc->GetUniqueNumRuleName());
+    SwNumRule* pNumRule = pDoc->GetNumRuleTable()[nPos];
+    {
+        SwNode& rNode = pWrtShell->GetCursor()->GetPoint()->nNode.GetNode();
+        SwTextNode& rTextNode = *rNode.GetTextNode();
+        rTextNode.SetAttr(SwNumRuleItem(pNumRule->GetName()));
+        rTextNode.SetAttrListLevel(0);
+    }
+    pWrtShell->SplitNode();
+    pWrtShell->Insert("second");
+    {
+        SwNode& rNode = pWrtShell->GetCursor()->GetPoint()->nNode.GetNode();
+        SwTextNode& rTextNode = *rNode.GetTextNode();
+        rTextNode.SetAttr(SwNumRuleItem(pNumRule->GetName()));
+        rTextNode.SetAttrListLevel(1);
+    }
+
+    // When exporting to xhtml:
+    ExportToReqif();
+
+    // Then make sure that there is a <li> between the outer and the inner 
<ol>:
+    SvMemoryStream aStream;
+    HtmlExportTest::wrapFragment(maTempFile, aStream);
+    xmlDocUniquePtr pXmlDoc = parseXmlStream(&aStream);
+    CPPUNIT_ASSERT(pDoc);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - XPath 
'//reqif-xhtml:ol/reqif-xhtml:li/reqif-xhtml:ol/reqif-xhtml:li/reqif-xhtml:p' 
not found
+    // i.e. the <li> inside the outer <ol> was missing.
+    assertXPathContent(
+        pXmlDoc, 
"//reqif-xhtml:ol/reqif-xhtml:li/reqif-xhtml:ol/reqif-xhtml:li/reqif-xhtml:p",
+        "second");
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/html/htmlnumwriter.cxx 
b/sw/source/filter/html/htmlnumwriter.cxx
index 7e2583a48583..965f7ccbfd70 100644
--- a/sw/source/filter/html/htmlnumwriter.cxx
+++ b/sw/source/filter/html/htmlnumwriter.cxx
@@ -208,11 +208,15 @@ Writer& OutHTML_NumberBulletListStart( SwHTMLWriter& rWrt,
 
         rWrt.m_aBulletGrfs[i].clear();
         OString sOut = "<" + rWrt.GetNamespace();
+        if (rWrt.mbXHTML && (nPrevDepth != 0 || i != 0))
+        {
+            sOut += OOO_STRING_SVTOOLS_HTML_li "><" + rWrt.GetNamespace();
+        }
         const SwNumFormat& rNumFormat = rInfo.GetNumRule()->Get( i );
         sal_Int16 eType = rNumFormat.GetNumberingType();
         if( SVX_NUM_CHAR_SPECIAL == eType )
         {
-            // ordered list: <OL>
+            // unordered list: <UL>
             sOut += OString(OOO_STRING_SVTOOLS_HTML_unorderlist);
 
             // determine the type by the bullet character
@@ -390,6 +394,12 @@ Writer& OutHTML_NumberBulletListEnd( SwHTMLWriter& rWrt,
         else
             aTag = OOO_STRING_SVTOOLS_HTML_orderlist;
         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), rWrt.GetNamespace() + aTag, 
false );
+        if (rWrt.mbXHTML && (nNextDepth != 0 || i != 1))
+        {
+            HTMLOutFuncs::Out_AsciiTag(
+                rWrt.Strm(), rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_li,
+                /*bOn=*/false);
+        }
         rWrt.m_bLFPossible = true;
     }
 

Reply via email to