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>
45 using namespace ::com::sun::star
;
49 HTMLOptionEnum
<IMapObjectType
> const aAreaShapeOptEnums
[] =
51 { OOO_STRING_SVTOOLS_HTML_SH_rect
, IMapObjectType::Rectangle
},
52 { OOO_STRING_SVTOOLS_HTML_SH_rectangle
, IMapObjectType::Rectangle
},
53 { OOO_STRING_SVTOOLS_HTML_SH_circ
, IMapObjectType::Circle
},
54 { OOO_STRING_SVTOOLS_HTML_SH_circle
, IMapObjectType::Circle
},
55 { OOO_STRING_SVTOOLS_HTML_SH_poly
, IMapObjectType::Polygon
},
56 { OOO_STRING_SVTOOLS_HTML_SH_polygon
, IMapObjectType::Polygon
},
57 { nullptr, IMapObjectType::Rectangle
}
60 SfxHTMLParser::SfxHTMLParser( SvStream
& rStream
, bool bIsNewDoc
,
62 : HTMLParser(rStream
, bIsNewDoc
)
64 , eScriptType(STARBASIC
)
66 DBG_ASSERT( RTL_TEXTENCODING_UTF8
== GetSrcEncoding( ),
67 "SfxHTMLParser::SfxHTMLParser: From where comes ZS?" );
69 DBG_ASSERT( !IsSwitchToUCS2(),
70 "SfxHTMLParser::SfxHTMLParser: Switch to UCS2?" );
72 // If the file starts with a BOM, switch to UCS2.
73 SetSwitchToUCS2( true );
76 SfxHTMLParser::~SfxHTMLParser()
78 DBG_ASSERT( !pDLMedium
, "Here is a File Download that has got stuck" );
81 bool SfxHTMLParser::ParseMapOptions(
82 ImageMap
* pImageMap
, const HTMLOptions
& rOptions
)
84 DBG_ASSERT( pImageMap
, "ParseMapOptions: No Image-Map" );
88 for (size_t i
= rOptions
.size(); i
; )
90 const HTMLOption
& aOption
= rOptions
[--i
];
91 if ( aOption
.GetToken() == HtmlOptionId::NAME
)
92 aName
= aOption
.GetString();
95 if( !aName
.isEmpty() )
96 pImageMap
->SetName( aName
);
98 return !aName
.isEmpty();
101 bool SfxHTMLParser::ParseAreaOptions(ImageMap
* pImageMap
, const OUString
& rBaseURL
,
102 const HTMLOptions
& rOptions
,
103 SvMacroItemId nEventMouseOver
,
104 SvMacroItemId nEventMouseOut
)
106 DBG_ASSERT( pImageMap
, "ParseAreaOptions: no Image-Map" );
108 IMapObjectType nShape
= IMapObjectType::Rectangle
;
109 std::vector
<sal_uInt32
> aCoords
;
110 OUString aName
, aHRef
, aAlt
, aTarget
;
111 bool bNoHRef
= false;
112 SvxMacroTableDtor aMacroTbl
;
114 for (size_t i
= rOptions
.size(); i
; )
116 SvMacroItemId nEvent
= SvMacroItemId::NONE
;
117 ScriptType eScrpType
= STARBASIC
;
118 const HTMLOption
& rOption
= rOptions
[--i
];
119 switch( rOption
.GetToken() )
121 case HtmlOptionId::NAME
:
122 aName
= rOption
.GetString();
124 case HtmlOptionId::SHAPE
:
125 rOption
.GetEnum( nShape
, aAreaShapeOptEnums
);
127 case HtmlOptionId::COORDS
:
128 rOption
.GetNumbers( aCoords
);
130 case HtmlOptionId::HREF
:
131 aHRef
= INetURLObject::GetAbsURL( rBaseURL
, rOption
.GetString() );
133 case HtmlOptionId::NOHREF
:
136 case HtmlOptionId::ALT
:
137 aAlt
= rOption
.GetString();
139 case HtmlOptionId::TARGET
:
140 aTarget
= rOption
.GetString();
143 case HtmlOptionId::ONMOUSEOVER
:
144 eScrpType
= JAVASCRIPT
;
146 case HtmlOptionId::SDONMOUSEOVER
:
147 nEvent
= nEventMouseOver
;
148 goto IMAPOBJ_SETEVENT
;
150 case HtmlOptionId::ONMOUSEOUT
:
151 eScrpType
= JAVASCRIPT
;
153 case HtmlOptionId::SDONMOUSEOUT
:
154 nEvent
= nEventMouseOut
;
155 goto IMAPOBJ_SETEVENT
;
157 if( nEvent
!= SvMacroItemId::NONE
)
159 OUString
sTmp( rOption
.GetString() );
160 if( !sTmp
.isEmpty() )
162 sTmp
= convertLineEnd(sTmp
, GetSystemLineEnd());
163 aMacroTbl
.Insert( nEvent
, SvxMacro( sTmp
, "", eScrpType
));
174 bool bNewArea
= true;
177 case IMapObjectType::Rectangle
:
178 if( aCoords
.size() >=4 )
180 tools::Rectangle
aRect( aCoords
[0], aCoords
[1],
181 aCoords
[2], aCoords
[3] );
182 std::unique_ptr
<IMapRectangleObject
> pMapRObj( new IMapRectangleObject(aRect
, aHRef
, aAlt
, OUString(), aTarget
, aName
,
184 if( !aMacroTbl
.empty() )
185 pMapRObj
->SetMacroTable( aMacroTbl
);
186 pImageMap
->InsertIMapObject( std::move(pMapRObj
) );
189 case IMapObjectType::Circle
:
190 if( aCoords
.size() >=3 )
192 Point
aPoint( aCoords
[0], aCoords
[1] );
193 std::unique_ptr
<IMapCircleObject
> pMapCObj(new IMapCircleObject(aPoint
, aCoords
[2],aHRef
, aAlt
, OUString(),
194 aTarget
, aName
, !bNoHRef
));
195 if( !aMacroTbl
.empty() )
196 pMapCObj
->SetMacroTable( aMacroTbl
);
197 pImageMap
->InsertIMapObject( std::move(pMapCObj
) );
200 case IMapObjectType::Polygon
:
201 if( aCoords
.size() >=6 )
203 sal_uInt16 nCount
= aCoords
.size() / 2;
204 tools::Polygon
aPoly( nCount
);
205 for( sal_uInt16 i
=0; i
<nCount
; i
++ )
206 aPoly
[i
] = Point( aCoords
[2*i
], aCoords
[2*i
+1] );
207 std::unique_ptr
<IMapPolygonObject
> pMapPObj(new IMapPolygonObject( aPoly
, aHRef
, aAlt
, OUString(), aTarget
, aName
,
209 if( !aMacroTbl
.empty() )
210 pMapPObj
->SetMacroTable( aMacroTbl
);
211 pImageMap
->InsertIMapObject( std::move(pMapPObj
) );
221 void SfxHTMLParser::StartFileDownload(const OUString
& rURL
)
223 DBG_ASSERT( !pDLMedium
, "StartFileDownload when active Download" );
227 pDLMedium
.reset( new SfxMedium( rURL
, SFX_STREAM_READONLY
) );
228 pDLMedium
->Download();
231 bool SfxHTMLParser::FinishFileDownload( OUString
& rStr
)
233 bool bOK
= pDLMedium
&& pDLMedium
->GetErrorCode() == ERRCODE_NONE
;
236 SvStream
* pStream
= pDLMedium
->GetInStream();
237 DBG_ASSERT( pStream
, "No In-Stream received from Medium" );
239 SvMemoryStream aStream
;
241 aStream
.WriteStream( *pStream
);
243 sal_uInt64
const nLen
= aStream
.TellEnd();
245 rStr
= read_uInt8s_ToOUString(aStream
, nLen
, RTL_TEXTENCODING_UTF8
);
253 void SfxHTMLParser::GetScriptType_Impl( SvKeyValueIterator
*pHTTPHeader
)
255 aScriptType
= SVX_MACRO_LANGUAGE_JAVASCRIPT
;
256 eScriptType
= JAVASCRIPT
;
261 for( bool bCont
= pHTTPHeader
->GetFirst( aKV
); bCont
;
262 bCont
= pHTTPHeader
->GetNext( aKV
) )
264 if( aKV
.GetKey().equalsIgnoreAsciiCase(
265 OOO_STRING_SVTOOLS_HTML_META_content_script_type
) )
267 if( !aKV
.GetValue().isEmpty() )
269 OUString
aTmp( aKV
.GetValue() );
270 if( aTmp
.startsWithIgnoreAsciiCase( "text/" ) )
271 aTmp
= aTmp
.copy( 5 );
272 else if( aTmp
.startsWithIgnoreAsciiCase( "application/" ) )
273 aTmp
= aTmp
.copy( 12 );
277 if( aTmp
.startsWithIgnoreAsciiCase( "x-" ) ) // MIME-experimental
279 aTmp
= aTmp
.copy( 2 );
282 if( aTmp
.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_LG_starbasic
) )
284 eScriptType
= STARBASIC
;
285 aScriptType
= SVX_MACRO_LANGUAGE_STARBASIC
;
287 if( !aTmp
.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_LG_javascript
) )
289 eScriptType
= EXTENDED_STYPE
;
298 ScriptType
SfxHTMLParser::GetScriptType( SvKeyValueIterator
*pHTTPHeader
) const
300 if( aScriptType
.isEmpty() )
301 const_cast<SfxHTMLParser
*>(this)->GetScriptType_Impl( pHTTPHeader
);
306 const OUString
& SfxHTMLParser::GetScriptTypeString(
307 SvKeyValueIterator
*pHTTPHeader
) const
309 if( aScriptType
.isEmpty() )
310 const_cast<SfxHTMLParser
*>(this)->GetScriptType_Impl( pHTTPHeader
);
315 double SfxHTMLParser::GetTableDataOptionsValNum( sal_uInt32
& nNumForm
,
316 LanguageType
& eNumLang
, const OUString
& aValStr
, const OUString
& aNumStr
,
317 SvNumberFormatter
& rFormatter
)
319 LanguageType
eParseLang(aNumStr
.toInt32());
320 sal_uInt32 nParseForm
= rFormatter
.GetFormatForLanguageIfBuiltIn( 0, eParseLang
);
322 (void)rFormatter
.IsNumberFormat(aValStr
, nParseForm
, fVal
);
323 if ( comphelper::string::getTokenCount(aNumStr
, ';') > 2 )
326 eNumLang
= LanguageType(aNumStr
.getToken( 1, ';', nIdx
).toInt32());
327 OUString
aFormat( aNumStr
.copy( nIdx
) );
329 SvNumFormatType nType
;
330 if ( eNumLang
!= LANGUAGE_SYSTEM
)
331 rFormatter
.PutEntry( aFormat
, nCheckPos
, nType
, nNumForm
, eNumLang
);
333 rFormatter
.PutandConvertEntry( aFormat
, nCheckPos
, nType
, nNumForm
,
334 eParseLang
, eNumLang
, true);
338 eNumLang
= LANGUAGE_SYSTEM
;
339 nNumForm
= rFormatter
.GetFormatForLanguageIfBuiltIn( 0, eNumLang
);
344 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */