From 46df2fa9da42f377afcf5226d63231ef3c6a8cff Mon Sep 17 00:00:00 2001 From: Rob Shearman Date: Thu, 12 Jul 2007 15:37:06 +0100 Subject: [PATCH] mshtml: Implement HTMLElement_insertAdjacentHTML and HTMLElement_insertAdjacentText. --- dlls/mshtml/htmlelem.c | 159 +++++++++++++++++++++++++++++++++++++++- dlls/mshtml/nsiface.idl | 15 ++++ 2 files changed, 170 insertions(+), 4 deletions(-) diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 9d5d4751efd..1a78ad26a61 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -683,20 +683,171 @@ static HRESULT WINAPI HTMLElement_get_outerText(IHTMLElement *iface, BSTR *p) return E_NOTIMPL; } +static HRESULT HTMLElement_InsertAdjacentNode(HTMLElement *This, BSTR where, nsIDOMNode *nsnode) +{ + static const WCHAR wszBeforeBegin[] = {'b','e','f','o','r','e','B','e','g','i','n',0}; + static const WCHAR wszAfterBegin[] = {'a','f','t','e','r','B','e','g','i','n',0}; + static const WCHAR wszBeforeEnd[] = {'b','e','f','o','r','e','E','n','d',0}; + static const WCHAR wszAfterEnd[] = {'a','f','t','e','r','E','n','d',0}; + nsresult nsres; + + if (!strcmpiW(where, wszBeforeBegin)) + { + nsIDOMNode *unused; + nsIDOMNode *parent; + nsres = nsIDOMNode_GetParentNode(This->nselem, &parent); + if (!parent) return E_INVALIDARG; + nsres = nsIDOMNode_InsertBefore(parent, nsnode, + (nsIDOMNode *)This->nselem, &unused); + if (unused) nsIDOMNode_Release(unused); + nsIDOMNode_Release(parent); + } + else if (!strcmpiW(where, wszAfterBegin)) + { + nsIDOMNode *unused; + nsIDOMNode *first_child; + nsIDOMNode_GetFirstChild(This->nselem, &first_child); + nsres = nsIDOMNode_InsertBefore(This->nselem, nsnode, first_child, &unused); + if (unused) nsIDOMNode_Release(unused); + if (first_child) nsIDOMNode_Release(first_child); + } + else if (!strcmpiW(where, wszBeforeEnd)) + { + nsIDOMNode *unused; + nsres = nsIDOMNode_AppendChild(This->nselem, nsnode, &unused); + if (unused) nsIDOMNode_Release(unused); + } + else if (!strcmpiW(where, wszAfterEnd)) + { + nsIDOMNode *unused; + nsIDOMNode *next_sibling; + nsIDOMNode *parent; + nsIDOMNode_GetParentNode(This->nselem, &parent); + if (!parent) return E_INVALIDARG; + + nsIDOMNode_GetNextSibling(This->nselem, &next_sibling); + if (next_sibling) + { + nsres = nsIDOMNode_InsertBefore(parent, nsnode, next_sibling, &unused); + nsIDOMNode_Release(next_sibling); + } + else + nsres = nsIDOMNode_AppendChild(parent, nsnode, &unused); + nsIDOMNode_Release(parent); + if (unused) nsIDOMNode_Release(unused); + } + else + { + ERR("invalid where: %s\n", debugstr_w(where)); + return E_INVALIDARG; + } + + if (NS_FAILED(nsres)) + return E_FAIL; + else + return S_OK; +} + static HRESULT WINAPI HTMLElement_insertAdjacentHTML(IHTMLElement *iface, BSTR where, BSTR html) { HTMLElement *This = HTMLELEM_THIS(iface); - FIXME("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(html)); - return E_NOTIMPL; + nsresult nsres; + nsIDOMDocument *nsdoc; + nsIDOMDocumentRange *nsdocrange; + nsIDOMRange *range; + nsIDOMNSRange *nsrange; + nsIDOMNode *nsnode; + nsAString ns_html; + HRESULT hr; + + TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(html)); + + nsres = nsIWebNavigation_GetDocument(This->node->doc->nscontainer->navigation, &nsdoc); + if(NS_FAILED(nsres)) + { + ERR("GetDocument failed: %08x\n", nsres); + return E_FAIL; + } + + nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMDocumentRange, (void **)&nsdocrange); + nsIDOMDocument_Release(nsdoc); + if(NS_FAILED(nsres)) + { + ERR("getting nsIDOMDocumentRange failed: %08x\n", nsres); + return E_FAIL; + } + nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &range); + nsIDOMDocumentRange_Release(nsdocrange); + if(NS_FAILED(nsres)) + { + ERR("CreateRange failed: %08x\n", nsres); + return E_FAIL; + } + + nsIDOMRange_SetStartBefore(range, (nsIDOMNode *)This->nselem); + + nsIDOMRange_QueryInterface(range, &IID_nsIDOMNSRange, (void **)&nsrange); + nsIDOMRange_Release(range); + if(NS_FAILED(nsres)) + { + ERR("getting nsIDOMNSRange failed: %08x\n", nsres); + return E_FAIL; + } + + nsAString_Init(&ns_html, html); + + nsres = nsIDOMNSRange_CreateContextualFragment(nsrange, &ns_html, (nsIDOMDocumentFragment **)&nsnode); + nsIDOMNSRange_Release(nsrange); + nsAString_Finish(&ns_html); + + if(NS_FAILED(nsres) || !nsnode) + { + ERR("CreateTextNode failed: %08x\n", nsres); + return E_FAIL; + } + + hr = HTMLElement_InsertAdjacentNode(This, where, nsnode); + nsIDOMNode_Release(nsnode); + + return hr; } static HRESULT WINAPI HTMLElement_insertAdjacentText(IHTMLElement *iface, BSTR where, BSTR text) { HTMLElement *This = HTMLELEM_THIS(iface); - FIXME("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(text)); - return E_NOTIMPL; + nsresult nsres; + nsIDOMDocument *nsdoc; + nsIDOMNode *nsnode; + nsAString ns_text; + HRESULT hr; + + TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(text)); + + nsres = nsIWebNavigation_GetDocument(This->node->doc->nscontainer->navigation, &nsdoc); + if(NS_FAILED(nsres) || !nsdoc) + { + ERR("GetDocument failed: %08x\n", nsres); + return E_FAIL; + } + + nsAString_Init(&ns_text, text); + + nsres = nsIDOMDocument_CreateTextNode(nsdoc, &ns_text, (nsIDOMText **)&nsnode); + nsIDOMDocument_Release(nsdoc); + nsAString_Finish(&ns_text); + + if(NS_FAILED(nsres) || !nsnode) + { + ERR("CreateTextNode failed: %08x\n", nsres); + return E_FAIL; + } + + hr = HTMLElement_InsertAdjacentNode(This, where, nsnode); + nsIDOMNode_Release(nsnode); + + return hr; } static HRESULT WINAPI HTMLElement_get_parentTextEdit(IHTMLElement *iface, IHTMLElement **p) diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl index cc7ae353273..983e38a3f75 100644 --- a/dlls/mshtml/nsiface.idl +++ b/dlls/mshtml/nsiface.idl @@ -700,6 +700,21 @@ interface nsIDOMRange : nsISupports nsresult Detach(); } +[ + object, + uuid(a6cf90f2-15b3-11d2-932e-00805f8add32) +] +interface nsIDOMNSRange : nsISupports +{ + nsresult CreateContextualFragment([in] const nsAString *fragment, [out] nsIDOMDocumentFragment **_retval); + nsresult IsPointInRange([in] nsIDOMNode *parent, [in] PRInt32 offset, [out] PRBool *_retval); + nsresult ComparePoint([in] nsIDOMNode *parent, [in] PRInt32 offset, [out] PRInt16 *_retval); + nsresult IntersectsNode([in] nsIDOMNode *n, [out] PRBool *_retval); + nsresult CompareNode([in] nsIDOMNode *n, [out] PRUint16 *_retval); + nsresult nSDetach(); +} + + [ object, uuid(7b9badc6-c9bc-447a-8670-dbd195aed24b)