mshtml: Parse and store onload attributes.
This commit is contained in:
parent
9e482ce938
commit
4c21a5d3b0
|
@ -20,6 +20,7 @@ C_SRCS = \
|
|||
htmldoc5.c \
|
||||
htmlelem.c \
|
||||
htmlelem2.c \
|
||||
htmlevent.c \
|
||||
htmlinput.c \
|
||||
htmllocation.c \
|
||||
htmlnode.c \
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright 2008 Jacek Caban for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "ole2.h"
|
||||
|
||||
#include "mshtml_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
|
||||
|
||||
typedef enum {
|
||||
EVENTID_LOAD,
|
||||
EVENTID_LAST
|
||||
} eventid;
|
||||
|
||||
struct event_target_t {
|
||||
IDispatch *event_table[EVENTID_LAST];
|
||||
};
|
||||
|
||||
static const WCHAR loadW[] = {'l','o','a','d',0};
|
||||
static const WCHAR onloadW[] = {'o','n','l','o','a','d',0};
|
||||
|
||||
typedef struct {
|
||||
LPCWSTR name;
|
||||
LPCWSTR attr_name;
|
||||
} event_info_t;
|
||||
|
||||
static const event_info_t event_info[] = {
|
||||
{loadW, onloadW}
|
||||
};
|
||||
|
||||
void check_event_attr(HTMLDocument *doc, nsIDOMElement *nselem)
|
||||
{
|
||||
const PRUnichar *attr_value;
|
||||
nsAString attr_name_str, attr_value_str;
|
||||
IDispatch *disp;
|
||||
HTMLDOMNode *node;
|
||||
int i;
|
||||
nsresult nsres;
|
||||
|
||||
nsAString_Init(&attr_value_str, NULL);
|
||||
nsAString_Init(&attr_name_str, NULL);
|
||||
|
||||
for(i=0; i < EVENTID_LAST; i++) {
|
||||
nsAString_SetData(&attr_name_str, event_info[i].attr_name);
|
||||
nsres = nsIDOMElement_GetAttribute(nselem, &attr_name_str, &attr_value_str);
|
||||
if(NS_SUCCEEDED(nsres)) {
|
||||
nsAString_GetData(&attr_value_str, &attr_value);
|
||||
if(!*attr_value)
|
||||
continue;
|
||||
|
||||
TRACE("%p.%s = %s\n", nselem, debugstr_w(event_info[i].attr_name), debugstr_w(attr_value));
|
||||
|
||||
disp = script_parse_event(doc, attr_value);
|
||||
if(disp) {
|
||||
node = get_node(doc, (nsIDOMNode*)nselem, TRUE);
|
||||
if(!node->event_target)
|
||||
node->event_target = heap_alloc_zero(sizeof(event_target_t));
|
||||
node->event_target->event_table[i] = disp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsAString_Finish(&attr_value_str);
|
||||
nsAString_Finish(&attr_name_str);
|
||||
}
|
||||
|
||||
void release_event_target(event_target_t *event_target)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i < EVENTID_LAST; i++) {
|
||||
if(event_target->event_table[i])
|
||||
IDispatch_Release(event_target->event_table[i]);
|
||||
}
|
||||
|
||||
heap_free(event_target);
|
||||
}
|
|
@ -331,6 +331,8 @@ void HTMLDOMNode_destructor(HTMLDOMNode *This)
|
|||
{
|
||||
if(This->nsnode)
|
||||
nsIDOMNode_Release(This->nsnode);
|
||||
if(This->event_target)
|
||||
release_event_target(This->event_target);
|
||||
}
|
||||
|
||||
static const NodeImplVtbl HTMLDOMNodeImplVtbl = {
|
||||
|
@ -357,6 +359,7 @@ static HTMLDOMNode *create_node(HTMLDocument *doc, nsIDOMNode *nsnode)
|
|||
ret->lpHTMLDOMNodeVtbl = &HTMLDOMNodeVtbl;
|
||||
ret->ref = 1;
|
||||
ret->doc = doc;
|
||||
ret->event_target = NULL;
|
||||
|
||||
nsIDOMNode_AddRef(nsnode);
|
||||
ret->nsnode = nsnode;
|
||||
|
|
|
@ -56,6 +56,7 @@ typedef struct HTMLDOMNode HTMLDOMNode;
|
|||
typedef struct ConnectionPoint ConnectionPoint;
|
||||
typedef struct BSCallback BSCallback;
|
||||
typedef struct nsChannelBSC nsChannelBSC;
|
||||
typedef struct event_target_t event_target_t;
|
||||
|
||||
/* NOTE: make sure to keep in sync with dispex.c */
|
||||
typedef enum {
|
||||
|
@ -274,6 +275,7 @@ struct HTMLDOMNode {
|
|||
|
||||
nsIDOMNode *nsnode;
|
||||
HTMLDocument *doc;
|
||||
event_target_t *event_target;
|
||||
|
||||
HTMLDOMNode *next;
|
||||
};
|
||||
|
@ -426,6 +428,9 @@ void get_editor_controller(NSContainer*);
|
|||
void init_nsevents(NSContainer*);
|
||||
nsresult get_nsinterface(nsISupports*,REFIID,void**);
|
||||
|
||||
void check_event_attr(HTMLDocument*,nsIDOMElement*);
|
||||
void release_event_target(event_target_t*);
|
||||
|
||||
void set_document_bscallback(HTMLDocument*,nsChannelBSC*);
|
||||
void set_current_mon(HTMLDocument*,IMoniker*);
|
||||
HRESULT start_binding(HTMLDocument*,BSCallback*,IBindCtx*);
|
||||
|
@ -472,6 +477,7 @@ void release_nodes(HTMLDocument*);
|
|||
void release_script_hosts(HTMLDocument*);
|
||||
void connect_scripts(HTMLDocument*);
|
||||
void doc_insert_script(HTMLDocument*,nsIDOMHTMLScriptElement*);
|
||||
IDispatch *script_parse_event(HTMLDocument*,LPCWSTR);
|
||||
|
||||
IHTMLElementCollection *create_all_collection(HTMLDOMNode*);
|
||||
|
||||
|
|
|
@ -167,6 +167,7 @@ static nsresult NSAPI handle_node_insert(nsIDOMEventListener *iface, nsIDOMEvent
|
|||
NSContainer *This = NSEVENTLIST_THIS(iface)->This;
|
||||
nsIDOMHTMLScriptElement *script;
|
||||
nsIDOMEventTarget *target;
|
||||
nsIDOMElement *elem;
|
||||
nsresult nsres;
|
||||
|
||||
TRACE("(%p %p)\n", This, event);
|
||||
|
@ -174,16 +175,23 @@ static nsresult NSAPI handle_node_insert(nsIDOMEventListener *iface, nsIDOMEvent
|
|||
nsres = nsIDOMEvent_GetTarget(event, &target);
|
||||
if(NS_FAILED(nsres)) {
|
||||
ERR("GetTarget failed: %08x\n", nsres);
|
||||
return nsres;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsres = nsISupports_QueryInterface(target, &IID_nsIDOMHTMLScriptElement, (void**)&script);
|
||||
nsres = nsIDOMEventTarget_QueryInterface(target, &IID_nsIDOMElement, (void**)&elem);
|
||||
nsIDOMEventTarget_Release(target);
|
||||
if(NS_FAILED(nsres))
|
||||
return NS_OK;
|
||||
|
||||
nsres = nsIDOMElement_QueryInterface(elem, &IID_nsIDOMHTMLScriptElement, (void**)&script);
|
||||
if(SUCCEEDED(nsres)) {
|
||||
doc_insert_script(This->doc, script);
|
||||
nsIDOMHTMLScriptElement_Release(script);
|
||||
}
|
||||
|
||||
nsIDOMEventTarget_Release(target);
|
||||
check_event_attr(This->doc, elem);
|
||||
|
||||
nsIDOMNode_Release(elem);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
|
||||
|
||||
static const WCHAR windowW[] = {'w','i','n','d','o','w',0};
|
||||
static const WCHAR emptyW[] = {0};
|
||||
|
||||
static const CLSID CLSID_JScript =
|
||||
{0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
|
||||
|
@ -507,7 +508,7 @@ static const IActiveScriptSiteDebug32Vtbl ActiveScriptSiteDebug32Vtbl = {
|
|||
ActiveScriptSiteDebug32_OnScriptErrorDebug
|
||||
};
|
||||
|
||||
static ScriptHost *create_script_host(HTMLDocument *doc, GUID *guid)
|
||||
static ScriptHost *create_script_host(HTMLDocument *doc, const GUID *guid)
|
||||
{
|
||||
ScriptHost *ret;
|
||||
HRESULT hres;
|
||||
|
@ -705,15 +706,9 @@ static BOOL get_script_guid(nsIDOMHTMLScriptElement *nsscript, GUID *guid)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static ScriptHost *get_script_host(HTMLDocument *doc, nsIDOMHTMLScriptElement *nsscript)
|
||||
static ScriptHost *get_script_host(HTMLDocument *doc, const GUID *guid)
|
||||
{
|
||||
ScriptHost *iter;
|
||||
GUID guid;
|
||||
|
||||
if(!get_script_guid(nsscript, &guid)) {
|
||||
WARN("Could not find script GUID\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(IsEqualGUID(&CLSID_JScript, &guid)) {
|
||||
FIXME("Ignoring JScript\n");
|
||||
|
@ -721,18 +716,24 @@ static ScriptHost *get_script_host(HTMLDocument *doc, nsIDOMHTMLScriptElement *n
|
|||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY(iter, &doc->script_hosts, ScriptHost, entry) {
|
||||
if(IsEqualGUID(&guid, &iter->guid))
|
||||
if(IsEqualGUID(guid, &iter->guid))
|
||||
return iter;
|
||||
}
|
||||
|
||||
return create_script_host(doc, &guid);
|
||||
return create_script_host(doc, guid);
|
||||
}
|
||||
|
||||
void doc_insert_script(HTMLDocument *doc, nsIDOMHTMLScriptElement *nsscript)
|
||||
{
|
||||
ScriptHost *script_host;
|
||||
GUID guid;
|
||||
|
||||
script_host = get_script_host(doc, nsscript);
|
||||
if(!get_script_guid(nsscript, &guid)) {
|
||||
WARN("Could not find script GUID\n");
|
||||
return;
|
||||
}
|
||||
|
||||
script_host = get_script_host(doc, &guid);
|
||||
if(!script_host)
|
||||
return;
|
||||
|
||||
|
@ -740,6 +741,55 @@ void doc_insert_script(HTMLDocument *doc, nsIDOMHTMLScriptElement *nsscript)
|
|||
parse_script_elem(script_host, nsscript);
|
||||
}
|
||||
|
||||
IDispatch *script_parse_event(HTMLDocument *doc, LPCWSTR text)
|
||||
{
|
||||
ScriptHost *script_host;
|
||||
GUID guid = CLSID_JScript;
|
||||
const WCHAR *ptr;
|
||||
IDispatch *disp;
|
||||
HRESULT hres;
|
||||
|
||||
static const WCHAR delimiterW[] = {'\"',0};
|
||||
|
||||
for(ptr = text; isalnumW(*ptr); ptr++);
|
||||
if(*ptr == ':') {
|
||||
LPWSTR language;
|
||||
BOOL b;
|
||||
|
||||
language = heap_alloc((ptr-text+1)*sizeof(WCHAR));
|
||||
memcpy(language, text, (ptr-text)*sizeof(WCHAR));
|
||||
language[ptr-text] = 0;
|
||||
|
||||
b = get_guid_from_language(language, &guid);
|
||||
|
||||
heap_free(language);
|
||||
|
||||
if(!b) {
|
||||
WARN("Could not find language\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
}else {
|
||||
ptr = text;
|
||||
}
|
||||
|
||||
script_host = get_script_host(doc, &guid);
|
||||
if(!script_host || !script_host->parse_proc)
|
||||
return NULL;
|
||||
|
||||
hres = IActiveScriptParseProcedure_ParseProcedureText(script_host->parse_proc, ptr, NULL, emptyW,
|
||||
NULL, NULL, delimiterW, 0 /* FIXME */, 0,
|
||||
SCRIPTPROC_HOSTMANAGESSOURCE|SCRIPTPROC_IMPLICIT_THIS|SCRIPTPROC_IMPLICIT_PARENTS, &disp);
|
||||
if(FAILED(hres)) {
|
||||
WARN("ParseProcedureText failed: %08x\n", hres);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRACE("ret %p\n", disp);
|
||||
return disp;
|
||||
}
|
||||
|
||||
void release_script_hosts(HTMLDocument *doc)
|
||||
{
|
||||
ScriptHost *iter;
|
||||
|
|
Loading…
Reference in New Issue