1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <com/sun/star/i18n/XBreakIterator.hpp>
21 #include <comphelper/string.hxx>
22 #include <svtools/htmlkywd.hxx>
23 #include <svtools/htmlout.hxx>
24 #include <osl/diagnose.h>
25 #include <fmtfld.hxx>
26 #include <doc.hxx>
27 #include <breakit.hxx>
28 #include <ndtxt.hxx>
29 #include <txtfld.hxx>
30 #include <fldbas.hxx>
31 #include <docufld.hxx>
32 #include <flddat.hxx>
33 #include <viewopt.hxx>
34 #include "htmlfld.hxx"
35 #include "wrthtml.hxx"
36 #include <rtl/strbuf.hxx>
37 #include "css1atr.hxx"
38 #include "css1kywd.hxx"
39
40 using namespace nsSwDocInfoSubType;
41
GetNumFormat(sal_uInt16 nFormat)42 const char *SwHTMLWriter::GetNumFormat( sal_uInt16 nFormat )
43 {
44 const char *pFormatStr = nullptr;
45
46 switch( static_cast<SvxNumType>(nFormat) )
47 {
48 case SVX_NUM_CHARS_UPPER_LETTER: pFormatStr = OOO_STRING_SW_HTML_FF_uletter; break;
49 case SVX_NUM_CHARS_LOWER_LETTER: pFormatStr = OOO_STRING_SW_HTML_FF_lletter; break;
50 case SVX_NUM_ROMAN_UPPER: pFormatStr = OOO_STRING_SW_HTML_FF_uroman; break;
51 case SVX_NUM_ROMAN_LOWER: pFormatStr = OOO_STRING_SW_HTML_FF_lroman; break;
52 case SVX_NUM_ARABIC: pFormatStr = OOO_STRING_SW_HTML_FF_arabic; break;
53 case SVX_NUM_NUMBER_NONE: pFormatStr = OOO_STRING_SW_HTML_FF_none; break;
54 case SVX_NUM_CHAR_SPECIAL: pFormatStr = OOO_STRING_SW_HTML_FF_char; break;
55 case SVX_NUM_PAGEDESC: pFormatStr = OOO_STRING_SW_HTML_FF_page; break;
56 case SVX_NUM_CHARS_UPPER_LETTER_N: pFormatStr = OOO_STRING_SW_HTML_FF_ulettern; break;
57 case SVX_NUM_CHARS_LOWER_LETTER_N: pFormatStr = OOO_STRING_SW_HTML_FF_llettern; break;
58 default:
59 ;
60 }
61
62 return pFormatStr;
63 }
64
OutHTML_SwField(Writer & rWrt,const SwField * pField,const SwTextNode & rTextNd,sal_Int32 nFieldPos)65 static Writer& OutHTML_SwField( Writer& rWrt, const SwField* pField,
66 const SwTextNode& rTextNd, sal_Int32 nFieldPos )
67 {
68 SwHTMLWriter & rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
69
70 const SwFieldType* pFieldTyp = pField->GetTyp();
71 SwFieldIds nField = pFieldTyp->Which();
72 sal_uLong nFormat = pField->GetFormat();
73
74 const char *pTypeStr=nullptr, // TYPE
75 *pSubStr=nullptr, // SUBTYPE
76 *pFormatStr=nullptr; // FORMAT (SW)
77 OUString aValue; // VALUE (SW)
78 bool bNumFormat=false; // SDNUM (Number-Formatter-Format)
79 bool bNumValue=false; // SDVAL (Number-Formatter-Value)
80 double dNumValue = 0.0; // SDVAL (Number-Formatter-Value)
81 bool bFixed=false; // SDFIXED
82 OUString aName; // NAME (CUSTOM)
83
84 switch( nField )
85 {
86 case SwFieldIds::ExtUser:
87 pTypeStr = OOO_STRING_SW_HTML_FT_sender;
88 switch( static_cast<SwExtUserSubType>(pField->GetSubType()) )
89 {
90 case EU_COMPANY: pSubStr = OOO_STRING_SW_HTML_FS_company; break;
91 case EU_FIRSTNAME: pSubStr = OOO_STRING_SW_HTML_FS_firstname; break;
92 case EU_NAME: pSubStr = OOO_STRING_SW_HTML_FS_name; break;
93 case EU_SHORTCUT: pSubStr = OOO_STRING_SW_HTML_FS_shortcut; break;
94 case EU_STREET: pSubStr = OOO_STRING_SW_HTML_FS_street; break;
95 case EU_COUNTRY: pSubStr = OOO_STRING_SW_HTML_FS_country; break;
96 case EU_ZIP: pSubStr = OOO_STRING_SW_HTML_FS_zip; break;
97 case EU_CITY: pSubStr = OOO_STRING_SW_HTML_FS_city; break;
98 case EU_TITLE: pSubStr = OOO_STRING_SW_HTML_FS_title; break;
99 case EU_POSITION: pSubStr = OOO_STRING_SW_HTML_FS_position; break;
100 case EU_PHONE_PRIVATE: pSubStr = OOO_STRING_SW_HTML_FS_pphone; break;
101 case EU_PHONE_COMPANY: pSubStr = OOO_STRING_SW_HTML_FS_cphone; break;
102 case EU_FAX: pSubStr = OOO_STRING_SW_HTML_FS_fax; break;
103 case EU_EMAIL: pSubStr = OOO_STRING_SW_HTML_FS_email; break;
104 case EU_STATE: pSubStr = OOO_STRING_SW_HTML_FS_state; break;
105 default:
106 ;
107 }
108 OSL_ENSURE( pSubStr, "unknown sub type for SwExtUserField" );
109 bFixed = static_cast<const SwExtUserField*>(pField)->IsFixed();
110 break;
111
112 case SwFieldIds::Author:
113 pTypeStr = OOO_STRING_SW_HTML_FT_author;
114 switch( static_cast<SwAuthorFormat>(nFormat) & 0xff)
115 {
116 case AF_NAME: pFormatStr = OOO_STRING_SW_HTML_FF_name; break;
117 case AF_SHORTCUT: pFormatStr = OOO_STRING_SW_HTML_FF_shortcut; break;
118 }
119 OSL_ENSURE( pFormatStr, "unknown format for SwAuthorField" );
120 bFixed = static_cast<const SwAuthorField*>(pField)->IsFixed();
121 break;
122
123 case SwFieldIds::DateTime:
124 pTypeStr = OOO_STRING_SW_HTML_FT_datetime;
125 bNumFormat = true;
126 if( static_cast<const SwDateTimeField*>(pField)->IsFixed() )
127 {
128 bNumValue = true;
129 dNumValue = static_cast<const SwDateTimeField*>(pField)->GetValue();
130 }
131 break;
132
133 case SwFieldIds::PageNumber:
134 {
135 pTypeStr = OOO_STRING_SW_HTML_FT_page;
136 SwPageNumSubType eSubType = static_cast<SwPageNumSubType>(pField->GetSubType());
137 switch( eSubType )
138 {
139 case PG_RANDOM: pSubStr = OOO_STRING_SW_HTML_FS_random; break;
140 case PG_NEXT: pSubStr = OOO_STRING_SW_HTML_FS_next; break;
141 case PG_PREV: pSubStr = OOO_STRING_SW_HTML_FS_prev; break;
142 }
143 OSL_ENSURE( pSubStr, "unknown sub type for SwPageNumberField" );
144 pFormatStr = SwHTMLWriter::GetNumFormat( static_cast< sal_uInt16 >(nFormat) );
145
146 if( static_cast<SvxNumType>(nFormat)==SVX_NUM_CHAR_SPECIAL )
147 {
148 aValue = static_cast<const SwPageNumberField *>(pField)->GetUserString();
149 }
150 else
151 {
152 const OUString& rValue = pField->GetPar2();
153 short nValue = static_cast<short>(rValue.toInt32());
154 if( (eSubType == PG_NEXT && nValue!=1) ||
155 (eSubType == PG_PREV && nValue!=-1) ||
156 (eSubType == PG_RANDOM && nValue!=0) )
157 {
158 aValue = rValue;
159 }
160 }
161 }
162 break;
163 case SwFieldIds::DocInfo:
164 {
165 sal_uInt16 nSubType = pField->GetSubType();
166 pTypeStr = OOO_STRING_SW_HTML_FT_docinfo;
167 sal_uInt16 nExtSubType = nSubType & 0x0f00;
168 nSubType &= 0x00ff;
169
170 switch( nSubType )
171 {
172 case DI_TITLE: pSubStr = OOO_STRING_SW_HTML_FS_title; break;
173 case DI_SUBJECT: pSubStr = OOO_STRING_SW_HTML_FS_theme; break;
174 case DI_KEYS: pSubStr = OOO_STRING_SW_HTML_FS_keys; break;
175 case DI_COMMENT: pSubStr = OOO_STRING_SW_HTML_FS_comment; break;
176 case DI_CREATE: pSubStr = OOO_STRING_SW_HTML_FS_create; break;
177 case DI_CHANGE: pSubStr = OOO_STRING_SW_HTML_FS_change; break;
178 case DI_CUSTOM: pSubStr = OOO_STRING_SW_HTML_FS_custom; break;
179 default: pTypeStr = nullptr; break;
180 }
181
182 if( DI_CUSTOM == nSubType ) {
183 aName = static_cast<const SwDocInfoField*>(pField)->GetName();
184 }
185
186 if( DI_CREATE == nSubType || DI_CHANGE == nSubType )
187 {
188 switch( nExtSubType )
189 {
190 case DI_SUB_AUTHOR:
191 pFormatStr = OOO_STRING_SW_HTML_FF_author;
192 break;
193 case DI_SUB_TIME:
194 pFormatStr = OOO_STRING_SW_HTML_FF_time;
195 bNumFormat = true;
196 break;
197 case DI_SUB_DATE:
198 pFormatStr = OOO_STRING_SW_HTML_FF_date;
199 bNumFormat = true;
200 break;
201 }
202 }
203 bFixed = static_cast<const SwDocInfoField*>(pField)->IsFixed();
204 if( bNumFormat )
205 {
206 if( bFixed )
207 {
208 // For a fixed field output the num value too.
209 // Fixed fields without number format shouldn't
210 // exist. See below for OSL_ENSURE().
211 dNumValue = static_cast<const SwDocInfoField*>(pField)->GetValue();
212 bNumValue = true;
213 }
214 else if( !nFormat )
215 {
216 // Non-fixed fields may not have a number format, when
217 // they come from a 4.0-document.
218 bNumFormat = false;
219 }
220 }
221 }
222 break;
223
224 case SwFieldIds::DocStat:
225 {
226 pTypeStr = OOO_STRING_SW_HTML_FT_docstat;
227 sal_uInt16 nSubType = pField->GetSubType();
228 switch( nSubType )
229 {
230 case DS_PAGE: pSubStr = OOO_STRING_SW_HTML_FS_page; break;
231 case DS_PARA: pSubStr = OOO_STRING_SW_HTML_FS_para; break;
232 case DS_WORD: pSubStr = OOO_STRING_SW_HTML_FS_word; break;
233 case DS_CHAR: pSubStr = OOO_STRING_SW_HTML_FS_char; break;
234 case DS_TBL: pSubStr = OOO_STRING_SW_HTML_FS_tbl; break;
235 case DS_GRF: pSubStr = OOO_STRING_SW_HTML_FS_grf; break;
236 case DS_OLE: pSubStr = OOO_STRING_SW_HTML_FS_ole; break;
237 default: pTypeStr = nullptr; break;
238 }
239 pFormatStr = SwHTMLWriter::GetNumFormat( static_cast< sal_uInt16 >(nFormat) );
240 }
241 break;
242
243 case SwFieldIds::Filename:
244 pTypeStr = OOO_STRING_SW_HTML_FT_filename;
245 switch( static_cast<SwFileNameFormat>(nFormat & ~FF_FIXED) )
246 {
247 case FF_NAME: pFormatStr = OOO_STRING_SW_HTML_FF_name; break;
248 case FF_PATHNAME: pFormatStr = OOO_STRING_SW_HTML_FF_pathname; break;
249 case FF_PATH: pFormatStr = OOO_STRING_SW_HTML_FF_path; break;
250 case FF_NAME_NOEXT: pFormatStr = OOO_STRING_SW_HTML_FF_name_noext; break;
251 default:
252 ;
253 }
254 bFixed = static_cast<const SwFileNameField*>(pField)->IsFixed();
255 OSL_ENSURE( pFormatStr, "unknown format for SwFileNameField" );
256 break;
257 default: break;
258 }
259
260 // ReqIF-XHTML doesn't allow <sdfield>.
261 if (rHTMLWrt.mbReqIF && pTypeStr)
262 {
263 pTypeStr = nullptr;
264 }
265
266 // Output the <sdfield> tag.
267 if( pTypeStr )
268 {
269 OStringBuffer sOut;
270 sOut.append('<');
271 sOut.append(rHTMLWrt.GetNamespace());
272 sOut.append(OOO_STRING_SVTOOLS_HTML_sdfield).append(' ').
273 append(OOO_STRING_SVTOOLS_HTML_O_type).append('=').
274 append(pTypeStr);
275 if( pSubStr )
276 {
277 sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_subtype).
278 append('=').append(pSubStr);
279 }
280 if( pFormatStr )
281 {
282 sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_format).
283 append('=').append(pFormatStr);
284 }
285 if( !aName.isEmpty() )
286 {
287 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_name "=\"");
288 rWrt.Strm().WriteOString( sOut.makeStringAndClear() );
289 HTMLOutFuncs::Out_String( rWrt.Strm(), aName, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
290 sOut.append('\"');
291 }
292 if( !aValue.isEmpty() )
293 {
294 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_value "=\"");
295 rWrt.Strm().WriteOString( sOut.makeStringAndClear() );
296 HTMLOutFuncs::Out_String( rWrt.Strm(), aValue, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
297 sOut.append('\"');
298 }
299 if( bNumFormat )
300 {
301 OSL_ENSURE( nFormat, "number format is 0" );
302 sOut.append(HTMLOutFuncs::CreateTableDataOptionsValNum(
303 bNumValue, dNumValue, nFormat,
304 *rHTMLWrt.m_pDoc->GetNumberFormatter(), rHTMLWrt.m_eDestEnc,
305 &rHTMLWrt.m_aNonConvertableCharacters));
306 }
307 if( bFixed )
308 {
309 sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_sdfixed);
310 }
311 sOut.append('>');
312 rWrt.Strm().WriteOString( sOut.makeStringAndClear() );
313 }
314
315 // output content of the field
316 OUString const sExpand( pField->ExpandField(true, nullptr) );
317 bool bNeedsCJKProcessing = false;
318 if( !sExpand.isEmpty() )
319 {
320 sal_uInt16 nScriptType = g_pBreakIt->GetBreakIter()->getScriptType( sExpand, 0 );
321 sal_Int32 nPos = g_pBreakIt->GetBreakIter()->endOfScript( sExpand, 0,
322 nScriptType );
323
324 sal_uInt16 nScript =
325 SwHTMLWriter::GetCSS1ScriptForScriptType( nScriptType );
326 if( (nPos < sExpand.getLength() && nPos >= 0) || nScript != rHTMLWrt.m_nCSS1Script )
327 {
328 bNeedsCJKProcessing = true;
329 }
330 }
331
332 if( bNeedsCJKProcessing )
333 {
334 //sequence of (start, end) property ranges we want to
335 //query
336 SfxItemSet aScriptItemSet( rWrt.m_pDoc->GetAttrPool(),
337 svl::Items<RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
338 RES_CHRATR_POSTURE, RES_CHRATR_POSTURE,
339 RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT,
340 RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_WEIGHT>{} );
341 rTextNd.GetParaAttr(aScriptItemSet, nFieldPos, nFieldPos+1);
342
343 sal_uInt16 aWesternWhichIds[4] =
344 { RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
345 RES_CHRATR_POSTURE, RES_CHRATR_WEIGHT };
346 sal_uInt16 aCJKWhichIds[4] =
347 { RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONTSIZE,
348 RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT };
349 sal_uInt16 aCTLWhichIds[4] =
350 { RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONTSIZE,
351 RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT };
352
353 sal_uInt16 *pRefWhichIds = nullptr;
354 switch( rHTMLWrt.m_nCSS1Script )
355 {
356 case CSS1_OUTMODE_WESTERN:
357 pRefWhichIds = aWesternWhichIds;
358 break;
359 case CSS1_OUTMODE_CJK:
360 pRefWhichIds = aCJKWhichIds;
361 break;
362 case CSS1_OUTMODE_CTL:
363 pRefWhichIds = aCTLWhichIds;
364 break;
365 }
366
367 sal_Int32 nPos = 0;
368 do
369 {
370 sal_uInt16 nScriptType = g_pBreakIt->GetBreakIter()->getScriptType( sExpand, nPos );
371 sal_uInt16 nScript =
372 SwHTMLWriter::GetCSS1ScriptForScriptType( nScriptType );
373 sal_Int32 nEndPos = g_pBreakIt->GetBreakIter()->endOfScript(
374 sExpand, nPos, nScriptType );
375 sal_Int32 nChunkLen = nEndPos - nPos;
376 if( nScript != CSS1_OUTMODE_ANY_SCRIPT &&
377 /* #108791# */ nScript != rHTMLWrt.m_nCSS1Script )
378 {
379 sal_uInt16 *pWhichIds = nullptr;
380 switch( nScript )
381 {
382 case CSS1_OUTMODE_WESTERN: pWhichIds = aWesternWhichIds; break;
383 case CSS1_OUTMODE_CJK: pWhichIds = aCJKWhichIds; break;
384 case CSS1_OUTMODE_CTL: pWhichIds = aCTLWhichIds; break;
385 }
386
387 rHTMLWrt.m_bTagOn = true;
388
389 const SfxPoolItem *aItems[5];
390 int nItems = 0;
391
392 assert(pWhichIds && pRefWhichIds);
393 if (pWhichIds && pRefWhichIds)
394 {
395 for( int i=0; i<4; i++ )
396 {
397 const SfxPoolItem *pRefItem =
398 aScriptItemSet.GetItem( pRefWhichIds[i] );
399 const SfxPoolItem *pItem =
400 aScriptItemSet.GetItem( pWhichIds[i] );
401 if( pRefItem && pItem &&
402 !(0==i ? swhtml_css1atr_equalFontItems( *pRefItem, *pItem )
403 : *pRefItem == *pItem) )
404 {
405 Out( aHTMLAttrFnTab, *pItem, rHTMLWrt );
406 aItems[nItems++] = pItem;
407 }
408 }
409 }
410
411 HTMLOutFuncs::Out_String( rWrt.Strm(), sExpand.copy( nPos, nChunkLen ),
412 rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
413
414 rHTMLWrt.m_bTagOn = false;
415 while( nItems )
416 Out( aHTMLAttrFnTab, *aItems[--nItems], rHTMLWrt );
417
418 }
419 else
420 {
421 HTMLOutFuncs::Out_String( rWrt.Strm(), sExpand.copy( nPos, nChunkLen ),
422 rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
423 }
424 nPos = nEndPos;
425 }
426 while( nPos < sExpand.getLength() );
427 }
428 else
429 {
430 HTMLOutFuncs::Out_String( rWrt.Strm(), sExpand,
431 rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
432 }
433
434 // Output the closing tag.
435 if( pTypeStr )
436 HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OString(rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_sdfield), false );
437
438 return rWrt;
439 }
440
OutHTML_SwFormatField(Writer & rWrt,const SfxPoolItem & rHt)441 Writer& OutHTML_SwFormatField( Writer& rWrt, const SfxPoolItem& rHt )
442 {
443 SwHTMLWriter& rHTMLWrt = static_cast<SwHTMLWriter&>(rWrt);
444 const SwFormatField & rField = static_cast<const SwFormatField&>(rHt);
445 const SwField* pField = rField.GetField();
446 const SwFieldType* pFieldTyp = pField->GetTyp();
447
448 if( SwFieldIds::SetExp == pFieldTyp->Which() &&
449 (nsSwGetSetExpType::GSE_STRING & pField->GetSubType()) )
450 {
451 const bool bOn = pFieldTyp->GetName() == "HTML_ON";
452 if (!bOn && pFieldTyp->GetName() != "HTML_OFF")
453 return rWrt;
454
455 OUString rText(comphelper::string::strip(pField->GetPar2(), ' '));
456 rWrt.Strm().WriteChar( '<' );
457 if( !bOn )
458 rWrt.Strm().WriteChar( '/' );
459 // TODO: HTML-Tags are written without entities, that for, characters
460 // not contained in the destination encoding are lost!
461 OString sTmp(OUStringToOString(rText,
462 static_cast<SwHTMLWriter&>(rWrt).m_eDestEnc));
463 rWrt.Strm().WriteOString( sTmp ).WriteChar( '>' );
464 }
465 else if( SwFieldIds::Postit == pFieldTyp->Which() )
466 {
467 // Comments will be written in ANSI character set, but with system
468 // line breaks.
469 const OUString& rComment = pField->GetPar2();
470 bool bWritten = false;
471
472 if( (rComment.getLength() >= 6 && rComment.startsWith("<") && rComment.endsWith(">") &&
473 rComment.copy( 1, 4 ).equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_meta) ) ||
474 (rComment.getLength() >= 7 &&
475 rComment.startsWith( "<!--" ) &&
476 rComment.endsWith( "-->" )) )
477 {
478 // directly output META tags
479 OUString sComment(convertLineEnd(rComment, GetSystemLineEnd()));
480 // TODO: HTML-Tags are written without entities, that for,
481 // characters not contained in the destination encoding are lost!
482 OString sTmp(OUStringToOString(sComment,
483 static_cast<SwHTMLWriter&>(rWrt).m_eDestEnc));
484 rWrt.Strm().WriteOString( sTmp );
485 bWritten = true;
486 }
487 else if( rComment.getLength() >= 7 &&
488 rComment.endsWith(">") &&
489 rComment.startsWithIgnoreAsciiCase( "HTML:" ) )
490 {
491 OUString sComment(comphelper::string::stripStart(rComment.subView(5), ' '));
492 if( '<' == sComment[0] )
493 {
494 sComment = convertLineEnd(sComment, GetSystemLineEnd());
495 // TODO: HTML-Tags are written without entities, that for,
496 // characters not contained in the destination encoding are
497 // lost!
498 OString sTmp(OUStringToOString(sComment,
499 static_cast<SwHTMLWriter&>(rWrt).m_eDestEnc));
500 rWrt.Strm().WriteOString( sTmp );
501 bWritten = true;
502 }
503
504 }
505
506 if( !bWritten )
507 {
508 OUString sComment(convertLineEnd(rComment, GetSystemLineEnd()));
509 // TODO: ???
510 OString sOut =
511 "<" OOO_STRING_SVTOOLS_HTML_comment
512 " " +
513 OUStringToOString(sComment, static_cast<SwHTMLWriter&>(rWrt).m_eDestEnc) +
514 " -->";
515 rWrt.Strm().WriteOString( sOut );
516 }
517 }
518 else if( SwFieldIds::Script == pFieldTyp->Which() )
519 {
520 if( rHTMLWrt.m_bLFPossible )
521 rHTMLWrt.OutNewLine( true );
522
523 bool bURL = static_cast<const SwScriptField *>(pField)->IsCodeURL();
524 const OUString& rType = pField->GetPar1();
525 OUString aContents, aURL;
526 if(bURL)
527 aURL = pField->GetPar2();
528 else
529 aContents = pField->GetPar2();
530
531 // otherwise is the script content itself. Since only JavaScript
532 // is in fields, it must be JavaScript ...:)
533 HTMLOutFuncs::OutScript( rWrt.Strm(), rWrt.GetBaseURL(), aContents, rType, JAVASCRIPT,
534 aURL, nullptr, nullptr, rHTMLWrt.m_eDestEnc, &rHTMLWrt.m_aNonConvertableCharacters );
535
536 if( rHTMLWrt.m_bLFPossible )
537 rHTMLWrt.OutNewLine( true );
538 }
539 else
540 {
541 const SwTextField *pTextField = rField.GetTextField();
542 OSL_ENSURE( pTextField, "Where is the txt fld?" );
543 if( pTextField )
544 {
545 // ReqIF-XHTML doesn't allow specifying a background color.
546 bool bFieldShadings = SwViewOption::IsFieldShadings() && !rHTMLWrt.mbReqIF;
547 if (bFieldShadings)
548 {
549 // If there is a text portion background started already, that should have priority.
550 auto it = rHTMLWrt.maStartedAttributes.find(RES_CHRATR_BACKGROUND);
551 if (it != rHTMLWrt.maStartedAttributes.end())
552 bFieldShadings = it->second <= 0;
553 }
554
555 if (bFieldShadings)
556 {
557 OStringBuffer sOut;
558 sOut.append("<" + rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span);
559 sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_style "=\"");
560 sOut.append(sCSS1_P_background);
561 sOut.append(": ");
562
563 Color& rColor = SwViewOption::GetFieldShadingsColor();
564 sOut.append(GetCSS1_Color(rColor));
565 sOut.append("\">");
566 rWrt.Strm().WriteOString(sOut.makeStringAndClear());
567 }
568
569 OutHTML_SwField( rWrt, pField, pTextField->GetTextNode(),
570 pTextField->GetStart() );
571
572 if (bFieldShadings)
573 HTMLOutFuncs::Out_AsciiTag(
574 rWrt.Strm(), OString(rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_span), false);
575 }
576 }
577 return rWrt;
578 }
579
580 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
581