static HRESULT WINAPI HTMLDocument3_getElementsByTagName(IHTMLDocument3 *iface, BSTR v, IHTMLElementCollection **pelColl) { HTMLDocument *This = impl_from_IHTMLDocument3(iface); nsIDOMNodeList *nslist; nsAString id_str; nsresult nsres; TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), pelColl); if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } nsAString_InitDepend(&id_str, v); nsres = nsIDOMHTMLDocument_GetElementsByTagName(This->doc_node->nsdoc, &id_str, &nslist); nsAString_Finish(&id_str); if(FAILED(nsres)) { ERR("GetElementByName failed: %08x\n", nsres); return E_FAIL; } *pelColl = create_collection_from_nodelist(This->doc_node, nslist); nsIDOMNodeList_Release(nslist); return S_OK; }
static ULONG WINAPI HTMLDOMChildrenCollection_Release(IHTMLDOMChildrenCollection *iface) { HTMLDOMChildrenCollection *This = impl_from_IHTMLDOMChildrenCollection(iface); LONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) ref=%d\n", This, ref); if(!ref) { nsIDOMNodeList_Release(This->nslist); heap_free(This); } return ref; }
static void remove_child_attr(nsIDOMElement *elem, LPCWSTR tag, nsAString *attr_str) { cpp_bool has_children; UINT32 child_cnt, i; nsIDOMNode *child_node; nsIDOMNodeList *node_list; UINT16 node_type; nsIDOMElement_HasChildNodes(elem, &has_children); if(!has_children) return; nsIDOMElement_GetChildNodes(elem, &node_list); nsIDOMNodeList_GetLength(node_list, &child_cnt); for(i=0; i<child_cnt; i++) { nsIDOMNodeList_Item(node_list, i, &child_node); nsIDOMNode_GetNodeType(child_node, &node_type); if(node_type == ELEMENT_NODE) { nsIDOMElement *child_elem; nsAString tag_str; const PRUnichar *ctag; nsIDOMNode_QueryInterface(child_node, &IID_nsIDOMElement, (void**)&child_elem); nsAString_Init(&tag_str, NULL); nsIDOMElement_GetTagName(child_elem, &tag_str); nsAString_GetData(&tag_str, &ctag); if(!strcmpiW(ctag, tag)) /* FIXME: remove node if there are no more attributes */ nsIDOMElement_RemoveAttribute(child_elem, attr_str); nsAString_Finish(&tag_str); remove_child_attr(child_elem, tag, attr_str); nsIDOMElement_Release(child_elem); } nsIDOMNode_Release(child_node); } nsIDOMNodeList_Release(node_list); }
static HRESULT WINAPI HTMLDOMNode_get_childNodes(IHTMLDOMNode *iface, IDispatch **p) { HTMLDOMNode *This = impl_from_IHTMLDOMNode(iface); nsIDOMNodeList *nslist; nsresult nsres; TRACE("(%p)->(%p)\n", This, p); nsres = nsIDOMNode_GetChildNodes(This->nsnode, &nslist); if(NS_FAILED(nsres)) { ERR("GetChildNodes failed: %08x\n", nsres); return E_FAIL; } *p = (IDispatch*)create_child_collection(This->doc, nslist); nsIDOMNodeList_Release(nslist); return S_OK; }
static HRESULT WINAPI HTMLDocument3_getElementsByName(IHTMLDocument3 *iface, BSTR v, IHTMLElementCollection **ppelColl) { HTMLDocument *This = impl_from_IHTMLDocument3(iface); nsIDOMNodeList *node_list; nsAString selector_str; WCHAR *selector; nsresult nsres; static const WCHAR formatW[] = {'*','[','i','d','=','%','s',']',',','*','[','n','a','m','e','=','%','s',']',0}; TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), ppelColl); if(!This->doc_node || !This->doc_node->nsdoc) { /* We should probably return an empty collection. */ FIXME("No nsdoc\n"); return E_NOTIMPL; } selector = heap_alloc(2*SysStringLen(v)*sizeof(WCHAR) + sizeof(formatW)); if(!selector) return E_OUTOFMEMORY; sprintfW(selector, formatW, v, v); /* * NOTE: IE getElementsByName implementation differs from Gecko. It searches both name and id attributes. * That's why we use CSS selector instead. We should also use name only when it applies to given element * types and search should be case insensitive. Those are currently not supported properly. */ nsAString_InitDepend(&selector_str, selector); nsres = nsIDOMNodeSelector_QuerySelectorAll(This->doc_node->nsnode_selector, &selector_str, &node_list); nsAString_Finish(&selector_str); heap_free(selector); if(NS_FAILED(nsres)) { ERR("QuerySelectorAll failed: %08x\n", nsres); return E_FAIL; } *ppelColl = create_collection_from_nodelist(This->doc_node, node_list); nsIDOMNodeList_Release(node_list); return S_OK; }
static HRESULT WINAPI HTMLElement2_getElementsByTagName(IHTMLElement2 *iface, BSTR v, IHTMLElementCollection **pelColl) { HTMLElement *This = impl_from_IHTMLElement2(iface); nsIDOMNodeList *nslist; nsAString tag_str; nsresult nsres; TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), pelColl); nsAString_InitDepend(&tag_str, v); nsres = nsIDOMHTMLElement_GetElementsByTagName(This->nselem, &tag_str, &nslist); nsAString_Finish(&tag_str); if(NS_FAILED(nsres)) { ERR("GetElementByTagName failed: %08x\n", nsres); return E_FAIL; } *pelColl = create_collection_from_nodelist(This->node.doc, nslist); nsIDOMNodeList_Release(nslist); return S_OK; }
HRESULT get_doc_elem_by_id(HTMLDocumentNode *doc, const WCHAR *id, HTMLElement **ret) { nsIDOMNodeList *nsnode_list; nsIDOMElement *nselem; nsIDOMNode *nsnode; nsAString id_str; nsresult nsres; HRESULT hres; if(!doc->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } nsAString_InitDepend(&id_str, id); /* get element by id attribute */ nsres = nsIDOMHTMLDocument_GetElementById(doc->nsdoc, &id_str, &nselem); if(FAILED(nsres)) { ERR("GetElementById failed: %08x\n", nsres); nsAString_Finish(&id_str); return E_FAIL; } /* get first element by name attribute */ nsres = nsIDOMHTMLDocument_GetElementsByName(doc->nsdoc, &id_str, &nsnode_list); nsAString_Finish(&id_str); if(FAILED(nsres)) { ERR("getElementsByName failed: %08x\n", nsres); if(nselem) nsIDOMElement_Release(nselem); return E_FAIL; } nsres = nsIDOMNodeList_Item(nsnode_list, 0, &nsnode); nsIDOMNodeList_Release(nsnode_list); assert(nsres == NS_OK); if(nsnode && nselem) { UINT16 pos; nsres = nsIDOMNode_CompareDocumentPosition(nsnode, (nsIDOMNode*)nselem, &pos); if(NS_FAILED(nsres)) { FIXME("CompareDocumentPosition failed: 0x%08x\n", nsres); nsIDOMNode_Release(nsnode); nsIDOMElement_Release(nselem); return E_FAIL; } TRACE("CompareDocumentPosition gave: 0x%x\n", pos); if(!(pos & (DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS))) { nsIDOMElement_Release(nselem); nselem = NULL; } } if(nsnode) { if(!nselem) { nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMElement, (void**)&nselem); assert(nsres == NS_OK); } nsIDOMNode_Release(nsnode); } if(!nselem) { *ret = NULL; return S_OK; } hres = get_elem(doc, nselem, ret); nsIDOMElement_Release(nselem); return hres; }
static HRESULT WINAPI HTMLDocument3_getElementById(IHTMLDocument3 *iface, BSTR v, IHTMLElement **pel) { 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; TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), pel); if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } nsAString_InitDepend(&id_str, v); /* get element by id attribute */ nsres = nsIDOMHTMLDocument_GetElementById(This->doc_node->nsdoc, &id_str, &nselem); if(FAILED(nsres)) { ERR("GetElementById failed: %08x\n", nsres); nsAString_Finish(&id_str); return E_FAIL; } nsnode_by_id = (nsIDOMNode*)nselem; /* get first element by name attribute */ nsres = nsIDOMHTMLDocument_GetElementsByName(This->doc_node->nsdoc, &id_str, &nsnode_list); nsAString_Finish(&id_str); if(FAILED(nsres)) { ERR("getElementsByName failed: %08x\n", nsres); if(nsnode_by_id) nsIDOMNode_Release(nsnode_by_id); return E_FAIL; } nsIDOMNodeList_Item(nsnode_list, 0, &nsnode_by_name); nsIDOMNodeList_Release(nsnode_list); 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 { *pel = NULL; } return S_OK; }