Commit 918b00f8 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

mshtml: More range tests and fixes.

parent f309cdf7
...@@ -497,12 +497,14 @@ static void _test_range_moveend(unsigned line, IHTMLTxtRange *range, LPWSTR unit ...@@ -497,12 +497,14 @@ static void _test_range_moveend(unsigned line, IHTMLTxtRange *range, LPWSTR unit
} }
#define test_range_put_text(r,t) _test_range_put_text(__LINE__,r,t) #define test_range_put_text(r,t) _test_range_put_text(__LINE__,r,t)
static void _test_range_put_text(unsigned line, IHTMLTxtRange *range, LPCWSTR text) static void _test_range_put_text(unsigned line, IHTMLTxtRange *range, const char *text)
{ {
HRESULT hres; HRESULT hres;
BSTR bstr = a2bstr(text);
hres = IHTMLTxtRange_put_text(range, (BSTR)text); hres = IHTMLTxtRange_put_text(range, bstr);
ok_(__FILE__,line) (hres == S_OK, "put_text failed: %08x\n", hres); ok_(__FILE__,line) (hres == S_OK, "put_text failed: %08x\n", hres);
SysFreeString(bstr);
_test_range_text(line, range, NULL); _test_range_text(line, range, NULL);
} }
...@@ -759,6 +761,14 @@ static void test_txtrange(IHTMLDocument2 *doc) ...@@ -759,6 +761,14 @@ static void test_txtrange(IHTMLDocument2 *doc)
test_range_text(range, NULL); test_range_text(range, NULL);
test_range_moveend(range, characterW, 3, 3); test_range_moveend(range, characterW, 3, 3);
test_range_text(range, "c 1"); test_range_text(range, "c 1");
test_range_expand(range, texteditW, VARIANT_TRUE, "test abc 123\r\nit's text");
test_range_collapse(range, TRUE);
test_range_move(range, characterW, 4, 4);
test_range_moveend(range, characterW, 1, 1);
test_range_text(range, " ");
test_range_move(range, wordW, 1, 1);
test_range_moveend(range, characterW, 2, 2);
test_range_text(range, "ab");
IHTMLTxtRange_Release(range); IHTMLTxtRange_Release(range);
...@@ -838,7 +848,7 @@ static void test_txtrange(IHTMLDocument2 *doc) ...@@ -838,7 +848,7 @@ static void test_txtrange(IHTMLDocument2 *doc)
test_range_collapse(range, TRUE); test_range_collapse(range, TRUE);
test_range_expand(range, wordW, VARIANT_TRUE, "test "); test_range_expand(range, wordW, VARIANT_TRUE, "test ");
test_range_put_text(range, wordW); test_range_put_text(range, "word");
test_range_text(body_range, "wordabc 123\r\nit's text"); test_range_text(body_range, "wordabc 123\r\nit's text");
test_range_text(range, NULL); test_range_text(range, NULL);
test_range_moveend(range, characterW, 3, 3); test_range_moveend(range, characterW, 3, 3);
...@@ -878,6 +888,20 @@ static void test_txtrange(IHTMLDocument2 *doc) ...@@ -878,6 +888,20 @@ static void test_txtrange(IHTMLDocument2 *doc)
test_range_expand(range, texteditW, VARIANT_TRUE, "wordabc 123\r\nit's text"); test_range_expand(range, texteditW, VARIANT_TRUE, "wordabc 123\r\nit's text");
test_range_move(range, characterW, 3, 3); test_range_move(range, characterW, 3, 3);
test_range_expand(range, wordW, VARIANT_TRUE, "wordabc "); test_range_expand(range, wordW, VARIANT_TRUE, "wordabc ");
test_range_moveend(range, characterW, -4, -4);
test_range_put_text(range, "abc def ");
test_range_expand(range, texteditW, VARIANT_TRUE, "abc def abc 123\r\nit's text");
test_range_move(range, wordW, 1, 1);
test_range_movestart(range, characterW, -1, -1);
test_range_text(range, " ");
test_range_move(range, wordW, 1, 1);
test_range_moveend(range, characterW, 3, 3);
test_range_text(range, "def");
test_range_put_text(range, "xyz");
test_range_moveend(range, characterW, 1, 1);
test_range_move(range, wordW, 1, 1);
test_range_moveend(range, characterW, 2, 2);
test_range_text(range, "ab");
IHTMLTxtRange_Release(range); IHTMLTxtRange_Release(range);
} }
......
...@@ -122,7 +122,7 @@ static int string_to_nscmptype(LPCWSTR str) ...@@ -122,7 +122,7 @@ static int string_to_nscmptype(LPCWSTR str)
static PRUint16 get_node_type(nsIDOMNode *node) static PRUint16 get_node_type(nsIDOMNode *node)
{ {
PRUint16 type = 0xfff; PRUint16 type = 0;
if(node) if(node)
nsIDOMNode_GetNodeType(node, &type); nsIDOMNode_GetNodeType(node, &type);
...@@ -190,6 +190,8 @@ static void wstrbuf_append_nodetxt(wstrbuf_t *buf, LPCWSTR str, int len) ...@@ -190,6 +190,8 @@ static void wstrbuf_append_nodetxt(wstrbuf_t *buf, LPCWSTR str, int len)
const WCHAR *s = str; const WCHAR *s = str;
WCHAR *d; WCHAR *d;
TRACE("%s\n", debugstr_wn(str, len));
if(buf->len+len >= buf->size) { if(buf->len+len >= buf->size) {
buf->size = 2*buf->len+len; buf->size = 2*buf->len+len;
buf->buf = mshtml_realloc(buf->buf, buf->size * sizeof(WCHAR)); buf->buf = mshtml_realloc(buf->buf, buf->size * sizeof(WCHAR));
...@@ -262,6 +264,9 @@ static BOOL fill_nodestr(dompos_t *pos) ...@@ -262,6 +264,9 @@ static BOOL fill_nodestr(dompos_t *pos)
nsIDOMText_Release(text); nsIDOMText_Release(text);
nsAString_GetData(&pos->str, &pos->p, NULL); nsAString_GetData(&pos->str, &pos->p, NULL);
if(pos->off == -1)
pos->off = *pos->p ? strlenW(pos->p)-1 : 0;
return TRUE; return TRUE;
} }
...@@ -416,7 +421,7 @@ static void set_range_pos(HTMLTxtRange *This, BOOL start, dompos_t *pos) ...@@ -416,7 +421,7 @@ static void set_range_pos(HTMLTxtRange *This, BOOL start, dompos_t *pos)
else else
nsres = nsIDOMRange_SetStartBefore(This->nsrange, pos->node); nsres = nsIDOMRange_SetStartBefore(This->nsrange, pos->node);
}else { }else {
if(pos->type == TEXT_NODE) if(pos->type == TEXT_NODE && pos->p[pos->off+1])
nsres = nsIDOMRange_SetEnd(This->nsrange, pos->node, pos->off+1); nsres = nsIDOMRange_SetEnd(This->nsrange, pos->node, pos->off+1);
else else
nsres = nsIDOMRange_SetEndAfter(This->nsrange, pos->node); nsres = nsIDOMRange_SetEndAfter(This->nsrange, pos->node);
...@@ -520,6 +525,27 @@ static WCHAR get_pos_char(const dompos_t *pos) ...@@ -520,6 +525,27 @@ static WCHAR get_pos_char(const dompos_t *pos)
return 0; return 0;
} }
static void end_space(const dompos_t *pos, dompos_t *new_pos)
{
const WCHAR *p;
*new_pos = *pos;
dompos_addref(new_pos);
if(pos->type != TEXT_NODE)
return;
p = new_pos->p+new_pos->off;
if(!*p || !isspace(*p))
return;
while(p[1] && isspace(p[1]))
p++;
new_pos->off = p - new_pos->p;
}
static WCHAR next_char(const dompos_t *pos, dompos_t *new_pos) static WCHAR next_char(const dompos_t *pos, dompos_t *new_pos)
{ {
nsIDOMNode *iter, *tmp; nsIDOMNode *iter, *tmp;
...@@ -528,7 +554,13 @@ static WCHAR next_char(const dompos_t *pos, dompos_t *new_pos) ...@@ -528,7 +554,13 @@ static WCHAR next_char(const dompos_t *pos, dompos_t *new_pos)
WCHAR cspace = 0; WCHAR cspace = 0;
if(pos->type == TEXT_NODE && pos->off != -1 && pos->p[pos->off]) { if(pos->type == TEXT_NODE && pos->off != -1 && pos->p[pos->off]) {
p = pos->p+pos->off+1; p = pos->p+pos->off;
if(isspace(*p))
while(isspaceW(*++p));
else
p++;
if(*p && isspaceW(*p)) { if(*p && isspaceW(*p)) {
cspace = ' '; cspace = ' ';
while(p[1] && isspaceW(p[1])) while(p[1] && isspaceW(p[1]))
...@@ -540,7 +572,7 @@ static WCHAR next_char(const dompos_t *pos, dompos_t *new_pos) ...@@ -540,7 +572,7 @@ static WCHAR next_char(const dompos_t *pos, dompos_t *new_pos)
new_pos->off = p - pos->p; new_pos->off = p - pos->p;
dompos_addref(new_pos); dompos_addref(new_pos);
return *p; return cspace ? cspace : *p;
}else { }else {
last_space = *pos; last_space = *pos;
last_space.off = p - pos->p; last_space.off = p - pos->p;
...@@ -719,8 +751,7 @@ static long move_next_chars(long cnt, const dompos_t *pos, BOOL col, const dompo ...@@ -719,8 +751,7 @@ static long move_next_chars(long cnt, const dompos_t *pos, BOOL col, const dompo
ret++; ret++;
if(ret >= cnt) { if(ret >= cnt) {
*new_pos = *pos; end_space(pos, new_pos);
dompos_addref(new_pos);
return ret; return ret;
} }
...@@ -771,75 +802,102 @@ static long move_prev_chars(HTMLTxtRange *This, long cnt, const dompos_t *pos, B ...@@ -771,75 +802,102 @@ static long move_prev_chars(HTMLTxtRange *This, long cnt, const dompos_t *pos, B
ret++; ret++;
if(bound_pos && dompos_cmp(&iter, bound_pos)) if(bound_pos && dompos_cmp(&iter, bound_pos)) {
*bounded = TRUE; *bounded = TRUE;
cnt--;
}
} }
*new_pos = iter; *new_pos = iter;
return ret; return bounded && *bounded ? ret+1 : ret;
} }
static BOOL find_next_space(const dompos_t *pos, dompos_t *ret) static long find_prev_space(HTMLTxtRange *This, const dompos_t *pos, BOOL first_space, dompos_t *ret)
{ {
dompos_t iter, tmp; dompos_t iter, tmp;
WCHAR c; WCHAR c;
c = next_char(pos, &iter); c = prev_char(This, pos, &iter);
if(!c) { if(!c || (first_space && isspaceW(c))) {
*ret = iter; *ret = iter;
return FALSE; return FALSE;
} }
while(c && !isspaceW(c)) { while(1) {
tmp = iter; tmp = iter;
c = next_char(&tmp, &iter); c = prev_char(This, &tmp, &iter);
if(!c || isspaceW(c)) {
dompos_release(&iter);
break;
}
dompos_release(&tmp); dompos_release(&tmp);
} }
*ret = iter; *ret = tmp;
return TRUE; return TRUE;
} }
static long find_prev_space(HTMLTxtRange *This, const dompos_t *pos, BOOL first_space, dompos_t *ret) static int find_word_end(const dompos_t *pos, dompos_t *ret)
{ {
dompos_t iter, tmp; dompos_t iter, tmp;
int cnt = 1;
WCHAR c; WCHAR c;
c = get_pos_char(pos);
if(isspaceW(c)) {
*ret = *pos;
dompos_addref(ret);
return 0;
}
c = prev_char(This, pos, &iter); c = next_char(pos, &iter);
if(!c || (first_space && isspaceW(c))) { if(!c) {
*ret = iter; *ret = iter;
return FALSE; return 0;
}
if(c == '\n') {
*ret = *pos;
dompos_addref(ret);
return 0;
} }
while(1) { while(c && !isspaceW(c)) {
tmp = iter; tmp = iter;
c = prev_char(This, &tmp, &iter); c = next_char(&tmp, &iter);
if(!c || isspaceW(c)) { if(c == '\n') {
dompos_release(&iter); dompos_release(&iter);
break; iter = tmp;
}else {
cnt++;
dompos_release(&tmp);
} }
dompos_release(&tmp);
} }
*ret = tmp; *ret = iter;
return TRUE; return cnt;
} }
static long move_next_words(long cnt, const dompos_t *pos, dompos_t *new_pos) static long move_next_words(long cnt, const dompos_t *pos, dompos_t *new_pos)
{ {
dompos_t iter, tmp; dompos_t iter, tmp;
long ret = 0; long ret = 0;
WCHAR c;
iter = *pos; c = get_pos_char(pos);
dompos_addref(&iter); if(isspaceW(c)) {
end_space(pos, &iter);
while(ret < cnt) {
if(!find_next_space(&iter, &tmp))
break;
ret++; ret++;
dompos_release(&iter); }else {
iter = tmp; c = next_char(pos, &iter);
if(c && isspaceW(c))
ret++;
}
while(c && ret < cnt) {
tmp = iter;
c = next_char(&tmp, &iter);
dompos_release(&tmp);
if(isspaceW(c))
ret++;
} }
*new_pos = iter; *new_pos = iter;
...@@ -1192,26 +1250,30 @@ static HRESULT WINAPI HTMLTxtRange_expand(IHTMLTxtRange *iface, BSTR Unit, VARIA ...@@ -1192,26 +1250,30 @@ static HRESULT WINAPI HTMLTxtRange_expand(IHTMLTxtRange *iface, BSTR Unit, VARIA
switch(unit) { switch(unit) {
case RU_WORD: { case RU_WORD: {
dompos_t end_pos, start_pos, new_pos; dompos_t end_pos, start_pos, new_start_pos, new_end_pos;
PRBool collapsed;
nsIDOMRange_GetCollapsed(This->nsrange, &collapsed);
get_cur_pos(This, TRUE, &start_pos); get_cur_pos(This, TRUE, &start_pos);
get_cur_pos(This, FALSE, &end_pos); get_cur_pos(This, FALSE, &end_pos);
if(!isspaceW(get_pos_char(&end_pos))) { if(find_word_end(&end_pos, &new_end_pos) || collapsed) {
if(find_next_space(&end_pos, &new_pos)) { set_range_pos(This, FALSE, &new_end_pos);
set_range_pos(This, FALSE, &new_pos); *Success = VARIANT_TRUE;
*Success = VARIANT_TRUE;
}
dompos_release(&new_pos);
} }
if(find_prev_space(This, &start_pos, TRUE, &new_pos)) { if(start_pos.type && (get_pos_char(&end_pos) || !dompos_cmp(&new_end_pos, &end_pos))) {
set_range_pos(This, TRUE, &new_pos); if(find_prev_space(This, &start_pos, TRUE, &new_start_pos)) {
*Success = VARIANT_TRUE; set_range_pos(This, TRUE, &new_start_pos);
*Success = VARIANT_TRUE;
}
dompos_release(&new_start_pos);
} }
dompos_release(&new_pos); dompos_release(&new_end_pos);
dompos_release(&end_pos); dompos_release(&end_pos);
dompos_release(&start_pos);
break; break;
} }
...@@ -1268,11 +1330,9 @@ static HRESULT WINAPI HTMLTxtRange_move(IHTMLTxtRange *iface, BSTR Unit, ...@@ -1268,11 +1330,9 @@ static HRESULT WINAPI HTMLTxtRange_move(IHTMLTxtRange *iface, BSTR Unit,
if(unit == RU_UNKNOWN) if(unit == RU_UNKNOWN)
return E_INVALIDARG; return E_INVALIDARG;
IHTMLTxtRange_collapse(HTMLTXTRANGE(This), TRUE);
if(!Count) { if(!Count) {
*ActualCount = 0; *ActualCount = 0;
return S_OK; return IHTMLTxtRange_collapse(HTMLTXTRANGE(This), TRUE);
} }
switch(unit) { switch(unit) {
...@@ -1284,8 +1344,9 @@ static HRESULT WINAPI HTMLTxtRange_move(IHTMLTxtRange *iface, BSTR Unit, ...@@ -1284,8 +1344,9 @@ static HRESULT WINAPI HTMLTxtRange_move(IHTMLTxtRange *iface, BSTR Unit,
if(Count > 0) { if(Count > 0) {
*ActualCount = move_next_chars(Count, &cur_pos, TRUE, NULL, NULL, &new_pos); *ActualCount = move_next_chars(Count, &cur_pos, TRUE, NULL, NULL, &new_pos);
set_range_pos(This, FALSE, &new_pos); set_range_pos(This, FALSE, &new_pos);
IHTMLTxtRange_collapse(HTMLTXTRANGE(This), FALSE);
dompos_release(&new_pos); dompos_release(&new_pos);
IHTMLTxtRange_collapse(HTMLTXTRANGE(This), FALSE);
}else { }else {
*ActualCount = -move_prev_chars(This, -Count, &cur_pos, FALSE, NULL, NULL, &new_pos); *ActualCount = -move_prev_chars(This, -Count, &cur_pos, FALSE, NULL, NULL, &new_pos);
set_range_pos(This, TRUE, &new_pos); set_range_pos(This, TRUE, &new_pos);
...@@ -1305,8 +1366,8 @@ static HRESULT WINAPI HTMLTxtRange_move(IHTMLTxtRange *iface, BSTR Unit, ...@@ -1305,8 +1366,8 @@ static HRESULT WINAPI HTMLTxtRange_move(IHTMLTxtRange *iface, BSTR Unit,
if(Count > 0) { if(Count > 0) {
*ActualCount = move_next_words(Count, &cur_pos, &new_pos); *ActualCount = move_next_words(Count, &cur_pos, &new_pos);
set_range_pos(This, FALSE, &new_pos); set_range_pos(This, FALSE, &new_pos);
IHTMLTxtRange_collapse(HTMLTXTRANGE(This), FALSE);
dompos_release(&new_pos); dompos_release(&new_pos);
IHTMLTxtRange_collapse(HTMLTXTRANGE(This), FALSE);
}else { }else {
*ActualCount = -move_prev_words(This, -Count, &cur_pos, &new_pos); *ActualCount = -move_prev_words(This, -Count, &cur_pos, &new_pos);
set_range_pos(This, TRUE, &new_pos); set_range_pos(This, TRUE, &new_pos);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment