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.stahl@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 2d6cd72..60b47be 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 7a04bee..0f36b36 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 9706c1d..7b3c7e4 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: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 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,29 +2850,329 @@
        </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 8ee3879..bdd2d05 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 8448665..0788b2b 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 f9da777..bc64eb5 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 f65e027..6e28d79 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 0000000..d2167ed
--- /dev/null
+++ b/sc/qa/extras/testdocuments/default-styles.ods
Binary files differ
diff --git a/sw/qa/extras/htmlexport/xhtmlexport.cxx b/sw/qa/extras/htmlexport/xhtmlexport.cxx
index 923c3fe..299b5ff 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);
}