Jacek Caban : mshtml: Store compatibility mode provided by meta element.

Alexandre Julliard julliard at winehq.org
Wed Jul 6 09:57:30 CDT 2016


Module: wine
Branch: master
Commit: bda4b35aa39c9b67374aca38744ad2cd7aee36a3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bda4b35aa39c9b67374aca38744ad2cd7aee36a3

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Jul  5 22:47:00 2016 +0200

mshtml: Store compatibility mode provided by meta element.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mshtml/mshtml_private.h | 13 ++++++
 dlls/mshtml/mutation.c       | 94 +++++++++++++++++++++++++++++++++++++++++---
 dlls/mshtml/nsiface.idl      | 17 ++++++++
 3 files changed, 118 insertions(+), 6 deletions(-)

diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index d2191e3..89344ed 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -229,6 +229,18 @@ TID_LIST
     LAST_tid
 } tid_t;
 
+typedef enum {
+    COMPAT_MODE_QUIRKS,
+    COMPAT_MODE_IE7,
+    COMPAT_MODE_IE8,
+    COMPAT_MODE_IE9,
+    COMPAT_MODE_IE10,
+    COMPAT_MODE_IE11
+} compat_mode_t;
+
+#define COMPAT_MODE_CNT (COMPAT_MODE_IE11+1)
+#define COMPAT_MODE_NONE COMPAT_MODE_QUIRKS
+
 typedef struct dispex_data_t dispex_data_t;
 typedef struct dispex_dynamic_data_t dispex_dynamic_data_t;
 
@@ -775,6 +787,7 @@ struct HTMLDocumentNode {
 
     LONG ref;
 
+    compat_mode_t document_mode;
     HTMLInnerWindow *window;
 
     nsIDOMHTMLDocument *nsdoc;
diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c
index adde295..dd3d119 100644
--- a/dlls/mshtml/mutation.c
+++ b/dlls/mshtml/mutation.c
@@ -361,6 +361,79 @@ static nsresult run_insert_script(HTMLDocumentNode *doc, nsISupports *script_ifa
     return NS_OK;
 }
 
+static void set_document_mode(HTMLDocumentNode *doc, compat_mode_t document_mode)
+{
+    TRACE("%p: %d\n", doc, document_mode);
+    doc->document_mode = document_mode;
+}
+
+static BOOL parse_ua_compatible(const WCHAR *p, compat_mode_t *r)
+{
+    int v = 0;
+
+    if(p[0] != 'I' || p[1] != 'E' || p[2] != '=')
+        return FALSE;
+
+    p += 3;
+    while('0' <= *p && *p <= '9')
+        v = v*10 + *(p++)-'0';
+    if(*p || !v)
+        return FALSE;
+
+    switch(v){
+    case 7:
+        *r = COMPAT_MODE_IE7;
+        break;
+    case 8:
+        *r = COMPAT_MODE_IE8;
+        break;
+    case 9:
+        *r = COMPAT_MODE_IE9;
+        break;
+    case 10:
+        *r = COMPAT_MODE_IE10;
+        break;
+    default:
+        *r = v < 7 ? COMPAT_MODE_QUIRKS : COMPAT_MODE_IE11;
+    }
+
+    return TRUE;
+}
+
+static void process_meta_element(HTMLDocumentNode *doc, nsIDOMHTMLMetaElement *meta_element)
+{
+    nsAString http_equiv_str, content_str;
+    nsresult nsres;
+
+    static const WCHAR x_ua_compatibleW[] = {'x','-','u','a','-','c','o','m','p','a','t','i','b','l','e',0};
+
+    nsAString_Init(&http_equiv_str, NULL);
+    nsAString_Init(&content_str, NULL);
+    nsres = nsIDOMHTMLMetaElement_GetHttpEquiv(meta_element, &http_equiv_str);
+    if(NS_SUCCEEDED(nsres))
+        nsres = nsIDOMHTMLMetaElement_GetContent(meta_element, &content_str);
+
+    if(NS_SUCCEEDED(nsres)) {
+        const PRUnichar *http_equiv, *content;
+
+        nsAString_GetData(&http_equiv_str, &http_equiv);
+        nsAString_GetData(&content_str, &content);
+
+        TRACE("%s: %s\n", debugstr_w(http_equiv), debugstr_w(content));
+
+        if(!strcmpiW(http_equiv, x_ua_compatibleW)) {
+            compat_mode_t document_mode;
+            if(parse_ua_compatible(content, &document_mode))
+                set_document_mode(doc, document_mode);
+            else
+                FIXME("Unsupported document mode %s\n", debugstr_w(content));
+        }
+    }
+
+    nsAString_Finish(&http_equiv_str);
+    nsAString_Finish(&content_str);
+}
+
 typedef struct nsRunnable nsRunnable;
 
 typedef nsresult (*runnable_proc_t)(HTMLDocumentNode*,nsISupports*,nsISupports*);
@@ -640,18 +713,13 @@ static void NSAPI nsDocumentObserver_BindToDocument(nsIDocumentObserver *iface,
     nsIDOMHTMLIFrameElement *nsiframe;
     nsIDOMHTMLFrameElement *nsframe;
     nsIDOMHTMLScriptElement *nsscript;
+    nsIDOMHTMLMetaElement *nsmeta;
     nsIDOMHTMLElement *nselem;
     nsIDOMComment *nscomment;
     nsresult nsres;
 
     TRACE("(%p)->(%p %p)\n", This, aDocument, aContent);
 
-    nsres = nsIContent_QueryInterface(aContent, &IID_nsIDOMHTMLElement, (void**)&nselem);
-    if(NS_SUCCEEDED(nsres)) {
-        check_event_attr(This, nselem);
-        nsIDOMHTMLElement_Release(nselem);
-    }
-
     nsres = nsIContent_QueryInterface(aContent, &IID_nsIDOMComment, (void**)&nscomment);
     if(NS_SUCCEEDED(nsres)) {
         TRACE("comment node\n");
@@ -661,6 +729,13 @@ static void NSAPI nsDocumentObserver_BindToDocument(nsIDocumentObserver *iface,
         return;
     }
 
+    nsres = nsIContent_QueryInterface(aContent, &IID_nsIDOMHTMLElement, (void**)&nselem);
+    if(NS_FAILED(nsres))
+        return;
+
+    check_event_attr(This, nselem);
+    nsIDOMHTMLElement_Release(nselem);
+
     nsres = nsIContent_QueryInterface(aContent, &IID_nsIDOMHTMLIFrameElement, (void**)&nsiframe);
     if(NS_SUCCEEDED(nsres)) {
         TRACE("iframe node\n");
@@ -695,6 +770,13 @@ static void NSAPI nsDocumentObserver_BindToDocument(nsIDocumentObserver *iface,
             add_script_runner(This, run_insert_script, (nsISupports*)nsscript, NULL);
 
         IHTMLScriptElement_Release(&script_elem->IHTMLScriptElement_iface);
+        return;
+    }
+
+    nsres = nsIContent_QueryInterface(aContent, &IID_nsIDOMHTMLMetaElement, (void**)&nsmeta);
+    if(NS_SUCCEEDED(nsres)) {
+        process_meta_element(This, nsmeta);
+        nsIDOMHTMLMetaElement_Release(nsmeta);
     }
 }
 
diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl
index 7d9fbe8..1b6104a 100644
--- a/dlls/mshtml/nsiface.idl
+++ b/dlls/mshtml/nsiface.idl
@@ -1146,6 +1146,23 @@ interface nsIDOMHTMLHeadElement : nsISupports
 
 [
     object,
+    uuid(2a3f789e-0667-464f-a8d7-6f58513443d9),
+    local
+]
+interface nsIDOMHTMLMetaElement : nsISupports
+{
+    nsresult GetContent(nsAString *aContent);
+    nsresult SetContent(const nsAString *aContent);
+    nsresult GetHttpEquiv(nsAString *aHttpEquiv);
+    nsresult SetHttpEquiv(const nsAString *aHttpEquiv);
+    nsresult GetName(nsAString *aName);
+    nsresult SetName(const nsAString *aName);
+    nsresult GetScheme(nsAString *aScheme);
+    nsresult SetScheme(const nsAString *aScheme);
+}
+
+[
+    object,
     uuid(4109a2d2-e7af-445d-bb72-c7c9b875f35e),
     local
 ]




More information about the wine-cvs mailing list