From 20b3aa62440a123aad1233c8598e9161a0b7ea8b Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 24 Nov 2014 18:47:41 +0100 Subject: [PATCH] mshtml: Added IHTMLTxtRange::setEndPoint implementation. --- dlls/mshtml/tests/dom.c | 75 +++++++++++++++++++++++++++++++++-------- dlls/mshtml/txtrange.c | 70 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 129 insertions(+), 16 deletions(-) diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 2d526fc040c..8a47207f5bb 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -4901,6 +4901,30 @@ static IHTMLTxtRange *test_create_body_range(IHTMLDocument2 *doc) return range; } +#define range_duplicate(a) _range_duplicate(__LINE__,a) +static IHTMLTxtRange *_range_duplicate(unsigned line, IHTMLTxtRange *range) +{ + IHTMLTxtRange *ret; + HRESULT hres; + + hres = IHTMLTxtRange_duplicate(range, &ret); + ok_(__FILE__,line)(hres == S_OK, "duplicate failed: %08x\n", hres); + + return ret; +} + +#define test_range_set_end_point(a,b,c,d) _test_range_set_end_point(__LINE__,a,b,c,d) +static void _test_range_set_end_point(unsigned line, IHTMLTxtRange *range, const char *how, + IHTMLTxtRange *ref_range, HRESULT exhres) +{ + BSTR str = a2bstr(how); + HRESULT hres; + + hres = IHTMLTxtRange_setEndPoint(range, str, ref_range); + ok_(__FILE__,line)(hres == exhres, "setEndPoint failed: %08x, expected %08x\n", hres, exhres); + SysFreeString(str); +} + static void test_txtrange(IHTMLDocument2 *doc) { IHTMLTxtRange *body_range, *range, *range2; @@ -4915,11 +4939,9 @@ static void test_txtrange(IHTMLDocument2 *doc) test_range_text(body_range, "test abc 123\r\nit's text"); - hres = IHTMLTxtRange_duplicate(body_range, &range); - ok(hres == S_OK, "duplicate failed: %08x\n", hres); + range = range_duplicate(body_range); + range2 = range_duplicate(body_range); - hres = IHTMLTxtRange_duplicate(body_range, &range2); - ok(hres == S_OK, "duplicate failed: %08x\n", hres); test_range_isequal(range, range2, VARIANT_TRUE); test_range_text(range, "test abc 123\r\nit's text"); @@ -4959,8 +4981,7 @@ static void test_txtrange(IHTMLDocument2 *doc) IHTMLTxtRange_Release(range); - hres = IHTMLTxtRange_duplicate(body_range, &range); - ok(hres == S_OK, "duplicate failed: %08x\n", hres); + range = range_duplicate(body_range); test_range_text(range, "test abc 123\r\nit's text"); test_range_move(range, characterW, 3, 3); @@ -4978,8 +4999,7 @@ static void test_txtrange(IHTMLDocument2 *doc) IHTMLTxtRange_Release(range); - hres = IHTMLTxtRange_duplicate(body_range, &range); - ok(hres == S_OK, "duplicate failed: %08x\n", hres); + range = range_duplicate(body_range); test_range_move(range, wordW, 1, 1); test_range_moveend(range, characterW, 2, 2); @@ -5005,8 +5025,7 @@ static void test_txtrange(IHTMLDocument2 *doc) IHTMLTxtRange_Release(range); - hres = IHTMLTxtRange_duplicate(body_range, &range); - ok(hres == S_OK, "duplicate failed: %08x\n", hres); + range = range_duplicate(body_range); test_range_move(range, wordW, 2, 2); test_range_moveend(range, characterW, 2, 2); @@ -5030,8 +5049,7 @@ static void test_txtrange(IHTMLDocument2 *doc) IHTMLTxtRange_Release(range); - hres = IHTMLTxtRange_duplicate(body_range, &range); - ok(hres == S_OK, "duplicate failed: %08x\n", hres); + range = range_duplicate(body_range); test_range_collapse(range, TRUE); test_range_expand(range, wordW, VARIANT_TRUE, "test "); @@ -5054,7 +5072,6 @@ static void test_txtrange(IHTMLDocument2 *doc) test_range_text(range, NULL); IHTMLTxtRange_Release(range); - IHTMLTxtRange_Release(body_range); hres = IHTMLDocument2_get_selection(doc, &selection); ok(hres == S_OK, "IHTMLDocument2_get_selection failed: %08x\n", hres); @@ -5116,9 +5133,39 @@ static void test_txtrange(IHTMLDocument2 *doc) test_range_text(range, "abc \r\npaste\r\nxyz abc 123\r\nit's text"); - IHTMLElement_Release(body); + test_range_move(range, wordW, 2, 2); + test_range_collapse(range, VARIANT_TRUE); + test_range_moveend(range, characterW, 5, 5); + test_range_text(range, "paste"); + + range2 = range_duplicate(range); + + test_range_set_end_point(range, "starttostart", body_range, S_OK); + test_range_text(range, "abc \r\npaste"); + + test_range_set_end_point(range, "endtoend", body_range, S_OK); + test_range_text(range, "abc \r\npaste\r\nxyz abc 123\r\nit's text"); + + test_range_set_end_point(range, "starttoend", range2, S_OK); + test_range_text(range, "\r\nxyz abc 123\r\nit's text"); + + test_range_set_end_point(range, "starttostart", body_range, S_OK); + test_range_set_end_point(range, "endtostart", range2, S_OK); + test_range_text(range, "abc "); + + test_range_set_end_point(range, "starttoend", body_range, S_OK); + test_range_text(range, "paste\r\nxyz abc 123\r\nit's text"); + + test_range_set_end_point(range, "EndToStart", body_range, S_OK); + test_range_text(range, "abc "); + + test_range_set_end_point(range, "xxx", body_range, E_INVALIDARG); IHTMLTxtRange_Release(range); + IHTMLTxtRange_Release(range2); + IHTMLTxtRange_Release(body_range); + IHTMLElement_Release(body); + } static void test_txtrange2(IHTMLDocument2 *doc) diff --git a/dlls/mshtml/txtrange.c b/dlls/mshtml/txtrange.c index 43c9f1a5f60..0dd3aaeb82c 100644 --- a/dlls/mshtml/txtrange.c +++ b/dlls/mshtml/txtrange.c @@ -1627,8 +1627,74 @@ static HRESULT WINAPI HTMLTxtRange_setEndPoint(IHTMLTxtRange *iface, BSTR how, IHTMLTxtRange *SourceRange) { HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface); - FIXME("(%p)->(%s %p)\n", This, debugstr_w(how), SourceRange); - return E_NOTIMPL; + HTMLTxtRange *src_range; + nsIDOMNode *ref_node; + INT32 ref_offset; + BOOL set_start; + int how_type; + INT16 cmp; + nsresult nsres; + + TRACE("(%p)->(%s %p)\n", This, debugstr_w(how), SourceRange); + + how_type = string_to_nscmptype(how); + if(how_type == -1) + return E_INVALIDARG; + + src_range = get_range_object(This->doc, SourceRange); + if(!src_range) + return E_FAIL; + + switch(how_type) { + case NS_START_TO_START: + case NS_END_TO_START: + nsres = nsIDOMRange_GetStartContainer(src_range->nsrange, &ref_node); + assert(nsres == NS_OK); + + nsres = nsIDOMRange_GetStartOffset(src_range->nsrange, &ref_offset); + assert(nsres == NS_OK); + + set_start = how_type == NS_START_TO_START; + break; + case NS_END_TO_END: + case NS_START_TO_END: + nsres = nsIDOMRange_GetEndContainer(src_range->nsrange, &ref_node); + assert(nsres == NS_OK); + + nsres = nsIDOMRange_GetEndOffset(src_range->nsrange, &ref_offset); + assert(nsres == NS_OK); + + set_start = how_type == NS_START_TO_END; + break; + DEFAULT_UNREACHABLE; + } + + nsres = nsIDOMRange_ComparePoint(This->nsrange, ref_node, ref_offset, &cmp); + assert(nsres == NS_OK); + + if(set_start) { + if(cmp <= 0) { + nsres = nsIDOMRange_SetStart(This->nsrange, ref_node, ref_offset); + }else { + nsres = nsIDOMRange_Collapse(This->nsrange, FALSE); + assert(nsres == NS_OK); + + nsres = nsIDOMRange_SetEnd(This->nsrange, ref_node, ref_offset); + } + }else { + if(cmp >= 0) { + nsres = nsIDOMRange_SetEnd(This->nsrange, ref_node, ref_offset); + }else { + nsres = nsIDOMRange_Collapse(This->nsrange, TRUE); + assert(nsres == NS_OK); + + nsres = nsIDOMRange_SetStart(This->nsrange, ref_node, ref_offset); + } + } + assert(nsres == NS_OK); + + nsIDOMNode_Release(ref_node); + return S_OK; } static HRESULT WINAPI HTMLTxtRange_compareEndPoints(IHTMLTxtRange *iface, BSTR how,