Jacek Caban : mshtml: Added support for conditional comments.
Alexandre Julliard
julliard at winehq.org
Thu Oct 16 06:07:06 CDT 2008
Module: wine
Branch: master
Commit: a1a25c534a22c0d6a868f9fcd62176dda65250c2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a1a25c534a22c0d6a868f9fcd62176dda65250c2
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed Oct 15 15:22:29 2008 -0500
mshtml: Added support for conditional comments.
---
dlls/mshtml/nsevents.c | 191 ++++++++++++++++++++++++++++++++++++++++++++---
dlls/mshtml/tests/dom.c | 24 ++++++
2 files changed, 204 insertions(+), 11 deletions(-)
diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c
index dc54322..806e9eb 100644
--- a/dlls/mshtml/nsevents.c
+++ b/dlls/mshtml/nsevents.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Jacek Caban for CodeWeavers
+ * Copyright 2007-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
@@ -175,11 +175,149 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event
return NS_OK;
}
+#define IE_MAJOR_VERSION 7
+#define IE_MINOR_VERSION 0
+
+static BOOL handle_insert_comment(HTMLDocument *doc, const PRUnichar *comment)
+{
+ DWORD len;
+ int majorv = 0, minorv = 0;
+ const PRUnichar *ptr, *end;
+ nsAString nsstr;
+ PRUnichar *buf;
+ nsresult nsres;
+
+ enum {
+ CMP_EQ,
+ CMP_LT,
+ CMP_LTE,
+ CMP_GT,
+ CMP_GTE
+ } cmpt = CMP_EQ;
+
+ static const PRUnichar endifW[] = {'<','!','[','e','n','d','i','f',']'};
+
+ if(comment[0] != '[' || comment[1] != 'i' || comment[2] != 'f')
+ return FALSE;
+
+ ptr = comment+3;
+ while(isspaceW(*ptr))
+ ptr++;
+
+ if(ptr[0] == 'l' && ptr[1] == 't') {
+ ptr += 2;
+ if(*ptr == 'e') {
+ cmpt = CMP_LTE;
+ ptr++;
+ }else {
+ cmpt = CMP_LT;
+ }
+ }else if(ptr[0] == 'g' && ptr[1] == 't') {
+ ptr += 2;
+ if(*ptr == 'e') {
+ cmpt = CMP_GTE;
+ ptr++;
+ }else {
+ cmpt = CMP_GT;
+ }
+ }
+
+ if(!isspaceW(*ptr++))
+ return FALSE;
+ while(isspaceW(*ptr))
+ ptr++;
+
+ if(ptr[0] != 'I' || ptr[1] != 'E')
+ return FALSE;
+
+ ptr +=2;
+ if(!isspaceW(*ptr++))
+ return FALSE;
+ while(isspaceW(*ptr))
+ ptr++;
+
+ if(!isdigitW(*ptr))
+ return FALSE;
+ while(isdigitW(*ptr))
+ majorv = majorv*10 + (*ptr++ - '0');
+
+ if(*ptr == '.') {
+ if(!isdigitW(*ptr))
+ return FALSE;
+ while(isdigitW(*ptr))
+ minorv = minorv*10 + (*ptr++ - '0');
+ }
+
+ while(isspaceW(*ptr))
+ ptr++;
+ if(ptr[0] != ']' || ptr[1] != '>')
+ return FALSE;
+ ptr += 2;
+
+ len = strlenW(ptr);
+ if(len < sizeof(endifW)/sizeof(WCHAR))
+ return FALSE;
+
+ end = ptr + len-sizeof(endifW)/sizeof(WCHAR);
+ if(memcmp(end, endifW, sizeof(endifW)))
+ return FALSE;
+
+ switch(cmpt) {
+ case CMP_EQ:
+ if(majorv == IE_MAJOR_VERSION && minorv == IE_MINOR_VERSION)
+ break;
+ return FALSE;
+ case CMP_LT:
+ if(majorv > IE_MAJOR_VERSION)
+ break;
+ if(majorv == IE_MAJOR_VERSION && minorv > IE_MINOR_VERSION)
+ break;
+ return FALSE;
+ case CMP_LTE:
+ if(majorv > IE_MAJOR_VERSION)
+ break;
+ if(majorv == IE_MAJOR_VERSION && minorv >= IE_MINOR_VERSION)
+ break;
+ return FALSE;
+ case CMP_GT:
+ if(majorv < IE_MAJOR_VERSION)
+ break;
+ if(majorv == IE_MAJOR_VERSION && minorv < IE_MINOR_VERSION)
+ break;
+ return FALSE;
+ case CMP_GTE:
+ if(majorv < IE_MAJOR_VERSION)
+ break;
+ if(majorv == IE_MAJOR_VERSION && minorv <= IE_MINOR_VERSION)
+ break;
+ return FALSE;
+ }
+
+ buf = heap_alloc((end-ptr+1)*sizeof(WCHAR));
+ if(!buf)
+ return FALSE;
+
+ memcpy(buf, ptr, (end-ptr)*sizeof(WCHAR));
+ buf[end-ptr] = 0;
+ nsAString_Init(&nsstr, buf);
+ heap_free(buf);
+
+ /* FIXME: Find better way to insert HTML to document. */
+ nsres = nsIDOMHTMLDocument_Write(doc->nsdoc, &nsstr);
+ nsAString_Finish(&nsstr);
+ if(NS_FAILED(nsres)) {
+ ERR("Write failed: %08x\n", nsres);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static nsresult NSAPI handle_node_insert(nsIDOMEventListener *iface, nsIDOMEvent *event)
{
NSContainer *This = NSEVENTLIST_THIS(iface)->This;
- nsIDOMHTMLScriptElement *script;
nsIDOMEventTarget *target;
+ nsIDOMComment *nscomment;
nsIDOMElement *elem;
nsresult nsres;
@@ -192,19 +330,50 @@ static nsresult NSAPI handle_node_insert(nsIDOMEventListener *iface, nsIDOMEvent
}
nsres = nsIDOMEventTarget_QueryInterface(target, &IID_nsIDOMElement, (void**)&elem);
- nsIDOMEventTarget_Release(target);
- if(NS_FAILED(nsres))
- return NS_OK;
+ if(NS_SUCCEEDED(nsres)) {
+ nsIDOMHTMLScriptElement *script;
+
+ nsres = nsIDOMElement_QueryInterface(elem, &IID_nsIDOMHTMLScriptElement, (void**)&script);
+ if(NS_SUCCEEDED(nsres)) {
+ doc_insert_script(This->doc, script);
+ nsIDOMHTMLScriptElement_Release(script);
+ }
- nsres = nsIDOMElement_QueryInterface(elem, &IID_nsIDOMHTMLScriptElement, (void**)&script);
- if(SUCCEEDED(nsres)) {
- doc_insert_script(This->doc, script);
- nsIDOMHTMLScriptElement_Release(script);
+ check_event_attr(This->doc, elem);
+
+ nsIDOMEventTarget_Release(target);
+ nsIDOMNode_Release(elem);
+ return NS_OK;
}
- check_event_attr(This->doc, elem);
+ nsres = nsIDOMEventTarget_QueryInterface(target, &IID_nsIDOMComment, (void**)&nscomment);
+ if(NS_SUCCEEDED(nsres)) {
+ nsAString comment_str;
+ BOOL remove_comment = FALSE;
+
+ nsAString_Init(&comment_str, NULL);
+ nsres = nsIDOMComment_GetData(nscomment, &comment_str);
+ if(NS_SUCCEEDED(nsres)) {
+ const PRUnichar *comment;
+
+ nsAString_GetData(&comment_str, &comment);
+ remove_comment = handle_insert_comment(This->doc, comment);
+ }
+
+ nsAString_Finish(&comment_str);
+
+ if(remove_comment) {
+ nsIDOMNode *nsparent, *tmp;
+
+ nsIDOMComment_GetParentNode(nscomment, &nsparent);
+ nsIDOMNode_RemoveChild(nsparent, (nsIDOMNode*)nscomment, &tmp);
+ nsIDOMNode_Release(nsparent);
+ nsIDOMNode_Release(tmp);
+ }
+
+ nsIDOMComment_Release(nscomment);
+ }
- nsIDOMNode_Release(elem);
return NS_OK;
}
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index 4388048..75538fe 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -53,6 +53,10 @@ static const char elem_test_str[] =
"</body></html>";
static const char indent_test_str[] =
"<html><head><title>test</title></head><body>abc<br /><a href=\"about:blank\">123</a></body></html>";
+static const char cond_comment_str[] =
+ "<html><head><title>test</title></head><body>"
+ "<!--[if gte IE 4]> <br> <![endif]-->"
+ "</body></html>";
static const WCHAR noneW[] = {'N','o','n','e',0};
@@ -3373,6 +3377,25 @@ static void test_indent(IHTMLDocument2 *doc)
IHTMLElementCollection_Release(col);
}
+static void test_cond_comment(IHTMLDocument2 *doc)
+{
+ IHTMLElementCollection *col;
+ HRESULT hres;
+
+ static const elem_type_t all_types[] = {
+ ET_HTML,
+ ET_HEAD,
+ ET_TITLE,
+ ET_BODY,
+ ET_BR
+ };
+
+ hres = IHTMLDocument2_get_all(doc, &col);
+ ok(hres == S_OK, "get_all failed: %08x\n", hres);
+ test_elem_collection((IUnknown*)col, all_types, sizeof(all_types)/sizeof(all_types[0]));
+ IHTMLElementCollection_Release(col);
+}
+
static IHTMLDocument2 *notif_doc;
static BOOL doc_complete;
@@ -3556,6 +3579,7 @@ START_TEST(dom)
run_domtest(doc_blank, test_create_elems);
run_domtest(doc_blank, test_defaults);
run_domtest(indent_test_str, test_indent);
+ run_domtest(cond_comment_str, test_cond_comment);
CoUninitialize();
gecko_installer_workaround(FALSE);
More information about the wine-cvs
mailing list