filter/source/xslt/odf2xhtml/export/common/table/table_rows.xsl |    5 
 filter/source/xslt/odf2xhtml/export/common/table_of_content.xsl |   25 
 filter/source/xslt/odf2xhtml/export/xhtml/body.xsl              |  345 
+++++++++-
 filter/source/xslt/odf2xhtml/export/xhtml/header.xsl            |    7 
 filter/source/xslt/odf2xhtml/export/xhtml/table.xsl             |    6 
 sc/CppunitTest_sc_html_export_test.mk                           |    5 
 sc/qa/extras/htmlexporttest.cxx                                 |   18 
 sc/qa/extras/testdocuments/default-styles.ods                   |binary
 sw/qa/extras/htmlexport/xhtmlexport.cxx                         |   23 
 9 files changed, 394 insertions(+), 40 deletions(-)

New commits:
commit 2d9f739ccfead38cdaa13780f7bb5172553dbd77
Author:     Svante Schubert <svante.schub...@gmail.com>
AuthorDate: Wed May 17 17:44:39 2023 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Fri Jun 9 15:12:40 2023 +0200

    tdf#155244 filter: XHTML export: Making ODF style IDs unique for ...
    
    ... HTML/CSS by adding a prefix (the @style:family with '-' as glue 
character)
    to their style name.
    
    Disabled debug output for style:family-name in XSL
    
    add text:a to text family
    
    ... and add a unit test.
    
    Change-Id: Ie846f5ea2a872872f38036aff59d29c8f530ed32
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152749
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/filter/source/xslt/odf2xhtml/export/common/table/table_rows.xsl 
b/filter/source/xslt/odf2xhtml/export/common/table/table_rows.xsl
index 2d6cd7285037..60b47be753ca 100644
--- a/filter/source/xslt/odf2xhtml/export/common/table/table_rows.xsl
+++ b/filter/source/xslt/odf2xhtml/export/common/table/table_rows.xsl
@@ -196,7 +196,10 @@
         <xsl:param name="node-position" />
 
         <xsl:attribute name="class">
-            <xsl:value-of select="translate(@table:style-name, '. %()/\+', 
'')" />
+            <xsl:call-template name="create-unique-style-id">
+                <xsl:with-param name="styleName" select="@table:style-name"/>
+                <xsl:with-param name="styleFamily" select="'table-row'"/>
+            </xsl:call-template>
         </xsl:attribute>
     </xsl:template>
 
diff --git a/filter/source/xslt/odf2xhtml/export/common/table_of_content.xsl 
b/filter/source/xslt/odf2xhtml/export/common/table_of_content.xsl
index 7a04bee074a8..0f36b36486de 100644
--- a/filter/source/xslt/odf2xhtml/export/common/table_of_content.xsl
+++ b/filter/source/xslt/odf2xhtml/export/common/table_of_content.xsl
@@ -93,7 +93,10 @@
                     </xsl:attribute>
                 </xsl:if>
                 <xsl:attribute name="class">
-                    <xsl:value-of 
select="translate(parent::*/@text:style-name, '.,;: %()[]/\+', 
'_____________')"/>
+                    <xsl:call-template name="create-unique-style-id">
+                        <xsl:with-param name="styleName" 
select="parent::*/@text:style-name"/>
+                        <xsl:with-param name="styleFamily" select="'table'"/>
+                    </xsl:call-template>
                 </xsl:attribute>
             </xsl:if>
 
@@ -317,7 +320,10 @@ Scenarios unmatched:
                     <xsl:element namespace="{$namespace}" name="p">
                         <xsl:if test="$position = 1">
                             <xsl:attribute name="class">
-                                <xsl:value-of 
select="translate(@text:style-name, '.,;: %()[]/\+', '_____________')"/>
+                                <xsl:call-template 
name="create-unique-style-id">
+                                    <xsl:with-param name="styleName" 
select="@text:style-name"/>
+                                    <xsl:with-param name="styleFamily" 
select="'paragraph'"/>
+                                </xsl:call-template>
                             </xsl:attribute>
                         </xsl:if>
                         <xsl:apply-templates mode="content-table">
@@ -341,7 +347,10 @@ Scenarios unmatched:
                                     <xsl:element namespace="{$namespace}" 
name="p">
                                         <xsl:if test="$position = 1">
                                             <xsl:attribute name="class">
-                                                <xsl:value-of 
select="translate(@text:style-name, '.,;: %()[]/\+', '_____________')"/>
+                                                <xsl:call-template 
name="create-unique-style-id">
+                                                    <xsl:with-param 
name="styleName" select="@text:style-name"/>
+                                                    <xsl:with-param 
name="styleFamily" select="'paragraph'"/>
+                                                </xsl:call-template>
                                             </xsl:attribute>
                                         </xsl:if>
                                         <xsl:call-template 
name="grab-cell-content-before-tab-stop">
@@ -358,7 +367,10 @@ Scenarios unmatched:
                                     <xsl:element namespace="{$namespace}" 
name="p">
                                         <xsl:if test="$position = 1">
                                             <xsl:attribute name="class">
-                                                <xsl:value-of 
select="translate(@text:style-name, '.,;: %()[]/\+', '_____________')"/>
+                                                <xsl:call-template 
name="create-unique-style-id">
+                                                    <xsl:with-param 
name="styleName" select="@text:style-name"/>
+                                                    <xsl:with-param 
name="styleFamily" select="'paragraph'"/>
+                                                </xsl:call-template>
                                             </xsl:attribute>
                                         </xsl:if>
                                         <xsl:call-template 
name="grab-cell-content-before-tab-stop">
@@ -382,7 +394,10 @@ Scenarios unmatched:
                                 <xsl:element namespace="{$namespace}" name="p">
                                     <xsl:if test="$position = 1">
                                         <xsl:attribute name="class">
-                                            <xsl:value-of 
select="translate(@text:style-name, '.,;: %()[]/\+', '_____________')"/>
+                                            <xsl:call-template 
name="create-unique-style-id">
+                                                <xsl:with-param 
name="styleName" select="@text:style-name"/>
+                                                <xsl:with-param 
name="styleFamily" select="'paragraph'"/>
+                                            </xsl:call-template>
                                         </xsl:attribute>
                                     </xsl:if>
                                     <xsl:element namespace="{$namespace}" 
name="td">
diff --git a/filter/source/xslt/odf2xhtml/export/xhtml/body.xsl 
b/filter/source/xslt/odf2xhtml/export/xhtml/body.xsl
index 9706c1df0615..7b3c7e4d3b17 100644
--- a/filter/source/xslt/odf2xhtml/export/xhtml/body.xsl
+++ b/filter/source/xslt/odf2xhtml/export/xhtml/body.xsl
@@ -19,7 +19,7 @@
 <!--
     For further documentation and updates visit 
http://xml.openoffice.org/odf2xhtml
 -->
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:dc="http://purl.org/dc/elements/1.1/"; 
xmlns:dom="http://www.w3.org/2001/xml-events"; 
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" 
xmlns:math="http://www.w3.org/1998/Math/MathML"; 
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" 
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:ooo="http://openoffice.org/2004/office"; 
xmlns:oooc="http://openoffice.org/2004/calc"; 
xmlns:ooow="http://openoffice.org/2004/writer"; 
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:s
 tyle="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:xforms="http://www.w3.org/2002/xforms"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:xt="http://www.jclark.com/xt"; xmlns:common="http://exslt.org/common"; 
xmlns:xalan="http://xml.apache.org/xalan"; 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 exclude-result-prefixes="chart config dc dom dr3d draw fo form loext math meta 
number office ooo oooc ooow script style svg table text xforms xlink xsd xsi xt 
common xalan" xmlns="http://www.w3.org/1999/xhtml";>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:dc="http://purl.org/dc/elements/1.1/"; 
xmlns:dom="http://www.w3.org/2001/xml-events"; 
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" 
xmlns:math="http://www.w3.org/1998/Math/MathML"; 
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" 
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:ooo="http://openoffice.org/2004/office"; 
xmlns:oooc="http://openoffice.org/2004/calc"; 
xmlns:ooow="http://openoffice.org/2004/writer"; 
xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:
 1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:xforms="http://www.w3.org/2002/xforms"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:xt="http://www.jclark.com/xt"; xmlns:common="http://exslt.org/common"; 
xmlns:xalan="http://xml.apache.org/xalan"; 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 exclude-result-prefixes="chart config dc dom dr3d draw fo form loext math meta 
number office ooo oooc ooow presentation script style svg table text xforms 
xlink xsd xsi xt common xalan" xmlns="http://www.w3.org/1999/xhtml";>
 
 
     <!--+++++ INCLUDED XSL MODULES +++++-->
@@ -1207,7 +1207,10 @@
             NOTE: Should be handled as CSS style in style header -->
             <xsl:variable name="min-label" 
