xref: /AOO41X/main/sw/source/filter/html/htmlbas.cxx (revision efeef26f81c84063fb0a91bde3856d4a51172d90)
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