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
19 #include "mshtml_private.h"
21 static const WCHAR brW
[] = {'b','r',0};
22 static const WCHAR hrW
[] = {'h','r',0};
25 IHTMLTxtRange IHTMLTxtRange_iface
;
26 IOleCommandTarget IOleCommandTarget_iface
;
31 HTMLDocumentNode
*doc
;
58 static HTMLTxtRange
*get_range_object(HTMLDocumentNode
*doc
, IHTMLTxtRange
*iface
)
62 LIST_FOR_EACH_ENTRY(iter
, &doc
->range_list
, HTMLTxtRange
, entry
) {
63 if(&iter
->IHTMLTxtRange_iface
== iface
)
67 ERR("Could not find range in document\n");
71 static range_unit_t
string_to_unit(LPCWSTR str
)
73 static const WCHAR characterW
[] =
74 {'c','h','a','r','a','c','t','e','r',0};
75 static const WCHAR wordW
[] =
77 static const WCHAR sentenceW
[] =
78 {'s','e','n','t','e','n','c','e',0};
79 static const WCHAR texteditW
[] =
80 {'t','e','x','t','e','d','i','t',0};
82 if(!strcmpiW(str
, characterW
)) return RU_CHAR
;
83 if(!strcmpiW(str
, wordW
)) return RU_WORD
;
84 if(!strcmpiW(str
, sentenceW
)) return RU_SENTENCE
;
85 if(!strcmpiW(str
, texteditW
)) return RU_TEXTEDIT
;
90 static int string_to_nscmptype(LPCWSTR str
)
92 static const WCHAR seW
[] = {'S','t','a','r','t','T','o','E','n','d',0};
93 static const WCHAR ssW
[] = {'S','t','a','r','t','T','o','S','t','a','r','t',0};
94 static const WCHAR esW
[] = {'E','n','d','T','o','S','t','a','r','t',0};
95 static const WCHAR eeW
[] = {'E','n','d','T','o','E','n','d',0};
97 if(!strcmpiW(str
, seW
)) return NS_START_TO_END
;
98 if(!strcmpiW(str
, ssW
)) return NS_START_TO_START
;
99 if(!strcmpiW(str
, esW
)) return NS_END_TO_START
;
100 if(!strcmpiW(str
, eeW
)) return NS_END_TO_END
;
105 static UINT16
get_node_type(nsIDOMNode
*node
)
110 nsIDOMNode_GetNodeType(node
, &type
);
115 static BOOL
is_elem_tag(nsIDOMNode
*node
, LPCWSTR istag
)
119 const PRUnichar
*tag
;
123 nsres
= nsIDOMNode_QueryInterface(node
, &IID_nsIDOMElement
, (void**)&elem
);
127 nsAString_Init(&tag_str
, NULL
);
128 nsIDOMElement_GetTagName(elem
, &tag_str
);
129 nsIDOMElement_Release(elem
);
130 nsAString_GetData(&tag_str
, &tag
);
132 ret
= !strcmpiW(tag
, istag
);
134 nsAString_Finish(&tag_str
);
139 static BOOL
is_space_elem(nsIDOMNode
*node
)
143 const PRUnichar
*tag
;
147 nsres
= nsIDOMNode_QueryInterface(node
, &IID_nsIDOMElement
, (void**)&elem
);
151 nsAString_Init(&tag_str
, NULL
);
152 nsIDOMElement_GetTagName(elem
, &tag_str
);
153 nsIDOMElement_Release(elem
);
154 nsAString_GetData(&tag_str
, &tag
);
156 ret
= !strcmpiW(tag
, brW
) || !strcmpiW(tag
, hrW
);
158 nsAString_Finish(&tag_str
);
163 static inline BOOL
wstrbuf_init(wstrbuf_t
*buf
)
167 buf
->buf
= heap_alloc(buf
->size
* sizeof(WCHAR
));
168 if (!buf
->buf
) return FALSE
;
173 static inline void wstrbuf_finish(wstrbuf_t
*buf
)
178 static void wstrbuf_append_len(wstrbuf_t
*buf
, LPCWSTR str
, int len
)
180 if(buf
->len
+len
>= buf
->size
) {
181 buf
->size
= 2*buf
->size
+len
;
182 buf
->buf
= heap_realloc(buf
->buf
, buf
->size
* sizeof(WCHAR
));
185 memcpy(buf
->buf
+buf
->len
, str
, len
*sizeof(WCHAR
));
187 buf
->buf
[buf
->len
] = 0;
190 static void wstrbuf_append_nodetxt(wstrbuf_t
*buf
, LPCWSTR str
, int len
)
192 const WCHAR
*s
= str
;
195 TRACE("%s\n", debugstr_wn(str
, 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 if(buf
->len
&& isspaceW(buf
->buf
[buf
->len
-1])) {
203 while(s
< str
+len
&& isspaceW(*s
))
207 d
= buf
->buf
+buf
->len
;
212 while(s
< str
+len
&& isspaceW(*s
))
219 buf
->len
= d
- buf
->buf
;
223 static void wstrbuf_append_node(wstrbuf_t
*buf
, nsIDOMNode
*node
)
226 switch(get_node_type(node
)) {
230 const PRUnichar
*data
;
232 nsIDOMNode_QueryInterface(node
, &IID_nsIDOMText
, (void**)&nstext
);
234 nsAString_Init(&data_str
, NULL
);
235 nsIDOMText_GetData(nstext
, &data_str
);
236 nsAString_GetData(&data_str
, &data
);
237 wstrbuf_append_nodetxt(buf
, data
, strlenW(data
));
238 nsAString_Finish(&data_str
);
240 nsIDOMText_Release(nstext
);
245 if(is_elem_tag(node
, brW
)) {
246 static const WCHAR endlW
[] = {'\r','\n'};
247 wstrbuf_append_len(buf
, endlW
, 2);
248 }else if(is_elem_tag(node
, hrW
)) {
249 static const WCHAR endl2W
[] = {'\r','\n','\r','\n'};
250 wstrbuf_append_len(buf
, endl2W
, 4);
255 static void wstrbuf_append_node_rec(wstrbuf_t
*buf
, nsIDOMNode
*node
)
257 nsIDOMNode
*iter
, *tmp
;
259 wstrbuf_append_node(buf
, node
);
261 nsIDOMNode_GetFirstChild(node
, &iter
);
263 wstrbuf_append_node_rec(buf
, iter
);
264 nsIDOMNode_GetNextSibling(iter
, &tmp
);
265 nsIDOMNode_Release(iter
);
270 static BOOL
fill_nodestr(dompos_t
*pos
)
275 if(pos
->type
!= TEXT_NODE
)
278 nsres
= nsIDOMNode_QueryInterface(pos
->node
, &IID_nsIDOMText
, (void**)&text
);
282 nsAString_Init(&pos
->str
, NULL
);
283 nsIDOMText_GetData(text
, &pos
->str
);
284 nsIDOMText_Release(text
);
285 nsAString_GetData(&pos
->str
, &pos
->p
);
288 pos
->off
= *pos
->p
? strlenW(pos
->p
)-1 : 0;
293 static nsIDOMNode
*next_node(nsIDOMNode
*iter
)
295 nsIDOMNode
*ret
, *tmp
;
301 nsres
= nsIDOMNode_GetFirstChild(iter
, &ret
);
302 if(NS_SUCCEEDED(nsres
) && ret
)
305 nsIDOMNode_AddRef(iter
);
308 nsres
= nsIDOMNode_GetNextSibling(iter
, &ret
);
309 if(NS_SUCCEEDED(nsres
) && ret
) {
310 nsIDOMNode_Release(iter
);
314 nsres
= nsIDOMNode_GetParentNode(iter
, &tmp
);
315 nsIDOMNode_Release(iter
);
317 }while(NS_SUCCEEDED(nsres
) && iter
);
322 static nsIDOMNode
*prev_node(HTMLTxtRange
*This
, nsIDOMNode
*iter
)
324 nsIDOMNode
*ret
, *tmp
;
328 nsIDOMHTMLElement
*nselem
;
330 nsIDOMHTMLDocument_GetBody(This
->doc
->nsdoc
, &nselem
);
331 nsIDOMHTMLElement_GetLastChild(nselem
, &tmp
);
333 return (nsIDOMNode
*)nselem
;
337 nsIDOMNode_GetLastChild(ret
, &tmp
);
340 nsIDOMHTMLElement_Release(nselem
);
345 nsres
= nsIDOMNode_GetLastChild(iter
, &ret
);
346 if(NS_SUCCEEDED(nsres
) && ret
)
349 nsIDOMNode_AddRef(iter
);
352 nsres
= nsIDOMNode_GetPreviousSibling(iter
, &ret
);
353 if(NS_SUCCEEDED(nsres
) && ret
) {
354 nsIDOMNode_Release(iter
);
358 nsres
= nsIDOMNode_GetParentNode(iter
, &tmp
);
359 nsIDOMNode_Release(iter
);
361 }while(NS_SUCCEEDED(nsres
) && iter
);
366 static nsIDOMNode
*get_child_node(nsIDOMNode
*node
, UINT32 off
)
368 nsIDOMNodeList
*node_list
;
369 nsIDOMNode
*ret
= NULL
;
371 nsIDOMNode_GetChildNodes(node
, &node_list
);
372 nsIDOMNodeList_Item(node_list
, off
, &ret
);
373 nsIDOMNodeList_Release(node_list
);
378 static void get_cur_pos(HTMLTxtRange
*This
, BOOL start
, dompos_t
*pos
)
387 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
392 nsIDOMRange_GetStartContainer(This
->nsrange
, &node
);
393 nsIDOMRange_GetStartOffset(This
->nsrange
, &off
);
395 nsIDOMRange_GetEndContainer(This
->nsrange
, &node
);
396 nsIDOMRange_GetEndOffset(This
->nsrange
, &off
);
399 pos
->type
= get_node_type(node
);
400 if(pos
->type
== ELEMENT_NODE
) {
402 pos
->node
= get_child_node(node
, off
);
405 pos
->node
= off
? get_child_node(node
, off
-1) : prev_node(This
, node
);
409 pos
->type
= get_node_type(pos
->node
);
410 nsIDOMNode_Release(node
);
418 pos
->node
= prev_node(This
, node
);
420 nsIDOMNode_Release(node
);
423 if(pos
->type
== TEXT_NODE
)
427 static void set_range_pos(HTMLTxtRange
*This
, BOOL start
, dompos_t
*pos
)
432 if(pos
->type
== TEXT_NODE
)
433 nsres
= nsIDOMRange_SetStart(This
->nsrange
, pos
->node
, pos
->off
);
435 nsres
= nsIDOMRange_SetStartBefore(This
->nsrange
, pos
->node
);
437 if(pos
->type
== TEXT_NODE
&& pos
->p
[pos
->off
+1])
438 nsres
= nsIDOMRange_SetEnd(This
->nsrange
, pos
->node
, pos
->off
+1);
440 nsres
= nsIDOMRange_SetEndAfter(This
->nsrange
, pos
->node
);
444 ERR("failed: %p %08x\n", pos
->node
, nsres
);
447 static inline void dompos_release(dompos_t
*pos
)
450 nsIDOMNode_Release(pos
->node
);
453 nsAString_Finish(&pos
->str
);
456 static inline void dompos_addref(dompos_t
*pos
)
459 nsIDOMNode_AddRef(pos
->node
);
461 if(pos
->type
== TEXT_NODE
)
465 static inline BOOL
dompos_cmp(const dompos_t
*pos1
, const dompos_t
*pos2
)
467 return pos1
->node
== pos2
->node
&& pos1
->off
== pos2
->off
;
470 static void range_to_string(HTMLTxtRange
*This
, wstrbuf_t
*buf
)
472 nsIDOMNode
*iter
, *tmp
;
473 dompos_t start_pos
, end_pos
;
476 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
484 get_cur_pos(This
, FALSE
, &end_pos
);
485 get_cur_pos(This
, TRUE
, &start_pos
);
487 if(start_pos
.type
== TEXT_NODE
) {
488 if(start_pos
.node
== end_pos
.node
) {
489 wstrbuf_append_nodetxt(buf
, start_pos
.p
+start_pos
.off
, end_pos
.off
-start_pos
.off
+1);
490 iter
= start_pos
.node
;
491 nsIDOMNode_AddRef(iter
);
493 wstrbuf_append_nodetxt(buf
, start_pos
.p
+start_pos
.off
, strlenW(start_pos
.p
+start_pos
.off
));
494 iter
= next_node(start_pos
.node
);
497 iter
= start_pos
.node
;
498 nsIDOMNode_AddRef(iter
);
501 while(iter
!= end_pos
.node
) {
502 wstrbuf_append_node(buf
, iter
);
503 tmp
= next_node(iter
);
504 nsIDOMNode_Release(iter
);
508 nsIDOMNode_AddRef(end_pos
.node
);
510 if(start_pos
.node
!= end_pos
.node
) {
511 if(end_pos
.type
== TEXT_NODE
)
512 wstrbuf_append_nodetxt(buf
, end_pos
.p
, end_pos
.off
+1);
514 wstrbuf_append_node(buf
, end_pos
.node
);
517 nsIDOMNode_Release(iter
);
518 dompos_release(&start_pos
);
519 dompos_release(&end_pos
);
524 for(p
= buf
->buf
+buf
->len
-1; p
>= buf
->buf
&& isspaceW(*p
); p
--);
526 p
= strchrW(p
, '\r');
532 HRESULT
get_node_text(HTMLDOMNode
*node
, BSTR
*ret
)
537 if (!wstrbuf_init(&buf
))
538 return E_OUTOFMEMORY
;
539 wstrbuf_append_node_rec(&buf
, node
->nsnode
);
541 *ret
= SysAllocString(buf
.buf
);
543 hres
= E_OUTOFMEMORY
;
547 wstrbuf_finish(&buf
);
550 TRACE("ret %s\n", debugstr_w(*ret
));
554 static WCHAR
get_pos_char(const dompos_t
*pos
)
558 return pos
->p
[pos
->off
];
560 if(is_space_elem(pos
->node
))
567 static void end_space(const dompos_t
*pos
, dompos_t
*new_pos
)
572 dompos_addref(new_pos
);
574 if(pos
->type
!= TEXT_NODE
)
577 p
= new_pos
->p
+new_pos
->off
;
579 if(!*p
|| !isspace(*p
))
582 while(p
[1] && isspace(p
[1]))
585 new_pos
->off
= p
- new_pos
->p
;
588 static WCHAR
next_char(const dompos_t
*pos
, dompos_t
*new_pos
)
590 nsIDOMNode
*iter
, *tmp
;
591 dompos_t last_space
, tmp_pos
;
595 if(pos
->type
== TEXT_NODE
&& pos
->off
!= -1 && pos
->p
[pos
->off
]) {
599 while(isspaceW(*++p
));
603 if(*p
&& isspaceW(*p
)) {
605 while(p
[1] && isspaceW(p
[1]))
611 new_pos
->off
= p
- pos
->p
;
612 dompos_addref(new_pos
);
614 return cspace
? cspace
: *p
;
617 last_space
.off
= p
- pos
->p
;
618 dompos_addref(&last_space
);
622 iter
= next_node(pos
->node
);
625 switch(get_node_type(iter
)) {
628 tmp_pos
.type
= TEXT_NODE
;
630 dompos_addref(&tmp_pos
);
635 dompos_release(&tmp_pos
);
637 }else if(isspaceW(*p
)) {
639 dompos_release(&last_space
);
643 while(p
[1] && isspaceW(p
[1]))
646 tmp_pos
.off
= p
-tmp_pos
.p
;
649 last_space
= tmp_pos
;
654 nsIDOMNode_Release(iter
);
657 *new_pos
= last_space
;
658 dompos_release(&tmp_pos
);
659 nsIDOMNode_Release(iter
);
667 nsIDOMNode_Release(iter
);
671 if(is_elem_tag(iter
, brW
)) {
673 dompos_release(&last_space
);
676 nsIDOMNode_AddRef(iter
);
677 last_space
.node
= iter
;
678 last_space
.type
= ELEMENT_NODE
;
681 }else if(is_elem_tag(iter
, hrW
)) {
683 *new_pos
= last_space
;
684 nsIDOMNode_Release(iter
);
688 new_pos
->node
= iter
;
689 new_pos
->type
= ELEMENT_NODE
;
697 iter
= next_node(iter
);
698 nsIDOMNode_Release(tmp
);
702 *new_pos
= last_space
;
705 dompos_addref(new_pos
);
711 static WCHAR
prev_char(HTMLTxtRange
*This
, const dompos_t
*pos
, dompos_t
*new_pos
)
713 nsIDOMNode
*iter
, *tmp
;
715 BOOL skip_space
= FALSE
;
717 if(pos
->type
== TEXT_NODE
&& isspaceW(pos
->p
[pos
->off
]))
720 if(pos
->type
== TEXT_NODE
&& pos
->off
) {
721 p
= pos
->p
+pos
->off
-1;
724 while(p
>= pos
->p
&& isspace(*p
))
730 new_pos
->off
= p
-pos
->p
;
731 dompos_addref(new_pos
);
732 return new_pos
->p
[new_pos
->off
];
736 iter
= prev_node(This
, pos
->node
);
739 switch(get_node_type(iter
)) {
744 tmp_pos
.type
= TEXT_NODE
;
746 dompos_addref(&tmp_pos
);
748 p
= tmp_pos
.p
+ strlenW(tmp_pos
.p
)-1;
751 while(p
>= tmp_pos
.p
&& isspaceW(*p
))
756 dompos_release(&tmp_pos
);
760 tmp_pos
.off
= p
-tmp_pos
.p
;
762 nsIDOMNode_Release(iter
);
767 if(is_elem_tag(iter
, brW
)) {
772 }else if(!is_elem_tag(iter
, hrW
)) {
776 new_pos
->node
= iter
;
777 new_pos
->type
= ELEMENT_NODE
;
784 iter
= prev_node(This
, iter
);
785 nsIDOMNode_Release(tmp
);
789 dompos_addref(new_pos
);
793 static LONG
move_next_chars(LONG cnt
, const dompos_t
*pos
, BOOL col
, const dompos_t
*bound_pos
,
794 BOOL
*bounded
, dompos_t
*new_pos
)
807 end_space(pos
, new_pos
);
811 c
= next_char(pos
, &iter
);
816 c
= next_char(&tmp
, &iter
);
817 dompos_release(&tmp
);
822 if(bound_pos
&& dompos_cmp(&tmp
, bound_pos
)) {
832 static LONG
move_prev_chars(HTMLTxtRange
*This
, LONG cnt
, const dompos_t
*pos
, BOOL end
,
833 const dompos_t
*bound_pos
, BOOL
*bounded
, dompos_t
*new_pos
)
837 BOOL prev_eq
= FALSE
;
843 c
= prev_char(This
, pos
, &iter
);
847 while(c
&& ret
< cnt
) {
849 c
= prev_char(This
, &tmp
, &iter
);
850 dompos_release(&tmp
);
864 prev_eq
= bound_pos
&& dompos_cmp(&iter
, bound_pos
);
871 static LONG
find_prev_space(HTMLTxtRange
*This
, const dompos_t
*pos
, BOOL first_space
, dompos_t
*ret
)
876 c
= prev_char(This
, pos
, &iter
);
877 if(!c
|| (first_space
&& isspaceW(c
))) {
884 c
= prev_char(This
, &tmp
, &iter
);
885 if(!c
|| isspaceW(c
)) {
886 dompos_release(&iter
);
889 dompos_release(&tmp
);
896 static int find_word_end(const dompos_t
*pos
, dompos_t
*ret
)
901 c
= get_pos_char(pos
);
908 c
= next_char(pos
, &iter
);
919 while(c
&& !isspaceW(c
)) {
921 c
= next_char(&tmp
, &iter
);
923 dompos_release(&iter
);
927 dompos_release(&tmp
);
935 static LONG
move_next_words(LONG cnt
, const dompos_t
*pos
, dompos_t
*new_pos
)
941 c
= get_pos_char(pos
);
943 end_space(pos
, &iter
);
946 c
= next_char(pos
, &iter
);
951 while(c
&& ret
< cnt
) {
953 c
= next_char(&tmp
, &iter
);
954 dompos_release(&tmp
);
963 static LONG
move_prev_words(HTMLTxtRange
*This
, LONG cnt
, const dompos_t
*pos
, dompos_t
*new_pos
)
969 dompos_addref(&iter
);
972 if(!find_prev_space(This
, &iter
, FALSE
, &tmp
))
975 dompos_release(&iter
);
984 static inline HTMLTxtRange
*impl_from_IHTMLTxtRange(IHTMLTxtRange
*iface
)
986 return CONTAINING_RECORD(iface
, HTMLTxtRange
, IHTMLTxtRange_iface
);
989 static HRESULT WINAPI
HTMLTxtRange_QueryInterface(IHTMLTxtRange
*iface
, REFIID riid
, void **ppv
)
991 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
995 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
996 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
997 *ppv
= &This
->IHTMLTxtRange_iface
;
998 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
999 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
1000 *ppv
= &This
->IHTMLTxtRange_iface
;
1001 }else if(IsEqualGUID(&IID_IHTMLTxtRange
, riid
)) {
1002 TRACE("(%p)->(IID_IHTMLTxtRange %p)\n", This
, ppv
);
1003 *ppv
= &This
->IHTMLTxtRange_iface
;
1004 }else if(IsEqualGUID(&IID_IOleCommandTarget
, riid
)) {
1005 TRACE("(%p)->(IID_IOleCommandTarget %p)\n", This
, ppv
);
1006 *ppv
= &This
->IOleCommandTarget_iface
;
1010 IUnknown_AddRef((IUnknown
*)*ppv
);
1014 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
1015 return E_NOINTERFACE
;
1018 static ULONG WINAPI
HTMLTxtRange_AddRef(IHTMLTxtRange
*iface
)
1020 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1021 LONG ref
= InterlockedIncrement(&This
->ref
);
1023 TRACE("(%p) ref=%d\n", This
, ref
);
1028 static ULONG WINAPI
HTMLTxtRange_Release(IHTMLTxtRange
*iface
)
1030 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1031 LONG ref
= InterlockedDecrement(&This
->ref
);
1033 TRACE("(%p) ref=%d\n", This
, ref
);
1037 nsIDOMRange_Release(This
->nsrange
);
1039 list_remove(&This
->entry
);
1046 static HRESULT WINAPI
HTMLTxtRange_GetTypeInfoCount(IHTMLTxtRange
*iface
, UINT
*pctinfo
)
1048 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1049 FIXME("(%p)->(%p)\n", This
, pctinfo
);
1053 static HRESULT WINAPI
HTMLTxtRange_GetTypeInfo(IHTMLTxtRange
*iface
, UINT iTInfo
,
1054 LCID lcid
, ITypeInfo
**ppTInfo
)
1056 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1057 FIXME("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1061 static HRESULT WINAPI
HTMLTxtRange_GetIDsOfNames(IHTMLTxtRange
*iface
, REFIID riid
,
1062 LPOLESTR
*rgszNames
, UINT cNames
,
1063 LCID lcid
, DISPID
*rgDispId
)
1065 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1066 FIXME("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
1071 static HRESULT WINAPI
HTMLTxtRange_Invoke(IHTMLTxtRange
*iface
, DISPID dispIdMember
,
1072 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
1073 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1075 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1076 FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1077 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1081 static HRESULT WINAPI
HTMLTxtRange_get_htmlText(IHTMLTxtRange
*iface
, BSTR
*p
)
1083 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1085 TRACE("(%p)->(%p)\n", This
, p
);
1090 nsIDOMDocumentFragment
*fragment
;
1093 nsres
= nsIDOMRange_CloneContents(This
->nsrange
, &fragment
);
1094 if(NS_SUCCEEDED(nsres
)) {
1095 const PRUnichar
*nstext
;
1098 nsAString_Init(&nsstr
, NULL
);
1099 nsnode_to_nsstring((nsIDOMNode
*)fragment
, &nsstr
);
1100 nsIDOMDocumentFragment_Release(fragment
);
1102 nsAString_GetData(&nsstr
, &nstext
);
1103 *p
= SysAllocString(nstext
);
1105 nsAString_Finish(&nsstr
);
1110 const WCHAR emptyW
[] = {0};
1111 *p
= SysAllocString(emptyW
);
1114 TRACE("return %s\n", debugstr_w(*p
));
1118 static HRESULT WINAPI
HTMLTxtRange_put_text(IHTMLTxtRange
*iface
, BSTR v
)
1120 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1121 nsIDOMText
*text_node
;
1125 TRACE("(%p)->(%s)\n", This
, debugstr_w(v
));
1128 return MSHTML_E_NODOC
;
1130 nsAString_InitDepend(&text_str
, v
);
1131 nsres
= nsIDOMHTMLDocument_CreateTextNode(This
->doc
->nsdoc
, &text_str
, &text_node
);
1132 nsAString_Finish(&text_str
);
1133 if(NS_FAILED(nsres
)) {
1134 ERR("CreateTextNode failed: %08x\n", nsres
);
1137 nsres
= nsIDOMRange_DeleteContents(This
->nsrange
);
1138 if(NS_FAILED(nsres
))
1139 ERR("DeleteContents failed: %08x\n", nsres
);
1141 nsres
= nsIDOMRange_InsertNode(This
->nsrange
, (nsIDOMNode
*)text_node
);
1142 if(NS_FAILED(nsres
))
1143 ERR("InsertNode failed: %08x\n", nsres
);
1145 nsres
= nsIDOMRange_SetEndAfter(This
->nsrange
, (nsIDOMNode
*)text_node
);
1146 if(NS_FAILED(nsres
))
1147 ERR("SetEndAfter failed: %08x\n", nsres
);
1149 return IHTMLTxtRange_collapse(&This
->IHTMLTxtRange_iface
, VARIANT_FALSE
);
1152 static HRESULT WINAPI
HTMLTxtRange_get_text(IHTMLTxtRange
*iface
, BSTR
*p
)
1154 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1157 TRACE("(%p)->(%p)\n", This
, p
);
1163 if (!wstrbuf_init(&buf
))
1164 return E_OUTOFMEMORY
;
1165 range_to_string(This
, &buf
);
1167 *p
= SysAllocString(buf
.buf
);
1168 wstrbuf_finish(&buf
);
1170 TRACE("ret %s\n", debugstr_w(*p
));
1174 static HRESULT WINAPI
HTMLTxtRange_parentElement(IHTMLTxtRange
*iface
, IHTMLElement
**parent
)
1176 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1177 nsIDOMNode
*nsnode
, *tmp
;
1181 TRACE("(%p)->(%p)\n", This
, parent
);
1183 nsIDOMRange_GetCommonAncestorContainer(This
->nsrange
, &nsnode
);
1184 while(nsnode
&& get_node_type(nsnode
) != ELEMENT_NODE
) {
1185 nsIDOMNode_GetParentNode(nsnode
, &tmp
);
1186 nsIDOMNode_Release(nsnode
);
1195 hres
= get_node(This
->doc
, nsnode
, TRUE
, &node
);
1196 nsIDOMNode_Release(nsnode
);
1200 hres
= IHTMLDOMNode_QueryInterface(&node
->IHTMLDOMNode_iface
, &IID_IHTMLElement
, (void**)parent
);
1205 static HRESULT WINAPI
HTMLTxtRange_duplicate(IHTMLTxtRange
*iface
, IHTMLTxtRange
**Duplicate
)
1207 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1208 nsIDOMRange
*nsrange
= NULL
;
1211 TRACE("(%p)->(%p)\n", This
, Duplicate
);
1213 nsIDOMRange_CloneRange(This
->nsrange
, &nsrange
);
1214 hres
= HTMLTxtRange_Create(This
->doc
, nsrange
, Duplicate
);
1215 nsIDOMRange_Release(nsrange
);
1220 static HRESULT WINAPI
HTMLTxtRange_inRange(IHTMLTxtRange
*iface
, IHTMLTxtRange
*Range
,
1221 VARIANT_BOOL
*InRange
)
1223 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1224 HTMLTxtRange
*src_range
;
1228 TRACE("(%p)->(%p %p)\n", This
, Range
, InRange
);
1230 *InRange
= VARIANT_FALSE
;
1232 src_range
= get_range_object(This
->doc
, Range
);
1236 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_START_TO_START
,
1237 src_range
->nsrange
, &nsret
);
1238 if(NS_SUCCEEDED(nsres
) && nsret
<= 0) {
1239 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_END_TO_END
,
1240 src_range
->nsrange
, &nsret
);
1241 if(NS_SUCCEEDED(nsres
) && nsret
>= 0)
1242 *InRange
= VARIANT_TRUE
;
1245 if(NS_FAILED(nsres
))
1246 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
1251 static HRESULT WINAPI
HTMLTxtRange_isEqual(IHTMLTxtRange
*iface
, IHTMLTxtRange
*Range
,
1252 VARIANT_BOOL
*IsEqual
)
1254 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1255 HTMLTxtRange
*src_range
;
1259 TRACE("(%p)->(%p %p)\n", This
, Range
, IsEqual
);
1261 *IsEqual
= VARIANT_FALSE
;
1263 src_range
= get_range_object(This
->doc
, Range
);
1267 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_START_TO_START
,
1268 src_range
->nsrange
, &nsret
);
1269 if(NS_SUCCEEDED(nsres
) && !nsret
) {
1270 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_END_TO_END
,
1271 src_range
->nsrange
, &nsret
);
1272 if(NS_SUCCEEDED(nsres
) && !nsret
)
1273 *IsEqual
= VARIANT_TRUE
;
1276 if(NS_FAILED(nsres
))
1277 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
1282 static HRESULT WINAPI
HTMLTxtRange_scrollIntoView(IHTMLTxtRange
*iface
, VARIANT_BOOL fStart
)
1284 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1285 FIXME("(%p)->(%x)\n", This
, fStart
);
1289 static HRESULT WINAPI
HTMLTxtRange_collapse(IHTMLTxtRange
*iface
, VARIANT_BOOL Start
)
1291 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1293 TRACE("(%p)->(%x)\n", This
, Start
);
1295 nsIDOMRange_Collapse(This
->nsrange
, Start
!= VARIANT_FALSE
);
1299 static HRESULT WINAPI
HTMLTxtRange_expand(IHTMLTxtRange
*iface
, BSTR Unit
, VARIANT_BOOL
*Success
)
1301 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1304 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(Unit
), Success
);
1306 unit
= string_to_unit(Unit
);
1307 if(unit
== RU_UNKNOWN
)
1308 return E_INVALIDARG
;
1310 *Success
= VARIANT_FALSE
;
1314 dompos_t end_pos
, start_pos
, new_start_pos
, new_end_pos
;
1317 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
1319 get_cur_pos(This
, TRUE
, &start_pos
);
1320 get_cur_pos(This
, FALSE
, &end_pos
);
1322 if(find_word_end(&end_pos
, &new_end_pos
) || collapsed
) {
1323 set_range_pos(This
, FALSE
, &new_end_pos
);
1324 *Success
= VARIANT_TRUE
;
1327 if(start_pos
.type
&& (get_pos_char(&end_pos
) || !dompos_cmp(&new_end_pos
, &end_pos
))) {
1328 if(find_prev_space(This
, &start_pos
, TRUE
, &new_start_pos
)) {
1329 set_range_pos(This
, TRUE
, &new_start_pos
);
1330 *Success
= VARIANT_TRUE
;
1332 dompos_release(&new_start_pos
);
1335 dompos_release(&new_end_pos
);
1336 dompos_release(&end_pos
);
1337 dompos_release(&start_pos
);
1343 nsIDOMHTMLElement
*nsbody
= NULL
;
1346 nsres
= nsIDOMHTMLDocument_GetBody(This
->doc
->nsdoc
, &nsbody
);
1347 if(NS_FAILED(nsres
) || !nsbody
) {
1348 ERR("Could not get body: %08x\n", nsres
);
1352 nsres
= nsIDOMRange_SelectNodeContents(This
->nsrange
, (nsIDOMNode
*)nsbody
);
1353 nsIDOMHTMLElement_Release(nsbody
);
1354 if(NS_FAILED(nsres
)) {
1355 ERR("Collapse failed: %08x\n", nsres
);
1359 *Success
= VARIANT_TRUE
;
1364 FIXME("Unimplemented unit %s\n", debugstr_w(Unit
));
1370 static HRESULT WINAPI
HTMLTxtRange_move(IHTMLTxtRange
*iface
, BSTR Unit
,
1371 LONG Count
, LONG
*ActualCount
)
1373 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1376 TRACE("(%p)->(%s %d %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1378 unit
= string_to_unit(Unit
);
1379 if(unit
== RU_UNKNOWN
)
1380 return E_INVALIDARG
;
1384 return IHTMLTxtRange_collapse(&This
->IHTMLTxtRange_iface
, TRUE
);
1389 dompos_t cur_pos
, new_pos
;
1391 get_cur_pos(This
, TRUE
, &cur_pos
);
1394 *ActualCount
= move_next_chars(Count
, &cur_pos
, TRUE
, NULL
, NULL
, &new_pos
);
1395 set_range_pos(This
, FALSE
, &new_pos
);
1396 dompos_release(&new_pos
);
1398 IHTMLTxtRange_collapse(&This
->IHTMLTxtRange_iface
, FALSE
);
1400 *ActualCount
= -move_prev_chars(This
, -Count
, &cur_pos
, FALSE
, NULL
, NULL
, &new_pos
);
1401 set_range_pos(This
, TRUE
, &new_pos
);
1402 IHTMLTxtRange_collapse(&This
->IHTMLTxtRange_iface
, TRUE
);
1403 dompos_release(&new_pos
);
1406 dompos_release(&cur_pos
);
1411 dompos_t cur_pos
, new_pos
;
1413 get_cur_pos(This
, TRUE
, &cur_pos
);
1416 *ActualCount
= move_next_words(Count
, &cur_pos
, &new_pos
);
1417 set_range_pos(This
, FALSE
, &new_pos
);
1418 dompos_release(&new_pos
);
1419 IHTMLTxtRange_collapse(&This
->IHTMLTxtRange_iface
, FALSE
);
1421 *ActualCount
= -move_prev_words(This
, -Count
, &cur_pos
, &new_pos
);
1422 set_range_pos(This
, TRUE
, &new_pos
);
1423 IHTMLTxtRange_collapse(&This
->IHTMLTxtRange_iface
, TRUE
);
1424 dompos_release(&new_pos
);
1427 dompos_release(&cur_pos
);
1432 FIXME("unimplemented unit %s\n", debugstr_w(Unit
));
1435 TRACE("ret %d\n", *ActualCount
);
1439 static HRESULT WINAPI
HTMLTxtRange_moveStart(IHTMLTxtRange
*iface
, BSTR Unit
,
1440 LONG Count
, LONG
*ActualCount
)
1442 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1445 TRACE("(%p)->(%s %d %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1447 unit
= string_to_unit(Unit
);
1448 if(unit
== RU_UNKNOWN
)
1449 return E_INVALIDARG
;
1458 dompos_t start_pos
, end_pos
, new_pos
;
1461 get_cur_pos(This
, TRUE
, &start_pos
);
1462 get_cur_pos(This
, FALSE
, &end_pos
);
1463 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
1468 *ActualCount
= move_next_chars(Count
, &start_pos
, collapsed
, &end_pos
, &bounded
, &new_pos
);
1469 set_range_pos(This
, !bounded
, &new_pos
);
1471 IHTMLTxtRange_collapse(&This
->IHTMLTxtRange_iface
, FALSE
);
1473 *ActualCount
= -move_prev_chars(This
, -Count
, &start_pos
, FALSE
, NULL
, NULL
, &new_pos
);
1474 set_range_pos(This
, TRUE
, &new_pos
);
1477 dompos_release(&start_pos
);
1478 dompos_release(&end_pos
);
1479 dompos_release(&new_pos
);
1484 FIXME("unimplemented unit %s\n", debugstr_w(Unit
));
1490 static HRESULT WINAPI
HTMLTxtRange_moveEnd(IHTMLTxtRange
*iface
, BSTR Unit
,
1491 LONG Count
, LONG
*ActualCount
)
1493 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1496 TRACE("(%p)->(%s %d %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1498 unit
= string_to_unit(Unit
);
1499 if(unit
== RU_UNKNOWN
)
1500 return E_INVALIDARG
;
1509 dompos_t start_pos
, end_pos
, new_pos
;
1512 get_cur_pos(This
, TRUE
, &start_pos
);
1513 get_cur_pos(This
, FALSE
, &end_pos
);
1514 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
1517 *ActualCount
= move_next_chars(Count
, &end_pos
, collapsed
, NULL
, NULL
, &new_pos
);
1518 set_range_pos(This
, FALSE
, &new_pos
);
1522 *ActualCount
= -move_prev_chars(This
, -Count
, &end_pos
, TRUE
, &start_pos
, &bounded
, &new_pos
);
1523 set_range_pos(This
, bounded
, &new_pos
);
1525 IHTMLTxtRange_collapse(&This
->IHTMLTxtRange_iface
, TRUE
);
1528 dompos_release(&start_pos
);
1529 dompos_release(&end_pos
);
1530 dompos_release(&new_pos
);
1535 FIXME("unimplemented unit %s\n", debugstr_w(Unit
));
1541 static HRESULT WINAPI
HTMLTxtRange_select(IHTMLTxtRange
*iface
)
1543 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1544 nsISelection
*nsselection
;
1547 TRACE("(%p)\n", This
);
1549 nsres
= nsIDOMWindow_GetSelection(This
->doc
->basedoc
.window
->nswindow
, &nsselection
);
1550 if(NS_FAILED(nsres
)) {
1551 ERR("GetSelection failed: %08x\n", nsres
);
1555 nsISelection_RemoveAllRanges(nsselection
);
1556 nsISelection_AddRange(nsselection
, This
->nsrange
);
1557 nsISelection_Release(nsselection
);
1561 static HRESULT WINAPI
HTMLTxtRange_pasteHTML(IHTMLTxtRange
*iface
, BSTR html
)
1563 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1564 FIXME("(%p)->(%s)\n", This
, debugstr_w(html
));
1568 static HRESULT WINAPI
HTMLTxtRange_moveToElementText(IHTMLTxtRange
*iface
, IHTMLElement
*element
)
1570 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1571 FIXME("(%p)->(%p)\n", This
, element
);
1575 static HRESULT WINAPI
HTMLTxtRange_setEndPoint(IHTMLTxtRange
*iface
, BSTR how
,
1576 IHTMLTxtRange
*SourceRange
)
1578 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1579 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(how
), SourceRange
);
1583 static HRESULT WINAPI
HTMLTxtRange_compareEndPoints(IHTMLTxtRange
*iface
, BSTR how
,
1584 IHTMLTxtRange
*SourceRange
, LONG
*ret
)
1586 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1587 HTMLTxtRange
*src_range
;
1592 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(how
), SourceRange
, ret
);
1594 nscmpt
= string_to_nscmptype(how
);
1596 return E_INVALIDARG
;
1598 src_range
= get_range_object(This
->doc
, SourceRange
);
1602 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, nscmpt
, src_range
->nsrange
, &nsret
);
1603 if(NS_FAILED(nsres
))
1604 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
1610 static HRESULT WINAPI
HTMLTxtRange_findText(IHTMLTxtRange
*iface
, BSTR String
,
1611 LONG count
, LONG Flags
, VARIANT_BOOL
*Success
)
1613 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1614 FIXME("(%p)->(%s %d %08x %p)\n", This
, debugstr_w(String
), count
, Flags
, Success
);
1618 static HRESULT WINAPI
HTMLTxtRange_moveToPoint(IHTMLTxtRange
*iface
, LONG x
, LONG y
)
1620 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1621 FIXME("(%p)->(%d %d)\n", This
, x
, y
);
1625 static HRESULT WINAPI
HTMLTxtRange_getBookmark(IHTMLTxtRange
*iface
, BSTR
*Bookmark
)
1627 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1628 FIXME("(%p)->(%p)\n", This
, Bookmark
);
1632 static HRESULT WINAPI
HTMLTxtRange_moveToBookmark(IHTMLTxtRange
*iface
, BSTR Bookmark
,
1633 VARIANT_BOOL
*Success
)
1635 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1636 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(Bookmark
), Success
);
1640 static HRESULT WINAPI
HTMLTxtRange_queryCommandSupported(IHTMLTxtRange
*iface
, BSTR cmdID
,
1641 VARIANT_BOOL
*pfRet
)
1643 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1644 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1648 static HRESULT WINAPI
HTMLTxtRange_queryCommandEnabled(IHTMLTxtRange
*iface
, BSTR cmdID
,
1649 VARIANT_BOOL
*pfRet
)
1651 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1652 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1656 static HRESULT WINAPI
HTMLTxtRange_queryCommandState(IHTMLTxtRange
*iface
, BSTR cmdID
,
1657 VARIANT_BOOL
*pfRet
)
1659 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1660 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1664 static HRESULT WINAPI
HTMLTxtRange_queryCommandIndeterm(IHTMLTxtRange
*iface
, BSTR cmdID
,
1665 VARIANT_BOOL
*pfRet
)
1667 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1668 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1672 static HRESULT WINAPI
HTMLTxtRange_queryCommandText(IHTMLTxtRange
*iface
, BSTR cmdID
,
1675 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1676 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pcmdText
);
1680 static HRESULT WINAPI
HTMLTxtRange_queryCommandValue(IHTMLTxtRange
*iface
, BSTR cmdID
,
1683 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1684 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pcmdValue
);
1688 static HRESULT WINAPI
HTMLTxtRange_execCommand(IHTMLTxtRange
*iface
, BSTR cmdID
,
1689 VARIANT_BOOL showUI
, VARIANT value
, VARIANT_BOOL
*pfRet
)
1691 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1692 FIXME("(%p)->(%s %x v %p)\n", This
, debugstr_w(cmdID
), showUI
, pfRet
);
1696 static HRESULT WINAPI
HTMLTxtRange_execCommandShowHelp(IHTMLTxtRange
*iface
, BSTR cmdID
,
1697 VARIANT_BOOL
*pfRet
)
1699 HTMLTxtRange
*This
= impl_from_IHTMLTxtRange(iface
);
1700 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1704 static const IHTMLTxtRangeVtbl HTMLTxtRangeVtbl
= {
1705 HTMLTxtRange_QueryInterface
,
1706 HTMLTxtRange_AddRef
,
1707 HTMLTxtRange_Release
,
1708 HTMLTxtRange_GetTypeInfoCount
,
1709 HTMLTxtRange_GetTypeInfo
,
1710 HTMLTxtRange_GetIDsOfNames
,
1711 HTMLTxtRange_Invoke
,
1712 HTMLTxtRange_get_htmlText
,
1713 HTMLTxtRange_put_text
,
1714 HTMLTxtRange_get_text
,
1715 HTMLTxtRange_parentElement
,
1716 HTMLTxtRange_duplicate
,
1717 HTMLTxtRange_inRange
,
1718 HTMLTxtRange_isEqual
,
1719 HTMLTxtRange_scrollIntoView
,
1720 HTMLTxtRange_collapse
,
1721 HTMLTxtRange_expand
,
1723 HTMLTxtRange_moveStart
,
1724 HTMLTxtRange_moveEnd
,
1725 HTMLTxtRange_select
,
1726 HTMLTxtRange_pasteHTML
,
1727 HTMLTxtRange_moveToElementText
,
1728 HTMLTxtRange_setEndPoint
,
1729 HTMLTxtRange_compareEndPoints
,
1730 HTMLTxtRange_findText
,
1731 HTMLTxtRange_moveToPoint
,
1732 HTMLTxtRange_getBookmark
,
1733 HTMLTxtRange_moveToBookmark
,
1734 HTMLTxtRange_queryCommandSupported
,
1735 HTMLTxtRange_queryCommandEnabled
,
1736 HTMLTxtRange_queryCommandState
,
1737 HTMLTxtRange_queryCommandIndeterm
,
1738 HTMLTxtRange_queryCommandText
,
1739 HTMLTxtRange_queryCommandValue
,
1740 HTMLTxtRange_execCommand
,
1741 HTMLTxtRange_execCommandShowHelp
1744 static inline HTMLTxtRange
*impl_from_IOleCommandTarget(IOleCommandTarget
*iface
)
1746 return CONTAINING_RECORD(iface
, HTMLTxtRange
, IOleCommandTarget_iface
);
1749 static HRESULT WINAPI
RangeCommandTarget_QueryInterface(IOleCommandTarget
*iface
, REFIID riid
, void **ppv
)
1751 HTMLTxtRange
*This
= impl_from_IOleCommandTarget(iface
);
1752 return IHTMLTxtRange_QueryInterface(&This
->IHTMLTxtRange_iface
, riid
, ppv
);
1755 static ULONG WINAPI
RangeCommandTarget_AddRef(IOleCommandTarget
*iface
)
1757 HTMLTxtRange
*This
= impl_from_IOleCommandTarget(iface
);
1758 return IHTMLTxtRange_AddRef(&This
->IHTMLTxtRange_iface
);
1761 static ULONG WINAPI
RangeCommandTarget_Release(IOleCommandTarget
*iface
)
1763 HTMLTxtRange
*This
= impl_from_IOleCommandTarget(iface
);
1764 return IHTMLTxtRange_Release(&This
->IHTMLTxtRange_iface
);
1767 static HRESULT WINAPI
RangeCommandTarget_QueryStatus(IOleCommandTarget
*iface
, const GUID
*pguidCmdGroup
,
1768 ULONG cCmds
, OLECMD prgCmds
[], OLECMDTEXT
*pCmdText
)
1770 HTMLTxtRange
*This
= impl_from_IOleCommandTarget(iface
);
1771 FIXME("(%p)->(%s %d %p %p)\n", This
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
1775 static HRESULT
exec_indent(HTMLTxtRange
*This
, VARIANT
*in
, VARIANT
*out
)
1777 nsIDOMHTMLElement
*blockquote_elem
, *p_elem
;
1778 nsIDOMDocumentFragment
*fragment
;
1781 static const PRUnichar blockquoteW
[] = {'B','L','O','C','K','Q','U','O','T','E',0};
1782 static const PRUnichar pW
[] = {'P',0};
1784 TRACE("(%p)->(%p %p)\n", This
, in
, out
);
1786 if(!This
->doc
->nsdoc
) {
1787 WARN("NULL nsdoc\n");
1791 create_nselem(This
->doc
, blockquoteW
, &blockquote_elem
);
1792 create_nselem(This
->doc
, pW
, &p_elem
);
1794 nsIDOMRange_ExtractContents(This
->nsrange
, &fragment
);
1795 nsIDOMHTMLElement_AppendChild(p_elem
, (nsIDOMNode
*)fragment
, &tmp
);
1796 nsIDOMDocumentFragment_Release(fragment
);
1797 nsIDOMNode_Release(tmp
);
1799 nsIDOMHTMLElement_AppendChild(blockquote_elem
, (nsIDOMNode
*)p_elem
, &tmp
);
1800 nsIDOMHTMLElement_Release(p_elem
);
1801 nsIDOMNode_Release(tmp
);
1803 nsIDOMRange_InsertNode(This
->nsrange
, (nsIDOMNode
*)blockquote_elem
);
1804 nsIDOMHTMLElement_Release(blockquote_elem
);
1809 static HRESULT WINAPI
RangeCommandTarget_Exec(IOleCommandTarget
*iface
, const GUID
*pguidCmdGroup
,
1810 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
1812 HTMLTxtRange
*This
= impl_from_IOleCommandTarget(iface
);
1814 TRACE("(%p)->(%s %d %x %p %p)\n", This
, debugstr_guid(pguidCmdGroup
), nCmdID
,
1815 nCmdexecopt
, pvaIn
, pvaOut
);
1817 if(pguidCmdGroup
&& IsEqualGUID(&CGID_MSHTML
, pguidCmdGroup
)) {
1820 return exec_indent(This
, pvaIn
, pvaOut
);
1822 FIXME("Unsupported cmdid %d of CGID_MSHTML\n", nCmdID
);
1825 FIXME("Unsupported cmd %d of group %s\n", nCmdID
, debugstr_guid(pguidCmdGroup
));
1831 static const IOleCommandTargetVtbl OleCommandTargetVtbl
= {
1832 RangeCommandTarget_QueryInterface
,
1833 RangeCommandTarget_AddRef
,
1834 RangeCommandTarget_Release
,
1835 RangeCommandTarget_QueryStatus
,
1836 RangeCommandTarget_Exec
1839 HRESULT
HTMLTxtRange_Create(HTMLDocumentNode
*doc
, nsIDOMRange
*nsrange
, IHTMLTxtRange
**p
)
1843 ret
= heap_alloc(sizeof(HTMLTxtRange
));
1845 return E_OUTOFMEMORY
;
1847 ret
->IHTMLTxtRange_iface
.lpVtbl
= &HTMLTxtRangeVtbl
;
1848 ret
->IOleCommandTarget_iface
.lpVtbl
= &OleCommandTargetVtbl
;
1852 nsIDOMRange_AddRef(nsrange
);
1853 ret
->nsrange
= nsrange
;
1856 list_add_head(&doc
->range_list
, &ret
->entry
);
1858 *p
= &ret
->IHTMLTxtRange_iface
;
1862 void detach_ranges(HTMLDocumentNode
*This
)
1866 LIST_FOR_EACH_ENTRY(iter
, &This
->range_list
, HTMLTxtRange
, entry
) {