Bump version to 21.06.18.1
[LibreOffice.git] / sfx2 / source / bastyp / sfxhtml.cxx
blob2e7cd46f6c30ff0985e7db3de0cd3d5ab0012868
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 <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>
41 #include <vector>
44 using namespace ::com::sun::star;
47 // <INPUT TYPE=xxx>
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,
60 SfxMedium *pMed )
61 : HTMLParser(rStream, bIsNewDoc)
62 , pMedium(pMed)
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" );
85 OUString aName;
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();
122 break;
123 case HtmlOptionId::SHAPE:
124 rOption.GetEnum( nShape, aAreaShapeOptEnums );
125 break;
126 case HtmlOptionId::COORDS:
127 rOption.GetNumbers( aCoords );
128 break;
129 case HtmlOptionId::HREF:
130 aHRef = INetURLObject::GetAbsURL( rBaseURL, rOption.GetString() );
131 break;
132 case HtmlOptionId::NOHREF:
133 bNoHRef = true;
134 break;
135 case HtmlOptionId::ALT:
136 aAlt = rOption.GetString();
137 break;
138 case HtmlOptionId::TARGET:
139 aTarget = rOption.GetString();
140 break;
142 case HtmlOptionId::ONMOUSEOVER:
143 eScrpType = JAVASCRIPT;
144 [[fallthrough]];
145 case HtmlOptionId::SDONMOUSEOVER:
146 nEvent = nEventMouseOver;
147 goto IMAPOBJ_SETEVENT;
149 case HtmlOptionId::ONMOUSEOUT:
150 eScrpType = JAVASCRIPT;
151 [[fallthrough]];
152 case HtmlOptionId::SDONMOUSEOUT:
153 nEvent = nEventMouseOut;
154 goto IMAPOBJ_SETEVENT;
155 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 ));
165 break;
166 default: break;
170 if( bNoHRef )
171 aHRef.clear();
173 bool bNewArea = true;
174 switch( nShape )
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,
182 !bNoHRef ));
183 if( !aMacroTbl.empty() )
184 pMapRObj->SetMacroTable( aMacroTbl );
185 pImageMap->InsertIMapObject( std::move(pMapRObj) );
187 break;
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) );
198 break;
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,
207 !bNoHRef ));
208 if( !aMacroTbl.empty() )
209 pMapPObj->SetMacroTable( aMacroTbl );
210 pImageMap->InsertIMapObject( std::move(pMapPObj) );
212 break;
213 default:
214 bNewArea = false;
217 return bNewArea;
220 void SfxHTMLParser::StartFileDownload(const OUString& rURL)
222 DBG_ASSERT( !pDLMedium, "StartFileDownload when active Download" );
223 if( pDLMedium )
224 return;
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;
233 if( bOK )
235 SvStream* pStream = pDLMedium->GetInStream();
236 DBG_ASSERT( pStream, "No In-Stream received from Medium" );
238 SvMemoryStream aStream;
239 if( pStream )
240 aStream.WriteStream( *pStream );
242 sal_uInt64 const nLen = aStream.TellEnd();
243 aStream.Seek( 0 );
244 rStr = read_uInt8s_ToOUString(aStream, nLen, RTL_TEXTENCODING_UTF8);
247 pDLMedium.reset();
249 return bOK;
252 void SfxHTMLParser::GetScriptType_Impl( SvKeyValueIterator *pHTTPHeader )
254 aScriptType = SVX_MACRO_LANGUAGE_JAVASCRIPT;
255 eScriptType = JAVASCRIPT;
256 if( !pHTTPHeader )
257 return;
259 SvKeyValue aKV;
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 );
273 else
274 break;
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;
289 aScriptType = aTmp;
292 break;
297 ScriptType SfxHTMLParser::GetScriptType( SvKeyValueIterator *pHTTPHeader ) const
299 if( aScriptType.isEmpty() )
300 const_cast<SfxHTMLParser *>(this)->GetScriptType_Impl( pHTTPHeader );
302 return eScriptType;
305 const OUString& SfxHTMLParser::GetScriptTypeString(
306 SvKeyValueIterator *pHTTPHeader ) const
308 if( aScriptType.isEmpty() )
309 const_cast<SfxHTMLParser *>(this)->GetScriptType_Impl( pHTTPHeader );
311 return aScriptType;
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 );
320 double fVal;
321 (void)rFormatter.IsNumberFormat(aValStr, nParseForm, fVal);
322 if ( comphelper::string::getTokenCount(aNumStr, ';') > 2 )
324 sal_Int32 nIdx {0};
325 eNumLang = LanguageType(aNumStr.getToken( 1, ';', nIdx ).toInt32());
326 OUString aFormat( aNumStr.copy( nIdx ) );
327 sal_Int32 nCheckPos;
328 SvNumFormatType nType;
329 if ( eNumLang != LANGUAGE_SYSTEM )
330 rFormatter.PutEntry( aFormat, nCheckPos, nType, nNumForm, eNumLang );
331 else
332 rFormatter.PutandConvertEntry( aFormat, nCheckPos, nType, nNumForm,
333 eParseLang, eNumLang, true);
335 else
337 eNumLang = LANGUAGE_SYSTEM;
338 nNumForm = rFormatter.GetFormatForLanguageIfBuiltIn( 0, eNumLang );
340 return fVal;
343 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */