2 * Copyright 2008 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #include "wine/debug.h"
35 #include "mshtml_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
39 static const WCHAR windowW
[] = {'w','i','n','d','o','w',0};
40 static const WCHAR emptyW
[] = {0};
42 static const CLSID CLSID_JScript
=
43 {0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
46 const IActiveScriptSiteVtbl
*lpIActiveScriptSiteVtbl
;
47 const IActiveScriptSiteInterruptPollVtbl
*lpIActiveScriptSiteInterruptPollVtbl
;
48 const IActiveScriptSiteWindowVtbl
*lpIActiveScriptSiteWindowVtbl
;
49 const IActiveScriptSiteDebug32Vtbl
*lpIActiveScriptSiteDebug32Vtbl
;
53 IActiveScript
*script
;
54 IActiveScriptParse
*parse
;
55 IActiveScriptParseProcedure
*parse_proc
;
57 SCRIPTSTATE script_state
;
65 #define ACTSCPSITE(x) ((IActiveScriptSite*) &(x)->lpIActiveScriptSiteVtbl)
66 #define ACTSCPPOLL(x) ((IActiveScriptSiteInterruptPoll*) &(x)->lpIActiveScriptSiteInterruptPollVtbl)
67 #define ACTSCPWIN(x) ((IActiveScriptSiteWindow*) &(x)->lpIActiveScriptSiteWindowVtbl)
68 #define ACTSCPDBG32(x) ((IActiveScriptSiteDebug32*) &(x)->lpIActiveScriptSiteDebug32Vtbl)
70 static BOOL
init_script_engine(ScriptHost
*script_host
)
72 IActiveScriptProperty
*property
;
73 IObjectSafety
*safety
;
75 DWORD supported_opts
=0, enabled_opts
=0;
78 hres
= IActiveScript_QueryInterface(script_host
->script
, &IID_IActiveScriptParse
, (void**)&script_host
->parse
);
80 WARN("Could not get IActiveScriptHost: %08x\n", hres
);
84 hres
= IActiveScript_QueryInterface(script_host
->script
, &IID_IObjectSafety
, (void**)&safety
);
86 FIXME("Could not get IObjectSafety: %08x\n", hres
);
90 hres
= IObjectSafety_GetInterfaceSafetyOptions(safety
, &IID_IActiveScriptParse
, &supported_opts
, &enabled_opts
);
92 FIXME("GetInterfaceSafetyOptions failed: %08x\n", hres
);
93 }else if(!(supported_opts
& INTERFACE_USES_DISPEX
)) {
94 FIXME("INTERFACE_USES_DISPEX is not supported\n");
96 hres
= IObjectSafety_SetInterfaceSafetyOptions(safety
, &IID_IActiveScriptParse
,
97 INTERFACESAFE_FOR_UNTRUSTED_DATA
|INTERFACE_USES_DISPEX
|INTERFACE_USES_SECURITY_MANAGER
,
98 INTERFACESAFE_FOR_UNTRUSTED_DATA
|INTERFACE_USES_DISPEX
|INTERFACE_USES_SECURITY_MANAGER
);
100 FIXME("SetInterfaceSafetyOptions failed: %08x\n", hres
);
103 IObjectSafety_Release(safety
);
107 hres
= IActiveScript_QueryInterface(script_host
->script
, &IID_IActiveScriptProperty
, (void**)&property
);
108 if(SUCCEEDED(hres
)) {
111 V_VT(&var
) = VT_BOOL
;
112 V_BOOL(&var
) = VARIANT_TRUE
;
113 hres
= IActiveScriptProperty_SetProperty(property
, SCRIPTPROP_HACK_TRIDENTEVENTSINK
, NULL
, &var
);
115 WARN("SetProperty failed: %08x\n", hres
);
117 IActiveScriptProperty_Release(property
);
119 WARN("Could not get IActiveScriptProperty: %08x\n", hres
);
122 hres
= IActiveScriptParse_InitNew(script_host
->parse
);
124 WARN("InitNew failed: %08x\n", hres
);
128 hres
= IActiveScript_SetScriptSite(script_host
->script
, ACTSCPSITE(script_host
));
130 WARN("SetScriptSite failed: %08x\n", hres
);
131 IActiveScript_Close(script_host
->script
);
135 hres
= IActiveScript_GetScriptState(script_host
->script
, &state
);
137 WARN("GetScriptState failed: %08x\n", hres
);
138 else if(state
!= SCRIPTSTATE_INITIALIZED
)
139 FIXME("state = %x\n", state
);
141 hres
= IActiveScript_SetScriptState(script_host
->script
, SCRIPTSTATE_STARTED
);
143 WARN("Starting script failed: %08x\n", hres
);
147 hres
= IActiveScript_AddNamedItem(script_host
->script
, windowW
,
148 SCRIPTITEM_ISVISIBLE
|SCRIPTITEM_ISSOURCE
|SCRIPTITEM_GLOBALMEMBERS
);
150 WARN("AddNamedItem failed: %08x\n", hres
);
152 hres
= IActiveScript_QueryInterface(script_host
->script
, &IID_IActiveScriptParseProcedure2
,
153 (void**)&script_host
->parse_proc
);
155 /* FIXME: QI for IActiveScriptParseProcedure */
156 WARN("Could not get IActiveScriptParseProcedure iface: %08x\n", hres
);
162 static void release_script_engine(ScriptHost
*This
)
167 switch(This
->script_state
) {
168 case SCRIPTSTATE_CONNECTED
:
169 IActiveScript_SetScriptState(This
->script
, SCRIPTSTATE_DISCONNECTED
);
171 case SCRIPTSTATE_STARTED
:
172 case SCRIPTSTATE_DISCONNECTED
:
173 case SCRIPTSTATE_INITIALIZED
:
174 IActiveScript_Close(This
->script
);
177 if(This
->parse_proc
) {
178 IActiveScriptParseProcedure_Release(This
->parse_proc
);
179 This
->parse_proc
= NULL
;
183 IActiveScriptParse_Release(This
->parse
);
188 IActiveScript_Release(This
->script
);
190 This
->script_state
= SCRIPTSTATE_UNINITIALIZED
;
193 void connect_scripts(HTMLDocument
*doc
)
197 LIST_FOR_EACH_ENTRY(iter
, &doc
->script_hosts
, ScriptHost
, entry
) {
198 if(iter
->script_state
== SCRIPTSTATE_STARTED
)
199 IActiveScript_SetScriptState(iter
->script
, SCRIPTSTATE_CONNECTED
);
203 #define ACTSCPSITE_THIS(iface) DEFINE_THIS(ScriptHost, IActiveScriptSite, iface)
205 static HRESULT WINAPI
ActiveScriptSite_QueryInterface(IActiveScriptSite
*iface
, REFIID riid
, void **ppv
)
207 ScriptHost
*This
= ACTSCPSITE_THIS(iface
);
211 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
212 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
213 *ppv
= ACTSCPSITE(This
);
214 }else if(IsEqualGUID(&IID_IActiveScriptSite
, riid
)) {
215 TRACE("(%p)->(IID_IActiveScriptSite %p)\n", This
, ppv
);
216 *ppv
= ACTSCPSITE(This
);
217 }else if(IsEqualGUID(&IID_IActiveScriptSiteInterruptPoll
, riid
)) {
218 TRACE("(%p)->(IID_IActiveScriptSiteInterruprtPoll %p)\n", This
, ppv
);
219 *ppv
= ACTSCPPOLL(This
);
220 }else if(IsEqualGUID(&IID_IActiveScriptSiteWindow
, riid
)) {
221 TRACE("(%p)->(IID_IActiveScriptSiteWindow %p)\n", This
, ppv
);
222 *ppv
= ACTSCPWIN(This
);
223 }else if(IsEqualGUID(&IID_IActiveScriptSiteDebug32
, riid
)) {
224 TRACE("(%p)->(IID_IActiveScriptSiteDebug32 %p)\n", This
, ppv
);
225 *ppv
= ACTSCPDBG32(This
);
226 }else if(IsEqualGUID(&IID_ICanHandleException
, riid
)) {
227 TRACE("(%p)->(IID_ICanHandleException not supported %p)\n", This
, ppv
);
228 return E_NOINTERFACE
;
230 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
231 return E_NOINTERFACE
;
234 IUnknown_AddRef((IUnknown
*)*ppv
);
238 static ULONG WINAPI
ActiveScriptSite_AddRef(IActiveScriptSite
*iface
)
240 ScriptHost
*This
= ACTSCPSITE_THIS(iface
);
241 LONG ref
= InterlockedIncrement(&This
->ref
);
243 TRACE("(%p) ref=%d\n", This
, ref
);
248 static ULONG WINAPI
ActiveScriptSite_Release(IActiveScriptSite
*iface
)
250 ScriptHost
*This
= ACTSCPSITE_THIS(iface
);
251 LONG ref
= InterlockedDecrement(&This
->ref
);
253 TRACE("(%p) ref=%d\n", This
, ref
);
256 release_script_engine(This
);
258 list_remove(&This
->entry
);
265 static HRESULT WINAPI
ActiveScriptSite_GetLCID(IActiveScriptSite
*iface
, LCID
*plcid
)
267 ScriptHost
*This
= ACTSCPSITE_THIS(iface
);
269 TRACE("(%p)->(%p)\n", This
, plcid
);
271 *plcid
= GetUserDefaultLCID();
275 static HRESULT WINAPI
ActiveScriptSite_GetItemInfo(IActiveScriptSite
*iface
, LPCOLESTR pstrName
,
276 DWORD dwReturnMask
, IUnknown
**ppiunkItem
, ITypeInfo
**ppti
)
278 ScriptHost
*This
= ACTSCPSITE_THIS(iface
);
280 TRACE("(%p)->(%s %x %p %p)\n", This
, debugstr_w(pstrName
), dwReturnMask
, ppiunkItem
, ppti
);
282 if(dwReturnMask
!= SCRIPTINFO_IUNKNOWN
) {
283 FIXME("Unsupported mask %x\n", dwReturnMask
);
289 if(strcmpW(pstrName
, windowW
))
290 return DISP_E_MEMBERNOTFOUND
;
295 /* FIXME: Return proxy object */
296 *ppiunkItem
= (IUnknown
*)HTMLWINDOW2(This
->doc
->window
);
297 IUnknown_AddRef(*ppiunkItem
);
302 static HRESULT WINAPI
ActiveScriptSite_GetDocVersionString(IActiveScriptSite
*iface
, BSTR
*pbstrVersion
)
304 ScriptHost
*This
= ACTSCPSITE_THIS(iface
);
305 FIXME("(%p)->(%p)\n", This
, pbstrVersion
);
309 static HRESULT WINAPI
ActiveScriptSite_OnScriptTerminate(IActiveScriptSite
*iface
,
310 const VARIANT
*pvarResult
, const EXCEPINFO
*pexcepinfo
)
312 ScriptHost
*This
= ACTSCPSITE_THIS(iface
);
313 FIXME("(%p)->(%p %p)\n", This
, pvarResult
, pexcepinfo
);
317 static HRESULT WINAPI
ActiveScriptSite_OnStateChange(IActiveScriptSite
*iface
, SCRIPTSTATE ssScriptState
)
319 ScriptHost
*This
= ACTSCPSITE_THIS(iface
);
321 TRACE("(%p)->(%x)\n", This
, ssScriptState
);
323 This
->script_state
= ssScriptState
;
327 static HRESULT WINAPI
ActiveScriptSite_OnScriptError(IActiveScriptSite
*iface
, IActiveScriptError
*pscripterror
)
329 ScriptHost
*This
= ACTSCPSITE_THIS(iface
);
330 FIXME("(%p)->(%p)\n", This
, pscripterror
);
334 static HRESULT WINAPI
ActiveScriptSite_OnEnterScript(IActiveScriptSite
*iface
)
336 ScriptHost
*This
= ACTSCPSITE_THIS(iface
);
338 TRACE("(%p)->()\n", This
);
343 static HRESULT WINAPI
ActiveScriptSite_OnLeaveScript(IActiveScriptSite
*iface
)
345 ScriptHost
*This
= ACTSCPSITE_THIS(iface
);
347 TRACE("(%p)->()\n", This
);
352 #undef ACTSCPSITE_THIS
354 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl
= {
355 ActiveScriptSite_QueryInterface
,
356 ActiveScriptSite_AddRef
,
357 ActiveScriptSite_Release
,
358 ActiveScriptSite_GetLCID
,
359 ActiveScriptSite_GetItemInfo
,
360 ActiveScriptSite_GetDocVersionString
,
361 ActiveScriptSite_OnScriptTerminate
,
362 ActiveScriptSite_OnStateChange
,
363 ActiveScriptSite_OnScriptError
,
364 ActiveScriptSite_OnEnterScript
,
365 ActiveScriptSite_OnLeaveScript
368 #define ACTSCPPOLL_THIS(iface) DEFINE_THIS(ScriptHost, IActiveScriptSiteInterruptPoll, iface)
370 static HRESULT WINAPI
ActiveScriptSiteInterruptPoll_QueryInterface(IActiveScriptSiteInterruptPoll
*iface
,
371 REFIID riid
, void **ppv
)
373 ScriptHost
*This
= ACTSCPPOLL_THIS(iface
);
374 return IActiveScriptSite_QueryInterface(ACTSCPSITE(This
), riid
, ppv
);
377 static ULONG WINAPI
ActiveScriptSiteInterruptPoll_AddRef(IActiveScriptSiteInterruptPoll
*iface
)
379 ScriptHost
*This
= ACTSCPPOLL_THIS(iface
);
380 return IActiveScriptSite_AddRef(ACTSCPSITE(This
));
383 static ULONG WINAPI
ActiveScriptSiteInterruptPoll_Release(IActiveScriptSiteInterruptPoll
*iface
)
385 ScriptHost
*This
= ACTSCPPOLL_THIS(iface
);
386 return IActiveScriptSite_Release(ACTSCPSITE(This
));
389 static HRESULT WINAPI
ActiveScriptSiteInterruptPoll_QueryContinue(IActiveScriptSiteInterruptPoll
*iface
)
391 ScriptHost
*This
= ACTSCPPOLL_THIS(iface
);
393 TRACE("(%p)\n", This
);
398 #undef ACTSCPPOLL_THIS
400 static const IActiveScriptSiteInterruptPollVtbl ActiveScriptSiteInterruptPollVtbl
= {
401 ActiveScriptSiteInterruptPoll_QueryInterface
,
402 ActiveScriptSiteInterruptPoll_AddRef
,
403 ActiveScriptSiteInterruptPoll_Release
,
404 ActiveScriptSiteInterruptPoll_QueryContinue
407 #define ACTSCPWIN_THIS(iface) DEFINE_THIS(ScriptHost, IActiveScriptSiteWindow, iface)
409 static HRESULT WINAPI
ActiveScriptSiteWindow_QueryInterface(IActiveScriptSiteWindow
*iface
,
410 REFIID riid
, void **ppv
)
412 ScriptHost
*This
= ACTSCPWIN_THIS(iface
);
413 return IActiveScriptSite_QueryInterface(ACTSCPSITE(This
), riid
, ppv
);
416 static ULONG WINAPI
ActiveScriptSiteWindow_AddRef(IActiveScriptSiteWindow
*iface
)
418 ScriptHost
*This
= ACTSCPWIN_THIS(iface
);
419 return IActiveScriptSite_AddRef(ACTSCPSITE(This
));
422 static ULONG WINAPI
ActiveScriptSiteWindow_Release(IActiveScriptSiteWindow
*iface
)
424 ScriptHost
*This
= ACTSCPWIN_THIS(iface
);
425 return IActiveScriptSite_Release(ACTSCPSITE(This
));
428 static HRESULT WINAPI
ActiveScriptSiteWindow_GetWindow(IActiveScriptSiteWindow
*iface
, HWND
*phwnd
)
430 ScriptHost
*This
= ACTSCPWIN_THIS(iface
);
431 FIXME("(%p)->(%p)\n", This
, phwnd
);
435 static HRESULT WINAPI
ActiveScriptSiteWindow_EnableModeless(IActiveScriptSiteWindow
*iface
, BOOL fEnable
)
437 ScriptHost
*This
= ACTSCPWIN_THIS(iface
);
438 FIXME("(%p)->(%x)\n", This
, fEnable
);
442 #undef ACTSCPWIN_THIS
444 static const IActiveScriptSiteWindowVtbl ActiveScriptSiteWindowVtbl
= {
445 ActiveScriptSiteWindow_QueryInterface
,
446 ActiveScriptSiteWindow_AddRef
,
447 ActiveScriptSiteWindow_Release
,
448 ActiveScriptSiteWindow_GetWindow
,
449 ActiveScriptSiteWindow_EnableModeless
452 #define ACTSCPDBG32_THIS(iface) DEFINE_THIS(ScriptHost, IActiveScriptSiteDebug32, iface)
454 static HRESULT WINAPI
ActiveScriptSiteDebug32_QueryInterface(IActiveScriptSiteDebug32
*iface
,
455 REFIID riid
, void **ppv
)
457 ScriptHost
*This
= ACTSCPDBG32_THIS(iface
);
458 return IActiveScriptSite_QueryInterface(ACTSCPSITE(This
), riid
, ppv
);
461 static ULONG WINAPI
ActiveScriptSiteDebug32_AddRef(IActiveScriptSiteDebug32
*iface
)
463 ScriptHost
*This
= ACTSCPDBG32_THIS(iface
);
464 return IActiveScriptSite_AddRef(ACTSCPSITE(This
));
467 static ULONG WINAPI
ActiveScriptSiteDebug32_Release(IActiveScriptSiteDebug32
*iface
)
469 ScriptHost
*This
= ACTSCPDBG32_THIS(iface
);
470 return IActiveScriptSite_Release(ACTSCPSITE(This
));
473 static HRESULT WINAPI
ActiveScriptSiteDebug32_GetDocumentContextFromPosition(IActiveScriptSiteDebug32
*iface
,
474 DWORD dwSourceContext
, ULONG uCharacterOffset
, ULONG uNumChars
, IDebugDocumentContext
**ppsc
)
476 ScriptHost
*This
= ACTSCPDBG32_THIS(iface
);
477 FIXME("(%p)->(%x %u %u %p)\n", This
, dwSourceContext
, uCharacterOffset
, uNumChars
, ppsc
);
481 static HRESULT WINAPI
ActiveScriptSiteDebug32_GetApplication(IActiveScriptSiteDebug32
*iface
, IDebugApplication32
**ppda
)
483 ScriptHost
*This
= ACTSCPDBG32_THIS(iface
);
484 FIXME("(%p)->(%p)\n", This
, ppda
);
488 static HRESULT WINAPI
ActiveScriptSiteDebug32_GetRootApplicationNode(IActiveScriptSiteDebug32
*iface
,
489 IDebugApplicationNode
**ppdanRoot
)
491 ScriptHost
*This
= ACTSCPDBG32_THIS(iface
);
492 FIXME("(%p)->(%p)\n", This
, ppdanRoot
);
496 static HRESULT WINAPI
ActiveScriptSiteDebug32_OnScriptErrorDebug(IActiveScriptSiteDebug32
*iface
,
497 IActiveScriptErrorDebug
*pErrorDebug
, BOOL
*pfEnterDebugger
, BOOL
*pfCallOnScriptErrorWhenContinuing
)
499 ScriptHost
*This
= ACTSCPDBG32_THIS(iface
);
500 FIXME("(%p)->(%p %p %p)\n", This
, pErrorDebug
, pfEnterDebugger
, pfCallOnScriptErrorWhenContinuing
);
504 #undef ACTSCPDBG32_THIS
506 static const IActiveScriptSiteDebug32Vtbl ActiveScriptSiteDebug32Vtbl
= {
507 ActiveScriptSiteDebug32_QueryInterface
,
508 ActiveScriptSiteDebug32_AddRef
,
509 ActiveScriptSiteDebug32_Release
,
510 ActiveScriptSiteDebug32_GetDocumentContextFromPosition
,
511 ActiveScriptSiteDebug32_GetApplication
,
512 ActiveScriptSiteDebug32_GetRootApplicationNode
,
513 ActiveScriptSiteDebug32_OnScriptErrorDebug
516 static ScriptHost
*create_script_host(HTMLDocument
*doc
, const GUID
*guid
)
521 ret
= heap_alloc_zero(sizeof(*ret
));
522 ret
->lpIActiveScriptSiteVtbl
= &ActiveScriptSiteVtbl
;
523 ret
->lpIActiveScriptSiteInterruptPollVtbl
= &ActiveScriptSiteInterruptPollVtbl
;
524 ret
->lpIActiveScriptSiteWindowVtbl
= &ActiveScriptSiteWindowVtbl
;
525 ret
->lpIActiveScriptSiteDebug32Vtbl
= &ActiveScriptSiteDebug32Vtbl
;
528 ret
->script_state
= SCRIPTSTATE_UNINITIALIZED
;
531 list_add_tail(&doc
->script_hosts
, &ret
->entry
);
533 hres
= CoCreateInstance(&ret
->guid
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
534 &IID_IActiveScript
, (void**)&ret
->script
);
536 WARN("Could not load script engine: %08x\n", hres
);
537 else if(!init_script_engine(ret
))
538 release_script_engine(ret
);
543 static void parse_text(ScriptHost
*script_host
, LPCWSTR text
)
549 static const WCHAR script_endW
[] = {'<','/','S','C','R','I','P','T','>',0};
551 TRACE("%s\n", debugstr_w(text
));
554 memset(&excepinfo
, 0, sizeof(excepinfo
));
555 hres
= IActiveScriptParse_ParseScriptText(script_host
->parse
, text
, windowW
, NULL
, script_endW
,
556 0, 0, SCRIPTTEXT_ISVISIBLE
|SCRIPTTEXT_HOSTMANAGESSOURCE
,
559 WARN("ParseScriptText failed: %08x\n", hres
);
563 static void parse_extern_script(ScriptHost
*script_host
, LPCWSTR src
)
571 static const WCHAR wine_schemaW
[] = {'w','i','n','e',':'};
573 if(strlenW(src
) > sizeof(wine_schemaW
)/sizeof(WCHAR
) && !memcmp(src
, wine_schemaW
, sizeof(wine_schemaW
)))
574 src
+= sizeof(wine_schemaW
)/sizeof(WCHAR
);
576 hres
= CreateURLMoniker(NULL
, src
, &mon
);
580 hres
= bind_mon_to_buffer(script_host
->doc
, mon
, (void**)&buf
, &size
);
581 IMoniker_Release(mon
);
585 len
= MultiByteToWideChar(CP_ACP
, 0, buf
, size
, NULL
, 0);
586 text
= heap_alloc((len
+1)*sizeof(WCHAR
));
587 MultiByteToWideChar(CP_ACP
, 0, buf
, size
, text
, len
);
591 parse_text(script_host
, text
);
596 static void parse_inline_script(ScriptHost
*script_host
, nsIDOMHTMLScriptElement
*nsscript
)
598 const PRUnichar
*text
;
602 nsAString_Init(&text_str
, NULL
);
604 nsres
= nsIDOMHTMLScriptElement_GetText(nsscript
, &text_str
);
606 if(NS_SUCCEEDED(nsres
)) {
607 nsAString_GetData(&text_str
, &text
);
608 parse_text(script_host
, text
);
610 ERR("GetText failed: %08x\n", nsres
);
613 nsAString_Finish(&text_str
);
616 static void parse_script_elem(ScriptHost
*script_host
, nsIDOMHTMLScriptElement
*nsscript
)
618 const PRUnichar
*src
;
622 nsAString_Init(&src_str
, NULL
);
624 nsres
= nsIDOMHTMLScriptElement_GetSrc(nsscript
, &src_str
);
625 nsAString_GetData(&src_str
, &src
);
628 ERR("GetSrc failed: %08x\n", nsres
);
630 parse_extern_script(script_host
, src
);
632 parse_inline_script(script_host
, nsscript
);
634 nsAString_Finish(&src_str
);
637 static BOOL
get_guid_from_type(LPCWSTR type
, GUID
*guid
)
639 const WCHAR text_javascriptW
[] =
640 {'t','e','x','t','/','j','a','v','a','s','c','r','i','p','t',0};
642 /* FIXME: Handle more types */
643 if(!strcmpW(type
, text_javascriptW
)) {
644 *guid
= CLSID_JScript
;
646 FIXME("Unknown type %s\n", debugstr_w(type
));
653 static BOOL
get_guid_from_language(LPCWSTR type
, GUID
*guid
)
657 hres
= CLSIDFromProgID(type
, guid
);
661 /* FIXME: Check CATID_ActiveScriptParse */
666 static BOOL
get_script_guid(nsIDOMHTMLScriptElement
*nsscript
, GUID
*guid
)
668 nsAString attr_str
, val_str
;
672 static const PRUnichar languageW
[] = {'l','a','n','g','u','a','g','e',0};
674 nsAString_Init(&val_str
, NULL
);
676 nsres
= nsIDOMHTMLScriptElement_GetType(nsscript
, &val_str
);
677 if(NS_SUCCEEDED(nsres
)) {
678 const PRUnichar
*type
;
680 nsAString_GetData(&val_str
, &type
);
682 ret
= get_guid_from_type(type
, guid
);
683 nsAString_Finish(&val_str
);
687 ERR("GetType failed: %08x\n", nsres
);
690 nsAString_Init(&attr_str
, languageW
);
692 nsres
= nsIDOMHTMLScriptElement_GetAttribute(nsscript
, &attr_str
, &val_str
);
693 if(NS_SUCCEEDED(nsres
)) {
694 const PRUnichar
*language
;
696 nsAString_GetData(&val_str
, &language
);
699 ret
= get_guid_from_language(language
, guid
);
701 *guid
= CLSID_JScript
;
705 ERR("GetAttribute(language) failed: %08x\n", nsres
);
708 nsAString_Finish(&attr_str
);
709 nsAString_Finish(&val_str
);
714 static ScriptHost
*get_script_host(HTMLDocument
*doc
, const GUID
*guid
)
718 if(IsEqualGUID(&CLSID_JScript
, guid
) && doc
->scriptmode
!= SCRIPTMODE_ACTIVESCRIPT
) {
719 TRACE("Ignoring JScript\n");
723 LIST_FOR_EACH_ENTRY(iter
, &doc
->script_hosts
, ScriptHost
, entry
) {
724 if(IsEqualGUID(guid
, &iter
->guid
))
728 return create_script_host(doc
, guid
);
731 void doc_insert_script(HTMLDocument
*doc
, nsIDOMHTMLScriptElement
*nsscript
)
733 ScriptHost
*script_host
;
736 if(!get_script_guid(nsscript
, &guid
)) {
737 WARN("Could not find script GUID\n");
741 script_host
= get_script_host(doc
, &guid
);
745 if(script_host
->parse
)
746 parse_script_elem(script_host
, nsscript
);
749 IDispatch
*script_parse_event(HTMLDocument
*doc
, LPCWSTR text
)
751 ScriptHost
*script_host
;
752 GUID guid
= CLSID_JScript
;
757 static const WCHAR delimiterW
[] = {'\"',0};
759 for(ptr
= text
; isalnumW(*ptr
); ptr
++);
764 language
= heap_alloc((ptr
-text
+1)*sizeof(WCHAR
));
765 memcpy(language
, text
, (ptr
-text
)*sizeof(WCHAR
));
766 language
[ptr
-text
] = 0;
768 b
= get_guid_from_language(language
, &guid
);
773 WARN("Could not find language\n");
782 script_host
= get_script_host(doc
, &guid
);
783 if(!script_host
|| !script_host
->parse_proc
)
786 hres
= IActiveScriptParseProcedure_ParseProcedureText(script_host
->parse_proc
, ptr
, NULL
, emptyW
,
787 NULL
, NULL
, delimiterW
, 0 /* FIXME */, 0,
788 SCRIPTPROC_HOSTMANAGESSOURCE
|SCRIPTPROC_IMPLICIT_THIS
|SCRIPTPROC_IMPLICIT_PARENTS
, &disp
);
790 WARN("ParseProcedureText failed: %08x\n", hres
);
794 TRACE("ret %p\n", disp
);
798 static BOOL
is_jscript_available(void)
800 static BOOL available
, checked
;
804 HRESULT hres
= CoGetClassObject(&CLSID_JScript
, CLSCTX_INPROC_SERVER
, NULL
, &IID_IUnknown
, (void**)&unk
);
806 if(SUCCEEDED(hres
)) {
808 IUnknown_Release(unk
);
818 void set_script_mode(HTMLDocument
*doc
, SCRIPTMODE mode
)
820 nsIWebBrowserSetup
*setup
;
823 if(mode
== SCRIPTMODE_ACTIVESCRIPT
&& !is_jscript_available()) {
824 TRACE("jscript.dll not available\n");
825 doc
->scriptmode
= SCRIPTMODE_GECKO
;
829 doc
->scriptmode
= mode
;
831 if(!doc
->nscontainer
|| !doc
->nscontainer
->webbrowser
)
834 nsres
= nsIWebBrowser_QueryInterface(doc
->nscontainer
->webbrowser
,
835 &IID_nsIWebBrowserSetup
, (void**)&setup
);
836 if(NS_SUCCEEDED(nsres
)) {
837 nsres
= nsIWebBrowserSetup_SetProperty(setup
, SETUP_ALLOW_JAVASCRIPT
,
838 doc
->scriptmode
== SCRIPTMODE_GECKO
);
839 nsIWebBrowserSetup_Release(setup
);
843 ERR("JavaScript setup failed: %08x\n", nsres
);
846 void release_script_hosts(HTMLDocument
*doc
)
850 while(!list_empty(&doc
->script_hosts
)) {
851 iter
= LIST_ENTRY(list_head(&doc
->script_hosts
), ScriptHost
, entry
);
853 release_script_engine(iter
);
854 list_remove(&iter
->entry
);
856 IActiveScript_Release(ACTSCPSITE(iter
));