1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include <tools/urlobj.hxx>
22 #include <tools/debug.hxx>
24 #include <sfx2/docfile.hxx>
25 #include <sfx2/event.hxx>
26 #include <openflag.hxx>
28 #include <svl/numformat.hxx>
29 #include <svtools/htmlkywd.hxx>
30 #include <svtools/htmltokn.h>
31 #include <vcl/imap.hxx>
32 #include <vcl/imapcirc.hxx>
33 #include <vcl/imapobj.hxx>
34 #include <vcl/imappoly.hxx>
35 #include <vcl/imaprect.hxx>
36 #include <svl/zforlist.hxx>
38 #include <sfx2/sfxhtml.hxx>
40 #include <comphelper/string.hxx>
41 #include <o3tl/string_view.hxx>
46 using namespace ::com::sun::star
;
50 HTMLOptionEnum
<IMapObjectType
> const aAreaShapeOptEnums
[] =
52 { OOO_STRING_SVTOOLS_HTML_SH_rect
, IMapObjectType::Rectangle
},
53 { OOO_STRING_SVTOOLS_HTML_SH_rectangle
, IMapObjectType::Rectangle
},
54 { OOO_STRING_SVTOOLS_HTML_SH_circ
, IMapObjectType::Circle
},
55 { OOO_STRING_SVTOOLS_HTML_SH_circle
, IMapObjectType::Circle
},
56 { OOO_STRING_SVTOOLS_HTML_SH_poly
, IMapObjectType::Polygon
},
57 { OOO_STRING_SVTOOLS_HTML_SH_polygon
, IMapObjectType::Polygon
},
58 { nullptr, IMapObjectType::Rectangle
}
61 SfxHTMLParser::SfxHTMLParser( SvStream
& rStream
, bool bIsNewDoc
,
63 : HTMLParser(rStream
, bIsNewDoc
)
65 , eScriptType(STARBASIC
)
67 DBG_ASSERT( RTL_TEXTENCODING_UTF8
== GetSrcEncoding( ),
68 "SfxHTMLParser::SfxHTMLParser: From where comes ZS?" );
70 DBG_ASSERT( !IsSwitchToUCS2(),
71 "SfxHTMLParser::SfxHTMLParser: Switch to UCS2?" );
73 // If the file starts with a BOM, switch to UCS2.
74 SetSwitchToUCS2( true );
77 SfxHTMLParser::~SfxHTMLParser()
79 DBG_ASSERT( !pDLMedium
, "Here is a File Download that has got stuck" );
82 bool SfxHTMLParser::ParseMapOptions(
83 ImageMap
* pImageMap
, const HTMLOptions
& rOptions
)
85 DBG_ASSERT( pImageMap
, "ParseMapOptions: No Image-Map" );
89 for (size_t i
= rOptions
.size(); i
; )
91 const HTMLOption
& aOption
= rOptions
[--i
];
92 if ( aOption
.GetToken() == HtmlOptionId::NAME
)
93 aName
= aOption
.GetString();
96 if( !aName
.isEmpty() )
97 pImageMap
->SetName( aName
);
99 return !aName
.isEmpty();
102 bool SfxHTMLParser::ParseAreaOptions(ImageMap
* pImageMap
, std::u16string_view rBaseURL
,
103 const HTMLOptions
& rOptions
,
104 SvMacroItemId nEventMouseOver
,
105 SvMacroItemId nEventMouseOut
)
107 DBG_ASSERT( pImageMap
, "ParseAreaOptions: no Image-Map" );
109 IMapObjectType nShape
= IMapObjectType::Rectangle
;
110 std::vector
<sal_uInt32
> aCoords
;
111 OUString aName
, aHRef
, aAlt
, aTarget
;
112 bool bNoHRef
= false;
113 SvxMacroTableDtor aMacroTbl
;
115 for (size_t i
= rOptions
.size(); i
; )
117 SvMacroItemId nEvent
= SvMacroItemId::NONE
;
118 ScriptType eScrpType
= STARBASIC
;
119 const HTMLOption
& rOption
= rOptions
[--i
];
120 switch( rOption
.GetToken() )
122 case HtmlOptionId::NAME
:
123 aName
= rOption
.GetString();
125 case HtmlOptionId::SHAPE
:
126 rOption
.GetEnum( nShape
, aAreaShapeOptEnums
);
128 case HtmlOptionId::COORDS
:
129 rOption
.GetNumbers( aCoords
);
131 case HtmlOptionId::HREF
:
132 aHRef
= INetURLObject::GetAbsURL( rBaseURL
, rOption
.GetString() );
134 case HtmlOptionId::NOHREF
:
137 case HtmlOptionId::ALT
:
138 aAlt
= rOption
.GetString();
140 case HtmlOptionId::TARGET
:
141 aTarget
= rOption
.GetString();
144 case HtmlOptionId::ONMOUSEOVER
:
145 eScrpType
= JAVASCRIPT
;
147 case HtmlOptionId::SDONMOUSEOVER
:
148 nEvent
= nEventMouseOver
;
149 goto IMAPOBJ_SETEVENT
;
151 case HtmlOptionId::ONMOUSEOUT
:
152 eScrpType
= JAVASCRIPT
;
154 case HtmlOptionId::SDONMOUSEOUT
:
155 nEvent
= nEventMouseOut
;
156 goto IMAPOBJ_SETEVENT
;
158 if( nEvent
!= SvMacroItemId::NONE
)
160 OUString
sTmp( rOption
.GetString() );
161 if( !sTmp
.isEmpty() )
163 sTmp
= convertLineEnd(sTmp
, GetSystemLineEnd());
164 aMacroTbl
.Insert( nEvent
, SvxMacro( sTmp
, u
""_ustr
, eScrpType
));
175 bool bNewArea
= true;
178 case IMapObjectType::Rectangle
:
179 if( aCoords
.size() >=4 )
181 tools::Rectangle
aRect( aCoords
[0], aCoords
[1],
182 aCoords
[2], aCoords
[3] );
183 std::unique_ptr
<IMapRectangleObject
> pMapRObj( new IMapRectangleObject(aRect
, aHRef
, aAlt
, OUString(), aTarget
, aName
,
185 if( !aMacroTbl
.empty() )
186 pMapRObj
->SetMacroTable( aMacroTbl
);
187 pImageMap
->InsertIMapObject( std::move(pMapRObj
) );
190 case IMapObjectType::Circle
:
191 if( aCoords
.size() >=3 )
193 Point
aPoint( aCoords
[0], aCoords
[1] );
194 std::unique_ptr
<IMapCircleObject
> pMapCObj(new IMapCircleObject(aPoint
, aCoords
[2],aHRef
, aAlt
, OUString(),
195 aTarget
, aName
, !bNoHRef
));
196 if( !aMacroTbl
.empty() )
197 pMapCObj
->SetMacroTable( aMacroTbl
);
198 pImageMap
->InsertIMapObject( std::move(pMapCObj
) );
201 case IMapObjectType::Polygon
:
202 if( aCoords
.size() >=6 )
204 sal_uInt16 nCount
= aCoords
.size() / 2;
205 tools::Polygon
aPoly( nCount
);
206 for( sal_uInt16 i
=0; i
<nCount
; i
++ )
207 aPoly
[i
] = Point( aCoords
[2*i
], aCoords
[2*i
+1] );
208 std::unique_ptr
<IMapPolygonObject
> pMapPObj(new IMapPolygonObject( aPoly
, aHRef
, aAlt
, OUString(), aTarget
, aName
,
210 if( !aMacroTbl
.empty() )
211 pMapPObj
->SetMacroTable( aMacroTbl
);
212 pImageMap
->InsertIMapObject( std::move(pMapPObj
) );
222 void SfxHTMLParser::StartFileDownload(const OUString
& rURL
)
224 DBG_ASSERT( !pDLMedium
, "StartFileDownload when active Download" );
228 pDLMedium
.reset( new SfxMedium( rURL
, SFX_STREAM_READONLY
) );
229 pDLMedium
->Download();
232 bool SfxHTMLParser::FinishFileDownload( OUString
& rStr
)
234 bool bOK
= pDLMedium
&& pDLMedium
->GetErrorCode() == ERRCODE_NONE
;
237 SvStream
* pStream
= pDLMedium
->GetInStream();
238 DBG_ASSERT( pStream
, "No In-Stream received from Medium" );
240 SvMemoryStream aStream
;
242 aStream
.WriteStream( *pStream
);
244 sal_uInt64
const nLen
= aStream
.TellEnd();
246 rStr
= read_uInt8s_ToOUString(aStream
, nLen
, RTL_TEXTENCODING_UTF8
);
254 void SfxHTMLParser::GetScriptType_Impl( SvKeyValueIterator
*pHTTPHeader
)
256 aScriptType
= SVX_MACRO_LANGUAGE_JAVASCRIPT
;
257 eScriptType
= JAVASCRIPT
;
262 for( bool bCont
= pHTTPHeader
->GetFirst( aKV
); bCont
;
263 bCont
= pHTTPHeader
->GetNext( aKV
) )
265 if( aKV
.GetKey().equalsIgnoreAsciiCase(
266 OOO_STRING_SVTOOLS_HTML_META_content_script_type
) )
268 if( !aKV
.GetValue().isEmpty() )
270 OUString
aTmp( aKV
.GetValue() );
271 if( aTmp
.startsWithIgnoreAsciiCase( "text/" ) )
272 aTmp
= aTmp
.copy( 5 );
273 else if( aTmp
.startsWithIgnoreAsciiCase( "application/" ) )
274 aTmp
= aTmp
.copy( 12 );
278 if( aTmp
.startsWithIgnoreAsciiCase( "x-" ) ) // MIME-experimental
280 aTmp
= aTmp
.copy( 2 );
283 if( aTmp
.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_LG_starbasic
) )
285 eScriptType
= STARBASIC
;
286 aScriptType
= SVX_MACRO_LANGUAGE_STARBASIC
;
288 if( !aTmp
.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_LG_javascript
) )
290 eScriptType
= EXTENDED_STYPE
;
299 ScriptType
SfxHTMLParser::GetScriptType( SvKeyValueIterator
*pHTTPHeader
) const
301 if( aScriptType
.isEmpty() )
302 const_cast<SfxHTMLParser
*>(this)->GetScriptType_Impl( pHTTPHeader
);
307 const OUString
& SfxHTMLParser::GetScriptTypeString(
308 SvKeyValueIterator
*pHTTPHeader
) const
310 if( aScriptType
.isEmpty() )
311 const_cast<SfxHTMLParser
*>(this)->GetScriptType_Impl( pHTTPHeader
);
316 double SfxHTMLParser::GetTableDataOptionsValNum( sal_uInt32
& nNumForm
,
317 LanguageType
& eNumLang
, const OUString
& aValStr
, std::u16string_view aNumStr
,
318 SvNumberFormatter
& rFormatter
)
320 LanguageType
eParseLang(o3tl::toInt32(aNumStr
));
321 sal_uInt32 nParseForm
= rFormatter
.GetFormatForLanguageIfBuiltIn( 0, eParseLang
);
323 (void)rFormatter
.IsNumberFormat(aValStr
, nParseForm
, fVal
);
324 if ( comphelper::string::getTokenCount(aNumStr
, ';') > 2 )
327 eNumLang
= LanguageType(o3tl::toInt32(o3tl::getToken(aNumStr
, 1, ';', nIdx
)));
328 OUString
aFormat( aNumStr
.substr( nIdx
) );
330 SvNumFormatType nType
;
331 if ( eNumLang
!= LANGUAGE_SYSTEM
)
332 rFormatter
.PutEntry( aFormat
, nCheckPos
, nType
, nNumForm
, eNumLang
);
334 rFormatter
.PutandConvertEntry( aFormat
, nCheckPos
, nType
, nNumForm
,
335 eParseLang
, eNumLang
, true);
339 eNumLang
= LANGUAGE_SYSTEM
;
340 nNumForm
= rFormatter
.GetFormatForLanguageIfBuiltIn( 0, eNumLang
);
345 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */