2 * Copyright 2006-2007 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/debug.h"
30 #include "wine/unicode.h"
32 #include "mshtml_private.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
36 static const WCHAR brW
[] = {'b','r',0};
37 static const WCHAR hrW
[] = {'h','r',0};
40 const IHTMLTxtRangeVtbl
*lpHTMLTxtRangeVtbl
;
41 const IOleCommandTargetVtbl
*lpOleCommandTargetVtbl
;
46 HTMLDocumentNode
*doc
;
51 #define HTMLTXTRANGE(x) ((IHTMLTxtRange*) &(x)->lpHTMLTxtRangeVtbl)
75 static HTMLTxtRange
*get_range_object(HTMLDocumentNode
*doc
, IHTMLTxtRange
*iface
)
79 LIST_FOR_EACH_ENTRY(iter
, &doc
->range_list
, HTMLTxtRange
, entry
) {
80 if(HTMLTXTRANGE(iter
) == iface
)
84 ERR("Could not find range in document\n");
88 static range_unit_t
string_to_unit(LPCWSTR str
)
90 static const WCHAR characterW
[] =
91 {'c','h','a','r','a','c','t','e','r',0};
92 static const WCHAR wordW
[] =
94 static const WCHAR sentenceW
[] =
95 {'s','e','n','t','e','n','c','e',0};
96 static const WCHAR texteditW
[] =
97 {'t','e','x','t','e','d','i','t',0};
99 if(!strcmpiW(str
, characterW
)) return RU_CHAR
;
100 if(!strcmpiW(str
, wordW
)) return RU_WORD
;
101 if(!strcmpiW(str
, sentenceW
)) return RU_SENTENCE
;
102 if(!strcmpiW(str
, texteditW
)) return RU_TEXTEDIT
;
107 static int string_to_nscmptype(LPCWSTR str
)
109 static const WCHAR seW
[] = {'S','t','a','r','t','T','o','E','n','d',0};
110 static const WCHAR ssW
[] = {'S','t','a','r','t','T','o','S','t','a','r','t',0};
111 static const WCHAR esW
[] = {'E','n','d','T','o','S','t','a','r','t',0};
112 static const WCHAR eeW
[] = {'E','n','d','T','o','E','n','d',0};
114 if(!strcmpiW(str
, seW
)) return NS_START_TO_END
;
115 if(!strcmpiW(str
, ssW
)) return NS_START_TO_START
;
116 if(!strcmpiW(str
, esW
)) return NS_END_TO_START
;
117 if(!strcmpiW(str
, eeW
)) return NS_END_TO_END
;
122 static PRUint16
get_node_type(nsIDOMNode
*node
)
127 nsIDOMNode_GetNodeType(node
, &type
);
132 static BOOL
is_elem_tag(nsIDOMNode
*node
, LPCWSTR istag
)
136 const PRUnichar
*tag
;
140 nsres
= nsIDOMNode_QueryInterface(node
, &IID_nsIDOMElement
, (void**)&elem
);
144 nsAString_Init(&tag_str
, NULL
);
145 nsIDOMElement_GetTagName(elem
, &tag_str
);
146 nsIDOMElement_Release(elem
);
147 nsAString_GetData(&tag_str
, &tag
);
149 ret
= !strcmpiW(tag
, istag
);
151 nsAString_Finish(&tag_str
);
156 static BOOL
is_space_elem(nsIDOMNode
*node
)
160 const PRUnichar
*tag
;
164 nsres
= nsIDOMNode_QueryInterface(node
, &IID_nsIDOMElement
, (void**)&elem
);
168 nsAString_Init(&tag_str
, NULL
);
169 nsIDOMElement_GetTagName(elem
, &tag_str
);
170 nsIDOMElement_Release(elem
);
171 nsAString_GetData(&tag_str
, &tag
);
173 ret
= !strcmpiW(tag
, brW
) || !strcmpiW(tag
, hrW
);
175 nsAString_Finish(&tag_str
);
180 static inline BOOL
wstrbuf_init(wstrbuf_t
*buf
)
184 buf
->buf
= heap_alloc(buf
->size
* sizeof(WCHAR
));
185 if (!buf
->buf
) return FALSE
;
190 static inline void wstrbuf_finish(wstrbuf_t
*buf
)
195 static void wstrbuf_append_len(wstrbuf_t
*buf
, LPCWSTR str
, int len
)
197 if(buf
->len
+len
>= buf
->size
) {
198 buf
->size
= 2*buf
->size
+len
;
199 buf
->buf
= heap_realloc(buf
->buf
, buf
->size
* sizeof(WCHAR
));
202 memcpy(buf
->buf
+buf
->len
, str
, len
*sizeof(WCHAR
));
204 buf
->buf
[buf
->len
] = 0;
207 static void wstrbuf_append_nodetxt(wstrbuf_t
*buf
, LPCWSTR str
, int len
)
209 const WCHAR
*s
= str
;
212 TRACE("%s\n", debugstr_wn(str
, len
));
214 if(buf
->len
+len
>= buf
->size
) {
215 buf
->size
= 2*buf
->size
+len
;
216 buf
->buf
= heap_realloc(buf
->buf
, buf
->size
* sizeof(WCHAR
));
219 if(buf
->len
&& isspaceW(buf
->buf
[buf
->len
-1])) {
220 while(s
< str
+len
&& isspaceW(*s
))
224 d
= buf
->buf
+buf
->len
;
229 while(s
< str
+len
&& isspaceW(*s
))
236 buf
->len
= d
- buf
->buf
;
240 static void wstrbuf_append_node(wstrbuf_t
*buf
, nsIDOMNode
*node
)
243 switch(get_node_type(node
)) {
247 const PRUnichar
*data
;
249 nsIDOMNode_QueryInterface(node
, &IID_nsIDOMText
, (void**)&nstext
);
251 nsAString_Init(&data_str
, NULL
);
252 nsIDOMText_GetData(nstext
, &data_str
);
253 nsAString_GetData(&data_str
, &data
);
254 wstrbuf_append_nodetxt(buf
, data
, strlenW(data
));
255 nsAString_Finish(&data_str
);
257 nsIDOMText_Release(nstext
);
262 if(is_elem_tag(node
, brW
)) {
263 static const WCHAR endlW
[] = {'\r','\n'};
264 wstrbuf_append_len(buf
, endlW
, 2);
265 }else if(is_elem_tag(node
, hrW
)) {
266 static const WCHAR endl2W
[] = {'\r','\n','\r','\n'};
267 wstrbuf_append_len(buf
, endl2W
, 4);
272 static void wstrbuf_append_node_rec(wstrbuf_t
*buf
, nsIDOMNode
*node
)
274 nsIDOMNode
*iter
, *tmp
;
276 wstrbuf_append_node(buf
, node
);
278 nsIDOMNode_GetFirstChild(node
, &iter
);
280 wstrbuf_append_node_rec(buf
, iter
);
281 nsIDOMNode_GetNextSibling(iter
, &tmp
);
282 nsIDOMNode_Release(iter
);
287 static BOOL
fill_nodestr(dompos_t
*pos
)
292 if(pos
->type
!= TEXT_NODE
)
295 nsres
= nsIDOMNode_QueryInterface(pos
->node
, &IID_nsIDOMText
, (void**)&text
);
299 nsAString_Init(&pos
->str
, NULL
);
300 nsIDOMText_GetData(text
, &pos
->str
);
301 nsIDOMText_Release(text
);
302 nsAString_GetData(&pos
->str
, &pos
->p
);
305 pos
->off
= *pos
->p
? strlenW(pos
->p
)-1 : 0;
310 static nsIDOMNode
*next_node(nsIDOMNode
*iter
)
312 nsIDOMNode
*ret
, *tmp
;
318 nsres
= nsIDOMNode_GetFirstChild(iter
, &ret
);
319 if(NS_SUCCEEDED(nsres
) && ret
)
322 nsIDOMNode_AddRef(iter
);
325 nsres
= nsIDOMNode_GetNextSibling(iter
, &ret
);
326 if(NS_SUCCEEDED(nsres
) && ret
) {
327 nsIDOMNode_Release(iter
);
331 nsres
= nsIDOMNode_GetParentNode(iter
, &tmp
);
332 nsIDOMNode_Release(iter
);
334 }while(NS_SUCCEEDED(nsres
) && iter
);
339 static nsIDOMNode
*prev_node(HTMLTxtRange
*This
, nsIDOMNode
*iter
)
341 nsIDOMNode
*ret
, *tmp
;
345 nsIDOMHTMLElement
*nselem
;
347 nsIDOMHTMLDocument_GetBody(This
->doc
->nsdoc
, &nselem
);
348 nsIDOMElement_GetLastChild(nselem
, &tmp
);
350 return (nsIDOMNode
*)nselem
;
354 nsIDOMNode_GetLastChild(ret
, &tmp
);
357 nsIDOMElement_Release(nselem
);
362 nsres
= nsIDOMNode_GetLastChild(iter
, &ret
);
363 if(NS_SUCCEEDED(nsres
) && ret
)
366 nsIDOMNode_AddRef(iter
);
369 nsres
= nsIDOMNode_GetPreviousSibling(iter
, &ret
);
370 if(NS_SUCCEEDED(nsres
) && ret
) {
371 nsIDOMNode_Release(iter
);
375 nsres
= nsIDOMNode_GetParentNode(iter
, &tmp
);
376 nsIDOMNode_Release(iter
);
378 }while(NS_SUCCEEDED(nsres
) && iter
);
383 static nsIDOMNode
*get_child_node(nsIDOMNode
*node
, PRUint32 off
)
385 nsIDOMNodeList
*node_list
;
386 nsIDOMNode
*ret
= NULL
;
388 nsIDOMNode_GetChildNodes(node
, &node_list
);
389 nsIDOMNodeList_Item(node_list
, off
, &ret
);
390 nsIDOMNodeList_Release(node_list
);
395 static void get_cur_pos(HTMLTxtRange
*This
, BOOL start
, dompos_t
*pos
)
404 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
409 nsIDOMRange_GetStartContainer(This
->nsrange
, &node
);
410 nsIDOMRange_GetStartOffset(This
->nsrange
, &off
);
412 nsIDOMRange_GetEndContainer(This
->nsrange
, &node
);
413 nsIDOMRange_GetEndOffset(This
->nsrange
, &off
);
416 pos
->type
= get_node_type(node
);
417 if(pos
->type
== ELEMENT_NODE
) {
419 pos
->node
= get_child_node(node
, off
);
422 pos
->node
= off
? get_child_node(node
, off
-1) : prev_node(This
, node
);
426 pos
->type
= get_node_type(pos
->node
);
427 nsIDOMNode_Release(node
);
435 pos
->node
= prev_node(This
, node
);
437 nsIDOMNode_Release(node
);
440 if(pos
->type
== TEXT_NODE
)
444 static void set_range_pos(HTMLTxtRange
*This
, BOOL start
, dompos_t
*pos
)
449 if(pos
->type
== TEXT_NODE
)
450 nsres
= nsIDOMRange_SetStart(This
->nsrange
, pos
->node
, pos
->off
);
452 nsres
= nsIDOMRange_SetStartBefore(This
->nsrange
, pos
->node
);
454 if(pos
->type
== TEXT_NODE
&& pos
->p
[pos
->off
+1])
455 nsres
= nsIDOMRange_SetEnd(This
->nsrange
, pos
->node
, pos
->off
+1);
457 nsres
= nsIDOMRange_SetEndAfter(This
->nsrange
, pos
->node
);
461 ERR("failed: %p %08x\n", pos
->node
, nsres
);
464 static inline void dompos_release(dompos_t
*pos
)
467 nsIDOMNode_Release(pos
->node
);
470 nsAString_Finish(&pos
->str
);
473 static inline void dompos_addref(dompos_t
*pos
)
476 nsIDOMNode_AddRef(pos
->node
);
478 if(pos
->type
== TEXT_NODE
)
482 static inline BOOL
dompos_cmp(const dompos_t
*pos1
, const dompos_t
*pos2
)
484 return pos1
->node
== pos2
->node
&& pos1
->off
== pos2
->off
;
487 static void range_to_string(HTMLTxtRange
*This
, wstrbuf_t
*buf
)
489 nsIDOMNode
*iter
, *tmp
;
490 dompos_t start_pos
, end_pos
;
493 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
501 get_cur_pos(This
, FALSE
, &end_pos
);
502 get_cur_pos(This
, TRUE
, &start_pos
);
504 if(start_pos
.type
== TEXT_NODE
) {
505 if(start_pos
.node
== end_pos
.node
) {
506 wstrbuf_append_nodetxt(buf
, start_pos
.p
+start_pos
.off
, end_pos
.off
-start_pos
.off
+1);
507 iter
= start_pos
.node
;
508 nsIDOMNode_AddRef(iter
);
510 wstrbuf_append_nodetxt(buf
, start_pos
.p
+start_pos
.off
, strlenW(start_pos
.p
+start_pos
.off
));
511 iter
= next_node(start_pos
.node
);
514 iter
= start_pos
.node
;
515 nsIDOMNode_AddRef(iter
);
518 while(iter
!= end_pos
.node
) {
519 wstrbuf_append_node(buf
, iter
);
520 tmp
= next_node(iter
);
521 nsIDOMNode_Release(iter
);
525 nsIDOMNode_AddRef(end_pos
.node
);
527 if(start_pos
.node
!= end_pos
.node
) {
528 if(end_pos
.type
== TEXT_NODE
)
529 wstrbuf_append_nodetxt(buf
, end_pos
.p
, end_pos
.off
+1);
531 wstrbuf_append_node(buf
, end_pos
.node
);
534 nsIDOMNode_Release(iter
);
535 dompos_release(&start_pos
);
536 dompos_release(&end_pos
);
541 for(p
= buf
->buf
+buf
->len
-1; p
>= buf
->buf
&& isspaceW(*p
); p
--);
543 p
= strchrW(p
, '\r');
549 HRESULT
get_node_text(HTMLDOMNode
*node
, BSTR
*ret
)
554 if (!wstrbuf_init(&buf
))
555 return E_OUTOFMEMORY
;
556 wstrbuf_append_node_rec(&buf
, node
->nsnode
);
558 *ret
= SysAllocString(buf
.buf
);
560 hres
= E_OUTOFMEMORY
;
564 wstrbuf_finish(&buf
);
567 TRACE("ret %s\n", debugstr_w(*ret
));
571 static WCHAR
get_pos_char(const dompos_t
*pos
)
575 return pos
->p
[pos
->off
];
577 if(is_space_elem(pos
->node
))
584 static void end_space(const dompos_t
*pos
, dompos_t
*new_pos
)
589 dompos_addref(new_pos
);
591 if(pos
->type
!= TEXT_NODE
)
594 p
= new_pos
->p
+new_pos
->off
;
596 if(!*p
|| !isspace(*p
))
599 while(p
[1] && isspace(p
[1]))
602 new_pos
->off
= p
- new_pos
->p
;
605 static WCHAR
next_char(const dompos_t
*pos
, dompos_t
*new_pos
)
607 nsIDOMNode
*iter
, *tmp
;
608 dompos_t last_space
, tmp_pos
;
612 if(pos
->type
== TEXT_NODE
&& pos
->off
!= -1 && pos
->p
[pos
->off
]) {
616 while(isspaceW(*++p
));
620 if(*p
&& isspaceW(*p
)) {
622 while(p
[1] && isspaceW(p
[1]))
628 new_pos
->off
= p
- pos
->p
;
629 dompos_addref(new_pos
);
631 return cspace
? cspace
: *p
;
634 last_space
.off
= p
- pos
->p
;
635 dompos_addref(&last_space
);
639 iter
= next_node(pos
->node
);
642 switch(get_node_type(iter
)) {
645 tmp_pos
.type
= TEXT_NODE
;
647 dompos_addref(&tmp_pos
);
652 dompos_release(&tmp_pos
);
654 }else if(isspaceW(*p
)) {
656 dompos_release(&last_space
);
660 while(p
[1] && isspaceW(p
[1]))
663 tmp_pos
.off
= p
-tmp_pos
.p
;
666 last_space
= tmp_pos
;
671 nsIDOMNode_Release(iter
);
674 *new_pos
= last_space
;
675 dompos_release(&tmp_pos
);
676 nsIDOMNode_Release(iter
);
684 nsIDOMNode_Release(iter
);
688 if(is_elem_tag(iter
, brW
)) {
690 dompos_release(&last_space
);
693 nsIDOMNode_AddRef(iter
);
694 last_space
.node
= iter
;
695 last_space
.type
= ELEMENT_NODE
;
698 }else if(is_elem_tag(iter
, hrW
)) {
700 *new_pos
= last_space
;
701 nsIDOMNode_Release(iter
);
705 new_pos
->node
= iter
;
706 new_pos
->type
= ELEMENT_NODE
;
714 iter
= next_node(iter
);
715 nsIDOMNode_Release(tmp
);
719 *new_pos
= last_space
;
722 dompos_addref(new_pos
);
728 static WCHAR
prev_char(HTMLTxtRange
*This
, const dompos_t
*pos
, dompos_t
*new_pos
)
730 nsIDOMNode
*iter
, *tmp
;
732 BOOL skip_space
= FALSE
;
734 if(pos
->type
== TEXT_NODE
&& isspaceW(pos
->p
[pos
->off
]))
737 if(pos
->type
== TEXT_NODE
&& pos
->off
) {
738 p
= pos
->p
+pos
->off
-1;
741 while(p
>= pos
->p
&& isspace(*p
))
747 new_pos
->off
= p
-pos
->p
;
748 dompos_addref(new_pos
);
749 return new_pos
->p
[new_pos
->off
];
753 iter
= prev_node(This
, pos
->node
);
756 switch(get_node_type(iter
)) {
761 tmp_pos
.type
= TEXT_NODE
;
763 dompos_addref(&tmp_pos
);
765 p
= tmp_pos
.p
+ strlenW(tmp_pos
.p
)-1;
768 while(p
>= tmp_pos
.p
&& isspaceW(*p
))
773 dompos_release(&tmp_pos
);
777 tmp_pos
.off
= p
-tmp_pos
.p
;
779 nsIDOMNode_Release(iter
);
784 if(is_elem_tag(iter
, brW
)) {
789 }else if(!is_elem_tag(iter
, hrW
)) {
793 new_pos
->node
= iter
;
794 new_pos
->type
= ELEMENT_NODE
;
801 iter
= prev_node(This
, iter
);
802 nsIDOMNode_Release(tmp
);
806 dompos_addref(new_pos
);
810 static LONG
move_next_chars(LONG cnt
, const dompos_t
*pos
, BOOL col
, const dompos_t
*bound_pos
,
811 BOOL
*bounded
, dompos_t
*new_pos
)
824 end_space(pos
, new_pos
);
828 c
= next_char(pos
, &iter
);
833 c
= next_char(&tmp
, &iter
);
834 dompos_release(&tmp
);
839 if(bound_pos
&& dompos_cmp(&tmp
, bound_pos
)) {
849 static LONG
move_prev_chars(HTMLTxtRange
*This
, LONG cnt
, const dompos_t
*pos
, BOOL end
,
850 const dompos_t
*bound_pos
, BOOL
*bounded
, dompos_t
*new_pos
)
854 BOOL prev_eq
= FALSE
;
860 c
= prev_char(This
, pos
, &iter
);
864 while(c
&& ret
< cnt
) {
866 c
= prev_char(This
, &tmp
, &iter
);
867 dompos_release(&tmp
);
881 prev_eq
= bound_pos
&& dompos_cmp(&iter
, bound_pos
);
888 static LONG
find_prev_space(HTMLTxtRange
*This
, const dompos_t
*pos
, BOOL first_space
, dompos_t
*ret
)
893 c
= prev_char(This
, pos
, &iter
);
894 if(!c
|| (first_space
&& isspaceW(c
))) {
901 c
= prev_char(This
, &tmp
, &iter
);
902 if(!c
|| isspaceW(c
)) {
903 dompos_release(&iter
);
906 dompos_release(&tmp
);
913 static int find_word_end(const dompos_t
*pos
, dompos_t
*ret
)
918 c
= get_pos_char(pos
);
925 c
= next_char(pos
, &iter
);
936 while(c
&& !isspaceW(c
)) {
938 c
= next_char(&tmp
, &iter
);
940 dompos_release(&iter
);
944 dompos_release(&tmp
);
952 static LONG
move_next_words(LONG cnt
, const dompos_t
*pos
, dompos_t
*new_pos
)
958 c
= get_pos_char(pos
);
960 end_space(pos
, &iter
);
963 c
= next_char(pos
, &iter
);
968 while(c
&& ret
< cnt
) {
970 c
= next_char(&tmp
, &iter
);
971 dompos_release(&tmp
);
980 static LONG
move_prev_words(HTMLTxtRange
*This
, LONG cnt
, const dompos_t
*pos
, dompos_t
*new_pos
)
986 dompos_addref(&iter
);
989 if(!find_prev_space(This
, &iter
, FALSE
, &tmp
))
992 dompos_release(&iter
);
1001 #define HTMLTXTRANGE_THIS(iface) DEFINE_THIS(HTMLTxtRange, HTMLTxtRange, iface)
1003 static HRESULT WINAPI
HTMLTxtRange_QueryInterface(IHTMLTxtRange
*iface
, REFIID riid
, void **ppv
)
1005 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1009 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
1010 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
1011 *ppv
= HTMLTXTRANGE(This
);
1012 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
1013 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
1014 *ppv
= HTMLTXTRANGE(This
);
1015 }else if(IsEqualGUID(&IID_IHTMLTxtRange
, riid
)) {
1016 TRACE("(%p)->(IID_IHTMLTxtRange %p)\n", This
, ppv
);
1017 *ppv
= HTMLTXTRANGE(This
);
1018 }else if(IsEqualGUID(&IID_IOleCommandTarget
, riid
)) {
1019 TRACE("(%p)->(IID_IOleCommandTarget %p)\n", This
, ppv
);
1020 *ppv
= CMDTARGET(This
);
1024 IUnknown_AddRef((IUnknown
*)*ppv
);
1028 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
1029 return E_NOINTERFACE
;
1032 static ULONG WINAPI
HTMLTxtRange_AddRef(IHTMLTxtRange
*iface
)
1034 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1035 LONG ref
= InterlockedIncrement(&This
->ref
);
1037 TRACE("(%p) ref=%d\n", This
, ref
);
1042 static ULONG WINAPI
HTMLTxtRange_Release(IHTMLTxtRange
*iface
)
1044 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1045 LONG ref
= InterlockedDecrement(&This
->ref
);
1047 TRACE("(%p) ref=%d\n", This
, ref
);
1051 nsISelection_Release(This
->nsrange
);
1053 list_remove(&This
->entry
);
1060 static HRESULT WINAPI
HTMLTxtRange_GetTypeInfoCount(IHTMLTxtRange
*iface
, UINT
*pctinfo
)
1062 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1063 FIXME("(%p)->(%p)\n", This
, pctinfo
);
1067 static HRESULT WINAPI
HTMLTxtRange_GetTypeInfo(IHTMLTxtRange
*iface
, UINT iTInfo
,
1068 LCID lcid
, ITypeInfo
**ppTInfo
)
1070 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1071 FIXME("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1075 static HRESULT WINAPI
HTMLTxtRange_GetIDsOfNames(IHTMLTxtRange
*iface
, REFIID riid
,
1076 LPOLESTR
*rgszNames
, UINT cNames
,
1077 LCID lcid
, DISPID
*rgDispId
)
1079 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1080 FIXME("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
1085 static HRESULT WINAPI
HTMLTxtRange_Invoke(IHTMLTxtRange
*iface
, DISPID dispIdMember
,
1086 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
1087 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1089 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1090 FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1091 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1095 static HRESULT WINAPI
HTMLTxtRange_get_htmlText(IHTMLTxtRange
*iface
, BSTR
*p
)
1097 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1099 TRACE("(%p)->(%p)\n", This
, p
);
1104 nsIDOMDocumentFragment
*fragment
;
1107 nsres
= nsIDOMRange_CloneContents(This
->nsrange
, &fragment
);
1108 if(NS_SUCCEEDED(nsres
)) {
1109 const PRUnichar
*nstext
;
1112 nsAString_Init(&nsstr
, NULL
);
1113 nsnode_to_nsstring((nsIDOMNode
*)fragment
, &nsstr
);
1114 nsIDOMDocumentFragment_Release(fragment
);
1116 nsAString_GetData(&nsstr
, &nstext
);
1117 *p
= SysAllocString(nstext
);
1119 nsAString_Finish(&nsstr
);
1124 const WCHAR emptyW
[] = {0};
1125 *p
= SysAllocString(emptyW
);
1128 TRACE("return %s\n", debugstr_w(*p
));
1132 static HRESULT WINAPI
HTMLTxtRange_put_text(IHTMLTxtRange
*iface
, BSTR v
)
1134 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1135 nsIDOMText
*text_node
;
1139 TRACE("(%p)->(%s)\n", This
, debugstr_w(v
));
1142 return MSHTML_E_NODOC
;
1144 nsAString_InitDepend(&text_str
, v
);
1145 nsres
= nsIDOMHTMLDocument_CreateTextNode(This
->doc
->nsdoc
, &text_str
, &text_node
);
1146 nsAString_Finish(&text_str
);
1147 if(NS_FAILED(nsres
)) {
1148 ERR("CreateTextNode failed: %08x\n", nsres
);
1151 nsres
= nsIDOMRange_DeleteContents(This
->nsrange
);
1152 if(NS_FAILED(nsres
))
1153 ERR("DeleteContents failed: %08x\n", nsres
);
1155 nsres
= nsIDOMRange_InsertNode(This
->nsrange
, (nsIDOMNode
*)text_node
);
1156 if(NS_FAILED(nsres
))
1157 ERR("InsertNode failed: %08x\n", nsres
);
1159 nsres
= nsIDOMRange_SetEndAfter(This
->nsrange
, (nsIDOMNode
*)text_node
);
1160 if(NS_FAILED(nsres
))
1161 ERR("SetEndAfter failed: %08x\n", nsres
);
1163 return IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), VARIANT_FALSE
);
1166 static HRESULT WINAPI
HTMLTxtRange_get_text(IHTMLTxtRange
*iface
, BSTR
*p
)
1168 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1171 TRACE("(%p)->(%p)\n", This
, p
);
1177 if (!wstrbuf_init(&buf
))
1178 return E_OUTOFMEMORY
;
1179 range_to_string(This
, &buf
);
1181 *p
= SysAllocString(buf
.buf
);
1182 wstrbuf_finish(&buf
);
1184 TRACE("ret %s\n", debugstr_w(*p
));
1188 static HRESULT WINAPI
HTMLTxtRange_parentElement(IHTMLTxtRange
*iface
, IHTMLElement
**parent
)
1190 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1191 nsIDOMNode
*nsnode
, *tmp
;
1194 TRACE("(%p)->(%p)\n", This
, parent
);
1196 nsIDOMRange_GetCommonAncestorContainer(This
->nsrange
, &nsnode
);
1197 while(nsnode
&& get_node_type(nsnode
) != ELEMENT_NODE
) {
1198 nsIDOMNode_GetParentNode(nsnode
, &tmp
);
1199 nsIDOMNode_Release(nsnode
);
1208 node
= get_node(This
->doc
, nsnode
, TRUE
);
1209 nsIDOMNode_Release(nsnode
);
1211 return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(node
), &IID_IHTMLElement
, (void**)parent
);
1214 static HRESULT WINAPI
HTMLTxtRange_duplicate(IHTMLTxtRange
*iface
, IHTMLTxtRange
**Duplicate
)
1216 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1217 nsIDOMRange
*nsrange
= NULL
;
1220 TRACE("(%p)->(%p)\n", This
, Duplicate
);
1222 nsIDOMRange_CloneRange(This
->nsrange
, &nsrange
);
1223 hres
= HTMLTxtRange_Create(This
->doc
, nsrange
, Duplicate
);
1224 nsIDOMRange_Release(nsrange
);
1229 static HRESULT WINAPI
HTMLTxtRange_inRange(IHTMLTxtRange
*iface
, IHTMLTxtRange
*Range
,
1230 VARIANT_BOOL
*InRange
)
1232 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1233 HTMLTxtRange
*src_range
;
1237 TRACE("(%p)->(%p %p)\n", This
, Range
, InRange
);
1239 *InRange
= VARIANT_FALSE
;
1241 src_range
= get_range_object(This
->doc
, Range
);
1245 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_START_TO_START
,
1246 src_range
->nsrange
, &nsret
);
1247 if(NS_SUCCEEDED(nsres
) && nsret
<= 0) {
1248 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_END_TO_END
,
1249 src_range
->nsrange
, &nsret
);
1250 if(NS_SUCCEEDED(nsres
) && nsret
>= 0)
1251 *InRange
= VARIANT_TRUE
;
1254 if(NS_FAILED(nsres
))
1255 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
1260 static HRESULT WINAPI
HTMLTxtRange_isEqual(IHTMLTxtRange
*iface
, IHTMLTxtRange
*Range
,
1261 VARIANT_BOOL
*IsEqual
)
1263 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1264 HTMLTxtRange
*src_range
;
1268 TRACE("(%p)->(%p %p)\n", This
, Range
, IsEqual
);
1270 *IsEqual
= VARIANT_FALSE
;
1272 src_range
= get_range_object(This
->doc
, Range
);
1276 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_START_TO_START
,
1277 src_range
->nsrange
, &nsret
);
1278 if(NS_SUCCEEDED(nsres
) && !nsret
) {
1279 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_END_TO_END
,
1280 src_range
->nsrange
, &nsret
);
1281 if(NS_SUCCEEDED(nsres
) && !nsret
)
1282 *IsEqual
= VARIANT_TRUE
;
1285 if(NS_FAILED(nsres
))
1286 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
1291 static HRESULT WINAPI
HTMLTxtRange_scrollIntoView(IHTMLTxtRange
*iface
, VARIANT_BOOL fStart
)
1293 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1294 FIXME("(%p)->(%x)\n", This
, fStart
);
1298 static HRESULT WINAPI
HTMLTxtRange_collapse(IHTMLTxtRange
*iface
, VARIANT_BOOL Start
)
1300 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1302 TRACE("(%p)->(%x)\n", This
, Start
);
1304 nsIDOMRange_Collapse(This
->nsrange
, Start
!= VARIANT_FALSE
);
1308 static HRESULT WINAPI
HTMLTxtRange_expand(IHTMLTxtRange
*iface
, BSTR Unit
, VARIANT_BOOL
*Success
)
1310 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1313 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(Unit
), Success
);
1315 unit
= string_to_unit(Unit
);
1316 if(unit
== RU_UNKNOWN
)
1317 return E_INVALIDARG
;
1319 *Success
= VARIANT_FALSE
;
1323 dompos_t end_pos
, start_pos
, new_start_pos
, new_end_pos
;
1326 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
1328 get_cur_pos(This
, TRUE
, &start_pos
);
1329 get_cur_pos(This
, FALSE
, &end_pos
);
1331 if(find_word_end(&end_pos
, &new_end_pos
) || collapsed
) {
1332 set_range_pos(This
, FALSE
, &new_end_pos
);
1333 *Success
= VARIANT_TRUE
;
1336 if(start_pos
.type
&& (get_pos_char(&end_pos
) || !dompos_cmp(&new_end_pos
, &end_pos
))) {
1337 if(find_prev_space(This
, &start_pos
, TRUE
, &new_start_pos
)) {
1338 set_range_pos(This
, TRUE
, &new_start_pos
);
1339 *Success
= VARIANT_TRUE
;
1341 dompos_release(&new_start_pos
);
1344 dompos_release(&new_end_pos
);
1345 dompos_release(&end_pos
);
1346 dompos_release(&start_pos
);
1352 nsIDOMHTMLElement
*nsbody
= NULL
;
1355 nsres
= nsIDOMHTMLDocument_GetBody(This
->doc
->nsdoc
, &nsbody
);
1356 if(NS_FAILED(nsres
) || !nsbody
) {
1357 ERR("Could not get body: %08x\n", nsres
);
1361 nsres
= nsIDOMRange_SelectNodeContents(This
->nsrange
, (nsIDOMNode
*)nsbody
);
1362 nsIDOMHTMLElement_Release(nsbody
);
1363 if(NS_FAILED(nsres
)) {
1364 ERR("Collapse failed: %08x\n", nsres
);
1368 *Success
= VARIANT_TRUE
;
1373 FIXME("Unimplemented unit %s\n", debugstr_w(Unit
));
1379 static HRESULT WINAPI
HTMLTxtRange_move(IHTMLTxtRange
*iface
, BSTR Unit
,
1380 LONG Count
, LONG
*ActualCount
)
1382 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1385 TRACE("(%p)->(%s %d %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1387 unit
= string_to_unit(Unit
);
1388 if(unit
== RU_UNKNOWN
)
1389 return E_INVALIDARG
;
1393 return IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1398 dompos_t cur_pos
, new_pos
;
1400 get_cur_pos(This
, TRUE
, &cur_pos
);
1403 *ActualCount
= move_next_chars(Count
, &cur_pos
, TRUE
, NULL
, NULL
, &new_pos
);
1404 set_range_pos(This
, FALSE
, &new_pos
);
1405 dompos_release(&new_pos
);
1407 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), FALSE
);
1409 *ActualCount
= -move_prev_chars(This
, -Count
, &cur_pos
, FALSE
, NULL
, NULL
, &new_pos
);
1410 set_range_pos(This
, TRUE
, &new_pos
);
1411 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1412 dompos_release(&new_pos
);
1415 dompos_release(&cur_pos
);
1420 dompos_t cur_pos
, new_pos
;
1422 get_cur_pos(This
, TRUE
, &cur_pos
);
1425 *ActualCount
= move_next_words(Count
, &cur_pos
, &new_pos
);
1426 set_range_pos(This
, FALSE
, &new_pos
);
1427 dompos_release(&new_pos
);
1428 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), FALSE
);
1430 *ActualCount
= -move_prev_words(This
, -Count
, &cur_pos
, &new_pos
);
1431 set_range_pos(This
, TRUE
, &new_pos
);
1432 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1433 dompos_release(&new_pos
);
1436 dompos_release(&cur_pos
);
1441 FIXME("unimplemented unit %s\n", debugstr_w(Unit
));
1444 TRACE("ret %d\n", *ActualCount
);
1448 static HRESULT WINAPI
HTMLTxtRange_moveStart(IHTMLTxtRange
*iface
, BSTR Unit
,
1449 LONG Count
, LONG
*ActualCount
)
1451 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1454 TRACE("(%p)->(%s %d %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1456 unit
= string_to_unit(Unit
);
1457 if(unit
== RU_UNKNOWN
)
1458 return E_INVALIDARG
;
1467 dompos_t start_pos
, end_pos
, new_pos
;
1470 get_cur_pos(This
, TRUE
, &start_pos
);
1471 get_cur_pos(This
, FALSE
, &end_pos
);
1472 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
1477 *ActualCount
= move_next_chars(Count
, &start_pos
, collapsed
, &end_pos
, &bounded
, &new_pos
);
1478 set_range_pos(This
, !bounded
, &new_pos
);
1480 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), FALSE
);
1482 *ActualCount
= -move_prev_chars(This
, -Count
, &start_pos
, FALSE
, NULL
, NULL
, &new_pos
);
1483 set_range_pos(This
, TRUE
, &new_pos
);
1486 dompos_release(&start_pos
);
1487 dompos_release(&end_pos
);
1488 dompos_release(&new_pos
);
1493 FIXME("unimplemented unit %s\n", debugstr_w(Unit
));
1499 static HRESULT WINAPI
HTMLTxtRange_moveEnd(IHTMLTxtRange
*iface
, BSTR Unit
,
1500 LONG Count
, LONG
*ActualCount
)
1502 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1505 TRACE("(%p)->(%s %d %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1507 unit
= string_to_unit(Unit
);
1508 if(unit
== RU_UNKNOWN
)
1509 return E_INVALIDARG
;
1518 dompos_t start_pos
, end_pos
, new_pos
;
1521 get_cur_pos(This
, TRUE
, &start_pos
);
1522 get_cur_pos(This
, FALSE
, &end_pos
);
1523 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
1526 *ActualCount
= move_next_chars(Count
, &end_pos
, collapsed
, NULL
, NULL
, &new_pos
);
1527 set_range_pos(This
, FALSE
, &new_pos
);
1531 *ActualCount
= -move_prev_chars(This
, -Count
, &end_pos
, TRUE
, &start_pos
, &bounded
, &new_pos
);
1532 set_range_pos(This
, bounded
, &new_pos
);
1534 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1537 dompos_release(&start_pos
);
1538 dompos_release(&end_pos
);
1539 dompos_release(&new_pos
);
1544 FIXME("unimplemented unit %s\n", debugstr_w(Unit
));
1550 static HRESULT WINAPI
HTMLTxtRange_select(IHTMLTxtRange
*iface
)
1552 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1553 nsISelection
*nsselection
;
1556 TRACE("(%p)\n", This
);
1558 nsres
= nsIDOMWindow_GetSelection(This
->doc
->basedoc
.window
->nswindow
, &nsselection
);
1559 if(NS_FAILED(nsres
)) {
1560 ERR("GetSelection failed: %08x\n", nsres
);
1564 nsISelection_RemoveAllRanges(nsselection
);
1565 nsISelection_AddRange(nsselection
, This
->nsrange
);
1566 nsISelection_Release(nsselection
);
1570 static HRESULT WINAPI
HTMLTxtRange_pasteHTML(IHTMLTxtRange
*iface
, BSTR html
)
1572 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1573 FIXME("(%p)->(%s)\n", This
, debugstr_w(html
));
1577 static HRESULT WINAPI
HTMLTxtRange_moveToElementText(IHTMLTxtRange
*iface
, IHTMLElement
*element
)
1579 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1580 FIXME("(%p)->(%p)\n", This
, element
);
1584 static HRESULT WINAPI
HTMLTxtRange_setEndPoint(IHTMLTxtRange
*iface
, BSTR how
,
1585 IHTMLTxtRange
*SourceRange
)
1587 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1588 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(how
), SourceRange
);
1592 static HRESULT WINAPI
HTMLTxtRange_compareEndPoints(IHTMLTxtRange
*iface
, BSTR how
,
1593 IHTMLTxtRange
*SourceRange
, LONG
*ret
)
1595 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1596 HTMLTxtRange
*src_range
;
1601 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(how
), SourceRange
, ret
);
1603 nscmpt
= string_to_nscmptype(how
);
1605 return E_INVALIDARG
;
1607 src_range
= get_range_object(This
->doc
, SourceRange
);
1611 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, nscmpt
, src_range
->nsrange
, &nsret
);
1612 if(NS_FAILED(nsres
))
1613 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
1619 static HRESULT WINAPI
HTMLTxtRange_findText(IHTMLTxtRange
*iface
, BSTR String
,
1620 LONG count
, LONG Flags
, VARIANT_BOOL
*Success
)
1622 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1623 FIXME("(%p)->(%s %d %08x %p)\n", This
, debugstr_w(String
), count
, Flags
, Success
);
1627 static HRESULT WINAPI
HTMLTxtRange_moveToPoint(IHTMLTxtRange
*iface
, LONG x
, LONG y
)
1629 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1630 FIXME("(%p)->(%d %d)\n", This
, x
, y
);
1634 static HRESULT WINAPI
HTMLTxtRange_getBookmark(IHTMLTxtRange
*iface
, BSTR
*Bookmark
)
1636 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1637 FIXME("(%p)->(%p)\n", This
, Bookmark
);
1641 static HRESULT WINAPI
HTMLTxtRange_moveToBookmark(IHTMLTxtRange
*iface
, BSTR Bookmark
,
1642 VARIANT_BOOL
*Success
)
1644 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1645 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(Bookmark
), Success
);
1649 static HRESULT WINAPI
HTMLTxtRange_queryCommandSupported(IHTMLTxtRange
*iface
, BSTR cmdID
,
1650 VARIANT_BOOL
*pfRet
)
1652 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1653 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1657 static HRESULT WINAPI
HTMLTxtRange_queryCommandEnabled(IHTMLTxtRange
*iface
, BSTR cmdID
,
1658 VARIANT_BOOL
*pfRet
)
1660 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1661 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1665 static HRESULT WINAPI
HTMLTxtRange_queryCommandState(IHTMLTxtRange
*iface
, BSTR cmdID
,
1666 VARIANT_BOOL
*pfRet
)
1668 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1669 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1673 static HRESULT WINAPI
HTMLTxtRange_queryCommandIndeterm(IHTMLTxtRange
*iface
, BSTR cmdID
,
1674 VARIANT_BOOL
*pfRet
)
1676 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1677 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1681 static HRESULT WINAPI
HTMLTxtRange_queryCommandText(IHTMLTxtRange
*iface
, BSTR cmdID
,
1684 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1685 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pcmdText
);
1689 static HRESULT WINAPI
HTMLTxtRange_queryCommandValue(IHTMLTxtRange
*iface
, BSTR cmdID
,
1692 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1693 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pcmdValue
);
1697 static HRESULT WINAPI
HTMLTxtRange_execCommand(IHTMLTxtRange
*iface
, BSTR cmdID
,
1698 VARIANT_BOOL showUI
, VARIANT value
, VARIANT_BOOL
*pfRet
)
1700 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1701 FIXME("(%p)->(%s %x v %p)\n", This
, debugstr_w(cmdID
), showUI
, pfRet
);
1705 static HRESULT WINAPI
HTMLTxtRange_execCommandShowHelp(IHTMLTxtRange
*iface
, BSTR cmdID
,
1706 VARIANT_BOOL
*pfRet
)
1708 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1709 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1713 #undef HTMLTXTRANGE_THIS
1715 static const IHTMLTxtRangeVtbl HTMLTxtRangeVtbl
= {
1716 HTMLTxtRange_QueryInterface
,
1717 HTMLTxtRange_AddRef
,
1718 HTMLTxtRange_Release
,
1719 HTMLTxtRange_GetTypeInfoCount
,
1720 HTMLTxtRange_GetTypeInfo
,
1721 HTMLTxtRange_GetIDsOfNames
,
1722 HTMLTxtRange_Invoke
,
1723 HTMLTxtRange_get_htmlText
,
1724 HTMLTxtRange_put_text
,
1725 HTMLTxtRange_get_text
,
1726 HTMLTxtRange_parentElement
,
1727 HTMLTxtRange_duplicate
,
1728 HTMLTxtRange_inRange
,
1729 HTMLTxtRange_isEqual
,
1730 HTMLTxtRange_scrollIntoView
,
1731 HTMLTxtRange_collapse
,
1732 HTMLTxtRange_expand
,
1734 HTMLTxtRange_moveStart
,
1735 HTMLTxtRange_moveEnd
,
1736 HTMLTxtRange_select
,
1737 HTMLTxtRange_pasteHTML
,
1738 HTMLTxtRange_moveToElementText
,
1739 HTMLTxtRange_setEndPoint
,
1740 HTMLTxtRange_compareEndPoints
,
1741 HTMLTxtRange_findText
,
1742 HTMLTxtRange_moveToPoint
,
1743 HTMLTxtRange_getBookmark
,
1744 HTMLTxtRange_moveToBookmark
,
1745 HTMLTxtRange_queryCommandSupported
,
1746 HTMLTxtRange_queryCommandEnabled
,
1747 HTMLTxtRange_queryCommandState
,
1748 HTMLTxtRange_queryCommandIndeterm
,
1749 HTMLTxtRange_queryCommandText
,
1750 HTMLTxtRange_queryCommandValue
,
1751 HTMLTxtRange_execCommand
,
1752 HTMLTxtRange_execCommandShowHelp
1755 #define OLECMDTRG_THIS(iface) DEFINE_THIS(HTMLTxtRange, OleCommandTarget, iface)
1757 static HRESULT WINAPI
RangeCommandTarget_QueryInterface(IOleCommandTarget
*iface
, REFIID riid
, void **ppv
)
1759 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1760 return IHTMLTxtRange_QueryInterface(HTMLTXTRANGE(This
), riid
, ppv
);
1763 static ULONG WINAPI
RangeCommandTarget_AddRef(IOleCommandTarget
*iface
)
1765 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1766 return IHTMLTxtRange_AddRef(HTMLTXTRANGE(This
));
1769 static ULONG WINAPI
RangeCommandTarget_Release(IOleCommandTarget
*iface
)
1771 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1772 return IHTMLTxtRange_Release(HTMLTXTRANGE(This
));
1775 static HRESULT WINAPI
RangeCommandTarget_QueryStatus(IOleCommandTarget
*iface
, const GUID
*pguidCmdGroup
,
1776 ULONG cCmds
, OLECMD prgCmds
[], OLECMDTEXT
*pCmdText
)
1778 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1779 FIXME("(%p)->(%s %d %p %p)\n", This
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
1783 static HRESULT
exec_indent(HTMLTxtRange
*This
, VARIANT
*in
, VARIANT
*out
)
1785 nsIDOMHTMLElement
*blockquote_elem
, *p_elem
;
1786 nsIDOMDocumentFragment
*fragment
;
1789 static const PRUnichar blockquoteW
[] = {'B','L','O','C','K','Q','U','O','T','E',0};
1790 static const PRUnichar pW
[] = {'P',0};
1792 TRACE("(%p)->(%p %p)\n", This
, in
, out
);
1794 if(!This
->doc
->nsdoc
) {
1795 WARN("NULL nsdoc\n");
1799 create_nselem(This
->doc
, blockquoteW
, &blockquote_elem
);
1800 create_nselem(This
->doc
, pW
, &p_elem
);
1802 nsIDOMRange_ExtractContents(This
->nsrange
, &fragment
);
1803 nsIDOMElement_AppendChild(p_elem
, (nsIDOMNode
*)fragment
, &tmp
);
1804 nsIDOMDocumentFragment_Release(fragment
);
1805 nsIDOMNode_Release(tmp
);
1807 nsIDOMElement_AppendChild(blockquote_elem
, (nsIDOMNode
*)p_elem
, &tmp
);
1808 nsIDOMElement_Release(p_elem
);
1809 nsIDOMNode_Release(tmp
);
1811 nsIDOMRange_InsertNode(This
->nsrange
, (nsIDOMNode
*)blockquote_elem
);
1812 nsIDOMElement_Release(blockquote_elem
);
1817 static HRESULT WINAPI
RangeCommandTarget_Exec(IOleCommandTarget
*iface
, const GUID
*pguidCmdGroup
,
1818 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
1820 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1822 TRACE("(%p)->(%s %d %x %p %p)\n", This
, debugstr_guid(pguidCmdGroup
), nCmdID
,
1823 nCmdexecopt
, pvaIn
, pvaOut
);
1825 if(pguidCmdGroup
&& IsEqualGUID(&CGID_MSHTML
, pguidCmdGroup
)) {
1828 return exec_indent(This
, pvaIn
, pvaOut
);
1830 FIXME("Unsupported cmdid %d of CGID_MSHTML\n", nCmdID
);
1833 FIXME("Unsupported cmd %d of group %s\n", nCmdID
, debugstr_guid(pguidCmdGroup
));
1839 #undef OLECMDTRG_THIS
1841 static const IOleCommandTargetVtbl OleCommandTargetVtbl
= {
1842 RangeCommandTarget_QueryInterface
,
1843 RangeCommandTarget_AddRef
,
1844 RangeCommandTarget_Release
,
1845 RangeCommandTarget_QueryStatus
,
1846 RangeCommandTarget_Exec
1849 HRESULT
HTMLTxtRange_Create(HTMLDocumentNode
*doc
, nsIDOMRange
*nsrange
, IHTMLTxtRange
**p
)
1853 ret
= heap_alloc(sizeof(HTMLTxtRange
));
1855 return E_OUTOFMEMORY
;
1857 ret
->lpHTMLTxtRangeVtbl
= &HTMLTxtRangeVtbl
;
1858 ret
->lpOleCommandTargetVtbl
= &OleCommandTargetVtbl
;
1862 nsIDOMRange_AddRef(nsrange
);
1863 ret
->nsrange
= nsrange
;
1866 list_add_head(&doc
->range_list
, &ret
->entry
);
1868 *p
= HTMLTXTRANGE(ret
);
1872 void detach_ranges(HTMLDocumentNode
*This
)
1876 LIST_FOR_EACH_ENTRY(iter
, &This
->range_list
, HTMLTxtRange
, entry
) {