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
32 #include "wine/debug.h"
33 #include "wine/unicode.h"
35 #include "mshtml_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
39 static const WCHAR brW
[] = {'b','r',0};
42 const IHTMLTxtRangeVtbl
*lpHTMLTxtRangeVtbl
;
43 const IOleCommandTargetVtbl
*lpOleCommandTargetVtbl
;
53 #define HTMLTXTRANGE(x) ((IHTMLTxtRange*) &(x)->lpHTMLTxtRangeVtbl)
77 static HTMLTxtRange
*get_range_object(HTMLDocument
*doc
, IHTMLTxtRange
*iface
)
81 LIST_FOR_EACH_ENTRY(iter
, &doc
->range_list
, HTMLTxtRange
, entry
) {
82 if(HTMLTXTRANGE(iter
) == iface
)
86 ERR("Could not find range in document\n");
90 static range_unit_t
string_to_unit(LPCWSTR str
)
92 static const WCHAR characterW
[] =
93 {'c','h','a','r','a','c','t','e','r',0};
94 static const WCHAR wordW
[] =
96 static const WCHAR sentenceW
[] =
97 {'s','e','n','t','e','n','c','e',0};
98 static const WCHAR texteditW
[] =
99 {'t','e','x','t','e','d','i','t',0};
101 if(!strcmpiW(str
, characterW
)) return RU_CHAR
;
102 if(!strcmpiW(str
, wordW
)) return RU_WORD
;
103 if(!strcmpiW(str
, sentenceW
)) return RU_SENTENCE
;
104 if(!strcmpiW(str
, texteditW
)) return RU_TEXTEDIT
;
109 static int string_to_nscmptype(LPCWSTR str
)
111 static const WCHAR seW
[] = {'S','t','a','r','t','T','o','E','n','d',0};
112 static const WCHAR ssW
[] = {'S','t','a','r','t','T','o','S','t','a','r','t',0};
113 static const WCHAR esW
[] = {'E','n','d','T','o','S','t','a','r','t',0};
114 static const WCHAR eeW
[] = {'E','n','d','T','o','E','n','d',0};
116 if(!strcmpiW(str
, seW
)) return NS_START_TO_END
;
117 if(!strcmpiW(str
, ssW
)) return NS_START_TO_START
;
118 if(!strcmpiW(str
, esW
)) return NS_END_TO_START
;
119 if(!strcmpiW(str
, eeW
)) return NS_END_TO_END
;
124 static PRUint16
get_node_type(nsIDOMNode
*node
)
129 nsIDOMNode_GetNodeType(node
, &type
);
134 static BOOL
is_br_node(nsIDOMNode
*node
)
138 const PRUnichar
*tag
;
142 nsres
= nsIDOMNode_QueryInterface(node
, &IID_nsIDOMElement
, (void**)&elem
);
146 nsAString_Init(&tag_str
, NULL
);
147 nsIDOMElement_GetTagName(elem
, &tag_str
);
148 nsIDOMElement_Release(elem
);
149 nsAString_GetData(&tag_str
, &tag
, 0);
151 if(!strcmpiW(tag
, brW
))
154 nsAString_Finish(&tag_str
);
159 static inline void wstrbuf_init(wstrbuf_t
*buf
)
163 buf
->buf
= mshtml_alloc(buf
->size
* sizeof(WCHAR
));
167 static inline void wstrbuf_finish(wstrbuf_t
*buf
)
169 mshtml_free(buf
->buf
);
172 static void wstrbuf_append_len(wstrbuf_t
*buf
, LPCWSTR str
, int len
)
174 if(buf
->len
+len
>= buf
->size
) {
175 buf
->size
= 2*buf
->len
+len
;
176 buf
->buf
= mshtml_realloc(buf
->buf
, buf
->size
* sizeof(WCHAR
));
179 memcpy(buf
->buf
+buf
->len
, str
, len
*sizeof(WCHAR
));
181 buf
->buf
[buf
->len
] = 0;
184 static inline void wstrbuf_append(wstrbuf_t
*buf
, LPCWSTR str
)
186 wstrbuf_append_len(buf
, str
, strlenW(str
));
189 static void wstrbuf_append_nodetxt(wstrbuf_t
*buf
, LPCWSTR str
, int len
)
191 const WCHAR
*s
= str
;
194 TRACE("%s\n", debugstr_wn(str
, len
));
196 if(buf
->len
+len
>= buf
->size
) {
197 buf
->size
= 2*buf
->len
+len
;
198 buf
->buf
= mshtml_realloc(buf
->buf
, buf
->size
* sizeof(WCHAR
));
201 if(buf
->len
&& isspaceW(buf
->buf
[buf
->len
-1])) {
202 while(s
< str
+len
&& isspaceW(*s
))
206 d
= buf
->buf
+buf
->len
;
211 while(s
< str
+len
&& isspaceW(*s
))
218 buf
->len
= d
- buf
->buf
;
222 static void wstrbuf_append_node(wstrbuf_t
*buf
, nsIDOMNode
*node
)
225 switch(get_node_type(node
)) {
229 const PRUnichar
*data
;
231 nsIDOMNode_QueryInterface(node
, &IID_nsIDOMText
, (void**)&nstext
);
233 nsAString_Init(&data_str
, NULL
);
234 nsIDOMText_GetData(nstext
, &data_str
);
235 nsAString_GetData(&data_str
, &data
, NULL
);
236 wstrbuf_append_nodetxt(buf
, data
, strlenW(data
));
237 nsAString_Finish(&data_str
);
239 nsIDOMText_Release(nstext
);
244 if(is_br_node(node
)) {
245 static const WCHAR endlW
[] = {'\r','\n'};
246 wstrbuf_append_len(buf
, endlW
, 2);
251 static BOOL
fill_nodestr(dompos_t
*pos
)
256 if(pos
->type
!= TEXT_NODE
)
259 nsres
= nsIDOMNode_QueryInterface(pos
->node
, &IID_nsIDOMText
, (void**)&text
);
263 nsAString_Init(&pos
->str
, NULL
);
264 nsIDOMText_GetData(text
, &pos
->str
);
265 nsIDOMText_Release(text
);
266 nsAString_GetData(&pos
->str
, &pos
->p
, NULL
);
269 pos
->off
= *pos
->p
? strlenW(pos
->p
)-1 : 0;
274 static nsIDOMNode
*next_node(nsIDOMNode
*iter
)
276 nsIDOMNode
*ret
, *tmp
;
282 nsres
= nsIDOMNode_GetFirstChild(iter
, &ret
);
283 if(NS_SUCCEEDED(nsres
) && ret
)
286 nsIDOMNode_AddRef(iter
);
289 nsres
= nsIDOMNode_GetNextSibling(iter
, &ret
);
290 if(NS_SUCCEEDED(nsres
) && ret
) {
291 nsIDOMNode_Release(iter
);
295 nsres
= nsIDOMNode_GetParentNode(iter
, &tmp
);
296 nsIDOMNode_Release(iter
);
298 }while(NS_SUCCEEDED(nsres
) && iter
);
303 static nsIDOMNode
*prev_node(HTMLTxtRange
*This
, nsIDOMNode
*iter
)
305 nsIDOMNode
*ret
, *tmp
;
309 nsIDOMHTMLDocument
*nshtmldoc
;
310 nsIDOMHTMLElement
*nselem
;
311 nsIDOMDocument
*nsdoc
;
313 nsIWebNavigation_GetDocument(This
->doc
->nscontainer
->navigation
, &nsdoc
);
314 nsIDOMDocument_QueryInterface(nsdoc
, &IID_nsIDOMHTMLDocument
, (void**)&nshtmldoc
);
315 nsIDOMDocument_Release(nsdoc
);
316 nsIDOMHTMLDocument_GetBody(nshtmldoc
, &nselem
);
317 nsIDOMHTMLDocument_Release(nshtmldoc
);
319 nsIDOMElement_GetLastChild(nselem
, &tmp
);
321 return (nsIDOMNode
*)nselem
;
325 nsIDOMNode_GetLastChild(ret
, &tmp
);
328 nsIDOMElement_Release(nselem
);
333 nsres
= nsIDOMNode_GetLastChild(iter
, &ret
);
334 if(NS_SUCCEEDED(nsres
) && ret
)
337 nsIDOMNode_AddRef(iter
);
340 nsres
= nsIDOMNode_GetPreviousSibling(iter
, &ret
);
341 if(NS_SUCCEEDED(nsres
) && ret
) {
342 nsIDOMNode_Release(iter
);
346 nsres
= nsIDOMNode_GetParentNode(iter
, &tmp
);
347 nsIDOMNode_Release(iter
);
349 }while(NS_SUCCEEDED(nsres
) && iter
);
354 static nsIDOMNode
*get_child_node(nsIDOMNode
*node
, PRUint32 off
)
356 nsIDOMNodeList
*node_list
;
357 nsIDOMNode
*ret
= NULL
;
359 nsIDOMNode_GetChildNodes(node
, &node_list
);
360 nsIDOMNodeList_Item(node_list
, off
, &ret
);
361 nsIDOMNodeList_Release(node_list
);
366 static void get_cur_pos(HTMLTxtRange
*This
, BOOL start
, dompos_t
*pos
)
375 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
380 nsIDOMRange_GetStartContainer(This
->nsrange
, &node
);
381 nsIDOMRange_GetStartOffset(This
->nsrange
, &off
);
383 nsIDOMRange_GetEndContainer(This
->nsrange
, &node
);
384 nsIDOMRange_GetEndOffset(This
->nsrange
, &off
);
387 pos
->type
= get_node_type(node
);
388 if(pos
->type
== ELEMENT_NODE
) {
390 pos
->node
= get_child_node(node
, off
);
393 pos
->node
= off
? get_child_node(node
, off
-1) : prev_node(This
, node
);
397 pos
->type
= get_node_type(pos
->node
);
398 nsIDOMNode_Release(node
);
406 pos
->node
= prev_node(This
, node
);
408 nsIDOMNode_Release(node
);
411 if(pos
->type
== TEXT_NODE
)
415 static void set_range_pos(HTMLTxtRange
*This
, BOOL start
, dompos_t
*pos
)
420 if(pos
->type
== TEXT_NODE
)
421 nsres
= nsIDOMRange_SetStart(This
->nsrange
, pos
->node
, pos
->off
);
423 nsres
= nsIDOMRange_SetStartBefore(This
->nsrange
, pos
->node
);
425 if(pos
->type
== TEXT_NODE
&& pos
->p
[pos
->off
+1])
426 nsres
= nsIDOMRange_SetEnd(This
->nsrange
, pos
->node
, pos
->off
+1);
428 nsres
= nsIDOMRange_SetEndAfter(This
->nsrange
, pos
->node
);
432 ERR("failed: %p %08x\n", pos
->node
, nsres
);
435 static inline void dompos_release(dompos_t
*pos
)
438 nsIDOMNode_Release(pos
->node
);
441 nsAString_Finish(&pos
->str
);
444 static inline void dompos_addref(dompos_t
*pos
)
447 nsIDOMNode_AddRef(pos
->node
);
449 if(pos
->type
== TEXT_NODE
)
453 static inline BOOL
dompos_cmp(const dompos_t
*pos1
, const dompos_t
*pos2
)
455 return pos1
->node
== pos2
->node
&& pos1
->off
== pos2
->off
;
458 static void range_to_string(HTMLTxtRange
*This
, wstrbuf_t
*buf
)
460 nsIDOMNode
*iter
, *tmp
;
461 dompos_t start_pos
, end_pos
;
464 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
472 get_cur_pos(This
, FALSE
, &end_pos
);
473 get_cur_pos(This
, TRUE
, &start_pos
);
475 if(start_pos
.type
== TEXT_NODE
) {
476 if(start_pos
.node
== end_pos
.node
) {
477 wstrbuf_append_nodetxt(buf
, start_pos
.p
+start_pos
.off
, end_pos
.off
-start_pos
.off
+1);
478 iter
= start_pos
.node
;
479 nsIDOMNode_AddRef(iter
);
481 wstrbuf_append_nodetxt(buf
, start_pos
.p
+start_pos
.off
, strlenW(start_pos
.p
+start_pos
.off
));
482 iter
= next_node(start_pos
.node
);
485 iter
= start_pos
.node
;
486 nsIDOMNode_AddRef(iter
);
489 while(iter
!= end_pos
.node
) {
490 wstrbuf_append_node(buf
, iter
);
491 tmp
= next_node(iter
);
492 nsIDOMNode_Release(iter
);
496 nsIDOMNode_AddRef(end_pos
.node
);
498 if(start_pos
.node
!= end_pos
.node
&& !is_br_node(end_pos
.node
))
499 wstrbuf_append_nodetxt(buf
, end_pos
.p
, end_pos
.off
+1);
501 nsIDOMNode_Release(iter
);
502 dompos_release(&start_pos
);
503 dompos_release(&end_pos
);
508 for(p
= buf
->buf
+buf
->len
-1; p
>= buf
->buf
&& isspaceW(*p
); p
--);
510 p
= strchrW(p
, '\r');
516 static WCHAR
get_pos_char(const dompos_t
*pos
)
520 return pos
->p
[pos
->off
];
522 if(is_br_node(pos
->node
))
529 static void end_space(const dompos_t
*pos
, dompos_t
*new_pos
)
534 dompos_addref(new_pos
);
536 if(pos
->type
!= TEXT_NODE
)
539 p
= new_pos
->p
+new_pos
->off
;
541 if(!*p
|| !isspace(*p
))
544 while(p
[1] && isspace(p
[1]))
547 new_pos
->off
= p
- new_pos
->p
;
550 static WCHAR
next_char(const dompos_t
*pos
, dompos_t
*new_pos
)
552 nsIDOMNode
*iter
, *tmp
;
553 dompos_t last_space
, tmp_pos
;
557 if(pos
->type
== TEXT_NODE
&& pos
->off
!= -1 && pos
->p
[pos
->off
]) {
561 while(isspaceW(*++p
));
565 if(*p
&& isspaceW(*p
)) {
567 while(p
[1] && isspaceW(p
[1]))
573 new_pos
->off
= p
- pos
->p
;
574 dompos_addref(new_pos
);
576 return cspace
? cspace
: *p
;
579 last_space
.off
= p
- pos
->p
;
580 dompos_addref(&last_space
);
584 iter
= next_node(pos
->node
);
587 switch(get_node_type(iter
)) {
590 tmp_pos
.type
= TEXT_NODE
;
591 dompos_addref(&tmp_pos
);
596 dompos_release(&tmp_pos
);
598 }else if(isspaceW(*p
)) {
600 dompos_release(&last_space
);
604 while(p
[1] && isspaceW(p
[1]))
607 tmp_pos
.off
= p
-tmp_pos
.p
;
610 last_space
= tmp_pos
;
615 nsIDOMNode_Release(iter
);
618 *new_pos
= last_space
;
619 dompos_release(&tmp_pos
);
620 nsIDOMNode_Release(iter
);
628 nsIDOMNode_Release(iter
);
632 if(!is_br_node(iter
))
636 dompos_release(&last_space
);
639 nsIDOMNode_AddRef(iter
);
640 last_space
.node
= iter
;
641 last_space
.type
= ELEMENT_NODE
;
647 iter
= next_node(iter
);
648 nsIDOMNode_Release(tmp
);
652 *new_pos
= last_space
;
655 dompos_addref(new_pos
);
661 static WCHAR
prev_char(HTMLTxtRange
*This
, const dompos_t
*pos
, dompos_t
*new_pos
)
663 nsIDOMNode
*iter
, *tmp
;
665 BOOL skip_space
= FALSE
;
667 if(pos
->type
== TEXT_NODE
&& isspaceW(pos
->p
[pos
->off
]))
670 if(pos
->type
== TEXT_NODE
&& pos
->off
) {
671 p
= pos
->p
+pos
->off
-1;
674 while(p
>= pos
->p
&& isspace(*p
))
680 new_pos
->off
= p
-pos
->p
;
681 dompos_addref(new_pos
);
682 return new_pos
->p
[new_pos
->off
];
686 iter
= prev_node(This
, pos
->node
);
689 switch(get_node_type(iter
)) {
694 tmp_pos
.type
= TEXT_NODE
;
695 dompos_addref(&tmp_pos
);
697 p
= tmp_pos
.p
+ strlenW(tmp_pos
.p
)-1;
700 while(p
>= tmp_pos
.p
&& isspaceW(*p
))
705 dompos_release(&tmp_pos
);
709 tmp_pos
.off
= p
-tmp_pos
.p
;
711 nsIDOMNode_Release(iter
);
716 if(!is_br_node(iter
))
724 new_pos
->node
= iter
;
725 new_pos
->type
= ELEMENT_NODE
;
732 iter
= prev_node(This
, iter
);
733 nsIDOMNode_Release(tmp
);
737 dompos_addref(new_pos
);
741 static long move_next_chars(long cnt
, const dompos_t
*pos
, BOOL col
, const dompos_t
*bound_pos
,
742 BOOL
*bounded
, dompos_t
*new_pos
)
755 end_space(pos
, new_pos
);
759 c
= next_char(pos
, &iter
);
764 c
= next_char(&tmp
, &iter
);
765 dompos_release(&tmp
);
770 if(bound_pos
&& dompos_cmp(&tmp
, bound_pos
)) {
780 static long move_prev_chars(HTMLTxtRange
*This
, long cnt
, const dompos_t
*pos
, BOOL end
,
781 const dompos_t
*bound_pos
, BOOL
*bounded
, dompos_t
*new_pos
)
790 c
= prev_char(This
, pos
, &iter
);
794 while(c
&& ret
< cnt
) {
796 c
= prev_char(This
, &tmp
, &iter
);
797 dompos_release(&tmp
);
806 if(bound_pos
&& dompos_cmp(&iter
, bound_pos
)) {
813 return bounded
&& *bounded
? ret
+1 : ret
;
816 static long find_prev_space(HTMLTxtRange
*This
, const dompos_t
*pos
, BOOL first_space
, dompos_t
*ret
)
821 c
= prev_char(This
, pos
, &iter
);
822 if(!c
|| (first_space
&& isspaceW(c
))) {
829 c
= prev_char(This
, &tmp
, &iter
);
830 if(!c
|| isspaceW(c
)) {
831 dompos_release(&iter
);
834 dompos_release(&tmp
);
841 static int find_word_end(const dompos_t
*pos
, dompos_t
*ret
)
846 c
= get_pos_char(pos
);
853 c
= next_char(pos
, &iter
);
864 while(c
&& !isspaceW(c
)) {
866 c
= next_char(&tmp
, &iter
);
868 dompos_release(&iter
);
872 dompos_release(&tmp
);
880 static long move_next_words(long cnt
, const dompos_t
*pos
, dompos_t
*new_pos
)
886 c
= get_pos_char(pos
);
888 end_space(pos
, &iter
);
891 c
= next_char(pos
, &iter
);
896 while(c
&& ret
< cnt
) {
898 c
= next_char(&tmp
, &iter
);
899 dompos_release(&tmp
);
908 static long move_prev_words(HTMLTxtRange
*This
, long cnt
, const dompos_t
*pos
, dompos_t
*new_pos
)
914 dompos_addref(&iter
);
917 if(!find_prev_space(This
, &iter
, FALSE
, &tmp
))
920 dompos_release(&iter
);
929 #define HTMLTXTRANGE_THIS(iface) DEFINE_THIS(HTMLTxtRange, HTMLTxtRange, iface)
931 static HRESULT WINAPI
HTMLTxtRange_QueryInterface(IHTMLTxtRange
*iface
, REFIID riid
, void **ppv
)
933 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
937 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
938 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
939 *ppv
= HTMLTXTRANGE(This
);
940 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
941 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
942 *ppv
= HTMLTXTRANGE(This
);
943 }else if(IsEqualGUID(&IID_IHTMLTxtRange
, riid
)) {
944 TRACE("(%p)->(IID_IHTMLTxtRange %p)\n", This
, ppv
);
945 *ppv
= HTMLTXTRANGE(This
);
946 }else if(IsEqualGUID(&IID_IOleCommandTarget
, riid
)) {
947 TRACE("(%p)->(IID_IOleCommandTarget %p)\n", This
, ppv
);
948 *ppv
= CMDTARGET(This
);
952 IUnknown_AddRef((IUnknown
*)*ppv
);
956 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
957 return E_NOINTERFACE
;
960 static ULONG WINAPI
HTMLTxtRange_AddRef(IHTMLTxtRange
*iface
)
962 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
963 LONG ref
= InterlockedIncrement(&This
->ref
);
965 TRACE("(%p) ref=%d\n", This
, ref
);
970 static ULONG WINAPI
HTMLTxtRange_Release(IHTMLTxtRange
*iface
)
972 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
973 LONG ref
= InterlockedDecrement(&This
->ref
);
975 TRACE("(%p) ref=%d\n", This
, ref
);
979 nsISelection_Release(This
->nsrange
);
981 list_remove(&This
->entry
);
988 static HRESULT WINAPI
HTMLTxtRange_GetTypeInfoCount(IHTMLTxtRange
*iface
, UINT
*pctinfo
)
990 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
991 FIXME("(%p)->(%p)\n", This
, pctinfo
);
995 static HRESULT WINAPI
HTMLTxtRange_GetTypeInfo(IHTMLTxtRange
*iface
, UINT iTInfo
,
996 LCID lcid
, ITypeInfo
**ppTInfo
)
998 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
999 FIXME("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1003 static HRESULT WINAPI
HTMLTxtRange_GetIDsOfNames(IHTMLTxtRange
*iface
, REFIID riid
,
1004 LPOLESTR
*rgszNames
, UINT cNames
,
1005 LCID lcid
, DISPID
*rgDispId
)
1007 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1008 FIXME("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
1013 static HRESULT WINAPI
HTMLTxtRange_Invoke(IHTMLTxtRange
*iface
, DISPID dispIdMember
,
1014 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
1015 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1017 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1018 FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1019 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1023 static HRESULT WINAPI
HTMLTxtRange_get_htmlText(IHTMLTxtRange
*iface
, BSTR
*p
)
1025 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1027 TRACE("(%p)->(%p)\n", This
, p
);
1032 nsIDOMDocumentFragment
*fragment
;
1035 nsres
= nsIDOMRange_CloneContents(This
->nsrange
, &fragment
);
1036 if(NS_SUCCEEDED(nsres
)) {
1037 const PRUnichar
*nstext
;
1040 nsAString_Init(&nsstr
, NULL
);
1041 nsnode_to_nsstring((nsIDOMNode
*)fragment
, &nsstr
);
1042 nsIDOMDocumentFragment_Release(fragment
);
1044 nsAString_GetData(&nsstr
, &nstext
, NULL
);
1045 *p
= SysAllocString(nstext
);
1047 nsAString_Finish(&nsstr
);
1052 const WCHAR emptyW
[] = {0};
1053 *p
= SysAllocString(emptyW
);
1056 TRACE("return %s\n", debugstr_w(*p
));
1060 static HRESULT WINAPI
HTMLTxtRange_put_text(IHTMLTxtRange
*iface
, BSTR v
)
1062 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1063 nsIDOMDocument
*nsdoc
;
1064 nsIDOMText
*text_node
;
1068 TRACE("(%p)->(%s)\n", This
, debugstr_w(v
));
1071 return MSHTML_E_NODOC
;
1073 nsres
= nsIWebNavigation_GetDocument(This
->doc
->nscontainer
->navigation
, &nsdoc
);
1074 if(NS_FAILED(nsres
)) {
1075 ERR("GetDocument failed: %08x\n", nsres
);
1079 nsAString_Init(&text_str
, v
);
1080 nsres
= nsIDOMDocument_CreateTextNode(nsdoc
, &text_str
, &text_node
);
1081 nsIDOMDocument_Release(nsdoc
);
1082 nsAString_Finish(&text_str
);
1083 if(NS_FAILED(nsres
)) {
1084 ERR("CreateTextNode failed: %08x\n", nsres
);
1087 nsres
= nsIDOMRange_DeleteContents(This
->nsrange
);
1088 if(NS_FAILED(nsres
))
1089 ERR("DeleteContents failed: %08x\n", nsres
);
1091 nsres
= nsIDOMRange_InsertNode(This
->nsrange
, (nsIDOMNode
*)text_node
);
1092 if(NS_FAILED(nsres
))
1093 ERR("InsertNode failed: %08x\n", nsres
);
1095 nsres
= nsIDOMRange_SetEndAfter(This
->nsrange
, (nsIDOMNode
*)text_node
);
1096 if(NS_FAILED(nsres
))
1097 ERR("SetEndAfter failed: %08x\n", nsres
);
1099 return IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), VARIANT_FALSE
);
1102 static HRESULT WINAPI
HTMLTxtRange_get_text(IHTMLTxtRange
*iface
, BSTR
*p
)
1104 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1107 TRACE("(%p)->(%p)\n", This
, p
);
1114 range_to_string(This
, &buf
);
1116 *p
= SysAllocString(buf
.buf
);
1117 wstrbuf_finish(&buf
);
1119 TRACE("ret %s\n", debugstr_w(*p
));
1123 static HRESULT WINAPI
HTMLTxtRange_parentElement(IHTMLTxtRange
*iface
, IHTMLElement
**parent
)
1125 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1126 nsIDOMNode
*nsnode
, *tmp
;
1129 TRACE("(%p)->(%p)\n", This
, parent
);
1131 nsIDOMRange_GetCommonAncestorContainer(This
->nsrange
, &nsnode
);
1132 while(nsnode
&& get_node_type(nsnode
) != ELEMENT_NODE
) {
1133 nsIDOMNode_GetParentNode(nsnode
, &tmp
);
1134 nsIDOMNode_Release(nsnode
);
1143 node
= get_node(This
->doc
, nsnode
);
1144 nsIDOMNode_Release(nsnode
);
1146 return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(node
), &IID_IHTMLElement
, (void**)parent
);
1149 static HRESULT WINAPI
HTMLTxtRange_duplicate(IHTMLTxtRange
*iface
, IHTMLTxtRange
**Duplicate
)
1151 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1152 nsIDOMRange
*nsrange
= NULL
;
1154 TRACE("(%p)->(%p)\n", This
, Duplicate
);
1156 nsIDOMRange_CloneRange(This
->nsrange
, &nsrange
);
1157 *Duplicate
= HTMLTxtRange_Create(This
->doc
, nsrange
);
1158 nsIDOMRange_Release(nsrange
);
1163 static HRESULT WINAPI
HTMLTxtRange_inRange(IHTMLTxtRange
*iface
, IHTMLTxtRange
*Range
,
1164 VARIANT_BOOL
*InRange
)
1166 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1167 HTMLTxtRange
*src_range
;
1171 TRACE("(%p)->(%p %p)\n", This
, Range
, InRange
);
1173 *InRange
= VARIANT_FALSE
;
1175 src_range
= get_range_object(This
->doc
, Range
);
1179 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_START_TO_START
,
1180 src_range
->nsrange
, &nsret
);
1181 if(NS_SUCCEEDED(nsres
) && nsret
<= 0) {
1182 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_END_TO_END
,
1183 src_range
->nsrange
, &nsret
);
1184 if(NS_SUCCEEDED(nsres
) && nsret
>= 0)
1185 *InRange
= VARIANT_TRUE
;
1188 if(NS_FAILED(nsres
))
1189 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
1194 static HRESULT WINAPI
HTMLTxtRange_isEqual(IHTMLTxtRange
*iface
, IHTMLTxtRange
*Range
,
1195 VARIANT_BOOL
*IsEqual
)
1197 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1198 HTMLTxtRange
*src_range
;
1202 TRACE("(%p)->(%p %p)\n", This
, Range
, IsEqual
);
1204 *IsEqual
= VARIANT_FALSE
;
1206 src_range
= get_range_object(This
->doc
, Range
);
1210 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_START_TO_START
,
1211 src_range
->nsrange
, &nsret
);
1212 if(NS_SUCCEEDED(nsres
) && !nsret
) {
1213 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_END_TO_END
,
1214 src_range
->nsrange
, &nsret
);
1215 if(NS_SUCCEEDED(nsres
) && !nsret
)
1216 *IsEqual
= VARIANT_TRUE
;
1219 if(NS_FAILED(nsres
))
1220 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
1225 static HRESULT WINAPI
HTMLTxtRange_scrollIntoView(IHTMLTxtRange
*iface
, VARIANT_BOOL fStart
)
1227 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1228 FIXME("(%p)->(%x)\n", This
, fStart
);
1232 static HRESULT WINAPI
HTMLTxtRange_collapse(IHTMLTxtRange
*iface
, VARIANT_BOOL Start
)
1234 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1236 TRACE("(%p)->(%x)\n", This
, Start
);
1238 nsIDOMRange_Collapse(This
->nsrange
, Start
!= VARIANT_FALSE
);
1242 static HRESULT WINAPI
HTMLTxtRange_expand(IHTMLTxtRange
*iface
, BSTR Unit
, VARIANT_BOOL
*Success
)
1244 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1247 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(Unit
), Success
);
1249 unit
= string_to_unit(Unit
);
1250 if(unit
== RU_UNKNOWN
)
1251 return E_INVALIDARG
;
1253 *Success
= VARIANT_FALSE
;
1257 dompos_t end_pos
, start_pos
, new_start_pos
, new_end_pos
;
1260 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
1262 get_cur_pos(This
, TRUE
, &start_pos
);
1263 get_cur_pos(This
, FALSE
, &end_pos
);
1265 if(find_word_end(&end_pos
, &new_end_pos
) || collapsed
) {
1266 set_range_pos(This
, FALSE
, &new_end_pos
);
1267 *Success
= VARIANT_TRUE
;
1270 if(start_pos
.type
&& (get_pos_char(&end_pos
) || !dompos_cmp(&new_end_pos
, &end_pos
))) {
1271 if(find_prev_space(This
, &start_pos
, TRUE
, &new_start_pos
)) {
1272 set_range_pos(This
, TRUE
, &new_start_pos
);
1273 *Success
= VARIANT_TRUE
;
1275 dompos_release(&new_start_pos
);
1278 dompos_release(&new_end_pos
);
1279 dompos_release(&end_pos
);
1280 dompos_release(&start_pos
);
1286 nsIDOMDocument
*nsdoc
;
1287 nsIDOMHTMLDocument
*nshtmldoc
;
1288 nsIDOMHTMLElement
*nsbody
= NULL
;
1291 nsres
= nsIWebNavigation_GetDocument(This
->doc
->nscontainer
->navigation
, &nsdoc
);
1292 if(NS_FAILED(nsres
) || !nsdoc
) {
1293 ERR("GetDocument failed: %08x\n", nsres
);
1297 nsIDOMDocument_QueryInterface(nsdoc
, &IID_nsIDOMHTMLDocument
, (void**)&nshtmldoc
);
1298 nsIDOMDocument_Release(nsdoc
);
1300 nsres
= nsIDOMHTMLDocument_GetBody(nshtmldoc
, &nsbody
);
1301 nsIDOMHTMLDocument_Release(nshtmldoc
);
1302 if(NS_FAILED(nsres
) || !nsbody
) {
1303 ERR("Could not get body: %08x\n", nsres
);
1307 nsres
= nsIDOMRange_SelectNodeContents(This
->nsrange
, (nsIDOMNode
*)nsbody
);
1308 nsIDOMHTMLElement_Release(nsbody
);
1309 if(NS_FAILED(nsres
)) {
1310 ERR("Collapse failed: %08x\n", nsres
);
1314 *Success
= VARIANT_TRUE
;
1319 FIXME("Unimplemented unit %s\n", debugstr_w(Unit
));
1325 static HRESULT WINAPI
HTMLTxtRange_move(IHTMLTxtRange
*iface
, BSTR Unit
,
1326 long Count
, long *ActualCount
)
1328 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1331 TRACE("(%p)->(%s %ld %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1333 unit
= string_to_unit(Unit
);
1334 if(unit
== RU_UNKNOWN
)
1335 return E_INVALIDARG
;
1339 return IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1344 dompos_t cur_pos
, new_pos
;
1346 get_cur_pos(This
, TRUE
, &cur_pos
);
1349 *ActualCount
= move_next_chars(Count
, &cur_pos
, TRUE
, NULL
, NULL
, &new_pos
);
1350 set_range_pos(This
, FALSE
, &new_pos
);
1351 dompos_release(&new_pos
);
1353 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), FALSE
);
1355 *ActualCount
= -move_prev_chars(This
, -Count
, &cur_pos
, FALSE
, NULL
, NULL
, &new_pos
);
1356 set_range_pos(This
, TRUE
, &new_pos
);
1357 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1358 dompos_release(&new_pos
);
1361 dompos_release(&cur_pos
);
1366 dompos_t cur_pos
, new_pos
;
1368 get_cur_pos(This
, TRUE
, &cur_pos
);
1371 *ActualCount
= move_next_words(Count
, &cur_pos
, &new_pos
);
1372 set_range_pos(This
, FALSE
, &new_pos
);
1373 dompos_release(&new_pos
);
1374 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), FALSE
);
1376 *ActualCount
= -move_prev_words(This
, -Count
, &cur_pos
, &new_pos
);
1377 set_range_pos(This
, TRUE
, &new_pos
);
1378 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1379 dompos_release(&new_pos
);
1382 dompos_release(&cur_pos
);
1387 FIXME("unimplemented unit %s\n", debugstr_w(Unit
));
1390 TRACE("ret %ld\n", *ActualCount
);
1394 static HRESULT WINAPI
HTMLTxtRange_moveStart(IHTMLTxtRange
*iface
, BSTR Unit
,
1395 long Count
, long *ActualCount
)
1397 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1400 TRACE("(%p)->(%s %ld %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1402 unit
= string_to_unit(Unit
);
1403 if(unit
== RU_UNKNOWN
)
1404 return E_INVALIDARG
;
1413 dompos_t start_pos
, end_pos
, new_pos
;
1416 get_cur_pos(This
, TRUE
, &start_pos
);
1417 get_cur_pos(This
, FALSE
, &end_pos
);
1418 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
1423 *ActualCount
= move_next_chars(Count
, &start_pos
, collapsed
, &end_pos
, &bounded
, &new_pos
);
1424 set_range_pos(This
, !bounded
, &new_pos
);
1426 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), FALSE
);
1428 *ActualCount
= -move_prev_chars(This
, -Count
, &start_pos
, FALSE
, NULL
, NULL
, &new_pos
);
1429 set_range_pos(This
, TRUE
, &new_pos
);
1432 dompos_release(&start_pos
);
1433 dompos_release(&end_pos
);
1434 dompos_release(&new_pos
);
1439 FIXME("unimplemented unit %s\n", debugstr_w(Unit
));
1445 static HRESULT WINAPI
HTMLTxtRange_moveEnd(IHTMLTxtRange
*iface
, BSTR Unit
,
1446 long Count
, long *ActualCount
)
1448 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1451 TRACE("(%p)->(%s %ld %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1453 unit
= string_to_unit(Unit
);
1454 if(unit
== RU_UNKNOWN
)
1455 return E_INVALIDARG
;
1464 dompos_t start_pos
, end_pos
, new_pos
;
1467 get_cur_pos(This
, TRUE
, &start_pos
);
1468 get_cur_pos(This
, FALSE
, &end_pos
);
1469 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
1472 *ActualCount
= move_next_chars(Count
, &end_pos
, collapsed
, NULL
, NULL
, &new_pos
);
1473 set_range_pos(This
, FALSE
, &new_pos
);
1477 *ActualCount
= -move_prev_chars(This
, -Count
, &end_pos
, TRUE
, &start_pos
, &bounded
, &new_pos
);
1478 set_range_pos(This
, bounded
, &new_pos
);
1480 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1483 dompos_release(&start_pos
);
1484 dompos_release(&end_pos
);
1485 dompos_release(&new_pos
);
1490 FIXME("unimplemented unit %s\n", debugstr_w(Unit
));
1496 static HRESULT WINAPI
HTMLTxtRange_select(IHTMLTxtRange
*iface
)
1498 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1500 TRACE("(%p)\n", This
);
1502 if(This
->doc
->nscontainer
) {
1503 nsIDOMWindow
*dom_window
= NULL
;
1504 nsISelection
*nsselection
;
1506 nsIWebBrowser_GetContentDOMWindow(This
->doc
->nscontainer
->webbrowser
, &dom_window
);
1507 nsIDOMWindow_GetSelection(dom_window
, &nsselection
);
1508 nsIDOMWindow_Release(dom_window
);
1510 nsISelection_RemoveAllRanges(nsselection
);
1511 nsISelection_AddRange(nsselection
, This
->nsrange
);
1513 nsISelection_Release(nsselection
);
1519 static HRESULT WINAPI
HTMLTxtRange_pasteHTML(IHTMLTxtRange
*iface
, BSTR html
)
1521 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1522 FIXME("(%p)->(%s)\n", This
, debugstr_w(html
));
1526 static HRESULT WINAPI
HTMLTxtRange_moveToElementText(IHTMLTxtRange
*iface
, IHTMLElement
*element
)
1528 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1529 FIXME("(%p)->(%p)\n", This
, element
);
1533 static HRESULT WINAPI
HTMLTxtRange_setEndPoint(IHTMLTxtRange
*iface
, BSTR how
,
1534 IHTMLTxtRange
*SourceRange
)
1536 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1537 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(how
), SourceRange
);
1541 static HRESULT WINAPI
HTMLTxtRange_compareEndPoints(IHTMLTxtRange
*iface
, BSTR how
,
1542 IHTMLTxtRange
*SourceRange
, long *ret
)
1544 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1545 HTMLTxtRange
*src_range
;
1550 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(how
), SourceRange
, ret
);
1552 nscmpt
= string_to_nscmptype(how
);
1554 return E_INVALIDARG
;
1556 src_range
= get_range_object(This
->doc
, SourceRange
);
1560 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, nscmpt
, src_range
->nsrange
, &nsret
);
1561 if(NS_FAILED(nsres
))
1562 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
1568 static HRESULT WINAPI
HTMLTxtRange_findText(IHTMLTxtRange
*iface
, BSTR String
,
1569 long count
, long Flags
, VARIANT_BOOL
*Success
)
1571 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1572 FIXME("(%p)->(%s %ld %08lx %p)\n", This
, debugstr_w(String
), count
, Flags
, Success
);
1576 static HRESULT WINAPI
HTMLTxtRange_moveToPoint(IHTMLTxtRange
*iface
, long x
, long y
)
1578 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1579 FIXME("(%p)->(%ld %ld)\n", This
, x
, y
);
1583 static HRESULT WINAPI
HTMLTxtRange_getBookmark(IHTMLTxtRange
*iface
, BSTR
*Bookmark
)
1585 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1586 FIXME("(%p)->(%p)\n", This
, Bookmark
);
1590 static HRESULT WINAPI
HTMLTxtRange_moveToBookmark(IHTMLTxtRange
*iface
, BSTR Bookmark
,
1591 VARIANT_BOOL
*Success
)
1593 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1594 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(Bookmark
), Success
);
1598 static HRESULT WINAPI
HTMLTxtRange_queryCommandSupported(IHTMLTxtRange
*iface
, BSTR cmdID
,
1599 VARIANT_BOOL
*pfRet
)
1601 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1602 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1606 static HRESULT WINAPI
HTMLTxtRange_queryCommandEnabled(IHTMLTxtRange
*iface
, BSTR cmdID
,
1607 VARIANT_BOOL
*pfRet
)
1609 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1610 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1614 static HRESULT WINAPI
HTMLTxtRange_queryCommandState(IHTMLTxtRange
*iface
, BSTR cmdID
,
1615 VARIANT_BOOL
*pfRet
)
1617 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1618 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1622 static HRESULT WINAPI
HTMLTxtRange_queryCommandIndeterm(IHTMLTxtRange
*iface
, BSTR cmdID
,
1623 VARIANT_BOOL
*pfRet
)
1625 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1626 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1630 static HRESULT WINAPI
HTMLTxtRange_queryCommandText(IHTMLTxtRange
*iface
, BSTR cmdID
,
1633 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1634 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pcmdText
);
1638 static HRESULT WINAPI
HTMLTxtRange_queryCommandValue(IHTMLTxtRange
*iface
, BSTR cmdID
,
1641 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1642 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pcmdValue
);
1646 static HRESULT WINAPI
HTMLTxtRange_execCommand(IHTMLTxtRange
*iface
, BSTR cmdID
,
1647 VARIANT_BOOL showUI
, VARIANT value
, VARIANT_BOOL
*pfRet
)
1649 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1650 FIXME("(%p)->(%s %x v %p)\n", This
, debugstr_w(cmdID
), showUI
, pfRet
);
1654 static HRESULT WINAPI
HTMLTxtRange_execCommandShowHelp(IHTMLTxtRange
*iface
, BSTR cmdID
,
1655 VARIANT_BOOL
*pfRet
)
1657 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1658 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1662 #undef HTMLTXTRANGE_THIS
1664 static const IHTMLTxtRangeVtbl HTMLTxtRangeVtbl
= {
1665 HTMLTxtRange_QueryInterface
,
1666 HTMLTxtRange_AddRef
,
1667 HTMLTxtRange_Release
,
1668 HTMLTxtRange_GetTypeInfoCount
,
1669 HTMLTxtRange_GetTypeInfo
,
1670 HTMLTxtRange_GetIDsOfNames
,
1671 HTMLTxtRange_Invoke
,
1672 HTMLTxtRange_get_htmlText
,
1673 HTMLTxtRange_put_text
,
1674 HTMLTxtRange_get_text
,
1675 HTMLTxtRange_parentElement
,
1676 HTMLTxtRange_duplicate
,
1677 HTMLTxtRange_inRange
,
1678 HTMLTxtRange_isEqual
,
1679 HTMLTxtRange_scrollIntoView
,
1680 HTMLTxtRange_collapse
,
1681 HTMLTxtRange_expand
,
1683 HTMLTxtRange_moveStart
,
1684 HTMLTxtRange_moveEnd
,
1685 HTMLTxtRange_select
,
1686 HTMLTxtRange_pasteHTML
,
1687 HTMLTxtRange_moveToElementText
,
1688 HTMLTxtRange_setEndPoint
,
1689 HTMLTxtRange_compareEndPoints
,
1690 HTMLTxtRange_findText
,
1691 HTMLTxtRange_moveToPoint
,
1692 HTMLTxtRange_getBookmark
,
1693 HTMLTxtRange_moveToBookmark
,
1694 HTMLTxtRange_queryCommandSupported
,
1695 HTMLTxtRange_queryCommandEnabled
,
1696 HTMLTxtRange_queryCommandState
,
1697 HTMLTxtRange_queryCommandIndeterm
,
1698 HTMLTxtRange_queryCommandText
,
1699 HTMLTxtRange_queryCommandValue
,
1700 HTMLTxtRange_execCommand
,
1701 HTMLTxtRange_execCommandShowHelp
1704 #define OLECMDTRG_THIS(iface) DEFINE_THIS(HTMLTxtRange, OleCommandTarget, iface)
1706 static HRESULT WINAPI
RangeCommandTarget_QueryInterface(IOleCommandTarget
*iface
, REFIID riid
, void **ppv
)
1708 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1709 return IHTMLTxtRange_QueryInterface(HTMLTXTRANGE(This
), riid
, ppv
);
1712 static ULONG WINAPI
RangeCommandTarget_AddRef(IOleCommandTarget
*iface
)
1714 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1715 return IHTMLTxtRange_AddRef(HTMLTXTRANGE(This
));
1718 static ULONG WINAPI
RangeCommandTarget_Release(IOleCommandTarget
*iface
)
1720 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1721 return IHTMLTxtRange_Release(HTMLTXTRANGE(This
));
1724 static HRESULT WINAPI
RangeCommandTarget_QueryStatus(IOleCommandTarget
*iface
, const GUID
*pguidCmdGroup
,
1725 ULONG cCmds
, OLECMD prgCmds
[], OLECMDTEXT
*pCmdText
)
1727 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1728 FIXME("(%p)->(%s %d %p %p)\n", This
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
1732 static HRESULT WINAPI
RangeCommandTarget_Exec(IOleCommandTarget
*iface
, const GUID
*pguidCmdGroup
,
1733 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
1735 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1736 TRACE("(%p)->(%s %d %x %p %p)\n", This
, debugstr_guid(pguidCmdGroup
), nCmdID
,
1737 nCmdexecopt
, pvaIn
, pvaOut
);
1739 if(pguidCmdGroup
&& IsEqualGUID(&CGID_MSHTML
, pguidCmdGroup
)) {
1740 FIXME("Unsupported cmdid %d of CGID_MSHTML\n", nCmdID
);
1742 FIXME("Unsupported cmd %d of group %s\n", nCmdID
, debugstr_guid(pguidCmdGroup
));
1748 #undef OLECMDTRG_THIS
1750 static const IOleCommandTargetVtbl OleCommandTargetVtbl
= {
1751 RangeCommandTarget_QueryInterface
,
1752 RangeCommandTarget_AddRef
,
1753 RangeCommandTarget_Release
,
1754 RangeCommandTarget_QueryStatus
,
1755 RangeCommandTarget_Exec
1758 IHTMLTxtRange
*HTMLTxtRange_Create(HTMLDocument
*doc
, nsIDOMRange
*nsrange
)
1760 HTMLTxtRange
*ret
= mshtml_alloc(sizeof(HTMLTxtRange
));
1762 ret
->lpHTMLTxtRangeVtbl
= &HTMLTxtRangeVtbl
;
1763 ret
->lpOleCommandTargetVtbl
= &OleCommandTargetVtbl
;
1767 nsIDOMRange_AddRef(nsrange
);
1768 ret
->nsrange
= nsrange
;
1771 list_add_head(&doc
->range_list
, &ret
->entry
);
1773 return HTMLTXTRANGE(ret
);
1776 void detach_ranges(HTMLDocument
*This
)
1780 LIST_FOR_EACH_ENTRY(iter
, &This
->range_list
, HTMLTxtRange
, entry
) {