diff --git a/dlls/mshtml/htmldoc3.c b/dlls/mshtml/htmldoc3.c
index a00fa95b21b..b930d882344 100644
--- a/dlls/mshtml/htmldoc3.c
+++ b/dlls/mshtml/htmldoc3.c
@@ -431,6 +431,8 @@ static HRESULT WINAPI HTMLDocument3_getElementById(IHTMLDocument3 *iface, BSTR v
HTMLDocument *This = HTMLDOC3_THIS(iface);
nsIDOMElement *nselem;
HTMLDOMNode *node;
+ nsIDOMNode *nsnode, *nsnode_by_id, *nsnode_by_name;
+ nsIDOMNodeList *nsnode_list;
nsAString id_str;
nsresult nsres;
@@ -442,16 +444,64 @@ static HRESULT WINAPI HTMLDocument3_getElementById(IHTMLDocument3 *iface, BSTR v
}
nsAString_Init(&id_str, v);
+ /* get element by id attribute */
nsres = nsIDOMHTMLDocument_GetElementById(This->doc_node->nsdoc, &id_str, &nselem);
- nsAString_Finish(&id_str);
if(FAILED(nsres)) {
ERR("GetElementById failed: %08x\n", nsres);
+ nsAString_Finish(&id_str);
return E_FAIL;
}
+ nsnode_by_id = (nsIDOMNode*)nselem;
- if(nselem) {
- node = get_node(This->doc_node, (nsIDOMNode*)nselem, TRUE);
- nsIDOMElement_Release(nselem);
+ /* get first element by name attribute */
+ nsres = nsIDOMHTMLDocument_GetElementsByName(This->doc_node->nsdoc, &id_str, &nsnode_list);
+ if(FAILED(nsres)) {
+ ERR("getElementsByName failed: %08x\n", nsres);
+ nsAString_Finish(&id_str);
+ if(nsnode_by_id)
+ nsIDOMNode_Release(nsnode_by_id);
+ return E_FAIL;
+ }
+ nsIDOMNodeList_Item(nsnode_list, 0, &nsnode_by_name);
+ nsIDOMNodeList_Release(nsnode_list);
+
+ nsAString_Finish(&id_str);
+
+ if(nsnode_by_name && nsnode_by_id) {
+ nsIDOM3Node *node3;
+ PRUint16 pos;
+
+ nsres = nsIDOMNode_QueryInterface(nsnode_by_name, &IID_nsIDOM3Node, (void**)&node3);
+ if(NS_FAILED(nsres)) {
+ FIXME("failed to get nsIDOM3Node interface: 0x%08x\n", nsres);
+ nsIDOMNode_Release(nsnode_by_name);
+ nsIDOMNode_Release(nsnode_by_id);
+ return E_FAIL;
+ }
+
+ nsres = nsIDOM3Node_CompareDocumentPosition(node3, nsnode_by_id, &pos);
+ nsIDOM3Node_Release(node3);
+ if(NS_FAILED(nsres)) {
+ FIXME("nsIDOM3Node_CompareDocumentPosition failed: 0x%08x\n", nsres);
+ nsIDOMNode_Release(nsnode_by_name);
+ nsIDOMNode_Release(nsnode_by_id);
+ return E_FAIL;
+ }
+
+ TRACE("CompareDocumentPosition gave: 0x%x\n", pos);
+ if(pos & PRECEDING || pos & CONTAINS) {
+ nsnode = nsnode_by_id;
+ nsIDOMNode_Release(nsnode_by_name);
+ }else {
+ nsnode = nsnode_by_name;
+ nsIDOMNode_Release(nsnode_by_id);
+ }
+ }else
+ nsnode = nsnode_by_name ? nsnode_by_name : nsnode_by_id;
+
+ if(nsnode) {
+ node = get_node(This->doc_node, nsnode, TRUE);
+ nsIDOMNode_Release(nsnode);
IHTMLDOMNode_QueryInterface(HTMLDOMNODE(node), &IID_IHTMLElement, (void**)pel);
}else {
diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl
index 19f29b0b663..9d0bb309dbd 100644
--- a/dlls/mshtml/nsiface.idl
+++ b/dlls/mshtml/nsiface.idl
@@ -140,6 +140,8 @@ typedef nsISupports nsIContent;
typedef nsISupports nsINode;
typedef nsISupports nsIStyleSheet;
typedef nsISupports nsIStyleRule;
+typedef nsISupports nsIVariant;
+typedef nsISupports nsIDOMUserDataHandler;
[
object,
@@ -601,6 +603,37 @@ interface nsIDOMNodeList : nsISupports
nsresult GetLength(PRUint32 *aLength);
}
+[
+ object,
+ uuid(29fb2a18-1dd2-11b2-8dd9-a6fd5d5ad12f),
+ local
+ /* NOT_FROZEN */
+]
+interface nsIDOM3Node : nsISupports
+{
+ enum NSDOCPOSITION {
+ DISCONNECTED = 1,
+ PRECEDING = 2,
+ FOLLOWING = 4,
+ CONTAINS = 8,
+ CONTAINED_BY = 16,
+ IMPLEMENTATION_SPECIFIC = 32
+ };
+
+ nsresult GetBaseURI(nsAString *aBaseURI);
+ nsresult CompareDocumentPosition(nsIDOMNode *other, PRUint16 *_retval);
+ nsresult GetTextContent(nsAString *aTextContent);
+ nsresult SetTextContent(const nsAString *aTextContent);
+ nsresult IsSameNode(nsIDOMNode *other, PRBool *_retval);
+ nsresult LookupPrefix(const nsAString *namespaceURI, PRBool *_retval);
+ nsresult IsDefaultNamespace(const nsAString *namespaceURI, PRBool *_retval);
+ nsresult LookupNamespaceURI(const nsAString *prefix, nsAString _retval);
+ nsresult IsEqualNode(nsIDOMNode *arg, PRBool *_retval);
+ nsresult GetFeature(const nsAString *feature, const nsAString *version, nsISupports **_retval);
+ nsresult SetUserData(const nsAString *key, nsIVariant *data, nsIDOMUserDataHandler *handler, nsIVariant **_retval);
+ nsresult GetUserData(const nsAString *key, nsIVariant **_retval);
+}
+
[
object,
uuid(a6cf907c-15b3-11d2-932e-00805f8add32),
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index 868116427fc..bd55c9f5fba 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -65,7 +65,7 @@ static const char cond_comment_str[] =
"