LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / sfx2 / source / bastyp / sfxhtml.cxx
blob9805fed0aa0f6bf140140213a2b1253e8499b6a6
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 .
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>
42 #include <vector>
45 using namespace ::com::sun::star;
48 // <INPUT TYPE=xxx>
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,
61 SfxMedium *pMed )
62 : HTMLParser(rStream, bIsNewDoc)
63 , pMedium(pMed)
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" );
86 OUString aName;
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();
123 break;
124 case HtmlOptionId::SHAPE:
125 rOption.GetEnum( nShape, aAreaShapeOptEnums );
126 break;
127 case HtmlOptionId::COORDS:
128 rOption.GetNumbers( aCoords );
129 break;
130 case HtmlOptionId::HREF:
131 aHRef = INetURLObject::GetAbsURL( rBaseURL, rOption.GetString() );
132 break;
133 case HtmlOptionId::NOHREF:
134 bNoHRef = true;
135 break;
136 case HtmlOptionId::ALT:
137 aAlt = rOption.GetString();
138 break;
139 case HtmlOptionId::TARGET:
140 aTarget = rOption.GetString();
141 break;
143 case HtmlOptionId::ONMOUSEOVER:
144 eScrpType = JAVASCRIPT;
145 [[fallthrough]];
146 case HtmlOptionId::SDONMOUSEOVER:
147 nEvent = nEventMouseOver;
148 goto IMAPOBJ_SETEVENT;
150 case HtmlOptionId::ONMOUSEOUT:
151 eScrpType = JAVASCRIPT;
152 [[fallthrough]];
153 case HtmlOptionId::SDONMOUSEOUT:
154 nEvent = nEventMouseOut;
155 goto IMAPOBJ_SETEVENT;
156 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 ));
166 break;
167 default: break;
171 if( bNoHRef )
172 aHRef.clear();
174 bool bNewArea = true;
175 switch( nShape )
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,
183 !bNoHRef ));
184 if( !aMacroTbl.empty() )
185 pMapRObj->SetMacroTable( aMacroTbl );
186 pImageMap->InsertIMapObject( std::move(pMapRObj) );
188 break;
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) );
199 break;
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,
208 !bNoHRef ));
209 if( !aMacroTbl.empty() )
210 pMapPObj->SetMacroTable( aMacroTbl );
211 pImageMap->InsertIMapObject( std::move(pMapPObj) );
213 break;
214 default:
215 bNewArea = false;
218 return bNewArea;
221 void SfxHTMLParser::StartFileDownload(const OUString& rURL)
223 DBG_ASSERT( !pDLMedium, "StartFileDownload when active Download" );
224 if( pDLMedium )
225 return;
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;
234 if( bOK )
236 SvStream* pStream = pDLMedium->GetInStream();
237 DBG_ASSERT( pStream, "No In-Stream received from Medium" );
239 SvMemoryStream aStream;
240 if( pStream )
241 aStream.WriteStream( *pStream );
243 sal_uInt64 const nLen = aStream.TellEnd();
244 aStream.Seek( 0 );
245 rStr = read_uInt8s_ToOUString(aStream, nLen, RTL_TEXTENCODING_UTF8);
248 pDLMedium.reset();
250 return bOK;
253 void SfxHTMLParser::GetScriptType_Impl( SvKeyValueIterator *pHTTPHeader )
255 aScriptType = SVX_MACRO_LANGUAGE_JAVASCRIPT;
256 eScriptType = JAVASCRIPT;
257 if( !pHTTPHeader )
258 return;
260 SvKeyValue aKV;
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 );
274 else
275 break;
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;
290 aScriptType = aTmp;
293 break;
298 ScriptType SfxHTMLParser::GetScriptType( SvKeyValueIterator *pHTTPHeader ) const
300 if( aScriptType.isEmpty() )
301 const_cast<SfxHTMLParser *>(this)->GetScriptType_Impl( pHTTPHeader );
303 return eScriptType;
306 const OUString& SfxHTMLParser::GetScriptTypeString(
307 SvKeyValueIterator *pHTTPHeader ) const
309 if( aScriptType.isEmpty() )
310 const_cast<SfxHTMLParser *>(this)->GetScriptType_Impl( pHTTPHeader );
312 return aScriptType;
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 );
321 double fVal;
322 (void)rFormatter.IsNumberFormat(aValStr, nParseForm, fVal);
323 if ( comphelper::string::getTokenCount(aNumStr, ';') > 2 )
325 sal_Int32 nIdx {0};
326 eNumLang = LanguageType(aNumStr.getToken( 1, ';', nIdx ).toInt32());
327 OUString aFormat( aNumStr.copy( nIdx ) );
328 sal_Int32 nCheckPos;
329 SvNumFormatType nType;
330 if ( eNumLang != LANGUAGE_SYSTEM )
331 rFormatter.PutEntry( aFormat, nCheckPos, nType, nNumForm, eNumLang );
332 else
333 rFormatter.PutandConvertEntry( aFormat, nCheckPos, nType, nNumForm,
334 eParseLang, eNumLang, true);
336 else
338 eNumLang = LANGUAGE_SYSTEM;
339 nNumForm = rFormatter.GetFormatForLanguageIfBuiltIn( 0, eNumLang );
341 return fVal;
344 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */