sw/qa/extras/htmlexport/htmlexport.cxx | 5 +-- sw/source/filter/html/css1atr.cxx | 45 +++++++++++++-------------------- sw/source/filter/html/wrthtml.hxx | 24 ++++++++++++++++- 3 files changed, 43 insertions(+), 31 deletions(-)
New commits: commit d701eff3519287db599a2612a635bc5f610ba082 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Fri Jun 10 08:08:52 2022 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Jun 10 09:01:04 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. Change-Id: I03301b1fd25593cbe83489dbf140e80138d4a0de Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135570 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx index e823632f08ea..6ca8c80699ea 100644 --- a/sw/qa/extras/htmlexport/htmlexport.cxx +++ b/sw/qa/extras/htmlexport/htmlexport.cxx @@ -804,9 +804,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 6f3a6f3270ff..9619002314af 100644 --- a/sw/source/filter/html/css1atr.cxx +++ b/sw/source/filter/html/css1atr.cxx @@ -103,14 +103,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, @@ -153,7 +145,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, @@ -191,9 +183,9 @@ OString lclConvToHex(sal_uInt16 nHex) } bool IgnorePropertyForReqIF(bool bReqIF, std::string_view rProperty, std::string_view 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. @@ -250,9 +242,9 @@ public: void SwHTMLWriter::OutCSS1_Property( const char *pProp, std::string_view sVal, const OUString *pSVal, - bool bTable ) + std::optional<sw::Css1Background> oMode ) { - if (IgnorePropertyForReqIF(mbReqIF, pProp, sVal, bTable)) + if (IgnorePropertyForReqIF(mbReqIF, pProp, sVal, oMode)) return; OStringBuffer sOut; @@ -1760,7 +1752,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, @@ -1790,7 +1782,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); @@ -1798,7 +1789,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(cCSS1_style_opt_end); @@ -2046,7 +2037,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 ); @@ -2063,7 +2054,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) Strm().WriteChar(cCSS1_style_opt_end); @@ -2078,7 +2069,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) { @@ -2100,7 +2091,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; @@ -3027,12 +3018,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); @@ -3049,7 +3040,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 ) @@ -3091,7 +3082,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 @@ -3162,7 +3153,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 @@ -3209,8 +3200,10 @@ static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt, } if( !sOut.isEmpty() ) + { rHTMLWrt.OutCSS1_Property(sCSS1_P_background, std::string_view(), &sOut, - nMode == Css1Background::Table); + nMode); + } return rWrt; } diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx index 434e13825340..866442a34928 100644 --- a/sw/source/filter/html/wrthtml.hxx +++ b/sw/source/filter/html/wrthtml.hxx @@ -255,6 +255,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; @@ -468,7 +482,7 @@ public: std::string_view rVal ); inline void OutCSS1_Property( const char *pProp, const OUString& rVal ); void OutCSS1_Property( const char *pProp, std::string_view pVal, - const OUString *pSVal, bool bTable = false ); + const OUString *pSVal, std::optional<sw::Css1Background> oBackground = std::nullopt ); void OutCSS1_UnitProperty( const char *pProp, tools::Long nVal ); void OutCSS1_PixelProperty( const char *pProp, tools::Long nVal, bool bVert ); void OutCSS1_SfxItemSet( const SfxItemSet& rItemSet, bool bDeep=true ); @@ -494,8 +508,12 @@ public: void writeFrameFormatOptions(HtmlWriter& aHtml, const SwFrameFormat& rFrameFormat, std::u16string_view 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, @@ -697,7 +715,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 ); @@ -712,7 +732,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, std::string_view rProperty, std::string_view rValue, - bool bTable = false); + std::optional<sw::Css1Background> oBackground = std::nullopt); #endif // INCLUDED_SW_SOURCE_FILTER_HTML_WRTHTML_HXX