select="$globalData/office:styles/text:outline-style/text:outline-level-style[@text:level
 = current()/@text:outline-level]/*/@text:min-label-width"/>
             <xsl:attribute name="class">
-                <xsl:value-of select="translate(@text:style-name, '.,;: 
%()[]/\+', '_____________')"/>
+                <xsl:call-template name="create-unique-style-id">
+                    <xsl:with-param name="styleName" 
select="@text:style-name"/>
+                    <xsl:with-param name="styleFamily" select="'paragraph'"/>
+                </xsl:call-template>
             </xsl:attribute>
 
             <xsl:call-template name="create-heading-anchor">
@@ -2847,30 +2850,330 @@
         </xsl:choose>
     </xsl:template>
 
-    <xsl:template match="@text:style-name | @draw:style-name | 
@draw:text-style-name | @table:style-name"><!-- | @presentation:style-name-->
+    <xsl:template match="@text:style-name | @draw:style-name | 
@draw:text-style-name | @table:style-name | @presentation:style-name">
         <xsl:param name="globalData"/>
 
-        <xsl:attribute name="class">
-               <xsl:choose>
-                       <xsl:when test="name() = 'draw:text-style-name' or 
name() = 'draw:style-name'">
-                    <xsl:choose>
-                        <xsl:when test="parent::*/@draw:text-style-name and 
parent::*/@draw:style-name">
-                            <xsl:value-of 
select="translate(parent::*/@draw:style-name, '.,;: %()[]/\+', 
'_____________')" /><xsl:text> </xsl:text>
-                            <xsl:value-of 
select="translate(parent::*/@draw:text-style-name, '.,;: %()[]/\+', 
'_____________')" />
-                        </xsl:when>
-                        <xsl:otherwise>
-                            <xsl:value-of select="translate(., '.,;: 
%()[]/\+', '_____________')" />
-                        </xsl:otherwise>
-                    </xsl:choose>
-                </xsl:when>
-                <xsl:otherwise>
-                    <xsl:value-of select="translate(., '.,;: %()[]/\+', 
'_____________')"/>
-                </xsl:otherwise>                   
-               </xsl:choose>    
-        </xsl:attribute>
+        <!-- the probem there can be more than one style-name attribute! We 
need to write class once with all style-name attribute values -->
+        <xsl:variable name="classAttributeValue">
+            <xsl:if test="parent::*/@text:style-name != ''"> 
+                <xsl:call-template name="create-unique-style-id">
+                    <xsl:with-param name="styleName" 
select="parent::*/@text:style-name"/>
+                    <xsl:with-param name="styleFamily">
+                        <xsl:call-template name="get-style-family-name">
+                            <xsl:with-param name="parentName" 
select="name(..)"/>
+                        </xsl:call-template>
+                    </xsl:with-param>
+                </xsl:call-template><xsl:text> </xsl:text>
+            </xsl:if>        
+            <xsl:if test="parent::*/@draw:style-name != ''"> 
+                <xsl:call-template name="create-unique-style-id">
+                    <xsl:with-param name="styleName" 
select="parent::*/@draw:style-name"/>
+                    <xsl:with-param name="styleFamily">
+                        <xsl:call-template name="get-style-family-name">
+                            <xsl:with-param name="parentName" 
select="name(..)"/>
+                        </xsl:call-template>
+                    </xsl:with-param>
+                </xsl:call-template><xsl:text> </xsl:text>
+            </xsl:if>
+            <xsl:if test="parent::*/@draw:text-style-name != ''"> 
+                <xsl:call-template name="create-unique-style-id">
+                    <xsl:with-param name="styleName" 
select="parent::*/@draw:text-style-name"/>
+                    <xsl:with-param name="styleFamily">
+                        <xsl:call-template name="get-style-family-name">
+                            <xsl:with-param name="parentName" 
select="name(..)"/>
+                        </xsl:call-template>
+                    </xsl:with-param>
+                </xsl:call-template><xsl:text> </xsl:text>
+            </xsl:if>
+            <xsl:if test="parent::*/@table:style-name != ''"> 
+                <xsl:call-template name="create-unique-style-id">
+                    <xsl:with-param name="styleName" 
select="parent::*/@table:style-name"/>
+                    <xsl:with-param name="styleFamily">
+                        <xsl:call-template name="get-style-family-name">
+                            <xsl:with-param name="parentName" 
select="name(..)"/>
+                        </xsl:call-template>
+                    </xsl:with-param>
+                </xsl:call-template><xsl:text> </xsl:text>
+            </xsl:if>
+            <xsl:if test="parent::*/@presentation:style-name != ''"> 
+                <xsl:call-template name="create-unique-style-id">
+                    <xsl:with-param name="styleName" 
select="parent::*/@presentation:style-name"/>
+                    <xsl:with-param name="styleFamily">
+                        <xsl:call-template name="get-style-family-name">
+                            <xsl:with-param name="parentName" 
select="name(..)"/>
+                        </xsl:call-template>
+                    </xsl:with-param>
+                </xsl:call-template><xsl:text> </xsl:text>
+            </xsl:if>
+        </xsl:variable>
+
+        <xsl:attribute name="class"><xsl:value-of 
select="normalize-space($classAttributeValue)"/></xsl:attribute>
+    </xsl:template>
+
+    
+    <xsl:template name="create-unique-style-id">
+        <xsl:param name="styleName" />
+        <xsl:param name="styleFamily" />
+
+        <xsl:call-template name="abbreviate-style-family-name">
+            <xsl:with-param name="styleFamily" select="$styleFamily"/>
+        </xsl:call-template>
+        <xsl:text>-</xsl:text>
+        <xsl:value-of select="translate($styleName, '.,;: %()[]/\+', 
'_____________')"/>
     </xsl:template>
 
 
