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 <svtools/htmlkywd.hxx>
29 #include <svtools/htmltokn.h>
30 #include <vcl/imap.hxx>
31 #include <vcl/imapcirc.hxx>
32 #include <vcl/imapobj.hxx>
33 #include <vcl/imappoly.hxx>
34 #include <vcl/imaprect.hxx>
35 #include <svl/zforlist.hxx>
37 #include <sfx2/sfxhtml.hxx>
39 #include <comphelper/string.hxx>
44 using namespace ::com::sun::star
;
48 HTMLOptionEnum
<IMapObjectType
> const aAreaShapeOptEnums
[] =
50 { OOO_STRING_SVTOOLS_HTML_SH_rect
, IMapObjectType::Rectangle
},
51 { OOO_STRING_SVTOOLS_HTML_SH_rectangle
, IMapObjectType::Rectangle
},
52 { OOO_STRING_SVTOOLS_HTML_SH_circ
, IMapObjectType::Circle
},
53 { OOO_STRING_SVTOOLS_HTML_SH_circle
, IMapObjectType::Circle
},
54 { OOO_STRING_SVTOOLS_HTML_SH_poly
, IMapObjectType::Polygon
},
55 { OOO_STRING_SVTOOLS_HTML_SH_polygon
, IMapObjectType::Polygon
},
56 { nullptr, IMapObjectType::Rectangle
}
59 SfxHTMLParser::SfxHTMLParser( SvStream
& rStream
, bool bIsNewDoc
,
61 : HTMLParser(rStream
, bIsNewDoc
)
63 , eScriptType(STARBASIC
)
65 DBG_ASSERT( RTL_TEXTENCODING_UTF8
== GetSrcEncoding( ),
66 "SfxHTMLParser::SfxHTMLParser: From where comes ZS?" );
68 DBG_ASSERT( !IsSwitchToUCS2(),
69 "SfxHTMLParser::SfxHTMLParser: Switch to UCS2?" );
71 // If the file starts with a BOM, switch to UCS2.
72 SetSwitchToUCS2( true );
75 SfxHTMLParser::~SfxHTMLParser()
77 DBG_ASSERT( !pDLMedium
, "Here is a File Download that has got stuck" );
80 bool SfxHTMLParser::ParseMapOptions(
81 ImageMap
* pImageMap
, const HTMLOptions
& rOptions
)
83 DBG_ASSERT( pImageMap
, "ParseMapOptions: No Image-Map" );
87 for (size_t i
= rOptions
.size(); i
; )
89 const HTMLOption
& aOption
= rOptions
[--i
];
90 if ( aOption
.GetToken() == HtmlOptionId::NAME
)
91 aName
= aOption
.GetString();
94 if( !aName
.isEmpty() )
95 pImageMap
->SetName( aName
);
97 return !aName
.isEmpty();
100 bool SfxHTMLParser::ParseAreaOptions(ImageMap
* pImageMap
, const OUString
& rBaseURL
,
101 const HTMLOptions
& rOptions
,
102 SvMacroItemId nEventMouseOver
,
103 SvMacroItemId nEventMouseOut
)
105 DBG_ASSERT( pImageMap
, "ParseAreaOptions: no Image-Map" );
107 IMapObjectType nShape
= IMapObjectType::Rectangle
;
108 std::vector
<sal_uInt32
> aCoords
;
109 OUString aName
, aHRef
, aAlt
, aTarget
;
110 bool bNoHRef
= false;
111 SvxMacroTableDtor aMacroTbl
;
113 for (size_t i
= rOptions
.size(); i
; )
115 SvMacroItemId nEvent
= SvMacroItemId::NONE
;
116 ScriptType eScrpType
= STARBASIC
;
117 const HTMLOption
& rOption
= rOptions
[--i
];
118 switch( rOption
.GetToken() )
120 case HtmlOptionId::NAME
:
121 aName
= rOption
.GetString();
123 case HtmlOptionId::SHAPE
:
124 rOption
.GetEnum( nShape
, aAreaShapeOptEnums
);
126 case HtmlOptionId::COORDS
:
127 rOption
.GetNumbers( aCoords
);
129 case HtmlOptionId::HREF
:
130 aHRef
= INetURLObject::GetAbsURL( rBaseURL
, rOption
.GetString() );
132 case HtmlOptionId::NOHREF
:
135 case HtmlOptionId::ALT
:
136 aAlt
= rOption
.GetString();
138 case HtmlOptionId::TARGET
:
139 aTarget
= rOption
.GetString();
142 case HtmlOptionId::ONMOUSEOVER
:
143 eScrpType
= JAVASCRIPT
;
145 case HtmlOptionId::SDONMOUSEOVER
:
146 nEvent
= nEventMouseOver
;
147 goto IMAPOBJ_SETEVENT
;
149 case HtmlOptionId::ONMOUSEOUT
:
150 eScrpType
= JAVASCRIPT
;
152 case HtmlOptionId::SDONMOUSEOUT
:
153 nEvent
= nEventMouseOut
;
154 goto IMAPOBJ_SETEVENT
;
156 if( nEvent
!= SvMacroItemId::NONE
)
158 OUString
sTmp( rOption
.GetString() );
159 if( !sTmp
.isEmpty() )
161 sTmp
= convertLineEnd(sTmp
, GetSystemLineEnd());
162 aMacroTbl
.Insert( nEvent
, SvxMacro( sTmp
, "", eScrpType
));
173 bool bNewArea
= true;
176 case IMapObjectType::Rectangle
:
177 if( aCoords
.size() >=4 )
179 tools::Rectangle
aRect( aCoords
[0], aCoords
[1],
180 aCoords
[2], aCoords
[3] );
181 std::unique_ptr
<IMapRectangleObject
> pMapRObj( new IMapRectangleObject(aRect
, aHRef
, aAlt
, OUString(), aTarget
, aName
,
183 if( !aMacroTbl
.empty() )
184 pMapRObj
->SetMacroTable( aMacroTbl
);
185 pImageMap
->InsertIMapObject( std::move(pMapRObj
) );
188 case IMapObjectType::Circle
:
189 if( aCoords
.size() >=3 )
191 Point
aPoint( aCoords
[0], aCoords
[1] );
192 std::unique_ptr
<IMapCircleObject
> pMapCObj(new IMapCircleObject(aPoint
, aCoords
[2],aHRef
, aAlt
, OUString(),
193 aTarget
, aName
, !bNoHRef
));
194 if( !aMacroTbl
.empty() )
195 pMapCObj
->SetMacroTable( aMacroTbl
);
196 pImageMap
->InsertIMapObject( std::move(pMapCObj
) );
199 case IMapObjectType::Polygon
:
200 if( aCoords
.size() >=6 )
202 sal_uInt16 nCount
= aCoords
.size() / 2;
203 tools::Polygon
aPoly( nCount
);
204 for( sal_uInt16 i
=0; i
<nCount
; i
++ )
205 aPoly
[i
] = Point( aCoords
[2*i
], aCoords
[2*i
+1] );
206 std::unique_ptr
<IMapPolygonObject
> pMapPObj(new IMapPolygonObject( aPoly
, aHRef
, aAlt
, OUString(), aTarget
, aName
,
208 if( !aMacroTbl
.empty() )
209 pMapPObj
->SetMacroTable( aMacroTbl
);
210 pImageMap
->InsertIMapObject( std::move(pMapPObj
) );
220 void SfxHTMLParser::StartFileDownload(const OUString
& rURL
)
222 DBG_ASSERT( !pDLMedium
, "StartFileDownload when active Download" );
226 pDLMedium
.reset( new SfxMedium( rURL
, SFX_STREAM_READONLY
) );
227 pDLMedium
->Download();
230 bool SfxHTMLParser::FinishFileDownload( OUString
& rStr
)
232 bool bOK
= pDLMedium
&& pDLMedium
->GetErrorCode() == ERRCODE_NONE
;
235 SvStream
* pStream
= pDLMedium
->GetInStream();
236 DBG_ASSERT( pStream
, "No In-Stream received from Medium" );
238 SvMemoryStream aStream
;
240 aStream
.WriteStream( *pStream
);
242 sal_uInt64
const nLen
= aStream
.TellEnd();
244 rStr
= read_uInt8s_ToOUString(aStream
, nLen
, RTL_TEXTENCODING_UTF8
);
252 void SfxHTMLParser::GetScriptType_Impl( SvKeyValueIterator
*pHTTPHeader
)
254 aScriptType
= SVX_MACRO_LANGUAGE_JAVASCRIPT
;
255 eScriptType
= JAVASCRIPT
;
260 for( bool bCont
= pHTTPHeader
->GetFirst( aKV
); bCont
;
261 bCont
= pHTTPHeader
->GetNext( aKV
) )
263 if( aKV
.GetKey().equalsIgnoreAsciiCase(
264 OOO_STRING_SVTOOLS_HTML_META_content_script_type
) )
266 if( !aKV
.GetValue().isEmpty() )
268 OUString
aTmp( aKV
.GetValue() );
269 if( aTmp
.startsWithIgnoreAsciiCase( "text/" ) )
270 aTmp
= aTmp
.copy( 5 );
271 else if( aTmp
.startsWithIgnoreAsciiCase( "application/" ) )
272 aTmp
= aTmp
.copy( 12 );
276 if( aTmp
.startsWithIgnoreAsciiCase( "x-" ) ) // MIME-experimental
278 aTmp
= aTmp
.copy( 2 );
281 if( aTmp
.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_LG_starbasic
) )
283 eScriptType
= STARBASIC
;
284 aScriptType
= SVX_MACRO_LANGUAGE_STARBASIC
;
286 if( !aTmp
.equalsIgnoreAsciiCase( OOO_STRING_SVTOOLS_HTML_LG_javascript
) )
288 eScriptType
= EXTENDED_STYPE
;
297 ScriptType
SfxHTMLParser::GetScriptType( SvKeyValueIterator
*pHTTPHeader
) const
299 if( aScriptType
.isEmpty() )
300 const_cast<SfxHTMLParser
*>(this)->GetScriptType_Impl( pHTTPHeader
);
305 const OUString
& SfxHTMLParser::GetScriptTypeString(
306 SvKeyValueIterator
*pHTTPHeader
) const
308 if( aScriptType
.isEmpty() )
309 const_cast<SfxHTMLParser
*>(this)->GetScriptType_Impl( pHTTPHeader
);
314 double SfxHTMLParser::GetTableDataOptionsValNum( sal_uInt32
& nNumForm
,
315 LanguageType
& eNumLang
, const OUString
& aValStr
, const OUString
& aNumStr
,
316 SvNumberFormatter
& rFormatter
)
318 LanguageType
eParseLang(aNumStr
.toInt32());
319 sal_uInt32 nParseForm
= rFormatter
.GetFormatForLanguageIfBuiltIn( 0, eParseLang
);
321 (void)rFormatter
.IsNumberFormat(aValStr
, nParseForm
, fVal
);
322 if ( comphelper::string::getTokenCount(aNumStr
, ';') > 2 )
325 eNumLang
= LanguageType(aNumStr
.getToken( 1, ';', nIdx
).toInt32());
326 OUString
aFormat( aNumStr
.copy( nIdx
) );
328 SvNumFormatType nType
;
329 if ( eNumLang
!= LANGUAGE_SYSTEM
)
330 rFormatter
.PutEntry( aFormat
, nCheckPos
, nType
, nNumForm
, eNumLang
);
332 rFormatter
.PutandConvertEntry( aFormat
, nCheckPos
, nType
, nNumForm
,
333 eParseLang
, eNumLang
, true);
337 eNumLang
= LANGUAGE_SYSTEM
;
338 nNumForm
= rFormatter
.GetFormatForLanguageIfBuiltIn( 0, eNumLang
);
343 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */