xref: /trunk/main/sw/source/filter/html/htmlbas.cxx (revision efeef26f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 
28 #include <hintids.hxx>
29 
30 #include <sfx2/sfx.hrc>
31 
32 #define _SVSTDARR_STRINGSSORTDTOR
33 #include <svl/svstdarr.hxx>
34 #include <basic/sbx.hxx>
35 #include <basic/basmgr.hxx>
36 #include <basic/sbmod.hxx>
37 #include <sfx2/evntconf.hxx>
38 #include <sfx2/app.hxx>
39 #include <svtools/htmlout.hxx>
40 #include <svtools/htmltokn.h>
41 #include <svtools/htmlkywd.hxx>
42 
43 #include <com/sun/star/document/XEventsSupplier.hpp>
44 #include <com/sun/star/uno/Reference.hxx>
45 
46 #include <fmtornt.hxx>
47 #include <fmtfld.hxx>
48 
49 #include "doc.hxx"
50 #include "docsh.hxx"
51 #include "docufld.hxx"
52 #include "wrthtml.hxx"
53 #include "swhtml.hxx"
54 
55 
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::uno;
58 using namespace ::com::sun::star::container;
59 
60 
61 static HTMLOutEvent __FAR_DATA aBodyEventTable[] =
62 {
63 	{ OOO_STRING_SVTOOLS_HTML_O_SDonload,		OOO_STRING_SVTOOLS_HTML_O_onload,		SFX_EVENT_OPENDOC	},
64 	{ OOO_STRING_SVTOOLS_HTML_O_SDonunload,	OOO_STRING_SVTOOLS_HTML_O_onunload,	SFX_EVENT_PREPARECLOSEDOC	},
65 	{ OOO_STRING_SVTOOLS_HTML_O_SDonfocus,	OOO_STRING_SVTOOLS_HTML_O_onfocus,	SFX_EVENT_ACTIVATEDOC	},
66 	{ OOO_STRING_SVTOOLS_HTML_O_SDonblur,		OOO_STRING_SVTOOLS_HTML_O_onblur,		SFX_EVENT_DEACTIVATEDOC	},
67 	{ 0,					0,				  	0					}
68 };
69 
70 
NewScript()71 void SwHTMLParser::NewScript()
72 {
73     ParseScriptOptions( aScriptType, sBaseURL, eScriptLang, aScriptURL,
74 						aBasicLib, aBasicModule );
75 
76 	if( aScriptURL.Len() )
77 	{
78 		// Den Inhalt des Script-Tags ignorieren
79 		bIgnoreRawData = sal_True;
80 	}
81 }
82 
EndScript()83 void SwHTMLParser::EndScript()
84 {
85 	sal_Bool bInsIntoBasic = sal_False,
86 		 bInsSrcIntoFld = sal_False;
87 
88 	switch( eScriptLang )
89 	{
90 	case HTML_SL_STARBASIC:
91 		bInsIntoBasic = sal_True;
92 		break;
93 	default:
94 		bInsSrcIntoFld = sal_True;
95 		break;
96 	}
97 
98 	bIgnoreRawData = sal_False;
99 	aScriptSource.ConvertLineEnd();
100 
101 //  MIB 23.5.97: SGML-Kommentare brauchen nicht mehr entfernt zu werden,
102 //	weil JS das jetzt selber kann.
103 //	RemoveSGMLComment( aScriptSource, sal_True );
104 
105 	// Ausser StarBasic und unbenutzem JavaScript jedes Script oder den
106 	// Modulnamen in einem Feld merken merken
107 	if( bInsSrcIntoFld && !bIgnoreHTMLComments )
108 	{
109 		SwScriptFieldType *pType =
110 			(SwScriptFieldType*)pDoc->GetSysFldType( RES_SCRIPTFLD );
111 
112 		SwScriptField aFld( pType, aScriptType,
113 							aScriptURL.Len() ? aScriptURL : aScriptSource,
114 							aScriptURL.Len()!=0 );
115 		InsertAttr( SwFmtFld( aFld ) );
116 	}
117 
118 	SwDocShell *pDocSh = pDoc->GetDocShell();
119 	if( aScriptSource.Len() && pDocSh &&
120 		bInsIntoBasic && IsNewDoc() )
121 	{
122 	// Fuer JavaScript und StarBasic noch ein Basic-Modul anlegen
123 		// Das Basic entfernt natuerlich weiterhin keine SGML-Kommentare
124 		RemoveSGMLComment( aScriptSource, sal_True );
125 
126         // get library name
127         ::rtl::OUString aLibName;
128         if( aBasicLib.Len() )
129             aLibName = aBasicLib;
130         else
131             aLibName = ::rtl::OUString::createFromAscii( "Standard" );
132 
133 	    // get module library container
134 	    Reference< script::XLibraryContainer > xModLibContainer( pDocSh->GetBasicContainer(), UNO_QUERY );
135 
136         if ( xModLibContainer.is() )
137         {
138             Reference< container::XNameContainer > xModLib;
139             if ( xModLibContainer->hasByName( aLibName ) )
140 	        {
141                 // get module library
142                 Any aElement = xModLibContainer->getByName( aLibName );
143 		        aElement >>= xModLib;
144 	        }
145             else
146             {
147                 // create module library
148                 xModLib = xModLibContainer->createLibrary( aLibName );
149             }
150 
151             if ( xModLib.is() )
152             {
153 				if( !aBasicModule.Len() )
154 				{
155                     // create module name
156 					sal_Bool bFound = sal_True;
157 					while( bFound )
158 					{
159 						aBasicModule.AssignAscii( "Modul" );
160 						aBasicModule += String::CreateFromInt32( (sal_Int32)(++nSBModuleCnt) );
161                         bFound = xModLib->hasByName( ::rtl::OUString( aBasicModule ) );
162                     }
163 				}
164 
165                 // create module
166                 ::rtl::OUString aModName( aBasicModule );
167                 if ( !xModLib->hasByName( aModName ) )
168                 {
169                     Any aElement;
170                     aElement <<= ::rtl::OUString( aScriptSource );
171                     xModLib->insertByName( aModName , aElement );
172                 }
173             }
174         }
175 
176         // get dialog library container
177 	    Reference< script::XLibraryContainer > xDlgLibContainer( pDocSh->GetDialogContainer(), UNO_QUERY );
178 
179         if ( xDlgLibContainer.is() )
180         {
181             if ( !xDlgLibContainer->hasByName( aLibName ) )
182 	        {
183                 // create dialog library
184             	xDlgLibContainer->createLibrary( aLibName );
185             }
186         }
187     }
188 
189 	aScriptSource.Erase();
190 	aScriptType.Erase();
191 	aScriptURL.Erase();
192 
193 	aBasicLib.Erase();
194 	aBasicModule.Erase();
195 }
196 
AddScriptSource()197 void SwHTMLParser::AddScriptSource()
198 {
199 	// Hier merken wir und nur ein par Strings
200 	if( aToken.Len() > 2 &&
201 		(HTML_SL_STARBASIC==eScriptLang && aToken.GetChar( 0 ) == '\'') )
202 	{
203 		xub_StrLen nPos = STRING_NOTFOUND;
204 		if( !aBasicLib.Len() )
205 		{
206 			nPos = aToken.SearchAscii( OOO_STRING_SVTOOLS_HTML_SB_library );
207 			if( nPos != STRING_NOTFOUND )
208 			{
209 				aBasicLib =
210 					aToken.Copy( nPos + sizeof(OOO_STRING_SVTOOLS_HTML_SB_library) - 1 );
211 				aBasicLib.EraseLeadingChars().EraseTrailingChars();
212 			}
213 		}
214 
215 		if( !aBasicModule.Len() && nPos==STRING_NOTFOUND )
216 		{
217 			nPos = aToken.SearchAscii( OOO_STRING_SVTOOLS_HTML_SB_module );
218 			if( nPos != STRING_NOTFOUND )
219 			{
220 				aBasicModule =
221 					aToken.Copy( nPos + sizeof(OOO_STRING_SVTOOLS_HTML_SB_module) - 1 );
222 				aBasicModule.EraseLeadingChars().EraseTrailingChars();
223 			}
224 		}
225 
226 		if( nPos==STRING_NOTFOUND )
227 		{
228 			if( aScriptSource.Len() )
229 				aScriptSource += '\n';
230 			(aScriptSource += aToken);
231 		}
232 	}
233 	else if( aScriptSource.Len() || aToken.Len() )
234 	{
235 		// Leerzeilen am Anfang werden ignoriert
236 		if( aScriptSource.Len() )
237 		{
238 			aScriptSource += '\n';
239 		}
240 		else
241 		{
242 			// Wir stehen hinter dem CR/LF der Zeile davor
243 			nScriptStartLineNr = GetLineNr() - 1;
244 		}
245 		aScriptSource += aToken;
246 	}
247 }
248 
InsertBasicDocEvent(rtl::OUString aEvent,const String & rName,ScriptType eScrType,const String & rScrType)249 void SwHTMLParser::InsertBasicDocEvent( rtl::OUString aEvent, const String& rName,
250 										ScriptType eScrType,
251 										const String& rScrType )
252 {
253 	ASSERT( rName.Len(), "InsertBasicDocEvent() ohne Macro gerufen" );
254 	if( !rName.Len() )
255 		return;
256 
257 	SwDocShell *pDocSh = pDoc->GetDocShell();
258 	ASSERT( pDocSh, "Wo ist die DocShell?" );
259 	if( !pDocSh )
260 		return;
261 
262 	String sEvent( rName );
263 	sEvent.ConvertLineEnd();
264 	String sScriptType;
265 	if( EXTENDED_STYPE == eScrType )
266 		sScriptType = rScrType;
267 
268 	rtl::OUString aEventName;
269 
270     SfxEventConfiguration::ConfigureEvent( aEvent, SvxMacro( sEvent, sScriptType, eScrType ),
271 						   pDocSh );
272 }
273 
OutBasic()274 void SwHTMLWriter::OutBasic()
275 {
276 	if( !bCfgStarBasic )
277 		return;
278 
279 	BasicManager *pBasicMan = pDoc->GetDocShell()->GetBasicManager();
280 	ASSERT( pBasicMan, "Wo ist der Basic-Manager?" );
281 	//JP 17.07.96: Bug 29538 - nur das DocumentBasic schreiben
282 	if( !pBasicMan || pBasicMan	== SFX_APP()->GetBasicManager() )
283 	{
284 		return;
285 	}
286 
287 	// und jetzt alle StarBasic-Module und alle unbenutzen JavaSrript-Module
288 	// ausgeben
289 	for( sal_uInt16 i=0; i<pBasicMan->GetLibCount(); i++ )
290 	{
291 		StarBASIC *pBasic = pBasicMan->GetLib( i  );
292 		const String& rLibName = pBasic->GetName();
293 
294 		SbxArray *pModules = pBasic->GetModules();
295 		for( sal_uInt16 j=0; j<pModules->Count(); j++ )
296 		{
297 			const SbModule *pModule = PTR_CAST( SbModule, pModules->Get(j) );
298 			ASSERT( pModule, "Wo ist das Modul?" );
299 
300 			String sLang(
301 					String::CreateFromAscii( SVX_MACRO_LANGUAGE_STARBASIC ) );
302 			ScriptType eType = STARBASIC;
303 
304 			if( 0==i && 0==j )
305 			{
306 				OutNewLine();
307 				ByteString sOut( '<' );
308 				sOut.Append( OOO_STRING_SVTOOLS_HTML_meta );
309 				sOut.Append( ' ' );
310 				sOut.Append( OOO_STRING_SVTOOLS_HTML_O_httpequiv );
311 			  	sOut.Append( "=\"" );
312 				sOut.Append( OOO_STRING_SVTOOLS_HTML_META_content_script_type );
313 				sOut.Append( "\" " );
314 				sOut.Append( OOO_STRING_SVTOOLS_HTML_O_content );
315 				sOut.Append( "=\"text/x-" );
316 				Strm() << sOut.GetBuffer();
317 				// Entities aren't welcome here
318 				ByteString sLang8( sLang, eDestEnc );
319 				Strm() << sLang8.GetBuffer() << "\">";
320 			}
321 
322 			const String& rModName = pModule->GetName();
323 			Strm() << SwHTMLWriter::sNewLine;	// nicht einruecken!
324             HTMLOutFuncs::OutScript( Strm(), GetBaseURL(), pModule->GetSource(),
325 									 sLang, eType, aEmptyStr,
326 									 &rLibName, &rModName,
327 								     eDestEnc, &aNonConvertableCharacters );
328 		}
329 	}
330 }
331 
332 static const char* aEventNames[] =
333 {
334 	"OnLoad", "OnPrepareUnload", "OnFocus", "OnUnfocus"
335 };
336 
OutBasicBodyEvents()337 void SwHTMLWriter::OutBasicBodyEvents()
338 {
339 	SwDocShell *pDocSh = pDoc->GetDocShell();
340 	if( !pDocSh )
341 		return;
342 
343     SvxMacroTableDtor *pDocTable = new SvxMacroTableDtor;
344 
345 	uno::Reference< document::XEventsSupplier > xSup( pDocSh->GetModel(), uno::UNO_QUERY );
346     uno::Reference < container::XNameReplace > xEvents = xSup->getEvents();
347     for ( sal_Int32 i=0; i<4; i++ )
348     {
349 		SvxMacro* pMacro = SfxEventConfiguration::ConvertToMacro( xEvents->getByName( ::rtl::OUString::createFromAscii(aEventNames[i]) ), pDocSh, sal_True );
350         if ( pMacro )
351             pDocTable->Insert( aBodyEventTable[i].nEvent, pMacro );
352     }
353 
354 	if( pDocTable && pDocTable->Count() )
355 		HTMLOutFuncs::Out_Events( Strm(), *pDocTable, aBodyEventTable,
356 								  bCfgStarBasic, eDestEnc, &aNonConvertableCharacters );
357 }
358 
359 
360