+    <xsl:template name="abbreviate-style-family-name">
+            <xsl:param name="styleFamily" />
+        <!--<xsl:message>abbreviate-style-family-name: The style family is 
'<xsl:value-of select="$styleFamily"/>'</xsl:message>-->
+
+        <!-- 
+               The complete set of family types (aka @style:family) is defined 
in the ODF specification:
+               
https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part3-schema/OpenDocument-v1.3-os-part3-schema.html#attribute-style_family
            
+            (realized style family 'section' is missing, see 
https://docs.oasis-open.org/office/OpenDocument/v1.3/os/schemas/OpenDocument-v1.3-schema-rng.html#12668
 
+                and wrote an issue to ODF TC: 
https://github.com/oasis-tcs/odf-tc/issues/49
+        -->
+        <xsl:choose>
+            <!-- chart: family name of styles for charts. -->
+            <xsl:when test="$styleFamily='chart'">
+                <xsl:text>chart</xsl:text>
+            </xsl:when>
+            <!-- drawing-page: family name of styles for drawing pages. -->
+            <xsl:when test="$styleFamily='drawing-page'">
+                <xsl:text>page</xsl:text>
+            </xsl:when>
+            <!-- graphic: family name of styles for graphic elements. -->
+            <xsl:when test="$styleFamily='graphic'">
+                <xsl:text>graphic</xsl:text>
+            </xsl:when>
+            <!-- paragraph: family name of styles for paragraphs. -->
+            <xsl:when test="$styleFamily='paragraph'">
+                <xsl:text>paragraph</xsl:text>
+            </xsl:when>
+            <!-- presentation: family name of styles for presentations. -->
+            <xsl:when test="$styleFamily='presentation'">
+                <xsl:text>presentation</xsl:text>
+            </xsl:when>
+            <!-- ruby: family name of styles for ruby text. -->
+            <xsl:when test="$styleFamily='ruby'">
+                <xsl:text>ruby</xsl:text>
+            </xsl:when>
+            <!-- section: family name of styles for sections. -->
+            <xsl:when test="$styleFamily='section'">
+                <xsl:text>section</xsl:text>
+            </xsl:when>            
+            <!-- table: family name of styles for tables. -->
+            <xsl:when test="$styleFamily='table'">
+                <xsl:text>table</xsl:text>
+            </xsl:when>
+            <!-- table-cell: family name of styles for table cells. -->
+            <xsl:when test="$styleFamily='table-cell'">
+                <xsl:text>cell</xsl:text>
+            </xsl:when>
+            <!-- table-column: family name of styles for table columns. -->
+            <xsl:when test="$styleFamily='table-column'">
+                <xsl:text>col</xsl:text>
+            </xsl:when>
+            <!-- table-row: family name of styles for table rows. -->
+            <xsl:when test="$styleFamily='table-row'">
+                <xsl:text>row</xsl:text>
+            </xsl:when>
+            <!-- text: family name of styles for text. -->
+            <xsl:when test="$styleFamily='text'">
+                <xsl:text>text</xsl:text>
+            </xsl:when>
+            <xsl:otherwise>
+                <xsl:message>WARNING: No style family found for <xsl:value-of 
select="$styleFamily"/></xsl:message>
+                <xsl:text>unknown-family</xsl:text>
+            </xsl:otherwise>
+        </xsl:choose>
+    </xsl:template>
+
+    <xsl:template name="get-style-family-name">
+        <xsl:param name="parentName" />
+
+
+        <!--<xsl:message>get-style-family-name: The style parent is 
'<xsl:value-of select="name(..)"/>'</xsl:message>-->
+        <!--
+               The complete set of family types (aka @style:family) is defined 
in the ODF specification:
+               
https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part3-schema/OpenDocument-v1.3-os-part3-schema.html#attribute-style_family
+            (realized style family 'section' is missing, see 
https://docs.oasis-open.org/office/OpenDocument/v1.3/os/schemas/OpenDocument-v1.3-schema-rng.html#12668
+                and wrote an issue to ODF TC: 
https://github.com/oasis-tcs/odf-tc/issues/49
+
+            in addition the mapping of styleable ODF elements to their 
@style:family attribute is availabe in structured form (XML) in the ODF Toolkit 
generator project:
+               
https://github.com/tdf/odftoolkit/blob/master/generator/schema2template/src/test/resources/test-input/odf/generation/odfdom-java/dom/grammar-additions.xml#LL43C52-L43C52r-additions.xml#LL43C52-L43C52
+        -->
+        <xsl:choose>
+            <!-- chart: family name of styles for charts. -->
+            <xsl:when test="
+                       $parentName='chart:axis' or
+                                       $parentName='chart:chart' or
+                                       $parentName='chart:data-point' or
+                                       $parentName='chart:error-indicator' or
+                                       $parentName='chart:floor' or
+                                       $parentName='chart:footer' or
+                                       $parentName='chart:grid' or
+                                       $parentName='chart:legend' or
+                                       $parentName='chart:mean-value' or
+                                       $parentName='chart:plot-area' or
+                                       $parentName='chart:regression-curve' or
+                                       $parentName='chart:series' or
+                                       $parentName='chart:stock-gain-marker' or
+                                       $parentName='chart:stock-loss-marker' or
+                                       $parentName='chart:stock-range-line' or
+                                       $parentName='chart:subtitle' or
+                                       $parentName='chart:title' or
+                                       $parentName='chart:wall'">
+                <xsl:text>chart</xsl:text>
+            </xsl:when>
+            <!-- drawing-page: family name of styles for drawing pages. -->
+            <xsl:when test="
+                       $parentName='draw:page' or
+                       $parentName='style:handout-master' or
+                       $parentName='style:master-page' or
+                               $parentName='presentation:notes'">
+                <xsl:text>drawing-page</xsl:text>
+            </xsl:when>
+            <!-- graphic: family name of styles for graphic elements. -->
+            <xsl:when test="
+                       $parentName='dr3d:cube' or
+                                       $parentName='dr3d:extrude' or
+                                       $parentName='dr3d:rotate' or
+                                       $parentName='dr3d:scene' or
+                                       $parentName='dr3d:sphere' or
+                                       $parentName='draw:caption' or
+                                       $parentName='draw:circle' or
+                                       $parentName='draw:connector' or
+                                       $parentName='draw:control' or
+                                       $parentName='draw:custom-shape' or
+                                       $parentName='draw:ellipse' or
+                                       $parentName='draw:frame' or
+                                       $parentName='draw:g' or
+                                       $parentName='draw:line' or
+                                       $parentName='draw:measure' or
+                                       $parentName='draw:page-thumbnail' or
+                                       $parentName='draw:path' or
+                                       $parentName='draw:polygon' or
+                                       $parentName='draw:polyline' or
+                                       $parentName='draw:rect' or
+                                       $parentName='draw:regular-polygon' or
+                                       $parentName='office:annotation'">
+                <xsl:text>graphic</xsl:text>
+            </xsl:when>
+            <!-- paragraph: family name of styles for paragraphs. -->
+            <xsl:when test="
+                                       
$parentName='text:alphabetical-index-entry-template' or
+                                       
$parentName='text:bibliography-entry-template' or
+                                       $parentName='text:h' or
+                                       
$parentName='text:illustration-index-entry-template' or
+                                       $parentName='text:index-source-style' or
+                                       $parentName='text:index-title-template' 
or
+                                       
$parentName='text:object-index-entry-template' or
+                                       $parentName='text:p' or
+                                       
$parentName='text:table-index-entry-template' or
+                                       
$parentName='text:table-of-content-entry-template' or
+                                       
$parentName='text:user-index-entry-template'">
+                <xsl:text>paragraph</xsl:text>
+            </xsl:when>
+            <!-- presentation: family name of styles for presentations. -->
+            <xsl:when test="
+                       $parentName='dr3d:cube' or
+                                       $parentName='dr3d:extrude' or
+                                       $parentName='dr3d:rotate' or
+                                       $parentName='dr3d:scene' or
+                                       $parentName='dr3d:sphere' or
+                                       $parentName='draw:caption' or
+                                       $parentName='draw:circle' or
+                                       $parentName='draw:connector' or
+                                       $parentName='draw:control' or
+                                       $parentName='draw:custom-shape' or
+                                       $parentName='draw:ellipse' or
+                                       $parentName='draw:frame' or
+                                       $parentName='draw:g' or
+                                       $parentName='draw:line' or
+                                       $parentName='draw:measure' or
+                                       $parentName='draw:page-thumbnail' or
+                                       $parentName='draw:path' or
+                                       $parentName='draw:polygon' or
+                                       $parentName='draw:polyline' or
+                                       $parentName='draw:rect' or
+                                       $parentName='draw:regular-polygon' or
+                                       $parentName='office:annotation'">
+                <xsl:text>presentation</xsl:text>
+            </xsl:when>
+            <!-- ruby: family name of styles for ruby text. -->
+            <xsl:when test="$parentName='text:ruby' or
+                                       $parentName='text:ruby-text'">
+                <xsl:text>ruby</xsl:text>
+            </xsl:when>
+            <!-- section: family name of styles for sections. -->
+            <xsl:when test="
+                                       $parentName='text:alphabetical-index' or
+                                       $parentName='text:bibliography' or
+                                       $parentName='text:illustration-index' or
+                                       $parentName='text:index-title' or
+                                       $parentName='text:object-index' or
+                                       $parentName='text:page' or
+                                       $parentName='text:section' or
+                                       $parentName='text:s' or
+                                       $parentName='text:table-index' or
+                                       $parentName='text:table-of-content' or
+                                       $parentName='text:user-index'">
+                <xsl:text>section</xsl:text>
+            </xsl:when>
+            <!-- table: family name of styles for tables. -->
+            <xsl:when test="$parentName='table:table'">
+                <xsl:text>table</xsl:text>
+            </xsl:when>
+            <!-- table-cell: family name of styles for table cells. -->
+            <xsl:when test="
+               $parentName='table:table-cell' or
+                               $parentName='table:body' or
+                               $parentName='table:even-columns' or
+                               $parentName='table:even-rows' or
+                               $parentName='table:first-column' or
+                               $parentName='table:first-row' or
+                               $parentName='table:last-column' or
+                               $parentName='table:last-row' or
+                               $parentName='table:odd-columns' or
+                               $parentName='table:odd-rows' or
+                               $parentName='table:covered-table-cell'">
+                <xsl:text>table-cell</xsl:text>
+            </xsl:when>
+            <!-- table-column: family name of styles for table columns. -->
+            <xsl:when test="$parentName='table:table-column'">
+                <xsl:text>table-column</xsl:text>
+            </xsl:when>
+            <!-- table-row: family name of styles for table rows. -->
+            <xsl:when test="$parentName='table:table-row'">
+                <xsl:text>table-row</xsl:text>
+            </xsl:when>
+            <!-- text: family name of styles for text. -->
+            <xsl:when test="
+               $parentName='text:index-entry-bibliography' or
+                               $parentName='text:index-entry-chapter' or
+                               $parentName='text:index-entry-link-end' or
+                               $parentName='text:index-entry-link-start' or
+                               $parentName='text:index-entry-page-number' or
+                               $parentName='text:index-entry-span' or
+                               $parentName='text:index-entry-tab-stop' or
+                               $parentName='text:index-entry-text' or
+                               $parentName='text:a' or
+                               $parentName='text:span' or
+                               $parentName='style:drop-cap' or
+                               $parentName='text:line-break' or
+                               $parentName='text:tab' or
+                               $parentName='text:linenumbering-configuration'">
+                <xsl:text>text</xsl:text>
+            </xsl:when>
+            <xsl:otherwise>
+                <xsl:message>WARNING: No style family found for parent element 
<xsl:value-of select="$parentName"/></xsl:message>
+                <xsl:text>unknown-family-parent</xsl:text>
+            </xsl:otherwise>
+        </xsl:choose>
+    </xsl:template>
+    
+
     <!-- ***************** -->
     <!-- *** Footnotes *** -->
     <!-- ***************** -->
diff --git a/filter/source/xslt/odf2xhtml/export/xhtml/header.xsl 
b/filter/source/xslt/odf2xhtml/export/xhtml/header.xsl
index 8ee38796ebdf..bdd2d05b0925 100644
--- a/filter/source/xslt/odf2xhtml/export/xhtml/header.xsl
+++ b/filter/source/xslt/odf2xhtml/export/xhtml/header.xsl
@@ -129,7 +129,12 @@
             <xsl:for-each select="$globalData/all-styles/style">
                     <xsl:if test="final-properties != ''">
                         <!-- NOTE: easy process, as only the style family in 
conjunction with the style name, makes the style unambiguous -->
-                        <xsl:text>.</xsl:text><!--<xsl:value-of 
select="@style:family" /><xsl:text>:</xsl:text>--><xsl:value-of 
select="translate(@style:name, '.,;: %()[]/\+', '_____________')"/><xsl:text> { 
</xsl:text> <xsl:value-of select="final-properties" /><xsl:text>}
+                        <xsl:text>.</xsl:text>
+                        <xsl:call-template name="create-unique-style-id">
+                            <xsl:with-param name="styleName" 
select="@style:name"/>
+                            <xsl:with-param name="styleFamily" 
select="@style:family"/>
+                        </xsl:call-template>
+                        <xsl:text>{ </xsl:text> <xsl:value-of 
select="final-properties" /><xsl:text>}
     </xsl:text>
                     </xsl:if>
 
diff --git a/filter/source/xslt/odf2xhtml/export/xhtml/table.xsl 
b/filter/source/xslt/odf2xhtml/export/xhtml/table.xsl
index 8448665d20b3..0788b2bf52a9 100644
--- a/filter/source/xslt/odf2xhtml/export/xhtml/table.xsl
+++ b/filter/source/xslt/odf2xhtml/export/xhtml/table.xsl
@@ -206,8 +206,10 @@
 
        <!-- cell style header -->
        <xsl:attribute name="class">
-           <xsl:value-of select="translate($styleName, '.,;: %()[]/\+', 
'_____________')"/>
+            <xsl:call-template name="create-unique-style-id">
+                <xsl:with-param name="styleName" select="$styleName"/>
+                <xsl:with-param name="styleFamily" select="'table-cell'"/>
+            </xsl:call-template>
        </xsl:attribute>
     </xsl:template>
 </xsl:stylesheet>
-
diff --git a/sc/CppunitTest_sc_html_export_test.mk 
b/sc/CppunitTest_sc_html_export_test.mk
index f9da77710a29..bc64eb5b7803 100644
--- a/sc/CppunitTest_sc_html_export_test.mk
+++ b/sc/CppunitTest_sc_html_export_test.mk
@@ -67,6 +67,11 @@ $(eval $(call gb_CppunitTest_use_api,sc_html_export_test,\
        oovbaapi \
 ))
 
+$(eval $(call gb_CppunitTest_use_packages,sc_html_export_test, \
+    filter_xhtml \
+    filter_xslt \
+))
+
 $(eval $(call gb_CppunitTest_use_ure,sc_html_export_test))
 $(eval $(call gb_CppunitTest_use_vcl,sc_html_export_test))
 
diff --git a/sc/qa/extras/htmlexporttest.cxx b/sc/qa/extras/htmlexporttest.cxx
index f65e027ae62e..6e28d791fbb3 100644
--- a/sc/qa/extras/htmlexporttest.cxx
+++ b/sc/qa/extras/htmlexporttest.cxx
@@ -50,8 +50,26 @@ public:
         assertXPath(pDoc, "/html/body/table/tr/td/img", 0);
     }
 
+    void testTdf155244()
+    {
+        loadFromURL(u"default-styles.ods");
+        save("XHTML Calc File");
+
+        xmlDocUniquePtr pXmlDoc = parseXml(maTempFile);
+        CPPUNIT_ASSERT(pXmlDoc);
+
+        assertXPath(pXmlDoc, "/xhtml:html", 1);
+        // the problem was that there were 2 CSS styles named "Default"
+        assertXPath(pXmlDoc, 
"/xhtml:html/xhtml:body/xhtml:table/xhtml:tr/xhtml:td", "class", 
"cell-Default");
+        OUString const styles = getXPathContent(pXmlDoc, 
"/xhtml:html/xhtml:head/xhtml:style");
+        CPPUNIT_ASSERT(styles.indexOf(".graphic-Default{ 
background-color:#729fcf;") != -1);
+        CPPUNIT_ASSERT(styles.indexOf(".cell-Default{ font-size:10pt; 
font-family:'Liberation Sans'; }") != -1);
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), styles.indexOf(".Default"));
+    }
+
     CPPUNIT_TEST_SUITE(ScHTMLExportTest);
     CPPUNIT_TEST(testHtmlSkipImage);
+    CPPUNIT_TEST(testTdf155244);
     CPPUNIT_TEST_SUITE_END();
 
 };
diff --git a/sc/qa/extras/testdocuments/default-styles.ods 
b/sc/qa/extras/testdocuments/default-styles.ods
new file mode 100644
index 000000000000..d2167ed2023b
Binary files /dev/null and b/sc/qa/extras/testdocuments/default-styles.ods 
differ
diff --git a/sw/qa/extras/htmlexport/xhtmlexport.cxx 
b/sw/qa/extras/htmlexport/xhtmlexport.cxx
index 923c3fecda8a..299b5ff6b5c8 100644
--- a/sw/qa/extras/htmlexport/xhtmlexport.cxx
+++ b/sw/qa/extras/htmlexport/xhtmlexport.cxx
@@ -49,7 +49,7 @@ DECLARE_HTMLEXPORT_TEST(testTdf131812, "tdf131812.odt")
     sal_uInt64 nLength = pStream->TellEnd();
     OString aStream(read_uInt8s_ToOString(*pStream, nLength));
     CPPUNIT_ASSERT(
-        aStream.indexOf(".P1 { font-size:12pt; font-family:\'Liberation 
Serif\'; "
+        aStream.indexOf(".paragraph-P1{ font-size:12pt; 
font-family:\'Liberation Serif\'; "
                         "writing-mode:horizontal-tb; direction:rtl; 
text-align:right ! important;}")
         != -1);
 }
@@ -138,18 +138,20 @@ DECLARE_HTMLEXPORT_TEST(testTdf107696, "tdf107696.odt")
     CPPUNIT_ASSERT(aStream.indexOf("span.heading_numbering { margin-right: 
0.8rem; }* { margin:0;}")
                    != -1);
     CPPUNIT_ASSERT(
-        aStream.indexOf("<h2 class=\"Heading_20_2\"><a "
+        aStream.indexOf("<h2 class=\"paragraph-Heading_20_2\"><a "
                         "id=\"a__Level_2_without_number\"><span/></a>Level 2 
without number</h2>")
         != -1);
     CPPUNIT_ASSERT(
-        aStream.indexOf("<h2 class=\"Heading_20_2\"><a 
id=\"a_3_1_Level_2__number_3_1\"><span "
-                        "class=\"heading_numbering\">3.1</span></a>Level <span 
"
-                        "class=\"T2\">2</span>, <span class=\"T1\">number 
3.1</span></h2>")
+        aStream.indexOf(
+            "<h2 class=\"paragraph-Heading_20_2\"><a 
id=\"a_3_1_Level_2__number_3_1\"><span "
+            "class=\"heading_numbering\">3.1</span></a>Level <span "
+            "class=\"text-T2\">2</span>, <span class=\"text-T1\">number 
3.1</span></h2>")
         != -1);
     CPPUNIT_ASSERT(
-        aStream.indexOf("<h2 class=\"Heading_20_2\"><a 
id=\"a_3_2_Level_2__number_3_2\"><span "
-                        "class=\"heading_numbering\">3.2</span></a>Level 2, 
<span "
-                        "class=\"T1\">number 3.2</span></h2>")
+        aStream.indexOf(
+            "<h2 class=\"paragraph-Heading_20_2\"><a 
id=\"a_3_2_Level_2__number_3_2\"><span "
+            "class=\"heading_numbering\">3.2</span></a>Level 2, <span "
+            "class=\"text-T1\">number 3.2</span></h2>")
         != -1);
 }
 
@@ -160,8 +162,9 @@ DECLARE_HTMLEXPORT_TEST(testTdf66305, "tdf66305.odt")
     sal_uInt64 nLength = pStream->TellEnd();
     OString aStream(read_uInt8s_ToOString(*pStream, nLength));
     CPPUNIT_ASSERT(
-        aStream.indexOf("<p class=\"P6\"><a 
href=\"#__RefHeading__82004_486970805\" "
-                        "class=\"Internet_20_link\">Introduction</a></p><p 
class=\"P7\"> </p>")
+        aStream.indexOf("<p class=\"paragraph-P6\"><a 
href=\"#__RefHeading__82004_486970805\" "
+                        
"class=\"text-Internet_20_link\">Introduction</a></p><p "
+                        "class=\"paragraph-P7\"> </p>")
         != -1);
 }
 

Reply via email to