Filter out more unwanted command URIs
[LibreOffice.git] / sw / source / filter / html / htmlfldw.cxx
blob325cd6aa2beef241320435884e88c76a28a12d22
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/i18n/XBreakIterator.hpp>
21 #include <comphelper/string.hxx>
22 #include <comphelper/xmlencode.hxx>
23 #include <svtools/htmlkywd.hxx>
24 #include <svtools/htmlout.hxx>
25 #include <osl/diagnose.h>
26 #include <o3tl/string_view.hxx>
27 #include <fmtfld.hxx>
28 #include <doc.hxx>
29 #include <docsh.hxx>
30 #include <view.hxx>
31 #include <wrtsh.hxx>
32 #include <breakit.hxx>
33 #include <ndtxt.hxx>
34 #include <txtfld.hxx>
35 #include <fldbas.hxx>
36 #include <docufld.hxx>
37 #include <flddat.hxx>
38 #include <viewopt.hxx>
39 #include "htmlfld.hxx"
40 #include "wrthtml.hxx"
41 #include <rtl/strbuf.hxx>
42 #include "css1atr.hxx"
43 #include "css1kywd.hxx"
45 using namespace nsSwDocInfoSubType;
47 const char *SwHTMLWriter::GetNumFormat( sal_uInt16 nFormat )
49 const char *pFormatStr = nullptr;
51 switch( static_cast<SvxNumType>(nFormat) )
53 case SVX_NUM_CHARS_UPPER_LETTER: pFormatStr = OOO_STRING_SW_HTML_FF_uletter; break;
54 case SVX_NUM_CHARS_LOWER_LETTER: pFormatStr = OOO_STRING_SW_HTML_FF_lletter; break;
55 case SVX_NUM_ROMAN_UPPER: pFormatStr = OOO_STRING_SW_HTML_FF_uroman; break;
56 case SVX_NUM_ROMAN_LOWER: pFormatStr = OOO_STRING_SW_HTML_FF_lroman; break;
57 case SVX_NUM_ARABIC: pFormatStr = OOO_STRING_SW_HTML_FF_arabic; break;
58 case SVX_NUM_NUMBER_NONE: pFormatStr = OOO_STRING_SW_HTML_FF_none; break;
59 case SVX_NUM_CHAR_SPECIAL: pFormatStr = OOO_STRING_SW_HTML_FF_char; break;
60 case SVX_NUM_PAGEDESC: pFormatStr = OOO_STRING_SW_HTML_FF_page; break;
61 case SVX_NUM_CHARS_UPPER_LETTER_N: pFormatStr = OOO_STRING_SW_HTML_FF_ulettern; break;
62 case SVX_NUM_CHARS_LOWER_LETTER_N: pFormatStr = OOO_STRING_SW_HTML_FF_llettern; break;
63 default:
67 return pFormatStr;
70 static SwHTMLWriter& OutHTML_SwField( SwHTMLWriter& rWrt, const SwField* pField,
71 const SwTextNode& rTextNd, sal_Int32 nFieldPos )
73 const SwFieldType* pFieldTyp = pField->GetTyp();
74 SwFieldIds nField = pFieldTyp->Which();
75 sal_uLong nFormat = pField->GetFormat();
77 const char *pTypeStr=nullptr, // TYPE
78 *pSubStr=nullptr, // SUBTYPE
79 *pFormatStr=nullptr; // FORMAT (SW)
80 OUString aValue; // VALUE (SW)
81 bool bNumFormat=false; // SDNUM (Number-Formatter-Format)
82 bool bNumValue=false; // SDVAL (Number-Formatter-Value)
83 double dNumValue = 0.0; // SDVAL (Number-Formatter-Value)
84 bool bFixed=false; // SDFIXED
85 OUString aName; // NAME (CUSTOM)
87 switch( nField )
89 case SwFieldIds::ExtUser:
90 pTypeStr = OOO_STRING_SW_HTML_FT_sender;
91 switch( static_cast<SwExtUserSubType>(pField->GetSubType()) )
93 case EU_COMPANY: pSubStr = OOO_STRING_SW_HTML_FS_company; break;
94 case EU_FIRSTNAME: pSubStr = OOO_STRING_SW_HTML_FS_firstname; break;
95 case EU_NAME: pSubStr = OOO_STRING_SW_HTML_FS_name; break;
96 case EU_SHORTCUT: pSubStr = OOO_STRING_SW_HTML_FS_shortcut; break;
97 case EU_STREET: pSubStr = OOO_STRING_SW_HTML_FS_street; break;
98 case EU_COUNTRY: pSubStr = OOO_STRING_SW_HTML_FS_country; break;
99 case EU_ZIP: pSubStr = OOO_STRING_SW_HTML_FS_zip; break;
100 case EU_CITY: pSubStr = OOO_STRING_SW_HTML_FS_city; break;
101 case EU_TITLE: pSubStr = OOO_STRING_SW_HTML_FS_title; break;
102 case EU_POSITION: pSubStr = OOO_STRING_SW_HTML_FS_position; break;
103 case EU_PHONE_PRIVATE: pSubStr = OOO_STRING_SW_HTML_FS_pphone; break;
104 case EU_PHONE_COMPANY: pSubStr = OOO_STRING_SW_HTML_FS_cphone; break;
105 case EU_FAX: pSubStr = OOO_STRING_SW_HTML_FS_fax; break;
106 case EU_EMAIL: pSubStr = OOO_STRING_SW_HTML_FS_email; break;
107 case EU_STATE: pSubStr = OOO_STRING_SW_HTML_FS_state; break;
108 default:
111 OSL_ENSURE( pSubStr, "unknown sub type for SwExtUserField" );
112 bFixed = static_cast<const SwExtUserField*>(pField)->IsFixed();
113 break;
115 case SwFieldIds::Author:
116 pTypeStr = OOO_STRING_SW_HTML_FT_author;
117 switch( static_cast<SwAuthorFormat>(nFormat) & 0xff)
119 case AF_NAME: pFormatStr = OOO_STRING_SW_HTML_FF_name; break;
120 case AF_SHORTCUT: pFormatStr = OOO_STRING_SW_HTML_FF_shortcut; break;
122 OSL_ENSURE( pFormatStr, "unknown format for SwAuthorField" );
123 bFixed = static_cast<const SwAuthorField*>(pField)->IsFixed();
124 break;
126 case SwFieldIds::DateTime:
127 pTypeStr = OOO_STRING_SW_HTML_FT_datetime;
128 bNumFormat = true;
129 if( static_cast<const SwDateTimeField*>(pField)->IsFixed() )
131 bNumValue = true;
132 dNumValue = static_cast<const SwDateTimeField*>(pField)->GetValue();
134 break;
136 case SwFieldIds::PageNumber:
138 pTypeStr = OOO_STRING_SW_HTML_FT_page;
139 SwPageNumSubType eSubType = static_cast<SwPageNumSubType>(pField->GetSubType());
140 switch( eSubType )
142 case PG_RANDOM: pSubStr = OOO_STRING_SW_HTML_FS_random; break;
143 case PG_NEXT: pSubStr = OOO_STRING_SW_HTML_FS_next; break;
144 case PG_PREV: pSubStr = OOO_STRING_SW_HTML_FS_prev; break;
146 OSL_ENSURE( pSubStr, "unknown sub type for SwPageNumberField" );
147 pFormatStr = SwHTMLWriter::GetNumFormat( static_cast< sal_uInt16 >(nFormat) );
149 if( static_cast<SvxNumType>(nFormat)==SVX_NUM_CHAR_SPECIAL )
151 aValue = static_cast<const SwPageNumberField *>(pField)->GetUserString();
153 else
155 const OUString aPar2Value = pField->GetPar2();
156 short nValue = static_cast<short>(aPar2Value.toInt32());
157 if( (eSubType == PG_NEXT && nValue!=1) ||
158 (eSubType == PG_PREV && nValue!=-1) ||
159 (eSubType == PG_RANDOM && nValue!=0) )
161 aValue = aPar2Value;
165 break;
166 case SwFieldIds::DocInfo:
168 sal_uInt16 nSubType = pField->GetSubType();
169 pTypeStr = OOO_STRING_SW_HTML_FT_docinfo;
170 sal_uInt16 nExtSubType = nSubType & 0x0f00;
171 nSubType &= 0x00ff;
173 switch( nSubType )
175 case DI_TITLE: pSubStr = OOO_STRING_SW_HTML_FS_title; break;
176 case DI_SUBJECT: pSubStr = OOO_STRING_SW_HTML_FS_theme; break;
177 case DI_KEYS: pSubStr = OOO_STRING_SW_HTML_FS_keys; break;
178 case DI_COMMENT: pSubStr = OOO_STRING_SW_HTML_FS_comment; break;
179 case DI_CREATE: pSubStr = OOO_STRING_SW_HTML_FS_create; break;
180 case DI_CHANGE: pSubStr = OOO_STRING_SW_HTML_FS_change; break;
181 case DI_CUSTOM: pSubStr = OOO_STRING_SW_HTML_FS_custom; break;
182 default: pTypeStr = nullptr; break;
185 if( DI_CUSTOM == nSubType ) {
186 aName = static_cast<const SwDocInfoField*>(pField)->GetName();
189 if( DI_CREATE == nSubType || DI_CHANGE == nSubType )
191 switch( nExtSubType )
193 case DI_SUB_AUTHOR:
194 pFormatStr = OOO_STRING_SW_HTML_FF_author;
195 break;
196 case DI_SUB_TIME:
197 pFormatStr = OOO_STRING_SW_HTML_FF_time;
198 bNumFormat = true;
199 break;
200 case DI_SUB_DATE:
201 pFormatStr = OOO_STRING_SW_HTML_FF_date;
202 bNumFormat = true;
203 break;
206 bFixed = static_cast<const SwDocInfoField*>(pField)->IsFixed();
207 if( bNumFormat )
209 if( bFixed )
211 // For a fixed field output the num value too.
212 // Fixed fields without number format shouldn't
213 // exist. See below for OSL_ENSURE().
214 dNumValue = static_cast<const SwDocInfoField*>(pField)->GetValue();
215 bNumValue = true;
217 else if( !nFormat )
219 // Non-fixed fields may not have a number format, when
220 // they come from a 4.0-document.
221 bNumFormat = false;
225 break;
227 case SwFieldIds::DocStat:
229 pTypeStr = OOO_STRING_SW_HTML_FT_docstat;
230 sal_uInt16 nSubType = pField->GetSubType();
231 switch( nSubType )
233 case DS_PAGE: pSubStr = OOO_STRING_SW_HTML_FS_page; break;
234 case DS_PARA: pSubStr = OOO_STRING_SW_HTML_FS_para; break;
235 case DS_WORD: pSubStr = OOO_STRING_SW_HTML_FS_word; break;
236 case DS_CHAR: pSubStr = OOO_STRING_SW_HTML_FS_char; break;
237 case DS_TBL: pSubStr = OOO_STRING_SW_HTML_FS_tbl; break;
238 case DS_GRF: pSubStr = OOO_STRING_SW_HTML_FS_grf; break;
239 case DS_OLE: pSubStr = OOO_STRING_SW_HTML_FS_ole; break;
240 default: pTypeStr = nullptr; break;
242 pFormatStr = SwHTMLWriter::GetNumFormat( static_cast< sal_uInt16 >(nFormat) );
244 break;
246 case SwFieldIds::Filename:
247 pTypeStr = OOO_STRING_SW_HTML_FT_filename;
248 switch( static_cast<SwFileNameFormat>(nFormat & ~FF_FIXED) )
250 case FF_NAME: pFormatStr = OOO_STRING_SW_HTML_FF_name; break;
251 case FF_PATHNAME: pFormatStr = OOO_STRING_SW_HTML_FF_pathname; break;
252 case FF_PATH: pFormatStr = OOO_STRING_SW_HTML_FF_path; break;
253 case FF_NAME_NOEXT: pFormatStr = OOO_STRING_SW_HTML_FF_name_noext; break;
254 default:
257 bFixed = static_cast<const SwFileNameField*>(pField)->IsFixed();
258 OSL_ENSURE( pFormatStr, "unknown format for SwFileNameField" );
259 break;
260 default: break;
263 // ReqIF-XHTML doesn't allow <sdfield>.
264 if (rWrt.mbReqIF && pTypeStr)
266 pTypeStr = nullptr;
269 // Output the <sdfield> tag.
270 if( pTypeStr )
272 OStringBuffer sOut("<"
273 + rWrt.GetNamespace()
274 + OOO_STRING_SVTOOLS_HTML_sdfield
276 OOO_STRING_SVTOOLS_HTML_O_type
278 + pTypeStr);
279 if( pSubStr )
281 sOut.append(OString::Concat(" " OOO_STRING_SVTOOLS_HTML_O_subtype "=")
282 + pSubStr);
284 if( pFormatStr )
286 sOut.append(OString::Concat(" " OOO_STRING_SVTOOLS_HTML_O_format "=")
287 + pFormatStr);
289 if( !aName.isEmpty() )
291 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_name "=\"");
292 rWrt.Strm().WriteOString( sOut );
293 sOut.setLength(0);
294 HTMLOutFuncs::Out_String( rWrt.Strm(), aName );
295 sOut.append('\"');
297 if( !aValue.isEmpty() )
299 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_value "=\"");
300 rWrt.Strm().WriteOString( sOut );
301 sOut.setLength(0);
302 HTMLOutFuncs::Out_String( rWrt.Strm(), aValue );
303 sOut.append('\"');
305 if( bNumFormat )
307 OSL_ENSURE( nFormat, "number format is 0" );
308 sOut.append(HTMLOutFuncs::CreateTableDataOptionsValNum(
309 bNumValue, dNumValue, nFormat,
310 *rWrt.m_pDoc->GetNumberFormatter()));
312 if( bFixed )
314 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_sdfixed);
316 sOut.append('>');
317 rWrt.Strm().WriteOString( sOut );
318 sOut.setLength(0);
321 // output content of the field
322 OUString const sExpand( pField->ExpandField(true, nullptr) );
323 bool bNeedsCJKProcessing = false;
324 if( !sExpand.isEmpty() )
326 sal_uInt16 nScriptType = g_pBreakIt->GetBreakIter()->getScriptType( sExpand, 0 );
327 sal_Int32 nPos = g_pBreakIt->GetBreakIter()->endOfScript( sExpand, 0,
328 nScriptType );
330 sal_uInt16 nScript =
331 SwHTMLWriter::GetCSS1ScriptForScriptType( nScriptType );
332 if( (nPos < sExpand.getLength() && nPos >= 0) || nScript != rWrt.m_nCSS1Script )
334 bNeedsCJKProcessing = true;
338 if( bNeedsCJKProcessing )
340 //sequence of (start, end) property ranges we want to
341 //query
342 SfxItemSetFixed<RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
343 RES_CHRATR_POSTURE, RES_CHRATR_POSTURE,
344 RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT,
345 RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_WEIGHT>
346 aScriptItemSet( rWrt.m_pDoc->GetAttrPool() );
347 rTextNd.GetParaAttr(aScriptItemSet, nFieldPos, nFieldPos+1);
349 sal_uInt16 aWesternWhichIds[4] =
350 { RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
351 RES_CHRATR_POSTURE, RES_CHRATR_WEIGHT };
352 sal_uInt16 aCJKWhichIds[4] =
353 { RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONTSIZE,
354 RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT };
355 sal_uInt16 aCTLWhichIds[4] =
356 { RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONTSIZE,
357 RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT };
359 sal_uInt16 *pRefWhichIds = nullptr;
360 switch( rWrt.m_nCSS1Script )
362 case CSS1_OUTMODE_WESTERN:
363 pRefWhichIds = aWesternWhichIds;
364 break;
365 case CSS1_OUTMODE_CJK:
366 pRefWhichIds = aCJKWhichIds;
367 break;
368 case CSS1_OUTMODE_CTL:
369 pRefWhichIds = aCTLWhichIds;
370 break;
373 sal_Int32 nPos = 0;
376 sal_uInt16 nScriptType = g_pBreakIt->GetBreakIter()->getScriptType( sExpand, nPos );
377 sal_uInt16 nScript =
378 SwHTMLWriter::GetCSS1ScriptForScriptType( nScriptType );
379 sal_Int32 nEndPos = g_pBreakIt->GetBreakIter()->endOfScript(
380 sExpand, nPos, nScriptType );
381 sal_Int32 nChunkLen = nEndPos - nPos;
382 if( nScript != CSS1_OUTMODE_ANY_SCRIPT &&
383 /* #108791# */ nScript != rWrt.m_nCSS1Script )
385 sal_uInt16 *pWhichIds = nullptr;
386 switch( nScript )
388 case CSS1_OUTMODE_WESTERN: pWhichIds = aWesternWhichIds; break;
389 case CSS1_OUTMODE_CJK: pWhichIds = aCJKWhichIds; break;
390 case CSS1_OUTMODE_CTL: pWhichIds = aCTLWhichIds; break;
393 rWrt.m_bTagOn = true;
395 const SfxPoolItem *aItems[5];
396 int nItems = 0;
398 assert(pWhichIds && pRefWhichIds);
399 if (pWhichIds && pRefWhichIds)
401 for( int i=0; i<4; i++ )
403 const SfxPoolItem *pRefItem =
404 aScriptItemSet.GetItem( pRefWhichIds[i] );
405 const SfxPoolItem *pItem =
406 aScriptItemSet.GetItem( pWhichIds[i] );
407 if( pRefItem && pItem &&
408 !(0==i ? swhtml_css1atr_equalFontItems( *pRefItem, *pItem )
409 : *pRefItem == *pItem) )
411 Out( aHTMLAttrFnTab, *pItem, rWrt );
412 aItems[nItems++] = pItem;
417 HTMLOutFuncs::Out_String( rWrt.Strm(), sExpand.subView( nPos, nChunkLen ) );
419 rWrt.m_bTagOn = false;
420 while( nItems )
421 Out( aHTMLAttrFnTab, *aItems[--nItems], rWrt );
424 else
426 HTMLOutFuncs::Out_String( rWrt.Strm(), sExpand.subView( nPos, nChunkLen ) );
428 nPos = nEndPos;
430 while( nPos < sExpand.getLength() );
432 else
434 HTMLOutFuncs::Out_String( rWrt.Strm(), sExpand );
437 // Output the closing tag.
438 if( pTypeStr )
439 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_sdfield), false );
441 return rWrt;
444 namespace
446 const SwViewOption* GetViewOptionFromDoc(SwDoc* pDoc)
448 SwDocShell* pDocShell = pDoc->GetDocShell();
449 if (!pDocShell)
451 return nullptr;
454 SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
455 if (!pWrtShell)
457 return nullptr;
460 return pWrtShell->GetViewOptions();
464 SwHTMLWriter& OutHTML_SwFormatField( SwHTMLWriter& rWrt, const SfxPoolItem& rHt )
466 const SwFormatField & rField = static_cast<const SwFormatField&>(rHt);
467 const SwField* pField = rField.GetField();
468 const SwFieldType* pFieldTyp = pField->GetTyp();
470 if( SwFieldIds::SetExp == pFieldTyp->Which() &&
471 (nsSwGetSetExpType::GSE_STRING & pField->GetSubType()) )
473 const bool bOn = pFieldTyp->GetName() == "HTML_ON";
474 if (!bOn && pFieldTyp->GetName() != "HTML_OFF")
475 return rWrt;
477 OUString rText(comphelper::string::strip(pField->GetPar2(), ' '));
478 rWrt.Strm().WriteChar( '<' );
479 if( !bOn )
480 rWrt.Strm().WriteChar( '/' );
481 // TODO: HTML-Tags are written without entities, that for, characters
482 // not contained in the destination encoding are lost!
483 OString sTmp(OUStringToOString(rText,
484 RTL_TEXTENCODING_UTF8));
485 rWrt.Strm().WriteOString( sTmp ).WriteChar( '>' );
487 else if( SwFieldIds::Postit == pFieldTyp->Which() )
489 // Comments will be written in ANSI character set, but with system
490 // line breaks.
491 const OUString aComment = pField->GetPar2();
492 bool bWritten = false;
494 if( (aComment.getLength() >= 6 && aComment.startsWith("<") && aComment.endsWith(">") &&
495 o3tl::equalsIgnoreAsciiCase(aComment.subView( 1, 4 ), u"" OOO_STRING_SVTOOLS_HTML_meta) ) ||
496 (aComment.getLength() >= 7 &&
497 aComment.startsWith( "<!--" ) &&
498 aComment.endsWith( "-->" )) )
500 // directly output META tags
501 OUString sComment(convertLineEnd(aComment, GetSystemLineEnd()));
502 // TODO: HTML-Tags are written without entities, that for,
503 // characters not contained in the destination encoding are lost!
504 OString sTmp(OUStringToOString(sComment,
505 RTL_TEXTENCODING_UTF8));
506 rWrt.Strm().WriteOString( sTmp );
507 bWritten = true;
509 else if( aComment.getLength() >= 7 &&
510 aComment.endsWith(">") &&
511 aComment.startsWithIgnoreAsciiCase( "HTML:" ) )
513 OUString sComment(comphelper::string::stripStart(aComment.subView(5), ' '));
514 if( '<' == sComment[0] )
516 sComment = convertLineEnd(sComment, GetSystemLineEnd());
517 // TODO: HTML-Tags are written without entities, that for,
518 // characters not contained in the destination encoding are
519 // lost!
520 OString sTmp(OUStringToOString(sComment,
521 RTL_TEXTENCODING_UTF8));
522 rWrt.Strm().WriteOString( sTmp );
523 bWritten = true;
528 if( !bWritten )
530 OUString sComment(convertLineEnd(aComment, GetSystemLineEnd()));
531 // TODO: ???
532 OString sOut =
533 "<" OOO_STRING_SVTOOLS_HTML_comment
534 " " +
535 OUStringToOString(comphelper::string::encodeForXml(sComment), RTL_TEXTENCODING_UTF8) +
536 " -->";
537 rWrt.Strm().WriteOString( sOut );
540 else if( SwFieldIds::Script == pFieldTyp->Which() )
542 if (rWrt.IsLFPossible())
543 rWrt.OutNewLine( true );
545 bool bURL = static_cast<const SwScriptField *>(pField)->IsCodeURL();
546 const OUString aType = pField->GetPar1();
547 OUString aContents, aURL;
548 if(bURL)
549 aURL = pField->GetPar2();
550 else
551 aContents = pField->GetPar2();
553 // otherwise is the script content itself. Since only JavaScript
554 // is in fields, it must be JavaScript ...:)
555 HTMLOutFuncs::OutScript( rWrt.Strm(), rWrt.GetBaseURL(), aContents, aType, JAVASCRIPT,
556 aURL, nullptr, nullptr );
558 if (rWrt.IsLFPossible())
559 rWrt.OutNewLine( true );
561 else
563 const SwTextField *pTextField = rField.GetTextField();
564 OSL_ENSURE( pTextField, "Where is the txt fld?" );
565 if (pTextField)
567 const SwViewOption* pViewOptions = GetViewOptionFromDoc(rWrt.m_pDoc);
568 // ReqIF-XHTML doesn't allow specifying a background color.
569 bool bFieldShadings = pViewOptions && pViewOptions->IsFieldShadings() && !rWrt.mbReqIF;
570 if (bFieldShadings)
572 // If there is a text portion background started already, that should have priority.
573 auto it = rWrt.maStartedAttributes.find(RES_CHRATR_BACKGROUND);
574 if (it != rWrt.maStartedAttributes.end())
575 bFieldShadings = it->second <= 0;
578 if (bFieldShadings)
580 const Color& rColor = pViewOptions->GetFieldShadingsColor();
581 OString sOut(
582 "<" + rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span
583 " " OOO_STRING_SVTOOLS_HTML_O_style "=\""
584 + sCSS1_P_background
585 + ": "
586 + GetCSS1_Color(rColor)
587 + "\">");
588 rWrt.Strm().WriteOString(sOut);
591 OutHTML_SwField( rWrt, pField, pTextField->GetTextNode(),
592 pTextField->GetStart() );
594 if (bFieldShadings)
595 HTMLOutFuncs::Out_AsciiTag(
596 rWrt.Strm(), Concat2View(rWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span), false);
599 return rWrt;
602 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */